diff --git a/.changeset/afraid-needles-divide.md b/.changeset/afraid-needles-divide.md new file mode 100644 index 0000000000..6db7f449b0 --- /dev/null +++ b/.changeset/afraid-needles-divide.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Removed `packages/backend/src/types.ts` from the template as it is unused. It was mistakenly left in after moving the template to the new backend system. diff --git a/.changeset/afraid-numbers-invite.md b/.changeset/afraid-numbers-invite.md deleted file mode 100644 index ee81341d3a..0000000000 --- a/.changeset/afraid-numbers-invite.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@backstage/repo-tools': minor ---- - -Updates the OpenAPI client template to support the new format for identifying plugin ID. You should now use `info.title` like so, - -```diff -info: -+ title: yourPluginId -- title: @internal/plugin-*-backend - -servers: - - / -- - yourPluginId -``` diff --git a/.changeset/angry-phones-arrive.md b/.changeset/angry-phones-arrive.md deleted file mode 100644 index 2afcd240a9..0000000000 --- a/.changeset/angry-phones-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': minor ---- - -Add support for `oneOf` in client generated by `schema openapi generate-client`. diff --git a/.changeset/beige-apples-press.md b/.changeset/beige-apples-press.md deleted file mode 100644 index 56c46db830..0000000000 --- a/.changeset/beige-apples-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops': patch ---- - -Added alpha support for the New Frontend System (Declarative Integration) diff --git a/.changeset/blue-keys-do.md b/.changeset/blue-keys-do.md deleted file mode 100644 index c933bac0f2..0000000000 --- a/.changeset/blue-keys-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': minor ---- - -**BREAKING**: Replace default plugin extension and plugin ids to be `app` instead of `root`. diff --git a/.changeset/brave-jobs-invite.md b/.changeset/brave-jobs-invite.md deleted file mode 100644 index 402c5cebe7..0000000000 --- a/.changeset/brave-jobs-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Added a new `LegacyRootDatabaseService` interface that can be used to avoid direct dependencies on the `DatabaseManager`. diff --git a/.changeset/breezy-cobras-sin.md b/.changeset/breezy-cobras-sin.md deleted file mode 100644 index 93b296c455..0000000000 --- a/.changeset/breezy-cobras-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': minor ---- - -**BREAKING**: Removed the experimental `createExtensionTree` API. diff --git a/.changeset/bright-pumpkins-rule.md b/.changeset/bright-pumpkins-rule.md new file mode 100644 index 0000000000..07de4f313c --- /dev/null +++ b/.changeset/bright-pumpkins-rule.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +Allow overriding `NotificationsPage` page properties diff --git a/.changeset/brown-items-hammer.md b/.changeset/brown-items-hammer.md deleted file mode 100644 index fa023a026b..0000000000 --- a/.changeset/brown-items-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-okta-provider': patch ---- - -Added missing `additionalScopes` option to configuration schema. diff --git a/.changeset/brown-peaches-hunt.md b/.changeset/brown-peaches-hunt.md deleted file mode 100644 index fc10acc211..0000000000 --- a/.changeset/brown-peaches-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Fix a bug with S3 Fetch that caused all objects to be flattened within a single folder on the local file system. diff --git a/.changeset/calm-cups-rule.md b/.changeset/calm-cups-rule.md deleted file mode 100644 index 48cb8a2012..0000000000 --- a/.changeset/calm-cups-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': patch ---- - -Fix wrong `alpha` support in dynamic plugins support: the `alpha` sub-package should not be required for the dynamic plugins to be loaded under the new backend system. diff --git a/.changeset/calm-items-double.md b/.changeset/calm-items-double.md deleted file mode 100644 index 3db8ad57d9..0000000000 --- a/.changeset/calm-items-double.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': minor ---- - -Allow to force the creation of a pull request from a forked repository diff --git a/.changeset/calm-onions-exercise.md b/.changeset/calm-onions-exercise.md deleted file mode 100644 index f1c58a173f..0000000000 --- a/.changeset/calm-onions-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Resolved an issue with generate-catalog-info where it was replacing upper case characters with -. diff --git a/.changeset/chatty-cycles-unite.md b/.changeset/chatty-cycles-unite.md new file mode 100644 index 0000000000..93dffbb143 --- /dev/null +++ b/.changeset/chatty-cycles-unite.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +'@backstage/core-compat-api': patch +'@backstage/create-app': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-catalog': patch +--- + +Update local development dependencies. diff --git a/.changeset/chilled-chefs-notice.md b/.changeset/chilled-chefs-notice.md deleted file mode 100644 index a12babb2a4..0000000000 --- a/.changeset/chilled-chefs-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-rails': patch ---- - -Make `containerRunner` argument optional diff --git a/.changeset/chilled-ways-wave.md b/.changeset/chilled-ways-wave.md deleted file mode 100644 index 68e4d1eb7d..0000000000 --- a/.changeset/chilled-ways-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -fix for: converting circular structure to JSON error diff --git a/.changeset/chilly-adults-sing.md b/.changeset/chilly-adults-sing.md new file mode 100644 index 0000000000..82f4cb88b2 --- /dev/null +++ b/.changeset/chilly-adults-sing.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Add lifecycle monitoring for the catalog processing diff --git a/.changeset/chilly-fireants-roll.md b/.changeset/chilly-fireants-roll.md new file mode 100644 index 0000000000..93c05fecb7 --- /dev/null +++ b/.changeset/chilly-fireants-roll.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Use relative time when displaying visits from the same day diff --git a/.changeset/chilly-seahorses-bake.md b/.changeset/chilly-seahorses-bake.md deleted file mode 100644 index 8ab80cf93e..0000000000 --- a/.changeset/chilly-seahorses-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -The backwards compatibility provider will now use the new `ComponentsApi` and `IconsApi` when implementing the old `AppContext`. diff --git a/.changeset/clever-chicken-jog.md b/.changeset/clever-chicken-jog.md deleted file mode 100644 index de65947105..0000000000 --- a/.changeset/clever-chicken-jog.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': minor ---- - -Added support for server side text filtering to paginated entity requests. diff --git a/.changeset/clever-steaks-hope.md b/.changeset/clever-steaks-hope.md deleted file mode 100644 index 94c6e8ee29..0000000000 --- a/.changeset/clever-steaks-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-unprocessed': patch ---- - -Explicitly only depend on the `use` method from the `HttpRouterService`. diff --git a/.changeset/cold-cheetahs-pull.md b/.changeset/cold-cheetahs-pull.md deleted file mode 100644 index 140a564e4f..0000000000 --- a/.changeset/cold-cheetahs-pull.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': minor -'@backstage/plugin-scaffolder-backend': patch ---- - -New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. - -Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` -and replaces its actions related to Bitbucket Server. - -- `publish:bitbucketServer` -- `publish:bitbucketServer:pull-request` diff --git a/.changeset/cold-cooks-care.md b/.changeset/cold-cooks-care.md deleted file mode 100644 index 56c41a55e9..0000000000 --- a/.changeset/cold-cooks-care.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-entity-validation': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-catalog': patch ---- - -Change default icon for unknown entities to nothing instead of the help icon. diff --git a/.changeset/cold-rats-leave.md b/.changeset/cold-rats-leave.md new file mode 100644 index 0000000000..6fe28d6371 --- /dev/null +++ b/.changeset/cold-rats-leave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fix issue with the log format not being respected when logging from actions diff --git a/.changeset/cool-elephants-march.md b/.changeset/cool-elephants-march.md new file mode 100644 index 0000000000..2396f9553d --- /dev/null +++ b/.changeset/cool-elephants-march.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitea': patch +--- + +Allow defining `repoVisibility` field for the action `publish:gitea` diff --git a/.changeset/cool-islands-impress.md b/.changeset/cool-islands-impress.md deleted file mode 100644 index df6df1ada2..0000000000 --- a/.changeset/cool-islands-impress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-sites': patch ---- - -Updated README diff --git a/.changeset/cool-walls-applaud.md b/.changeset/cool-walls-applaud.md deleted file mode 100644 index d548b926fb..0000000000 --- a/.changeset/cool-walls-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Updated README to list AsyncApi v3 as supported diff --git a/.changeset/create-app-1706621803.md b/.changeset/create-app-1706621803.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1706621803.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/cuddly-chairs-kick.md b/.changeset/cuddly-chairs-kick.md new file mode 100644 index 0000000000..ebb53b8e26 --- /dev/null +++ b/.changeset/cuddly-chairs-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Add ability to configure the Node.js HTTP Server when configuring the root HTTP Router service diff --git a/.changeset/curly-shirts-flow.md b/.changeset/curly-shirts-flow.md new file mode 100644 index 0000000000..b9a73809ba --- /dev/null +++ b/.changeset/curly-shirts-flow.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Update the paths logic in the api reports command to support complex subpaths diff --git a/.changeset/curvy-icons-peel.md b/.changeset/curvy-icons-peel.md deleted file mode 100644 index bbadcb0a55..0000000000 --- a/.changeset/curvy-icons-peel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-badges-backend': patch ---- - -Updating the `authorization` middleware to call the Catalog to check that the requesting user has permission to see the Entity before generating the UUID. diff --git a/.changeset/curvy-ladybugs-impress.md b/.changeset/curvy-ladybugs-impress.md deleted file mode 100644 index ab799e4888..0000000000 --- a/.changeset/curvy-ladybugs-impress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-adr': patch ---- - -Updated README diff --git a/.changeset/curvy-planes-flash.md b/.changeset/curvy-planes-flash.md new file mode 100644 index 0000000000..0d3368e53d --- /dev/null +++ b/.changeset/curvy-planes-flash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch +--- + +Allow skipping archived repositories (`skipArchivedRepos` flag) on Bitbucket. diff --git a/.changeset/cyan-bats-lick.md b/.changeset/cyan-bats-lick.md deleted file mode 100644 index 0683d806b0..0000000000 --- a/.changeset/cyan-bats-lick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops-backend': patch ---- - -Added a note about Service Principles diff --git a/.changeset/cyan-ducks-sin.md b/.changeset/cyan-ducks-sin.md deleted file mode 100644 index 4b69fabcc2..0000000000 --- a/.changeset/cyan-ducks-sin.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-common': minor ---- - -**BREAKING**: `A gitilesBaseUrl` must be provided for the Gerrit integration to work. -You can disable this check by setting `DISABLE_GERRIT_GITILES_REQUIREMENT=1` but -this will be removed in a future release. If you are not able to use the Gitiles -Gerrit plugin, please open an issue towards `https://github.com/backstage/backstage` diff --git a/.changeset/cyan-icons-rest.md b/.changeset/cyan-icons-rest.md deleted file mode 100644 index 3092c1bc90..0000000000 --- a/.changeset/cyan-icons-rest.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-explore-backend': patch ---- - -Add support for the new backend system. - -A new backend plugin for the explore backend -was added and exported as `default`. - -You can use it with the new backend system like - -```ts title="packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-explore-backend')); -``` diff --git a/.changeset/dirty-cheetahs-shave.md b/.changeset/dirty-cheetahs-shave.md deleted file mode 100644 index 1691adec2d..0000000000 --- a/.changeset/dirty-cheetahs-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Support additional algorithms in the `/.well-known/openid-configuration` endpoint. diff --git a/.changeset/dirty-mirrors-retire.md b/.changeset/dirty-mirrors-retire.md deleted file mode 100644 index cb0bcd66a8..0000000000 --- a/.changeset/dirty-mirrors-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -Updated dependency `@oriflame/backstage-plugin-score-card` to `^0.8.0`. diff --git a/.changeset/dirty-plums-fix.md b/.changeset/dirty-plums-fix.md deleted file mode 100644 index fb0655377c..0000000000 --- a/.changeset/dirty-plums-fix.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend-module-jsonfc': patch ---- - -Add support for the new backend system. - -A new backend module for the tech-insights backend -was added and exported as `default`. - -The module will register the `JsonRulesEngineFactCheckerFactory` -as `FactCheckerFactory`, loading checks from the config. - -You can use it with the new backend system like - -```ts title="packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-tech-insights-backend-module-jsonfc')); -``` diff --git a/.changeset/dry-lizards-taste.md b/.changeset/dry-lizards-taste.md deleted file mode 100644 index 90e4c9f659..0000000000 --- a/.changeset/dry-lizards-taste.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/app-defaults': patch -'@backstage/plugin-catalog': patch ---- - -Change default icon for `kind:resource` to the storage icon. diff --git a/.changeset/dry-lobsters-flash.md b/.changeset/dry-lobsters-flash.md deleted file mode 100644 index 9815bf62f4..0000000000 --- a/.changeset/dry-lobsters-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -Added `IconsApi` implementation and the ability to configure icons through the `icons` option for `createApp` and `createSpecializedApp`. This is not a long-term solution as icons should be installable via extensions instead. This is just a stop-gap to make sure there is feature parity with the existing frontend system. diff --git a/.changeset/dry-sloths-impress.md b/.changeset/dry-sloths-impress.md new file mode 100644 index 0000000000..6bd5ba4156 --- /dev/null +++ b/.changeset/dry-sloths-impress.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-model': minor +--- + +Introduce a domain attribute to the domain entity to allow a hierarchy of domains to exist. diff --git a/.changeset/dry-vans-kiss.md b/.changeset/dry-vans-kiss.md deleted file mode 100644 index 5d11df989c..0000000000 --- a/.changeset/dry-vans-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Simple typo fix in the fetch:template action example on the word 'skeleton'. diff --git a/.changeset/dull-dolphins-explain.md b/.changeset/dull-dolphins-explain.md deleted file mode 100644 index d8864e72e8..0000000000 --- a/.changeset/dull-dolphins-explain.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -The default EKS cluster entity transformer now sets the new -`kubernetes.io/x-k8s-aws-id` annotation. diff --git a/.changeset/dull-fireants-repeat.md b/.changeset/dull-fireants-repeat.md deleted file mode 100644 index 4e849bfbaf..0000000000 --- a/.changeset/dull-fireants-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Use the externalized `auth-backend-module-microsoft-provider` again. diff --git a/.changeset/eight-hounds-dream.md b/.changeset/eight-hounds-dream.md deleted file mode 100644 index 8bf945d684..0000000000 --- a/.changeset/eight-hounds-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-adr': patch ---- - -Fix alignment of text in `AdrSearchResultListItem`. Update size and font to match other `SearchResultListItem`. diff --git a/.changeset/eight-pumas-rule.md b/.changeset/eight-pumas-rule.md deleted file mode 100644 index 166ebd8bd3..0000000000 --- a/.changeset/eight-pumas-rule.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': minor ---- - -**BREAKING** The `PodScope`, `PodAndErrors`, and `PodExecTerminalProps` types no -longer have a `clusterName` field; instead they now have the field `cluster` -which contains the full `ClusterAttributes`. diff --git a/.changeset/eighty-apricots-kneel.md b/.changeset/eighty-apricots-kneel.md new file mode 100644 index 0000000000..a9cabaf378 --- /dev/null +++ b/.changeset/eighty-apricots-kneel.md @@ -0,0 +1,5 @@ +--- +'@techdocs/cli': patch +--- + +Fix cookie endpoint mock for `serve` diff --git a/.changeset/eighty-bats-stare.md b/.changeset/eighty-bats-stare.md new file mode 100644 index 0000000000..6ebb2e9265 --- /dev/null +++ b/.changeset/eighty-bats-stare.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Update path in Readme for Plugin Techdocs to show the correct setup information. diff --git a/.changeset/eleven-pandas-divide.md b/.changeset/eleven-pandas-divide.md new file mode 100644 index 0000000000..912d34570a --- /dev/null +++ b/.changeset/eleven-pandas-divide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +Added events support for `GitlabDiscoveryEntityProvider` and `GitlabOrgDiscoveryEntityProvider`. diff --git a/.changeset/eleven-walls-relate.md b/.changeset/eleven-walls-relate.md deleted file mode 100644 index 43c1d5dea9..0000000000 --- a/.changeset/eleven-walls-relate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-oidc-provider': patch ---- - -Fixed a bug where the OIDC authenticator did not properly persist granted OAuth scopes. diff --git a/.changeset/empty-ligers-hang.md b/.changeset/empty-ligers-hang.md deleted file mode 100644 index c17609712a..0000000000 --- a/.changeset/empty-ligers-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -Overflowing labels in OwnerPicker (Catalog) are now truncated. Hovering over them shows the full label diff --git a/.changeset/fair-mirrors-hammer.md b/.changeset/fair-mirrors-hammer.md deleted file mode 100644 index 3884835d11..0000000000 --- a/.changeset/fair-mirrors-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-graph': patch ---- - -use `CatalogClient.getEntitiesByRefs()` to reduce the number of backend requests from plugin `catalog-graph` diff --git a/.changeset/famous-houses-thank.md b/.changeset/famous-houses-thank.md deleted file mode 100644 index 8fa0eb2d75..0000000000 --- a/.changeset/famous-houses-thank.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-test-utils': patch -'@backstage/frontend-app-api': patch -'@backstage/core-compat-api': patch ---- - -Updates to use the new `RouteResolutionsApi`. diff --git a/.changeset/famous-zoos-remain.md b/.changeset/famous-zoos-remain.md deleted file mode 100644 index be4147c21e..0000000000 --- a/.changeset/famous-zoos-remain.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-entity-feedback-backend': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-lighthouse-backend': patch -'@backstage/plugin-devtools-backend': patch -'@backstage/plugin-linguist-backend': patch -'@backstage/plugin-badges-backend': patch -'@backstage/plugin-adr-backend': patch -'@backstage/plugin-airbrake': patch ---- - -Updated New Backend System instructions to use default import diff --git a/.changeset/fast-jeans-walk.md b/.changeset/fast-jeans-walk.md deleted file mode 100644 index f733c9f464..0000000000 --- a/.changeset/fast-jeans-walk.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': minor -'@backstage/plugin-scaffolder': minor ---- - -Remove the old legacy exports from `/alpha` diff --git a/.changeset/fast-onions-own.md b/.changeset/fast-onions-own.md deleted file mode 100644 index 6977b035bc..0000000000 --- a/.changeset/fast-onions-own.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -`FetchUrlReader#readUrl()` now supports passing an optional `token` to authenticate requests. diff --git a/.changeset/fifty-adults-watch.md b/.changeset/fifty-adults-watch.md deleted file mode 100644 index 8bff1c28cd..0000000000 --- a/.changeset/fifty-adults-watch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-devtools': patch ---- - -Refactored code to improve accessibility by moving elements outside the `ul` tag and placing them appropriately. Also adjusted theme to offer better contrast. diff --git a/.changeset/fifty-files-argue.md b/.changeset/fifty-files-argue.md deleted file mode 100644 index b80b2989af..0000000000 --- a/.changeset/fifty-files-argue.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-test-utils': minor -'@backstage/backend-common': minor ---- - -drop databases after unit tests if the database instance is not running in docker diff --git a/.changeset/five-hornets-wash.md b/.changeset/five-hornets-wash.md deleted file mode 100644 index c29debb518..0000000000 --- a/.changeset/five-hornets-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Fix some deprecations and misplaced `await` usage. diff --git a/.changeset/fix-stackoverflow.md b/.changeset/fix-stackoverflow.md new file mode 100644 index 0000000000..6ce9f15737 --- /dev/null +++ b/.changeset/fix-stackoverflow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +--- + +Fix plugin/incremental-ingestion 'Maximum call stack size exceeded' error when ingest large entities. diff --git a/.changeset/flat-roses-happen.md b/.changeset/flat-roses-happen.md deleted file mode 100644 index e20e063b4f..0000000000 --- a/.changeset/flat-roses-happen.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket': minor ---- - -Split `@backstage/plugin-scaffolder-backend-module-bitbucket` into -`@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` and -`@backstage/plugin-scaffolder-backend-module-bitbucket-server`. - -`@backstage/plugin-scaffolder-backend-module-bitbucket` was **deprecated** in favor of these two replacements. - -Please use any of the two replacements depending on your needs. - -```diff -- backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket')); -+ backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket-cloud')); -+ backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket-server')); -``` diff --git a/.changeset/flat-wasps-fold.md b/.changeset/flat-wasps-fold.md deleted file mode 100644 index 653dc0d78f..0000000000 --- a/.changeset/flat-wasps-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -Added initial `IconsApi` definition. diff --git a/.changeset/fluffy-hotels-wait.md b/.changeset/fluffy-hotels-wait.md new file mode 100644 index 0000000000..a578f2fb4a --- /dev/null +++ b/.changeset/fluffy-hotels-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Both the target and types library have been bumped from ES2021 to ES2022 in `@backstage/cli/config/tsconfig.json`. diff --git a/.changeset/fluffy-jeans-eat.md b/.changeset/fluffy-jeans-eat.md deleted file mode 100644 index 8935c33937..0000000000 --- a/.changeset/fluffy-jeans-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added check for the `repository` field in the `repo fix` command. diff --git a/.changeset/forty-beers-sniff.md b/.changeset/forty-beers-sniff.md deleted file mode 100644 index 130726f94f..0000000000 --- a/.changeset/forty-beers-sniff.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/plugin-catalog-graph': patch ---- - -Added possibility to show arrow heads for graph edges for better understandability. - -In order to show arrow heads in the catalog graph page, add `showArrowHeads` attribute to `CatalogGraphPage` component -(typically in `packages/app/src/App.tsx`): - -```diff -- -+ -``` - -In order to show arrow heads in entity graphs, add `showArrowHeads` attribute to `EntityCatalogGraphCard` components -(typically multiple occurrences in `packages/app/src/components/catalog/EntityPage.tsx`): - -```diff -- -+ -``` diff --git a/.changeset/forty-cars-scream.md b/.changeset/forty-cars-scream.md deleted file mode 100644 index 284acc3c44..0000000000 --- a/.changeset/forty-cars-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Allow defining default output text to be shown diff --git a/.changeset/forty-eagles-kick.md b/.changeset/forty-eagles-kick.md deleted file mode 100644 index 4d701a729b..0000000000 --- a/.changeset/forty-eagles-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Pod dialogs display cluster title when specified. diff --git a/.changeset/four-cooks-serve.md b/.changeset/four-cooks-serve.md new file mode 100644 index 0000000000..864807cc49 --- /dev/null +++ b/.changeset/four-cooks-serve.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-notifications-node': patch +--- + +Support for filtering entities from notification recipients after resolving them from the recipients diff --git a/.changeset/four-mugs-try.md b/.changeset/four-mugs-try.md deleted file mode 100644 index 11fdf783d4..0000000000 --- a/.changeset/four-mugs-try.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': minor ---- - -**BREAKING**: Removed the `SidebarIntro` component as it was providing instructions for features that do not exist, along with `IntroCard`. If you were relying on this component and want to keep using it you can refer to the original implementations of [`SidebarIntro`](https://github.com/backstage/backstage/blob/80f2413334ed9b221ec3c2b7c22fa737ad8d8885/packages/core-components/src/layout/Sidebar/Intro.tsx#L149) and [`IntroCard`](https://github.com/backstage/backstage/blob/80f2413334ed9b221ec3c2b7c22fa737ad8d8885/packages/core-components/src/layout/Sidebar/Intro.tsx#L100). diff --git a/.changeset/four-walls-perform.md b/.changeset/four-walls-perform.md deleted file mode 100644 index 5275da7b79..0000000000 --- a/.changeset/four-walls-perform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Updating the `EntityPicker` to only select `kind` `metadata.name` and `metadata.namespace` by default to improve performance on larger datasets. diff --git a/.changeset/fresh-crews-impress.md b/.changeset/fresh-crews-impress.md new file mode 100644 index 0000000000..18f98f1dd9 --- /dev/null +++ b/.changeset/fresh-crews-impress.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Move the JWKS registration outside of the lifecycle middleware diff --git a/.changeset/fresh-gifts-smile.md b/.changeset/fresh-gifts-smile.md deleted file mode 100644 index 446e9f3c54..0000000000 --- a/.changeset/fresh-gifts-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-module-addons-contrib': patch ---- - -Fixed the value label text color in dark mode for the TextSize addon. diff --git a/.changeset/fresh-paws-raise.md b/.changeset/fresh-paws-raise.md deleted file mode 100644 index 61712db1e8..0000000000 --- a/.changeset/fresh-paws-raise.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -The `ErrorPanel` component will display the `title` field (when specified) for -clusters with errors. diff --git a/.changeset/friendly-cheetahs-rescue.md b/.changeset/friendly-cheetahs-rescue.md deleted file mode 100644 index 4f54a022af..0000000000 --- a/.changeset/friendly-cheetahs-rescue.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Fixed an issue where a misleading error message would be logged when an -unsupported service locator method was specified. diff --git a/.changeset/friendly-terms-love.md b/.changeset/friendly-terms-love.md deleted file mode 100644 index 18fc399740..0000000000 --- a/.changeset/friendly-terms-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Introduced `knip` to the `knip-reports` command, which generates a `knip-report.md` file for your packages with dependency warnings, if any. diff --git a/.changeset/funny-buttons-sip.md b/.changeset/funny-buttons-sip.md deleted file mode 100644 index c455b8a31b..0000000000 --- a/.changeset/funny-buttons-sip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Move the `NODE_OPTIONS` messaging for `--no-node-snapshot` to the `SecureTemplater` in order to get better messaging at runtime diff --git a/.changeset/funny-meals-tease.md b/.changeset/funny-meals-tease.md deleted file mode 100644 index 3dce739952..0000000000 --- a/.changeset/funny-meals-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': minor ---- - -support oidc customization diff --git a/.changeset/funny-timers-visit.md b/.changeset/funny-timers-visit.md deleted file mode 100644 index 3d802328b5..0000000000 --- a/.changeset/funny-timers-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Fix broken XtermJS CSS import diff --git a/.changeset/fuzzy-comics-collect.md b/.changeset/fuzzy-comics-collect.md deleted file mode 100644 index 5ce6b3c967..0000000000 --- a/.changeset/fuzzy-comics-collect.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend-module-jsonfc': patch ---- - -Support loading `TechInsightsJsonRuleCheck` instances from config. - -Uses the check `id` as key. - -Example: - -```yaml title="app-config.yaml" -techInsights: - factChecker: - checks: - groupOwnerCheck: - type: json-rules-engine - name: Group Owner Check - description: Verifies that a group has been set as the spec.owner for this entity - factIds: - - entityOwnershipFactRetriever - rule: - conditions: - all: - - fact: hasGroupOwner - operator: equal - value: true -``` diff --git a/.changeset/fuzzy-turtles-camp.md b/.changeset/fuzzy-turtles-camp.md deleted file mode 100644 index ca1767bd30..0000000000 --- a/.changeset/fuzzy-turtles-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-node': patch ---- - -Added `repository` field to `BackstagePackageJson` type. diff --git a/.changeset/giant-suits-switch.md b/.changeset/giant-suits-switch.md deleted file mode 100644 index 77d0e62c73..0000000000 --- a/.changeset/giant-suits-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops-backend': patch ---- - -Fixed bug with `extractPartsFromAsset` that resulted in a leading `.` being removed from the path in an otherwise valid path (ex. `.assets/image.png`). The leading `.` will now only be moved for paths beginning with `./`. diff --git a/.changeset/gold-waves-bake.md b/.changeset/gold-waves-bake.md new file mode 100644 index 0000000000..2883b7b967 --- /dev/null +++ b/.changeset/gold-waves-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Add support for `versions:migrate` to do code changes. Can be skipped with `--no-code-changes` diff --git a/.changeset/good-lemons-lick.md b/.changeset/good-lemons-lick.md deleted file mode 100644 index 3fde0c7d84..0000000000 --- a/.changeset/good-lemons-lick.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch -'@backstage/plugin-scaffolder-backend-module-gerrit': patch -'@backstage/plugin-scaffolder-backend-module-github': patch -'@backstage/plugin-scaffolder-backend-module-gitlab': patch -'@backstage/plugin-scaffolder-backend-module-sentry': patch -'@backstage/plugin-scaffolder-backend-module-yeoman': patch -'@backstage/plugin-scaffolder-backend-module-azure': patch -'@backstage/plugin-scaffolder-backend-module-rails': patch ---- - -Exporting a default module for the new Backend System diff --git a/.changeset/gorgeous-bobcats-press.md b/.changeset/gorgeous-bobcats-press.md deleted file mode 100644 index 6193918cb7..0000000000 --- a/.changeset/gorgeous-bobcats-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Include the extension point ID and the module ID in the backend init error message. diff --git a/.changeset/gorgeous-cameras-cross.md b/.changeset/gorgeous-cameras-cross.md new file mode 100644 index 0000000000..50d7ddb2d7 --- /dev/null +++ b/.changeset/gorgeous-cameras-cross.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-addons-test-utils': patch +--- + +Fix bug in TechDocsAddonTester when jest.resetAllMocks is called between tests diff --git a/.changeset/gorgeous-pumas-draw.md b/.changeset/gorgeous-pumas-draw.md deleted file mode 100644 index 2e94c61c63..0000000000 --- a/.changeset/gorgeous-pumas-draw.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-analytics-module-newrelic-browser': minor -'@backstage/plugin-analytics-module-ga4': minor -'@backstage/plugin-analytics-module-ga': minor -'@backstage/core-compat-api': minor ---- - -Add support to the new analytics api. diff --git a/.changeset/gorgeous-ways-applaud.md b/.changeset/gorgeous-ways-applaud.md deleted file mode 100644 index 4b28e2e656..0000000000 --- a/.changeset/gorgeous-ways-applaud.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-signals-backend': patch -'@backstage/plugin-signals-react': patch -'@backstage/plugin-signals-node': patch -'@backstage/plugin-signals': patch ---- - -Fix disconnect loop on server start diff --git a/.changeset/great-rats-collect.md b/.changeset/great-rats-collect.md deleted file mode 100644 index 24b01c0fe3..0000000000 --- a/.changeset/great-rats-collect.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': minor ---- - -**BREAKING** The backend will fail to start if two clusters in the app-config -have the same name. The requirement for unique names has been declared in the -docs for some time, but is now enforced. diff --git a/.changeset/green-adults-push.md b/.changeset/green-adults-push.md new file mode 100644 index 0000000000..3edc21c385 --- /dev/null +++ b/.changeset/green-adults-push.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Add preserveModules to rollup, which allows better async loading and tree-shaking in webpack diff --git a/.changeset/green-dogs-fold.md b/.changeset/green-dogs-fold.md deleted file mode 100644 index c23f7c2a29..0000000000 --- a/.changeset/green-dogs-fold.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-tech-insights-node': patch ---- - -Add support for the new backend system. - -A new backend plugin for the tech-insights backend -was added and exported as `default`. - -You can use it with the new backend system like - -```ts title="packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-tech-insights-backend')); -``` diff --git a/.changeset/green-flies-draw.md b/.changeset/green-flies-draw.md deleted file mode 100644 index 6b967feceb..0000000000 --- a/.changeset/green-flies-draw.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Upgrade jest diff --git a/.changeset/grumpy-poets-study.md b/.changeset/grumpy-poets-study.md deleted file mode 100644 index 9925f2f87a..0000000000 --- a/.changeset/grumpy-poets-study.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Added basic support for the new frontend system, exported from the `/alpha` subpath. diff --git a/.changeset/happy-peas-hunt.md b/.changeset/happy-peas-hunt.md deleted file mode 100644 index 8fbac9c33a..0000000000 --- a/.changeset/happy-peas-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -The `/clusters` API now surfaces cluster titles. diff --git a/.changeset/healthy-bees-deliver.md b/.changeset/healthy-bees-deliver.md deleted file mode 100644 index 80da17dc0b..0000000000 --- a/.changeset/healthy-bees-deliver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-common': patch ---- - -The `ClusterAttributes` type now includes the cluster title. diff --git a/.changeset/healthy-goats-jump.md b/.changeset/healthy-goats-jump.md deleted file mode 100644 index e5b43d3f8c..0000000000 --- a/.changeset/healthy-goats-jump.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-kubernetes-react': patch ---- - -The `ErrorReporting` component's cluster column now displays cluster titles when -specified. diff --git a/.changeset/hip-carrots-drive.md b/.changeset/hip-carrots-drive.md new file mode 100644 index 0000000000..5852916b74 --- /dev/null +++ b/.changeset/hip-carrots-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +The default `TokenManager` implementation no longer requires keys to be configured in production, but it will throw an errors when generating or authenticating tokens. The default `AuthService` implementation will now also provide additional context if such an error is throw when falling back to using the `TokenManager` service to generate tokens for outgoing requests. diff --git a/.changeset/hip-ears-add.md b/.changeset/hip-ears-add.md deleted file mode 100644 index 1e7f656507..0000000000 --- a/.changeset/hip-ears-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -The auth backend will now refuse to issue user tokens are excessively large. diff --git a/.changeset/honest-pets-judge.md b/.changeset/honest-pets-judge.md deleted file mode 100644 index 468fc1b6d5..0000000000 --- a/.changeset/honest-pets-judge.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-notifications-backend': patch -'@backstage/plugin-notifications-common': patch -'@backstage/plugin-notifications': patch ---- - -Add support for signal type in notifications diff --git a/.changeset/hot-forks-train.md b/.changeset/hot-forks-train.md new file mode 100644 index 0000000000..a5300085b6 --- /dev/null +++ b/.changeset/hot-forks-train.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +Allow showing notifications as snackbars in the UI diff --git a/.changeset/hot-horses-matter.md b/.changeset/hot-horses-matter.md deleted file mode 100644 index 1b544c0854..0000000000 --- a/.changeset/hot-horses-matter.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-search-backend-module-stack-overflow-collator': patch -'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-events-backend-module-bitbucket-cloud': patch -'@backstage/plugin-tech-insights-backend-module-jsonfc': patch -'@backstage/plugin-catalog-backend-module-unprocessed': patch -'@backstage/plugin-analytics-module-newrelic-browser': patch -'@backstage/plugin-scaffolder-backend-module-gitlab': patch -'@backstage/plugin-scaffolder-backend-module-sentry': patch -'@backstage/plugin-scaffolder-backend-module-yeoman': patch -'@backstage/plugin-catalog-backend-module-puppetdb': patch -'@backstage/plugin-scaffolder-backend-module-rails': patch -'@backstage/plugin-api-docs-module-protoc-gen-doc': patch -'@backstage/plugin-catalog-backend-module-msgraph': patch -'@backstage/plugin-catalog-backend-module-openapi': patch -'@backstage/plugin-search-backend-module-techdocs': patch -'@backstage/plugin-events-backend-module-aws-sqs': patch -'@backstage/plugin-search-backend-module-catalog': patch -'@backstage/plugin-search-backend-module-explore': patch -'@backstage/plugin-catalog-unprocessed-entities': patch -'@backstage/plugin-events-backend-module-gerrit': patch -'@backstage/plugin-events-backend-module-github': patch -'@backstage/plugin-events-backend-module-gitlab': patch -'@backstage/plugin-events-backend-module-azure': patch -'@backstage/plugin-entity-feedback-backend': patch -'@backstage/plugin-code-coverage-backend': patch -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-analytics-module-ga4': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/backend-plugin-api': patch -'@backstage/plugin-analytics-module-ga': patch -'@backstage/plugin-azure-sites-backend': patch -'@backstage/backend-dev-utils': patch -'@backstage/plugin-github-deployments': patch -'@backstage/plugin-lighthouse-backend': patch -'@backstage/plugin-microsoft-calendar': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/backend-defaults': patch -'@backstage/plugin-entity-validation': patch -'@backstage/plugin-sonarqube-backend': patch -'@backstage/backend-app-api': patch -'@backstage/plugin-devtools-backend': patch -'@backstage/plugin-linguist-backend': patch -'@backstage/plugin-playlist-backend': patch -'@backstage/backend-common': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-explore-backend': patch -'@backstage/plugin-graphql-voyager': patch -'@backstage/plugin-jenkins-backend': patch -'@backstage/plugin-rollbar-backend': patch -'@backstage/backend-tasks': patch -'@backstage/plugin-badges-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-events-backend': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-octopus-deploy': patch -'@backstage/plugin-splunk-on-call': patch -'@backstage/plugin-techdocs-react': patch -'@backstage/app-defaults': patch -'@backstage/core-app-api': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-nomad-backend': patch -'@backstage/plugin-tech-insights': patch -'@backstage/plugin-vault-backend': patch -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-code-climate': patch -'@backstage/plugin-adr-backend': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-azure-sites': patch -'@backstage/plugin-firehydrant': patch -'@backstage/plugin-lighthouse': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-tech-radar': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-dynatrace': patch -'@backstage/plugin-shortcuts': patch -'@backstage/plugin-sonarqube': patch -'@backstage/plugin-xcmetrics': patch -'@backstage/plugin-airbrake': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-linguist': patch -'@backstage/plugin-newrelic': patch -'@backstage/plugin-opencost': patch -'@backstage/plugin-periskop': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-rollbar': patch -'@backstage/plugin-allure': patch -'@backstage/plugin-badges': patch -'@backstage/plugin-bazaar': patch -'@backstage/plugin-sentry': patch -'@backstage/plugin-fossa': patch -'@backstage/plugin-ilert': patch -'@backstage/plugin-nomad': patch -'@backstage/plugin-vault': patch -'@backstage/plugin-home': patch ---- - -Use `--cwd` as the first `yarn` argument diff --git a/.changeset/hot-paws-tap.md b/.changeset/hot-paws-tap.md deleted file mode 100644 index 30d8b396ba..0000000000 --- a/.changeset/hot-paws-tap.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/catalog-model': patch -'@backstage/test-utils': patch -'@backstage/plugin-explore': patch ---- - -Fix wording in API reference diff --git a/.changeset/hot-pillows-poke.md b/.changeset/hot-pillows-poke.md deleted file mode 100644 index 8060e7121f..0000000000 --- a/.changeset/hot-pillows-poke.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-user-settings': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-tech-radar': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-search': patch ---- - -Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. diff --git a/.changeset/hot-tips-doubt.md b/.changeset/hot-tips-doubt.md deleted file mode 100644 index 464ddec302..0000000000 --- a/.changeset/hot-tips-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-openapi-utils': patch ---- - -Internal updates due to `json-schema-to-ts` diff --git a/.changeset/hungry-days-remain.md b/.changeset/hungry-days-remain.md deleted file mode 100644 index b0c3642a35..0000000000 --- a/.changeset/hungry-days-remain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/theme': patch ---- - -Fixed missing extra variables like `applyDarkStyles` in Mui V5 theme after calling `createUnifiedThemeFromV4` function diff --git a/.changeset/hungry-lions-sit.md b/.changeset/hungry-lions-sit.md deleted file mode 100644 index b283cc976f..0000000000 --- a/.changeset/hungry-lions-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch ---- - -Use the Gitbeaker library for `gitlab:projectAccessToken:create` action, enabling the `expiresAt` option diff --git a/.changeset/itchy-gorillas-hope.md b/.changeset/itchy-gorillas-hope.md new file mode 100644 index 0000000000..cd285161ff --- /dev/null +++ b/.changeset/itchy-gorillas-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Removed the Tech Radar and GitHub Actions plugins from the template, which have been moved to the community plugins repository. diff --git a/.changeset/itchy-keys-wonder.md b/.changeset/itchy-keys-wonder.md new file mode 100644 index 0000000000..879dc096a4 --- /dev/null +++ b/.changeset/itchy-keys-wonder.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +'@backstage/backend-app-api': patch +--- + +Redact `meta` fields too with the logger diff --git a/.changeset/khaki-seahorses-joke.md b/.changeset/khaki-seahorses-joke.md deleted file mode 100644 index 9382d6f108..0000000000 --- a/.changeset/khaki-seahorses-joke.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/integration-aws-node': patch -'@backstage/integration': patch ---- - -All single-line secrets read from config will now have both leading and trailing whitespace trimmed. This is done to ensure that the secrets are always valid HTTP header values, since many fetch implementations will include the header value itself when an error is thrown due to invalid header values. diff --git a/.changeset/kind-clouds-fly.md b/.changeset/kind-clouds-fly.md deleted file mode 100644 index 22aa7cda33..0000000000 --- a/.changeset/kind-clouds-fly.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes-node': patch ---- - -Enabled a way to include custom auth metadata info on the clusters endpoint. If you want to implement a Kubernetes auth strategy which requires surfacing custom auth metadata to the frontend, use the new presentAuthMetadata method on the AuthenticationStrategy interface. diff --git a/.changeset/kind-wombats-draw.md b/.changeset/kind-wombats-draw.md deleted file mode 100644 index 29a0e9da3c..0000000000 --- a/.changeset/kind-wombats-draw.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/core-plugin-api': minor -'@backstage/app-defaults': minor -'@backstage/core-app-api': minor -'@backstage/frontend-plugin-api': patch ---- - -Added a utility API for VMware Cloud auth; the API ref is available in the -`@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the -implementation is in `@backstage/core-app-api` and a factory has been added to -`@backstage/app-defaults`. diff --git a/.changeset/large-frogs-grab.md b/.changeset/large-frogs-grab.md deleted file mode 100644 index 2d36de3407..0000000000 --- a/.changeset/large-frogs-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Adding `supportedSubmitMethods` prop to `api-docs` to pass to the Swagger UI. This allows users to specify which HTTP methods they wish to allow end-users to make requests through the `Try It Out` button on the Swagger UI. diff --git a/.changeset/large-moons-speak.md b/.changeset/large-moons-speak.md deleted file mode 100644 index efd94c5df3..0000000000 --- a/.changeset/large-moons-speak.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/catalog-client': minor -'@backstage/plugin-catalog-backend': minor ---- - -Add API to get location by entity diff --git a/.changeset/large-tables-wonder.md b/.changeset/large-tables-wonder.md deleted file mode 100644 index 9c10f172a1..0000000000 --- a/.changeset/large-tables-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Add experimental support for an optional `public` app entry point that lets users sign-in before being able to access the full app. diff --git a/.changeset/late-planes-fix.md b/.changeset/late-planes-fix.md new file mode 100644 index 0000000000..a57d7ec1d4 --- /dev/null +++ b/.changeset/late-planes-fix.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-search-backend-node': patch +'@backstage/plugin-search-backend': patch +--- + +Add lifecycle monitoring for the search index registry diff --git a/.changeset/late-poets-love.md b/.changeset/late-poets-love.md deleted file mode 100644 index 03b975b2b5..0000000000 --- a/.changeset/late-poets-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Allow the `createConfigSecretEnumerator` to take an optional `schema` argument with an already-loaded global configuration schema. diff --git a/.changeset/lazy-dolls-roll.md b/.changeset/lazy-dolls-roll.md deleted file mode 100644 index da375727cc..0000000000 --- a/.changeset/lazy-dolls-roll.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-tasks': patch ---- - -The `TaskScheduler.fromConfig` method now accepts the `LegacyRootDatabaseService` interface rather than the full `DatabaseManager` implementation. diff --git a/.changeset/lemon-cameras-remember.md b/.changeset/lemon-cameras-remember.md deleted file mode 100644 index 29cd88602f..0000000000 --- a/.changeset/lemon-cameras-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Migrated oidc auth provider to new `@backstage/plugin-auth-backend-module-oidc-provider` module package. diff --git a/.changeset/long-stingrays-look.md b/.changeset/long-stingrays-look.md deleted file mode 100644 index f1df12169e..0000000000 --- a/.changeset/long-stingrays-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -Updated the paginated catalog table to support server side text filtering. diff --git a/.changeset/long-suns-bow.md b/.changeset/long-suns-bow.md deleted file mode 100644 index 81fafa8dae..0000000000 --- a/.changeset/long-suns-bow.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': minor -'@backstage/plugin-search-backend': minor -'@backstage/plugin-todo-backend': patch ---- - -Updates the OpenAPI spec to use plugin as `info.title` instead of package name. diff --git a/.changeset/long-wasps-wait.md b/.changeset/long-wasps-wait.md deleted file mode 100644 index f027fb97ce..0000000000 --- a/.changeset/long-wasps-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/config-loader': patch ---- - -Make schema processing gracefully handle an empty config. diff --git a/.changeset/loud-frogs-eat.md b/.changeset/loud-frogs-eat.md new file mode 100644 index 0000000000..dd1ab978f1 --- /dev/null +++ b/.changeset/loud-frogs-eat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Add examples for `gitlab:repo:push` scaffolder action & improve related tests diff --git a/.changeset/loud-vans-greet.md b/.changeset/loud-vans-greet.md new file mode 100644 index 0000000000..732413174b --- /dev/null +++ b/.changeset/loud-vans-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Internal refactor to only create one external token handler diff --git a/.changeset/loud-walls-compare.md b/.changeset/loud-walls-compare.md deleted file mode 100644 index 495ad933d9..0000000000 --- a/.changeset/loud-walls-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Fixed inconsistencies in icons used for System and Template diff --git a/.changeset/lovely-bugs-prove.md b/.changeset/lovely-bugs-prove.md deleted file mode 100644 index de55f329bb..0000000000 --- a/.changeset/lovely-bugs-prove.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@backstage/repo-tools': minor ---- - -**BREAKING**: The `schema openapi *` commands are now renamed into `package schema openapi *` and `repo schema openapi *`. The aim is to make it more clear what the command is operating on, the entire repo or just a single package. - -The following commands now live under the `package` namespace, - -- `schema openapi generate` is now `package schema openapi generate --server` -- `schema openapi generate-client` is now `package schema openapi generate --client-package` -- `schema openapi init` is now `package schema openapi init` - -And these commands live under the new `repo` namespace, - -- `schema openapi lint` is now `repo schema openapi lint` -- `schema openapi test` is now `repo schema openapi test` -- `schema openapi verify` is now `repo schema openapi verify` - -The `package schema openapi generate` now supports defining both `--server` and `--client-package` to generate both at once.This update also reworks the `--client-package` flag to accept only an output directory as the input directory can now be inferred. diff --git a/.changeset/lovely-games-cry.md b/.changeset/lovely-games-cry.md new file mode 100644 index 0000000000..5209b93496 --- /dev/null +++ b/.changeset/lovely-games-cry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-react': patch +--- + +When using `CookieAuthRefreshProvider` or `useCookieAuthRefresh`, a 404 response from the cookie endpoint will now be treated as if cookie auth is disabled and is not needed. diff --git a/.changeset/lovely-starfishes-remain.md b/.changeset/lovely-starfishes-remain.md deleted file mode 100644 index c57bfa0aaa..0000000000 --- a/.changeset/lovely-starfishes-remain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Removed alpha symbol from Task List header diff --git a/.changeset/lucky-bugs-bow.md b/.changeset/lucky-bugs-bow.md deleted file mode 100644 index ee17883408..0000000000 --- a/.changeset/lucky-bugs-bow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Add a seed file for `yarn.lock` in newly created apps. This file is downloaded directly from `https://github.com/backstage/backstage` at the time of creating a new project, ensuring that users always receive the latest version. The purpose of the seed file is to initialize the lock file with known good versions of individual dependencies that have had bad new releases published. The seed file will have no effect if the dependency is not present, it can not be used to install additional packages. diff --git a/.changeset/lucky-news-guess.md b/.changeset/lucky-news-guess.md new file mode 100644 index 0000000000..9c2cc4e8b0 --- /dev/null +++ b/.changeset/lucky-news-guess.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch +--- + +Add examples for `publish:bitbucketServer:pull-request` scaffolder action & improve related tests diff --git a/.changeset/many-pugs-change.md b/.changeset/many-pugs-change.md deleted file mode 100644 index 318c571891..0000000000 --- a/.changeset/many-pugs-change.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -The purpose of this patch is to add a new login method which is `googleServiceAccount` configuring the kubernetes properties in the app-config.yaml file with authProvider key diff --git a/.changeset/mean-apes-wait.md b/.changeset/mean-apes-wait.md deleted file mode 100644 index 838f1f2286..0000000000 --- a/.changeset/mean-apes-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch ---- - -Added `validateLocationsExist` to the config diff --git a/.changeset/metal-elephants-sit.md b/.changeset/metal-elephants-sit.md deleted file mode 100644 index 093936da3b..0000000000 --- a/.changeset/metal-elephants-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Introduced a new `MultiEntityPicker` field that supports selecting multiple Entities diff --git a/.changeset/metal-students-drive.md b/.changeset/metal-students-drive.md deleted file mode 100644 index 04f338c64e..0000000000 --- a/.changeset/metal-students-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-entity-validation': patch ---- - -Improves UX of the EntityValidationPage: Moves the validate button below the EntityTextArea which is actually validated, the location TextField can now be hidden to prevent confusion about what is validated and additional content can be added to the top of the validation page. diff --git a/.changeset/mighty-steaks-shave.md b/.changeset/mighty-steaks-shave.md deleted file mode 100644 index b85447e5c0..0000000000 --- a/.changeset/mighty-steaks-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped TypeScript to version `5.3`. diff --git a/.changeset/mighty-tomatoes-visit.md b/.changeset/mighty-tomatoes-visit.md deleted file mode 100644 index beb37d02ed..0000000000 --- a/.changeset/mighty-tomatoes-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -adds a x-goog-api-client header to existing API requests in this plugin to clearly identify API requests from this GKE plugin. headers are formatted as follows where `libVersion` represents the current dotted version number of the Backstage GKE plugin and `libName` represent the current Google API used at backstage. diff --git a/.changeset/mighty-toys-laugh.md b/.changeset/mighty-toys-laugh.md deleted file mode 100644 index ad48e84565..0000000000 --- a/.changeset/mighty-toys-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': minor ---- - -Add support to `configSchema` option on the `createEntityCardExtension` factory function. diff --git a/.changeset/modern-peaches-clean.md b/.changeset/modern-peaches-clean.md deleted file mode 100644 index 13dbb75183..0000000000 --- a/.changeset/modern-peaches-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Updated the default app index template at `packages/app/public/index.html` to have a fallback value for the `app.title` config. diff --git a/.changeset/nasty-days-jog.md b/.changeset/nasty-days-jog.md deleted file mode 100644 index 09454609b2..0000000000 --- a/.changeset/nasty-days-jog.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-aws-alb-provider': patch ---- - -Refactored to use the `jose` library for JWT handling. diff --git a/.changeset/nasty-shirts-look.md b/.changeset/nasty-shirts-look.md deleted file mode 100644 index 32213ee219..0000000000 --- a/.changeset/nasty-shirts-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Use EntityDisplayName JSX element entity information directly for FeaturedDocsCard. diff --git a/.changeset/nasty-suns-speak.md b/.changeset/nasty-suns-speak.md deleted file mode 100644 index 2c5fff25a1..0000000000 --- a/.changeset/nasty-suns-speak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Add an internal limiter on concurrency when launching processes diff --git a/.changeset/neat-eels-greet.md b/.changeset/neat-eels-greet.md deleted file mode 100644 index 5ba4777934..0000000000 --- a/.changeset/neat-eels-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-graph': minor ---- - -Migrate plugin to the new frontend system, it is experimental and available via alpha subpath. diff --git a/.changeset/neat-hotels-wink.md b/.changeset/neat-hotels-wink.md deleted file mode 100644 index fca82e38fa..0000000000 --- a/.changeset/neat-hotels-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -Added the option to provide custom `groupTransformer`, `userTransformer` and `groupNameTransformer` to allow custom transformations of groups and users diff --git a/.changeset/neat-kiwis-joke.md b/.changeset/neat-kiwis-joke.md deleted file mode 100644 index 852ec1d430..0000000000 --- a/.changeset/neat-kiwis-joke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Add a User-Agent header for calls towards Google Cloud Storage. diff --git a/.changeset/new-plants-rhyme.md b/.changeset/new-plants-rhyme.md deleted file mode 100644 index c901754069..0000000000 --- a/.changeset/new-plants-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Responses from the `/api/kubernetes/services/:serviceId` endpoint now include the cluster title. diff --git a/.changeset/nice-carrots-dream.md b/.changeset/nice-carrots-dream.md deleted file mode 100644 index 3b57dfd9e0..0000000000 --- a/.changeset/nice-carrots-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch ---- - -Decreased number of teams fetched by GraphQL Query responsible for fetching Teams and Members in organization, due to timeouts when running against big organizations diff --git a/.changeset/nine-bulldogs-camp.md b/.changeset/nine-bulldogs-camp.md deleted file mode 100644 index b6612b9948..0000000000 --- a/.changeset/nine-bulldogs-camp.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/catalog-client': minor -'@backstage/plugin-catalog-backend': minor -'@backstage/plugin-search-backend': minor -'@backstage/plugin-todo-backend': patch ---- - -Updates the OpenAPI specification title to plugin ID instead of package name. diff --git a/.changeset/nine-olives-swim.md b/.changeset/nine-olives-swim.md deleted file mode 100644 index 40852c08c2..0000000000 --- a/.changeset/nine-olives-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-node': minor ---- - -Added functions to clone a repo, create a branch, add files and push and commit to the branch. This allows for files to be added to the a PR for use in the bitbucket pull request action for issue #21762 diff --git a/.changeset/ninety-hats-kiss.md b/.changeset/ninety-hats-kiss.md deleted file mode 100644 index ff5ec770f7..0000000000 --- a/.changeset/ninety-hats-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-playlist': patch ---- - -Conditionally render playlist description only when it's non-empty diff --git a/.changeset/ninety-rules-sneeze.md b/.changeset/ninety-rules-sneeze.md deleted file mode 100644 index bea9d00f7e..0000000000 --- a/.changeset/ninety-rules-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Minor performance improvement for `queryEntities` when the limit is 0. diff --git a/.changeset/odd-beds-confess.md b/.changeset/odd-beds-confess.md deleted file mode 100644 index 5a766beb9d..0000000000 --- a/.changeset/odd-beds-confess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Replace uses of deprecated types with replacements internally. diff --git a/.changeset/old-papayas-shave.md b/.changeset/old-papayas-shave.md deleted file mode 100644 index 1372b9ce85..0000000000 --- a/.changeset/old-papayas-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -Wrap the root element with the analytics context to ensure it always exists for all extensions. diff --git a/.changeset/old-students-smoke.md b/.changeset/old-students-smoke.md deleted file mode 100644 index 8e072c5203..0000000000 --- a/.changeset/old-students-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-oidc-provider': minor ---- - -Created new `@backstage/plugin-auth-backend-module-oidc-provider` module package to house oidc auth provider migration. diff --git a/.changeset/olive-boats-agree.md b/.changeset/olive-boats-agree.md deleted file mode 100644 index e489476bcc..0000000000 --- a/.changeset/olive-boats-agree.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -'@backstage/core-app-api': patch -'@backstage/core-components': patch -'@backstage/core-plugin-api': patch -'@backstage/dev-utils': patch -'@backstage/frontend-app-api': patch -'@backstage/frontend-plugin-api': patch -'@backstage/plugin-adr': patch -'@backstage/plugin-airbrake': patch -'@backstage/plugin-allure': patch -'@backstage/plugin-apache-airflow': patch -'@backstage/plugin-api-docs-module-protoc-gen-doc': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-apollo-explorer': patch -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-azure-sites': patch -'@backstage/plugin-badges': patch -'@backstage/plugin-bazaar': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-catalog-unprocessed-entities': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-cloudbuild': patch -'@backstage/plugin-code-climate': patch -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-config-schema': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-dynatrace': patch -'@backstage/plugin-entity-feedback': patch -'@backstage/plugin-entity-validation': patch -'@backstage/plugin-explore': 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-github-issues': patch -'@backstage/plugin-github-pull-requests-board': patch -'@backstage/plugin-gitops-profiles': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-graphql-voyager': patch -'@backstage/plugin-home': patch -'@backstage/plugin-ilert': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-kafka': patch -'@backstage/plugin-kubernetes-cluster': patch -'@backstage/plugin-kubernetes-react': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-lighthouse': patch -'@backstage/plugin-linguist': patch -'@backstage/plugin-microsoft-calendar': patch -'@backstage/plugin-newrelic-dashboard': patch -'@backstage/plugin-newrelic': patch -'@backstage/plugin-nomad': patch -'@backstage/plugin-octopus-deploy': patch -'@backstage/plugin-opencost': patch -'@backstage/plugin-org-react': patch -'@backstage/plugin-org': patch -'@backstage/plugin-pagerduty': patch -'@backstage/plugin-periskop': patch -'@backstage/plugin-permission-react': patch -'@backstage/plugin-playlist': patch -'@backstage/plugin-puppetdb': patch -'@backstage/plugin-rollbar': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-search-react': 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-stackstorm': patch -'@backstage/plugin-tech-insights': patch -'@backstage/plugin-tech-radar': patch -'@backstage/plugin-techdocs-addons-test-utils': patch -'@backstage/plugin-techdocs-react': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-vault': patch -'@backstage/plugin-xcmetrics': patch -'@backstage/test-utils': patch -'@backstage/theme': patch ---- - -Widen `@types/react` dependency range to include version 18. diff --git a/.changeset/olive-experts-fold.md b/.changeset/olive-experts-fold.md deleted file mode 100644 index 29b9bfc28f..0000000000 --- a/.changeset/olive-experts-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Rollback the change for wildcard discovery, this fixes a bug with the `AzureUrlReader` not working with wildcard paths diff --git a/.changeset/olive-singers-accept.md b/.changeset/olive-singers-accept.md deleted file mode 100644 index 7e8cf7ae8d..0000000000 --- a/.changeset/olive-singers-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -Added `convertLegacyRouteRefs` for bulk conversion of plugin routes. diff --git a/.changeset/orange-gorillas-clean.md b/.changeset/orange-gorillas-clean.md deleted file mode 100644 index d346adce6c..0000000000 --- a/.changeset/orange-gorillas-clean.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-tech-insights-node': patch ---- - -Move `FactRetrieverRegistry` and `PersistenceContext` to `@backstage/plugin-tech-insights-node`. - -Original exports are marked as deprecated and re-export the moved types. - -Please replace uses like - -```ts -import { - FactRetrieverRegistry, - PersistenceContext, -} from '@backstage/plugin-tech-insights-backend'; -``` - -with - -```ts -import { - FactRetrieverRegistry, - PersistenceContext, -} from '@backstage/plugin-tech-insights-node'; -``` diff --git a/.changeset/orange-numbers-think.md b/.changeset/orange-numbers-think.md new file mode 100644 index 0000000000..21dc7ce76b --- /dev/null +++ b/.changeset/orange-numbers-think.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-catalog': patch +--- + +Fix wiring of the module exported at the `/alpha` path, which was causing authentication failures. diff --git a/.changeset/orange-suns-yell.md b/.changeset/orange-suns-yell.md deleted file mode 100644 index f7314411eb..0000000000 --- a/.changeset/orange-suns-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -Add entity warning components to the default entity overview page. diff --git a/.changeset/orange-walls-complain.md b/.changeset/orange-walls-complain.md deleted file mode 100644 index 477d42d913..0000000000 --- a/.changeset/orange-walls-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Add line clamping to `CatalogSearchResultListItem` diff --git a/.changeset/perfect-colts-hammer.md b/.changeset/perfect-colts-hammer.md deleted file mode 100644 index 616bcbda6f..0000000000 --- a/.changeset/perfect-colts-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Organized imports in plugin.ts diff --git a/.changeset/perfect-points-hope.md b/.changeset/perfect-points-hope.md new file mode 100644 index 0000000000..cfc42f77a3 --- /dev/null +++ b/.changeset/perfect-points-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-oidc-provider': patch +--- + +Add nonce to authorize request to be added in ID token diff --git a/.changeset/polite-meals-hug.md b/.changeset/polite-meals-hug.md deleted file mode 100644 index 664f450c6d..0000000000 --- a/.changeset/polite-meals-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-stack-overflow': patch ---- - -Fixes a bug that made the API return questions not related to the tags provided diff --git a/.changeset/poor-jeans-rescue.md b/.changeset/poor-jeans-rescue.md deleted file mode 100644 index e44b9c6bc6..0000000000 --- a/.changeset/poor-jeans-rescue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Make `http://localhost:3000` the default base URL for serving locally, and `/` the default public path for built apps. The app build no longer requires any configuration values to be present. diff --git a/.changeset/poor-points-do.md b/.changeset/poor-points-do.md deleted file mode 100644 index 198ef24c83..0000000000 --- a/.changeset/poor-points-do.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-scaffolder-entity-model': patch -'@backstage/plugin-search-backend-module-stack-overflow-collator': patch -'@backstage/plugin-permission-backend-module-allow-all-policy': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch -'@backstage/plugin-auth-backend-module-oauth2-proxy-provider': patch -'@backstage/plugin-auth-backend-module-vmware-cloud-provider': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch -'@backstage/plugin-catalog-backend-module-backstage-openapi': patch -'@backstage/plugin-auth-backend-module-atlassian-provider': patch -'@backstage/plugin-auth-backend-module-microsoft-provider': patch -'@backstage/plugin-auth-backend-module-pinniped-provider': patch -'@backstage/plugin-auth-backend-module-github-provider': patch -'@backstage/plugin-auth-backend-module-gitlab-provider': patch -'@backstage/plugin-auth-backend-module-oauth2-provider': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch -'@backstage/plugin-analytics-module-newrelic-browser': patch -'@backstage/plugin-auth-backend-module-oidc-provider': patch -'@backstage/plugin-auth-backend-module-okta-provider': patch -'@backstage/plugin-catalog-backend-module-github-org': patch -'@backstage/backend-dynamic-feature-service': patch -'@backstage/plugin-scaffolder-backend-module-gerrit': patch -'@backstage/plugin-scaffolder-backend-module-github': patch -'@backstage/plugin-scaffolder-backend-module-azure': patch -'@backstage/plugin-notifications-backend': patch -'@backstage/frontend-test-utils': patch -'@backstage/plugin-analytics-module-ga4': patch -'@backstage/plugin-notifications-common': patch -'@backstage/plugin-notifications-node': patch -'@backstage/frontend-app-api': patch -'@backstage/plugin-kubernetes-react': patch -'@backstage/e2e-test-utils': patch -'@backstage/plugin-kubernetes-node': patch -'@backstage/plugin-signals-backend': patch -'@backstage/plugin-app-visualizer': patch -'@backstage/plugin-notifications': patch -'@backstage/plugin-signals-react': patch -'@backstage/plugin-vault-backend': patch -'@backstage/plugin-signals-node': patch -'@backstage/plugin-vault-node': patch -'@backstage/plugin-app-node': patch -'@backstage/plugin-opencost': patch -'@backstage/plugin-signals': patch ---- - -Added or fixed the `repository` field in `package.json`. diff --git a/.changeset/pre.json b/.changeset/pre.json index 80baf3d416..809cd51567 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,507 +1,337 @@ { - "mode": "exit", + "mode": "pre", "tag": "next", "initialVersions": { - "example-app": "0.2.91", - "@backstage/app-defaults": "1.4.7", - "example-app-next": "0.0.5", - "app-next-example-plugin": "0.0.5", - "example-backend": "0.2.91", - "@backstage/backend-app-api": "0.5.10", - "@backstage/backend-common": "0.20.1", - "@backstage/backend-defaults": "0.2.9", - "@backstage/backend-dev-utils": "0.1.3", - "@backstage/backend-dynamic-feature-service": "0.1.0", - "example-backend-next": "0.0.19", - "@backstage/backend-openapi-utils": "0.1.2", - "@backstage/backend-plugin-api": "0.6.9", - "@backstage/backend-tasks": "0.5.14", - "@backstage/backend-test-utils": "0.2.10", - "@backstage/catalog-client": "1.5.2", - "@backstage/catalog-model": "1.4.3", - "@backstage/cli": "0.25.1", + "example-app": "0.2.96", + "@backstage/app-defaults": "1.5.4", + "example-app-next": "0.0.10", + "app-next-example-plugin": "0.0.10", + "example-backend": "0.2.97", + "@backstage/backend-app-api": "0.7.0", + "@backstage/backend-common": "0.21.7", + "@backstage/backend-defaults": "0.2.17", + "@backstage/backend-dev-utils": "0.1.4", + "@backstage/backend-dynamic-feature-service": "0.2.9", + "example-backend-next": "0.0.25", + "@backstage/backend-openapi-utils": "0.1.10", + "@backstage/backend-plugin-api": "0.6.17", + "@backstage/backend-tasks": "0.5.22", + "@backstage/backend-test-utils": "0.3.7", + "@backstage/catalog-client": "1.6.4", + "@backstage/catalog-model": "1.4.5", + "@backstage/cli": "0.26.3", "@backstage/cli-common": "0.1.13", - "@backstage/cli-node": "0.2.2", - "@backstage/codemods": "0.1.46", - "@backstage/config": "1.1.1", - "@backstage/config-loader": "1.6.1", - "@backstage/core-app-api": "1.11.3", - "@backstage/core-compat-api": "0.1.1", - "@backstage/core-components": "0.13.10", - "@backstage/core-plugin-api": "1.8.2", - "@backstage/create-app": "0.5.9", - "@backstage/dev-utils": "1.0.26", - "e2e-test": "0.2.11", - "@backstage/e2e-test-utils": "0.1.0", - "@backstage/errors": "1.2.3", - "@backstage/eslint-plugin": "0.1.4", - "@backstage/frontend-app-api": "0.5.0", - "@backstage/frontend-plugin-api": "0.5.0", - "@backstage/frontend-test-utils": "0.1.1", - "@backstage/integration": "1.8.0", - "@backstage/integration-aws-node": "0.1.8", - "@backstage/integration-react": "1.1.23", + "@backstage/cli-node": "0.2.5", + "@backstage/codemods": "0.1.48", + "@backstage/config": "1.2.0", + "@backstage/config-loader": "1.8.0", + "@backstage/core-app-api": "1.12.4", + "@backstage/core-compat-api": "0.2.4", + "@backstage/core-components": "0.14.4", + "@backstage/core-plugin-api": "1.9.2", + "@backstage/create-app": "0.5.14", + "@backstage/dev-utils": "1.0.31", + "e2e-test": "0.2.15", + "@backstage/e2e-test-utils": "0.1.1", + "@backstage/errors": "1.2.4", + "@backstage/eslint-plugin": "0.1.7", + "@backstage/frontend-app-api": "0.6.4", + "@backstage/frontend-plugin-api": "0.6.4", + "@backstage/frontend-test-utils": "0.1.6", + "@backstage/integration": "1.10.0", + "@backstage/integration-aws-node": "0.1.12", + "@backstage/integration-react": "1.1.26", "@backstage/release-manifests": "0.0.11", - "@backstage/repo-tools": "0.5.2", - "@techdocs/cli": "1.8.1", - "techdocs-cli-embedded-app": "0.2.90", - "@backstage/test-utils": "1.4.7", - "@backstage/theme": "0.5.0", + "@backstage/repo-tools": "0.8.0", + "@techdocs/cli": "1.8.9", + "techdocs-cli-embedded-app": "0.2.95", + "@backstage/test-utils": "1.5.4", + "@backstage/theme": "0.5.3", "@backstage/types": "1.1.1", - "@backstage/version-bridge": "1.0.7", - "@backstage/plugin-adr": "0.6.12", - "@backstage/plugin-adr-backend": "0.4.6", - "@backstage/plugin-adr-common": "0.2.19", - "@backstage/plugin-airbrake": "0.3.29", - "@backstage/plugin-airbrake-backend": "0.3.6", - "@backstage/plugin-allure": "0.1.45", - "@backstage/plugin-analytics-module-ga": "0.1.37", - "@backstage/plugin-analytics-module-ga4": "0.1.8", - "@backstage/plugin-analytics-module-newrelic-browser": "0.0.6", - "@backstage/plugin-apache-airflow": "0.2.19", - "@backstage/plugin-api-docs": "0.10.3", - "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.5", - "@backstage/plugin-apollo-explorer": "0.1.19", - "@backstage/plugin-app-backend": "0.3.57", - "@backstage/plugin-app-node": "0.1.9", - "@backstage/plugin-app-visualizer": "0.1.0", - "@backstage/plugin-auth-backend": "0.20.3", - "@backstage/plugin-auth-backend-module-atlassian-provider": "0.1.1", - "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-github-provider": "0.1.6", - "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.6", - "@backstage/plugin-auth-backend-module-google-provider": "0.1.6", - "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.4", - "@backstage/plugin-auth-backend-module-oauth2-provider": "0.1.6", - "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.1", - "@backstage/plugin-auth-backend-module-okta-provider": "0.0.2", - "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.3", - "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.1.1", - "@backstage/plugin-auth-node": "0.4.3", - "@backstage/plugin-azure-devops": "0.3.11", - "@backstage/plugin-azure-devops-backend": "0.5.1", - "@backstage/plugin-azure-devops-common": "0.3.2", - "@backstage/plugin-azure-sites": "0.1.18", - "@backstage/plugin-azure-sites-backend": "0.1.19", - "@backstage/plugin-azure-sites-common": "0.1.1", - "@backstage/plugin-badges": "0.2.53", - "@backstage/plugin-badges-backend": "0.3.6", - "@backstage/plugin-bazaar": "0.2.21", - "@backstage/plugin-bazaar-backend": "0.3.7", - "@backstage/plugin-bitbucket-cloud-common": "0.2.15", - "@backstage/plugin-bitrise": "0.1.56", - "@backstage/plugin-catalog": "1.16.1", - "@backstage/plugin-catalog-backend": "1.16.1", - "@backstage/plugin-catalog-backend-module-aws": "0.3.3", - "@backstage/plugin-catalog-backend-module-azure": "0.1.28", - "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.1.2", - "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.24", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.24", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.22", - "@backstage/plugin-catalog-backend-module-gcp": "0.1.9", - "@backstage/plugin-catalog-backend-module-gerrit": "0.1.25", - "@backstage/plugin-catalog-backend-module-github": "0.4.7", - "@backstage/plugin-catalog-backend-module-github-org": "0.1.3", - "@backstage/plugin-catalog-backend-module-gitlab": "0.3.6", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.4.13", - "@backstage/plugin-catalog-backend-module-ldap": "0.5.24", - "@backstage/plugin-catalog-backend-module-msgraph": "0.5.16", - "@backstage/plugin-catalog-backend-module-openapi": "0.1.26", - "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.14", - "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.6", - "@backstage/plugin-catalog-backend-module-unprocessed": "0.3.6", - "@backstage/plugin-catalog-common": "1.0.20", - "@backstage/plugin-catalog-graph": "0.3.3", - "@backstage/plugin-catalog-import": "0.10.5", - "@backstage/plugin-catalog-node": "1.6.1", - "@backstage/plugin-catalog-react": "1.9.3", - "@backstage/plugin-catalog-unprocessed-entities": "0.1.7", - "@backstage/plugin-cicd-statistics": "0.1.31", - "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.25", - "@backstage/plugin-circleci": "0.3.29", - "@backstage/plugin-cloudbuild": "0.3.29", - "@backstage/plugin-code-climate": "0.1.29", - "@backstage/plugin-code-coverage": "0.2.22", - "@backstage/plugin-code-coverage-backend": "0.2.23", - "@backstage/plugin-codescene": "0.1.21", - "@backstage/plugin-config-schema": "0.1.49", - "@backstage/plugin-cost-insights": "0.12.18", + "@backstage/version-bridge": "1.0.8", + "@backstage/plugin-adr": "0.6.17", + "@backstage/plugin-adr-backend": "0.4.14", + "@backstage/plugin-adr-common": "0.2.22", + "@backstage/plugin-airbrake": "0.3.34", + "@backstage/plugin-airbrake-backend": "0.3.14", + "@backstage/plugin-allure": "0.1.50", + "@backstage/plugin-analytics-module-ga": "0.2.4", + "@backstage/plugin-analytics-module-ga4": "0.2.4", + "@backstage/plugin-analytics-module-newrelic-browser": "0.1.4", + "@backstage/plugin-apache-airflow": "0.2.24", + "@backstage/plugin-api-docs": "0.11.4", + "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.6", + "@backstage/plugin-apollo-explorer": "0.2.0", + "@backstage/plugin-app-backend": "0.3.65", + "@backstage/plugin-app-node": "0.1.17", + "@backstage/plugin-app-visualizer": "0.1.5", + "@backstage/plugin-auth-backend": "0.22.4", + "@backstage/plugin-auth-backend-module-atlassian-provider": "0.1.9", + "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.1.9", + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.1.0", + "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.1.0", + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.1.0", + "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.2.12", + "@backstage/plugin-auth-backend-module-github-provider": "0.1.14", + "@backstage/plugin-auth-backend-module-gitlab-provider": "0.1.14", + "@backstage/plugin-auth-backend-module-google-provider": "0.1.14", + "@backstage/plugin-auth-backend-module-guest-provider": "0.1.3", + "@backstage/plugin-auth-backend-module-microsoft-provider": "0.1.12", + "@backstage/plugin-auth-backend-module-oauth2-provider": "0.1.14", + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.1.10", + "@backstage/plugin-auth-backend-module-oidc-provider": "0.1.8", + "@backstage/plugin-auth-backend-module-okta-provider": "0.0.10", + "@backstage/plugin-auth-backend-module-pinniped-provider": "0.1.11", + "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.1.9", + "@backstage/plugin-auth-node": "0.4.12", + "@backstage/plugin-auth-react": "0.1.0", + "@backstage/plugin-azure-devops": "0.4.3", + "@backstage/plugin-azure-devops-backend": "0.6.4", + "@backstage/plugin-azure-devops-common": "0.4.1", + "@backstage/plugin-azure-sites": "0.1.23", + "@backstage/plugin-azure-sites-backend": "0.3.4", + "@backstage/plugin-azure-sites-common": "0.1.3", + "@backstage/plugin-badges": "0.2.58", + "@backstage/plugin-badges-backend": "0.4.0", + "@backstage/plugin-bazaar": "0.2.26", + "@backstage/plugin-bazaar-backend": "0.3.15", + "@backstage/plugin-bitbucket-cloud-common": "0.2.18", + "@backstage/plugin-bitrise": "0.1.61", + "@backstage/plugin-catalog": "1.19.0", + "@backstage/plugin-catalog-backend": "1.21.1", + "@backstage/plugin-catalog-backend-module-aws": "0.3.12", + "@backstage/plugin-catalog-backend-module-azure": "0.1.37", + "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.2.0", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.2.4", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.31", + "@backstage/plugin-catalog-backend-module-gcp": "0.1.18", + "@backstage/plugin-catalog-backend-module-gerrit": "0.1.34", + "@backstage/plugin-catalog-backend-module-github": "0.6.0", + "@backstage/plugin-catalog-backend-module-github-org": "0.1.12", + "@backstage/plugin-catalog-backend-module-gitlab": "0.3.15", + "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.4.22", + "@backstage/plugin-catalog-backend-module-ldap": "0.5.33", + "@backstage/plugin-catalog-backend-module-msgraph": "0.5.25", + "@backstage/plugin-catalog-backend-module-openapi": "0.1.35", + "@backstage/plugin-catalog-backend-module-puppetdb": "0.1.23", + "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.1.15", + "@backstage/plugin-catalog-backend-module-unprocessed": "0.4.4", + "@backstage/plugin-catalog-common": "1.0.22", + "@backstage/plugin-catalog-graph": "0.4.4", + "@backstage/plugin-catalog-import": "0.10.10", + "@backstage/plugin-catalog-node": "1.11.1", + "@backstage/plugin-catalog-react": "1.11.3", + "@backstage/plugin-catalog-unprocessed-entities": "0.2.3", + "@backstage/plugin-catalog-unprocessed-entities-common": "0.0.1", + "@backstage/plugin-cicd-statistics": "0.1.36", + "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.30", + "@backstage/plugin-circleci": "0.3.34", + "@backstage/plugin-cloudbuild": "0.5.1", + "@backstage/plugin-code-climate": "0.1.34", + "@backstage/plugin-code-coverage": "0.2.27", + "@backstage/plugin-code-coverage-backend": "0.2.31", + "@backstage/plugin-codescene": "0.1.26", + "@backstage/plugin-config-schema": "0.1.54", + "@backstage/plugin-cost-insights": "0.12.23", "@backstage/plugin-cost-insights-common": "0.1.2", - "@backstage/plugin-devtools": "0.1.8", - "@backstage/plugin-devtools-backend": "0.2.6", - "@backstage/plugin-devtools-common": "0.1.8", - "@backstage/plugin-dynatrace": "8.0.3", - "@backstage/plugin-entity-feedback": "0.2.12", - "@backstage/plugin-entity-feedback-backend": "0.2.6", + "@backstage/plugin-devtools": "0.1.13", + "@backstage/plugin-devtools-backend": "0.3.3", + "@backstage/plugin-devtools-common": "0.1.9", + "@backstage/plugin-dynatrace": "10.0.3", + "@backstage/plugin-entity-feedback": "0.2.17", + "@backstage/plugin-entity-feedback-backend": "0.2.14", "@backstage/plugin-entity-feedback-common": "0.1.3", - "@backstage/plugin-entity-validation": "0.1.14", - "@backstage/plugin-events-backend": "0.2.18", - "@backstage/plugin-events-backend-module-aws-sqs": "0.2.12", - "@backstage/plugin-events-backend-module-azure": "0.1.19", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.19", - "@backstage/plugin-events-backend-module-gerrit": "0.1.19", - "@backstage/plugin-events-backend-module-github": "0.1.19", - "@backstage/plugin-events-backend-module-gitlab": "0.1.19", - "@backstage/plugin-events-backend-test-utils": "0.1.19", - "@backstage/plugin-events-node": "0.2.18", - "@internal/plugin-todo-list": "1.0.21", - "@internal/plugin-todo-list-backend": "1.0.21", - "@internal/plugin-todo-list-common": "1.0.17", - "@backstage/plugin-explore": "0.4.15", - "@backstage/plugin-explore-backend": "0.0.19", + "@backstage/plugin-entity-validation": "0.1.19", + "@backstage/plugin-events-backend": "0.3.4", + "@backstage/plugin-events-backend-module-aws-sqs": "0.3.3", + "@backstage/plugin-events-backend-module-azure": "0.2.3", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.3", + "@backstage/plugin-events-backend-module-gerrit": "0.2.3", + "@backstage/plugin-events-backend-module-github": "0.2.3", + "@backstage/plugin-events-backend-module-gitlab": "0.2.3", + "@backstage/plugin-events-backend-test-utils": "0.1.27", + "@backstage/plugin-events-node": "0.3.3", + "@internal/plugin-todo-list": "1.0.26", + "@internal/plugin-todo-list-backend": "1.0.26", + "@internal/plugin-todo-list-common": "1.0.18", + "@backstage/plugin-explore": "0.4.20", + "@backstage/plugin-explore-backend": "0.0.27", "@backstage/plugin-explore-common": "0.0.2", - "@backstage/plugin-explore-react": "0.0.35", - "@backstage/plugin-firehydrant": "0.2.13", - "@backstage/plugin-fossa": "0.2.61", - "@backstage/plugin-gcalendar": "0.3.22", - "@backstage/plugin-gcp-projects": "0.3.45", - "@backstage/plugin-git-release-manager": "0.3.41", - "@backstage/plugin-github-actions": "0.6.10", - "@backstage/plugin-github-deployments": "0.1.60", - "@backstage/plugin-github-issues": "0.2.18", - "@backstage/plugin-github-pull-requests-board": "0.1.23", - "@backstage/plugin-gitops-profiles": "0.3.44", - "@backstage/plugin-gocd": "0.1.35", - "@backstage/plugin-graphiql": "0.3.2", - "@backstage/plugin-graphql-voyager": "0.1.11", - "@backstage/plugin-home": "0.6.1", - "@backstage/plugin-home-react": "0.1.7", - "@backstage/plugin-ilert": "0.2.18", - "@backstage/plugin-jenkins": "0.9.4", - "@backstage/plugin-jenkins-backend": "0.3.3", - "@backstage/plugin-jenkins-common": "0.1.23", - "@backstage/plugin-kafka": "0.3.29", - "@backstage/plugin-kafka-backend": "0.3.7", - "@backstage/plugin-kubernetes": "0.11.4", - "@backstage/plugin-kubernetes-backend": "0.14.1", - "@backstage/plugin-kubernetes-cluster": "0.0.5", - "@backstage/plugin-kubernetes-common": "0.7.3", - "@backstage/plugin-kubernetes-node": "0.1.3", - "@backstage/plugin-kubernetes-react": "0.2.1", - "@backstage/plugin-lighthouse": "0.4.14", - "@backstage/plugin-lighthouse-backend": "0.4.1", - "@backstage/plugin-lighthouse-common": "0.1.4", - "@backstage/plugin-linguist": "0.1.14", - "@backstage/plugin-linguist-backend": "0.5.6", + "@backstage/plugin-explore-react": "0.0.38", + "@backstage/plugin-firehydrant": "0.2.18", + "@backstage/plugin-fossa": "0.2.66", + "@backstage/plugin-gcalendar": "0.3.27", + "@backstage/plugin-gcp-projects": "0.3.50", + "@backstage/plugin-git-release-manager": "0.3.46", + "@backstage/plugin-github-actions": "0.6.15", + "@backstage/plugin-github-deployments": "0.1.65", + "@backstage/plugin-github-issues": "0.4.1", + "@backstage/plugin-github-pull-requests-board": "0.2.0", + "@backstage/plugin-gitops-profiles": "0.3.49", + "@backstage/plugin-gocd": "0.1.40", + "@backstage/plugin-graphiql": "0.3.7", + "@backstage/plugin-graphql-voyager": "0.1.16", + "@backstage/plugin-home": "0.7.3", + "@backstage/plugin-home-react": "0.1.12", + "@backstage/plugin-ilert": "0.2.23", + "@backstage/plugin-jenkins": "0.9.9", + "@backstage/plugin-jenkins-backend": "0.4.4", + "@backstage/plugin-jenkins-common": "0.1.25", + "@backstage/plugin-kafka": "0.3.34", + "@backstage/plugin-kafka-backend": "0.3.15", + "@backstage/plugin-kubernetes": "0.11.9", + "@backstage/plugin-kubernetes-backend": "0.17.0", + "@backstage/plugin-kubernetes-cluster": "0.0.10", + "@backstage/plugin-kubernetes-common": "0.7.5", + "@backstage/plugin-kubernetes-node": "0.1.11", + "@backstage/plugin-kubernetes-react": "0.3.4", + "@backstage/plugin-lighthouse": "0.4.19", + "@backstage/plugin-lighthouse-backend": "0.4.10", + "@backstage/plugin-lighthouse-common": "0.1.5", + "@backstage/plugin-linguist": "0.1.19", + "@backstage/plugin-linguist-backend": "0.5.15", "@backstage/plugin-linguist-common": "0.1.2", - "@backstage/plugin-microsoft-calendar": "0.1.11", - "@backstage/plugin-newrelic": "0.3.44", - "@backstage/plugin-newrelic-dashboard": "0.3.4", - "@backstage/plugin-nomad": "0.1.10", - "@backstage/plugin-nomad-backend": "0.1.11", - "@backstage/plugin-octopus-deploy": "0.2.11", - "@backstage/plugin-opencost": "0.2.4", - "@backstage/plugin-org": "0.6.19", - "@backstage/plugin-org-react": "0.1.18", - "@backstage/plugin-pagerduty": "0.7.1", - "@backstage/plugin-periskop": "0.1.27", - "@backstage/plugin-periskop-backend": "0.2.7", - "@backstage/plugin-permission-backend": "0.5.32", - "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.6", - "@backstage/plugin-permission-common": "0.7.12", - "@backstage/plugin-permission-node": "0.7.20", - "@backstage/plugin-permission-react": "0.4.19", - "@backstage/plugin-playlist": "0.2.3", - "@backstage/plugin-playlist-backend": "0.3.13", - "@backstage/plugin-playlist-common": "0.1.14", - "@backstage/plugin-proxy-backend": "0.4.7", - "@backstage/plugin-puppetdb": "0.1.12", - "@backstage/plugin-rollbar": "0.4.29", - "@backstage/plugin-rollbar-backend": "0.1.54", - "@backstage/plugin-scaffolder": "1.17.1", - "@backstage/plugin-scaffolder-backend": "1.20.0", - "@backstage/plugin-scaffolder-backend-module-azure": "0.1.1", - "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.1.1", - "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.10", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.33", - "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.1", - "@backstage/plugin-scaffolder-backend-module-github": "0.1.1", - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.2.12", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.26", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.17", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.30", - "@backstage/plugin-scaffolder-common": "1.4.5", - "@backstage/plugin-scaffolder-node": "0.2.10", - "@backstage/plugin-scaffolder-react": "1.7.1", - "@backstage/plugin-search": "1.4.5", - "@backstage/plugin-search-backend": "1.4.9", - "@backstage/plugin-search-backend-module-catalog": "0.1.13", - "@backstage/plugin-search-backend-module-elasticsearch": "1.3.12", - "@backstage/plugin-search-backend-module-explore": "0.1.13", - "@backstage/plugin-search-backend-module-pg": "0.5.18", - "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.1.2", - "@backstage/plugin-search-backend-module-techdocs": "0.1.13", - "@backstage/plugin-search-backend-node": "1.2.13", - "@backstage/plugin-search-common": "1.2.10", - "@backstage/plugin-search-react": "1.7.5", - "@backstage/plugin-sentry": "0.5.14", - "@backstage/plugin-shortcuts": "0.3.18", - "@backstage/plugin-sonarqube": "0.7.11", - "@backstage/plugin-sonarqube-backend": "0.2.11", - "@backstage/plugin-sonarqube-react": "0.1.12", - "@backstage/plugin-splunk-on-call": "0.4.18", - "@backstage/plugin-stack-overflow": "0.1.24", - "@backstage/plugin-stack-overflow-backend": "0.2.13", - "@backstage/plugin-stackstorm": "0.1.10", - "@backstage/plugin-tech-insights": "0.3.21", - "@backstage/plugin-tech-insights-backend": "0.5.23", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.41", + "@backstage/plugin-microsoft-calendar": "0.1.16", + "@backstage/plugin-newrelic": "0.3.49", + "@backstage/plugin-newrelic-dashboard": "0.3.9", + "@backstage/plugin-nomad": "0.1.15", + "@backstage/plugin-nomad-backend": "0.1.19", + "@backstage/plugin-notifications": "0.2.0", + "@backstage/plugin-notifications-backend": "0.2.0", + "@backstage/plugin-notifications-common": "0.0.3", + "@backstage/plugin-notifications-node": "0.1.3", + "@backstage/plugin-octopus-deploy": "0.2.16", + "@backstage/plugin-opencost": "0.2.9", + "@backstage/plugin-org": "0.6.24", + "@backstage/plugin-org-react": "0.1.23", + "@backstage/plugin-pagerduty": "0.7.6", + "@backstage/plugin-periskop": "0.1.32", + "@backstage/plugin-periskop-backend": "0.2.15", + "@backstage/plugin-permission-backend": "0.5.41", + "@backstage/plugin-permission-backend-module-allow-all-policy": "0.1.14", + "@backstage/plugin-permission-common": "0.7.13", + "@backstage/plugin-permission-node": "0.7.28", + "@backstage/plugin-permission-react": "0.4.22", + "@backstage/plugin-playlist": "0.2.8", + "@backstage/plugin-playlist-backend": "0.3.21", + "@backstage/plugin-playlist-common": "0.1.15", + "@backstage/plugin-proxy-backend": "0.4.15", + "@backstage/plugin-puppetdb": "0.1.17", + "@backstage/plugin-rollbar": "0.4.34", + "@backstage/plugin-rollbar-backend": "0.1.62", + "@backstage/plugin-scaffolder": "1.19.3", + "@backstage/plugin-scaffolder-backend": "1.22.4", + "@backstage/plugin-scaffolder-backend-module-azure": "0.1.9", + "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.2.7", + "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.1.7", + "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.1.7", + "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.2.18", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.41", + "@backstage/plugin-scaffolder-backend-module-gerrit": "0.1.9", + "@backstage/plugin-scaffolder-backend-module-gitea": "0.1.7", + "@backstage/plugin-scaffolder-backend-module-github": "0.2.7", + "@backstage/plugin-scaffolder-backend-module-gitlab": "0.3.3", + "@backstage/plugin-scaffolder-backend-module-rails": "0.4.34", + "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.25", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.3.0", + "@backstage/plugin-scaffolder-common": "1.5.1", + "@backstage/plugin-scaffolder-node": "0.4.3", + "@backstage/plugin-scaffolder-node-test-utils": "0.1.3", + "@backstage/plugin-scaffolder-react": "1.8.4", + "@backstage/plugin-search": "1.4.10", + "@backstage/plugin-search-backend": "1.5.7", + "@backstage/plugin-search-backend-module-catalog": "0.1.22", + "@backstage/plugin-search-backend-module-elasticsearch": "1.4.0", + "@backstage/plugin-search-backend-module-explore": "0.1.21", + "@backstage/plugin-search-backend-module-pg": "0.5.26", + "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.1.10", + "@backstage/plugin-search-backend-module-techdocs": "0.1.22", + "@backstage/plugin-search-backend-node": "1.2.21", + "@backstage/plugin-search-common": "1.2.11", + "@backstage/plugin-search-react": "1.7.10", + "@backstage/plugin-sentry": "0.5.19", + "@backstage/plugin-shortcuts": "0.3.23", + "@backstage/plugin-signals": "0.0.5", + "@backstage/plugin-signals-backend": "0.1.3", + "@backstage/plugin-signals-node": "0.1.3", + "@backstage/plugin-signals-react": "0.0.3", + "@backstage/plugin-sonarqube": "0.7.16", + "@backstage/plugin-sonarqube-backend": "0.2.19", + "@backstage/plugin-sonarqube-react": "0.1.15", + "@backstage/plugin-splunk-on-call": "0.4.23", + "@backstage/plugin-stack-overflow": "0.1.29", + "@backstage/plugin-stack-overflow-backend": "0.2.21", + "@backstage/plugin-stackstorm": "0.1.15", + "@backstage/plugin-tech-insights": "0.3.26", + "@backstage/plugin-tech-insights-backend": "0.5.31", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.49", "@backstage/plugin-tech-insights-common": "0.2.12", - "@backstage/plugin-tech-insights-node": "0.4.15", - "@backstage/plugin-tech-radar": "0.6.12", - "@backstage/plugin-techdocs": "1.9.3", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.26", - "@backstage/plugin-techdocs-backend": "1.9.2", - "@backstage/plugin-techdocs-module-addons-contrib": "1.1.4", - "@backstage/plugin-techdocs-node": "1.11.1", - "@backstage/plugin-techdocs-react": "1.1.15", - "@backstage/plugin-todo": "0.2.33", - "@backstage/plugin-todo-backend": "0.3.7", - "@backstage/plugin-user-settings": "0.8.0", - "@backstage/plugin-user-settings-backend": "0.2.8", - "@backstage/plugin-vault": "0.1.24", - "@backstage/plugin-vault-backend": "0.4.2", - "@backstage/plugin-vault-node": "0.1.2", - "@backstage/plugin-xcmetrics": "0.2.47", - "@backstage/plugin-auth-backend-module-oidc-provider": "0.0.0", - "@backstage/plugin-signals": "0.0.0", - "@backstage/plugin-signals-backend": "0.0.0", - "@backstage/plugin-signals-node": "0.0.0", - "@backstage/plugin-signals-react": "0.0.0", - "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.0.0", - "@backstage/plugin-notifications": "0.0.0", - "@backstage/plugin-notifications-backend": "0.0.0", - "@backstage/plugin-notifications-common": "0.0.0", - "@backstage/plugin-notifications-node": "0.0.0", - "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.0.0", - "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.0.0" + "@backstage/plugin-tech-insights-node": "0.6.0", + "@backstage/plugin-tech-radar": "0.7.3", + "@backstage/plugin-techdocs": "1.10.4", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.31", + "@backstage/plugin-techdocs-backend": "1.10.4", + "@backstage/plugin-techdocs-module-addons-contrib": "1.1.9", + "@backstage/plugin-techdocs-node": "1.12.3", + "@backstage/plugin-techdocs-react": "1.2.3", + "@backstage/plugin-todo": "0.2.38", + "@backstage/plugin-todo-backend": "0.3.16", + "@backstage/plugin-user-settings": "0.8.5", + "@backstage/plugin-user-settings-backend": "0.2.16", + "@backstage/plugin-vault": "0.1.29", + "@backstage/plugin-vault-backend": "0.4.10", + "@backstage/plugin-vault-node": "0.1.10", + "@backstage/plugin-xcmetrics": "0.2.52", + "@backstage/plugin-catalog-backend-module-gitlab-org": "0.0.0" }, "changesets": [ - "afraid-numbers-invite", - "angry-phones-arrive", - "beige-apples-press", - "blue-keys-do", - "brave-jobs-invite", - "breezy-cobras-sin", - "brown-items-hammer", - "brown-peaches-hunt", - "calm-cups-rule", - "calm-items-double", - "calm-onions-exercise", - "chilled-chefs-notice", - "chilled-ways-wave", - "chilly-seahorses-bake", - "cold-cheetahs-pull", - "cold-cooks-care", - "cool-islands-impress", - "cool-walls-applaud", - "create-app-1706621803", - "curvy-icons-peel", - "curvy-ladybugs-impress", - "cyan-bats-lick", - "cyan-ducks-sin", - "cyan-icons-rest", - "dirty-cheetahs-shave", - "dirty-mirrors-retire", - "dirty-plums-fix", - "dry-lizards-taste", - "dry-lobsters-flash", - "dry-vans-kiss", - "dull-dolphins-explain", - "dull-fireants-repeat", - "eight-hounds-dream", - "eight-pumas-rule", - "eleven-walls-relate", - "empty-ligers-hang", - "fair-mirrors-hammer", - "famous-houses-thank", - "fast-jeans-walk", - "fast-onions-own", - "fifty-adults-watch", - "fifty-files-argue", - "flat-roses-happen", - "flat-wasps-fold", - "fluffy-jeans-eat", - "forty-beers-sniff", - "forty-cars-scream", - "forty-eagles-kick", - "four-mugs-try", - "four-walls-perform", - "fresh-gifts-smile", - "fresh-paws-raise", - "friendly-cheetahs-rescue", - "friendly-terms-love", - "funny-buttons-sip", - "funny-timers-visit", - "fuzzy-comics-collect", - "fuzzy-turtles-camp", - "giant-suits-switch", - "good-lemons-lick", - "gorgeous-bobcats-press", - "gorgeous-pumas-draw", - "gorgeous-ways-applaud", - "great-rats-collect", - "green-dogs-fold", - "green-flies-draw", - "grumpy-poets-study", - "happy-peas-hunt", - "healthy-bees-deliver", - "healthy-goats-jump", - "hip-ears-add", - "hot-horses-matter", - "hot-paws-tap", - "hot-pillows-poke", - "hot-tips-doubt", - "hungry-days-remain", - "hungry-lions-sit", - "khaki-seahorses-joke", - "kind-clouds-fly", - "kind-wombats-draw", - "large-frogs-grab", - "large-moons-speak", - "large-tables-wonder", - "late-poets-love", - "lazy-dolls-roll", - "lemon-cameras-remember", - "long-suns-bow", - "long-wasps-wait", - "loud-walls-compare", - "lovely-bugs-prove", - "lovely-starfishes-remain", - "lucky-bugs-bow", - "many-pugs-change", - "mean-apes-wait", - "metal-elephants-sit", - "metal-students-drive", - "mighty-steaks-shave", - "mighty-tomatoes-visit", - "mighty-toys-laugh", - "modern-peaches-clean", - "nasty-days-jog", - "nasty-shirts-look", - "neat-eels-greet", - "neat-hotels-wink", - "neat-kiwis-joke", - "new-plants-rhyme", - "nice-carrots-dream", - "nine-bulldogs-camp", - "nine-olives-swim", - "ninety-hats-kiss", - "ninety-rules-sneeze", - "old-papayas-shave", - "old-students-smoke", - "olive-boats-agree", - "olive-experts-fold", - "olive-singers-accept", - "orange-gorillas-clean", - "orange-suns-yell", - "orange-walls-complain", - "perfect-colts-hammer", - "polite-meals-hug", - "poor-jeans-rescue", - "poor-points-do", - "quick-gifts-leave", - "quick-penguins-refuse", - "quick-ties-stare", - "quiet-donkeys-punch", - "rare-seals-thank", - "real-eggs-sip", - "real-grapes-sing", - "red-bottles-swim", - "red-eggs-serve", - "renovate-235713b", - "renovate-2d87790", - "renovate-47c1714", - "renovate-4b698fb", - "renovate-5f8d1ca", - "renovate-95b717a", - "renovate-97e6aa5", - "renovate-b35b354", - "renovate-c392808", - "renovate-d7337c1", - "renovate-f253121", - "renovate-f4b1d70", - "renovate-f58dd5c", - "renovate-f92a114", - "renovate-fb2e0b9", - "rich-bees-fry", - "rotten-lemons-cry", - "selfish-mails-scream", - "serious-carpets-learn", - "serious-dryers-grin", - "seven-dots-serve", - "seven-plums-return", - "shaggy-trainers-rule", - "shaggy-windows-cross", - "sharp-pandas-hunt", - "shiny-apes-glow", - "shiny-clocks-greet", - "shiny-poets-tease", - "short-cherries-mix", - "shy-carrots-decide", - "silent-hotels-knock", - "silent-poets-grab", - "silent-waves-pretend", - "silver-crabs-exercise", - "six-emus-buy", - "six-jobs-sin", - "six-melons-end", - "sixty-bags-fry", - "sixty-shoes-prove", - "slimy-rats-fly", - "smart-numbers-call", - "soft-balloons-relax", - "soft-beans-tease", - "sour-ligers-hunt", - "sour-rivers-fry", - "spicy-bobcats-return", - "spotty-jokes-unite", - "spotty-kids-pay", - "spotty-phones-attend", - "strange-parents-hammer", - "strong-lobsters-hide", - "strong-news-develop", - "sweet-ravens-glow", - "swift-pumpkins-shake", - "tall-frogs-clap", - "tall-tools-compare", - "tame-numbers-smile", - "tame-rockets-sin", - "tasty-feet-cheat", - "tasty-oranges-rescue", - "ten-numbers-happen", - "ten-planets-guess", - "ten-trainers-cough", - "tender-flowers-collect", - "thin-turtles-float", - "thirty-dolls-admire", - "tidy-cooks-mix", - "tidy-cooks-mixed", - "tidy-peaches-nail", - "tiny-donuts-drive", - "tiny-kiwis-know", - "tough-drinks-scream", - "twelve-hounds-know", - "twelve-pens-rescue", - "twelve-shirts-buy", - "twelve-weeks-march", - "twenty-taxis-mate", - "two-coats-smile", - "two-geese-explain", - "two-singers-learn", - "unlucky-pens-search", - "unlucky-wasps-tan", - "warm-maps-scream", - "weak-news-jam", - "wet-emus-work", - "wet-lions-crash", - "wicked-ants-reflect", - "wicked-dolphins-wash", - "wicked-elephants-scream", - "wild-owls-doubt", - "wise-flies-laugh", - "wise-papayas-cough", - "young-ladybugs-decide", - "young-rules-repeat" + "afraid-needles-divide", + "bright-pumpkins-rule", + "chatty-cycles-unite", + "chilly-adults-sing", + "chilly-fireants-roll", + "cold-rats-leave", + "cool-elephants-march", + "cuddly-chairs-kick", + "curvy-planes-flash", + "dry-sloths-impress", + "eighty-apricots-kneel", + "eighty-bats-stare", + "eleven-pandas-divide", + "fix-stackoverflow", + "fluffy-hotels-wait", + "fresh-crews-impress", + "gold-waves-bake", + "gorgeous-cameras-cross", + "green-adults-push", + "hip-carrots-drive", + "itchy-gorillas-hope", + "itchy-keys-wonder", + "late-planes-fix", + "loud-frogs-eat", + "loud-vans-greet", + "lovely-games-cry", + "lucky-news-guess", + "orange-numbers-think", + "perfect-points-hope", + "proud-doors-cheat", + "purple-parents-sin", + "purple-waves-smile", + "rare-fireants-tickle", + "real-crabs-obey", + "renovate-0d0bd5c", + "selfish-pigs-glow", + "shy-students-clap", + "smart-avocados-invent", + "smooth-garlics-behave", + "sour-socks-approve", + "stupid-onions-know", + "tasty-apes-learn", + "thick-llamas-itch", + "tricky-cougars-shout", + "unlucky-days-play", + "unlucky-rivers-collect", + "warm-fans-promise", + "young-olives-drop" ] } diff --git a/.changeset/proud-doors-cheat.md b/.changeset/proud-doors-cheat.md new file mode 100644 index 0000000000..55ab7878d4 --- /dev/null +++ b/.changeset/proud-doors-cheat.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +Fixed bug where scrollbars don't pick up the theme when in dark mode diff --git a/.changeset/purple-camels-applaud.md b/.changeset/purple-camels-applaud.md deleted file mode 100644 index 4f6858922a..0000000000 --- a/.changeset/purple-camels-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fixed a bug where `fullTextFilter` wasn't preserved correctly in the cursor. diff --git a/.changeset/purple-parents-sin.md b/.changeset/purple-parents-sin.md new file mode 100644 index 0000000000..4de90893ef --- /dev/null +++ b/.changeset/purple-parents-sin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-backstage-openapi': patch +--- + +Fix incorrect dependency import. diff --git a/.changeset/purple-waves-smile.md b/.changeset/purple-waves-smile.md new file mode 100644 index 0000000000..44da72ea70 --- /dev/null +++ b/.changeset/purple-waves-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-guest-provider': patch +--- + +Error if used outside of a development environment without explicit allowance diff --git a/.changeset/quick-gifts-leave.md b/.changeset/quick-gifts-leave.md deleted file mode 100644 index 2f5f2a4635..0000000000 --- a/.changeset/quick-gifts-leave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -The `Cluster` component now renders the cluster's title, if specified. diff --git a/.changeset/quick-penguins-refuse.md b/.changeset/quick-penguins-refuse.md deleted file mode 100644 index 5d3165114b..0000000000 --- a/.changeset/quick-penguins-refuse.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Added `ScaffolderPageContextMenu` to `ActionsPage`, `ListTaskPage`, and `TemplateEditorPage` so that you can more easily navigate between these pages diff --git a/.changeset/quick-ties-stare.md b/.changeset/quick-ties-stare.md deleted file mode 100644 index 19eb50feed..0000000000 --- a/.changeset/quick-ties-stare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch -'@backstage/backend-common': patch ---- - -Support `token` in `readTree`, `readUrl` and `search` diff --git a/.changeset/quiet-donkeys-punch.md b/.changeset/quiet-donkeys-punch.md deleted file mode 100644 index a375ed148c..0000000000 --- a/.changeset/quiet-donkeys-punch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Extracted common dialog component. diff --git a/.changeset/rare-fireants-tickle.md b/.changeset/rare-fireants-tickle.md new file mode 100644 index 0000000000..8668d4c287 --- /dev/null +++ b/.changeset/rare-fireants-tickle.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Added optional `initialShowDropDown` prop to `SidebarSubmenuItem` to internally manage the initial display state of the dropdown items. diff --git a/.changeset/rare-seals-thank.md b/.changeset/rare-seals-thank.md deleted file mode 100644 index 345c1c91b4..0000000000 --- a/.changeset/rare-seals-thank.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -Added `RouteResolutionsApi` as a replacement for the routing context. diff --git a/.changeset/real-crabs-obey.md b/.changeset/real-crabs-obey.md new file mode 100644 index 0000000000..9a52f0e5a6 --- /dev/null +++ b/.changeset/real-crabs-obey.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-explore': patch +--- + +Migrate search collator to use the new auth services. diff --git a/.changeset/real-eggs-sip.md b/.changeset/real-eggs-sip.md deleted file mode 100644 index ca23d792f8..0000000000 --- a/.changeset/real-eggs-sip.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-signals-backend': patch -'@backstage/plugin-signals': patch -'@backstage/plugin-signals-react': patch -'@backstage/plugin-signals-node': patch ---- - -Add support to subscribe and publish messages through signals plugins diff --git a/.changeset/real-grapes-sing.md b/.changeset/real-grapes-sing.md deleted file mode 100644 index 484fc7969a..0000000000 --- a/.changeset/real-grapes-sing.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/app-defaults': minor -'@backstage/plugin-playlist': patch -'@backstage/plugin-scaffolder': minor ---- - -Added stack trace display to `ErrorPage` and updated existing refs diff --git a/.changeset/red-bottles-swim.md b/.changeset/red-bottles-swim.md deleted file mode 100644 index eebdc85298..0000000000 --- a/.changeset/red-bottles-swim.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-auth-node': patch ---- - -The helper function `makeProfileInfo` and `PassportHelpers.transformProfile` -were refactored to use the `jose` library. diff --git a/.changeset/red-eggs-serve.md b/.changeset/red-eggs-serve.md deleted file mode 100644 index 1b2c9b3b07..0000000000 --- a/.changeset/red-eggs-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-app-backend': patch ---- - -Support injecting config multiple times in a single bundle diff --git a/.changeset/renovate-05666d4.md b/.changeset/renovate-05666d4.md deleted file mode 100644 index 3e8a997820..0000000000 --- a/.changeset/renovate-05666d4.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `vite-plugin-node-polyfills` to `^0.21.0`. diff --git a/.changeset/renovate-0d0bd5c.md b/.changeset/renovate-0d0bd5c.md new file mode 100644 index 0000000000..ac3fe697f9 --- /dev/null +++ b/.changeset/renovate-0d0bd5c.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-home-react': patch +'@backstage/plugin-home': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Updated dependency `@rjsf/utils` to `5.18.2`. +Updated dependency `@rjsf/core` to `5.18.2`. +Updated dependency `@rjsf/material-ui` to `5.18.2`. +Updated dependency `@rjsf/validator-ajv8` to `5.18.2`. diff --git a/.changeset/renovate-151b8b9.md b/.changeset/renovate-151b8b9.md deleted file mode 100644 index 1702b28596..0000000000 --- a/.changeset/renovate-151b8b9.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch -'@backstage/backend-dynamic-feature-service': patch -'@backstage/plugin-scaffolder-backend-module-github': patch -'@backstage/plugin-scaffolder-backend-module-rails': patch -'@backstage/plugin-catalog-backend-module-gerrit': patch -'@backstage/backend-test-utils': patch -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/backend-app-api': patch -'@backstage/plugin-devtools-backend': patch -'@backstage/plugin-linguist-backend': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/backend-common': patch -'@backstage/e2e-test-utils': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-rollbar-backend': patch -'@backstage/plugin-scaffolder-node': patch -'@backstage/config-loader': patch -'@techdocs/cli': patch -'@backstage/plugin-techdocs-node': patch -'@backstage/plugin-auth-backend': patch -'@backstage/create-app': patch -'@backstage/repo-tools': patch -'@backstage/plugin-app-backend': patch -'@backstage/cli-node': patch -'@backstage/plugin-app-node': patch -'@backstage/cli': patch ---- - -Updated dependency `fs-extra` to `^11.2.0`. -Updated dependency `@types/fs-extra` to `^11.0.0`. diff --git a/.changeset/renovate-235713b.md b/.changeset/renovate-235713b.md deleted file mode 100644 index 148062dadb..0000000000 --- a/.changeset/renovate-235713b.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-entity-validation': patch -'@backstage/plugin-gcp-projects': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch ---- - -Updated dependency `@react-hookz/web` to `^24.0.0`. diff --git a/.changeset/renovate-2d87790.md b/.changeset/renovate-2d87790.md deleted file mode 100644 index 5230172e2b..0000000000 --- a/.changeset/renovate-2d87790.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-home-react': patch -'@backstage/plugin-home': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Updated dependency `@rjsf/utils` to `5.17.0`. -Updated dependency `@rjsf/core` to `5.17.0`. -Updated dependency `@rjsf/material-ui` to `5.17.0`. -Updated dependency `@rjsf/validator-ajv8` to `5.17.0`. diff --git a/.changeset/renovate-3365c7c.md b/.changeset/renovate-3365c7c.md deleted file mode 100644 index 193ba2b702..0000000000 --- a/.changeset/renovate-3365c7c.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `esbuild-loader` to `^4.0.0`. diff --git a/.changeset/renovate-47c1714.md b/.changeset/renovate-47c1714.md deleted file mode 100644 index 4544d36713..0000000000 --- a/.changeset/renovate-47c1714.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-home-react': patch -'@backstage/plugin-home': patch -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Updated dependency `@rjsf/utils` to `5.16.1`. -Updated dependency `@rjsf/core` to `5.16.1`. -Updated dependency `@rjsf/material-ui` to `5.16.1`. -Updated dependency `@rjsf/validator-ajv8` to `5.16.1`. diff --git a/.changeset/renovate-49df276.md b/.changeset/renovate-49df276.md deleted file mode 100644 index 942ead5597..0000000000 --- a/.changeset/renovate-49df276.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `eslint-config-prettier` to `^9.0.0`. diff --git a/.changeset/renovate-4b0ba1e.md b/.changeset/renovate-4b0ba1e.md deleted file mode 100644 index 54dcd58187..0000000000 --- a/.changeset/renovate-4b0ba1e.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/config-loader': patch ---- - -Updated dependency `typescript-json-schema` to `^0.63.0`. diff --git a/.changeset/renovate-4b698fb.md b/.changeset/renovate-4b698fb.md deleted file mode 100644 index 220aa5c848..0000000000 --- a/.changeset/renovate-4b698fb.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `vite-plugin-node-polyfills` to `^0.19.0`. diff --git a/.changeset/renovate-5bd1178.md b/.changeset/renovate-5bd1178.md deleted file mode 100644 index 200c66c3fe..0000000000 --- a/.changeset/renovate-5bd1178.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-common': patch -'@techdocs/cli': patch -'@backstage/plugin-techdocs-backend': patch ---- - -Updated dependency `dockerode` to `^4.0.0`. diff --git a/.changeset/renovate-5f8d1ca.md b/.changeset/renovate-5f8d1ca.md deleted file mode 100644 index 03f8d4b961..0000000000 --- a/.changeset/renovate-5f8d1ca.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-oidc-provider': patch ---- - -Updated dependency `passport` to `^0.7.0`. diff --git a/.changeset/renovate-635e66d.md b/.changeset/renovate-635e66d.md deleted file mode 100644 index 2b5b6ad983..0000000000 --- a/.changeset/renovate-635e66d.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `eslint-webpack-plugin` to `^4.0.0`. diff --git a/.changeset/renovate-786f04b.md b/.changeset/renovate-786f04b.md deleted file mode 100644 index c5f9b9b891..0000000000 --- a/.changeset/renovate-786f04b.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/codemods': patch -'@backstage/create-app': patch -'@backstage/repo-tools': patch -'@techdocs/cli': patch ---- - -Updated dependency `commander` to `^12.0.0`. diff --git a/.changeset/renovate-95b717a.md b/.changeset/renovate-95b717a.md deleted file mode 100644 index 59beab8d04..0000000000 --- a/.changeset/renovate-95b717a.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-bitbucket-cloud-common': patch ---- - -Updated dependency `ts-morph` to `^21.0.0`. diff --git a/.changeset/renovate-97e6aa5.md b/.changeset/renovate-97e6aa5.md deleted file mode 100644 index 51f4edccd2..0000000000 --- a/.changeset/renovate-97e6aa5.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-opencost': patch ---- - -Updated dependency `date-fns` to `^3.0.0`. diff --git a/.changeset/renovate-b35b354.md b/.changeset/renovate-b35b354.md deleted file mode 100644 index 750ef50a74..0000000000 --- a/.changeset/renovate-b35b354.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-tasks': patch ---- - -Updated dependency `cron` to `^3.0.0`. diff --git a/.changeset/renovate-c392808.md b/.changeset/renovate-c392808.md deleted file mode 100644 index 4d7f660d34..0000000000 --- a/.changeset/renovate-c392808.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-gcalendar': patch -'@backstage/plugin-microsoft-calendar': patch -'@backstage/plugin-techdocs': patch ---- - -Updated dependency `dompurify` to `^3.0.0`. -Updated dependency `@types/dompurify` to `^3.0.0`. diff --git a/.changeset/renovate-d7337c1.md b/.changeset/renovate-d7337c1.md deleted file mode 100644 index dabbee8a44..0000000000 --- a/.changeset/renovate-d7337c1.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `fork-ts-checker-webpack-plugin` to `^9.0.0`. diff --git a/.changeset/renovate-f253121.md b/.changeset/renovate-f253121.md deleted file mode 100644 index 42899973fd..0000000000 --- a/.changeset/renovate-f253121.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/cli': patch -'@backstage/integration': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs-node': patch -'@backstage/plugin-techdocs': patch ---- - -Updated dependency `git-url-parse` to `^14.0.0`. diff --git a/.changeset/renovate-f4b1d70.md b/.changeset/renovate-f4b1d70.md deleted file mode 100644 index 7b07ee8364..0000000000 --- a/.changeset/renovate-f4b1d70.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated dependency `esbuild` to `^0.20.0`. diff --git a/.changeset/renovate-f58dd5c.md b/.changeset/renovate-f58dd5c.md deleted file mode 100644 index 8a226034ea..0000000000 --- a/.changeset/renovate-f58dd5c.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Updated dependency `graphiql` to `3.1.0`. diff --git a/.changeset/renovate-f92a114.md b/.changeset/renovate-f92a114.md deleted file mode 100644 index 6ca0ea33d8..0000000000 --- a/.changeset/renovate-f92a114.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `eslint-plugin-deprecation` to `^2.0.0`. diff --git a/.changeset/renovate-fb2e0b9.md b/.changeset/renovate-fb2e0b9.md deleted file mode 100644 index 39277aaa2a..0000000000 --- a/.changeset/renovate-fb2e0b9.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Updated dependency `@asyncapi/react-component` to `1.2.13`. diff --git a/.changeset/rich-bees-fry.md b/.changeset/rich-bees-fry.md deleted file mode 100644 index 281719340b..0000000000 --- a/.changeset/rich-bees-fry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-app-backend': patch -'@backstage/plugin-app-node': patch ---- - -Allow the `app-backend` plugin to use a global configuration schema provided externally through an extension. diff --git a/.changeset/rotten-lemons-cry.md b/.changeset/rotten-lemons-cry.md deleted file mode 100644 index 2bcc4c2ea7..0000000000 --- a/.changeset/rotten-lemons-cry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-microsoft-provider': patch ---- - -Added the possibility to use custom scopes for performing login with Microsoft EntraID. diff --git a/.changeset/selfish-mails-scream.md b/.changeset/selfish-mails-scream.md deleted file mode 100644 index 7d1149f27a..0000000000 --- a/.changeset/selfish-mails-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@techdocs/cli': patch ---- - -fix: mkdocs parameter casing diff --git a/.changeset/selfish-pigs-glow.md b/.changeset/selfish-pigs-glow.md new file mode 100644 index 0000000000..c7808c0283 --- /dev/null +++ b/.changeset/selfish-pigs-glow.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-auth-node': patch +--- + +Allow overriding default ownership resolving with the new `AuthOwnershipResolutionExtensionPoint` diff --git a/.changeset/serious-carpets-learn.md b/.changeset/serious-carpets-learn.md deleted file mode 100644 index 1f13420976..0000000000 --- a/.changeset/serious-carpets-learn.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor -'@backstage/plugin-scaffolder-common': minor -'@backstage/plugin-scaffolder-react': minor -'@backstage/plugin-scaffolder-node': minor -'@backstage/plugin-scaffolder': patch ---- - -Introduced the first version of recoverable tasks. diff --git a/.changeset/serious-dryers-grin.md b/.changeset/serious-dryers-grin.md deleted file mode 100644 index 24d17f4959..0000000000 --- a/.changeset/serious-dryers-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Fix entity content extension filtering. diff --git a/.changeset/seven-dots-serve.md b/.changeset/seven-dots-serve.md deleted file mode 100644 index 80919b5d28..0000000000 --- a/.changeset/seven-dots-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -Exported `CatalogTable.defaultColumnsFunc` for defining the columns in `` of some Kinds while using the default columns for the others. diff --git a/.changeset/seven-plums-return.md b/.changeset/seven-plums-return.md deleted file mode 100644 index 71016577b1..0000000000 --- a/.changeset/seven-plums-return.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes-common': patch ---- - -Clusters configured with the `aws` authentication strategy can now customize the -`x-k8s-aws-id` header value used to generate tokens. This value can be specified -specified via the `kubernetes.io/x-k8s-aws-id` parameter (in -`metadata.annotations` for clusters in the catalog, or the `authMetadata` block -on clusters in the app-config). This is particularly helpful when a Backstage -instance contains multiple AWS clusters with the same name in different regions --- using this new parameter, the clusters can be given different logical names -to distinguish them but still use the same ID for the purposes of generating -tokens. diff --git a/.changeset/shaggy-trainers-rule.md b/.changeset/shaggy-trainers-rule.md deleted file mode 100644 index 4140a400e1..0000000000 --- a/.changeset/shaggy-trainers-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Throw a more specific exception `NotImplementedError` when an API implementation cannot be found. diff --git a/.changeset/shaggy-windows-cross.md b/.changeset/shaggy-windows-cross.md deleted file mode 100644 index 185c6d59ef..0000000000 --- a/.changeset/shaggy-windows-cross.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/app-defaults': patch -'@backstage/core-app-api': patch -'@backstage/test-utils': patch ---- - -Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. diff --git a/.changeset/sharp-pandas-hunt.md b/.changeset/sharp-pandas-hunt.md deleted file mode 100644 index 1c69c02a0b..0000000000 --- a/.changeset/sharp-pandas-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-bitrise': patch ---- - -Update README diff --git a/.changeset/shiny-apes-glow.md b/.changeset/shiny-apes-glow.md deleted file mode 100644 index 5ff66157cd..0000000000 --- a/.changeset/shiny-apes-glow.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': minor -'@backstage/plugin-scaffolder-backend': patch ---- - -New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`. - -Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` -and replaces its actions related to Bitbucket Cloud. - -- `publish:bitbucketCloud` -- `bitbucket:pipelines:run` diff --git a/.changeset/shiny-clocks-greet.md b/.changeset/shiny-clocks-greet.md deleted file mode 100644 index 0c112ff81f..0000000000 --- a/.changeset/shiny-clocks-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings': patch ---- - -conditionally rendering the user name and email in user settings page diff --git a/.changeset/shiny-poets-tease.md b/.changeset/shiny-poets-tease.md deleted file mode 100644 index a991601a88..0000000000 --- a/.changeset/shiny-poets-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': patch ---- - -Update to a newer version of `@trendyol-js/openstack-swift-sdk` diff --git a/.changeset/short-cherries-mix.md b/.changeset/short-cherries-mix.md deleted file mode 100644 index 866f7a0971..0000000000 --- a/.changeset/short-cherries-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gerrit': patch ---- - -Provide default branch when creating repositories. diff --git a/.changeset/shy-carrots-decide.md b/.changeset/shy-carrots-decide.md deleted file mode 100644 index 5f64f3d4bd..0000000000 --- a/.changeset/shy-carrots-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-app-backend': patch ---- - -Do not force caching of the Javascript asset that contains the injected config. diff --git a/.changeset/shy-students-clap.md b/.changeset/shy-students-clap.md new file mode 100644 index 0000000000..0e6244f21d --- /dev/null +++ b/.changeset/shy-students-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab-org': patch +--- + +Added a new `catalog-backend-module-gitlab-org` module which adds the `GitlabOrgDiscoveryEntityProvider` to the catalog's providers using the new backend system. diff --git a/.changeset/silent-hotels-knock.md b/.changeset/silent-hotels-knock.md deleted file mode 100644 index 7ff5d978d2..0000000000 --- a/.changeset/silent-hotels-knock.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -'@backstage/frontend-app-api': minor ---- - -**BREAKING**: The `app.routes.bindings` app-config mapping has been simplified. You now only need to specify the plugin ID and route ID on both sides of the mapping. - -Old form: - -```yaml -app: - routes: - bindings: - plugin.catalog.externalRoutes.viewTechDoc: plugin.techdocs.routes.docRoot - plugin.catalog.externalRoutes.createComponent: plugin.catalog-import.routes.importPage -``` - -New form: - -```yaml -app: - routes: - bindings: - catalog.viewTechDoc: techdocs.docRoot - catalog.createComponent: catalog-import.importPage -``` diff --git a/.changeset/silent-poets-grab.md b/.changeset/silent-poets-grab.md deleted file mode 100644 index 0d76e263d2..0000000000 --- a/.changeset/silent-poets-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -Improved the error message when data input/output shapes do not match diff --git a/.changeset/silent-waves-pretend.md b/.changeset/silent-waves-pretend.md deleted file mode 100644 index 5986579fe6..0000000000 --- a/.changeset/silent-waves-pretend.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-aws-alb-provider': minor -'@backstage/plugin-auth-backend': patch ---- - -Migrated the AWS ALB auth provider to new `@backstage/plugin-auth-backend-module-aws-alb-provider` module package. diff --git a/.changeset/silver-crabs-exercise.md b/.changeset/silver-crabs-exercise.md deleted file mode 100644 index ff34b5a3c3..0000000000 --- a/.changeset/silver-crabs-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': minor ---- - -Migrate the `api-docs` to the new frontend system. It is experimental and available via alpha subpath. diff --git a/.changeset/six-emus-buy.md b/.changeset/six-emus-buy.md deleted file mode 100644 index 1ef2a8e124..0000000000 --- a/.changeset/six-emus-buy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-signals-react': patch -'@backstage/plugin-signals-node': patch -'@backstage/plugin-signals': patch ---- - -Allow defining signal type to publish and receive diff --git a/.changeset/six-jobs-sin.md b/.changeset/six-jobs-sin.md deleted file mode 100644 index 307190ae81..0000000000 --- a/.changeset/six-jobs-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-client': patch ---- - -Internal updates to auto-generated files. diff --git a/.changeset/six-melons-end.md b/.changeset/six-melons-end.md deleted file mode 100644 index f139e49887..0000000000 --- a/.changeset/six-melons-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Fixed a bug where the logs dialog and any other functionality depending on the proxy endpoint would fail for clusters configured with the OIDC auth provider. diff --git a/.changeset/six-scissors-smile.md b/.changeset/six-scissors-smile.md new file mode 100644 index 0000000000..7680edbba6 --- /dev/null +++ b/.changeset/six-scissors-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +The `SignInPage` guest provider will now fall back to legacy guest auth if the backend request fails, allowing guest auth without a running backend. diff --git a/.changeset/sixty-bags-fry.md b/.changeset/sixty-bags-fry.md deleted file mode 100644 index 139e31c6a4..0000000000 --- a/.changeset/sixty-bags-fry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-node': patch ---- - -The `ClusterDetails` type now has a `title` field, which should be a -human-readable name. diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md deleted file mode 100644 index fe9438eeb2..0000000000 --- a/.changeset/sixty-shoes-prove.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': minor ---- - -**BREAKING** The pod exec terminal is now disabled by default since there are several scenarios where it is known not to work. It can be re-enabled at your own risk by setting the config parameter `kubernetes.podExecTerminal.enabled` to `true`. diff --git a/.changeset/slimy-rats-fly.md b/.changeset/slimy-rats-fly.md deleted file mode 100644 index 81fcae5bb2..0000000000 --- a/.changeset/slimy-rats-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Added basic support for the new frontend system, exported from the `/alpha` subpath. diff --git a/.changeset/smart-avocados-invent.md b/.changeset/smart-avocados-invent.md new file mode 100644 index 0000000000..c71b6fef37 --- /dev/null +++ b/.changeset/smart-avocados-invent.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-dynamic-feature-service': patch +--- + +Updates the `scanRoot` method in the `PluginScanner` class to specifically ignore the `lost+found` directory, which is a system-generated directory used for file recovery on Unix-like systems. Skipping this directory avoids unnecessary errors. diff --git a/.changeset/smart-numbers-call.md b/.changeset/smart-numbers-call.md deleted file mode 100644 index 24a2053259..0000000000 --- a/.changeset/smart-numbers-call.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -The default `ComponentsApi` implementation now uses the `ComponentRef` ID as the component key, rather than the reference instance. This fixes a bug where duplicate installations of `@backstage/frontend-plugin-api` would break the app. diff --git a/.changeset/smooth-garlics-behave.md b/.changeset/smooth-garlics-behave.md new file mode 100644 index 0000000000..ed972ae164 --- /dev/null +++ b/.changeset/smooth-garlics-behave.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Added option to `ServerTokenManager.fromConfig` that allows it to be instantiated in production without any configured keys. diff --git a/.changeset/soft-balloons-relax.md b/.changeset/soft-balloons-relax.md deleted file mode 100644 index 3fae8984a3..0000000000 --- a/.changeset/soft-balloons-relax.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/app-defaults': patch ---- - -Fix invalid HTTP status code 501 in Error Page diff --git a/.changeset/soft-beans-tease.md b/.changeset/soft-beans-tease.md deleted file mode 100644 index 881900e773..0000000000 --- a/.changeset/soft-beans-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-cloudbuild': patch ---- - -Add telemetry HTTP header Google Cloud Platform diff --git a/.changeset/sour-ligers-hunt.md b/.changeset/sour-ligers-hunt.md deleted file mode 100644 index 5642494c24..0000000000 --- a/.changeset/sour-ligers-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Added `experimentalExtraAllowedOrigins` to config diff --git a/.changeset/sour-rivers-fry.md b/.changeset/sour-rivers-fry.md deleted file mode 100644 index 1b74850614..0000000000 --- a/.changeset/sour-rivers-fry.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Updated `packages/app` as well as the root `package.json` type resolutions to use React v18. - -The `@testing-library/*` dependencies have also been updated to the ones compatible with React v18, and the test at `packages/app/src/App.test.tsx` had been updated to use more modern patterns that work better with these new versions. - -For information on how to migrate existing apps to React v18, see the [migration guide](https://backstage.io/docs/tutorials/react18-migration) diff --git a/.changeset/sour-socks-approve.md b/.changeset/sour-socks-approve.md new file mode 100644 index 0000000000..db40806280 --- /dev/null +++ b/.changeset/sour-socks-approve.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Emit well known relationships for the Domain entity kind. diff --git a/.changeset/spicy-bobcats-return.md b/.changeset/spicy-bobcats-return.md deleted file mode 100644 index 9bd4b33784..0000000000 --- a/.changeset/spicy-bobcats-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-dynatrace': patch ---- - -Fixed Dynatrace plugin proxy configuration diff --git a/.changeset/spotty-jokes-unite.md b/.changeset/spotty-jokes-unite.md deleted file mode 100644 index 15097e42d0..0000000000 --- a/.changeset/spotty-jokes-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Harmonize the package naming and allow custom prefix diff --git a/.changeset/spotty-kids-pay.md b/.changeset/spotty-kids-pay.md deleted file mode 100644 index 157515201d..0000000000 --- a/.changeset/spotty-kids-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Ability for user to configure backstage token expiration diff --git a/.changeset/spotty-phones-attend.md b/.changeset/spotty-phones-attend.md deleted file mode 100644 index 79bd38061d..0000000000 --- a/.changeset/spotty-phones-attend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -Move the AWS account e-mail from labels to annotations to fix the creation of `cloud-account` resources. diff --git a/.changeset/strange-parents-hammer.md b/.changeset/strange-parents-hammer.md deleted file mode 100644 index 57d5eeb83d..0000000000 --- a/.changeset/strange-parents-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/test-utils': minor ---- - -Added `components` option to `TestAppOptions`, which will be forwarded as the `components` option to `createApp`. diff --git a/.changeset/strong-lobsters-hide.md b/.changeset/strong-lobsters-hide.md deleted file mode 100644 index 7b51355eb7..0000000000 --- a/.changeset/strong-lobsters-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -App component extensions are no longer wrapped in an `ExtensionBoundary`, allowing them to inherit the outer context instead. diff --git a/.changeset/strong-news-develop.md b/.changeset/strong-news-develop.md deleted file mode 100644 index 1cbe4dda07..0000000000 --- a/.changeset/strong-news-develop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-explore': patch ---- - -Use the EntityDisplayName component for rendering Group nodes diff --git a/.changeset/stupid-onions-know.md b/.changeset/stupid-onions-know.md new file mode 100644 index 0000000000..3d028557be --- /dev/null +++ b/.changeset/stupid-onions-know.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +Empty descriptions are not rendered to improve the look&feel. diff --git a/.changeset/sweet-ravens-glow.md b/.changeset/sweet-ravens-glow.md deleted file mode 100644 index 045f7edbf2..0000000000 --- a/.changeset/sweet-ravens-glow.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/integration': minor -'@backstage/backend-common': patch ---- - -Fix rate limit detection by looking for HTTP status code 429 and updating the header `x-ratelimit-remaining` to look for in case of a 403 code is returned diff --git a/.changeset/swift-pumpkins-shake.md b/.changeset/swift-pumpkins-shake.md deleted file mode 100644 index c7a0a44ade..0000000000 --- a/.changeset/swift-pumpkins-shake.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': minor ---- - -Implement the discovery of additional individual configuration schemas for dynamic plugins, and provide: - -- an alternate implementation of the root logger service that takes them into account, -- an extension to the App backend plugin to set a global configuration schema that takes them into account. diff --git a/.changeset/tall-fireants-fix.md b/.changeset/tall-fireants-fix.md deleted file mode 100644 index 3fbc78290f..0000000000 --- a/.changeset/tall-fireants-fix.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-catalog-backend': patch ---- - -Upgraded `prom-client` to version 15 diff --git a/.changeset/tall-frogs-clap.md b/.changeset/tall-frogs-clap.md deleted file mode 100644 index 1e87ca316c..0000000000 --- a/.changeset/tall-frogs-clap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-sites-backend': patch ---- - -Added `permissionIntegrationRouter` for azure-sites-backend routes diff --git a/.changeset/tall-tools-compare.md b/.changeset/tall-tools-compare.md deleted file mode 100644 index f55c8ef5a5..0000000000 --- a/.changeset/tall-tools-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-node': patch ---- - -Introduced `PinnipedHelper` class to enable authentication to Kubernetes clusters through Pinniped diff --git a/.changeset/tame-numbers-smile.md b/.changeset/tame-numbers-smile.md deleted file mode 100644 index 1d675f8c9c..0000000000 --- a/.changeset/tame-numbers-smile.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes-node': patch ---- - -Enabling authentication to kubernetes clusters with mTLS x509 client certs diff --git a/.changeset/tame-rockets-sin.md b/.changeset/tame-rockets-sin.md deleted file mode 100644 index 30c7289871..0000000000 --- a/.changeset/tame-rockets-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-module-addons-contrib': patch ---- - -Fix position of the ReportIssue component when is displaying at the top of the container. diff --git a/.changeset/tasty-apes-learn.md b/.changeset/tasty-apes-learn.md new file mode 100644 index 0000000000..7a4545cf10 --- /dev/null +++ b/.changeset/tasty-apes-learn.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +Fix to show web notifications even when browser is on foreground. Fix duplicate notifications with multiple tabs. diff --git a/.changeset/tasty-feet-cheat.md b/.changeset/tasty-feet-cheat.md deleted file mode 100644 index 1e93439fa6..0000000000 --- a/.changeset/tasty-feet-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Fixes an issue where comments would be duplicated in the template. Also, removes a header with the title and version of the OpenAPI spec from generated code. diff --git a/.changeset/tasty-oranges-rescue.md b/.changeset/tasty-oranges-rescue.md deleted file mode 100644 index b146c2e143..0000000000 --- a/.changeset/tasty-oranges-rescue.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-auth-backend': minor ---- - -**BREAKING**: The `saml` provider has been migrated from `passport-saml` to `@node-saml/passport-saml`. - -This comes with breaking changes to config options: - -- `audience` is now mandatory -- `wantAuthnResponseSigned` is now exposed and defaults to `true` -- `wantAssertionsSigned` is now exposed and defaults to `true` diff --git a/.changeset/ten-numbers-happen.md b/.changeset/ten-numbers-happen.md deleted file mode 100644 index 73397d4568..0000000000 --- a/.changeset/ten-numbers-happen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Custom per-cluster auth metadata (mainly for use with custom `AuthenticationStrategy` implementations) can now be specified in the `authMetadata` property of clusters in the app-config. diff --git a/.changeset/ten-planets-guess.md b/.changeset/ten-planets-guess.md deleted file mode 100644 index c8510dc6b2..0000000000 --- a/.changeset/ten-planets-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Fix typo in VisitsStorageApi diff --git a/.changeset/ten-trainers-cough.md b/.changeset/ten-trainers-cough.md deleted file mode 100644 index 53a82def90..0000000000 --- a/.changeset/ten-trainers-cough.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor -'@backstage/plugin-scaffolder-node': minor ---- - -Support providing an overriding token for `fetch:template`, `fetch:plain` and `fetch:file` when interacting with upstream integrations diff --git a/.changeset/tender-flowers-collect.md b/.changeset/tender-flowers-collect.md deleted file mode 100644 index dfbf96a52c..0000000000 --- a/.changeset/tender-flowers-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -Updated the styling for tags to avoid word break. diff --git a/.changeset/thick-llamas-itch.md b/.changeset/thick-llamas-itch.md new file mode 100644 index 0000000000..17d4fb23b6 --- /dev/null +++ b/.changeset/thick-llamas-itch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +Allow defining `className` and additional properties for `NotificationsSideBarItem` diff --git a/.changeset/thin-turtles-float.md b/.changeset/thin-turtles-float.md deleted file mode 100644 index 7416093e17..0000000000 --- a/.changeset/thin-turtles-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Clusters in the catalog can now specify a human-readable title via `metadata.title`. diff --git a/.changeset/thirty-dolls-admire.md b/.changeset/thirty-dolls-admire.md deleted file mode 100644 index 1011508a98..0000000000 --- a/.changeset/thirty-dolls-admire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': minor ---- - -Prevent Entity Providers from eliminating Users and Groups from the DB when the synchronisation fails diff --git a/.changeset/tidy-cooks-mix.md b/.changeset/tidy-cooks-mix.md deleted file mode 100644 index 873de64a45..0000000000 --- a/.changeset/tidy-cooks-mix.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -'@backstage/plugin-azure-sites-backend': patch -'@backstage/plugin-azure-sites-common': patch -'@backstage/plugin-azure-sites': patch ---- - -Azure Sites `start` and `stop` action is now protected with the Permissions framework. - -The below example describes an action that forbids anyone but the owner of the catalog entity to trigger actions towards a site tied to an entity. - -```typescript - // packages/backend/src/plugins/permission.ts - import { azureSitesActionPermission } from '@backstage/plugin-azure-sites-common'; - ... - class TestPermissionPolicy implements PermissionPolicy { - async handle(request: PolicyQuery, user?: BackstageIdentityResponse): Promise { - if (isPermission(request.permission, azureSitesActionPermission)) { - return createCatalogConditionalDecision( - request.permission, - catalogConditions.isEntityOwner({ - claims: user?.identity.ownershipEntityRefs ?? [], - }), - ); - } - ... - return { - result: AuthorizeResult.ALLOW, - }; - } - ... - } -``` diff --git a/.changeset/tidy-cooks-mixed.md b/.changeset/tidy-cooks-mixed.md deleted file mode 100644 index a72f1ee0df..0000000000 --- a/.changeset/tidy-cooks-mixed.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -'@backstage/plugin-azure-sites-backend': minor ---- - -**BREAKING**: `catalogApi` and `permissionsApi` are now a requirement to be passed through to the `createRouter` function. - -You can fix the typescript issues by passing through the required dependencies like the below `diff` shows: - -```diff - import { - createRouter, - AzureSitesApi, - } from '@backstage/plugin-azure-sites-backend'; - import { Router } from 'express'; - import { PluginEnvironment } from '../types'; - - export default async function createPlugin( - env: PluginEnvironment, - ): Promise { -+ const catalogClient = new CatalogClient({ -+ discoveryApi: env.discovery, -+ }); - - return await createRouter({ - logger: env.logger, - azureSitesApi: AzureSitesApi.fromConfig(env.config), -+ catalogApi: catalogClient, -+ permissionsApi: env.permissions, - }); - } -``` diff --git a/.changeset/tidy-peaches-nail.md b/.changeset/tidy-peaches-nail.md deleted file mode 100644 index d044a6bfaa..0000000000 --- a/.changeset/tidy-peaches-nail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Clusters in the app-config can now specify a `title` property for human readability. diff --git a/.changeset/tiny-donuts-drive.md b/.changeset/tiny-donuts-drive.md deleted file mode 100644 index aadac7a276..0000000000 --- a/.changeset/tiny-donuts-drive.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Backstage will log a warning whenever duplicate cluster names are detected -- -even if clusters sharing the same name come from separate locators. diff --git a/.changeset/tiny-kiwis-know.md b/.changeset/tiny-kiwis-know.md deleted file mode 100644 index add4736527..0000000000 --- a/.changeset/tiny-kiwis-know.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependencies in frontend plugin templates diff --git a/.changeset/tough-drinks-scream.md b/.changeset/tough-drinks-scream.md deleted file mode 100644 index 3d2f154016..0000000000 --- a/.changeset/tough-drinks-scream.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-cloudbuild': minor ---- - -Changed build list view to automatically filter builds based on repository name matching component-info's metadata.name. -Added optional `google.com/cloudbuild-repo-name` annotation which allows you to specify a different repository to filter on. -Added optional `google.com/cloudbuild-trigger-name` annotation which allows you to filter based on a trigger name instead of a repo name. -Updated the ReadMe with information about the filtering and some other minor verbiage updates. -Changed `substitutions.BRANCH_NAME` to `substitutions.REF_NAME` so that the Ref field is populated properly. -Added optional `google.com/cloudbuild-location` annotation which allows you to specify the Cloud Build location of your builds. Default is global scope. -Changed build list view to show builds in a specific location if the location annotation is used. -Updated ReadMe with information about the use of the location filtering. diff --git a/.changeset/tricky-cougars-shout.md b/.changeset/tricky-cougars-shout.md new file mode 100644 index 0000000000..eed14c9eb8 --- /dev/null +++ b/.changeset/tricky-cougars-shout.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-explore': patch +--- + +Update README.md to point to explore plugin in community-plugins repository. diff --git a/.changeset/twelve-hounds-know.md b/.changeset/twelve-hounds-know.md deleted file mode 100644 index 3c95c71ddb..0000000000 --- a/.changeset/twelve-hounds-know.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': minor ---- - -Use more distinguishable icons for link (`Link`) and text output (`Description`). diff --git a/.changeset/twelve-pens-rescue.md b/.changeset/twelve-pens-rescue.md deleted file mode 100644 index 9d40fb2851..0000000000 --- a/.changeset/twelve-pens-rescue.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch -'@backstage/frontend-app-api': patch -'@backstage/core-compat-api': patch ---- - -Allow external route refs in the new system to have a `defaultTarget` pointing to a route that it'll resolve to by default if no explicit bindings were made by the adopter. diff --git a/.changeset/twelve-shirts-buy.md b/.changeset/twelve-shirts-buy.md deleted file mode 100644 index 6183c7dabd..0000000000 --- a/.changeset/twelve-shirts-buy.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-catalog-node': patch ---- - -Add support for `onProcessingError` handler at the catalog plugin (new backend system). - -You can use `setOnProcessingErrorHandler` at the `catalogProcessingExtensionPoint` -as replacement for - -```ts -catalogBuilder.subscribe({ - onProcessingError: hander, -}); -``` diff --git a/.changeset/twelve-weeks-march.md b/.changeset/twelve-weeks-march.md deleted file mode 100644 index 4d9fff5b34..0000000000 --- a/.changeset/twelve-weeks-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Fix issue where `ui:schema` was replaced with an empty object if `dependencies` is defined diff --git a/.changeset/twenty-taxis-mate.md b/.changeset/twenty-taxis-mate.md deleted file mode 100644 index 65ed158e9b..0000000000 --- a/.changeset/twenty-taxis-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing them to be used to bind external routes in configuration. diff --git a/.changeset/two-coats-smile.md b/.changeset/two-coats-smile.md deleted file mode 100644 index 65abb7a1eb..0000000000 --- a/.changeset/two-coats-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated the backend module template to make the module instance the package default export. diff --git a/.changeset/two-geese-explain.md b/.changeset/two-geese-explain.md deleted file mode 100644 index 12ae307cfe..0000000000 --- a/.changeset/two-geese-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fixed an issue that would cause an invalid `__backstage-autodetected-plugins__.js` to be written when using experimental module discovery. diff --git a/.changeset/two-singers-learn.md b/.changeset/two-singers-learn.md deleted file mode 100644 index f5c2a78ab0..0000000000 --- a/.changeset/two-singers-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-devtools': patch ---- - -Added alpha support for the New Frontend System (Declarative Integration) diff --git a/.changeset/unlucky-days-play.md b/.changeset/unlucky-days-play.md new file mode 100644 index 0000000000..b847ebd2fc --- /dev/null +++ b/.changeset/unlucky-days-play.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +Fix infinite loop in the notification title counter diff --git a/.changeset/unlucky-pens-search.md b/.changeset/unlucky-pens-search.md deleted file mode 100644 index 4786c14691..0000000000 --- a/.changeset/unlucky-pens-search.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -When using node 20+ the `scaffolder-backend` will now throw an error at startup if the `--no-node-snapshot` option was -not provided to node. diff --git a/.changeset/unlucky-rivers-collect.md b/.changeset/unlucky-rivers-collect.md new file mode 100644 index 0000000000..c5ec865658 --- /dev/null +++ b/.changeset/unlucky-rivers-collect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications-backend': patch +--- + +Updated documentation for sending messages by external services. diff --git a/.changeset/unlucky-wasps-tan.md b/.changeset/unlucky-wasps-tan.md deleted file mode 100644 index 97813cb416..0000000000 --- a/.changeset/unlucky-wasps-tan.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch ---- - -Enhanced the pull request action to allow for adding new content to the PR as described in this issue #21762 diff --git a/.changeset/warm-fans-promise.md b/.changeset/warm-fans-promise.md new file mode 100644 index 0000000000..a8a8f8a2c7 --- /dev/null +++ b/.changeset/warm-fans-promise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications': patch +--- + +The rendered size of a notification is limited for very long descriptions. diff --git a/.changeset/warm-maps-scream.md b/.changeset/warm-maps-scream.md deleted file mode 100644 index 3ea5d93b03..0000000000 --- a/.changeset/warm-maps-scream.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-linguist': patch ---- - -Updated imports from named to default imports to help with the Material UI v4 to v5 migration diff --git a/.changeset/weak-news-jam.md b/.changeset/weak-news-jam.md deleted file mode 100644 index a1f44082da..0000000000 --- a/.changeset/weak-news-jam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch ---- - -Fix bug that erroneously caused a separator or a 0 to render in the TemplateCard for Templates with empty links diff --git a/.changeset/wet-emus-work.md b/.changeset/wet-emus-work.md deleted file mode 100644 index 413670a325..0000000000 --- a/.changeset/wet-emus-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -collectLegacyRoutes throws in case invalid element is found diff --git a/.changeset/wet-lions-crash.md b/.changeset/wet-lions-crash.md deleted file mode 100644 index 795e60588d..0000000000 --- a/.changeset/wet-lions-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-puppetdb': patch ---- - -Added `latest_report_status` parameter from the PuppetDB node api and added it as a tag to the nodes. The status is valuable information as it displays which nodes are compliant to your configuration and which ones are failing are making changes. diff --git a/.changeset/wicked-ants-reflect.md b/.changeset/wicked-ants-reflect.md deleted file mode 100644 index 4882d12a34..0000000000 --- a/.changeset/wicked-ants-reflect.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-notifications-backend': patch -'@backstage/plugin-notifications-common': patch -'@backstage/plugin-notifications-node': patch -'@backstage/plugin-notifications': patch ---- - -Initial notifications system for backstage diff --git a/.changeset/wicked-dolphins-wash.md b/.changeset/wicked-dolphins-wash.md deleted file mode 100644 index 9258913c41..0000000000 --- a/.changeset/wicked-dolphins-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -On LocalKubectlProxyClusterLocator, when resolving localhost, IPv4 address is placed before IPv6 address, ignoring the order from the DNS resolver. This change is necessary since by default kubectl proxy listen on IPv4 diff --git a/.changeset/wicked-elephants-scream.md b/.changeset/wicked-elephants-scream.md deleted file mode 100644 index f002a48ba8..0000000000 --- a/.changeset/wicked-elephants-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops': patch ---- - -Prefer `dev.azure.com/build-definition` annotation when it is provided, as it is more specific than `dev.azure.com/project-repo`. This can also be used as a filter for mono-repos. diff --git a/.changeset/wild-owls-doubt.md b/.changeset/wild-owls-doubt.md deleted file mode 100644 index 84abffb159..0000000000 --- a/.changeset/wild-owls-doubt.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -The built-in module list has been trimmed down when using the new Backend System. Provider specific modules should now be installed with `backend.add` to provide additional actions to the scaffolder. These modules are as follows: - -- `@backstage/plugin-scaffolder-backend-module-github` -- `@backstage/plugin-scaffolder-backend-module-gitlab` -- `@backstage/plugin-scaffolder-backend-module-bitbucket` -- `@backstage/plugin-scaffolder-backend-module-gitea` -- `@backstage/plugin-scaffolder-backend-module-gerrit` -- `@backstage/plugin-scaffolder-backend-module-confluence-to-markdown` -- `@backstage/plugin-scaffolder-backend-module-cookiecutter` -- `@backstage/plugin-scaffolder-backend-module-rails` -- `@backstage/plugin-scaffolder-backend-module-sentry` -- `@backstage/plugin-scaffolder-backend-module-yeoman` diff --git a/.changeset/wise-flies-laugh.md b/.changeset/wise-flies-laugh.md deleted file mode 100644 index 4b31b4e9ba..0000000000 --- a/.changeset/wise-flies-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Added filter support for HomePageVisitedByType in order to enable filtering entities from the list diff --git a/.changeset/wise-papayas-cough.md b/.changeset/wise-papayas-cough.md deleted file mode 100644 index 955e7fefcc..0000000000 --- a/.changeset/wise-papayas-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Add a config declaration for `workingDirectory` diff --git a/.changeset/young-ladybugs-decide.md b/.changeset/young-ladybugs-decide.md deleted file mode 100644 index 53284cbc37..0000000000 --- a/.changeset/young-ladybugs-decide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder-node': patch ---- - -Add option to configure nunjucks with the `trimBlocks` and `lstripBlocks` options in the fetch:template action diff --git a/.changeset/young-olives-drop.md b/.changeset/young-olives-drop.md new file mode 100644 index 0000000000..4058293be8 --- /dev/null +++ b/.changeset/young-olives-drop.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Removed explicit `toString()` method from `ServiceRef` type. diff --git a/.changeset/young-rules-repeat.md b/.changeset/young-rules-repeat.md deleted file mode 100644 index 6fb17f0608..0000000000 --- a/.changeset/young-rules-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/eslint-plugin': patch ---- - -Added new `@backstage/no-top-level-material-ui-4-imports` rule that forbids top level imports from Material UI v4 packages diff --git a/.eslintrc.js b/.eslintrc.js index 2df965ab73..01cad187be 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,8 +23,11 @@ module.exports = { 'notice/notice': [ 'error', { - // eslint-disable-next-line no-restricted-syntax - templateFile: path.resolve(__dirname, './scripts/copyright-header.txt'), + templateFile: path.resolve( + // eslint-disable-next-line no-restricted-syntax + __dirname, + './scripts/templates/copyright-header.txt' + ), onNonMatchingHeader: 'replace', }, ], diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 247ce66010..0000000000 --- a/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -**/api-report*.md linguist-generated=true -**/cli-report.md linguist-generated=true -**/knip-report.md linguist-generated=true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 75416ace16..9fc63fbd04 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,6 +8,7 @@ yarn.lock @backstage/maintainers @backstage-service */yarn.lock @backstage/maintainers @backstage-service /.changeset/*.md +/beps/0001-notifications-system @backstage/maintainers @backstage/notifications-maintainers /docs/assets/search @backstage/discoverability-maintainers /docs/features/search @backstage/discoverability-maintainers /docs/features/techdocs @backstage/techdocs-maintainers @@ -44,15 +45,7 @@ yarn.lock @backstage/maintainers @backst /plugins/devtools-common @backstage/maintainers @backstage/reviewers @awanlin /plugins/entity-feedback @backstage/maintainers @backstage/reviewers @kuangp /plugins/entity-feedback-* @backstage/maintainers @backstage/reviewers @kuangp -/plugins/events-backend @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-module-aws-sqs @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-module-azure @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-module-bitbucket-cloud @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-module-gerrit @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-module-github @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-module-gitlab @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-backend-test-utils @backstage/maintainers @backstage/reviewers @pjungermann -/plugins/events-node @backstage/maintainers @backstage/reviewers @pjungermann +/plugins/events-* @backstage/maintainers @backstage/reviewers @backstage/events-maintainers /plugins/explore @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers /plugins/explore-react @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers /plugins/fossa @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers @@ -66,6 +59,8 @@ yarn.lock @backstage/maintainers @backst /plugins/linguist @backstage/maintainers @backstage/reviewers @awanlin /plugins/linguist-backend @backstage/maintainers @backstage/reviewers @awanlin /plugins/linguist-common @backstage/maintainers @backstage/reviewers @awanlin +/plugins/notifications @backstage/maintainers @backstage/notifications-maintainers +/plugins/notifications-* @backstage/maintainers @backstage/notifications-maintainers /plugins/octopus-deploy @backstage/maintainers @backstage/reviewers @jmezach /plugins/permission-* @backstage/permission-maintainers /plugins/playlist @backstage/maintainers @backstage/reviewers @kuangp @@ -76,6 +71,8 @@ yarn.lock @backstage/maintainers @backst /plugins/scaffolder-* @backstage/maintainers @backstage/reviewers @backstage/scaffolder-maintainers /plugins/search @backstage/discoverability-maintainers /plugins/search-* @backstage/discoverability-maintainers +/plugins/signals @backstage/maintainers @backstage/notifications-maintainers +/plugins/signals-* @backstage/maintainers @backstage/notifications-maintainers /plugins/sonarqube @backstage/maintainers @backstage/reviewers @backstage/sda-se-reviewers /plugins/stack-overflow @backstage/discoverability-maintainers /plugins/stack-overflow-backend @backstage/discoverability-maintainers diff --git a/.github/ISSUE_TEMPLATE/plugin.yaml b/.github/ISSUE_TEMPLATE/plugin.yaml deleted file mode 100644 index a7f5216631..0000000000 --- a/.github/ISSUE_TEMPLATE/plugin.yaml +++ /dev/null @@ -1,52 +0,0 @@ -name: 🔌 Plugin -description: 'Submit a proposal for a new Plugin' -title: '🔌 Plugin: ' -labels: [plugin] -body: - - type: markdown - attributes: - value: | - We value your time and efforts to submit this Plugin request form. 🙏 - - type: textarea - id: plugin-summary - validations: - required: true - attributes: - label: '🔖 Summary' - description: 'Provide a general summary of the plugin and how it should work' - placeholder: 'You should add ...' - - type: textarea - id: website - attributes: - label: '🌐 Project website (if applicable)' - description: 'Add a link to the open source project or product this plugin will integrate with, if existing' - placeholder: 'Website Link is ...' - - type: textarea - id: context - attributes: - label: '✌️ Context' - description: 'A clear and concise description about the Plugin.' - placeholder: 'Providing additional context' - - type: checkboxes - id: no-duplicate-issues - attributes: - label: '👀 Have you spent some time to check if this plugin request has been raised before?' - options: - - label: "I checked and didn't find similar issue" - required: true - - type: checkboxes - id: read-code-of-conduct - attributes: - label: '🏢 Have you read the Code of Conduct?' - options: - - label: 'I have read the [Code of Conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md)' - required: true - - type: dropdown - id: willing-to-submit-pr - attributes: - label: Are you willing to submit PR? - description: This is absolutely not required, but we are happy to guide you in the contribution process. - options: - - Yes I am willing to submit a PR! - - No, but I'm happy to collaborate on a PR with someone else - - No, I don't have time to work on this right now diff --git a/.github/issue-labeler.yml b/.github/issue-labeler.yml new file mode 100644 index 0000000000..6d74ce8902 --- /dev/null +++ b/.github/issue-labeler.yml @@ -0,0 +1,14 @@ +area:techdocs: + - '/(techdocs|tech-docs|tech docs)/i' +area:discoverability: + - '/search/i' +area:events: + - '/events/i' +area:catalog: + - '/catalog/i' +area:scaffolder: + - '/scaffolder/i' +area:permission: + - '/permission/i' +bep: + - '/\bbep\b/i' diff --git a/.github/labeler.yml b/.github/labeler.yml index 6653c2d868..a58da1d2f7 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -11,6 +11,10 @@ area:discoverability: # search + home - plugins/search-*/**/* - packages/search-*/**/* - plugins/home/**/* +area:events: + - changed-files: + - any-glob-to-any-file: + - plugins/events-*/**/* area:kubernetes: - changed-files: - any-glob-to-any-file: @@ -31,6 +35,10 @@ area:techdocs: - plugins/techdocs/**/* - plugins/techdocs-*/**/* - packages/techdocs-*/**/* +bep: + - changed-files: + - any-glob-to-any-file: + - beps/**/* auth: - changed-files: - any-glob-to-any-file: diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 5d979d5f22..a9cb54912a 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,13 +3,16 @@ labels: ['dependencies'], - extends: [ - 'config:best-practices', - ':gitSignOff', - 'default:pinDigestsDisabled', - ], + extends: ['config:best-practices', ':gitSignOff'], // do not pin dev dependencies, which are part of the best-practices preset - ignorePresets: [':pinDevDependencies', ':pinDigest'], + ignorePresets: [':pinDevDependencies', ':pinDigest', 'docker:pinDigests'], + + constraints: { + // TODO(freben): Remove this later; it addresses a temporary issue in corepack + // https://github.com/nodejs/corepack/issues/379 + // https://github.com/renovatebot/renovate/discussions/27465 + corepack: '0.24.1', + }, // the default limit are 10 PRs prConcurrentLimit: 20, @@ -42,5 +45,26 @@ matchSourceUrls: ['https://github.com/yarnpkg/berry'], enabled: false, }, + // ESM only majors, that we're not ready for yet + { + matchPackageNames: ['node-fetch'], + allowedVersions: '<3.0.0', + }, + { + matchPackageNames: ['inquirer', '@types/inquirer'], + allowedVersions: '<9.0.0', + }, + { + matchPackageNames: ['ora'], + allowedVersions: '<5.0.0', + }, + { + matchPackageNames: ['p-limit'], + allowedVersions: '<4.0.0', + }, + { + matchPackageNames: ['p-queue'], + allowedVersions: '<7.0.0', + }, ], } diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index c38a115fa3..026e5a9b18 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -16,6 +16,7 @@ api asciidoc async Atlassian +autofix automations autoscaling Autoscaling @@ -34,6 +35,7 @@ Blackbox bool boolean Brex +broadcasted bugfixes builtins callout @@ -84,6 +86,7 @@ debuggability declaratively deduplicated deliverables +denormalized dependabot deps destructured @@ -329,6 +332,7 @@ reusability Reusability roadmaps rollbar +rollout Roboto Rollbar Rollup @@ -358,6 +362,8 @@ SIG SIGs siloed Sinon +snackbars +snackbar Snyk Sonarqube sourcemaps @@ -471,3 +477,4 @@ Zolotusky zoomable zsh scrollable +severities diff --git a/.github/workflows/automate_changeset_feedback.yml b/.github/workflows/automate_changeset_feedback.yml index 89b611f981..4d965499d2 100644 --- a/.github/workflows/automate_changeset_feedback.yml +++ b/.github/workflows/automate_changeset_feedback.yml @@ -27,14 +27,14 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: # Fetch the commit that's merged into the base rather than the target ref # This will let us diff only the contents of the PR, without fetching more history ref: 'refs/pull/${{ github.event.pull_request.number }}/merge' - name: fetch base run: git fetch --depth 1 origin ${{ github.base_ref }} - - uses: backstage/actions/changeset-feedback@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + - uses: backstage/actions/changeset-feedback@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 name: Generate feedback with: diff-ref: 'origin/master' diff --git a/.github/workflows/automate_merge_message.yml b/.github/workflows/automate_merge_message.yml index 0c6dacde69..38243ee0ac 100644 --- a/.github/workflows/automate_merge_message.yml +++ b/.github/workflows/automate_merge_message.yml @@ -28,7 +28,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: ref: '${{ github.event.pull_request.merge_commit_sha }}' diff --git a/.github/workflows/automate_stale.yml b/.github/workflows/automate_stale.yml index b4a7271875..c7674e853d 100644 --- a/.github/workflows/automate_stale.yml +++ b/.github/workflows/automate_stale.yml @@ -28,15 +28,15 @@ jobs: for your contributions. days-before-issue-stale: 60 days-before-issue-close: 7 - exempt-issue-labels: plugin,after-vacations,will-fix + exempt-issue-labels: plugin,after-vacations,will-fix,bep stale-issue-label: stale stale-pr-message: > This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! - days-before-pr-stale: 7 - days-before-pr-close: 5 + days-before-pr-stale: 14 + days-before-pr-close: 7 exempt-pr-labels: after-vacations,will-fix stale-pr-label: stale operations-per-run: 100 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5df2a2509d..fdd31b2d57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -41,7 +41,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -68,7 +68,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -77,7 +77,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -197,10 +197,15 @@ jobs: INTEGRATION_TEST_AZURE_TOKEN: ${{ secrets.INTEGRATION_TEST_AZURE_TOKEN }} steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: fetch branch master + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + - name: fetch master branch run: git fetch origin master + # Need to fetch the base branch to be able to verify the release + - name: fetch base branch + if: github.event.pull_request.base.ref != 'master' + run: git fetch origin ${{ github.event.pull_request.base.ref }} + - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: @@ -208,10 +213,14 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} + # This check is done here since it needs git history + - name: verify release + run: node scripts/verify-release.js + - name: lint changed packages run: yarn backstage-cli repo lint --since origin/master diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 6ae0310813..c32d50ced5 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -13,7 +13,7 @@ jobs: with: egress-policy: audit - - uses: backstage/actions/cron@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + - uses: backstage/actions/cron@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index eef70ff02c..020254c872 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -5,6 +5,10 @@ on: repository_dispatch: types: [release-published] +env: + RELEASE_VERSION: v${{ github.event.client_payload.version }} + TAG_VERSION: ghcr.io/${{ github.repository_owner }}/backstage:${{ github.event.client_payload.version }} + jobs: build: runs-on: ubuntu-latest @@ -21,10 +25,10 @@ jobs: egress-policy: audit - name: checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: path: backstage - ref: v${{ github.event.client_payload.version }} + ref: ${{ github.event.client_payload.version && env.RELEASE_VERSION || github.ref }} - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -33,7 +37,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -47,24 +51,24 @@ jobs: working-directory: ./example-app - name: Login to GitHub Container Registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Build and push - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 with: context: './example-app' file: ./example-app/packages/backend/Dockerfile - push: ${{ (github.event_name == "repository_dispatch") && (github.event.action == "release-published") }} + push: ${{ (github.event_name == 'repository_dispatch') && (github.event.action == 'release-published') }} platforms: linux/amd64,linux/arm64 tags: | ghcr.io/${{ github.repository_owner }}/backstage:latest - ghcr.io/${{ github.repository_owner }}/backstage:${{ github.event.client_payload.version }} + ${{ github.event.client_payload.version && env.TAG_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 e9abba59a3..6864ec67dc 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -28,7 +28,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js 18.x uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -66,7 +66,7 @@ jobs: run: ls microsite/build && ls microsite/build/storybook - name: Deploy both microsite and storybook to gh-pages - uses: JamesIves/github-pages-deploy-action@65b5dfd4f5bcd3a7403bbc2959c144256167464e # v4.5.0 + uses: JamesIves/github-pages-deploy-action@ec9c88baef04b842ca6f0a132fd61c762aa6c1b0 # v4.6.0 with: branch: gh-pages folder: microsite/build diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index 43fafde90b..07c3db0f11 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -19,7 +19,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js 18.x uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -27,7 +27,7 @@ jobs: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v18.x diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index c91fec948e..775d8d00f8 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -65,7 +65,7 @@ jobs: INTEGRATION_TEST_AZURE_TOKEN: ${{ secrets.INTEGRATION_TEST_AZURE_TOKEN }} steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -73,7 +73,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -148,7 +148,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -156,7 +156,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index 54bc8d8782..f8f5efacc4 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -14,5 +14,12 @@ jobs: with: egress-policy: audit - - name: Issue sync - uses: backstage/actions/issue-sync@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + - name: Add issue labels + uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4 + with: + include-title: 1 + include-body: 0 + configuration-path: .github/issue-labeler.yml + enable-versioned-regex: 0 + not-before: 2024-04-19T15:03:51Z + repo-token: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index 18300b074e..72256a8c6e 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -40,7 +40,7 @@ jobs: const prNumber = artifact.name.slice('pr_number-'.length) core.setOutput('pr-number', prNumber); - - uses: backstage/actions/re-review@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + - uses: backstage/actions/re-review@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 89531bf70a..3aa20b1c96 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -23,7 +23,7 @@ jobs: egress-policy: audit - name: PR sync - uses: backstage/actions/pr-sync@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/pr-sync@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 621776d69b..91f1b02fee 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -34,7 +34,7 @@ jobs: egress-policy: audit - name: 'Checkout code' - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: persist-credentials: false @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index f34011348c..5dbd0361c1 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -14,7 +14,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: # Fetch changes to previous commit - required for 'only_changed' in Prettier action fetch-depth: 0 @@ -25,7 +25,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index c2a447e369..8b3be335ed 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -16,7 +16,7 @@ jobs: egress-policy: audit - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: fetch-depth: 2 ref: ${{ github.head_ref }} diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 64dec1905a..b0a2499d43 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -21,7 +21,7 @@ jobs: run: npm install semver@7.3.5 fs-extra@10.0.0 @manypkg/get-packages@1.1.1 - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: path: backstage # 'v' prefix is added here for the tag, we keep it out of the manifest logic @@ -29,7 +29,7 @@ jobs: # Checkout backstage/versions into /backstage/versions, which is where store the output - name: Checkout versions - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: repository: backstage/versions path: backstage/versions diff --git a/.github/workflows/sync_renovate-changesets.yml b/.github/workflows/sync_renovate-changesets.yml index 83b9f8f574..d02e35483c 100644 --- a/.github/workflows/sync_renovate-changesets.yml +++ b/.github/workflows/sync_renovate-changesets.yml @@ -16,7 +16,7 @@ jobs: egress-policy: audit - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: fetch-depth: 2 ref: ${{ github.head_ref }} diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index 02d4d55301..d5a4048044 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -16,7 +16,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js 18.x uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -24,12 +24,12 @@ jobs: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v18.x - name: Create Snyk report - uses: snyk/actions/node@1d672a455ab3339ef0a0021e1ec809165ee12fad # master + uses: snyk/actions/node@8349f9043a8b7f0f3ee8885bf28f0b388d2446e8 # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > @@ -43,6 +43,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Update Github issues - run: yarn ts-node scripts/snyk-github-issue-sync.ts + run: ./scripts/snyk-github-issue-sync.ts env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 7ee4e72d38..70fb8a44d9 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -29,9 +29,9 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@1d672a455ab3339ef0a0021e1ec809165ee12fad # master + uses: snyk/actions/node@8349f9043a8b7f0f3ee8885bf28f0b388d2446e8 # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@1d672a455ab3339ef0a0021e1ec809165ee12fad # master + uses: snyk/actions/node@8349f9043a8b7f0f3ee8885bf28f0b388d2446e8 # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 with: sarif_file: snyk.sarif diff --git a/.github/workflows/sync_version-packages.yml b/.github/workflows/sync_version-packages.yml index 3164e471d2..b2ad80b6da 100644 --- a/.github/workflows/sync_version-packages.yml +++ b/.github/workflows/sync_version-packages.yml @@ -18,7 +18,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: fetch-depth: 20000 fetch-tags: true @@ -26,7 +26,7 @@ jobs: - name: Install Dependencies run: yarn --immutable - name: Create Release Pull Request - uses: backstage/changesets-action@99063c276a7f12e024cb310e7a05a3a5b89449f8 # v2.1.0 + uses: backstage/changesets-action@291bfc1f76d1dcfbf967f5810dc0423592eae09a # v2.3.1 with: # Calls out to `changeset version`, but also runs prettier version: yarn release diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index b4e7d4b904..4a52af21bc 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -31,7 +31,7 @@ jobs: egress-policy: audit - name: checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: setup-node uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -40,7 +40,7 @@ jobs: registry-url: https://registry.npmjs.org/ - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: linux-v18 @@ -53,7 +53,7 @@ jobs: yarn workspace example-backend build - name: Set up Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Generate UUID image name id: uuid @@ -67,7 +67,7 @@ jobs: tags: type=raw,value=60d - name: Build Image - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 with: context: . file: packages/backend/Dockerfile @@ -89,7 +89,7 @@ jobs: egress-policy: audit - name: Checkout git repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Render Compose File run: | # update image after the build above diff --git a/.github/workflows/uffizzi-preview.yaml b/.github/workflows/uffizzi-preview.yaml index 9db724fa96..b4c5aa3caa 100644 --- a/.github/workflows/uffizzi-preview.yaml +++ b/.github/workflows/uffizzi-preview.yaml @@ -76,7 +76,7 @@ jobs: - name: Cache Manifests File if: ${{ steps.event.outputs.ACTION != 'closed' }} - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: manifests.rendered.yml key: ${{ steps.hash.outputs.MANIFESTS_FILE_HASH }} @@ -106,7 +106,7 @@ jobs: # Identify comment to be updated - name: Find comment for Ephemeral Environment - uses: peter-evans/find-comment@d5fe37641ad8451bdd80312415672ba26c86575e # v3 + uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3 id: find-comment with: issue-number: ${{ needs.cache-manifests-file.outputs.pr-number }} @@ -140,7 +140,7 @@ jobs: - name: Fetch cached Manifests File id: cache - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4 + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4 with: path: manifests.rendered.yml key: ${{ needs.cache-manifests-file.outputs.manifests-cache-key }} @@ -220,7 +220,7 @@ jobs: # Identify comment to be updated - name: Find comment for Ephemeral Environment - uses: peter-evans/find-comment@d5fe37641ad8451bdd80312415672ba26c86575e # v3 + uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3 id: find-comment with: issue-number: ${{ needs.cache-manifests-file.outputs.pr-number }} diff --git a/.github/workflows/verify_accessibility.yml b/.github/workflows/verify_accessibility.yml index cbce7ce6ab..1c25d709cb 100644 --- a/.github/workflows/verify_accessibility.yml +++ b/.github/workflows/verify_accessibility.yml @@ -24,13 +24,13 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Use Node.js 18.x uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18.x - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v18.x - name: run Lighthouse CI diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index 7c7ef286db..e82577763e 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -47,7 +47,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/autobuild@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@379614612a29c9e28f31f39a59013eb8012a51f0 # v3.24.3 + uses: github/codeql-action/analyze@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 diff --git a/.github/workflows/verify_docs-quality.yml b/.github/workflows/verify_docs-quality.yml index 2065af00fb..3550df6fc0 100644 --- a/.github/workflows/verify_docs-quality.yml +++ b/.github/workflows/verify_docs-quality.yml @@ -16,7 +16,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 # Vale does not support file excludes, so we use the script to generate a list of files instead # The action also does not allow args or a local config file to be passed in, so the files array diff --git a/.github/workflows/verify_e2e-kubernetes.yml b/.github/workflows/verify_e2e-kubernetes.yml index 2304bdbb26..6ff41c8b74 100644 --- a/.github/workflows/verify_e2e-kubernetes.yml +++ b/.github/workflows/verify_e2e-kubernetes.yml @@ -26,7 +26,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -35,7 +35,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index dc62ce5725..a750dfea3b 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -45,7 +45,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Configure Git run: | @@ -58,7 +58,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index 0bce75f720..3bcda5f2b6 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -34,8 +34,8 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: '3.9' diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index ae2e7c7e99..078ddd6855 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -42,7 +42,7 @@ jobs: git config --global core.autocrlf false git config --global core.eol lf - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Configure Git run: | @@ -56,7 +56,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: setup python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: '3.10' @@ -78,7 +78,7 @@ jobs: uses: browser-actions/setup-chrome@803ef6dfb4fdf22089c9563225d95e4a515820a0 # latest - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_fossa.yml b/.github/workflows/verify_fossa.yml index fd555159b1..801c5fbd28 100644 --- a/.github/workflows/verify_fossa.yml +++ b/.github/workflows/verify_fossa.yml @@ -19,7 +19,7 @@ jobs: egress-policy: audit - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Install Fossa run: "curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | bash" diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index cee89a8ba2..68378aa086 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -28,12 +28,18 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js 18.x uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18.x + - uses: actions/setup-python@v5 + with: + python-version: '3.9' + + - name: Install MkDocs dependencies + run: pip install mkdocs mkdocs-techdocs-core # Skip caching of microsite dependencies, it keeps the global cache size # smaller, which make Windows builds a lot faster for the rest of the project. @@ -47,9 +53,6 @@ jobs: - name: build API reference run: yarn build:api-docs - - name: Install MkDocs dependencies - run: pip3 install mkdocs mkdocs-techdocs-core - - name: Build MkDocs for TechDocs run: mkdocs build --strict diff --git a/.github/workflows/verify_microsite_accessibility.yml b/.github/workflows/verify_microsite_accessibility.yml index fa5e54905f..e0fea1a72c 100644 --- a/.github/workflows/verify_microsite_accessibility.yml +++ b/.github/workflows/verify_microsite_accessibility.yml @@ -19,7 +19,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Use Node.js 18.x uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 70fb16ac48..940c136797 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -32,7 +32,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: fetch-depth: 0 # Required to retrieve git history @@ -42,7 +42,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@af61233abb88019335b07ab855873d991f43d25a # v0.6.7 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: storybook yarn install @@ -51,7 +51,7 @@ jobs: - run: yarn build-storybook - - uses: chromaui/action@c9067691aca4a28d6fbb40d9eea6e144369fbcae # v10 + - uses: chromaui/action@3dcb6636a4f8eed347ef6214f5d74d2b5fee45e4 # v11 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 7d772bd765..32b0452eec 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -33,7 +33,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 diff --git a/.gitignore b/.gitignore index e499faf29e..5ba3da3148 100644 --- a/.gitignore +++ b/.gitignore @@ -166,3 +166,7 @@ plugins-report.csv # Temporary knip configs knip.json + +# Schemathesis temporary files +.hypothesis/ +.cassettes/ diff --git a/.lighthouseci/scripts/guest-auth.js b/.lighthouseci/scripts/guest-auth.js index 7f686cbbc6..9f0d35bcf7 100644 --- a/.lighthouseci/scripts/guest-auth.js +++ b/.lighthouseci/scripts/guest-auth.js @@ -7,5 +7,4 @@ module.exports = async (browser, context) => { await page.evaluate(() => { localStorage.setItem('@backstage/core:SignInPage:provider', 'guest'); }); - await page.goto('http://localhost:3000'); }; diff --git a/.prettierignore b/.prettierignore index c561036ebb..3a16bd1388 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,6 +11,7 @@ cli-report.md plugins/scaffolder-backend/sample-templates .vscode dist-types +.eslintrc.js # reduce the barrier for adopters to add themselves ADOPTERS.md diff --git a/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs b/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs index 911cd235e8..4e89c7c352 100644 --- a/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs +++ b/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs @@ -3,8 +3,8 @@ module.exports = { name: "@yarnpkg/plugin-workspace-tools", factory: function (require) { -var plugin=(()=>{var wr=Object.create,me=Object.defineProperty,Sr=Object.defineProperties,vr=Object.getOwnPropertyDescriptor,Hr=Object.getOwnPropertyDescriptors,$r=Object.getOwnPropertyNames,et=Object.getOwnPropertySymbols,kr=Object.getPrototypeOf,tt=Object.prototype.hasOwnProperty,Tr=Object.prototype.propertyIsEnumerable;var rt=(e,t,r)=>t in e?me(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,B=(e,t)=>{for(var r in t||(t={}))tt.call(t,r)&&rt(e,r,t[r]);if(et)for(var r of et(t))Tr.call(t,r)&&rt(e,r,t[r]);return e},Q=(e,t)=>Sr(e,Hr(t)),Lr=e=>me(e,"__esModule",{value:!0});var K=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Or=(e,t)=>{for(var r in t)me(e,r,{get:t[r],enumerable:!0})},Nr=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of $r(t))!tt.call(e,n)&&n!=="default"&&me(e,n,{get:()=>t[n],enumerable:!(r=vr(t,n))||r.enumerable});return e},X=e=>Nr(Lr(me(e!=null?wr(kr(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var $e=K(te=>{"use strict";te.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1;te.find=(e,t)=>e.nodes.find(r=>r.type===t);te.exceedsLimit=(e,t,r=1,n)=>n===!1||!te.isInteger(e)||!te.isInteger(t)?!1:(Number(t)-Number(e))/Number(r)>=n;te.escapeNode=(e,t=0,r)=>{let n=e.nodes[t];!n||(r&&n.type===r||n.type==="open"||n.type==="close")&&n.escaped!==!0&&(n.value="\\"+n.value,n.escaped=!0)};te.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0==0?(e.invalid=!0,!0):!1;te.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0==0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1;te.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0;te.reduce=e=>e.reduce((t,r)=>(r.type==="text"&&t.push(r.value),r.type==="range"&&(r.type="text"),t),[]);te.flatten=(...e)=>{let t=[],r=n=>{for(let s=0;s<n.length;s++){let a=n[s];Array.isArray(a)?r(a,t):a!==void 0&&t.push(a)}return t};return r(e),t}});var ke=K((is,at)=>{"use strict";var it=$e();at.exports=(e,t={})=>{let r=(n,s={})=>{let a=t.escapeInvalid&&it.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o="";if(n.value)return(a||i)&&it.isOpenOrClose(n)?"\\"+n.value:n.value;if(n.value)return n.value;if(n.nodes)for(let h of n.nodes)o+=r(h);return o};return r(e)}});var ct=K((os,ot)=>{"use strict";ot.exports=function(e){return typeof e=="number"?e-e==0:typeof e=="string"&&e.trim()!==""?Number.isFinite?Number.isFinite(+e):isFinite(+e):!1}});var At=K((cs,ut)=>{"use strict";var lt=ct(),pe=(e,t,r)=>{if(lt(e)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(t===void 0||e===t)return String(e);if(lt(t)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let n=B({relaxZeros:!0},r);typeof n.strictZeros=="boolean"&&(n.relaxZeros=n.strictZeros===!1);let s=String(n.relaxZeros),a=String(n.shorthand),i=String(n.capture),o=String(n.wrap),h=e+":"+t+"="+s+a+i+o;if(pe.cache.hasOwnProperty(h))return pe.cache[h].result;let g=Math.min(e,t),f=Math.max(e,t);if(Math.abs(g-f)===1){let R=e+"|"+t;return n.capture?`(${R})`:n.wrap===!1?R:`(?:${R})`}let A=ft(e)||ft(t),p={min:e,max:t,a:g,b:f},k=[],y=[];if(A&&(p.isPadded=A,p.maxLen=String(p.max).length),g<0){let R=f<0?Math.abs(f):1;y=pt(R,Math.abs(g),p,n),g=p.a=0}return f>=0&&(k=pt(g,f,p,n)),p.negatives=y,p.positives=k,p.result=Ir(y,k,n),n.capture===!0?p.result=`(${p.result})`:n.wrap!==!1&&k.length+y.length>1&&(p.result=`(?:${p.result})`),pe.cache[h]=p,p.result};function Ir(e,t,r){let n=Pe(e,t,"-",!1,r)||[],s=Pe(t,e,"",!1,r)||[],a=Pe(e,t,"-?",!0,r)||[];return n.concat(a).concat(s).join("|")}function Mr(e,t){let r=1,n=1,s=ht(e,r),a=new Set([t]);for(;e<=s&&s<=t;)a.add(s),r+=1,s=ht(e,r);for(s=dt(t+1,n)-1;e<s&&s<=t;)a.add(s),n+=1,s=dt(t+1,n)-1;return a=[...a],a.sort(Br),a}function Ur(e,t,r){if(e===t)return{pattern:e,count:[],digits:0};let n=Pr(e,t),s=n.length,a="",i=0;for(let o=0;o<s;o++){let[h,g]=n[o];h===g?a+=h:h!=="0"||g!=="9"?a+=Dr(h,g,r):i++}return i&&(a+=r.shorthand===!0?"\\d":"[0-9]"),{pattern:a,count:[i],digits:s}}function pt(e,t,r,n){let s=Mr(e,t),a=[],i=e,o;for(let h=0;h<s.length;h++){let g=s[h],f=Ur(String(i),String(g),n),A="";if(!r.isPadded&&o&&o.pattern===f.pattern){o.count.length>1&&o.count.pop(),o.count.push(f.count[0]),o.string=o.pattern+gt(o.count),i=g+1;continue}r.isPadded&&(A=Gr(g,r,n)),f.string=A+f.pattern+gt(f.count),a.push(f),i=g+1,o=f}return a}function Pe(e,t,r,n,s){let a=[];for(let i of e){let{string:o}=i;!n&&!mt(t,"string",o)&&a.push(r+o),n&&mt(t,"string",o)&&a.push(r+o)}return a}function Pr(e,t){let r=[];for(let n=0;n<e.length;n++)r.push([e[n],t[n]]);return r}function Br(e,t){return e>t?1:t>e?-1:0}function mt(e,t,r){return e.some(n=>n[t]===r)}function ht(e,t){return Number(String(e).slice(0,-t)+"9".repeat(t))}function dt(e,t){return e-e%Math.pow(10,t)}function gt(e){let[t=0,r=""]=e;return r||t>1?`{${t+(r?","+r:"")}}`:""}function Dr(e,t,r){return`[${e}${t-e==1?"":"-"}${t}]`}function ft(e){return/^-?(0+)\d/.test(e)}function Gr(e,t,r){if(!t.isPadded)return e;let n=Math.abs(t.maxLen-String(e).length),s=r.relaxZeros!==!1;switch(n){case 0:return"";case 1:return s?"0?":"0";case 2:return s?"0{0,2}":"00";default:return s?`0{0,${n}}`:`0{${n}}`}}pe.cache={};pe.clearCache=()=>pe.cache={};ut.exports=pe});var Ge=K((us,Rt)=>{"use strict";var qr=require("util"),yt=At(),bt=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Kr=e=>t=>e===!0?Number(t):String(t),De=e=>typeof e=="number"||typeof e=="string"&&e!=="",Re=e=>Number.isInteger(+e),Ue=e=>{let t=`${e}`,r=-1;if(t[0]==="-"&&(t=t.slice(1)),t==="0")return!1;for(;t[++r]==="0";);return r>0},Wr=(e,t,r)=>typeof e=="string"||typeof t=="string"?!0:r.stringify===!0,jr=(e,t,r)=>{if(t>0){let n=e[0]==="-"?"-":"";n&&(e=e.slice(1)),e=n+e.padStart(n?t-1:t,"0")}return r===!1?String(e):e},_t=(e,t)=>{let r=e[0]==="-"?"-":"";for(r&&(e=e.slice(1),t--);e.length<t;)e="0"+e;return r?"-"+e:e},Fr=(e,t)=>{e.negatives.sort((i,o)=>i<o?-1:i>o?1:0),e.positives.sort((i,o)=>i<o?-1:i>o?1:0);let r=t.capture?"":"?:",n="",s="",a;return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(s=`-(${r}${e.negatives.join("|")})`),n&&s?a=`${n}|${s}`:a=n||s,t.wrap?`(${r}${a})`:a},Et=(e,t,r,n)=>{if(r)return yt(e,t,B({wrap:!1},n));let s=String.fromCharCode(e);if(e===t)return s;let a=String.fromCharCode(t);return`[${s}-${a}]`},xt=(e,t,r)=>{if(Array.isArray(e)){let n=r.wrap===!0,s=r.capture?"":"?:";return n?`(${s}${e.join("|")})`:e.join("|")}return yt(e,t,r)},Ct=(...e)=>new RangeError("Invalid range arguments: "+qr.inspect(...e)),wt=(e,t,r)=>{if(r.strictRanges===!0)throw Ct([e,t]);return[]},Qr=(e,t)=>{if(t.strictRanges===!0)throw new TypeError(`Expected step "${e}" to be a number`);return[]},Xr=(e,t,r=1,n={})=>{let s=Number(e),a=Number(t);if(!Number.isInteger(s)||!Number.isInteger(a)){if(n.strictRanges===!0)throw Ct([e,t]);return[]}s===0&&(s=0),a===0&&(a=0);let i=s>a,o=String(e),h=String(t),g=String(r);r=Math.max(Math.abs(r),1);let f=Ue(o)||Ue(h)||Ue(g),A=f?Math.max(o.length,h.length,g.length):0,p=f===!1&&Wr(e,t,n)===!1,k=n.transform||Kr(p);if(n.toRegex&&r===1)return Et(_t(e,A),_t(t,A),!0,n);let y={negatives:[],positives:[]},R=T=>y[T<0?"negatives":"positives"].push(Math.abs(T)),_=[],x=0;for(;i?s>=a:s<=a;)n.toRegex===!0&&r>1?R(s):_.push(jr(k(s,x),A,p)),s=i?s-r:s+r,x++;return n.toRegex===!0?r>1?Fr(y,n):xt(_,null,B({wrap:!1},n)):_},Zr=(e,t,r=1,n={})=>{if(!Re(e)&&e.length>1||!Re(t)&&t.length>1)return wt(e,t,n);let s=n.transform||(p=>String.fromCharCode(p)),a=`${e}`.charCodeAt(0),i=`${t}`.charCodeAt(0),o=a>i,h=Math.min(a,i),g=Math.max(a,i);if(n.toRegex&&r===1)return Et(h,g,!1,n);let f=[],A=0;for(;o?a>=i:a<=i;)f.push(s(a,A)),a=o?a-r:a+r,A++;return n.toRegex===!0?xt(f,null,{wrap:!1,options:n}):f},Te=(e,t,r,n={})=>{if(t==null&&De(e))return[e];if(!De(e)||!De(t))return wt(e,t,n);if(typeof r=="function")return Te(e,t,1,{transform:r});if(bt(r))return Te(e,t,0,r);let s=B({},n);return s.capture===!0&&(s.wrap=!0),r=r||s.step||1,Re(r)?Re(e)&&Re(t)?Xr(e,t,r,s):Zr(e,t,Math.max(Math.abs(r),1),s):r!=null&&!bt(r)?Qr(r,s):Te(e,t,1,r)};Rt.exports=Te});var Ht=K((ls,St)=>{"use strict";var Yr=Ge(),vt=$e(),zr=(e,t={})=>{let r=(n,s={})=>{let a=vt.isInvalidBrace(s),i=n.invalid===!0&&t.escapeInvalid===!0,o=a===!0||i===!0,h=t.escapeInvalid===!0?"\\":"",g="";if(n.isOpen===!0||n.isClose===!0)return h+n.value;if(n.type==="open")return o?h+n.value:"(";if(n.type==="close")return o?h+n.value:")";if(n.type==="comma")return n.prev.type==="comma"?"":o?n.value:"|";if(n.value)return n.value;if(n.nodes&&n.ranges>0){let f=vt.reduce(n.nodes),A=Yr(...f,Q(B({},t),{wrap:!1,toRegex:!0}));if(A.length!==0)return f.length>1&&A.length>1?`(${A})`:A}if(n.nodes)for(let f of n.nodes)g+=r(f,n);return g};return r(e)};St.exports=zr});var Tt=K((ps,$t)=>{"use strict";var Vr=Ge(),kt=ke(),he=$e(),fe=(e="",t="",r=!1)=>{let n=[];if(e=[].concat(e),t=[].concat(t),!t.length)return e;if(!e.length)return r?he.flatten(t).map(s=>`{${s}}`):t;for(let s of e)if(Array.isArray(s))for(let a of s)n.push(fe(a,t,r));else for(let a of t)r===!0&&typeof a=="string"&&(a=`{${a}}`),n.push(Array.isArray(a)?fe(s,a,r):s+a);return he.flatten(n)},Jr=(e,t={})=>{let r=t.rangeLimit===void 0?1e3:t.rangeLimit,n=(s,a={})=>{s.queue=[];let i=a,o=a.queue;for(;i.type!=="brace"&&i.type!=="root"&&i.parent;)i=i.parent,o=i.queue;if(s.invalid||s.dollar){o.push(fe(o.pop(),kt(s,t)));return}if(s.type==="brace"&&s.invalid!==!0&&s.nodes.length===2){o.push(fe(o.pop(),["{}"]));return}if(s.nodes&&s.ranges>0){let A=he.reduce(s.nodes);if(he.exceedsLimit(...A,t.step,r))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let p=Vr(...A,t);p.length===0&&(p=kt(s,t)),o.push(fe(o.pop(),p)),s.nodes=[];return}let h=he.encloseBrace(s),g=s.queue,f=s;for(;f.type!=="brace"&&f.type!=="root"&&f.parent;)f=f.parent,g=f.queue;for(let A=0;A<s.nodes.length;A++){let p=s.nodes[A];if(p.type==="comma"&&s.type==="brace"){A===1&&g.push(""),g.push("");continue}if(p.type==="close"){o.push(fe(o.pop(),g,h));continue}if(p.value&&p.type!=="open"){g.push(fe(g.pop(),p.value));continue}p.nodes&&n(p,s)}return g};return he.flatten(n(e))};$t.exports=Jr});var Ot=K((fs,Lt)=>{"use strict";Lt.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` -`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Pt=K((hs,Nt)=>{"use strict";var en=ke(),{MAX_LENGTH:It,CHAR_BACKSLASH:qe,CHAR_BACKTICK:tn,CHAR_COMMA:rn,CHAR_DOT:nn,CHAR_LEFT_PARENTHESES:sn,CHAR_RIGHT_PARENTHESES:an,CHAR_LEFT_CURLY_BRACE:on,CHAR_RIGHT_CURLY_BRACE:cn,CHAR_LEFT_SQUARE_BRACKET:Bt,CHAR_RIGHT_SQUARE_BRACKET:Mt,CHAR_DOUBLE_QUOTE:un,CHAR_SINGLE_QUOTE:ln,CHAR_NO_BREAK_SPACE:pn,CHAR_ZERO_WIDTH_NOBREAK_SPACE:fn}=Ot(),hn=(e,t={})=>{if(typeof e!="string")throw new TypeError("Expected a string");let r=t||{},n=typeof r.maxLength=="number"?Math.min(It,r.maxLength):It;if(e.length>n)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${n})`);let s={type:"root",input:e,nodes:[]},a=[s],i=s,o=s,h=0,g=e.length,f=0,A=0,p,k={},y=()=>e[f++],R=_=>{if(_.type==="text"&&o.type==="dot"&&(o.type="text"),o&&o.type==="text"&&_.type==="text"){o.value+=_.value;return}return i.nodes.push(_),_.parent=i,_.prev=o,o=_,_};for(R({type:"bos"});f<g;)if(i=a[a.length-1],p=y(),!(p===fn||p===pn)){if(p===qe){R({type:"text",value:(t.keepEscaping?p:"")+y()});continue}if(p===Mt){R({type:"text",value:"\\"+p});continue}if(p===Bt){h++;let _=!0,x;for(;f<g&&(x=y());){if(p+=x,x===Bt){h++;continue}if(x===qe){p+=y();continue}if(x===Mt&&(h--,h===0))break}R({type:"text",value:p});continue}if(p===sn){i=R({type:"paren",nodes:[]}),a.push(i),R({type:"text",value:p});continue}if(p===an){if(i.type!=="paren"){R({type:"text",value:p});continue}i=a.pop(),R({type:"text",value:p}),i=a[a.length-1];continue}if(p===un||p===ln||p===tn){let _=p,x;for(t.keepQuotes!==!0&&(p="");f<g&&(x=y());){if(x===qe){p+=x+y();continue}if(x===_){t.keepQuotes===!0&&(p+=x);break}p+=x}R({type:"text",value:p});continue}if(p===on){A++;let _=o.value&&o.value.slice(-1)==="$"||i.dollar===!0;i=R({type:"brace",open:!0,close:!1,dollar:_,depth:A,commas:0,ranges:0,nodes:[]}),a.push(i),R({type:"open",value:p});continue}if(p===cn){if(i.type!=="brace"){R({type:"text",value:p});continue}let _="close";i=a.pop(),i.close=!0,R({type:_,value:p}),A--,i=a[a.length-1];continue}if(p===rn&&A>0){if(i.ranges>0){i.ranges=0;let _=i.nodes.shift();i.nodes=[_,{type:"text",value:en(i)}]}R({type:"comma",value:p}),i.commas++;continue}if(p===nn&&A>0&&i.commas===0){let _=i.nodes;if(A===0||_.length===0){R({type:"text",value:p});continue}if(o.type==="dot"){if(i.range=[],o.value+=p,o.type="range",i.nodes.length!==3&&i.nodes.length!==5){i.invalid=!0,i.ranges=0,o.type="text";continue}i.ranges++,i.args=[];continue}if(o.type==="range"){_.pop();let x=_[_.length-1];x.value+=o.value+p,o=x,i.ranges--;continue}R({type:"dot",value:p});continue}R({type:"text",value:p})}do if(i=a.pop(),i.type!=="root"){i.nodes.forEach(T=>{T.nodes||(T.type==="open"&&(T.isOpen=!0),T.type==="close"&&(T.isClose=!0),T.nodes||(T.type="text"),T.invalid=!0)});let _=a[a.length-1],x=_.nodes.indexOf(i);_.nodes.splice(x,1,...i.nodes)}while(a.length>0);return R({type:"eos"}),s};Nt.exports=hn});var Gt=K((ds,Dt)=>{"use strict";var Ut=ke(),dn=Ht(),gn=Tt(),mn=Pt(),V=(e,t={})=>{let r=[];if(Array.isArray(e))for(let n of e){let s=V.create(n,t);Array.isArray(s)?r.push(...s):r.push(s)}else r=[].concat(V.create(e,t));return t&&t.expand===!0&&t.nodupes===!0&&(r=[...new Set(r)]),r};V.parse=(e,t={})=>mn(e,t);V.stringify=(e,t={})=>typeof e=="string"?Ut(V.parse(e,t),t):Ut(e,t);V.compile=(e,t={})=>(typeof e=="string"&&(e=V.parse(e,t)),dn(e,t));V.expand=(e,t={})=>{typeof e=="string"&&(e=V.parse(e,t));let r=gn(e,t);return t.noempty===!0&&(r=r.filter(Boolean)),t.nodupes===!0&&(r=[...new Set(r)]),r};V.create=(e,t={})=>e===""||e.length<3?[e]:t.expand!==!0?V.compile(e,t):V.expand(e,t);Dt.exports=V});var ye=K((gs,qt)=>{"use strict";var An=require("path"),ie="\\\\/",Kt=`[^${ie}]`,ce="\\.",Rn="\\+",yn="\\?",Le="\\/",bn="(?=.)",Wt="[^/]",Ke=`(?:${Le}|$)`,jt=`(?:^|${Le})`,We=`${ce}{1,2}${Ke}`,_n=`(?!${ce})`,En=`(?!${jt}${We})`,xn=`(?!${ce}{0,1}${Ke})`,Cn=`(?!${We})`,wn=`[^.${Le}]`,Sn=`${Wt}*?`,Ft={DOT_LITERAL:ce,PLUS_LITERAL:Rn,QMARK_LITERAL:yn,SLASH_LITERAL:Le,ONE_CHAR:bn,QMARK:Wt,END_ANCHOR:Ke,DOTS_SLASH:We,NO_DOT:_n,NO_DOTS:En,NO_DOT_SLASH:xn,NO_DOTS_SLASH:Cn,QMARK_NO_DOT:wn,STAR:Sn,START_ANCHOR:jt},vn=Q(B({},Ft),{SLASH_LITERAL:`[${ie}]`,QMARK:Kt,STAR:`${Kt}*?`,DOTS_SLASH:`${ce}{1,2}(?:[${ie}]|$)`,NO_DOT:`(?!${ce})`,NO_DOTS:`(?!(?:^|[${ie}])${ce}{1,2}(?:[${ie}]|$))`,NO_DOT_SLASH:`(?!${ce}{0,1}(?:[${ie}]|$))`,NO_DOTS_SLASH:`(?!${ce}{1,2}(?:[${ie}]|$))`,QMARK_NO_DOT:`[^.${ie}]`,START_ANCHOR:`(?:^|[${ie}])`,END_ANCHOR:`(?:[${ie}]|$)`}),Hn={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};qt.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:Hn,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:An.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===!0?vn:Ft}}});var be=K(Z=>{"use strict";var $n=require("path"),kn=process.platform==="win32",{REGEX_BACKSLASH:Tn,REGEX_REMOVE_BACKSLASH:Ln,REGEX_SPECIAL_CHARS:On,REGEX_SPECIAL_CHARS_GLOBAL:Nn}=ye();Z.isObject=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);Z.hasRegexChars=e=>On.test(e);Z.isRegexChar=e=>e.length===1&&Z.hasRegexChars(e);Z.escapeRegex=e=>e.replace(Nn,"\\$1");Z.toPosixSlashes=e=>e.replace(Tn,"/");Z.removeBackslashes=e=>e.replace(Ln,t=>t==="\\"?"":t);Z.supportsLookbehinds=()=>{let e=process.version.slice(1).split(".").map(Number);return e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10};Z.isWindows=e=>e&&typeof e.windows=="boolean"?e.windows:kn===!0||$n.sep==="\\";Z.escapeLast=(e,t,r)=>{let n=e.lastIndexOf(t,r);return n===-1?e:e[n-1]==="\\"?Z.escapeLast(e,t,n-1):`${e.slice(0,n)}\\${e.slice(n)}`};Z.removePrefix=(e,t={})=>{let r=e;return r.startsWith("./")&&(r=r.slice(2),t.prefix="./"),r};Z.wrapOutput=(e,t={},r={})=>{let n=r.contains?"":"^",s=r.contains?"":"$",a=`${n}(?:${e})${s}`;return t.negated===!0&&(a=`(?:^(?!${a}).*$)`),a}});var er=K((As,Qt)=>{"use strict";var Xt=be(),{CHAR_ASTERISK:je,CHAR_AT:In,CHAR_BACKWARD_SLASH:_e,CHAR_COMMA:Bn,CHAR_DOT:Fe,CHAR_EXCLAMATION_MARK:Qe,CHAR_FORWARD_SLASH:Zt,CHAR_LEFT_CURLY_BRACE:Xe,CHAR_LEFT_PARENTHESES:Ze,CHAR_LEFT_SQUARE_BRACKET:Mn,CHAR_PLUS:Pn,CHAR_QUESTION_MARK:Yt,CHAR_RIGHT_CURLY_BRACE:Dn,CHAR_RIGHT_PARENTHESES:zt,CHAR_RIGHT_SQUARE_BRACKET:Un}=ye(),Vt=e=>e===Zt||e===_e,Jt=e=>{e.isPrefix!==!0&&(e.depth=e.isGlobstar?Infinity:1)},Gn=(e,t)=>{let r=t||{},n=e.length-1,s=r.parts===!0||r.scanToEnd===!0,a=[],i=[],o=[],h=e,g=-1,f=0,A=0,p=!1,k=!1,y=!1,R=!1,_=!1,x=!1,T=!1,O=!1,W=!1,G=!1,ne=0,E,b,C={value:"",depth:0,isGlob:!1},M=()=>g>=n,l=()=>h.charCodeAt(g+1),H=()=>(E=b,h.charCodeAt(++g));for(;g<n;){b=H();let I;if(b===_e){T=C.backslashes=!0,b=H(),b===Xe&&(x=!0);continue}if(x===!0||b===Xe){for(ne++;M()!==!0&&(b=H());){if(b===_e){T=C.backslashes=!0,H();continue}if(b===Xe){ne++;continue}if(x!==!0&&b===Fe&&(b=H())===Fe){if(p=C.isBrace=!0,y=C.isGlob=!0,G=!0,s===!0)continue;break}if(x!==!0&&b===Bn){if(p=C.isBrace=!0,y=C.isGlob=!0,G=!0,s===!0)continue;break}if(b===Dn&&(ne--,ne===0)){x=!1,p=C.isBrace=!0,G=!0;break}}if(s===!0)continue;break}if(b===Zt){if(a.push(g),i.push(C),C={value:"",depth:0,isGlob:!1},G===!0)continue;if(E===Fe&&g===f+1){f+=2;continue}A=g+1;continue}if(r.noext!==!0&&(b===Pn||b===In||b===je||b===Yt||b===Qe)===!0&&l()===Ze){if(y=C.isGlob=!0,R=C.isExtglob=!0,G=!0,b===Qe&&g===f&&(W=!0),s===!0){for(;M()!==!0&&(b=H());){if(b===_e){T=C.backslashes=!0,b=H();continue}if(b===zt){y=C.isGlob=!0,G=!0;break}}continue}break}if(b===je){if(E===je&&(_=C.isGlobstar=!0),y=C.isGlob=!0,G=!0,s===!0)continue;break}if(b===Yt){if(y=C.isGlob=!0,G=!0,s===!0)continue;break}if(b===Mn){for(;M()!==!0&&(I=H());){if(I===_e){T=C.backslashes=!0,H();continue}if(I===Un){k=C.isBracket=!0,y=C.isGlob=!0,G=!0;break}}if(s===!0)continue;break}if(r.nonegate!==!0&&b===Qe&&g===f){O=C.negated=!0,f++;continue}if(r.noparen!==!0&&b===Ze){if(y=C.isGlob=!0,s===!0){for(;M()!==!0&&(b=H());){if(b===Ze){T=C.backslashes=!0,b=H();continue}if(b===zt){G=!0;break}}continue}break}if(y===!0){if(G=!0,s===!0)continue;break}}r.noext===!0&&(R=!1,y=!1);let w=h,j="",c="";f>0&&(j=h.slice(0,f),h=h.slice(f),A-=f),w&&y===!0&&A>0?(w=h.slice(0,A),c=h.slice(A)):y===!0?(w="",c=h):w=h,w&&w!==""&&w!=="/"&&w!==h&&Vt(w.charCodeAt(w.length-1))&&(w=w.slice(0,-1)),r.unescape===!0&&(c&&(c=Xt.removeBackslashes(c)),w&&T===!0&&(w=Xt.removeBackslashes(w)));let u={prefix:j,input:e,start:f,base:w,glob:c,isBrace:p,isBracket:k,isGlob:y,isExtglob:R,isGlobstar:_,negated:O,negatedExtglob:W};if(r.tokens===!0&&(u.maxDepth=0,Vt(b)||i.push(C),u.tokens=i),r.parts===!0||r.tokens===!0){let I;for(let $=0;$<a.length;$++){let ee=I?I+1:f,se=a[$],z=e.slice(ee,se);r.tokens&&($===0&&f!==0?(i[$].isPrefix=!0,i[$].value=j):i[$].value=z,Jt(i[$]),u.maxDepth+=i[$].depth),($!==0||z!=="")&&o.push(z),I=se}if(I&&I+1<e.length){let $=e.slice(I+1);o.push($),r.tokens&&(i[i.length-1].value=$,Jt(i[i.length-1]),u.maxDepth+=i[i.length-1].depth)}u.slashes=a,u.parts=o}return u};Qt.exports=Gn});var sr=K((Rs,tr)=>{"use strict";var Oe=ye(),J=be(),{MAX_LENGTH:Ne,POSIX_REGEX_SOURCE:qn,REGEX_NON_SPECIAL_CHARS:Kn,REGEX_SPECIAL_CHARS_BACKREF:Wn,REPLACEMENTS:rr}=Oe,jn=(e,t)=>{if(typeof t.expandRange=="function")return t.expandRange(...e,t);e.sort();let r=`[${e.join("-")}]`;try{new RegExp(r)}catch(n){return e.map(s=>J.escapeRegex(s)).join("..")}return r},de=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`,nr=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");e=rr[e]||e;let r=B({},t),n=typeof r.maxLength=="number"?Math.min(Ne,r.maxLength):Ne,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);let a={type:"bos",value:"",output:r.prepend||""},i=[a],o=r.capture?"":"?:",h=J.isWindows(t),g=Oe.globChars(h),f=Oe.extglobChars(g),{DOT_LITERAL:A,PLUS_LITERAL:p,SLASH_LITERAL:k,ONE_CHAR:y,DOTS_SLASH:R,NO_DOT:_,NO_DOT_SLASH:x,NO_DOTS_SLASH:T,QMARK:O,QMARK_NO_DOT:W,STAR:G,START_ANCHOR:ne}=g,E=m=>`(${o}(?:(?!${ne}${m.dot?R:A}).)*?)`,b=r.dot?"":_,C=r.dot?O:W,M=r.bash===!0?E(r):G;r.capture&&(M=`(${M})`),typeof r.noext=="boolean"&&(r.noextglob=r.noext);let l={input:e,index:-1,start:0,dot:r.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:i};e=J.removePrefix(e,l),s=e.length;let H=[],w=[],j=[],c=a,u,I=()=>l.index===s-1,$=l.peek=(m=1)=>e[l.index+m],ee=l.advance=()=>e[++l.index]||"",se=()=>e.slice(l.index+1),z=(m="",L=0)=>{l.consumed+=m,l.index+=L},Ce=m=>{l.output+=m.output!=null?m.output:m.value,z(m.value)},xr=()=>{let m=1;for(;$()==="!"&&($(2)!=="("||$(3)==="?");)ee(),l.start++,m++;return m%2==0?!1:(l.negated=!0,l.start++,!0)},we=m=>{l[m]++,j.push(m)},ue=m=>{l[m]--,j.pop()},v=m=>{if(c.type==="globstar"){let L=l.braces>0&&(m.type==="comma"||m.type==="brace"),d=m.extglob===!0||H.length&&(m.type==="pipe"||m.type==="paren");m.type!=="slash"&&m.type!=="paren"&&!L&&!d&&(l.output=l.output.slice(0,-c.output.length),c.type="star",c.value="*",c.output=M,l.output+=c.output)}if(H.length&&m.type!=="paren"&&(H[H.length-1].inner+=m.value),(m.value||m.output)&&Ce(m),c&&c.type==="text"&&m.type==="text"){c.value+=m.value,c.output=(c.output||"")+m.value;return}m.prev=c,i.push(m),c=m},Se=(m,L)=>{let d=Q(B({},f[L]),{conditions:1,inner:""});d.prev=c,d.parens=l.parens,d.output=l.output;let S=(r.capture?"(":"")+d.open;we("parens"),v({type:m,value:L,output:l.output?"":y}),v({type:"paren",extglob:!0,value:ee(),output:S}),H.push(d)},Cr=m=>{let L=m.close+(r.capture?")":""),d;if(m.type==="negate"){let S=M;m.inner&&m.inner.length>1&&m.inner.includes("/")&&(S=E(r)),(S!==M||I()||/^\)+$/.test(se()))&&(L=m.close=`)$))${S}`),m.inner.includes("*")&&(d=se())&&/^\.[^\\/.]+$/.test(d)&&(L=m.close=`)${d})${S})`),m.prev.type==="bos"&&(l.negatedExtglob=!0)}v({type:"paren",extglob:!0,value:u,output:L}),ue("parens")};if(r.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(e)){let m=!1,L=e.replace(Wn,(d,S,P,F,q,Me)=>F==="\\"?(m=!0,d):F==="?"?S?S+F+(q?O.repeat(q.length):""):Me===0?C+(q?O.repeat(q.length):""):O.repeat(P.length):F==="."?A.repeat(P.length):F==="*"?S?S+F+(q?M:""):M:S?d:`\\${d}`);return m===!0&&(r.unescape===!0?L=L.replace(/\\/g,""):L=L.replace(/\\+/g,d=>d.length%2==0?"\\\\":d?"\\":"")),L===e&&r.contains===!0?(l.output=e,l):(l.output=J.wrapOutput(L,l,t),l)}for(;!I();){if(u=ee(),u==="\0")continue;if(u==="\\"){let d=$();if(d==="/"&&r.bash!==!0||d==="."||d===";")continue;if(!d){u+="\\",v({type:"text",value:u});continue}let S=/^\\+/.exec(se()),P=0;if(S&&S[0].length>2&&(P=S[0].length,l.index+=P,P%2!=0&&(u+="\\")),r.unescape===!0?u=ee():u+=ee(),l.brackets===0){v({type:"text",value:u});continue}}if(l.brackets>0&&(u!=="]"||c.value==="["||c.value==="[^")){if(r.posix!==!1&&u===":"){let d=c.value.slice(1);if(d.includes("[")&&(c.posix=!0,d.includes(":"))){let S=c.value.lastIndexOf("["),P=c.value.slice(0,S),F=c.value.slice(S+2),q=qn[F];if(q){c.value=P+q,l.backtrack=!0,ee(),!a.output&&i.indexOf(c)===1&&(a.output=y);continue}}}(u==="["&&$()!==":"||u==="-"&&$()==="]")&&(u=`\\${u}`),u==="]"&&(c.value==="["||c.value==="[^")&&(u=`\\${u}`),r.posix===!0&&u==="!"&&c.value==="["&&(u="^"),c.value+=u,Ce({value:u});continue}if(l.quotes===1&&u!=='"'){u=J.escapeRegex(u),c.value+=u,Ce({value:u});continue}if(u==='"'){l.quotes=l.quotes===1?0:1,r.keepQuotes===!0&&v({type:"text",value:u});continue}if(u==="("){we("parens"),v({type:"paren",value:u});continue}if(u===")"){if(l.parens===0&&r.strictBrackets===!0)throw new SyntaxError(de("opening","("));let d=H[H.length-1];if(d&&l.parens===d.parens+1){Cr(H.pop());continue}v({type:"paren",value:u,output:l.parens?")":"\\)"}),ue("parens");continue}if(u==="["){if(r.nobracket===!0||!se().includes("]")){if(r.nobracket!==!0&&r.strictBrackets===!0)throw new SyntaxError(de("closing","]"));u=`\\${u}`}else we("brackets");v({type:"bracket",value:u});continue}if(u==="]"){if(r.nobracket===!0||c&&c.type==="bracket"&&c.value.length===1){v({type:"text",value:u,output:`\\${u}`});continue}if(l.brackets===0){if(r.strictBrackets===!0)throw new SyntaxError(de("opening","["));v({type:"text",value:u,output:`\\${u}`});continue}ue("brackets");let d=c.value.slice(1);if(c.posix!==!0&&d[0]==="^"&&!d.includes("/")&&(u=`/${u}`),c.value+=u,Ce({value:u}),r.literalBrackets===!1||J.hasRegexChars(d))continue;let S=J.escapeRegex(c.value);if(l.output=l.output.slice(0,-c.value.length),r.literalBrackets===!0){l.output+=S,c.value=S;continue}c.value=`(${o}${S}|${c.value})`,l.output+=c.value;continue}if(u==="{"&&r.nobrace!==!0){we("braces");let d={type:"brace",value:u,output:"(",outputIndex:l.output.length,tokensIndex:l.tokens.length};w.push(d),v(d);continue}if(u==="}"){let d=w[w.length-1];if(r.nobrace===!0||!d){v({type:"text",value:u,output:u});continue}let S=")";if(d.dots===!0){let P=i.slice(),F=[];for(let q=P.length-1;q>=0&&(i.pop(),P[q].type!=="brace");q--)P[q].type!=="dots"&&F.unshift(P[q].value);S=jn(F,r),l.backtrack=!0}if(d.comma!==!0&&d.dots!==!0){let P=l.output.slice(0,d.outputIndex),F=l.tokens.slice(d.tokensIndex);d.value=d.output="\\{",u=S="\\}",l.output=P;for(let q of F)l.output+=q.output||q.value}v({type:"brace",value:u,output:S}),ue("braces"),w.pop();continue}if(u==="|"){H.length>0&&H[H.length-1].conditions++,v({type:"text",value:u});continue}if(u===","){let d=u,S=w[w.length-1];S&&j[j.length-1]==="braces"&&(S.comma=!0,d="|"),v({type:"comma",value:u,output:d});continue}if(u==="/"){if(c.type==="dot"&&l.index===l.start+1){l.start=l.index+1,l.consumed="",l.output="",i.pop(),c=a;continue}v({type:"slash",value:u,output:k});continue}if(u==="."){if(l.braces>0&&c.type==="dot"){c.value==="."&&(c.output=A);let d=w[w.length-1];c.type="dots",c.output+=u,c.value+=u,d.dots=!0;continue}if(l.braces+l.parens===0&&c.type!=="bos"&&c.type!=="slash"){v({type:"text",value:u,output:A});continue}v({type:"dot",value:u,output:A});continue}if(u==="?"){if(!(c&&c.value==="(")&&r.noextglob!==!0&&$()==="("&&$(2)!=="?"){Se("qmark",u);continue}if(c&&c.type==="paren"){let S=$(),P=u;if(S==="<"&&!J.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(c.value==="("&&!/[!=<:]/.test(S)||S==="<"&&!/<([!=]|\w+>)/.test(se()))&&(P=`\\${u}`),v({type:"text",value:u,output:P});continue}if(r.dot!==!0&&(c.type==="slash"||c.type==="bos")){v({type:"qmark",value:u,output:W});continue}v({type:"qmark",value:u,output:O});continue}if(u==="!"){if(r.noextglob!==!0&&$()==="("&&($(2)!=="?"||!/[!=<:]/.test($(3)))){Se("negate",u);continue}if(r.nonegate!==!0&&l.index===0){xr();continue}}if(u==="+"){if(r.noextglob!==!0&&$()==="("&&$(2)!=="?"){Se("plus",u);continue}if(c&&c.value==="("||r.regex===!1){v({type:"plus",value:u,output:p});continue}if(c&&(c.type==="bracket"||c.type==="paren"||c.type==="brace")||l.parens>0){v({type:"plus",value:u});continue}v({type:"plus",value:p});continue}if(u==="@"){if(r.noextglob!==!0&&$()==="("&&$(2)!=="?"){v({type:"at",extglob:!0,value:u,output:""});continue}v({type:"text",value:u});continue}if(u!=="*"){(u==="$"||u==="^")&&(u=`\\${u}`);let d=Kn.exec(se());d&&(u+=d[0],l.index+=d[0].length),v({type:"text",value:u});continue}if(c&&(c.type==="globstar"||c.star===!0)){c.type="star",c.star=!0,c.value+=u,c.output=M,l.backtrack=!0,l.globstar=!0,z(u);continue}let m=se();if(r.noextglob!==!0&&/^\([^?]/.test(m)){Se("star",u);continue}if(c.type==="star"){if(r.noglobstar===!0){z(u);continue}let d=c.prev,S=d.prev,P=d.type==="slash"||d.type==="bos",F=S&&(S.type==="star"||S.type==="globstar");if(r.bash===!0&&(!P||m[0]&&m[0]!=="/")){v({type:"star",value:u,output:""});continue}let q=l.braces>0&&(d.type==="comma"||d.type==="brace"),Me=H.length&&(d.type==="pipe"||d.type==="paren");if(!P&&d.type!=="paren"&&!q&&!Me){v({type:"star",value:u,output:""});continue}for(;m.slice(0,3)==="/**";){let ve=e[l.index+4];if(ve&&ve!=="/")break;m=m.slice(3),z("/**",3)}if(d.type==="bos"&&I()){c.type="globstar",c.value+=u,c.output=E(r),l.output=c.output,l.globstar=!0,z(u);continue}if(d.type==="slash"&&d.prev.type!=="bos"&&!F&&I()){l.output=l.output.slice(0,-(d.output+c.output).length),d.output=`(?:${d.output}`,c.type="globstar",c.output=E(r)+(r.strictSlashes?")":"|$)"),c.value+=u,l.globstar=!0,l.output+=d.output+c.output,z(u);continue}if(d.type==="slash"&&d.prev.type!=="bos"&&m[0]==="/"){let ve=m[1]!==void 0?"|$":"";l.output=l.output.slice(0,-(d.output+c.output).length),d.output=`(?:${d.output}`,c.type="globstar",c.output=`${E(r)}${k}|${k}${ve})`,c.value+=u,l.output+=d.output+c.output,l.globstar=!0,z(u+ee()),v({type:"slash",value:"/",output:""});continue}if(d.type==="bos"&&m[0]==="/"){c.type="globstar",c.value+=u,c.output=`(?:^|${k}|${E(r)}${k})`,l.output=c.output,l.globstar=!0,z(u+ee()),v({type:"slash",value:"/",output:""});continue}l.output=l.output.slice(0,-c.output.length),c.type="globstar",c.output=E(r),c.value+=u,l.output+=c.output,l.globstar=!0,z(u);continue}let L={type:"star",value:u,output:M};if(r.bash===!0){L.output=".*?",(c.type==="bos"||c.type==="slash")&&(L.output=b+L.output),v(L);continue}if(c&&(c.type==="bracket"||c.type==="paren")&&r.regex===!0){L.output=u,v(L);continue}(l.index===l.start||c.type==="slash"||c.type==="dot")&&(c.type==="dot"?(l.output+=x,c.output+=x):r.dot===!0?(l.output+=T,c.output+=T):(l.output+=b,c.output+=b),$()!=="*"&&(l.output+=y,c.output+=y)),v(L)}for(;l.brackets>0;){if(r.strictBrackets===!0)throw new SyntaxError(de("closing","]"));l.output=J.escapeLast(l.output,"["),ue("brackets")}for(;l.parens>0;){if(r.strictBrackets===!0)throw new SyntaxError(de("closing",")"));l.output=J.escapeLast(l.output,"("),ue("parens")}for(;l.braces>0;){if(r.strictBrackets===!0)throw new SyntaxError(de("closing","}"));l.output=J.escapeLast(l.output,"{"),ue("braces")}if(r.strictSlashes!==!0&&(c.type==="star"||c.type==="bracket")&&v({type:"maybe_slash",value:"",output:`${k}?`}),l.backtrack===!0){l.output="";for(let m of l.tokens)l.output+=m.output!=null?m.output:m.value,m.suffix&&(l.output+=m.suffix)}return l};nr.fastpaths=(e,t)=>{let r=B({},t),n=typeof r.maxLength=="number"?Math.min(Ne,r.maxLength):Ne,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);e=rr[e]||e;let a=J.isWindows(t),{DOT_LITERAL:i,SLASH_LITERAL:o,ONE_CHAR:h,DOTS_SLASH:g,NO_DOT:f,NO_DOTS:A,NO_DOTS_SLASH:p,STAR:k,START_ANCHOR:y}=Oe.globChars(a),R=r.dot?A:f,_=r.dot?p:f,x=r.capture?"":"?:",T={negated:!1,prefix:""},O=r.bash===!0?".*?":k;r.capture&&(O=`(${O})`);let W=b=>b.noglobstar===!0?O:`(${x}(?:(?!${y}${b.dot?g:i}).)*?)`,G=b=>{switch(b){case"*":return`${R}${h}${O}`;case".*":return`${i}${h}${O}`;case"*.*":return`${R}${O}${i}${h}${O}`;case"*/*":return`${R}${O}${o}${h}${_}${O}`;case"**":return R+W(r);case"**/*":return`(?:${R}${W(r)}${o})?${_}${h}${O}`;case"**/*.*":return`(?:${R}${W(r)}${o})?${_}${O}${i}${h}${O}`;case"**/.*":return`(?:${R}${W(r)}${o})?${i}${h}${O}`;default:{let C=/^(.*?)\.(\w+)$/.exec(b);if(!C)return;let M=G(C[1]);return M?M+i+C[2]:void 0}}},ne=J.removePrefix(e,T),E=G(ne);return E&&r.strictSlashes!==!0&&(E+=`${o}?`),E};tr.exports=nr});var ir=K((ys,ar)=>{"use strict";var Fn=require("path"),Qn=er(),Ye=sr(),ze=be(),Xn=ye(),Zn=e=>e&&typeof e=="object"&&!Array.isArray(e),D=(e,t,r=!1)=>{if(Array.isArray(e)){let f=e.map(p=>D(p,t,r));return p=>{for(let k of f){let y=k(p);if(y)return y}return!1}}let n=Zn(e)&&e.tokens&&e.input;if(e===""||typeof e!="string"&&!n)throw new TypeError("Expected pattern to be a non-empty string");let s=t||{},a=ze.isWindows(t),i=n?D.compileRe(e,t):D.makeRe(e,t,!1,!0),o=i.state;delete i.state;let h=()=>!1;if(s.ignore){let f=Q(B({},t),{ignore:null,onMatch:null,onResult:null});h=D(s.ignore,f,r)}let g=(f,A=!1)=>{let{isMatch:p,match:k,output:y}=D.test(f,i,t,{glob:e,posix:a}),R={glob:e,state:o,regex:i,posix:a,input:f,output:y,match:k,isMatch:p};return typeof s.onResult=="function"&&s.onResult(R),p===!1?(R.isMatch=!1,A?R:!1):h(f)?(typeof s.onIgnore=="function"&&s.onIgnore(R),R.isMatch=!1,A?R:!1):(typeof s.onMatch=="function"&&s.onMatch(R),A?R:!0)};return r&&(g.state=o),g};D.test=(e,t,r,{glob:n,posix:s}={})=>{if(typeof e!="string")throw new TypeError("Expected input to be a string");if(e==="")return{isMatch:!1,output:""};let a=r||{},i=a.format||(s?ze.toPosixSlashes:null),o=e===n,h=o&&i?i(e):e;return o===!1&&(h=i?i(e):e,o=h===n),(o===!1||a.capture===!0)&&(a.matchBase===!0||a.basename===!0?o=D.matchBase(e,t,r,s):o=t.exec(h)),{isMatch:Boolean(o),match:o,output:h}};D.matchBase=(e,t,r,n=ze.isWindows(r))=>(t instanceof RegExp?t:D.makeRe(t,r)).test(Fn.basename(e));D.isMatch=(e,t,r)=>D(t,r)(e);D.parse=(e,t)=>Array.isArray(e)?e.map(r=>D.parse(r,t)):Ye(e,Q(B({},t),{fastpaths:!1}));D.scan=(e,t)=>Qn(e,t);D.compileRe=(e,t,r=!1,n=!1)=>{if(r===!0)return e.output;let s=t||{},a=s.contains?"":"^",i=s.contains?"":"$",o=`${a}(?:${e.output})${i}`;e&&e.negated===!0&&(o=`^(?!${o}).*$`);let h=D.toRegex(o,t);return n===!0&&(h.state=e),h};D.makeRe=(e,t={},r=!1,n=!1)=>{if(!e||typeof e!="string")throw new TypeError("Expected a non-empty string");let s={negated:!1,fastpaths:!0};return t.fastpaths!==!1&&(e[0]==="."||e[0]==="*")&&(s.output=Ye.fastpaths(e,t)),s.output||(s=Ye(e,t)),D.compileRe(s,t,r,n)};D.toRegex=(e,t)=>{try{let r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(r){if(t&&t.debug===!0)throw r;return/$^/}};D.constants=Xn;ar.exports=D});var cr=K((bs,or)=>{"use strict";or.exports=ir()});var hr=K((_s,ur)=>{"use strict";var lr=require("util"),pr=Gt(),oe=cr(),Ve=be(),fr=e=>e===""||e==="./",N=(e,t,r)=>{t=[].concat(t),e=[].concat(e);let n=new Set,s=new Set,a=new Set,i=0,o=f=>{a.add(f.output),r&&r.onResult&&r.onResult(f)};for(let f=0;f<t.length;f++){let A=oe(String(t[f]),Q(B({},r),{onResult:o}),!0),p=A.state.negated||A.state.negatedExtglob;p&&i++;for(let k of e){let y=A(k,!0);!(p?!y.isMatch:y.isMatch)||(p?n.add(y.output):(n.delete(y.output),s.add(y.output)))}}let g=(i===t.length?[...a]:[...s]).filter(f=>!n.has(f));if(r&&g.length===0){if(r.failglob===!0)throw new Error(`No matches found for "${t.join(", ")}"`);if(r.nonull===!0||r.nullglob===!0)return r.unescape?t.map(f=>f.replace(/\\/g,"")):t}return g};N.match=N;N.matcher=(e,t)=>oe(e,t);N.isMatch=(e,t,r)=>oe(t,r)(e);N.any=N.isMatch;N.not=(e,t,r={})=>{t=[].concat(t).map(String);let n=new Set,s=[],a=o=>{r.onResult&&r.onResult(o),s.push(o.output)},i=N(e,t,Q(B({},r),{onResult:a}));for(let o of s)i.includes(o)||n.add(o);return[...n]};N.contains=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${lr.inspect(e)}"`);if(Array.isArray(t))return t.some(n=>N.contains(e,n,r));if(typeof t=="string"){if(fr(e)||fr(t))return!1;if(e.includes(t)||e.startsWith("./")&&e.slice(2).includes(t))return!0}return N.isMatch(e,t,Q(B({},r),{contains:!0}))};N.matchKeys=(e,t,r)=>{if(!Ve.isObject(e))throw new TypeError("Expected the first argument to be an object");let n=N(Object.keys(e),t,r),s={};for(let a of n)s[a]=e[a];return s};N.some=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=oe(String(s),r);if(n.some(i=>a(i)))return!0}return!1};N.every=(e,t,r)=>{let n=[].concat(e);for(let s of[].concat(t)){let a=oe(String(s),r);if(!n.every(i=>a(i)))return!1}return!0};N.all=(e,t,r)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${lr.inspect(e)}"`);return[].concat(t).every(n=>oe(n,r)(e))};N.capture=(e,t,r)=>{let n=Ve.isWindows(r),a=oe.makeRe(String(e),Q(B({},r),{capture:!0})).exec(n?Ve.toPosixSlashes(t):t);if(a)return a.slice(1).map(i=>i===void 0?"":i)};N.makeRe=(...e)=>oe.makeRe(...e);N.scan=(...e)=>oe.scan(...e);N.parse=(e,t)=>{let r=[];for(let n of[].concat(e||[]))for(let s of pr(String(n),t))r.push(oe.parse(s,t));return r};N.braces=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return t&&t.nobrace===!0||!/\{.*\}/.test(e)?[e]:pr(e,t)};N.braceExpand=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a string");return N.braces(e,Q(B({},t),{expand:!0}))};ur.exports=N});var gr=K((Es,dr)=>{"use strict";dr.exports=(e,...t)=>new Promise(r=>{r(e(...t))})});var Ar=K((xs,Je)=>{"use strict";var Yn=gr(),mr=e=>{if(e<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let t=[],r=0,n=()=>{r--,t.length>0&&t.shift()()},s=(o,h,...g)=>{r++;let f=Yn(o,...g);h(f),f.then(n,n)},a=(o,h,...g)=>{r<e?s(o,h,...g):t.push(s.bind(null,o,h,...g))},i=(o,...h)=>new Promise(g=>a(o,g,...h));return Object.defineProperties(i,{activeCount:{get:()=>r},pendingCount:{get:()=>t.length}}),i};Je.exports=mr;Je.exports.default=mr});var Vn={};Or(Vn,{default:()=>es});var He=X(require("@yarnpkg/cli")),ae=X(require("@yarnpkg/core")),nt=X(require("@yarnpkg/core")),le=X(require("clipanion")),Ae=class extends He.BaseCommand{constructor(){super(...arguments);this.json=le.Option.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.production=le.Option.Boolean("--production",!1,{description:"Only install regular dependencies by omitting dev dependencies"});this.all=le.Option.Boolean("-A,--all",!1,{description:"Install the entire project"});this.workspaces=le.Option.Rest()}async execute(){let t=await ae.Configuration.find(this.context.cwd,this.context.plugins),{project:r,workspace:n}=await ae.Project.find(t,this.context.cwd),s=await ae.Cache.find(t);await r.restoreInstallState({restoreResolutions:!1});let a;if(this.all)a=new Set(r.workspaces);else if(this.workspaces.length===0){if(!n)throw new He.WorkspaceRequiredError(r.cwd,this.context.cwd);a=new Set([n])}else a=new Set(this.workspaces.map(o=>r.getWorkspaceByIdent(nt.structUtils.parseIdent(o))));for(let o of a)for(let h of this.production?["dependencies"]:ae.Manifest.hardDependencies)for(let g of o.manifest.getForScope(h).values()){let f=r.tryWorkspaceByDescriptor(g);f!==null&&a.add(f)}for(let o of r.workspaces)a.has(o)?this.production&&o.manifest.devDependencies.clear():(o.manifest.installConfig=o.manifest.installConfig||{},o.manifest.installConfig.selfReferences=!1,o.manifest.dependencies.clear(),o.manifest.devDependencies.clear(),o.manifest.peerDependencies.clear(),o.manifest.scripts.clear());return(await ae.StreamReport.start({configuration:t,json:this.json,stdout:this.context.stdout,includeLogs:!0},async o=>{await r.install({cache:s,report:o,persistProject:!1})})).exitCode()}};Ae.paths=[["workspaces","focus"]],Ae.usage=le.Command.Usage({category:"Workspace-related commands",description:"install a single workspace and its dependencies",details:"\n This command will run an install as if the specified workspaces (and all other workspaces they depend on) were the only ones in the project. If no workspaces are explicitly listed, the active one will be assumed.\n\n Note that this command is only very moderately useful when using zero-installs, since the cache will contain all the packages anyway - meaning that the only difference between a full install and a focused install would just be a few extra lines in the `.pnp.cjs` file, at the cost of introducing an extra complexity.\n\n If the `-A,--all` flag is set, the entire project will be installed. Combine with `--production` to replicate the old `yarn install --production`.\n "});var st=Ae;var Ie=X(require("@yarnpkg/cli")),ge=X(require("@yarnpkg/core")),Ee=X(require("@yarnpkg/core")),Y=X(require("@yarnpkg/core")),Rr=X(require("@yarnpkg/plugin-git")),U=X(require("clipanion")),Be=X(hr()),yr=X(require("os")),br=X(Ar()),re=X(require("typanion")),xe=class extends Ie.BaseCommand{constructor(){super(...arguments);this.recursive=U.Option.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.from=U.Option.Array("--from",[],{description:"An array of glob pattern idents from which to base any recursion"});this.all=U.Option.Boolean("-A,--all",!1,{description:"Run the command on all workspaces of a project"});this.verbose=U.Option.Boolean("-v,--verbose",!1,{description:"Prefix each output line with the name of the originating workspace"});this.parallel=U.Option.Boolean("-p,--parallel",!1,{description:"Run the commands in parallel"});this.interlaced=U.Option.Boolean("-i,--interlaced",!1,{description:"Print the output of commands in real-time instead of buffering it"});this.jobs=U.Option.String("-j,--jobs",{description:"The maximum number of parallel tasks that the execution will be limited to; or `unlimited`",validator:re.isOneOf([re.isEnum(["unlimited"]),re.applyCascade(re.isNumber(),[re.isInteger(),re.isAtLeast(1)])])});this.topological=U.Option.Boolean("-t,--topological",!1,{description:"Run the command after all workspaces it depends on (regular) have finished"});this.topologicalDev=U.Option.Boolean("--topological-dev",!1,{description:"Run the command after all workspaces it depends on (regular + dev) have finished"});this.include=U.Option.Array("--include",[],{description:"An array of glob pattern idents; only matching workspaces will be traversed"});this.exclude=U.Option.Array("--exclude",[],{description:"An array of glob pattern idents; matching workspaces won't be traversed"});this.publicOnly=U.Option.Boolean("--no-private",{description:"Avoid running the command on private workspaces"});this.since=U.Option.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.commandName=U.Option.String();this.args=U.Option.Proxy()}async execute(){let t=await ge.Configuration.find(this.context.cwd,this.context.plugins),{project:r,workspace:n}=await ge.Project.find(t,this.context.cwd);if(!this.all&&!n)throw new Ie.WorkspaceRequiredError(r.cwd,this.context.cwd);await r.restoreInstallState();let s=this.cli.process([this.commandName,...this.args]),a=s.path.length===1&&s.path[0]==="run"&&typeof s.scriptName!="undefined"?s.scriptName:null;if(s.path.length===0)throw new U.UsageError("Invalid subcommand name for iteration - use the 'run' keyword if you wish to execute a script");let i=this.all?r.topLevelWorkspace:n,o=this.since?Array.from(await Rr.gitUtils.fetchChangedWorkspaces({ref:this.since,project:r})):[i,...this.from.length>0?i.getRecursiveWorkspaceChildren():[]],h=E=>Be.default.isMatch(Y.structUtils.stringifyIdent(E.locator),this.from),g=this.from.length>0?o.filter(h):o,f=new Set([...g,...g.map(E=>[...this.recursive?this.since?E.getRecursiveWorkspaceDependents():E.getRecursiveWorkspaceDependencies():E.getRecursiveWorkspaceChildren()]).flat()]),A=[],p=!1;if(a==null?void 0:a.includes(":")){for(let E of r.workspaces)if(E.manifest.scripts.has(a)&&(p=!p,p===!1))break}for(let E of f)a&&!E.manifest.scripts.has(a)&&!p&&!(await ge.scriptUtils.getWorkspaceAccessibleBinaries(E)).has(a)||a===process.env.npm_lifecycle_event&&E.cwd===n.cwd||this.include.length>0&&!Be.default.isMatch(Y.structUtils.stringifyIdent(E.locator),this.include)||this.exclude.length>0&&Be.default.isMatch(Y.structUtils.stringifyIdent(E.locator),this.exclude)||this.publicOnly&&E.manifest.private===!0||A.push(E);let k=this.parallel?this.jobs==="unlimited"?Infinity:Number(this.jobs)||Math.max(1,(0,yr.cpus)().length/2):1,y=k===1?!1:this.parallel,R=y?this.interlaced:!0,_=(0,br.default)(k),x=new Map,T=new Set,O=0,W=null,G=!1,ne=await Ee.StreamReport.start({configuration:t,stdout:this.context.stdout},async E=>{let b=async(C,{commandIndex:M})=>{if(G)return-1;!y&&this.verbose&&M>1&&E.reportSeparator();let l=zn(C,{configuration:t,verbose:this.verbose,commandIndex:M}),[H,w]=_r(E,{prefix:l,interlaced:R}),[j,c]=_r(E,{prefix:l,interlaced:R});try{this.verbose&&E.reportInfo(null,`${l} Process started`);let u=Date.now(),I=await this.cli.run([this.commandName,...this.args],{cwd:C.cwd,stdout:H,stderr:j})||0;H.end(),j.end(),await w,await c;let $=Date.now();if(this.verbose){let ee=t.get("enableTimers")?`, completed in ${Y.formatUtils.pretty(t,$-u,Y.formatUtils.Type.DURATION)}`:"";E.reportInfo(null,`${l} Process exited (exit code ${I})${ee}`)}return I===130&&(G=!0,W=I),I}catch(u){throw H.end(),j.end(),await w,await c,u}};for(let C of A)x.set(C.anchoredLocator.locatorHash,C);for(;x.size>0&&!E.hasErrors();){let C=[];for(let[H,w]of x){if(T.has(w.anchoredDescriptor.descriptorHash))continue;let j=!0;if(this.topological||this.topologicalDev){let c=this.topologicalDev?new Map([...w.manifest.dependencies,...w.manifest.devDependencies]):w.manifest.dependencies;for(let u of c.values()){let I=r.tryWorkspaceByDescriptor(u);if(j=I===null||!x.has(I.anchoredLocator.locatorHash),!j)break}}if(!!j&&(T.add(w.anchoredDescriptor.descriptorHash),C.push(_(async()=>{let c=await b(w,{commandIndex:++O});return x.delete(H),T.delete(w.anchoredDescriptor.descriptorHash),c})),!y))break}if(C.length===0){let H=Array.from(x.values()).map(w=>Y.structUtils.prettyLocator(t,w.anchoredLocator)).join(", ");E.reportError(Ee.MessageName.CYCLIC_DEPENDENCIES,`Dependency cycle detected (${H})`);return}let l=(await Promise.all(C)).find(H=>H!==0);W===null&&(W=typeof l!="undefined"?1:W),(this.topological||this.topologicalDev)&&typeof l!="undefined"&&E.reportError(Ee.MessageName.UNNAMED,"The command failed for workspaces that are depended upon by other workspaces; can't satisfy the dependency graph")}});return W!==null?W:ne.exitCode()}};xe.paths=[["workspaces","foreach"]],xe.usage=U.Command.Usage({category:"Workspace-related commands",description:"run a command on all workspaces",details:"\n This command will run a given sub-command on current and all its descendant workspaces. Various flags can alter the exact behavior of the command:\n\n - If `-p,--parallel` is set, the commands will be ran in parallel; they'll by default be limited to a number of parallel tasks roughly equal to half your core number, but that can be overridden via `-j,--jobs`, or disabled by setting `-j unlimited`.\n\n - If `-p,--parallel` and `-i,--interlaced` are both set, Yarn will print the lines from the output as it receives them. If `-i,--interlaced` wasn't set, it would instead buffer the output from each process and print the resulting buffers only after their source processes have exited.\n\n - If `-t,--topological` is set, Yarn will only run the command after all workspaces that it depends on through the `dependencies` field have successfully finished executing. If `--topological-dev` is set, both the `dependencies` and `devDependencies` fields will be considered when figuring out the wait points.\n\n - If `-A,--all` is set, Yarn will run the command on all the workspaces of a project. By default yarn runs the command only on current and all its descendant workspaces.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `--from` is set, Yarn will use the packages matching the 'from' glob as the starting point for any recursive search.\n\n - If `--since` is set, Yarn will only run the command on workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - The command may apply to only some workspaces through the use of `--include` which acts as a whitelist. The `--exclude` flag will do the opposite and will be a list of packages that mustn't execute the script. Both flags accept glob patterns (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n Adding the `-v,--verbose` flag will cause Yarn to print more information; in particular the name of the workspace that generated the output will be printed at the front of each line.\n\n If the command is `run` and the script being run does not exist the child workspace will be skipped without error.\n ",examples:[["Publish current and all descendant packages","yarn workspaces foreach npm publish --tolerate-republish"],["Run build script on current and all descendant packages","yarn workspaces foreach run build"],["Run build script on current and all descendant packages in parallel, building package dependencies first","yarn workspaces foreach -pt run build"],["Run build script on several packages and all their dependencies, building dependencies first","yarn workspaces foreach -ptR --from '{workspace-a,workspace-b}' run build"]]});var Er=xe;function _r(e,{prefix:t,interlaced:r}){let n=e.createStreamReporter(t),s=new Y.miscUtils.DefaultStream;s.pipe(n,{end:!1}),s.on("finish",()=>{n.end()});let a=new Promise(o=>{n.on("finish",()=>{o(s.active)})});if(r)return[s,a];let i=new Y.miscUtils.BufferStream;return i.pipe(s,{end:!1}),i.on("finish",()=>{s.end()}),[i,a]}function zn(e,{configuration:t,commandIndex:r,verbose:n}){if(!n)return null;let s=Y.structUtils.convertToIdent(e.locator),i=`[${Y.structUtils.stringifyIdent(s)}]:`,o=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],h=o[r%o.length];return Y.formatUtils.pretty(t,i,h)}var Jn={commands:[st,Er]},es=Jn;return Vn;})(); +var plugin=(()=>{var yr=Object.create;var we=Object.defineProperty;var _r=Object.getOwnPropertyDescriptor;var Er=Object.getOwnPropertyNames;var br=Object.getPrototypeOf,xr=Object.prototype.hasOwnProperty;var W=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(r,t)=>(typeof require<"u"?require:r)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+e+'" is not supported')});var q=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports),Cr=(e,r)=>{for(var t in r)we(e,t,{get:r[t],enumerable:!0})},Je=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of Er(r))!xr.call(e,s)&&s!==t&&we(e,s,{get:()=>r[s],enumerable:!(n=_r(r,s))||n.enumerable});return e};var Be=(e,r,t)=>(t=e!=null?yr(br(e)):{},Je(r||!e||!e.__esModule?we(t,"default",{value:e,enumerable:!0}):t,e)),wr=e=>Je(we({},"__esModule",{value:!0}),e);var ve=q(ee=>{"use strict";ee.isInteger=e=>typeof e=="number"?Number.isInteger(e):typeof e=="string"&&e.trim()!==""?Number.isInteger(Number(e)):!1;ee.find=(e,r)=>e.nodes.find(t=>t.type===r);ee.exceedsLimit=(e,r,t=1,n)=>n===!1||!ee.isInteger(e)||!ee.isInteger(r)?!1:(Number(r)-Number(e))/Number(t)>=n;ee.escapeNode=(e,r=0,t)=>{let n=e.nodes[r];!n||(t&&n.type===t||n.type==="open"||n.type==="close")&&n.escaped!==!0&&(n.value="\\"+n.value,n.escaped=!0)};ee.encloseBrace=e=>e.type!=="brace"?!1:e.commas>>0+e.ranges>>0===0?(e.invalid=!0,!0):!1;ee.isInvalidBrace=e=>e.type!=="brace"?!1:e.invalid===!0||e.dollar?!0:e.commas>>0+e.ranges>>0===0||e.open!==!0||e.close!==!0?(e.invalid=!0,!0):!1;ee.isOpenOrClose=e=>e.type==="open"||e.type==="close"?!0:e.open===!0||e.close===!0;ee.reduce=e=>e.reduce((r,t)=>(t.type==="text"&&r.push(t.value),t.type==="range"&&(t.type="text"),r),[]);ee.flatten=(...e)=>{let r=[],t=n=>{for(let s=0;s<n.length;s++){let i=n[s];Array.isArray(i)?t(i,r):i!==void 0&&r.push(i)}return r};return t(e),r}});var He=q((zn,rt)=>{"use strict";var tt=ve();rt.exports=(e,r={})=>{let t=(n,s={})=>{let i=r.escapeInvalid&&tt.isInvalidBrace(s),a=n.invalid===!0&&r.escapeInvalid===!0,c="";if(n.value)return(i||a)&&tt.isOpenOrClose(n)?"\\"+n.value:n.value;if(n.value)return n.value;if(n.nodes)for(let p of n.nodes)c+=t(p);return c};return t(e)}});var st=q((Vn,nt)=>{"use strict";nt.exports=function(e){return typeof e=="number"?e-e===0:typeof e=="string"&&e.trim()!==""?Number.isFinite?Number.isFinite(+e):isFinite(+e):!1}});var ht=q((Jn,pt)=>{"use strict";var at=st(),le=(e,r,t)=>{if(at(e)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(r===void 0||e===r)return String(e);if(at(r)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let n={relaxZeros:!0,...t};typeof n.strictZeros=="boolean"&&(n.relaxZeros=n.strictZeros===!1);let s=String(n.relaxZeros),i=String(n.shorthand),a=String(n.capture),c=String(n.wrap),p=e+":"+r+"="+s+i+a+c;if(le.cache.hasOwnProperty(p))return le.cache[p].result;let m=Math.min(e,r),h=Math.max(e,r);if(Math.abs(m-h)===1){let y=e+"|"+r;return n.capture?`(${y})`:n.wrap===!1?y:`(?:${y})`}let R=ft(e)||ft(r),f={min:e,max:r,a:m,b:h},$=[],_=[];if(R&&(f.isPadded=R,f.maxLen=String(f.max).length),m<0){let y=h<0?Math.abs(h):1;_=it(y,Math.abs(m),f,n),m=f.a=0}return h>=0&&($=it(m,h,f,n)),f.negatives=_,f.positives=$,f.result=Sr(_,$,n),n.capture===!0?f.result=`(${f.result})`:n.wrap!==!1&&$.length+_.length>1&&(f.result=`(?:${f.result})`),le.cache[p]=f,f.result};function Sr(e,r,t){let n=Pe(e,r,"-",!1,t)||[],s=Pe(r,e,"",!1,t)||[],i=Pe(e,r,"-?",!0,t)||[];return n.concat(i).concat(s).join("|")}function vr(e,r){let t=1,n=1,s=ut(e,t),i=new Set([r]);for(;e<=s&&s<=r;)i.add(s),t+=1,s=ut(e,t);for(s=ct(r+1,n)-1;e<s&&s<=r;)i.add(s),n+=1,s=ct(r+1,n)-1;return i=[...i],i.sort(Tr),i}function Hr(e,r,t){if(e===r)return{pattern:e,count:[],digits:0};let n=$r(e,r),s=n.length,i="",a=0;for(let c=0;c<s;c++){let[p,m]=n[c];p===m?i+=p:p!=="0"||m!=="9"?i+=kr(p,m,t):a++}return a&&(i+=t.shorthand===!0?"\\d":"[0-9]"),{pattern:i,count:[a],digits:s}}function it(e,r,t,n){let s=vr(e,r),i=[],a=e,c;for(let p=0;p<s.length;p++){let m=s[p],h=Hr(String(a),String(m),n),R="";if(!t.isPadded&&c&&c.pattern===h.pattern){c.count.length>1&&c.count.pop(),c.count.push(h.count[0]),c.string=c.pattern+lt(c.count),a=m+1;continue}t.isPadded&&(R=Lr(m,t,n)),h.string=R+h.pattern+lt(h.count),i.push(h),a=m+1,c=h}return i}function Pe(e,r,t,n,s){let i=[];for(let a of e){let{string:c}=a;!n&&!ot(r,"string",c)&&i.push(t+c),n&&ot(r,"string",c)&&i.push(t+c)}return i}function $r(e,r){let t=[];for(let n=0;n<e.length;n++)t.push([e[n],r[n]]);return t}function Tr(e,r){return e>r?1:r>e?-1:0}function ot(e,r,t){return e.some(n=>n[r]===t)}function ut(e,r){return Number(String(e).slice(0,-r)+"9".repeat(r))}function ct(e,r){return e-e%Math.pow(10,r)}function lt(e){let[r=0,t=""]=e;return t||r>1?`{${r+(t?","+t:"")}}`:""}function kr(e,r,t){return`[${e}${r-e===1?"":"-"}${r}]`}function ft(e){return/^-?(0+)\d/.test(e)}function Lr(e,r,t){if(!r.isPadded)return e;let n=Math.abs(r.maxLen-String(e).length),s=t.relaxZeros!==!1;switch(n){case 0:return"";case 1:return s?"0?":"0";case 2:return s?"0{0,2}":"00";default:return s?`0{0,${n}}`:`0{${n}}`}}le.cache={};le.clearCache=()=>le.cache={};pt.exports=le});var Ue=q((es,Et)=>{"use strict";var Or=W("util"),At=ht(),dt=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),Nr=e=>r=>e===!0?Number(r):String(r),Me=e=>typeof e=="number"||typeof e=="string"&&e!=="",Ae=e=>Number.isInteger(+e),De=e=>{let r=`${e}`,t=-1;if(r[0]==="-"&&(r=r.slice(1)),r==="0")return!1;for(;r[++t]==="0";);return t>0},Ir=(e,r,t)=>typeof e=="string"||typeof r=="string"?!0:t.stringify===!0,Br=(e,r,t)=>{if(r>0){let n=e[0]==="-"?"-":"";n&&(e=e.slice(1)),e=n+e.padStart(n?r-1:r,"0")}return t===!1?String(e):e},gt=(e,r)=>{let t=e[0]==="-"?"-":"";for(t&&(e=e.slice(1),r--);e.length<r;)e="0"+e;return t?"-"+e:e},Pr=(e,r)=>{e.negatives.sort((a,c)=>a<c?-1:a>c?1:0),e.positives.sort((a,c)=>a<c?-1:a>c?1:0);let t=r.capture?"":"?:",n="",s="",i;return e.positives.length&&(n=e.positives.join("|")),e.negatives.length&&(s=`-(${t}${e.negatives.join("|")})`),n&&s?i=`${n}|${s}`:i=n||s,r.wrap?`(${t}${i})`:i},mt=(e,r,t,n)=>{if(t)return At(e,r,{wrap:!1,...n});let s=String.fromCharCode(e);if(e===r)return s;let i=String.fromCharCode(r);return`[${s}-${i}]`},Rt=(e,r,t)=>{if(Array.isArray(e)){let n=t.wrap===!0,s=t.capture?"":"?:";return n?`(${s}${e.join("|")})`:e.join("|")}return At(e,r,t)},yt=(...e)=>new RangeError("Invalid range arguments: "+Or.inspect(...e)),_t=(e,r,t)=>{if(t.strictRanges===!0)throw yt([e,r]);return[]},Mr=(e,r)=>{if(r.strictRanges===!0)throw new TypeError(`Expected step "${e}" to be a number`);return[]},Dr=(e,r,t=1,n={})=>{let s=Number(e),i=Number(r);if(!Number.isInteger(s)||!Number.isInteger(i)){if(n.strictRanges===!0)throw yt([e,r]);return[]}s===0&&(s=0),i===0&&(i=0);let a=s>i,c=String(e),p=String(r),m=String(t);t=Math.max(Math.abs(t),1);let h=De(c)||De(p)||De(m),R=h?Math.max(c.length,p.length,m.length):0,f=h===!1&&Ir(e,r,n)===!1,$=n.transform||Nr(f);if(n.toRegex&&t===1)return mt(gt(e,R),gt(r,R),!0,n);let _={negatives:[],positives:[]},y=T=>_[T<0?"negatives":"positives"].push(Math.abs(T)),E=[],S=0;for(;a?s>=i:s<=i;)n.toRegex===!0&&t>1?y(s):E.push(Br($(s,S),R,f)),s=a?s-t:s+t,S++;return n.toRegex===!0?t>1?Pr(_,n):Rt(E,null,{wrap:!1,...n}):E},Ur=(e,r,t=1,n={})=>{if(!Ae(e)&&e.length>1||!Ae(r)&&r.length>1)return _t(e,r,n);let s=n.transform||(f=>String.fromCharCode(f)),i=`${e}`.charCodeAt(0),a=`${r}`.charCodeAt(0),c=i>a,p=Math.min(i,a),m=Math.max(i,a);if(n.toRegex&&t===1)return mt(p,m,!1,n);let h=[],R=0;for(;c?i>=a:i<=a;)h.push(s(i,R)),i=c?i-t:i+t,R++;return n.toRegex===!0?Rt(h,null,{wrap:!1,options:n}):h},$e=(e,r,t,n={})=>{if(r==null&&Me(e))return[e];if(!Me(e)||!Me(r))return _t(e,r,n);if(typeof t=="function")return $e(e,r,1,{transform:t});if(dt(t))return $e(e,r,0,t);let s={...n};return s.capture===!0&&(s.wrap=!0),t=t||s.step||1,Ae(t)?Ae(e)&&Ae(r)?Dr(e,r,t,s):Ur(e,r,Math.max(Math.abs(t),1),s):t!=null&&!dt(t)?Mr(t,s):$e(e,r,1,t)};Et.exports=$e});var Ct=q((ts,xt)=>{"use strict";var Gr=Ue(),bt=ve(),qr=(e,r={})=>{let t=(n,s={})=>{let i=bt.isInvalidBrace(s),a=n.invalid===!0&&r.escapeInvalid===!0,c=i===!0||a===!0,p=r.escapeInvalid===!0?"\\":"",m="";if(n.isOpen===!0||n.isClose===!0)return p+n.value;if(n.type==="open")return c?p+n.value:"(";if(n.type==="close")return c?p+n.value:")";if(n.type==="comma")return n.prev.type==="comma"?"":c?n.value:"|";if(n.value)return n.value;if(n.nodes&&n.ranges>0){let h=bt.reduce(n.nodes),R=Gr(...h,{...r,wrap:!1,toRegex:!0});if(R.length!==0)return h.length>1&&R.length>1?`(${R})`:R}if(n.nodes)for(let h of n.nodes)m+=t(h,n);return m};return t(e)};xt.exports=qr});var vt=q((rs,St)=>{"use strict";var Kr=Ue(),wt=He(),he=ve(),fe=(e="",r="",t=!1)=>{let n=[];if(e=[].concat(e),r=[].concat(r),!r.length)return e;if(!e.length)return t?he.flatten(r).map(s=>`{${s}}`):r;for(let s of e)if(Array.isArray(s))for(let i of s)n.push(fe(i,r,t));else for(let i of r)t===!0&&typeof i=="string"&&(i=`{${i}}`),n.push(Array.isArray(i)?fe(s,i,t):s+i);return he.flatten(n)},Wr=(e,r={})=>{let t=r.rangeLimit===void 0?1e3:r.rangeLimit,n=(s,i={})=>{s.queue=[];let a=i,c=i.queue;for(;a.type!=="brace"&&a.type!=="root"&&a.parent;)a=a.parent,c=a.queue;if(s.invalid||s.dollar){c.push(fe(c.pop(),wt(s,r)));return}if(s.type==="brace"&&s.invalid!==!0&&s.nodes.length===2){c.push(fe(c.pop(),["{}"]));return}if(s.nodes&&s.ranges>0){let R=he.reduce(s.nodes);if(he.exceedsLimit(...R,r.step,t))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let f=Kr(...R,r);f.length===0&&(f=wt(s,r)),c.push(fe(c.pop(),f)),s.nodes=[];return}let p=he.encloseBrace(s),m=s.queue,h=s;for(;h.type!=="brace"&&h.type!=="root"&&h.parent;)h=h.parent,m=h.queue;for(let R=0;R<s.nodes.length;R++){let f=s.nodes[R];if(f.type==="comma"&&s.type==="brace"){R===1&&m.push(""),m.push("");continue}if(f.type==="close"){c.push(fe(c.pop(),m,p));continue}if(f.value&&f.type!=="open"){m.push(fe(m.pop(),f.value));continue}f.nodes&&n(f,s)}return m};return he.flatten(n(e))};St.exports=Wr});var $t=q((ns,Ht)=>{"use strict";Ht.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Nt=q((ss,Ot)=>{"use strict";var jr=He(),{MAX_LENGTH:Tt,CHAR_BACKSLASH:Ge,CHAR_BACKTICK:Fr,CHAR_COMMA:Qr,CHAR_DOT:Xr,CHAR_LEFT_PARENTHESES:Zr,CHAR_RIGHT_PARENTHESES:Yr,CHAR_LEFT_CURLY_BRACE:zr,CHAR_RIGHT_CURLY_BRACE:Vr,CHAR_LEFT_SQUARE_BRACKET:kt,CHAR_RIGHT_SQUARE_BRACKET:Lt,CHAR_DOUBLE_QUOTE:Jr,CHAR_SINGLE_QUOTE:en,CHAR_NO_BREAK_SPACE:tn,CHAR_ZERO_WIDTH_NOBREAK_SPACE:rn}=$t(),nn=(e,r={})=>{if(typeof e!="string")throw new TypeError("Expected a string");let t=r||{},n=typeof t.maxLength=="number"?Math.min(Tt,t.maxLength):Tt;if(e.length>n)throw new SyntaxError(`Input length (${e.length}), exceeds max characters (${n})`);let s={type:"root",input:e,nodes:[]},i=[s],a=s,c=s,p=0,m=e.length,h=0,R=0,f,$={},_=()=>e[h++],y=E=>{if(E.type==="text"&&c.type==="dot"&&(c.type="text"),c&&c.type==="text"&&E.type==="text"){c.value+=E.value;return}return a.nodes.push(E),E.parent=a,E.prev=c,c=E,E};for(y({type:"bos"});h<m;)if(a=i[i.length-1],f=_(),!(f===rn||f===tn)){if(f===Ge){y({type:"text",value:(r.keepEscaping?f:"")+_()});continue}if(f===Lt){y({type:"text",value:"\\"+f});continue}if(f===kt){p++;let E=!0,S;for(;h<m&&(S=_());){if(f+=S,S===kt){p++;continue}if(S===Ge){f+=_();continue}if(S===Lt&&(p--,p===0))break}y({type:"text",value:f});continue}if(f===Zr){a=y({type:"paren",nodes:[]}),i.push(a),y({type:"text",value:f});continue}if(f===Yr){if(a.type!=="paren"){y({type:"text",value:f});continue}a=i.pop(),y({type:"text",value:f}),a=i[i.length-1];continue}if(f===Jr||f===en||f===Fr){let E=f,S;for(r.keepQuotes!==!0&&(f="");h<m&&(S=_());){if(S===Ge){f+=S+_();continue}if(S===E){r.keepQuotes===!0&&(f+=S);break}f+=S}y({type:"text",value:f});continue}if(f===zr){R++;let E=c.value&&c.value.slice(-1)==="$"||a.dollar===!0;a=y({type:"brace",open:!0,close:!1,dollar:E,depth:R,commas:0,ranges:0,nodes:[]}),i.push(a),y({type:"open",value:f});continue}if(f===Vr){if(a.type!=="brace"){y({type:"text",value:f});continue}let E="close";a=i.pop(),a.close=!0,y({type:E,value:f}),R--,a=i[i.length-1];continue}if(f===Qr&&R>0){if(a.ranges>0){a.ranges=0;let E=a.nodes.shift();a.nodes=[E,{type:"text",value:jr(a)}]}y({type:"comma",value:f}),a.commas++;continue}if(f===Xr&&R>0&&a.commas===0){let E=a.nodes;if(R===0||E.length===0){y({type:"text",value:f});continue}if(c.type==="dot"){if(a.range=[],c.value+=f,c.type="range",a.nodes.length!==3&&a.nodes.length!==5){a.invalid=!0,a.ranges=0,c.type="text";continue}a.ranges++,a.args=[];continue}if(c.type==="range"){E.pop();let S=E[E.length-1];S.value+=c.value+f,c=S,a.ranges--;continue}y({type:"dot",value:f});continue}y({type:"text",value:f})}do if(a=i.pop(),a.type!=="root"){a.nodes.forEach(T=>{T.nodes||(T.type==="open"&&(T.isOpen=!0),T.type==="close"&&(T.isClose=!0),T.nodes||(T.type="text"),T.invalid=!0)});let E=i[i.length-1],S=E.nodes.indexOf(a);E.nodes.splice(S,1,...a.nodes)}while(i.length>0);return y({type:"eos"}),s};Ot.exports=nn});var Pt=q((as,Bt)=>{"use strict";var It=He(),sn=Ct(),an=vt(),on=Nt(),Z=(e,r={})=>{let t=[];if(Array.isArray(e))for(let n of e){let s=Z.create(n,r);Array.isArray(s)?t.push(...s):t.push(s)}else t=[].concat(Z.create(e,r));return r&&r.expand===!0&&r.nodupes===!0&&(t=[...new Set(t)]),t};Z.parse=(e,r={})=>on(e,r);Z.stringify=(e,r={})=>It(typeof e=="string"?Z.parse(e,r):e,r);Z.compile=(e,r={})=>(typeof e=="string"&&(e=Z.parse(e,r)),sn(e,r));Z.expand=(e,r={})=>{typeof e=="string"&&(e=Z.parse(e,r));let t=an(e,r);return r.noempty===!0&&(t=t.filter(Boolean)),r.nodupes===!0&&(t=[...new Set(t)]),t};Z.create=(e,r={})=>e===""||e.length<3?[e]:r.expand!==!0?Z.compile(e,r):Z.expand(e,r);Bt.exports=Z});var me=q((is,qt)=>{"use strict";var un=W("path"),se="\\\\/",Mt=`[^${se}]`,ie="\\.",cn="\\+",ln="\\?",Te="\\/",fn="(?=.)",Dt="[^/]",qe=`(?:${Te}|$)`,Ut=`(?:^|${Te})`,Ke=`${ie}{1,2}${qe}`,pn=`(?!${ie})`,hn=`(?!${Ut}${Ke})`,dn=`(?!${ie}{0,1}${qe})`,gn=`(?!${Ke})`,An=`[^.${Te}]`,mn=`${Dt}*?`,Gt={DOT_LITERAL:ie,PLUS_LITERAL:cn,QMARK_LITERAL:ln,SLASH_LITERAL:Te,ONE_CHAR:fn,QMARK:Dt,END_ANCHOR:qe,DOTS_SLASH:Ke,NO_DOT:pn,NO_DOTS:hn,NO_DOT_SLASH:dn,NO_DOTS_SLASH:gn,QMARK_NO_DOT:An,STAR:mn,START_ANCHOR:Ut},Rn={...Gt,SLASH_LITERAL:`[${se}]`,QMARK:Mt,STAR:`${Mt}*?`,DOTS_SLASH:`${ie}{1,2}(?:[${se}]|$)`,NO_DOT:`(?!${ie})`,NO_DOTS:`(?!(?:^|[${se}])${ie}{1,2}(?:[${se}]|$))`,NO_DOT_SLASH:`(?!${ie}{0,1}(?:[${se}]|$))`,NO_DOTS_SLASH:`(?!${ie}{1,2}(?:[${se}]|$))`,QMARK_NO_DOT:`[^.${se}]`,START_ANCHOR:`(?:^|[${se}])`,END_ANCHOR:`(?:[${se}]|$)`},yn={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};qt.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:yn,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:un.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===!0?Rn:Gt}}});var Re=q(Q=>{"use strict";var _n=W("path"),En=process.platform==="win32",{REGEX_BACKSLASH:bn,REGEX_REMOVE_BACKSLASH:xn,REGEX_SPECIAL_CHARS:Cn,REGEX_SPECIAL_CHARS_GLOBAL:wn}=me();Q.isObject=e=>e!==null&&typeof e=="object"&&!Array.isArray(e);Q.hasRegexChars=e=>Cn.test(e);Q.isRegexChar=e=>e.length===1&&Q.hasRegexChars(e);Q.escapeRegex=e=>e.replace(wn,"\\$1");Q.toPosixSlashes=e=>e.replace(bn,"/");Q.removeBackslashes=e=>e.replace(xn,r=>r==="\\"?"":r);Q.supportsLookbehinds=()=>{let e=process.version.slice(1).split(".").map(Number);return e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10};Q.isWindows=e=>e&&typeof e.windows=="boolean"?e.windows:En===!0||_n.sep==="\\";Q.escapeLast=(e,r,t)=>{let n=e.lastIndexOf(r,t);return n===-1?e:e[n-1]==="\\"?Q.escapeLast(e,r,n-1):`${e.slice(0,n)}\\${e.slice(n)}`};Q.removePrefix=(e,r={})=>{let t=e;return t.startsWith("./")&&(t=t.slice(2),r.prefix="./"),t};Q.wrapOutput=(e,r={},t={})=>{let n=t.contains?"":"^",s=t.contains?"":"$",i=`${n}(?:${e})${s}`;return r.negated===!0&&(i=`(?:^(?!${i}).*$)`),i}});var Yt=q((us,Zt)=>{"use strict";var Kt=Re(),{CHAR_ASTERISK:We,CHAR_AT:Sn,CHAR_BACKWARD_SLASH:ye,CHAR_COMMA:vn,CHAR_DOT:je,CHAR_EXCLAMATION_MARK:Fe,CHAR_FORWARD_SLASH:Xt,CHAR_LEFT_CURLY_BRACE:Qe,CHAR_LEFT_PARENTHESES:Xe,CHAR_LEFT_SQUARE_BRACKET:Hn,CHAR_PLUS:$n,CHAR_QUESTION_MARK:Wt,CHAR_RIGHT_CURLY_BRACE:Tn,CHAR_RIGHT_PARENTHESES:jt,CHAR_RIGHT_SQUARE_BRACKET:kn}=me(),Ft=e=>e===Xt||e===ye,Qt=e=>{e.isPrefix!==!0&&(e.depth=e.isGlobstar?1/0:1)},Ln=(e,r)=>{let t=r||{},n=e.length-1,s=t.parts===!0||t.scanToEnd===!0,i=[],a=[],c=[],p=e,m=-1,h=0,R=0,f=!1,$=!1,_=!1,y=!1,E=!1,S=!1,T=!1,L=!1,z=!1,I=!1,re=0,K,g,v={value:"",depth:0,isGlob:!1},k=()=>m>=n,l=()=>p.charCodeAt(m+1),H=()=>(K=g,p.charCodeAt(++m));for(;m<n;){g=H();let P;if(g===ye){T=v.backslashes=!0,g=H(),g===Qe&&(S=!0);continue}if(S===!0||g===Qe){for(re++;k()!==!0&&(g=H());){if(g===ye){T=v.backslashes=!0,H();continue}if(g===Qe){re++;continue}if(S!==!0&&g===je&&(g=H())===je){if(f=v.isBrace=!0,_=v.isGlob=!0,I=!0,s===!0)continue;break}if(S!==!0&&g===vn){if(f=v.isBrace=!0,_=v.isGlob=!0,I=!0,s===!0)continue;break}if(g===Tn&&(re--,re===0)){S=!1,f=v.isBrace=!0,I=!0;break}}if(s===!0)continue;break}if(g===Xt){if(i.push(m),a.push(v),v={value:"",depth:0,isGlob:!1},I===!0)continue;if(K===je&&m===h+1){h+=2;continue}R=m+1;continue}if(t.noext!==!0&&(g===$n||g===Sn||g===We||g===Wt||g===Fe)===!0&&l()===Xe){if(_=v.isGlob=!0,y=v.isExtglob=!0,I=!0,g===Fe&&m===h&&(z=!0),s===!0){for(;k()!==!0&&(g=H());){if(g===ye){T=v.backslashes=!0,g=H();continue}if(g===jt){_=v.isGlob=!0,I=!0;break}}continue}break}if(g===We){if(K===We&&(E=v.isGlobstar=!0),_=v.isGlob=!0,I=!0,s===!0)continue;break}if(g===Wt){if(_=v.isGlob=!0,I=!0,s===!0)continue;break}if(g===Hn){for(;k()!==!0&&(P=H());){if(P===ye){T=v.backslashes=!0,H();continue}if(P===kn){$=v.isBracket=!0,_=v.isGlob=!0,I=!0;break}}if(s===!0)continue;break}if(t.nonegate!==!0&&g===Fe&&m===h){L=v.negated=!0,h++;continue}if(t.noparen!==!0&&g===Xe){if(_=v.isGlob=!0,s===!0){for(;k()!==!0&&(g=H());){if(g===Xe){T=v.backslashes=!0,g=H();continue}if(g===jt){I=!0;break}}continue}break}if(_===!0){if(I=!0,s===!0)continue;break}}t.noext===!0&&(y=!1,_=!1);let w=p,B="",o="";h>0&&(B=p.slice(0,h),p=p.slice(h),R-=h),w&&_===!0&&R>0?(w=p.slice(0,R),o=p.slice(R)):_===!0?(w="",o=p):w=p,w&&w!==""&&w!=="/"&&w!==p&&Ft(w.charCodeAt(w.length-1))&&(w=w.slice(0,-1)),t.unescape===!0&&(o&&(o=Kt.removeBackslashes(o)),w&&T===!0&&(w=Kt.removeBackslashes(w)));let u={prefix:B,input:e,start:h,base:w,glob:o,isBrace:f,isBracket:$,isGlob:_,isExtglob:y,isGlobstar:E,negated:L,negatedExtglob:z};if(t.tokens===!0&&(u.maxDepth=0,Ft(g)||a.push(v),u.tokens=a),t.parts===!0||t.tokens===!0){let P;for(let b=0;b<i.length;b++){let V=P?P+1:h,J=i[b],X=e.slice(V,J);t.tokens&&(b===0&&h!==0?(a[b].isPrefix=!0,a[b].value=B):a[b].value=X,Qt(a[b]),u.maxDepth+=a[b].depth),(b!==0||X!=="")&&c.push(X),P=J}if(P&&P+1<e.length){let b=e.slice(P+1);c.push(b),t.tokens&&(a[a.length-1].value=b,Qt(a[a.length-1]),u.maxDepth+=a[a.length-1].depth)}u.slashes=i,u.parts=c}return u};Zt.exports=Ln});var er=q((cs,Jt)=>{"use strict";var ke=me(),Y=Re(),{MAX_LENGTH:Le,POSIX_REGEX_SOURCE:On,REGEX_NON_SPECIAL_CHARS:Nn,REGEX_SPECIAL_CHARS_BACKREF:In,REPLACEMENTS:zt}=ke,Bn=(e,r)=>{if(typeof r.expandRange=="function")return r.expandRange(...e,r);e.sort();let t=`[${e.join("-")}]`;try{new RegExp(t)}catch{return e.map(s=>Y.escapeRegex(s)).join("..")}return t},de=(e,r)=>`Missing ${e}: "${r}" - use "\\\\${r}" to match literal characters`,Vt=(e,r)=>{if(typeof e!="string")throw new TypeError("Expected a string");e=zt[e]||e;let t={...r},n=typeof t.maxLength=="number"?Math.min(Le,t.maxLength):Le,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);let i={type:"bos",value:"",output:t.prepend||""},a=[i],c=t.capture?"":"?:",p=Y.isWindows(r),m=ke.globChars(p),h=ke.extglobChars(m),{DOT_LITERAL:R,PLUS_LITERAL:f,SLASH_LITERAL:$,ONE_CHAR:_,DOTS_SLASH:y,NO_DOT:E,NO_DOT_SLASH:S,NO_DOTS_SLASH:T,QMARK:L,QMARK_NO_DOT:z,STAR:I,START_ANCHOR:re}=m,K=A=>`(${c}(?:(?!${re}${A.dot?y:R}).)*?)`,g=t.dot?"":E,v=t.dot?L:z,k=t.bash===!0?K(t):I;t.capture&&(k=`(${k})`),typeof t.noext=="boolean"&&(t.noextglob=t.noext);let l={input:e,index:-1,start:0,dot:t.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:a};e=Y.removePrefix(e,l),s=e.length;let H=[],w=[],B=[],o=i,u,P=()=>l.index===s-1,b=l.peek=(A=1)=>e[l.index+A],V=l.advance=()=>e[++l.index]||"",J=()=>e.slice(l.index+1),X=(A="",O=0)=>{l.consumed+=A,l.index+=O},Ee=A=>{l.output+=A.output!=null?A.output:A.value,X(A.value)},mr=()=>{let A=1;for(;b()==="!"&&(b(2)!=="("||b(3)==="?");)V(),l.start++,A++;return A%2===0?!1:(l.negated=!0,l.start++,!0)},be=A=>{l[A]++,B.push(A)},oe=A=>{l[A]--,B.pop()},C=A=>{if(o.type==="globstar"){let O=l.braces>0&&(A.type==="comma"||A.type==="brace"),d=A.extglob===!0||H.length&&(A.type==="pipe"||A.type==="paren");A.type!=="slash"&&A.type!=="paren"&&!O&&!d&&(l.output=l.output.slice(0,-o.output.length),o.type="star",o.value="*",o.output=k,l.output+=o.output)}if(H.length&&A.type!=="paren"&&(H[H.length-1].inner+=A.value),(A.value||A.output)&&Ee(A),o&&o.type==="text"&&A.type==="text"){o.value+=A.value,o.output=(o.output||"")+A.value;return}A.prev=o,a.push(A),o=A},xe=(A,O)=>{let d={...h[O],conditions:1,inner:""};d.prev=o,d.parens=l.parens,d.output=l.output;let x=(t.capture?"(":"")+d.open;be("parens"),C({type:A,value:O,output:l.output?"":_}),C({type:"paren",extglob:!0,value:V(),output:x}),H.push(d)},Rr=A=>{let O=A.close+(t.capture?")":""),d;if(A.type==="negate"){let x=k;A.inner&&A.inner.length>1&&A.inner.includes("/")&&(x=K(t)),(x!==k||P()||/^\)+$/.test(J()))&&(O=A.close=`)$))${x}`),A.inner.includes("*")&&(d=J())&&/^\.[^\\/.]+$/.test(d)&&(O=A.close=`)${d})${x})`),A.prev.type==="bos"&&(l.negatedExtglob=!0)}C({type:"paren",extglob:!0,value:u,output:O}),oe("parens")};if(t.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(e)){let A=!1,O=e.replace(In,(d,x,M,j,G,Ie)=>j==="\\"?(A=!0,d):j==="?"?x?x+j+(G?L.repeat(G.length):""):Ie===0?v+(G?L.repeat(G.length):""):L.repeat(M.length):j==="."?R.repeat(M.length):j==="*"?x?x+j+(G?k:""):k:x?d:`\\${d}`);return A===!0&&(t.unescape===!0?O=O.replace(/\\/g,""):O=O.replace(/\\+/g,d=>d.length%2===0?"\\\\":d?"\\":"")),O===e&&t.contains===!0?(l.output=e,l):(l.output=Y.wrapOutput(O,l,r),l)}for(;!P();){if(u=V(),u==="\0")continue;if(u==="\\"){let d=b();if(d==="/"&&t.bash!==!0||d==="."||d===";")continue;if(!d){u+="\\",C({type:"text",value:u});continue}let x=/^\\+/.exec(J()),M=0;if(x&&x[0].length>2&&(M=x[0].length,l.index+=M,M%2!==0&&(u+="\\")),t.unescape===!0?u=V():u+=V(),l.brackets===0){C({type:"text",value:u});continue}}if(l.brackets>0&&(u!=="]"||o.value==="["||o.value==="[^")){if(t.posix!==!1&&u===":"){let d=o.value.slice(1);if(d.includes("[")&&(o.posix=!0,d.includes(":"))){let x=o.value.lastIndexOf("["),M=o.value.slice(0,x),j=o.value.slice(x+2),G=On[j];if(G){o.value=M+G,l.backtrack=!0,V(),!i.output&&a.indexOf(o)===1&&(i.output=_);continue}}}(u==="["&&b()!==":"||u==="-"&&b()==="]")&&(u=`\\${u}`),u==="]"&&(o.value==="["||o.value==="[^")&&(u=`\\${u}`),t.posix===!0&&u==="!"&&o.value==="["&&(u="^"),o.value+=u,Ee({value:u});continue}if(l.quotes===1&&u!=='"'){u=Y.escapeRegex(u),o.value+=u,Ee({value:u});continue}if(u==='"'){l.quotes=l.quotes===1?0:1,t.keepQuotes===!0&&C({type:"text",value:u});continue}if(u==="("){be("parens"),C({type:"paren",value:u});continue}if(u===")"){if(l.parens===0&&t.strictBrackets===!0)throw new SyntaxError(de("opening","("));let d=H[H.length-1];if(d&&l.parens===d.parens+1){Rr(H.pop());continue}C({type:"paren",value:u,output:l.parens?")":"\\)"}),oe("parens");continue}if(u==="["){if(t.nobracket===!0||!J().includes("]")){if(t.nobracket!==!0&&t.strictBrackets===!0)throw new SyntaxError(de("closing","]"));u=`\\${u}`}else be("brackets");C({type:"bracket",value:u});continue}if(u==="]"){if(t.nobracket===!0||o&&o.type==="bracket"&&o.value.length===1){C({type:"text",value:u,output:`\\${u}`});continue}if(l.brackets===0){if(t.strictBrackets===!0)throw new SyntaxError(de("opening","["));C({type:"text",value:u,output:`\\${u}`});continue}oe("brackets");let d=o.value.slice(1);if(o.posix!==!0&&d[0]==="^"&&!d.includes("/")&&(u=`/${u}`),o.value+=u,Ee({value:u}),t.literalBrackets===!1||Y.hasRegexChars(d))continue;let x=Y.escapeRegex(o.value);if(l.output=l.output.slice(0,-o.value.length),t.literalBrackets===!0){l.output+=x,o.value=x;continue}o.value=`(${c}${x}|${o.value})`,l.output+=o.value;continue}if(u==="{"&&t.nobrace!==!0){be("braces");let d={type:"brace",value:u,output:"(",outputIndex:l.output.length,tokensIndex:l.tokens.length};w.push(d),C(d);continue}if(u==="}"){let d=w[w.length-1];if(t.nobrace===!0||!d){C({type:"text",value:u,output:u});continue}let x=")";if(d.dots===!0){let M=a.slice(),j=[];for(let G=M.length-1;G>=0&&(a.pop(),M[G].type!=="brace");G--)M[G].type!=="dots"&&j.unshift(M[G].value);x=Bn(j,t),l.backtrack=!0}if(d.comma!==!0&&d.dots!==!0){let M=l.output.slice(0,d.outputIndex),j=l.tokens.slice(d.tokensIndex);d.value=d.output="\\{",u=x="\\}",l.output=M;for(let G of j)l.output+=G.output||G.value}C({type:"brace",value:u,output:x}),oe("braces"),w.pop();continue}if(u==="|"){H.length>0&&H[H.length-1].conditions++,C({type:"text",value:u});continue}if(u===","){let d=u,x=w[w.length-1];x&&B[B.length-1]==="braces"&&(x.comma=!0,d="|"),C({type:"comma",value:u,output:d});continue}if(u==="/"){if(o.type==="dot"&&l.index===l.start+1){l.start=l.index+1,l.consumed="",l.output="",a.pop(),o=i;continue}C({type:"slash",value:u,output:$});continue}if(u==="."){if(l.braces>0&&o.type==="dot"){o.value==="."&&(o.output=R);let d=w[w.length-1];o.type="dots",o.output+=u,o.value+=u,d.dots=!0;continue}if(l.braces+l.parens===0&&o.type!=="bos"&&o.type!=="slash"){C({type:"text",value:u,output:R});continue}C({type:"dot",value:u,output:R});continue}if(u==="?"){if(!(o&&o.value==="(")&&t.noextglob!==!0&&b()==="("&&b(2)!=="?"){xe("qmark",u);continue}if(o&&o.type==="paren"){let x=b(),M=u;if(x==="<"&&!Y.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(o.value==="("&&!/[!=<:]/.test(x)||x==="<"&&!/<([!=]|\w+>)/.test(J()))&&(M=`\\${u}`),C({type:"text",value:u,output:M});continue}if(t.dot!==!0&&(o.type==="slash"||o.type==="bos")){C({type:"qmark",value:u,output:z});continue}C({type:"qmark",value:u,output:L});continue}if(u==="!"){if(t.noextglob!==!0&&b()==="("&&(b(2)!=="?"||!/[!=<:]/.test(b(3)))){xe("negate",u);continue}if(t.nonegate!==!0&&l.index===0){mr();continue}}if(u==="+"){if(t.noextglob!==!0&&b()==="("&&b(2)!=="?"){xe("plus",u);continue}if(o&&o.value==="("||t.regex===!1){C({type:"plus",value:u,output:f});continue}if(o&&(o.type==="bracket"||o.type==="paren"||o.type==="brace")||l.parens>0){C({type:"plus",value:u});continue}C({type:"plus",value:f});continue}if(u==="@"){if(t.noextglob!==!0&&b()==="("&&b(2)!=="?"){C({type:"at",extglob:!0,value:u,output:""});continue}C({type:"text",value:u});continue}if(u!=="*"){(u==="$"||u==="^")&&(u=`\\${u}`);let d=Nn.exec(J());d&&(u+=d[0],l.index+=d[0].length),C({type:"text",value:u});continue}if(o&&(o.type==="globstar"||o.star===!0)){o.type="star",o.star=!0,o.value+=u,o.output=k,l.backtrack=!0,l.globstar=!0,X(u);continue}let A=J();if(t.noextglob!==!0&&/^\([^?]/.test(A)){xe("star",u);continue}if(o.type==="star"){if(t.noglobstar===!0){X(u);continue}let d=o.prev,x=d.prev,M=d.type==="slash"||d.type==="bos",j=x&&(x.type==="star"||x.type==="globstar");if(t.bash===!0&&(!M||A[0]&&A[0]!=="/")){C({type:"star",value:u,output:""});continue}let G=l.braces>0&&(d.type==="comma"||d.type==="brace"),Ie=H.length&&(d.type==="pipe"||d.type==="paren");if(!M&&d.type!=="paren"&&!G&&!Ie){C({type:"star",value:u,output:""});continue}for(;A.slice(0,3)==="/**";){let Ce=e[l.index+4];if(Ce&&Ce!=="/")break;A=A.slice(3),X("/**",3)}if(d.type==="bos"&&P()){o.type="globstar",o.value+=u,o.output=K(t),l.output=o.output,l.globstar=!0,X(u);continue}if(d.type==="slash"&&d.prev.type!=="bos"&&!j&&P()){l.output=l.output.slice(0,-(d.output+o.output).length),d.output=`(?:${d.output}`,o.type="globstar",o.output=K(t)+(t.strictSlashes?")":"|$)"),o.value+=u,l.globstar=!0,l.output+=d.output+o.output,X(u);continue}if(d.type==="slash"&&d.prev.type!=="bos"&&A[0]==="/"){let Ce=A[1]!==void 0?"|$":"";l.output=l.output.slice(0,-(d.output+o.output).length),d.output=`(?:${d.output}`,o.type="globstar",o.output=`${K(t)}${$}|${$}${Ce})`,o.value+=u,l.output+=d.output+o.output,l.globstar=!0,X(u+V()),C({type:"slash",value:"/",output:""});continue}if(d.type==="bos"&&A[0]==="/"){o.type="globstar",o.value+=u,o.output=`(?:^|${$}|${K(t)}${$})`,l.output=o.output,l.globstar=!0,X(u+V()),C({type:"slash",value:"/",output:""});continue}l.output=l.output.slice(0,-o.output.length),o.type="globstar",o.output=K(t),o.value+=u,l.output+=o.output,l.globstar=!0,X(u);continue}let O={type:"star",value:u,output:k};if(t.bash===!0){O.output=".*?",(o.type==="bos"||o.type==="slash")&&(O.output=g+O.output),C(O);continue}if(o&&(o.type==="bracket"||o.type==="paren")&&t.regex===!0){O.output=u,C(O);continue}(l.index===l.start||o.type==="slash"||o.type==="dot")&&(o.type==="dot"?(l.output+=S,o.output+=S):t.dot===!0?(l.output+=T,o.output+=T):(l.output+=g,o.output+=g),b()!=="*"&&(l.output+=_,o.output+=_)),C(O)}for(;l.brackets>0;){if(t.strictBrackets===!0)throw new SyntaxError(de("closing","]"));l.output=Y.escapeLast(l.output,"["),oe("brackets")}for(;l.parens>0;){if(t.strictBrackets===!0)throw new SyntaxError(de("closing",")"));l.output=Y.escapeLast(l.output,"("),oe("parens")}for(;l.braces>0;){if(t.strictBrackets===!0)throw new SyntaxError(de("closing","}"));l.output=Y.escapeLast(l.output,"{"),oe("braces")}if(t.strictSlashes!==!0&&(o.type==="star"||o.type==="bracket")&&C({type:"maybe_slash",value:"",output:`${$}?`}),l.backtrack===!0){l.output="";for(let A of l.tokens)l.output+=A.output!=null?A.output:A.value,A.suffix&&(l.output+=A.suffix)}return l};Vt.fastpaths=(e,r)=>{let t={...r},n=typeof t.maxLength=="number"?Math.min(Le,t.maxLength):Le,s=e.length;if(s>n)throw new SyntaxError(`Input length: ${s}, exceeds maximum allowed length: ${n}`);e=zt[e]||e;let i=Y.isWindows(r),{DOT_LITERAL:a,SLASH_LITERAL:c,ONE_CHAR:p,DOTS_SLASH:m,NO_DOT:h,NO_DOTS:R,NO_DOTS_SLASH:f,STAR:$,START_ANCHOR:_}=ke.globChars(i),y=t.dot?R:h,E=t.dot?f:h,S=t.capture?"":"?:",T={negated:!1,prefix:""},L=t.bash===!0?".*?":$;t.capture&&(L=`(${L})`);let z=g=>g.noglobstar===!0?L:`(${S}(?:(?!${_}${g.dot?m:a}).)*?)`,I=g=>{switch(g){case"*":return`${y}${p}${L}`;case".*":return`${a}${p}${L}`;case"*.*":return`${y}${L}${a}${p}${L}`;case"*/*":return`${y}${L}${c}${p}${E}${L}`;case"**":return y+z(t);case"**/*":return`(?:${y}${z(t)}${c})?${E}${p}${L}`;case"**/*.*":return`(?:${y}${z(t)}${c})?${E}${L}${a}${p}${L}`;case"**/.*":return`(?:${y}${z(t)}${c})?${a}${p}${L}`;default:{let v=/^(.*?)\.(\w+)$/.exec(g);if(!v)return;let k=I(v[1]);return k?k+a+v[2]:void 0}}},re=Y.removePrefix(e,T),K=I(re);return K&&t.strictSlashes!==!0&&(K+=`${c}?`),K};Jt.exports=Vt});var rr=q((ls,tr)=>{"use strict";var Pn=W("path"),Mn=Yt(),Ze=er(),Ye=Re(),Dn=me(),Un=e=>e&&typeof e=="object"&&!Array.isArray(e),D=(e,r,t=!1)=>{if(Array.isArray(e)){let h=e.map(f=>D(f,r,t));return f=>{for(let $ of h){let _=$(f);if(_)return _}return!1}}let n=Un(e)&&e.tokens&&e.input;if(e===""||typeof e!="string"&&!n)throw new TypeError("Expected pattern to be a non-empty string");let s=r||{},i=Ye.isWindows(r),a=n?D.compileRe(e,r):D.makeRe(e,r,!1,!0),c=a.state;delete a.state;let p=()=>!1;if(s.ignore){let h={...r,ignore:null,onMatch:null,onResult:null};p=D(s.ignore,h,t)}let m=(h,R=!1)=>{let{isMatch:f,match:$,output:_}=D.test(h,a,r,{glob:e,posix:i}),y={glob:e,state:c,regex:a,posix:i,input:h,output:_,match:$,isMatch:f};return typeof s.onResult=="function"&&s.onResult(y),f===!1?(y.isMatch=!1,R?y:!1):p(h)?(typeof s.onIgnore=="function"&&s.onIgnore(y),y.isMatch=!1,R?y:!1):(typeof s.onMatch=="function"&&s.onMatch(y),R?y:!0)};return t&&(m.state=c),m};D.test=(e,r,t,{glob:n,posix:s}={})=>{if(typeof e!="string")throw new TypeError("Expected input to be a string");if(e==="")return{isMatch:!1,output:""};let i=t||{},a=i.format||(s?Ye.toPosixSlashes:null),c=e===n,p=c&&a?a(e):e;return c===!1&&(p=a?a(e):e,c=p===n),(c===!1||i.capture===!0)&&(i.matchBase===!0||i.basename===!0?c=D.matchBase(e,r,t,s):c=r.exec(p)),{isMatch:Boolean(c),match:c,output:p}};D.matchBase=(e,r,t,n=Ye.isWindows(t))=>(r instanceof RegExp?r:D.makeRe(r,t)).test(Pn.basename(e));D.isMatch=(e,r,t)=>D(r,t)(e);D.parse=(e,r)=>Array.isArray(e)?e.map(t=>D.parse(t,r)):Ze(e,{...r,fastpaths:!1});D.scan=(e,r)=>Mn(e,r);D.compileRe=(e,r,t=!1,n=!1)=>{if(t===!0)return e.output;let s=r||{},i=s.contains?"":"^",a=s.contains?"":"$",c=`${i}(?:${e.output})${a}`;e&&e.negated===!0&&(c=`^(?!${c}).*$`);let p=D.toRegex(c,r);return n===!0&&(p.state=e),p};D.makeRe=(e,r={},t=!1,n=!1)=>{if(!e||typeof e!="string")throw new TypeError("Expected a non-empty string");let s={negated:!1,fastpaths:!0};return r.fastpaths!==!1&&(e[0]==="."||e[0]==="*")&&(s.output=Ze.fastpaths(e,r)),s.output||(s=Ze(e,r)),D.compileRe(s,r,t,n)};D.toRegex=(e,r)=>{try{let t=r||{};return new RegExp(e,t.flags||(t.nocase?"i":""))}catch(t){if(r&&r.debug===!0)throw t;return/$^/}};D.constants=Dn;tr.exports=D});var sr=q((fs,nr)=>{"use strict";nr.exports=rr()});var cr=q((ps,ur)=>{"use strict";var ir=W("util"),or=Pt(),ae=sr(),ze=Re(),ar=e=>e===""||e==="./",N=(e,r,t)=>{r=[].concat(r),e=[].concat(e);let n=new Set,s=new Set,i=new Set,a=0,c=h=>{i.add(h.output),t&&t.onResult&&t.onResult(h)};for(let h=0;h<r.length;h++){let R=ae(String(r[h]),{...t,onResult:c},!0),f=R.state.negated||R.state.negatedExtglob;f&&a++;for(let $ of e){let _=R($,!0);!(f?!_.isMatch:_.isMatch)||(f?n.add(_.output):(n.delete(_.output),s.add(_.output)))}}let m=(a===r.length?[...i]:[...s]).filter(h=>!n.has(h));if(t&&m.length===0){if(t.failglob===!0)throw new Error(`No matches found for "${r.join(", ")}"`);if(t.nonull===!0||t.nullglob===!0)return t.unescape?r.map(h=>h.replace(/\\/g,"")):r}return m};N.match=N;N.matcher=(e,r)=>ae(e,r);N.isMatch=(e,r,t)=>ae(r,t)(e);N.any=N.isMatch;N.not=(e,r,t={})=>{r=[].concat(r).map(String);let n=new Set,s=[],a=N(e,r,{...t,onResult:c=>{t.onResult&&t.onResult(c),s.push(c.output)}});for(let c of s)a.includes(c)||n.add(c);return[...n]};N.contains=(e,r,t)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${ir.inspect(e)}"`);if(Array.isArray(r))return r.some(n=>N.contains(e,n,t));if(typeof r=="string"){if(ar(e)||ar(r))return!1;if(e.includes(r)||e.startsWith("./")&&e.slice(2).includes(r))return!0}return N.isMatch(e,r,{...t,contains:!0})};N.matchKeys=(e,r,t)=>{if(!ze.isObject(e))throw new TypeError("Expected the first argument to be an object");let n=N(Object.keys(e),r,t),s={};for(let i of n)s[i]=e[i];return s};N.some=(e,r,t)=>{let n=[].concat(e);for(let s of[].concat(r)){let i=ae(String(s),t);if(n.some(a=>i(a)))return!0}return!1};N.every=(e,r,t)=>{let n=[].concat(e);for(let s of[].concat(r)){let i=ae(String(s),t);if(!n.every(a=>i(a)))return!1}return!0};N.all=(e,r,t)=>{if(typeof e!="string")throw new TypeError(`Expected a string: "${ir.inspect(e)}"`);return[].concat(r).every(n=>ae(n,t)(e))};N.capture=(e,r,t)=>{let n=ze.isWindows(t),i=ae.makeRe(String(e),{...t,capture:!0}).exec(n?ze.toPosixSlashes(r):r);if(i)return i.slice(1).map(a=>a===void 0?"":a)};N.makeRe=(...e)=>ae.makeRe(...e);N.scan=(...e)=>ae.scan(...e);N.parse=(e,r)=>{let t=[];for(let n of[].concat(e||[]))for(let s of or(String(n),r))t.push(ae.parse(s,r));return t};N.braces=(e,r)=>{if(typeof e!="string")throw new TypeError("Expected a string");return r&&r.nobrace===!0||!/\{.*\}/.test(e)?[e]:or(e,r)};N.braceExpand=(e,r)=>{if(typeof e!="string")throw new TypeError("Expected a string");return N.braces(e,{...r,expand:!0})};ur.exports=N});var fr=q((hs,lr)=>{"use strict";lr.exports=(e,...r)=>new Promise(t=>{t(e(...r))})});var hr=q((ds,Ve)=>{"use strict";var Gn=fr(),pr=e=>{if(e<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let r=[],t=0,n=()=>{t--,r.length>0&&r.shift()()},s=(c,p,...m)=>{t++;let h=Gn(c,...m);p(h),h.then(n,n)},i=(c,p,...m)=>{t<e?s(c,p,...m):r.push(s.bind(null,c,p,...m))},a=(c,...p)=>new Promise(m=>i(c,m,...p));return Object.defineProperties(a,{activeCount:{get:()=>t},pendingCount:{get:()=>r.length}}),a};Ve.exports=pr;Ve.exports.default=pr});var jn={};Cr(jn,{default:()=>Wn});var Se=W("@yarnpkg/cli"),ne=W("@yarnpkg/core"),et=W("@yarnpkg/core"),ue=W("clipanion"),ce=class extends Se.BaseCommand{constructor(){super(...arguments);this.json=ue.Option.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.production=ue.Option.Boolean("--production",!1,{description:"Only install regular dependencies by omitting dev dependencies"});this.all=ue.Option.Boolean("-A,--all",!1,{description:"Install the entire project"});this.workspaces=ue.Option.Rest()}async execute(){let t=await ne.Configuration.find(this.context.cwd,this.context.plugins),{project:n,workspace:s}=await ne.Project.find(t,this.context.cwd),i=await ne.Cache.find(t);await n.restoreInstallState({restoreResolutions:!1});let a;if(this.all)a=new Set(n.workspaces);else if(this.workspaces.length===0){if(!s)throw new Se.WorkspaceRequiredError(n.cwd,this.context.cwd);a=new Set([s])}else a=new Set(this.workspaces.map(p=>n.getWorkspaceByIdent(et.structUtils.parseIdent(p))));for(let p of a)for(let m of this.production?["dependencies"]:ne.Manifest.hardDependencies)for(let h of p.manifest.getForScope(m).values()){let R=n.tryWorkspaceByDescriptor(h);R!==null&&a.add(R)}for(let p of n.workspaces)a.has(p)?this.production&&p.manifest.devDependencies.clear():(p.manifest.installConfig=p.manifest.installConfig||{},p.manifest.installConfig.selfReferences=!1,p.manifest.dependencies.clear(),p.manifest.devDependencies.clear(),p.manifest.peerDependencies.clear(),p.manifest.scripts.clear());return(await ne.StreamReport.start({configuration:t,json:this.json,stdout:this.context.stdout,includeLogs:!0},async p=>{await n.install({cache:i,report:p,persistProject:!1})})).exitCode()}};ce.paths=[["workspaces","focus"]],ce.usage=ue.Command.Usage({category:"Workspace-related commands",description:"install a single workspace and its dependencies",details:"\n This command will run an install as if the specified workspaces (and all other workspaces they depend on) were the only ones in the project. If no workspaces are explicitly listed, the active one will be assumed.\n\n Note that this command is only very moderately useful when using zero-installs, since the cache will contain all the packages anyway - meaning that the only difference between a full install and a focused install would just be a few extra lines in the `.pnp.cjs` file, at the cost of introducing an extra complexity.\n\n If the `-A,--all` flag is set, the entire project will be installed. Combine with `--production` to replicate the old `yarn install --production`.\n "});var Ne=W("@yarnpkg/cli"),ge=W("@yarnpkg/core"),_e=W("@yarnpkg/core"),F=W("@yarnpkg/core"),gr=W("@yarnpkg/plugin-git"),U=W("clipanion"),Oe=Be(cr()),Ar=Be(hr()),te=Be(W("typanion")),pe=class extends Ne.BaseCommand{constructor(){super(...arguments);this.recursive=U.Option.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.from=U.Option.Array("--from",[],{description:"An array of glob pattern idents from which to base any recursion"});this.all=U.Option.Boolean("-A,--all",!1,{description:"Run the command on all workspaces of a project"});this.verbose=U.Option.Boolean("-v,--verbose",!1,{description:"Prefix each output line with the name of the originating workspace"});this.parallel=U.Option.Boolean("-p,--parallel",!1,{description:"Run the commands in parallel"});this.interlaced=U.Option.Boolean("-i,--interlaced",!1,{description:"Print the output of commands in real-time instead of buffering it"});this.jobs=U.Option.String("-j,--jobs",{description:"The maximum number of parallel tasks that the execution will be limited to; or `unlimited`",validator:te.isOneOf([te.isEnum(["unlimited"]),te.applyCascade(te.isNumber(),[te.isInteger(),te.isAtLeast(1)])])});this.topological=U.Option.Boolean("-t,--topological",!1,{description:"Run the command after all workspaces it depends on (regular) have finished"});this.topologicalDev=U.Option.Boolean("--topological-dev",!1,{description:"Run the command after all workspaces it depends on (regular + dev) have finished"});this.include=U.Option.Array("--include",[],{description:"An array of glob pattern idents; only matching workspaces will be traversed"});this.exclude=U.Option.Array("--exclude",[],{description:"An array of glob pattern idents; matching workspaces won't be traversed"});this.publicOnly=U.Option.Boolean("--no-private",{description:"Avoid running the command on private workspaces"});this.since=U.Option.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.commandName=U.Option.String();this.args=U.Option.Proxy()}async execute(){let t=await ge.Configuration.find(this.context.cwd,this.context.plugins),{project:n,workspace:s}=await ge.Project.find(t,this.context.cwd);if(!this.all&&!s)throw new Ne.WorkspaceRequiredError(n.cwd,this.context.cwd);await n.restoreInstallState();let i=this.cli.process([this.commandName,...this.args]),a=i.path.length===1&&i.path[0]==="run"&&typeof i.scriptName<"u"?i.scriptName:null;if(i.path.length===0)throw new U.UsageError("Invalid subcommand name for iteration - use the 'run' keyword if you wish to execute a script");let c=this.all?n.topLevelWorkspace:s,p=this.since?Array.from(await gr.gitUtils.fetchChangedWorkspaces({ref:this.since,project:n})):[c,...this.from.length>0?c.getRecursiveWorkspaceChildren():[]],m=g=>Oe.default.isMatch(F.structUtils.stringifyIdent(g.locator),this.from),h=this.from.length>0?p.filter(m):p,R=new Set([...h,...h.map(g=>[...this.recursive?this.since?g.getRecursiveWorkspaceDependents():g.getRecursiveWorkspaceDependencies():g.getRecursiveWorkspaceChildren()]).flat()]),f=[],$=!1;if(a!=null&&a.includes(":")){for(let g of n.workspaces)if(g.manifest.scripts.has(a)&&($=!$,$===!1))break}for(let g of R)a&&!g.manifest.scripts.has(a)&&!$&&!(await ge.scriptUtils.getWorkspaceAccessibleBinaries(g)).has(a)||a===process.env.npm_lifecycle_event&&g.cwd===s.cwd||this.include.length>0&&!Oe.default.isMatch(F.structUtils.stringifyIdent(g.locator),this.include)||this.exclude.length>0&&Oe.default.isMatch(F.structUtils.stringifyIdent(g.locator),this.exclude)||this.publicOnly&&g.manifest.private===!0||f.push(g);let _=this.parallel?this.jobs==="unlimited"?1/0:Number(this.jobs)||Math.ceil(F.nodeUtils.availableParallelism()/2):1,y=_===1?!1:this.parallel,E=y?this.interlaced:!0,S=(0,Ar.default)(_),T=new Map,L=new Set,z=0,I=null,re=!1,K=await _e.StreamReport.start({configuration:t,stdout:this.context.stdout,includePrefix:!1},async g=>{let v=async(k,{commandIndex:l})=>{if(re)return-1;!y&&this.verbose&&l>1&&g.reportSeparator();let H=qn(k,{configuration:t,verbose:this.verbose,commandIndex:l}),[w,B]=dr(g,{prefix:H,interlaced:E}),[o,u]=dr(g,{prefix:H,interlaced:E});try{this.verbose&&g.reportInfo(null,`${H} Process started`);let P=Date.now(),b=await this.cli.run([this.commandName,...this.args],{cwd:k.cwd,stdout:w,stderr:o})||0;w.end(),o.end(),await B,await u;let V=Date.now();if(this.verbose){let J=t.get("enableTimers")?`, completed in ${F.formatUtils.pretty(t,V-P,F.formatUtils.Type.DURATION)}`:"";g.reportInfo(null,`${H} Process exited (exit code ${b})${J}`)}return b===130&&(re=!0,I=b),b}catch(P){throw w.end(),o.end(),await B,await u,P}};for(let k of f)T.set(k.anchoredLocator.locatorHash,k);for(;T.size>0&&!g.hasErrors();){let k=[];for(let[w,B]of T){if(L.has(B.anchoredDescriptor.descriptorHash))continue;let o=!0;if(this.topological||this.topologicalDev){let u=this.topologicalDev?new Map([...B.manifest.dependencies,...B.manifest.devDependencies]):B.manifest.dependencies;for(let P of u.values()){let b=n.tryWorkspaceByDescriptor(P);if(o=b===null||!T.has(b.anchoredLocator.locatorHash),!o)break}}if(!!o&&(L.add(B.anchoredDescriptor.descriptorHash),k.push(S(async()=>{let u=await v(B,{commandIndex:++z});return T.delete(w),L.delete(B.anchoredDescriptor.descriptorHash),u})),!y))break}if(k.length===0){let w=Array.from(T.values()).map(B=>F.structUtils.prettyLocator(t,B.anchoredLocator)).join(", ");g.reportError(_e.MessageName.CYCLIC_DEPENDENCIES,`Dependency cycle detected (${w})`);return}let H=(await Promise.all(k)).find(w=>w!==0);I===null&&(I=typeof H<"u"?1:I),(this.topological||this.topologicalDev)&&typeof H<"u"&&g.reportError(_e.MessageName.UNNAMED,"The command failed for workspaces that are depended upon by other workspaces; can't satisfy the dependency graph")}});return I!==null?I:K.exitCode()}};pe.paths=[["workspaces","foreach"]],pe.usage=U.Command.Usage({category:"Workspace-related commands",description:"run a command on all workspaces",details:"\n This command will run a given sub-command on current and all its descendant workspaces. Various flags can alter the exact behavior of the command:\n\n - If `-p,--parallel` is set, the commands will be ran in parallel; they'll by default be limited to a number of parallel tasks roughly equal to half your core number, but that can be overridden via `-j,--jobs`, or disabled by setting `-j unlimited`.\n\n - If `-p,--parallel` and `-i,--interlaced` are both set, Yarn will print the lines from the output as it receives them. If `-i,--interlaced` wasn't set, it would instead buffer the output from each process and print the resulting buffers only after their source processes have exited.\n\n - If `-t,--topological` is set, Yarn will only run the command after all workspaces that it depends on through the `dependencies` field have successfully finished executing. If `--topological-dev` is set, both the `dependencies` and `devDependencies` fields will be considered when figuring out the wait points.\n\n - If `-A,--all` is set, Yarn will run the command on all the workspaces of a project. By default yarn runs the command only on current and all its descendant workspaces.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `--from` is set, Yarn will use the packages matching the 'from' glob as the starting point for any recursive search.\n\n - If `--since` is set, Yarn will only run the command on workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - The command may apply to only some workspaces through the use of `--include` which acts as a whitelist. The `--exclude` flag will do the opposite and will be a list of packages that mustn't execute the script. Both flags accept glob patterns (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n Adding the `-v,--verbose` flag will cause Yarn to print more information; in particular the name of the workspace that generated the output will be printed at the front of each line.\n\n If the command is `run` and the script being run does not exist the child workspace will be skipped without error.\n ",examples:[["Publish current and all descendant packages","yarn workspaces foreach npm publish --tolerate-republish"],["Run build script on current and all descendant packages","yarn workspaces foreach run build"],["Run build script on current and all descendant packages in parallel, building package dependencies first","yarn workspaces foreach -pt run build"],["Run build script on several packages and all their dependencies, building dependencies first","yarn workspaces foreach -ptR --from '{workspace-a,workspace-b}' run build"]]});function dr(e,{prefix:r,interlaced:t}){let n=e.createStreamReporter(r),s=new F.miscUtils.DefaultStream;s.pipe(n,{end:!1}),s.on("finish",()=>{n.end()});let i=new Promise(c=>{n.on("finish",()=>{c(s.active)})});if(t)return[s,i];let a=new F.miscUtils.BufferStream;return a.pipe(s,{end:!1}),a.on("finish",()=>{s.end()}),[a,i]}function qn(e,{configuration:r,commandIndex:t,verbose:n}){if(!n)return null;let i=`[${F.structUtils.stringifyIdent(e.locator)}]:`,a=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],c=a[t%a.length];return F.formatUtils.pretty(r,i,c)}var Kn={commands:[ce,pe]},Wn=Kn;return wr(jn);})(); /*! * fill-range <https://github.com/jonschlinkert/fill-range> * diff --git a/.yarn/releases/yarn-3.2.3.cjs b/.yarn/releases/yarn-3.2.3.cjs deleted file mode 100755 index 12bde0351e..0000000000 --- a/.yarn/releases/yarn-3.2.3.cjs +++ /dev/null @@ -1,783 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable */ -//prettier-ignore -(()=>{var age=Object.create,Uh=Object.defineProperty,Age=Object.defineProperties,lge=Object.getOwnPropertyDescriptor,cge=Object.getOwnPropertyDescriptors,uge=Object.getOwnPropertyNames,RE=Object.getOwnPropertySymbols,gge=Object.getPrototypeOf,tQ=Object.prototype.hasOwnProperty,HO=Object.prototype.propertyIsEnumerable;var jO=(r,e,t)=>e in r?Uh(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,N=(r,e)=>{for(var t in e||(e={}))tQ.call(e,t)&&jO(r,t,e[t]);if(RE)for(var t of RE(e))HO.call(e,t)&&jO(r,t,e[t]);return r},te=(r,e)=>Age(r,cge(e)),fge=r=>Uh(r,"__esModule",{value:!0});var Or=(r,e)=>{var t={};for(var i in r)tQ.call(r,i)&&e.indexOf(i)<0&&(t[i]=r[i]);if(r!=null&&RE)for(var i of RE(r))e.indexOf(i)<0&&HO.call(r,i)&&(t[i]=r[i]);return t},hge=(r,e)=>()=>(r&&(e=r(r=0)),e),w=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ft=(r,e)=>{for(var t in e)Uh(r,t,{get:e[t],enumerable:!0})},pge=(r,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of uge(e))!tQ.call(r,i)&&i!=="default"&&Uh(r,i,{get:()=>e[i],enumerable:!(t=lge(e,i))||t.enumerable});return r},ge=r=>pge(fge(Uh(r!=null?age(gge(r)):{},"default",r&&r.__esModule&&"default"in r?{get:()=>r.default,enumerable:!0}:{value:r,enumerable:!0})),r);var hM=w((s7e,cM)=>{cM.exports=uM;uM.sync=Dge;var gM=require("fs");function Rge(r,e){var t=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!t||(t=t.split(";"),t.indexOf("")!==-1))return!0;for(var i=0;i<t.length;i++){var n=t[i].toLowerCase();if(n&&r.substr(-n.length).toLowerCase()===n)return!0}return!1}function fM(r,e,t){return!r.isSymbolicLink()&&!r.isFile()?!1:Rge(e,t)}function uM(r,e,t){gM.stat(r,function(i,n){t(i,i?!1:fM(n,r,e))})}function Dge(r,e){return fM(gM.statSync(r),r,e)}});var EM=w((o7e,pM)=>{pM.exports=dM;dM.sync=Fge;var CM=require("fs");function dM(r,e,t){CM.stat(r,function(i,n){t(i,i?!1:mM(n,e))})}function Fge(r,e){return mM(CM.statSync(r),e)}function mM(r,e){return r.isFile()&&Nge(r,e)}function Nge(r,e){var t=r.mode,i=r.uid,n=r.gid,s=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),o=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),u=a|l,g=t&c||t&l&&n===o||t&a&&i===s||t&u&&s===0;return g}});var yM=w((A7e,IM)=>{var a7e=require("fs"),_E;process.platform==="win32"||global.TESTING_WINDOWS?_E=hM():_E=EM();IM.exports=mQ;mQ.sync=Lge;function mQ(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){mQ(r,e||{},function(s,o){s?n(s):i(o)})})}_E(r,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),t(i,n)})}function Lge(r,e){try{return _E.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}});var kM=w((l7e,wM)=>{var Zu=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",BM=require("path"),Tge=Zu?";":":",bM=yM(),QM=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),SM=(r,e)=>{let t=e.colon||Tge,i=r.match(/\//)||Zu&&r.match(/\\/)?[""]:[...Zu?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],n=Zu?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=Zu?n.split(t):[""];return Zu&&r.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},vM=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=SM(r,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(QM(r));let f=i[c],h=/^".*"$/.test(f)?f.slice(1,-1):f,p=BM.join(h,r),m=!h&&/^\.[\\\/]/.test(r)?r.slice(0,2)+p:p;u(l(m,c,0))}),l=(c,u,g)=>new Promise((f,h)=>{if(g===n.length)return f(a(u+1));let p=n[g];bM(c+p,{pathExt:s},(m,y)=>{if(!m&&y)if(e.all)o.push(c+p);else return f(c+p);return f(l(c,u,g+1))})});return t?a(0).then(c=>t(null,c),t):a(0)},Oge=(r,e)=>{e=e||{};let{pathEnv:t,pathExt:i,pathExtExe:n}=SM(r,e),s=[];for(let o=0;o<t.length;o++){let a=t[o],l=/^".*"$/.test(a)?a.slice(1,-1):a,c=BM.join(l,r),u=!l&&/^\.[\\\/]/.test(r)?r.slice(0,2)+c:c;for(let g=0;g<i.length;g++){let f=u+i[g];try{if(bM.sync(f,{pathExt:n}))if(e.all)s.push(f);else return f}catch(h){}}}if(e.all&&s.length)return s;if(e.nothrow)return null;throw QM(r)};wM.exports=vM;vM.sync=Oge});var PM=w((c7e,EQ)=>{"use strict";var xM=(r={})=>{let e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};EQ.exports=xM;EQ.exports.default=xM});var NM=w((u7e,DM)=>{"use strict";var RM=require("path"),Mge=kM(),Uge=PM();function FM(r,e){let t=r.options.env||process.env,i=process.cwd(),n=r.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(r.options.cwd)}catch(a){}let o;try{o=Mge.sync(r.command,{path:t[Uge({env:t})],pathExt:e?RM.delimiter:void 0})}catch(a){}finally{s&&process.chdir(i)}return o&&(o=RM.resolve(n?r.options.cwd:"",o)),o}function Kge(r){return FM(r)||FM(r,!0)}DM.exports=Kge});var LM=w((g7e,IQ)=>{"use strict";var yQ=/([()\][%!^"`<>&|;, *?])/g;function Hge(r){return r=r.replace(yQ,"^$1"),r}function jge(r,e){return r=`${r}`,r=r.replace(/(\\*)"/g,'$1$1\\"'),r=r.replace(/(\\*)$/,"$1$1"),r=`"${r}"`,r=r.replace(yQ,"^$1"),e&&(r=r.replace(yQ,"^$1")),r}IQ.exports.command=Hge;IQ.exports.argument=jge});var OM=w((f7e,TM)=>{"use strict";TM.exports=/^#!(.*)/});var UM=w((h7e,MM)=>{"use strict";var Gge=OM();MM.exports=(r="")=>{let e=r.match(Gge);if(!e)return null;let[t,i]=e[0].replace(/#! ?/,"").split(" "),n=t.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var HM=w((p7e,KM)=>{"use strict";var wQ=require("fs"),Yge=UM();function qge(r){let e=150,t=Buffer.alloc(e),i;try{i=wQ.openSync(r,"r"),wQ.readSync(i,t,0,e,0),wQ.closeSync(i)}catch(n){}return Yge(t.toString())}KM.exports=qge});var qM=w((d7e,jM)=>{"use strict";var Jge=require("path"),GM=NM(),YM=LM(),Wge=HM(),zge=process.platform==="win32",_ge=/\.(?:com|exe)$/i,Vge=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Xge(r){r.file=GM(r);let e=r.file&&Wge(r.file);return e?(r.args.unshift(r.file),r.command=e,GM(r)):r.file}function Zge(r){if(!zge)return r;let e=Xge(r),t=!_ge.test(e);if(r.options.forceShell||t){let i=Vge.test(e);r.command=Jge.normalize(r.command),r.command=YM.command(r.command),r.args=r.args.map(s=>YM.argument(s,i));let n=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${n}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function $ge(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);let i={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?i:Zge(i)}jM.exports=$ge});var zM=w((C7e,JM)=>{"use strict";var BQ=process.platform==="win32";function bQ(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function efe(r,e){if(!BQ)return;let t=r.emit;r.emit=function(i,n){if(i==="exit"){let s=WM(n,e,"spawn");if(s)return t.call(r,"error",s)}return t.apply(r,arguments)}}function WM(r,e){return BQ&&r===1&&!e.file?bQ(e.original,"spawn"):null}function tfe(r,e){return BQ&&r===1&&!e.file?bQ(e.original,"spawnSync"):null}JM.exports={hookChildProcess:efe,verifyENOENT:WM,verifyENOENTSync:tfe,notFoundError:bQ}});var vQ=w((m7e,$u)=>{"use strict";var _M=require("child_process"),QQ=qM(),SQ=zM();function VM(r,e,t){let i=QQ(r,e,t),n=_M.spawn(i.command,i.args,i.options);return SQ.hookChildProcess(n,i),n}function rfe(r,e,t){let i=QQ(r,e,t),n=_M.spawnSync(i.command,i.args,i.options);return n.error=n.error||SQ.verifyENOENTSync(n.status,i),n}$u.exports=VM;$u.exports.spawn=VM;$u.exports.sync=rfe;$u.exports._parse=QQ;$u.exports._enoent=SQ});var ZM=w((E7e,XM)=>{"use strict";function ife(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function uc(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,uc)}ife(uc,Error);uc.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g<c.parts.length;g++)u+=c.parts[g]instanceof Array?s(c.parts[g][0])+"-"+s(c.parts[g][1]):s(c.parts[g]);return"["+(c.inverted?"^":"")+u+"]"},any:function(c){return"any character"},end:function(c){return"end of input"},other:function(c){return c.description}};function i(c){return c.charCodeAt(0).toString(16).toUpperCase()}function n(c){return c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function s(c){return c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function o(c){return t[c.type](c)}function a(c){var u=new Array(c.length),g,f;for(g=0;g<c.length;g++)u[g]=o(c[g]);if(u.sort(),u.length>0){for(g=1,f=1;g<u.length;g++)u[g-1]!==u[g]&&(u[f]=u[g],f++);u.length=f}switch(u.length){case 1:return u[0];case 2:return u[0]+" or "+u[1];default:return u.slice(0,-1).join(", ")+", or "+u[u.length-1]}}function l(c){return c?'"'+n(c)+'"':"end of input"}return"Expected "+a(r)+" but "+l(e)+" found."};function nfe(r,e){e=e!==void 0?e:{};var t={},i={Start:jA},n=jA,s=function(C){return C||[]},o=function(C,Q,F){return[{command:C,type:Q}].concat(F||[])},a=function(C,Q){return[{command:C,type:Q||";"}]},l=function(C){return C},c=";",u=me(";",!1),g="&",f=me("&",!1),h=function(C,Q){return Q?{chain:C,then:Q}:{chain:C}},p=function(C,Q){return{type:C,line:Q}},m="&&",y=me("&&",!1),b="||",v=me("||",!1),k=function(C,Q){return Q?te(N({},C),{then:Q}):C},T=function(C,Q){return{type:C,chain:Q}},Y="|&",q=me("|&",!1),$="|",z=me("|",!1),ne="=",ee=me("=",!1),A=function(C,Q){return{name:C,args:[Q]}},oe=function(C){return{name:C,args:[]}},ce="(",Z=me("(",!1),O=")",L=me(")",!1),de=function(C,Q){return{type:"subshell",subshell:C,args:Q}},Be="{",Ge=me("{",!1),re="}",se=me("}",!1),be=function(C,Q){return{type:"group",group:C,args:Q}},he=function(C,Q){return{type:"command",args:Q,envs:C}},Fe=function(C){return{type:"envs",envs:C}},Ue=function(C){return C},xe=function(C){return C},ve=/^[0-9]/,pe=_e([["0","9"]],!1,!1),V=function(C,Q,F){return{type:"redirection",subtype:Q,fd:C!==null?parseInt(C):null,args:[F]}},Qe=">>",le=me(">>",!1),fe=">&",gt=me(">&",!1),Ht=">",Mt=me(">",!1),Ei="<<<",jt=me("<<<",!1),Qr="<&",Oi=me("<&",!1),$s="<",Hn=me("<",!1),jn=function(C){return{type:"argument",segments:[].concat(...C)}},Sr=function(C){return C},Gn="$'",fs=me("$'",!1),Qa="'",RA=me("'",!1),Lu=function(C){return[{type:"text",text:C}]},hs='""',FA=me('""',!1),Sa=function(){return{type:"text",text:""}},Tu='"',NA=me('"',!1),LA=function(C){return C},vr=function(C){return{type:"arithmetic",arithmetic:C,quoted:!0}},_l=function(C){return{type:"shell",shell:C,quoted:!0}},Ou=function(C){return te(N({type:"variable"},C),{quoted:!0})},Po=function(C){return{type:"text",text:C}},Mu=function(C){return{type:"arithmetic",arithmetic:C,quoted:!1}},vh=function(C){return{type:"shell",shell:C,quoted:!1}},kh=function(C){return te(N({type:"variable"},C),{quoted:!1})},Dr=function(C){return{type:"glob",pattern:C}},Ae=/^[^']/,Do=_e(["'"],!0,!1),Yn=function(C){return C.join("")},Uu=/^[^$"]/,St=_e(["$",'"'],!0,!1),Vl=`\\ -`,qn=me(`\\ -`,!1),ps=function(){return""},ds="\\",pt=me("\\",!1),Ro=/^[\\$"`]/,lt=_e(["\\","$",'"',"`"],!1,!1),mn=function(C){return C},S="\\a",Tt=me("\\a",!1),Ku=function(){return"a"},Xl="\\b",xh=me("\\b",!1),Ph=function(){return"\b"},Dh=/^[Ee]/,Rh=_e(["E","e"],!1,!1),Fh=function(){return""},j="\\f",wt=me("\\f",!1),TA=function(){return"\f"},$i="\\n",Zl=me("\\n",!1),$e=function(){return` -`},va="\\r",Hu=me("\\r",!1),wE=function(){return"\r"},Nh="\\t",BE=me("\\t",!1),gr=function(){return" "},Jn="\\v",$l=me("\\v",!1),Lh=function(){return"\v"},eo=/^[\\'"?]/,ka=_e(["\\","'",'"',"?"],!1,!1),En=function(C){return String.fromCharCode(parseInt(C,16))},Oe="\\x",ju=me("\\x",!1),ec="\\u",to=me("\\u",!1),tc="\\U",OA=me("\\U",!1),Gu=function(C){return String.fromCodePoint(parseInt(C,16))},Yu=/^[0-7]/,xa=_e([["0","7"]],!1,!1),Pa=/^[0-9a-fA-f]/,nt=_e([["0","9"],["a","f"],["A","f"]],!1,!1),Fo=ot(),MA="-",rc=me("-",!1),ro="+",ic=me("+",!1),bE=".",Th=me(".",!1),qu=function(C,Q,F){return{type:"number",value:(C==="-"?-1:1)*parseFloat(Q.join("")+"."+F.join(""))}},Oh=function(C,Q){return{type:"number",value:(C==="-"?-1:1)*parseInt(Q.join(""))}},QE=function(C){return N({type:"variable"},C)},nc=function(C){return{type:"variable",name:C}},SE=function(C){return C},Ju="*",UA=me("*",!1),Tr="/",vE=me("/",!1),io=function(C,Q,F){return{type:Q==="*"?"multiplication":"division",right:F}},no=function(C,Q){return Q.reduce((F,K)=>N({left:F},K),C)},Wu=function(C,Q,F){return{type:Q==="+"?"addition":"subtraction",right:F}},KA="$((",R=me("$((",!1),G="))",Ce=me("))",!1),je=function(C){return C},Te="$(",Xe=me("$(",!1),Et=function(C){return C},Rt="${",Wn=me("${",!1),Mb=":-",fO=me(":-",!1),hO=function(C,Q){return{name:C,defaultValue:Q}},Ub=":-}",pO=me(":-}",!1),dO=function(C){return{name:C,defaultValue:[]}},Kb=":+",CO=me(":+",!1),mO=function(C,Q){return{name:C,alternativeValue:Q}},Hb=":+}",EO=me(":+}",!1),IO=function(C){return{name:C,alternativeValue:[]}},jb=function(C){return{name:C}},yO="$",wO=me("$",!1),BO=function(C){return e.isGlobPattern(C)},bO=function(C){return C},Gb=/^[a-zA-Z0-9_]/,Yb=_e([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),qb=function(){return M()},Jb=/^[$@*?#a-zA-Z0-9_\-]/,Wb=_e(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),QO=/^[(){}<>$|&; \t"']/,zu=_e(["(",")","{","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),zb=/^[<>&; \t"']/,_b=_e(["<",">","&",";"," "," ",'"',"'"],!1,!1),kE=/^[ \t]/,xE=_e([" "," "],!1,!1),B=0,Ke=0,HA=[{line:1,column:1}],d=0,E=[],I=0,D;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function M(){return r.substring(Ke,B)}function _(){return yt(Ke,B)}function ie(C,Q){throw Q=Q!==void 0?Q:yt(Ke,B),Mi([ut(C)],r.substring(Ke,B),Q)}function we(C,Q){throw Q=Q!==void 0?Q:yt(Ke,B),zn(C,Q)}function me(C,Q){return{type:"literal",text:C,ignoreCase:Q}}function _e(C,Q,F){return{type:"class",parts:C,inverted:Q,ignoreCase:F}}function ot(){return{type:"any"}}function Bt(){return{type:"end"}}function ut(C){return{type:"other",description:C}}function st(C){var Q=HA[C],F;if(Q)return Q;for(F=C-1;!HA[F];)F--;for(Q=HA[F],Q={line:Q.line,column:Q.column};F<C;)r.charCodeAt(F)===10?(Q.line++,Q.column=1):Q.column++,F++;return HA[C]=Q,Q}function yt(C,Q){var F=st(C),K=st(Q);return{start:{offset:C,line:F.line,column:F.column},end:{offset:Q,line:K.line,column:K.column}}}function ke(C){B<d||(B>d&&(d=B,E=[]),E.push(C))}function zn(C,Q){return new uc(C,null,null,Q)}function Mi(C,Q,F){return new uc(uc.buildMessage(C,Q),C,Q,F)}function jA(){var C,Q;return C=B,Q=Yr(),Q===t&&(Q=null),Q!==t&&(Ke=C,Q=s(Q)),C=Q,C}function Yr(){var C,Q,F,K,ue;if(C=B,Q=qr(),Q!==t){for(F=[],K=qe();K!==t;)F.push(K),K=qe();F!==t?(K=Da(),K!==t?(ue=Cs(),ue===t&&(ue=null),ue!==t?(Ke=C,Q=o(Q,K,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;if(C===t)if(C=B,Q=qr(),Q!==t){for(F=[],K=qe();K!==t;)F.push(K),K=qe();F!==t?(K=Da(),K===t&&(K=null),K!==t?(Ke=C,Q=a(Q,K),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;return C}function Cs(){var C,Q,F,K,ue;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t)if(F=Yr(),F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();K!==t?(Ke=C,Q=l(F),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t;return C}function Da(){var C;return r.charCodeAt(B)===59?(C=c,B++):(C=t,I===0&&ke(u)),C===t&&(r.charCodeAt(B)===38?(C=g,B++):(C=t,I===0&&ke(f))),C}function qr(){var C,Q,F;return C=B,Q=SO(),Q!==t?(F=Yue(),F===t&&(F=null),F!==t?(Ke=C,Q=h(Q,F),C=Q):(B=C,C=t)):(B=C,C=t),C}function Yue(){var C,Q,F,K,ue,De,Ct;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t)if(F=que(),F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();if(K!==t)if(ue=qr(),ue!==t){for(De=[],Ct=qe();Ct!==t;)De.push(Ct),Ct=qe();De!==t?(Ke=C,Q=p(F,ue),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;return C}function que(){var C;return r.substr(B,2)===m?(C=m,B+=2):(C=t,I===0&&ke(y)),C===t&&(r.substr(B,2)===b?(C=b,B+=2):(C=t,I===0&&ke(v))),C}function SO(){var C,Q,F;return C=B,Q=zue(),Q!==t?(F=Jue(),F===t&&(F=null),F!==t?(Ke=C,Q=k(Q,F),C=Q):(B=C,C=t)):(B=C,C=t),C}function Jue(){var C,Q,F,K,ue,De,Ct;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t)if(F=Wue(),F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();if(K!==t)if(ue=SO(),ue!==t){for(De=[],Ct=qe();Ct!==t;)De.push(Ct),Ct=qe();De!==t?(Ke=C,Q=T(F,ue),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;return C}function Wue(){var C;return r.substr(B,2)===Y?(C=Y,B+=2):(C=t,I===0&&ke(q)),C===t&&(r.charCodeAt(B)===124?(C=$,B++):(C=t,I===0&&ke(z))),C}function PE(){var C,Q,F,K,ue,De;if(C=B,Q=MO(),Q!==t)if(r.charCodeAt(B)===61?(F=ne,B++):(F=t,I===0&&ke(ee)),F!==t)if(K=xO(),K!==t){for(ue=[],De=qe();De!==t;)ue.push(De),De=qe();ue!==t?(Ke=C,Q=A(Q,K),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t;else B=C,C=t;if(C===t)if(C=B,Q=MO(),Q!==t)if(r.charCodeAt(B)===61?(F=ne,B++):(F=t,I===0&&ke(ee)),F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();K!==t?(Ke=C,Q=oe(Q),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t;return C}function zue(){var C,Q,F,K,ue,De,Ct,bt,$r,Ii,ms;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t)if(r.charCodeAt(B)===40?(F=ce,B++):(F=t,I===0&&ke(Z)),F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();if(K!==t)if(ue=Yr(),ue!==t){for(De=[],Ct=qe();Ct!==t;)De.push(Ct),Ct=qe();if(De!==t)if(r.charCodeAt(B)===41?(Ct=O,B++):(Ct=t,I===0&&ke(L)),Ct!==t){for(bt=[],$r=qe();$r!==t;)bt.push($r),$r=qe();if(bt!==t){for($r=[],Ii=Mh();Ii!==t;)$r.push(Ii),Ii=Mh();if($r!==t){for(Ii=[],ms=qe();ms!==t;)Ii.push(ms),ms=qe();Ii!==t?(Ke=C,Q=de(ue,$r),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;if(C===t){for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t)if(r.charCodeAt(B)===123?(F=Be,B++):(F=t,I===0&&ke(Ge)),F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();if(K!==t)if(ue=Yr(),ue!==t){for(De=[],Ct=qe();Ct!==t;)De.push(Ct),Ct=qe();if(De!==t)if(r.charCodeAt(B)===125?(Ct=re,B++):(Ct=t,I===0&&ke(se)),Ct!==t){for(bt=[],$r=qe();$r!==t;)bt.push($r),$r=qe();if(bt!==t){for($r=[],Ii=Mh();Ii!==t;)$r.push(Ii),Ii=Mh();if($r!==t){for(Ii=[],ms=qe();ms!==t;)Ii.push(ms),ms=qe();Ii!==t?(Ke=C,Q=be(ue,$r),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;if(C===t){for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t){for(F=[],K=PE();K!==t;)F.push(K),K=PE();if(F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();if(K!==t){if(ue=[],De=kO(),De!==t)for(;De!==t;)ue.push(De),De=kO();else ue=t;if(ue!==t){for(De=[],Ct=qe();Ct!==t;)De.push(Ct),Ct=qe();De!==t?(Ke=C,Q=he(F,ue),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}else B=C,C=t}else B=C,C=t;if(C===t){for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t){if(F=[],K=PE(),K!==t)for(;K!==t;)F.push(K),K=PE();else F=t;if(F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();K!==t?(Ke=C,Q=Fe(F),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}}}return C}function vO(){var C,Q,F,K,ue;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t){if(F=[],K=DE(),K!==t)for(;K!==t;)F.push(K),K=DE();else F=t;if(F!==t){for(K=[],ue=qe();ue!==t;)K.push(ue),ue=qe();K!==t?(Ke=C,Q=Ue(F),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t;return C}function kO(){var C,Q,F;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();if(Q!==t?(F=Mh(),F!==t?(Ke=C,Q=xe(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t){for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();Q!==t?(F=DE(),F!==t?(Ke=C,Q=xe(F),C=Q):(B=C,C=t)):(B=C,C=t)}return C}function Mh(){var C,Q,F,K,ue;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();return Q!==t?(ve.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(pe)),F===t&&(F=null),F!==t?(K=_ue(),K!==t?(ue=DE(),ue!==t?(Ke=C,Q=V(F,K,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function _ue(){var C;return r.substr(B,2)===Qe?(C=Qe,B+=2):(C=t,I===0&&ke(le)),C===t&&(r.substr(B,2)===fe?(C=fe,B+=2):(C=t,I===0&&ke(gt)),C===t&&(r.charCodeAt(B)===62?(C=Ht,B++):(C=t,I===0&&ke(Mt)),C===t&&(r.substr(B,3)===Ei?(C=Ei,B+=3):(C=t,I===0&&ke(jt)),C===t&&(r.substr(B,2)===Qr?(C=Qr,B+=2):(C=t,I===0&&ke(Oi)),C===t&&(r.charCodeAt(B)===60?(C=$s,B++):(C=t,I===0&&ke(Hn))))))),C}function DE(){var C,Q,F;for(C=B,Q=[],F=qe();F!==t;)Q.push(F),F=qe();return Q!==t?(F=xO(),F!==t?(Ke=C,Q=xe(F),C=Q):(B=C,C=t)):(B=C,C=t),C}function xO(){var C,Q,F;if(C=B,Q=[],F=PO(),F!==t)for(;F!==t;)Q.push(F),F=PO();else Q=t;return Q!==t&&(Ke=C,Q=jn(Q)),C=Q,C}function PO(){var C,Q;return C=B,Q=Vue(),Q!==t&&(Ke=C,Q=Sr(Q)),C=Q,C===t&&(C=B,Q=Xue(),Q!==t&&(Ke=C,Q=Sr(Q)),C=Q,C===t&&(C=B,Q=Zue(),Q!==t&&(Ke=C,Q=Sr(Q)),C=Q,C===t&&(C=B,Q=$ue(),Q!==t&&(Ke=C,Q=Sr(Q)),C=Q))),C}function Vue(){var C,Q,F,K;return C=B,r.substr(B,2)===Gn?(Q=Gn,B+=2):(Q=t,I===0&&ke(fs)),Q!==t?(F=rge(),F!==t?(r.charCodeAt(B)===39?(K=Qa,B++):(K=t,I===0&&ke(RA)),K!==t?(Ke=C,Q=Lu(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function Xue(){var C,Q,F,K;return C=B,r.charCodeAt(B)===39?(Q=Qa,B++):(Q=t,I===0&&ke(RA)),Q!==t?(F=ege(),F!==t?(r.charCodeAt(B)===39?(K=Qa,B++):(K=t,I===0&&ke(RA)),K!==t?(Ke=C,Q=Lu(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function Zue(){var C,Q,F,K;if(C=B,r.substr(B,2)===hs?(Q=hs,B+=2):(Q=t,I===0&&ke(FA)),Q!==t&&(Ke=C,Q=Sa()),C=Q,C===t)if(C=B,r.charCodeAt(B)===34?(Q=Tu,B++):(Q=t,I===0&&ke(NA)),Q!==t){for(F=[],K=DO();K!==t;)F.push(K),K=DO();F!==t?(r.charCodeAt(B)===34?(K=Tu,B++):(K=t,I===0&&ke(NA)),K!==t?(Ke=C,Q=LA(F),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;return C}function $ue(){var C,Q,F;if(C=B,Q=[],F=RO(),F!==t)for(;F!==t;)Q.push(F),F=RO();else Q=t;return Q!==t&&(Ke=C,Q=LA(Q)),C=Q,C}function DO(){var C,Q;return C=B,Q=TO(),Q!==t&&(Ke=C,Q=vr(Q)),C=Q,C===t&&(C=B,Q=OO(),Q!==t&&(Ke=C,Q=_l(Q)),C=Q,C===t&&(C=B,Q=$b(),Q!==t&&(Ke=C,Q=Ou(Q)),C=Q,C===t&&(C=B,Q=tge(),Q!==t&&(Ke=C,Q=Po(Q)),C=Q))),C}function RO(){var C,Q;return C=B,Q=TO(),Q!==t&&(Ke=C,Q=Mu(Q)),C=Q,C===t&&(C=B,Q=OO(),Q!==t&&(Ke=C,Q=vh(Q)),C=Q,C===t&&(C=B,Q=$b(),Q!==t&&(Ke=C,Q=kh(Q)),C=Q,C===t&&(C=B,Q=sge(),Q!==t&&(Ke=C,Q=Dr(Q)),C=Q,C===t&&(C=B,Q=nge(),Q!==t&&(Ke=C,Q=Po(Q)),C=Q)))),C}function ege(){var C,Q,F;for(C=B,Q=[],Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Do));F!==t;)Q.push(F),Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Do));return Q!==t&&(Ke=C,Q=Yn(Q)),C=Q,C}function tge(){var C,Q,F;if(C=B,Q=[],F=FO(),F===t&&(Uu.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(St))),F!==t)for(;F!==t;)Q.push(F),F=FO(),F===t&&(Uu.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(St)));else Q=t;return Q!==t&&(Ke=C,Q=Yn(Q)),C=Q,C}function FO(){var C,Q,F;return C=B,r.substr(B,2)===Vl?(Q=Vl,B+=2):(Q=t,I===0&&ke(qn)),Q!==t&&(Ke=C,Q=ps()),C=Q,C===t&&(C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&ke(pt)),Q!==t?(Ro.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(lt)),F!==t?(Ke=C,Q=mn(F),C=Q):(B=C,C=t)):(B=C,C=t)),C}function rge(){var C,Q,F;for(C=B,Q=[],F=NO(),F===t&&(Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Do)));F!==t;)Q.push(F),F=NO(),F===t&&(Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Do)));return Q!==t&&(Ke=C,Q=Yn(Q)),C=Q,C}function NO(){var C,Q,F;return C=B,r.substr(B,2)===S?(Q=S,B+=2):(Q=t,I===0&&ke(Tt)),Q!==t&&(Ke=C,Q=Ku()),C=Q,C===t&&(C=B,r.substr(B,2)===Xl?(Q=Xl,B+=2):(Q=t,I===0&&ke(xh)),Q!==t&&(Ke=C,Q=Ph()),C=Q,C===t&&(C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&ke(pt)),Q!==t?(Dh.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Rh)),F!==t?(Ke=C,Q=Fh(),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===j?(Q=j,B+=2):(Q=t,I===0&&ke(wt)),Q!==t&&(Ke=C,Q=TA()),C=Q,C===t&&(C=B,r.substr(B,2)===$i?(Q=$i,B+=2):(Q=t,I===0&&ke(Zl)),Q!==t&&(Ke=C,Q=$e()),C=Q,C===t&&(C=B,r.substr(B,2)===va?(Q=va,B+=2):(Q=t,I===0&&ke(Hu)),Q!==t&&(Ke=C,Q=wE()),C=Q,C===t&&(C=B,r.substr(B,2)===Nh?(Q=Nh,B+=2):(Q=t,I===0&&ke(BE)),Q!==t&&(Ke=C,Q=gr()),C=Q,C===t&&(C=B,r.substr(B,2)===Jn?(Q=Jn,B+=2):(Q=t,I===0&&ke($l)),Q!==t&&(Ke=C,Q=Lh()),C=Q,C===t&&(C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&ke(pt)),Q!==t?(eo.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(ka)),F!==t?(Ke=C,Q=mn(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=ige()))))))))),C}function ige(){var C,Q,F,K,ue,De,Ct,bt,$r,Ii,ms,eQ;return C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&ke(pt)),Q!==t?(F=Vb(),F!==t?(Ke=C,Q=En(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Oe?(Q=Oe,B+=2):(Q=t,I===0&&ke(ju)),Q!==t?(F=B,K=B,ue=Vb(),ue!==t?(De=_n(),De!==t?(ue=[ue,De],K=ue):(B=K,K=t)):(B=K,K=t),K===t&&(K=Vb()),K!==t?F=r.substring(F,B):F=K,F!==t?(Ke=C,Q=En(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===ec?(Q=ec,B+=2):(Q=t,I===0&&ke(to)),Q!==t?(F=B,K=B,ue=_n(),ue!==t?(De=_n(),De!==t?(Ct=_n(),Ct!==t?(bt=_n(),bt!==t?(ue=[ue,De,Ct,bt],K=ue):(B=K,K=t)):(B=K,K=t)):(B=K,K=t)):(B=K,K=t),K!==t?F=r.substring(F,B):F=K,F!==t?(Ke=C,Q=En(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===tc?(Q=tc,B+=2):(Q=t,I===0&&ke(OA)),Q!==t?(F=B,K=B,ue=_n(),ue!==t?(De=_n(),De!==t?(Ct=_n(),Ct!==t?(bt=_n(),bt!==t?($r=_n(),$r!==t?(Ii=_n(),Ii!==t?(ms=_n(),ms!==t?(eQ=_n(),eQ!==t?(ue=[ue,De,Ct,bt,$r,Ii,ms,eQ],K=ue):(B=K,K=t)):(B=K,K=t)):(B=K,K=t)):(B=K,K=t)):(B=K,K=t)):(B=K,K=t)):(B=K,K=t)):(B=K,K=t),K!==t?F=r.substring(F,B):F=K,F!==t?(Ke=C,Q=Gu(F),C=Q):(B=C,C=t)):(B=C,C=t)))),C}function Vb(){var C;return Yu.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&ke(xa)),C}function _n(){var C;return Pa.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&ke(nt)),C}function nge(){var C,Q,F,K,ue;if(C=B,Q=[],F=B,r.charCodeAt(B)===92?(K=ds,B++):(K=t,I===0&&ke(pt)),K!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&ke(Fo)),ue!==t?(Ke=F,K=mn(ue),F=K):(B=F,F=t)):(B=F,F=t),F===t&&(F=B,K=B,I++,ue=UO(),I--,ue===t?K=void 0:(B=K,K=t),K!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&ke(Fo)),ue!==t?(Ke=F,K=mn(ue),F=K):(B=F,F=t)):(B=F,F=t)),F!==t)for(;F!==t;)Q.push(F),F=B,r.charCodeAt(B)===92?(K=ds,B++):(K=t,I===0&&ke(pt)),K!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&ke(Fo)),ue!==t?(Ke=F,K=mn(ue),F=K):(B=F,F=t)):(B=F,F=t),F===t&&(F=B,K=B,I++,ue=UO(),I--,ue===t?K=void 0:(B=K,K=t),K!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&ke(Fo)),ue!==t?(Ke=F,K=mn(ue),F=K):(B=F,F=t)):(B=F,F=t));else Q=t;return Q!==t&&(Ke=C,Q=Yn(Q)),C=Q,C}function Xb(){var C,Q,F,K,ue,De;if(C=B,r.charCodeAt(B)===45?(Q=MA,B++):(Q=t,I===0&&ke(rc)),Q===t&&(r.charCodeAt(B)===43?(Q=ro,B++):(Q=t,I===0&&ke(ic))),Q===t&&(Q=null),Q!==t){if(F=[],ve.test(r.charAt(B))?(K=r.charAt(B),B++):(K=t,I===0&&ke(pe)),K!==t)for(;K!==t;)F.push(K),ve.test(r.charAt(B))?(K=r.charAt(B),B++):(K=t,I===0&&ke(pe));else F=t;if(F!==t)if(r.charCodeAt(B)===46?(K=bE,B++):(K=t,I===0&&ke(Th)),K!==t){if(ue=[],ve.test(r.charAt(B))?(De=r.charAt(B),B++):(De=t,I===0&&ke(pe)),De!==t)for(;De!==t;)ue.push(De),ve.test(r.charAt(B))?(De=r.charAt(B),B++):(De=t,I===0&&ke(pe));else ue=t;ue!==t?(Ke=C,Q=qu(Q,F,ue),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;if(C===t){if(C=B,r.charCodeAt(B)===45?(Q=MA,B++):(Q=t,I===0&&ke(rc)),Q===t&&(r.charCodeAt(B)===43?(Q=ro,B++):(Q=t,I===0&&ke(ic))),Q===t&&(Q=null),Q!==t){if(F=[],ve.test(r.charAt(B))?(K=r.charAt(B),B++):(K=t,I===0&&ke(pe)),K!==t)for(;K!==t;)F.push(K),ve.test(r.charAt(B))?(K=r.charAt(B),B++):(K=t,I===0&&ke(pe));else F=t;F!==t?(Ke=C,Q=Oh(Q,F),C=Q):(B=C,C=t)}else B=C,C=t;if(C===t&&(C=B,Q=$b(),Q!==t&&(Ke=C,Q=QE(Q)),C=Q,C===t&&(C=B,Q=sc(),Q!==t&&(Ke=C,Q=nc(Q)),C=Q,C===t)))if(C=B,r.charCodeAt(B)===40?(Q=ce,B++):(Q=t,I===0&&ke(Z)),Q!==t){for(F=[],K=qe();K!==t;)F.push(K),K=qe();if(F!==t)if(K=LO(),K!==t){for(ue=[],De=qe();De!==t;)ue.push(De),De=qe();ue!==t?(r.charCodeAt(B)===41?(De=O,B++):(De=t,I===0&&ke(L)),De!==t?(Ke=C,Q=SE(K),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t}return C}function Zb(){var C,Q,F,K,ue,De,Ct,bt;if(C=B,Q=Xb(),Q!==t){for(F=[],K=B,ue=[],De=qe();De!==t;)ue.push(De),De=qe();if(ue!==t)if(r.charCodeAt(B)===42?(De=Ju,B++):(De=t,I===0&&ke(UA)),De===t&&(r.charCodeAt(B)===47?(De=Tr,B++):(De=t,I===0&&ke(vE))),De!==t){for(Ct=[],bt=qe();bt!==t;)Ct.push(bt),bt=qe();Ct!==t?(bt=Xb(),bt!==t?(Ke=K,ue=io(Q,De,bt),K=ue):(B=K,K=t)):(B=K,K=t)}else B=K,K=t;else B=K,K=t;for(;K!==t;){for(F.push(K),K=B,ue=[],De=qe();De!==t;)ue.push(De),De=qe();if(ue!==t)if(r.charCodeAt(B)===42?(De=Ju,B++):(De=t,I===0&&ke(UA)),De===t&&(r.charCodeAt(B)===47?(De=Tr,B++):(De=t,I===0&&ke(vE))),De!==t){for(Ct=[],bt=qe();bt!==t;)Ct.push(bt),bt=qe();Ct!==t?(bt=Xb(),bt!==t?(Ke=K,ue=io(Q,De,bt),K=ue):(B=K,K=t)):(B=K,K=t)}else B=K,K=t;else B=K,K=t}F!==t?(Ke=C,Q=no(Q,F),C=Q):(B=C,C=t)}else B=C,C=t;return C}function LO(){var C,Q,F,K,ue,De,Ct,bt;if(C=B,Q=Zb(),Q!==t){for(F=[],K=B,ue=[],De=qe();De!==t;)ue.push(De),De=qe();if(ue!==t)if(r.charCodeAt(B)===43?(De=ro,B++):(De=t,I===0&&ke(ic)),De===t&&(r.charCodeAt(B)===45?(De=MA,B++):(De=t,I===0&&ke(rc))),De!==t){for(Ct=[],bt=qe();bt!==t;)Ct.push(bt),bt=qe();Ct!==t?(bt=Zb(),bt!==t?(Ke=K,ue=Wu(Q,De,bt),K=ue):(B=K,K=t)):(B=K,K=t)}else B=K,K=t;else B=K,K=t;for(;K!==t;){for(F.push(K),K=B,ue=[],De=qe();De!==t;)ue.push(De),De=qe();if(ue!==t)if(r.charCodeAt(B)===43?(De=ro,B++):(De=t,I===0&&ke(ic)),De===t&&(r.charCodeAt(B)===45?(De=MA,B++):(De=t,I===0&&ke(rc))),De!==t){for(Ct=[],bt=qe();bt!==t;)Ct.push(bt),bt=qe();Ct!==t?(bt=Zb(),bt!==t?(Ke=K,ue=Wu(Q,De,bt),K=ue):(B=K,K=t)):(B=K,K=t)}else B=K,K=t;else B=K,K=t}F!==t?(Ke=C,Q=no(Q,F),C=Q):(B=C,C=t)}else B=C,C=t;return C}function TO(){var C,Q,F,K,ue,De;if(C=B,r.substr(B,3)===KA?(Q=KA,B+=3):(Q=t,I===0&&ke(R)),Q!==t){for(F=[],K=qe();K!==t;)F.push(K),K=qe();if(F!==t)if(K=LO(),K!==t){for(ue=[],De=qe();De!==t;)ue.push(De),De=qe();ue!==t?(r.substr(B,2)===G?(De=G,B+=2):(De=t,I===0&&ke(Ce)),De!==t?(Ke=C,Q=je(K),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;return C}function OO(){var C,Q,F,K;return C=B,r.substr(B,2)===Te?(Q=Te,B+=2):(Q=t,I===0&&ke(Xe)),Q!==t?(F=Yr(),F!==t?(r.charCodeAt(B)===41?(K=O,B++):(K=t,I===0&&ke(L)),K!==t?(Ke=C,Q=Et(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function $b(){var C,Q,F,K,ue,De;return C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&ke(Wn)),Q!==t?(F=sc(),F!==t?(r.substr(B,2)===Mb?(K=Mb,B+=2):(K=t,I===0&&ke(fO)),K!==t?(ue=vO(),ue!==t?(r.charCodeAt(B)===125?(De=re,B++):(De=t,I===0&&ke(se)),De!==t?(Ke=C,Q=hO(F,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&ke(Wn)),Q!==t?(F=sc(),F!==t?(r.substr(B,3)===Ub?(K=Ub,B+=3):(K=t,I===0&&ke(pO)),K!==t?(Ke=C,Q=dO(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&ke(Wn)),Q!==t?(F=sc(),F!==t?(r.substr(B,2)===Kb?(K=Kb,B+=2):(K=t,I===0&&ke(CO)),K!==t?(ue=vO(),ue!==t?(r.charCodeAt(B)===125?(De=re,B++):(De=t,I===0&&ke(se)),De!==t?(Ke=C,Q=mO(F,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&ke(Wn)),Q!==t?(F=sc(),F!==t?(r.substr(B,3)===Hb?(K=Hb,B+=3):(K=t,I===0&&ke(EO)),K!==t?(Ke=C,Q=IO(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&ke(Wn)),Q!==t?(F=sc(),F!==t?(r.charCodeAt(B)===125?(K=re,B++):(K=t,I===0&&ke(se)),K!==t?(Ke=C,Q=jb(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.charCodeAt(B)===36?(Q=yO,B++):(Q=t,I===0&&ke(wO)),Q!==t?(F=sc(),F!==t?(Ke=C,Q=jb(F),C=Q):(B=C,C=t)):(B=C,C=t)))))),C}function sge(){var C,Q,F;return C=B,Q=oge(),Q!==t?(Ke=B,F=BO(Q),F?F=void 0:F=t,F!==t?(Ke=C,Q=bO(Q),C=Q):(B=C,C=t)):(B=C,C=t),C}function oge(){var C,Q,F,K,ue;if(C=B,Q=[],F=B,K=B,I++,ue=KO(),I--,ue===t?K=void 0:(B=K,K=t),K!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&ke(Fo)),ue!==t?(Ke=F,K=mn(ue),F=K):(B=F,F=t)):(B=F,F=t),F!==t)for(;F!==t;)Q.push(F),F=B,K=B,I++,ue=KO(),I--,ue===t?K=void 0:(B=K,K=t),K!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&ke(Fo)),ue!==t?(Ke=F,K=mn(ue),F=K):(B=F,F=t)):(B=F,F=t);else Q=t;return Q!==t&&(Ke=C,Q=Yn(Q)),C=Q,C}function MO(){var C,Q,F;if(C=B,Q=[],Gb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Yb)),F!==t)for(;F!==t;)Q.push(F),Gb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Yb));else Q=t;return Q!==t&&(Ke=C,Q=qb()),C=Q,C}function sc(){var C,Q,F;if(C=B,Q=[],Jb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Wb)),F!==t)for(;F!==t;)Q.push(F),Jb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&ke(Wb));else Q=t;return Q!==t&&(Ke=C,Q=qb()),C=Q,C}function UO(){var C;return QO.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&ke(zu)),C}function KO(){var C;return zb.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&ke(_b)),C}function qe(){var C,Q;if(C=[],kE.test(r.charAt(B))?(Q=r.charAt(B),B++):(Q=t,I===0&&ke(xE)),Q!==t)for(;Q!==t;)C.push(Q),kE.test(r.charAt(B))?(Q=r.charAt(B),B++):(Q=t,I===0&&ke(xE));else C=t;return C}if(D=n(),D!==t&&B===r.length)return D;throw D!==t&&B<r.length&&ke(Bt()),Mi(E,d<r.length?r.charAt(d):null,d<r.length?yt(d,d+1):yt(d,d))}XM.exports={SyntaxError:uc,parse:nfe}});var t1=w((F7e,e1)=>{"use strict";function sfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function fc(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,fc)}sfe(fc,Error);fc.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g<c.parts.length;g++)u+=c.parts[g]instanceof Array?s(c.parts[g][0])+"-"+s(c.parts[g][1]):s(c.parts[g]);return"["+(c.inverted?"^":"")+u+"]"},any:function(c){return"any character"},end:function(c){return"end of input"},other:function(c){return c.description}};function i(c){return c.charCodeAt(0).toString(16).toUpperCase()}function n(c){return c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function s(c){return c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function o(c){return t[c.type](c)}function a(c){var u=new Array(c.length),g,f;for(g=0;g<c.length;g++)u[g]=o(c[g]);if(u.sort(),u.length>0){for(g=1,f=1;g<u.length;g++)u[g-1]!==u[g]&&(u[f]=u[g],f++);u.length=f}switch(u.length){case 1:return u[0];case 2:return u[0]+" or "+u[1];default:return u.slice(0,-1).join(", ")+", or "+u[u.length-1]}}function l(c){return c?'"'+n(c)+'"':"end of input"}return"Expected "+a(r)+" but "+l(e)+" found."};function ofe(r,e){e=e!==void 0?e:{};var t={},i={resolution:he},n=he,s="/",o=ce("/",!1),a=function(pe,V){return{from:pe,descriptor:V}},l=function(pe){return{descriptor:pe}},c="@",u=ce("@",!1),g=function(pe,V){return{fullName:pe,description:V}},f=function(pe){return{fullName:pe}},h=function(){return ne()},p=/^[^\/@]/,m=Z(["/","@"],!0,!1),y=/^[^\/]/,b=Z(["/"],!0,!1),v=0,k=0,T=[{line:1,column:1}],Y=0,q=[],$=0,z;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function ne(){return r.substring(k,v)}function ee(){return Ge(k,v)}function A(pe,V){throw V=V!==void 0?V:Ge(k,v),be([de(pe)],r.substring(k,v),V)}function oe(pe,V){throw V=V!==void 0?V:Ge(k,v),se(pe,V)}function ce(pe,V){return{type:"literal",text:pe,ignoreCase:V}}function Z(pe,V,Qe){return{type:"class",parts:pe,inverted:V,ignoreCase:Qe}}function O(){return{type:"any"}}function L(){return{type:"end"}}function de(pe){return{type:"other",description:pe}}function Be(pe){var V=T[pe],Qe;if(V)return V;for(Qe=pe-1;!T[Qe];)Qe--;for(V=T[Qe],V={line:V.line,column:V.column};Qe<pe;)r.charCodeAt(Qe)===10?(V.line++,V.column=1):V.column++,Qe++;return T[pe]=V,V}function Ge(pe,V){var Qe=Be(pe),le=Be(V);return{start:{offset:pe,line:Qe.line,column:Qe.column},end:{offset:V,line:le.line,column:le.column}}}function re(pe){v<Y||(v>Y&&(Y=v,q=[]),q.push(pe))}function se(pe,V){return new fc(pe,null,null,V)}function be(pe,V,Qe){return new fc(fc.buildMessage(pe,V),pe,V,Qe)}function he(){var pe,V,Qe,le;return pe=v,V=Fe(),V!==t?(r.charCodeAt(v)===47?(Qe=s,v++):(Qe=t,$===0&&re(o)),Qe!==t?(le=Fe(),le!==t?(k=pe,V=a(V,le),pe=V):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t),pe===t&&(pe=v,V=Fe(),V!==t&&(k=pe,V=l(V)),pe=V),pe}function Fe(){var pe,V,Qe,le;return pe=v,V=Ue(),V!==t?(r.charCodeAt(v)===64?(Qe=c,v++):(Qe=t,$===0&&re(u)),Qe!==t?(le=ve(),le!==t?(k=pe,V=g(V,le),pe=V):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t),pe===t&&(pe=v,V=Ue(),V!==t&&(k=pe,V=f(V)),pe=V),pe}function Ue(){var pe,V,Qe,le,fe;return pe=v,r.charCodeAt(v)===64?(V=c,v++):(V=t,$===0&&re(u)),V!==t?(Qe=xe(),Qe!==t?(r.charCodeAt(v)===47?(le=s,v++):(le=t,$===0&&re(o)),le!==t?(fe=xe(),fe!==t?(k=pe,V=h(),pe=V):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t),pe===t&&(pe=v,V=xe(),V!==t&&(k=pe,V=h()),pe=V),pe}function xe(){var pe,V,Qe;if(pe=v,V=[],p.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(m)),Qe!==t)for(;Qe!==t;)V.push(Qe),p.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(m));else V=t;return V!==t&&(k=pe,V=h()),pe=V,pe}function ve(){var pe,V,Qe;if(pe=v,V=[],y.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(b)),Qe!==t)for(;Qe!==t;)V.push(Qe),y.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(b));else V=t;return V!==t&&(k=pe,V=h()),pe=V,pe}if(z=n(),z!==t&&v===r.length)return z;throw z!==t&&v<r.length&&re(L()),be(q,Y<r.length?r.charAt(Y):null,Y<r.length?Ge(Y,Y+1):Ge(Y,Y))}e1.exports={SyntaxError:fc,parse:ofe}});var pc=w((L7e,hc)=>{"use strict";function i1(r){return typeof r=="undefined"||r===null}function afe(r){return typeof r=="object"&&r!==null}function Afe(r){return Array.isArray(r)?r:i1(r)?[]:[r]}function lfe(r,e){var t,i,n,s;if(e)for(s=Object.keys(e),t=0,i=s.length;t<i;t+=1)n=s[t],r[n]=e[n];return r}function cfe(r,e){var t="",i;for(i=0;i<e;i+=1)t+=r;return t}function ufe(r){return r===0&&Number.NEGATIVE_INFINITY===1/r}hc.exports.isNothing=i1;hc.exports.isObject=afe;hc.exports.toArray=Afe;hc.exports.repeat=cfe;hc.exports.isNegativeZero=ufe;hc.exports.extend=lfe});var rg=w((T7e,n1)=>{"use strict";function tp(r,e){Error.call(this),this.name="YAMLException",this.reason=r,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}tp.prototype=Object.create(Error.prototype);tp.prototype.constructor=tp;tp.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t};n1.exports=tp});var a1=w((O7e,s1)=>{"use strict";var o1=pc();function FQ(r,e,t,i,n){this.name=r,this.buffer=e,this.position=t,this.line=i,this.column=n}FQ.prototype.getSnippet=function(e,t){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,t=t||75,i="",n=this.position;n>0&&`\0\r -\x85\u2028\u2029`.indexOf(this.buffer.charAt(n-1))===-1;)if(n-=1,this.position-n>t/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;o<this.buffer.length&&`\0\r -\x85\u2028\u2029`.indexOf(this.buffer.charAt(o))===-1;)if(o+=1,o-this.position>t/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),o1.repeat(" ",e)+i+a+s+` -`+o1.repeat(" ",e+this.position-n+i.length)+"^"};FQ.prototype.toString=function(e){var t,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(i+=`: -`+t)),i};s1.exports=FQ});var ci=w((M7e,A1)=>{"use strict";var l1=rg(),gfe=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],ffe=["scalar","sequence","mapping"];function hfe(r){var e={};return r!==null&&Object.keys(r).forEach(function(t){r[t].forEach(function(i){e[String(i)]=t})}),e}function pfe(r,e){if(e=e||{},Object.keys(e).forEach(function(t){if(gfe.indexOf(t)===-1)throw new l1('Unknown option "'+t+'" is met in definition of "'+r+'" YAML type.')}),this.tag=r,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=hfe(e.styleAliases||null),ffe.indexOf(this.kind)===-1)throw new l1('Unknown kind "'+this.kind+'" is specified for "'+r+'" YAML type.')}A1.exports=pfe});var dc=w((U7e,c1)=>{"use strict";var u1=pc(),rI=rg(),dfe=ci();function NQ(r,e,t){var i=[];return r.include.forEach(function(n){t=NQ(n,e,t)}),r[e].forEach(function(n){t.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),t.push(n)}),t.filter(function(n,s){return i.indexOf(s)===-1})}function Cfe(){var r={scalar:{},sequence:{},mapping:{},fallback:{}},e,t;function i(n){r[n.kind][n.tag]=r.fallback[n.tag]=n}for(e=0,t=arguments.length;e<t;e+=1)arguments[e].forEach(i);return r}function ig(r){this.include=r.include||[],this.implicit=r.implicit||[],this.explicit=r.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&e.loadKind!=="scalar")throw new rI("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=NQ(this,"implicit",[]),this.compiledExplicit=NQ(this,"explicit",[]),this.compiledTypeMap=Cfe(this.compiledImplicit,this.compiledExplicit)}ig.DEFAULT=null;ig.create=function(){var e,t;switch(arguments.length){case 1:e=ig.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new rI("Wrong number of arguments for Schema.create function")}if(e=u1.toArray(e),t=u1.toArray(t),!e.every(function(i){return i instanceof ig}))throw new rI("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(i){return i instanceof dfe}))throw new rI("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new ig({include:e,explicit:t})};c1.exports=ig});var f1=w((K7e,g1)=>{"use strict";var mfe=ci();g1.exports=new mfe("tag:yaml.org,2002:str",{kind:"scalar",construct:function(r){return r!==null?r:""}})});var p1=w((H7e,h1)=>{"use strict";var Efe=ci();h1.exports=new Efe("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(r){return r!==null?r:[]}})});var C1=w((j7e,d1)=>{"use strict";var Ife=ci();d1.exports=new Ife("tag:yaml.org,2002:map",{kind:"mapping",construct:function(r){return r!==null?r:{}}})});var iI=w((G7e,m1)=>{"use strict";var yfe=dc();m1.exports=new yfe({explicit:[f1(),p1(),C1()]})});var I1=w((Y7e,E1)=>{"use strict";var wfe=ci();function Bfe(r){if(r===null)return!0;var e=r.length;return e===1&&r==="~"||e===4&&(r==="null"||r==="Null"||r==="NULL")}function bfe(){return null}function Qfe(r){return r===null}E1.exports=new wfe("tag:yaml.org,2002:null",{kind:"scalar",resolve:Bfe,construct:bfe,predicate:Qfe,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var w1=w((q7e,y1)=>{"use strict";var Sfe=ci();function vfe(r){if(r===null)return!1;var e=r.length;return e===4&&(r==="true"||r==="True"||r==="TRUE")||e===5&&(r==="false"||r==="False"||r==="FALSE")}function kfe(r){return r==="true"||r==="True"||r==="TRUE"}function xfe(r){return Object.prototype.toString.call(r)==="[object Boolean]"}y1.exports=new Sfe("tag:yaml.org,2002:bool",{kind:"scalar",resolve:vfe,construct:kfe,predicate:xfe,represent:{lowercase:function(r){return r?"true":"false"},uppercase:function(r){return r?"TRUE":"FALSE"},camelcase:function(r){return r?"True":"False"}},defaultStyle:"lowercase"})});var b1=w((J7e,B1)=>{"use strict";var Pfe=pc(),Dfe=ci();function Rfe(r){return 48<=r&&r<=57||65<=r&&r<=70||97<=r&&r<=102}function Ffe(r){return 48<=r&&r<=55}function Nfe(r){return 48<=r&&r<=57}function Lfe(r){if(r===null)return!1;var e=r.length,t=0,i=!1,n;if(!e)return!1;if(n=r[t],(n==="-"||n==="+")&&(n=r[++t]),n==="0"){if(t+1===e)return!0;if(n=r[++t],n==="b"){for(t++;t<e;t++)if(n=r[t],n!=="_"){if(n!=="0"&&n!=="1")return!1;i=!0}return i&&n!=="_"}if(n==="x"){for(t++;t<e;t++)if(n=r[t],n!=="_"){if(!Rfe(r.charCodeAt(t)))return!1;i=!0}return i&&n!=="_"}for(;t<e;t++)if(n=r[t],n!=="_"){if(!Ffe(r.charCodeAt(t)))return!1;i=!0}return i&&n!=="_"}if(n==="_")return!1;for(;t<e;t++)if(n=r[t],n!=="_"){if(n===":")break;if(!Nfe(r.charCodeAt(t)))return!1;i=!0}return!i||n==="_"?!1:n!==":"?!0:/^(:[0-5]?[0-9])+$/.test(r.slice(t))}function Tfe(r){var e=r,t=1,i,n,s=[];return e.indexOf("_")!==-1&&(e=e.replace(/_/g,"")),i=e[0],(i==="-"||i==="+")&&(i==="-"&&(t=-1),e=e.slice(1),i=e[0]),e==="0"?0:i==="0"?e[1]==="b"?t*parseInt(e.slice(2),2):e[1]==="x"?t*parseInt(e,16):t*parseInt(e,8):e.indexOf(":")!==-1?(e.split(":").forEach(function(o){s.unshift(parseInt(o,10))}),e=0,n=1,s.forEach(function(o){e+=o*n,n*=60}),t*e):t*parseInt(e,10)}function Ofe(r){return Object.prototype.toString.call(r)==="[object Number]"&&r%1==0&&!Pfe.isNegativeZero(r)}B1.exports=new Dfe("tag:yaml.org,2002:int",{kind:"scalar",resolve:Lfe,construct:Tfe,predicate:Ofe,represent:{binary:function(r){return r>=0?"0b"+r.toString(2):"-0b"+r.toString(2).slice(1)},octal:function(r){return r>=0?"0"+r.toString(8):"-0"+r.toString(8).slice(1)},decimal:function(r){return r.toString(10)},hexadecimal:function(r){return r>=0?"0x"+r.toString(16).toUpperCase():"-0x"+r.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var v1=w((W7e,Q1)=>{"use strict";var S1=pc(),Mfe=ci(),Ufe=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function Kfe(r){return!(r===null||!Ufe.test(r)||r[r.length-1]==="_")}function Hfe(r){var e,t,i,n;return e=r.replace(/_/g,"").toLowerCase(),t=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(s){n.unshift(parseFloat(s,10))}),e=0,i=1,n.forEach(function(s){e+=s*i,i*=60}),t*e):t*parseFloat(e,10)}var jfe=/^[-+]?[0-9]+e/;function Gfe(r,e){var t;if(isNaN(r))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===r)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===r)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(S1.isNegativeZero(r))return"-0.0";return t=r.toString(10),jfe.test(t)?t.replace("e",".e"):t}function Yfe(r){return Object.prototype.toString.call(r)==="[object Number]"&&(r%1!=0||S1.isNegativeZero(r))}Q1.exports=new Mfe("tag:yaml.org,2002:float",{kind:"scalar",resolve:Kfe,construct:Hfe,predicate:Yfe,represent:Gfe,defaultStyle:"lowercase"})});var LQ=w((z7e,k1)=>{"use strict";var qfe=dc();k1.exports=new qfe({include:[iI()],implicit:[I1(),w1(),b1(),v1()]})});var TQ=w((_7e,x1)=>{"use strict";var Jfe=dc();x1.exports=new Jfe({include:[LQ()]})});var F1=w((V7e,P1)=>{"use strict";var Wfe=ci(),D1=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),R1=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function zfe(r){return r===null?!1:D1.exec(r)!==null||R1.exec(r)!==null}function _fe(r){var e,t,i,n,s,o,a,l=0,c=null,u,g,f;if(e=D1.exec(r),e===null&&(e=R1.exec(r)),e===null)throw new Error("Date resolve error");if(t=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(t,i,n));if(s=+e[4],o=+e[5],a=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(u=+e[10],g=+(e[11]||0),c=(u*60+g)*6e4,e[9]==="-"&&(c=-c)),f=new Date(Date.UTC(t,i,n,s,o,a,l)),c&&f.setTime(f.getTime()-c),f}function Vfe(r){return r.toISOString()}P1.exports=new Wfe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:zfe,construct:_fe,instanceOf:Date,represent:Vfe})});var L1=w((X7e,N1)=>{"use strict";var Xfe=ci();function Zfe(r){return r==="<<"||r===null}N1.exports=new Xfe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:Zfe})});var M1=w((Z7e,T1)=>{"use strict";var Cc;try{O1=require,Cc=O1("buffer").Buffer}catch(r){}var O1,$fe=ci(),OQ=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= -\r`;function ehe(r){if(r===null)return!1;var e,t,i=0,n=r.length,s=OQ;for(t=0;t<n;t++)if(e=s.indexOf(r.charAt(t)),!(e>64)){if(e<0)return!1;i+=6}return i%8==0}function the(r){var e,t,i=r.replace(/[\r\n=]/g,""),n=i.length,s=OQ,o=0,a=[];for(e=0;e<n;e++)e%4==0&&e&&(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)),o=o<<6|s.indexOf(i.charAt(e));return t=n%4*6,t===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):t===18?(a.push(o>>10&255),a.push(o>>2&255)):t===12&&a.push(o>>4&255),Cc?Cc.from?Cc.from(a):new Cc(a):a}function rhe(r){var e="",t=0,i,n,s=r.length,o=OQ;for(i=0;i<s;i++)i%3==0&&i&&(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]),t=(t<<8)+r[i];return n=s%3,n===0?(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]):n===2?(e+=o[t>>10&63],e+=o[t>>4&63],e+=o[t<<2&63],e+=o[64]):n===1&&(e+=o[t>>2&63],e+=o[t<<4&63],e+=o[64],e+=o[64]),e}function ihe(r){return Cc&&Cc.isBuffer(r)}T1.exports=new $fe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:ehe,construct:the,predicate:ihe,represent:rhe})});var K1=w(($7e,U1)=>{"use strict";var nhe=ci(),she=Object.prototype.hasOwnProperty,ohe=Object.prototype.toString;function ahe(r){if(r===null)return!0;var e=[],t,i,n,s,o,a=r;for(t=0,i=a.length;t<i;t+=1){if(n=a[t],o=!1,ohe.call(n)!=="[object Object]")return!1;for(s in n)if(she.call(n,s))if(!o)o=!0;else return!1;if(!o)return!1;if(e.indexOf(s)===-1)e.push(s);else return!1}return!0}function Ahe(r){return r!==null?r:[]}U1.exports=new nhe("tag:yaml.org,2002:omap",{kind:"sequence",resolve:ahe,construct:Ahe})});var j1=w((eXe,H1)=>{"use strict";var lhe=ci(),che=Object.prototype.toString;function uhe(r){if(r===null)return!0;var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e<t;e+=1){if(i=o[e],che.call(i)!=="[object Object]"||(n=Object.keys(i),n.length!==1))return!1;s[e]=[n[0],i[n[0]]]}return!0}function ghe(r){if(r===null)return[];var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e<t;e+=1)i=o[e],n=Object.keys(i),s[e]=[n[0],i[n[0]]];return s}H1.exports=new lhe("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:uhe,construct:ghe})});var Y1=w((tXe,G1)=>{"use strict";var fhe=ci(),hhe=Object.prototype.hasOwnProperty;function phe(r){if(r===null)return!0;var e,t=r;for(e in t)if(hhe.call(t,e)&&t[e]!==null)return!1;return!0}function dhe(r){return r!==null?r:{}}G1.exports=new fhe("tag:yaml.org,2002:set",{kind:"mapping",resolve:phe,construct:dhe})});var ng=w((rXe,q1)=>{"use strict";var Che=dc();q1.exports=new Che({include:[TQ()],implicit:[F1(),L1()],explicit:[M1(),K1(),j1(),Y1()]})});var W1=w((iXe,J1)=>{"use strict";var mhe=ci();function Ehe(){return!0}function Ihe(){}function yhe(){return""}function whe(r){return typeof r=="undefined"}J1.exports=new mhe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:Ehe,construct:Ihe,predicate:whe,represent:yhe})});var _1=w((nXe,z1)=>{"use strict";var Bhe=ci();function bhe(r){if(r===null||r.length===0)return!1;var e=r,t=/\/([gim]*)$/.exec(r),i="";return!(e[0]==="/"&&(t&&(i=t[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function Qhe(r){var e=r,t=/\/([gim]*)$/.exec(r),i="";return e[0]==="/"&&(t&&(i=t[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function She(r){var e="/"+r.source+"/";return r.global&&(e+="g"),r.multiline&&(e+="m"),r.ignoreCase&&(e+="i"),e}function vhe(r){return Object.prototype.toString.call(r)==="[object RegExp]"}z1.exports=new Bhe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:bhe,construct:Qhe,predicate:vhe,represent:She})});var Z1=w((sXe,V1)=>{"use strict";var nI;try{X1=require,nI=X1("esprima")}catch(r){typeof window!="undefined"&&(nI=window.esprima)}var X1,khe=ci();function xhe(r){if(r===null)return!1;try{var e="("+r+")",t=nI.parse(e,{range:!0});return!(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")}catch(i){return!1}}function Phe(r){var e="("+r+")",t=nI.parse(e,{range:!0}),i=[],n;if(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return t.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=t.body[0].expression.body.range,t.body[0].expression.body.type==="BlockStatement"?new Function(i,e.slice(n[0]+1,n[1]-1)):new Function(i,"return "+e.slice(n[0],n[1]))}function Dhe(r){return r.toString()}function Rhe(r){return Object.prototype.toString.call(r)==="[object Function]"}V1.exports=new khe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:xhe,construct:Phe,predicate:Rhe,represent:Dhe})});var rp=w((oXe,$1)=>{"use strict";var eU=dc();$1.exports=eU.DEFAULT=new eU({include:[ng()],explicit:[W1(),_1(),Z1()]})});var EU=w((aXe,ip)=>{"use strict";var Ma=pc(),tU=rg(),Fhe=a1(),rU=ng(),Nhe=rp(),WA=Object.prototype.hasOwnProperty,sI=1,iU=2,nU=3,oI=4,MQ=1,Lhe=2,sU=3,The=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Ohe=/[\x85\u2028\u2029]/,Mhe=/[,\[\]\{\}]/,oU=/^(?:!|!!|![a-z\-]+!)$/i,aU=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function AU(r){return Object.prototype.toString.call(r)}function Oo(r){return r===10||r===13}function mc(r){return r===9||r===32}function yn(r){return r===9||r===32||r===10||r===13}function sg(r){return r===44||r===91||r===93||r===123||r===125}function Uhe(r){var e;return 48<=r&&r<=57?r-48:(e=r|32,97<=e&&e<=102?e-97+10:-1)}function Khe(r){return r===120?2:r===117?4:r===85?8:0}function Hhe(r){return 48<=r&&r<=57?r-48:-1}function lU(r){return r===48?"\0":r===97?"\x07":r===98?"\b":r===116||r===9?" ":r===110?` -`:r===118?"\v":r===102?"\f":r===114?"\r":r===101?"":r===32?" ":r===34?'"':r===47?"/":r===92?"\\":r===78?"\x85":r===95?"\xA0":r===76?"\u2028":r===80?"\u2029":""}function jhe(r){return r<=65535?String.fromCharCode(r):String.fromCharCode((r-65536>>10)+55296,(r-65536&1023)+56320)}var cU=new Array(256),uU=new Array(256);for(var og=0;og<256;og++)cU[og]=lU(og)?1:0,uU[og]=lU(og);function Ghe(r,e){this.input=r,this.filename=e.filename||null,this.schema=e.schema||Nhe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=r.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function gU(r,e){return new tU(e,new Fhe(r.filename,r.input,r.position,r.line,r.position-r.lineStart))}function dt(r,e){throw gU(r,e)}function aI(r,e){r.onWarning&&r.onWarning.call(null,gU(r,e))}var fU={YAML:function(e,t,i){var n,s,o;e.version!==null&&dt(e,"duplication of %YAML directive"),i.length!==1&&dt(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&&dt(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&&dt(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&aI(e,"unsupported YAML version of the document")},TAG:function(e,t,i){var n,s;i.length!==2&&dt(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],oU.test(n)||dt(e,"ill-formed tag handle (first argument) of the TAG directive"),WA.call(e.tagMap,n)&&dt(e,'there is a previously declared suffix for "'+n+'" tag handle'),aU.test(s)||dt(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function zA(r,e,t,i){var n,s,o,a;if(e<t){if(a=r.input.slice(e,t),i)for(n=0,s=a.length;n<s;n+=1)o=a.charCodeAt(n),o===9||32<=o&&o<=1114111||dt(r,"expected valid JSON character");else The.test(a)&&dt(r,"the stream contains non-printable characters");r.result+=a}}function hU(r,e,t,i){var n,s,o,a;for(Ma.isObject(t)||dt(r,"cannot merge mappings; the provided source object is unacceptable"),n=Object.keys(t),o=0,a=n.length;o<a;o+=1)s=n[o],WA.call(e,s)||(e[s]=t[s],i[s]=!0)}function ag(r,e,t,i,n,s,o,a){var l,c;if(Array.isArray(n))for(n=Array.prototype.slice.call(n),l=0,c=n.length;l<c;l+=1)Array.isArray(n[l])&&dt(r,"nested arrays are not supported inside keys"),typeof n=="object"&&AU(n[l])==="[object Object]"&&(n[l]="[object Object]");if(typeof n=="object"&&AU(n)==="[object Object]"&&(n="[object Object]"),n=String(n),e===null&&(e={}),i==="tag:yaml.org,2002:merge")if(Array.isArray(s))for(l=0,c=s.length;l<c;l+=1)hU(r,e,s[l],t);else hU(r,e,s,t);else!r.json&&!WA.call(t,n)&&WA.call(e,n)&&(r.line=o||r.line,r.position=a||r.position,dt(r,"duplicated mapping key")),e[n]=s,delete t[n];return e}function UQ(r){var e;e=r.input.charCodeAt(r.position),e===10?r.position++:e===13?(r.position++,r.input.charCodeAt(r.position)===10&&r.position++):dt(r,"a line break is expected"),r.line+=1,r.lineStart=r.position}function ei(r,e,t){for(var i=0,n=r.input.charCodeAt(r.position);n!==0;){for(;mc(n);)n=r.input.charCodeAt(++r.position);if(e&&n===35)do n=r.input.charCodeAt(++r.position);while(n!==10&&n!==13&&n!==0);if(Oo(n))for(UQ(r),n=r.input.charCodeAt(r.position),i++,r.lineIndent=0;n===32;)r.lineIndent++,n=r.input.charCodeAt(++r.position);else break}return t!==-1&&i!==0&&r.lineIndent<t&&aI(r,"deficient indentation"),i}function AI(r){var e=r.position,t;return t=r.input.charCodeAt(e),!!((t===45||t===46)&&t===r.input.charCodeAt(e+1)&&t===r.input.charCodeAt(e+2)&&(e+=3,t=r.input.charCodeAt(e),t===0||yn(t)))}function KQ(r,e){e===1?r.result+=" ":e>1&&(r.result+=Ma.repeat(` -`,e-1))}function Yhe(r,e,t){var i,n,s,o,a,l,c,u,g=r.kind,f=r.result,h;if(h=r.input.charCodeAt(r.position),yn(h)||sg(h)||h===35||h===38||h===42||h===33||h===124||h===62||h===39||h===34||h===37||h===64||h===96||(h===63||h===45)&&(n=r.input.charCodeAt(r.position+1),yn(n)||t&&sg(n)))return!1;for(r.kind="scalar",r.result="",s=o=r.position,a=!1;h!==0;){if(h===58){if(n=r.input.charCodeAt(r.position+1),yn(n)||t&&sg(n))break}else if(h===35){if(i=r.input.charCodeAt(r.position-1),yn(i))break}else{if(r.position===r.lineStart&&AI(r)||t&&sg(h))break;if(Oo(h))if(l=r.line,c=r.lineStart,u=r.lineIndent,ei(r,!1,-1),r.lineIndent>=e){a=!0,h=r.input.charCodeAt(r.position);continue}else{r.position=o,r.line=l,r.lineStart=c,r.lineIndent=u;break}}a&&(zA(r,s,o,!1),KQ(r,r.line-l),s=o=r.position,a=!1),mc(h)||(o=r.position+1),h=r.input.charCodeAt(++r.position)}return zA(r,s,o,!1),r.result?!0:(r.kind=g,r.result=f,!1)}function qhe(r,e){var t,i,n;if(t=r.input.charCodeAt(r.position),t!==39)return!1;for(r.kind="scalar",r.result="",r.position++,i=n=r.position;(t=r.input.charCodeAt(r.position))!==0;)if(t===39)if(zA(r,i,r.position,!0),t=r.input.charCodeAt(++r.position),t===39)i=r.position,r.position++,n=r.position;else return!0;else Oo(t)?(zA(r,i,n,!0),KQ(r,ei(r,!1,e)),i=n=r.position):r.position===r.lineStart&&AI(r)?dt(r,"unexpected end of the document within a single quoted scalar"):(r.position++,n=r.position);dt(r,"unexpected end of the stream within a single quoted scalar")}function Jhe(r,e){var t,i,n,s,o,a;if(a=r.input.charCodeAt(r.position),a!==34)return!1;for(r.kind="scalar",r.result="",r.position++,t=i=r.position;(a=r.input.charCodeAt(r.position))!==0;){if(a===34)return zA(r,t,r.position,!0),r.position++,!0;if(a===92){if(zA(r,t,r.position,!0),a=r.input.charCodeAt(++r.position),Oo(a))ei(r,!1,e);else if(a<256&&cU[a])r.result+=uU[a],r.position++;else if((o=Khe(a))>0){for(n=o,s=0;n>0;n--)a=r.input.charCodeAt(++r.position),(o=Uhe(a))>=0?s=(s<<4)+o:dt(r,"expected hexadecimal character");r.result+=jhe(s),r.position++}else dt(r,"unknown escape sequence");t=i=r.position}else Oo(a)?(zA(r,t,i,!0),KQ(r,ei(r,!1,e)),t=i=r.position):r.position===r.lineStart&&AI(r)?dt(r,"unexpected end of the document within a double quoted scalar"):(r.position++,i=r.position)}dt(r,"unexpected end of the stream within a double quoted scalar")}function Whe(r,e){var t=!0,i,n=r.tag,s,o=r.anchor,a,l,c,u,g,f={},h,p,m,y;if(y=r.input.charCodeAt(r.position),y===91)l=93,g=!1,s=[];else if(y===123)l=125,g=!0,s={};else return!1;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),y=r.input.charCodeAt(++r.position);y!==0;){if(ei(r,!0,e),y=r.input.charCodeAt(r.position),y===l)return r.position++,r.tag=n,r.anchor=o,r.kind=g?"mapping":"sequence",r.result=s,!0;t||dt(r,"missed comma between flow collection entries"),p=h=m=null,c=u=!1,y===63&&(a=r.input.charCodeAt(r.position+1),yn(a)&&(c=u=!0,r.position++,ei(r,!0,e))),i=r.line,Ag(r,e,sI,!1,!0),p=r.tag,h=r.result,ei(r,!0,e),y=r.input.charCodeAt(r.position),(u||r.line===i)&&y===58&&(c=!0,y=r.input.charCodeAt(++r.position),ei(r,!0,e),Ag(r,e,sI,!1,!0),m=r.result),g?ag(r,s,f,p,h,m):c?s.push(ag(r,null,f,p,h,m)):s.push(h),ei(r,!0,e),y=r.input.charCodeAt(r.position),y===44?(t=!0,y=r.input.charCodeAt(++r.position)):t=!1}dt(r,"unexpected end of the stream within a flow collection")}function zhe(r,e){var t,i,n=MQ,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=r.input.charCodeAt(r.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(r.kind="scalar",r.result="";g!==0;)if(g=r.input.charCodeAt(++r.position),g===43||g===45)MQ===n?n=g===43?sU:Lhe:dt(r,"repeat of a chomping mode identifier");else if((u=Hhe(g))>=0)u===0?dt(r,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?dt(r,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(mc(g)){do g=r.input.charCodeAt(++r.position);while(mc(g));if(g===35)do g=r.input.charCodeAt(++r.position);while(!Oo(g)&&g!==0)}for(;g!==0;){for(UQ(r),r.lineIndent=0,g=r.input.charCodeAt(r.position);(!o||r.lineIndent<a)&&g===32;)r.lineIndent++,g=r.input.charCodeAt(++r.position);if(!o&&r.lineIndent>a&&(a=r.lineIndent),Oo(g)){l++;continue}if(r.lineIndent<a){n===sU?r.result+=Ma.repeat(` -`,s?1+l:l):n===MQ&&s&&(r.result+=` -`);break}for(i?mc(g)?(c=!0,r.result+=Ma.repeat(` -`,s?1+l:l)):c?(c=!1,r.result+=Ma.repeat(` -`,l+1)):l===0?s&&(r.result+=" "):r.result+=Ma.repeat(` -`,l):r.result+=Ma.repeat(` -`,s?1+l:l),s=!0,o=!0,l=0,t=r.position;!Oo(g)&&g!==0;)g=r.input.charCodeAt(++r.position);zA(r,t,r.position,!1)}return!0}function pU(r,e){var t,i=r.tag,n=r.anchor,s=[],o,a=!1,l;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),l=r.input.charCodeAt(r.position);l!==0&&!(l!==45||(o=r.input.charCodeAt(r.position+1),!yn(o)));){if(a=!0,r.position++,ei(r,!0,-1)&&r.lineIndent<=e){s.push(null),l=r.input.charCodeAt(r.position);continue}if(t=r.line,Ag(r,e,nU,!1,!0),s.push(r.result),ei(r,!0,-1),l=r.input.charCodeAt(r.position),(r.line===t||r.lineIndent>e)&&l!==0)dt(r,"bad indentation of a sequence entry");else if(r.lineIndent<e)break}return a?(r.tag=i,r.anchor=n,r.kind="sequence",r.result=s,!0):!1}function _he(r,e,t){var i,n,s,o,a=r.tag,l=r.anchor,c={},u={},g=null,f=null,h=null,p=!1,m=!1,y;for(r.anchor!==null&&(r.anchorMap[r.anchor]=c),y=r.input.charCodeAt(r.position);y!==0;){if(i=r.input.charCodeAt(r.position+1),s=r.line,o=r.position,(y===63||y===58)&&yn(i))y===63?(p&&(ag(r,c,u,g,f,null),g=f=h=null),m=!0,p=!0,n=!0):p?(p=!1,n=!0):dt(r,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),r.position+=1,y=i;else if(Ag(r,t,iU,!1,!0))if(r.line===s){for(y=r.input.charCodeAt(r.position);mc(y);)y=r.input.charCodeAt(++r.position);if(y===58)y=r.input.charCodeAt(++r.position),yn(y)||dt(r,"a whitespace character is expected after the key-value separator within a block mapping"),p&&(ag(r,c,u,g,f,null),g=f=h=null),m=!0,p=!1,n=!1,g=r.tag,f=r.result;else if(m)dt(r,"can not read an implicit mapping pair; a colon is missed");else return r.tag=a,r.anchor=l,!0}else if(m)dt(r,"can not read a block mapping entry; a multiline key may not be an implicit key");else return r.tag=a,r.anchor=l,!0;else break;if((r.line===s||r.lineIndent>e)&&(Ag(r,e,oI,!0,n)&&(p?f=r.result:h=r.result),p||(ag(r,c,u,g,f,h,s,o),g=f=h=null),ei(r,!0,-1),y=r.input.charCodeAt(r.position)),r.lineIndent>e&&y!==0)dt(r,"bad indentation of a mapping entry");else if(r.lineIndent<e)break}return p&&ag(r,c,u,g,f,null),m&&(r.tag=a,r.anchor=l,r.kind="mapping",r.result=c),m}function Vhe(r){var e,t=!1,i=!1,n,s,o;if(o=r.input.charCodeAt(r.position),o!==33)return!1;if(r.tag!==null&&dt(r,"duplication of a tag property"),o=r.input.charCodeAt(++r.position),o===60?(t=!0,o=r.input.charCodeAt(++r.position)):o===33?(i=!0,n="!!",o=r.input.charCodeAt(++r.position)):n="!",e=r.position,t){do o=r.input.charCodeAt(++r.position);while(o!==0&&o!==62);r.position<r.length?(s=r.input.slice(e,r.position),o=r.input.charCodeAt(++r.position)):dt(r,"unexpected end of the stream within a verbatim tag")}else{for(;o!==0&&!yn(o);)o===33&&(i?dt(r,"tag suffix cannot contain exclamation marks"):(n=r.input.slice(e-1,r.position+1),oU.test(n)||dt(r,"named tag handle cannot contain such characters"),i=!0,e=r.position+1)),o=r.input.charCodeAt(++r.position);s=r.input.slice(e,r.position),Mhe.test(s)&&dt(r,"tag suffix cannot contain flow indicator characters")}return s&&!aU.test(s)&&dt(r,"tag name cannot contain such characters: "+s),t?r.tag=s:WA.call(r.tagMap,n)?r.tag=r.tagMap[n]+s:n==="!"?r.tag="!"+s:n==="!!"?r.tag="tag:yaml.org,2002:"+s:dt(r,'undeclared tag handle "'+n+'"'),!0}function Xhe(r){var e,t;if(t=r.input.charCodeAt(r.position),t!==38)return!1;for(r.anchor!==null&&dt(r,"duplication of an anchor property"),t=r.input.charCodeAt(++r.position),e=r.position;t!==0&&!yn(t)&&!sg(t);)t=r.input.charCodeAt(++r.position);return r.position===e&&dt(r,"name of an anchor node must contain at least one character"),r.anchor=r.input.slice(e,r.position),!0}function Zhe(r){var e,t,i;if(i=r.input.charCodeAt(r.position),i!==42)return!1;for(i=r.input.charCodeAt(++r.position),e=r.position;i!==0&&!yn(i)&&!sg(i);)i=r.input.charCodeAt(++r.position);return r.position===e&&dt(r,"name of an alias node must contain at least one character"),t=r.input.slice(e,r.position),WA.call(r.anchorMap,t)||dt(r,'unidentified alias "'+t+'"'),r.result=r.anchorMap[t],ei(r,!0,-1),!0}function Ag(r,e,t,i,n){var s,o,a,l=1,c=!1,u=!1,g,f,h,p,m;if(r.listener!==null&&r.listener("open",r),r.tag=null,r.anchor=null,r.kind=null,r.result=null,s=o=a=oI===t||nU===t,i&&ei(r,!0,-1)&&(c=!0,r.lineIndent>e?l=1:r.lineIndent===e?l=0:r.lineIndent<e&&(l=-1)),l===1)for(;Vhe(r)||Xhe(r);)ei(r,!0,-1)?(c=!0,a=s,r.lineIndent>e?l=1:r.lineIndent===e?l=0:r.lineIndent<e&&(l=-1)):a=!1;if(a&&(a=c||n),(l===1||oI===t)&&(sI===t||iU===t?p=e:p=e+1,m=r.position-r.lineStart,l===1?a&&(pU(r,m)||_he(r,m,p))||Whe(r,p)?u=!0:(o&&zhe(r,p)||qhe(r,p)||Jhe(r,p)?u=!0:Zhe(r)?(u=!0,(r.tag!==null||r.anchor!==null)&&dt(r,"alias node should not have any properties")):Yhe(r,p,sI===t)&&(u=!0,r.tag===null&&(r.tag="?")),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):l===0&&(u=a&&pU(r,m))),r.tag!==null&&r.tag!=="!")if(r.tag==="?"){for(r.result!==null&&r.kind!=="scalar"&&dt(r,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+r.kind+'"'),g=0,f=r.implicitTypes.length;g<f;g+=1)if(h=r.implicitTypes[g],h.resolve(r.result)){r.result=h.construct(r.result),r.tag=h.tag,r.anchor!==null&&(r.anchorMap[r.anchor]=r.result);break}}else WA.call(r.typeMap[r.kind||"fallback"],r.tag)?(h=r.typeMap[r.kind||"fallback"][r.tag],r.result!==null&&h.kind!==r.kind&&dt(r,"unacceptable node kind for !<"+r.tag+'> tag; it should be "'+h.kind+'", not "'+r.kind+'"'),h.resolve(r.result)?(r.result=h.construct(r.result),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):dt(r,"cannot resolve a node with !<"+r.tag+"> explicit tag")):dt(r,"unknown tag !<"+r.tag+">");return r.listener!==null&&r.listener("close",r),r.tag!==null||r.anchor!==null||u}function $he(r){var e=r.position,t,i,n,s=!1,o;for(r.version=null,r.checkLineBreaks=r.legacy,r.tagMap={},r.anchorMap={};(o=r.input.charCodeAt(r.position))!==0&&(ei(r,!0,-1),o=r.input.charCodeAt(r.position),!(r.lineIndent>0||o!==37));){for(s=!0,o=r.input.charCodeAt(++r.position),t=r.position;o!==0&&!yn(o);)o=r.input.charCodeAt(++r.position);for(i=r.input.slice(t,r.position),n=[],i.length<1&&dt(r,"directive name must not be less than one character in length");o!==0;){for(;mc(o);)o=r.input.charCodeAt(++r.position);if(o===35){do o=r.input.charCodeAt(++r.position);while(o!==0&&!Oo(o));break}if(Oo(o))break;for(t=r.position;o!==0&&!yn(o);)o=r.input.charCodeAt(++r.position);n.push(r.input.slice(t,r.position))}o!==0&&UQ(r),WA.call(fU,i)?fU[i](r,i,n):aI(r,'unknown document directive "'+i+'"')}if(ei(r,!0,-1),r.lineIndent===0&&r.input.charCodeAt(r.position)===45&&r.input.charCodeAt(r.position+1)===45&&r.input.charCodeAt(r.position+2)===45?(r.position+=3,ei(r,!0,-1)):s&&dt(r,"directives end mark is expected"),Ag(r,r.lineIndent-1,oI,!1,!0),ei(r,!0,-1),r.checkLineBreaks&&Ohe.test(r.input.slice(e,r.position))&&aI(r,"non-ASCII line breaks are interpreted as content"),r.documents.push(r.result),r.position===r.lineStart&&AI(r)){r.input.charCodeAt(r.position)===46&&(r.position+=3,ei(r,!0,-1));return}if(r.position<r.length-1)dt(r,"end of the stream or a document separator is expected");else return}function dU(r,e){r=String(r),e=e||{},r.length!==0&&(r.charCodeAt(r.length-1)!==10&&r.charCodeAt(r.length-1)!==13&&(r+=` -`),r.charCodeAt(0)===65279&&(r=r.slice(1)));var t=new Ghe(r,e),i=r.indexOf("\0");for(i!==-1&&(t.position=i,dt(t,"null byte is not allowed in input")),t.input+="\0";t.input.charCodeAt(t.position)===32;)t.lineIndent+=1,t.position+=1;for(;t.position<t.length-1;)$he(t);return t.documents}function CU(r,e,t){e!==null&&typeof e=="object"&&typeof t=="undefined"&&(t=e,e=null);var i=dU(r,t);if(typeof e!="function")return i;for(var n=0,s=i.length;n<s;n+=1)e(i[n])}function mU(r,e){var t=dU(r,e);if(t.length!==0){if(t.length===1)return t[0];throw new tU("expected a single document in the stream, but found more")}}function epe(r,e,t){return typeof e=="object"&&e!==null&&typeof t=="undefined"&&(t=e,e=null),CU(r,e,Ma.extend({schema:rU},t))}function tpe(r,e){return mU(r,Ma.extend({schema:rU},e))}ip.exports.loadAll=CU;ip.exports.load=mU;ip.exports.safeLoadAll=epe;ip.exports.safeLoad=tpe});var jU=w((AXe,HQ)=>{"use strict";var np=pc(),sp=rg(),rpe=rp(),ipe=ng(),IU=Object.prototype.toString,yU=Object.prototype.hasOwnProperty,npe=9,op=10,spe=13,ope=32,ape=33,Ape=34,wU=35,lpe=37,cpe=38,upe=39,gpe=42,BU=44,fpe=45,bU=58,hpe=61,ppe=62,dpe=63,Cpe=64,QU=91,SU=93,mpe=96,vU=123,Epe=124,kU=125,Ui={};Ui[0]="\\0";Ui[7]="\\a";Ui[8]="\\b";Ui[9]="\\t";Ui[10]="\\n";Ui[11]="\\v";Ui[12]="\\f";Ui[13]="\\r";Ui[27]="\\e";Ui[34]='\\"';Ui[92]="\\\\";Ui[133]="\\N";Ui[160]="\\_";Ui[8232]="\\L";Ui[8233]="\\P";var Ipe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function ype(r,e){var t,i,n,s,o,a,l;if(e===null)return{};for(t={},i=Object.keys(e),n=0,s=i.length;n<s;n+=1)o=i[n],a=String(e[o]),o.slice(0,2)==="!!"&&(o="tag:yaml.org,2002:"+o.slice(2)),l=r.compiledTypeMap.fallback[o],l&&yU.call(l.styleAliases,a)&&(a=l.styleAliases[a]),t[o]=a;return t}function xU(r){var e,t,i;if(e=r.toString(16).toUpperCase(),r<=255)t="x",i=2;else if(r<=65535)t="u",i=4;else if(r<=4294967295)t="U",i=8;else throw new sp("code point within a string may not be greater than 0xFFFFFFFF");return"\\"+t+np.repeat("0",i-e.length)+e}function wpe(r){this.schema=r.schema||rpe,this.indent=Math.max(1,r.indent||2),this.noArrayIndent=r.noArrayIndent||!1,this.skipInvalid=r.skipInvalid||!1,this.flowLevel=np.isNothing(r.flowLevel)?-1:r.flowLevel,this.styleMap=ype(this.schema,r.styles||null),this.sortKeys=r.sortKeys||!1,this.lineWidth=r.lineWidth||80,this.noRefs=r.noRefs||!1,this.noCompatMode=r.noCompatMode||!1,this.condenseFlow=r.condenseFlow||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function PU(r,e){for(var t=np.repeat(" ",e),i=0,n=-1,s="",o,a=r.length;i<a;)n=r.indexOf(` -`,i),n===-1?(o=r.slice(i),i=a):(o=r.slice(i,n+1),i=n+1),o.length&&o!==` -`&&(s+=t),s+=o;return s}function jQ(r,e){return` -`+np.repeat(" ",r.indent*e)}function Bpe(r,e){var t,i,n;for(t=0,i=r.implicitTypes.length;t<i;t+=1)if(n=r.implicitTypes[t],n.resolve(e))return!0;return!1}function GQ(r){return r===ope||r===npe}function lg(r){return 32<=r&&r<=126||161<=r&&r<=55295&&r!==8232&&r!==8233||57344<=r&&r<=65533&&r!==65279||65536<=r&&r<=1114111}function bpe(r){return lg(r)&&!GQ(r)&&r!==65279&&r!==spe&&r!==op}function DU(r,e){return lg(r)&&r!==65279&&r!==BU&&r!==QU&&r!==SU&&r!==vU&&r!==kU&&r!==bU&&(r!==wU||e&&bpe(e))}function Qpe(r){return lg(r)&&r!==65279&&!GQ(r)&&r!==fpe&&r!==dpe&&r!==bU&&r!==BU&&r!==QU&&r!==SU&&r!==vU&&r!==kU&&r!==wU&&r!==cpe&&r!==gpe&&r!==ape&&r!==Epe&&r!==hpe&&r!==ppe&&r!==upe&&r!==Ape&&r!==lpe&&r!==Cpe&&r!==mpe}function RU(r){var e=/^\n* /;return e.test(r)}var FU=1,NU=2,LU=3,TU=4,lI=5;function Spe(r,e,t,i,n){var s,o,a,l=!1,c=!1,u=i!==-1,g=-1,f=Qpe(r.charCodeAt(0))&&!GQ(r.charCodeAt(r.length-1));if(e)for(s=0;s<r.length;s++){if(o=r.charCodeAt(s),!lg(o))return lI;a=s>0?r.charCodeAt(s-1):null,f=f&&DU(o,a)}else{for(s=0;s<r.length;s++){if(o=r.charCodeAt(s),o===op)l=!0,u&&(c=c||s-g-1>i&&r[g+1]!==" ",g=s);else if(!lg(o))return lI;a=s>0?r.charCodeAt(s-1):null,f=f&&DU(o,a)}c=c||u&&s-g-1>i&&r[g+1]!==" "}return!l&&!c?f&&!n(r)?FU:NU:t>9&&RU(r)?lI:c?TU:LU}function xpe(r,e,t,i){r.dump=function(){if(e.length===0)return"''";if(!r.noCompatMode&&Ipe.indexOf(e)!==-1)return"'"+e+"'";var n=r.indent*Math.max(1,t),s=r.lineWidth===-1?-1:Math.max(Math.min(r.lineWidth,40),r.lineWidth-n),o=i||r.flowLevel>-1&&t>=r.flowLevel;function a(l){return Bpe(r,l)}switch(Spe(e,o,r.indent,s,a)){case FU:return e;case NU:return"'"+e.replace(/'/g,"''")+"'";case LU:return"|"+OU(e,r.indent)+MU(PU(e,n));case TU:return">"+OU(e,r.indent)+MU(PU(vpe(e,s),n));case lI:return'"'+kpe(e,s)+'"';default:throw new sp("impossible error: invalid scalar style")}}()}function OU(r,e){var t=RU(r)?String(e):"",i=r[r.length-1]===` -`,n=i&&(r[r.length-2]===` -`||r===` -`),s=n?"+":i?"":"-";return t+s+` -`}function MU(r){return r[r.length-1]===` -`?r.slice(0,-1):r}function vpe(r,e){for(var t=/(\n+)([^\n]*)/g,i=function(){var c=r.indexOf(` -`);return c=c!==-1?c:r.length,t.lastIndex=c,UU(r.slice(0,c),e)}(),n=r[0]===` -`||r[0]===" ",s,o;o=t.exec(r);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` -`:"")+UU(l,e),n=s}return i}function UU(r,e){if(r===""||r[0]===" ")return r;for(var t=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=t.exec(r);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` -`+r.slice(n,s),n=s+1),o=a;return l+=` -`,r.length-n>e&&o>n?l+=r.slice(n,o)+` -`+r.slice(o+1):l+=r.slice(n),l.slice(1)}function kpe(r){for(var e="",t,i,n,s=0;s<r.length;s++){if(t=r.charCodeAt(s),t>=55296&&t<=56319&&(i=r.charCodeAt(s+1),i>=56320&&i<=57343)){e+=xU((t-55296)*1024+i-56320+65536),s++;continue}n=Ui[t],e+=!n&&lg(t)?r[s]:n||xU(t)}return e}function Ppe(r,e,t){var i="",n=r.tag,s,o;for(s=0,o=t.length;s<o;s+=1)Ec(r,e,t[s],!1,!1)&&(s!==0&&(i+=","+(r.condenseFlow?"":" ")),i+=r.dump);r.tag=n,r.dump="["+i+"]"}function Dpe(r,e,t,i){var n="",s=r.tag,o,a;for(o=0,a=t.length;o<a;o+=1)Ec(r,e+1,t[o],!0,!0)&&((!i||o!==0)&&(n+=jQ(r,e)),r.dump&&op===r.dump.charCodeAt(0)?n+="-":n+="- ",n+=r.dump);r.tag=s,r.dump=n||"[]"}function Rpe(r,e,t){var i="",n=r.tag,s=Object.keys(t),o,a,l,c,u;for(o=0,a=s.length;o<a;o+=1)u="",o!==0&&(u+=", "),r.condenseFlow&&(u+='"'),l=s[o],c=t[l],!!Ec(r,e,l,!1,!1)&&(r.dump.length>1024&&(u+="? "),u+=r.dump+(r.condenseFlow?'"':"")+":"+(r.condenseFlow?"":" "),!!Ec(r,e,c,!1,!1)&&(u+=r.dump,i+=u));r.tag=n,r.dump="{"+i+"}"}function Fpe(r,e,t,i){var n="",s=r.tag,o=Object.keys(t),a,l,c,u,g,f;if(r.sortKeys===!0)o.sort();else if(typeof r.sortKeys=="function")o.sort(r.sortKeys);else if(r.sortKeys)throw new sp("sortKeys must be a boolean or a function");for(a=0,l=o.length;a<l;a+=1)f="",(!i||a!==0)&&(f+=jQ(r,e)),c=o[a],u=t[c],!!Ec(r,e+1,c,!0,!0,!0)&&(g=r.tag!==null&&r.tag!=="?"||r.dump&&r.dump.length>1024,g&&(r.dump&&op===r.dump.charCodeAt(0)?f+="?":f+="? "),f+=r.dump,g&&(f+=jQ(r,e)),!!Ec(r,e+1,u,!0,g)&&(r.dump&&op===r.dump.charCodeAt(0)?f+=":":f+=": ",f+=r.dump,n+=f));r.tag=s,r.dump=n||"{}"}function KU(r,e,t){var i,n,s,o,a,l;for(n=t?r.explicitTypes:r.implicitTypes,s=0,o=n.length;s<o;s+=1)if(a=n[s],(a.instanceOf||a.predicate)&&(!a.instanceOf||typeof e=="object"&&e instanceof a.instanceOf)&&(!a.predicate||a.predicate(e))){if(r.tag=t?a.tag:"?",a.represent){if(l=r.styleMap[a.tag]||a.defaultStyle,IU.call(a.represent)==="[object Function]")i=a.represent(e,l);else if(yU.call(a.represent,l))i=a.represent[l](e,l);else throw new sp("!<"+a.tag+'> tag resolver accepts not "'+l+'" style');r.dump=i}return!0}return!1}function Ec(r,e,t,i,n,s){r.tag=null,r.dump=t,KU(r,t,!1)||KU(r,t,!0);var o=IU.call(r.dump);i&&(i=r.flowLevel<0||r.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=r.duplicates.indexOf(t),c=l!==-1),(r.tag!==null&&r.tag!=="?"||c||r.indent!==2&&e>0)&&(n=!1),c&&r.usedDuplicates[l])r.dump="*ref_"+l;else{if(a&&c&&!r.usedDuplicates[l]&&(r.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(r.dump).length!==0?(Fpe(r,e,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(Rpe(r,e,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump));else if(o==="[object Array]"){var u=r.noArrayIndent&&e>0?e-1:e;i&&r.dump.length!==0?(Dpe(r,u,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(Ppe(r,u,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump))}else if(o==="[object String]")r.tag!=="?"&&xpe(r,r.dump,e,s);else{if(r.skipInvalid)return!1;throw new sp("unacceptable kind of an object to dump "+o)}r.tag!==null&&r.tag!=="?"&&(r.dump="!<"+r.tag+"> "+r.dump)}return!0}function Npe(r,e){var t=[],i=[],n,s;for(YQ(r,t,i),n=0,s=i.length;n<s;n+=1)e.duplicates.push(t[i[n]]);e.usedDuplicates=new Array(s)}function YQ(r,e,t){var i,n,s;if(r!==null&&typeof r=="object")if(n=e.indexOf(r),n!==-1)t.indexOf(n)===-1&&t.push(n);else if(e.push(r),Array.isArray(r))for(n=0,s=r.length;n<s;n+=1)YQ(r[n],e,t);else for(i=Object.keys(r),n=0,s=i.length;n<s;n+=1)YQ(r[i[n]],e,t)}function HU(r,e){e=e||{};var t=new wpe(e);return t.noRefs||Npe(r,t),Ec(t,0,r,!0,!0)?t.dump+` -`:""}function Lpe(r,e){return HU(r,np.extend({schema:ipe},e))}HQ.exports.dump=HU;HQ.exports.safeDump=Lpe});var YU=w((lXe,Mr)=>{"use strict";var cI=EU(),GU=jU();function uI(r){return function(){throw new Error("Function "+r+" is deprecated and cannot be used.")}}Mr.exports.Type=ci();Mr.exports.Schema=dc();Mr.exports.FAILSAFE_SCHEMA=iI();Mr.exports.JSON_SCHEMA=LQ();Mr.exports.CORE_SCHEMA=TQ();Mr.exports.DEFAULT_SAFE_SCHEMA=ng();Mr.exports.DEFAULT_FULL_SCHEMA=rp();Mr.exports.load=cI.load;Mr.exports.loadAll=cI.loadAll;Mr.exports.safeLoad=cI.safeLoad;Mr.exports.safeLoadAll=cI.safeLoadAll;Mr.exports.dump=GU.dump;Mr.exports.safeDump=GU.safeDump;Mr.exports.YAMLException=rg();Mr.exports.MINIMAL_SCHEMA=iI();Mr.exports.SAFE_SCHEMA=ng();Mr.exports.DEFAULT_SCHEMA=rp();Mr.exports.scan=uI("scan");Mr.exports.parse=uI("parse");Mr.exports.compose=uI("compose");Mr.exports.addConstructor=uI("addConstructor")});var JU=w((cXe,qU)=>{"use strict";var Tpe=YU();qU.exports=Tpe});var zU=w((uXe,WU)=>{"use strict";function Ope(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function Ic(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Ic)}Ope(Ic,Error);Ic.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g<c.parts.length;g++)u+=c.parts[g]instanceof Array?s(c.parts[g][0])+"-"+s(c.parts[g][1]):s(c.parts[g]);return"["+(c.inverted?"^":"")+u+"]"},any:function(c){return"any character"},end:function(c){return"end of input"},other:function(c){return c.description}};function i(c){return c.charCodeAt(0).toString(16).toUpperCase()}function n(c){return c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function s(c){return c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function o(c){return t[c.type](c)}function a(c){var u=new Array(c.length),g,f;for(g=0;g<c.length;g++)u[g]=o(c[g]);if(u.sort(),u.length>0){for(g=1,f=1;g<u.length;g++)u[g-1]!==u[g]&&(u[f]=u[g],f++);u.length=f}switch(u.length){case 1:return u[0];case 2:return u[0]+" or "+u[1];default:return u.slice(0,-1).join(", ")+", or "+u[u.length-1]}}function l(c){return c?'"'+n(c)+'"':"end of input"}return"Expected "+a(r)+" but "+l(e)+" found."};function Mpe(r,e){e=e!==void 0?e:{};var t={},i={Start:to},n=to,s=function(R){return[].concat(...R)},o="-",a=gr("-",!1),l=function(R){return R},c=function(R){return Object.assign({},...R)},u="#",g=gr("#",!1),f=$l(),h=function(){return{}},p=":",m=gr(":",!1),y=function(R,G){return{[R]:G}},b=",",v=gr(",",!1),k=function(R,G){return G},T=function(R,G,Ce){return Object.assign({},...[R].concat(G).map(je=>({[je]:Ce})))},Y=function(R){return R},q=function(R){return R},$=eo("correct indentation"),z=" ",ne=gr(" ",!1),ee=function(R){return R.length===KA*Wu},A=function(R){return R.length===(KA+1)*Wu},oe=function(){return KA++,!0},ce=function(){return KA--,!0},Z=function(){return Hu()},O=eo("pseudostring"),L=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,de=Jn(["\r",` -`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),Be=/^[^\r\n\t ,\][{}:#"']/,Ge=Jn(["\r",` -`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),re=function(){return Hu().replace(/^ *| *$/g,"")},se="--",be=gr("--",!1),he=/^[a-zA-Z\/0-9]/,Fe=Jn([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),Ue=/^[^\r\n\t :,]/,xe=Jn(["\r",` -`," "," ",":",","],!0,!1),ve="null",pe=gr("null",!1),V=function(){return null},Qe="true",le=gr("true",!1),fe=function(){return!0},gt="false",Ht=gr("false",!1),Mt=function(){return!1},Ei=eo("string"),jt='"',Qr=gr('"',!1),Oi=function(){return""},$s=function(R){return R},Hn=function(R){return R.join("")},jn=/^[^"\\\0-\x1F\x7F]/,Sr=Jn(['"',"\\",["\0",""],"\x7F"],!0,!1),Gn='\\"',fs=gr('\\"',!1),Qa=function(){return'"'},RA="\\\\",Lu=gr("\\\\",!1),hs=function(){return"\\"},FA="\\/",Sa=gr("\\/",!1),Tu=function(){return"/"},NA="\\b",LA=gr("\\b",!1),vr=function(){return"\b"},_l="\\f",Ou=gr("\\f",!1),Po=function(){return"\f"},Mu="\\n",vh=gr("\\n",!1),kh=function(){return` -`},Dr="\\r",Ae=gr("\\r",!1),Do=function(){return"\r"},Yn="\\t",Uu=gr("\\t",!1),St=function(){return" "},Vl="\\u",qn=gr("\\u",!1),ps=function(R,G,Ce,je){return String.fromCharCode(parseInt(`0x${R}${G}${Ce}${je}`))},ds=/^[0-9a-fA-F]/,pt=Jn([["0","9"],["a","f"],["A","F"]],!1,!1),Ro=eo("blank space"),lt=/^[ \t]/,mn=Jn([" "," "],!1,!1),S=eo("white space"),Tt=/^[ \t\n\r]/,Ku=Jn([" "," ",` -`,"\r"],!1,!1),Xl=`\r -`,xh=gr(`\r -`,!1),Ph=` -`,Dh=gr(` -`,!1),Rh="\r",Fh=gr("\r",!1),j=0,wt=0,TA=[{line:1,column:1}],$i=0,Zl=[],$e=0,va;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function Hu(){return r.substring(wt,j)}function wE(){return En(wt,j)}function Nh(R,G){throw G=G!==void 0?G:En(wt,j),ec([eo(R)],r.substring(wt,j),G)}function BE(R,G){throw G=G!==void 0?G:En(wt,j),ju(R,G)}function gr(R,G){return{type:"literal",text:R,ignoreCase:G}}function Jn(R,G,Ce){return{type:"class",parts:R,inverted:G,ignoreCase:Ce}}function $l(){return{type:"any"}}function Lh(){return{type:"end"}}function eo(R){return{type:"other",description:R}}function ka(R){var G=TA[R],Ce;if(G)return G;for(Ce=R-1;!TA[Ce];)Ce--;for(G=TA[Ce],G={line:G.line,column:G.column};Ce<R;)r.charCodeAt(Ce)===10?(G.line++,G.column=1):G.column++,Ce++;return TA[R]=G,G}function En(R,G){var Ce=ka(R),je=ka(G);return{start:{offset:R,line:Ce.line,column:Ce.column},end:{offset:G,line:je.line,column:je.column}}}function Oe(R){j<$i||(j>$i&&($i=j,Zl=[]),Zl.push(R))}function ju(R,G){return new Ic(R,null,null,G)}function ec(R,G,Ce){return new Ic(Ic.buildMessage(R,G),R,G,Ce)}function to(){var R;return R=Gu(),R}function tc(){var R,G,Ce;for(R=j,G=[],Ce=OA();Ce!==t;)G.push(Ce),Ce=OA();return G!==t&&(wt=R,G=s(G)),R=G,R}function OA(){var R,G,Ce,je,Te;return R=j,G=Pa(),G!==t?(r.charCodeAt(j)===45?(Ce=o,j++):(Ce=t,$e===0&&Oe(a)),Ce!==t?(je=Tr(),je!==t?(Te=xa(),Te!==t?(wt=R,G=l(Te),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R}function Gu(){var R,G,Ce;for(R=j,G=[],Ce=Yu();Ce!==t;)G.push(Ce),Ce=Yu();return G!==t&&(wt=R,G=c(G)),R=G,R}function Yu(){var R,G,Ce,je,Te,Xe,Et,Rt,Wn;if(R=j,G=Tr(),G===t&&(G=null),G!==t){if(Ce=j,r.charCodeAt(j)===35?(je=u,j++):(je=t,$e===0&&Oe(g)),je!==t){if(Te=[],Xe=j,Et=j,$e++,Rt=no(),$e--,Rt===t?Et=void 0:(j=Et,Et=t),Et!==t?(r.length>j?(Rt=r.charAt(j),j++):(Rt=t,$e===0&&Oe(f)),Rt!==t?(Et=[Et,Rt],Xe=Et):(j=Xe,Xe=t)):(j=Xe,Xe=t),Xe!==t)for(;Xe!==t;)Te.push(Xe),Xe=j,Et=j,$e++,Rt=no(),$e--,Rt===t?Et=void 0:(j=Et,Et=t),Et!==t?(r.length>j?(Rt=r.charAt(j),j++):(Rt=t,$e===0&&Oe(f)),Rt!==t?(Et=[Et,Rt],Xe=Et):(j=Xe,Xe=t)):(j=Xe,Xe=t);else Te=t;Te!==t?(je=[je,Te],Ce=je):(j=Ce,Ce=t)}else j=Ce,Ce=t;if(Ce===t&&(Ce=null),Ce!==t){if(je=[],Te=io(),Te!==t)for(;Te!==t;)je.push(Te),Te=io();else je=t;je!==t?(wt=R,G=h(),R=G):(j=R,R=t)}else j=R,R=t}else j=R,R=t;if(R===t&&(R=j,G=Pa(),G!==t?(Ce=rc(),Ce!==t?(je=Tr(),je===t&&(je=null),je!==t?(r.charCodeAt(j)===58?(Te=p,j++):(Te=t,$e===0&&Oe(m)),Te!==t?(Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(Et=xa(),Et!==t?(wt=R,G=y(Ce,Et),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t&&(R=j,G=Pa(),G!==t?(Ce=ro(),Ce!==t?(je=Tr(),je===t&&(je=null),je!==t?(r.charCodeAt(j)===58?(Te=p,j++):(Te=t,$e===0&&Oe(m)),Te!==t?(Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(Et=xa(),Et!==t?(wt=R,G=y(Ce,Et),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t))){if(R=j,G=Pa(),G!==t)if(Ce=ro(),Ce!==t)if(je=Tr(),je!==t)if(Te=bE(),Te!==t){if(Xe=[],Et=io(),Et!==t)for(;Et!==t;)Xe.push(Et),Et=io();else Xe=t;Xe!==t?(wt=R,G=y(Ce,Te),R=G):(j=R,R=t)}else j=R,R=t;else j=R,R=t;else j=R,R=t;else j=R,R=t;if(R===t)if(R=j,G=Pa(),G!==t)if(Ce=ro(),Ce!==t){if(je=[],Te=j,Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(r.charCodeAt(j)===44?(Et=b,j++):(Et=t,$e===0&&Oe(v)),Et!==t?(Rt=Tr(),Rt===t&&(Rt=null),Rt!==t?(Wn=ro(),Wn!==t?(wt=Te,Xe=k(Ce,Wn),Te=Xe):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t),Te!==t)for(;Te!==t;)je.push(Te),Te=j,Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(r.charCodeAt(j)===44?(Et=b,j++):(Et=t,$e===0&&Oe(v)),Et!==t?(Rt=Tr(),Rt===t&&(Rt=null),Rt!==t?(Wn=ro(),Wn!==t?(wt=Te,Xe=k(Ce,Wn),Te=Xe):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t);else je=t;je!==t?(Te=Tr(),Te===t&&(Te=null),Te!==t?(r.charCodeAt(j)===58?(Xe=p,j++):(Xe=t,$e===0&&Oe(m)),Xe!==t?(Et=Tr(),Et===t&&(Et=null),Et!==t?(Rt=xa(),Rt!==t?(wt=R,G=T(Ce,je,Rt),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)}else j=R,R=t;else j=R,R=t}return R}function xa(){var R,G,Ce,je,Te,Xe,Et;if(R=j,G=j,$e++,Ce=j,je=no(),je!==t?(Te=nt(),Te!==t?(r.charCodeAt(j)===45?(Xe=o,j++):(Xe=t,$e===0&&Oe(a)),Xe!==t?(Et=Tr(),Et!==t?(je=[je,Te,Xe,Et],Ce=je):(j=Ce,Ce=t)):(j=Ce,Ce=t)):(j=Ce,Ce=t)):(j=Ce,Ce=t),$e--,Ce!==t?(j=G,G=void 0):G=t,G!==t?(Ce=io(),Ce!==t?(je=Fo(),je!==t?(Te=tc(),Te!==t?(Xe=MA(),Xe!==t?(wt=R,G=Y(Te),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t&&(R=j,G=no(),G!==t?(Ce=Fo(),Ce!==t?(je=Gu(),je!==t?(Te=MA(),Te!==t?(wt=R,G=Y(je),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t))if(R=j,G=ic(),G!==t){if(Ce=[],je=io(),je!==t)for(;je!==t;)Ce.push(je),je=io();else Ce=t;Ce!==t?(wt=R,G=q(G),R=G):(j=R,R=t)}else j=R,R=t;return R}function Pa(){var R,G,Ce;for($e++,R=j,G=[],r.charCodeAt(j)===32?(Ce=z,j++):(Ce=t,$e===0&&Oe(ne));Ce!==t;)G.push(Ce),r.charCodeAt(j)===32?(Ce=z,j++):(Ce=t,$e===0&&Oe(ne));return G!==t?(wt=j,Ce=ee(G),Ce?Ce=void 0:Ce=t,Ce!==t?(G=[G,Ce],R=G):(j=R,R=t)):(j=R,R=t),$e--,R===t&&(G=t,$e===0&&Oe($)),R}function nt(){var R,G,Ce;for(R=j,G=[],r.charCodeAt(j)===32?(Ce=z,j++):(Ce=t,$e===0&&Oe(ne));Ce!==t;)G.push(Ce),r.charCodeAt(j)===32?(Ce=z,j++):(Ce=t,$e===0&&Oe(ne));return G!==t?(wt=j,Ce=A(G),Ce?Ce=void 0:Ce=t,Ce!==t?(G=[G,Ce],R=G):(j=R,R=t)):(j=R,R=t),R}function Fo(){var R;return wt=j,R=oe(),R?R=void 0:R=t,R}function MA(){var R;return wt=j,R=ce(),R?R=void 0:R=t,R}function rc(){var R;return R=nc(),R===t&&(R=Th()),R}function ro(){var R,G,Ce;if(R=nc(),R===t){if(R=j,G=[],Ce=qu(),Ce!==t)for(;Ce!==t;)G.push(Ce),Ce=qu();else G=t;G!==t&&(wt=R,G=Z()),R=G}return R}function ic(){var R;return R=Oh(),R===t&&(R=QE(),R===t&&(R=nc(),R===t&&(R=Th()))),R}function bE(){var R;return R=Oh(),R===t&&(R=nc(),R===t&&(R=qu())),R}function Th(){var R,G,Ce,je,Te,Xe;if($e++,R=j,L.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(de)),G!==t){for(Ce=[],je=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Be.test(r.charAt(j))?(Xe=r.charAt(j),j++):(Xe=t,$e===0&&Oe(Ge)),Xe!==t?(Te=[Te,Xe],je=Te):(j=je,je=t)):(j=je,je=t);je!==t;)Ce.push(je),je=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Be.test(r.charAt(j))?(Xe=r.charAt(j),j++):(Xe=t,$e===0&&Oe(Ge)),Xe!==t?(Te=[Te,Xe],je=Te):(j=je,je=t)):(j=je,je=t);Ce!==t?(wt=R,G=re(),R=G):(j=R,R=t)}else j=R,R=t;return $e--,R===t&&(G=t,$e===0&&Oe(O)),R}function qu(){var R,G,Ce,je,Te;if(R=j,r.substr(j,2)===se?(G=se,j+=2):(G=t,$e===0&&Oe(be)),G===t&&(G=null),G!==t)if(he.test(r.charAt(j))?(Ce=r.charAt(j),j++):(Ce=t,$e===0&&Oe(Fe)),Ce!==t){for(je=[],Ue.test(r.charAt(j))?(Te=r.charAt(j),j++):(Te=t,$e===0&&Oe(xe));Te!==t;)je.push(Te),Ue.test(r.charAt(j))?(Te=r.charAt(j),j++):(Te=t,$e===0&&Oe(xe));je!==t?(wt=R,G=re(),R=G):(j=R,R=t)}else j=R,R=t;else j=R,R=t;return R}function Oh(){var R,G;return R=j,r.substr(j,4)===ve?(G=ve,j+=4):(G=t,$e===0&&Oe(pe)),G!==t&&(wt=R,G=V()),R=G,R}function QE(){var R,G;return R=j,r.substr(j,4)===Qe?(G=Qe,j+=4):(G=t,$e===0&&Oe(le)),G!==t&&(wt=R,G=fe()),R=G,R===t&&(R=j,r.substr(j,5)===gt?(G=gt,j+=5):(G=t,$e===0&&Oe(Ht)),G!==t&&(wt=R,G=Mt()),R=G),R}function nc(){var R,G,Ce,je;return $e++,R=j,r.charCodeAt(j)===34?(G=jt,j++):(G=t,$e===0&&Oe(Qr)),G!==t?(r.charCodeAt(j)===34?(Ce=jt,j++):(Ce=t,$e===0&&Oe(Qr)),Ce!==t?(wt=R,G=Oi(),R=G):(j=R,R=t)):(j=R,R=t),R===t&&(R=j,r.charCodeAt(j)===34?(G=jt,j++):(G=t,$e===0&&Oe(Qr)),G!==t?(Ce=SE(),Ce!==t?(r.charCodeAt(j)===34?(je=jt,j++):(je=t,$e===0&&Oe(Qr)),je!==t?(wt=R,G=$s(Ce),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)),$e--,R===t&&(G=t,$e===0&&Oe(Ei)),R}function SE(){var R,G,Ce;if(R=j,G=[],Ce=Ju(),Ce!==t)for(;Ce!==t;)G.push(Ce),Ce=Ju();else G=t;return G!==t&&(wt=R,G=Hn(G)),R=G,R}function Ju(){var R,G,Ce,je,Te,Xe;return jn.test(r.charAt(j))?(R=r.charAt(j),j++):(R=t,$e===0&&Oe(Sr)),R===t&&(R=j,r.substr(j,2)===Gn?(G=Gn,j+=2):(G=t,$e===0&&Oe(fs)),G!==t&&(wt=R,G=Qa()),R=G,R===t&&(R=j,r.substr(j,2)===RA?(G=RA,j+=2):(G=t,$e===0&&Oe(Lu)),G!==t&&(wt=R,G=hs()),R=G,R===t&&(R=j,r.substr(j,2)===FA?(G=FA,j+=2):(G=t,$e===0&&Oe(Sa)),G!==t&&(wt=R,G=Tu()),R=G,R===t&&(R=j,r.substr(j,2)===NA?(G=NA,j+=2):(G=t,$e===0&&Oe(LA)),G!==t&&(wt=R,G=vr()),R=G,R===t&&(R=j,r.substr(j,2)===_l?(G=_l,j+=2):(G=t,$e===0&&Oe(Ou)),G!==t&&(wt=R,G=Po()),R=G,R===t&&(R=j,r.substr(j,2)===Mu?(G=Mu,j+=2):(G=t,$e===0&&Oe(vh)),G!==t&&(wt=R,G=kh()),R=G,R===t&&(R=j,r.substr(j,2)===Dr?(G=Dr,j+=2):(G=t,$e===0&&Oe(Ae)),G!==t&&(wt=R,G=Do()),R=G,R===t&&(R=j,r.substr(j,2)===Yn?(G=Yn,j+=2):(G=t,$e===0&&Oe(Uu)),G!==t&&(wt=R,G=St()),R=G,R===t&&(R=j,r.substr(j,2)===Vl?(G=Vl,j+=2):(G=t,$e===0&&Oe(qn)),G!==t?(Ce=UA(),Ce!==t?(je=UA(),je!==t?(Te=UA(),Te!==t?(Xe=UA(),Xe!==t?(wt=R,G=ps(Ce,je,Te,Xe),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)))))))))),R}function UA(){var R;return ds.test(r.charAt(j))?(R=r.charAt(j),j++):(R=t,$e===0&&Oe(pt)),R}function Tr(){var R,G;if($e++,R=[],lt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(mn)),G!==t)for(;G!==t;)R.push(G),lt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(mn));else R=t;return $e--,R===t&&(G=t,$e===0&&Oe(Ro)),R}function vE(){var R,G;if($e++,R=[],Tt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(Ku)),G!==t)for(;G!==t;)R.push(G),Tt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(Ku));else R=t;return $e--,R===t&&(G=t,$e===0&&Oe(S)),R}function io(){var R,G,Ce,je,Te,Xe;if(R=j,G=no(),G!==t){for(Ce=[],je=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Xe=no(),Xe!==t?(Te=[Te,Xe],je=Te):(j=je,je=t)):(j=je,je=t);je!==t;)Ce.push(je),je=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Xe=no(),Xe!==t?(Te=[Te,Xe],je=Te):(j=je,je=t)):(j=je,je=t);Ce!==t?(G=[G,Ce],R=G):(j=R,R=t)}else j=R,R=t;return R}function no(){var R;return r.substr(j,2)===Xl?(R=Xl,j+=2):(R=t,$e===0&&Oe(xh)),R===t&&(r.charCodeAt(j)===10?(R=Ph,j++):(R=t,$e===0&&Oe(Dh)),R===t&&(r.charCodeAt(j)===13?(R=Rh,j++):(R=t,$e===0&&Oe(Fh)))),R}let Wu=2,KA=0;if(va=n(),va!==t&&j===r.length)return va;throw va!==t&&j<r.length&&Oe(Lh()),ec(Zl,$i<r.length?r.charAt($i):null,$i<r.length?En($i,$i+1):En($i,$i))}WU.exports={SyntaxError:Ic,parse:Mpe}});var eK=w((dXe,WQ)=>{"use strict";var Gpe=r=>{let e=!1,t=!1,i=!1;for(let n=0;n<r.length;n++){let s=r[n];e&&/[a-zA-Z]/.test(s)&&s.toUpperCase()===s?(r=r.slice(0,n)+"-"+r.slice(n),e=!1,i=t,t=!0,n++):t&&i&&/[a-zA-Z]/.test(s)&&s.toLowerCase()===s?(r=r.slice(0,n-1)+"-"+r.slice(n-1),i=t,t=!1,e=!0):(e=s.toLowerCase()===s&&s.toUpperCase()!==s,i=t,t=s.toUpperCase()===s&&s.toLowerCase()!==s)}return r},$U=(r,e)=>{if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let t=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(r)?r=r.map(n=>n.trim()).filter(n=>n.length).join("-"):r=r.trim(),r.length===0?"":r.length===1?e.pascalCase?r.toUpperCase():r.toLowerCase():(r!==r.toLowerCase()&&(r=Gpe(r)),r=r.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),t(r))};WQ.exports=$U;WQ.exports.default=$U});var rK=w((CXe,tK)=>{tK.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var yc=w(Zn=>{"use strict";var iK=rK(),Mo=process.env;Object.defineProperty(Zn,"_vendors",{value:iK.map(function(r){return r.constant})});Zn.name=null;Zn.isPR=null;iK.forEach(function(r){let t=(Array.isArray(r.env)?r.env:[r.env]).every(function(i){return nK(i)});if(Zn[r.constant]=t,t)switch(Zn.name=r.name,typeof r.pr){case"string":Zn.isPR=!!Mo[r.pr];break;case"object":"env"in r.pr?Zn.isPR=r.pr.env in Mo&&Mo[r.pr.env]!==r.pr.ne:"any"in r.pr?Zn.isPR=r.pr.any.some(function(i){return!!Mo[i]}):Zn.isPR=nK(r.pr);break;default:Zn.isPR=null}});Zn.isCI=!!(Mo.CI||Mo.CONTINUOUS_INTEGRATION||Mo.BUILD_NUMBER||Mo.RUN_ID||Zn.name);function nK(r){return typeof r=="string"?!!Mo[r]:Object.keys(r).every(function(e){return Mo[e]===r[e]})}});var ug={};ft(ug,{KeyRelationship:()=>bc,applyCascade:()=>hp,base64RegExp:()=>lK,colorStringAlphaRegExp:()=>AK,colorStringRegExp:()=>aK,computeKey:()=>_A,getPrintable:()=>ti,hasExactLength:()=>hK,hasForbiddenKeys:()=>yde,hasKeyRelationship:()=>tS,hasMaxLength:()=>nde,hasMinLength:()=>ide,hasMutuallyExclusiveKeys:()=>wde,hasRequiredKeys:()=>Ide,hasUniqueItems:()=>sde,isArray:()=>_pe,isAtLeast:()=>Ade,isAtMost:()=>lde,isBase64:()=>mde,isBoolean:()=>Jpe,isDate:()=>zpe,isDict:()=>Xpe,isEnum:()=>nn,isHexColor:()=>Cde,isISO8601:()=>dde,isInExclusiveRange:()=>ude,isInInclusiveRange:()=>cde,isInstanceOf:()=>$pe,isInteger:()=>gde,isJSON:()=>Ede,isLiteral:()=>Ype,isLowerCase:()=>fde,isNegative:()=>ode,isNullable:()=>rde,isNumber:()=>Wpe,isObject:()=>Zpe,isOneOf:()=>ede,isOptional:()=>tde,isPositive:()=>ade,isString:()=>fp,isTuple:()=>Vpe,isUUID4:()=>pde,isUnknown:()=>fK,isUpperCase:()=>hde,iso8601RegExp:()=>eS,makeCoercionFn:()=>Bc,makeSetter:()=>gK,makeTrait:()=>uK,makeValidator:()=>vt,matchesRegExp:()=>pp,plural:()=>pI,pushError:()=>mt,simpleKeyRegExp:()=>oK,uuid4RegExp:()=>cK});function vt({test:r}){return uK(r)()}function ti(r){return r===null?"null":r===void 0?"undefined":r===""?"an empty string":JSON.stringify(r)}function _A(r,e){var t,i,n;return typeof e=="number"?`${(t=r==null?void 0:r.p)!==null&&t!==void 0?t:"."}[${e}]`:oK.test(e)?`${(i=r==null?void 0:r.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=r==null?void 0:r.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function Bc(r,e){return t=>{let i=r[e];return r[e]=t,Bc(r,e).bind(null,i)}}function gK(r,e){return t=>{r[e]=t}}function pI(r,e,t){return r===1?e:t}function mt({errors:r,p:e}={},t){return r==null||r.push(`${e!=null?e:"."}: ${t}`),!1}function Ype(r){return vt({test:(e,t)=>e!==r?mt(t,`Expected a literal (got ${ti(r)})`):!0})}function nn(r){let e=Array.isArray(r)?r:Object.values(r),t=new Set(e);return vt({test:(i,n)=>t.has(i)?!0:mt(n,`Expected a valid enumeration value (got ${ti(i)})`)})}var oK,aK,AK,lK,cK,eS,uK,fK,fp,qpe,Jpe,Wpe,zpe,_pe,Vpe,Xpe,Zpe,$pe,ede,hp,tde,rde,ide,nde,hK,sde,ode,ade,Ade,lde,cde,ude,gde,pp,fde,hde,pde,dde,Cde,mde,Ede,Ide,yde,wde,bc,Bde,tS,ws=hge(()=>{oK=/^[a-zA-Z_][a-zA-Z0-9_]*$/,aK=/^#[0-9a-f]{6}$/i,AK=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,lK=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,cK=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,eS=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/,uK=r=>()=>r;fK=()=>vt({test:(r,e)=>!0});fp=()=>vt({test:(r,e)=>typeof r!="string"?mt(e,`Expected a string (got ${ti(r)})`):!0});qpe=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),Jpe=()=>vt({test:(r,e)=>{var t;if(typeof r!="boolean"){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return mt(e,"Unbound coercion result");let i=qpe.get(r);if(typeof i!="undefined")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return mt(e,`Expected a boolean (got ${ti(r)})`)}return!0}}),Wpe=()=>vt({test:(r,e)=>{var t;if(typeof r!="number"){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return mt(e,"Unbound coercion result");let i;if(typeof r=="string"){let n;try{n=JSON.parse(r)}catch(s){}if(typeof n=="number")if(JSON.stringify(n)===r)i=n;else return mt(e,`Received a number that can't be safely represented by the runtime (${r})`)}if(typeof i!="undefined")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return mt(e,`Expected a number (got ${ti(r)})`)}return!0}}),zpe=()=>vt({test:(r,e)=>{var t;if(!(r instanceof Date)){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return mt(e,"Unbound coercion result");let i;if(typeof r=="string"&&eS.test(r))i=new Date(r);else{let n;if(typeof r=="string"){let s;try{s=JSON.parse(r)}catch(o){}typeof s=="number"&&(n=s)}else typeof r=="number"&&(n=r);if(typeof n!="undefined")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return mt(e,`Received a timestamp that can't be safely represented by the runtime (${r})`)}if(typeof i!="undefined")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return mt(e,`Expected a date (got ${ti(r)})`)}return!0}}),_pe=(r,{delimiter:e}={})=>vt({test:(t,i)=>{var n;if(typeof t=="string"&&typeof e!="undefined"&&typeof(i==null?void 0:i.coercions)!="undefined"){if(typeof(i==null?void 0:i.coercion)=="undefined")return mt(i,"Unbound coercion result");t=t.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,t)])}if(!Array.isArray(t))return mt(i,`Expected an array (got ${ti(t)})`);let s=!0;for(let o=0,a=t.length;o<a&&(s=r(t[o],Object.assign(Object.assign({},i),{p:_A(i,o),coercion:Bc(t,o)}))&&s,!(!s&&(i==null?void 0:i.errors)==null));++o);return s}}),Vpe=(r,{delimiter:e}={})=>{let t=hK(r.length);return vt({test:(i,n)=>{var s;if(typeof i=="string"&&typeof e!="undefined"&&typeof(n==null?void 0:n.coercions)!="undefined"){if(typeof(n==null?void 0:n.coercion)=="undefined")return mt(n,"Unbound coercion result");i=i.split(e),n.coercions.push([(s=n.p)!==null&&s!==void 0?s:".",n.coercion.bind(null,i)])}if(!Array.isArray(i))return mt(n,`Expected a tuple (got ${ti(i)})`);let o=t(i,Object.assign({},n));for(let a=0,l=i.length;a<l&&a<r.length&&(o=r[a](i[a],Object.assign(Object.assign({},n),{p:_A(n,a),coercion:Bc(i,a)}))&&o,!(!o&&(n==null?void 0:n.errors)==null));++a);return o}})},Xpe=(r,{keys:e=null}={})=>vt({test:(t,i)=>{if(typeof t!="object"||t===null)return mt(i,`Expected an object (got ${ti(t)})`);let n=Object.keys(t),s=!0;for(let o=0,a=n.length;o<a&&(s||(i==null?void 0:i.errors)!=null);++o){let l=n[o],c=t[l];if(l==="__proto__"||l==="constructor"){s=mt(Object.assign(Object.assign({},i),{p:_A(i,l)}),"Unsafe property name");continue}if(e!==null&&!e(l,i)){s=!1;continue}if(!r(c,Object.assign(Object.assign({},i),{p:_A(i,l),coercion:Bc(t,l)}))){s=!1;continue}}return s}}),Zpe=(r,{extra:e=null}={})=>{let t=Object.keys(r);return vt({test:(i,n)=>{if(typeof i!="object"||i===null)return mt(n,`Expected an object (got ${ti(i)})`);let s=new Set([...t,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=mt(Object.assign(Object.assign({},n),{p:_A(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(r,l)?r[l]:void 0,u=Object.prototype.hasOwnProperty.call(i,l)?i[l]:void 0;typeof c!="undefined"?a=c(u,Object.assign(Object.assign({},n),{p:_A(n,l),coercion:Bc(i,l)}))&&a:e===null?a=mt(Object.assign(Object.assign({},n),{p:_A(n,l)}),`Extraneous property (got ${ti(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:gK(i,l)})}if(!a&&(n==null?void 0:n.errors)==null)break}return e!==null&&(a||(n==null?void 0:n.errors)!=null)&&(a=e(o,n)&&a),a}})},$pe=r=>vt({test:(e,t)=>e instanceof r?!0:mt(t,`Expected an instance of ${r.name} (got ${ti(e)})`)}),ede=(r,{exclusive:e=!1}={})=>vt({test:(t,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)!="undefined"?[]:void 0;for(let c=0,u=r.length;c<u;++c){let g=typeof(i==null?void 0:i.errors)!="undefined"?[]:void 0,f=typeof(i==null?void 0:i.coercions)!="undefined"?[]:void 0;if(r[c](t,Object.assign(Object.assign({},i),{errors:g,coercions:f,p:`${(n=i==null?void 0:i.p)!==null&&n!==void 0?n:"."}#${c+1}`}))){if(a.push([`#${c+1}`,f]),!e)break}else l==null||l.push(g[0])}if(a.length===1){let[,c]=a[0];return typeof c!="undefined"&&((s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...c)),!0}return a.length>1?mt(i,`Expected to match exactly a single predicate (matched ${a.join(", ")})`):(o=i==null?void 0:i.errors)===null||o===void 0||o.push(...l),!1}}),hp=(r,e)=>vt({test:(t,i)=>{var n,s;let o={value:t},a=typeof(i==null?void 0:i.coercions)!="undefined"?Bc(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)!="undefined"?[]:void 0;if(!r(t,Object.assign(Object.assign({},i),{coercion:a,coercions:l})))return!1;let c=[];if(typeof l!="undefined")for(let[,u]of l)c.push(u());try{if(typeof(i==null?void 0:i.coercions)!="undefined"){if(o.value!==t){if(typeof(i==null?void 0:i.coercion)=="undefined")return mt(i,"Unbound coercion result");i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,o.value)])}(s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...l)}return e.every(u=>u(o.value,i))}finally{for(let u of c)u()}}}),tde=r=>vt({test:(e,t)=>typeof e=="undefined"?!0:r(e,t)}),rde=r=>vt({test:(e,t)=>e===null?!0:r(e,t)}),ide=r=>vt({test:(e,t)=>e.length>=r?!0:mt(t,`Expected to have a length of at least ${r} elements (got ${e.length})`)}),nde=r=>vt({test:(e,t)=>e.length<=r?!0:mt(t,`Expected to have a length of at most ${r} elements (got ${e.length})`)}),hK=r=>vt({test:(e,t)=>e.length!==r?mt(t,`Expected to have a length of exactly ${r} elements (got ${e.length})`):!0}),sde=({map:r}={})=>vt({test:(e,t)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;s<o;++s){let a=e[s],l=typeof r!="undefined"?r(a):a;if(i.has(l)){if(n.has(l))continue;mt(t,`Expected to contain unique elements; got a duplicate with ${ti(e)}`),n.add(l)}else i.add(l)}return n.size===0}}),ode=()=>vt({test:(r,e)=>r<=0?!0:mt(e,`Expected to be negative (got ${r})`)}),ade=()=>vt({test:(r,e)=>r>=0?!0:mt(e,`Expected to be positive (got ${r})`)}),Ade=r=>vt({test:(e,t)=>e>=r?!0:mt(t,`Expected to be at least ${r} (got ${e})`)}),lde=r=>vt({test:(e,t)=>e<=r?!0:mt(t,`Expected to be at most ${r} (got ${e})`)}),cde=(r,e)=>vt({test:(t,i)=>t>=r&&t<=e?!0:mt(i,`Expected to be in the [${r}; ${e}] range (got ${t})`)}),ude=(r,e)=>vt({test:(t,i)=>t>=r&&t<e?!0:mt(i,`Expected to be in the [${r}; ${e}[ range (got ${t})`)}),gde=({unsafe:r=!1}={})=>vt({test:(e,t)=>e!==Math.round(e)?mt(t,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:mt(t,`Expected to be a safe integer (got ${e})`)}),pp=r=>vt({test:(e,t)=>r.test(e)?!0:mt(t,`Expected to match the pattern ${r.toString()} (got ${ti(e)})`)}),fde=()=>vt({test:(r,e)=>r!==r.toLowerCase()?mt(e,`Expected to be all-lowercase (got ${r})`):!0}),hde=()=>vt({test:(r,e)=>r!==r.toUpperCase()?mt(e,`Expected to be all-uppercase (got ${r})`):!0}),pde=()=>vt({test:(r,e)=>cK.test(r)?!0:mt(e,`Expected to be a valid UUID v4 (got ${ti(r)})`)}),dde=()=>vt({test:(r,e)=>eS.test(r)?!1:mt(e,`Expected to be a valid ISO 8601 date string (got ${ti(r)})`)}),Cde=({alpha:r=!1})=>vt({test:(e,t)=>(r?aK.test(e):AK.test(e))?!0:mt(t,`Expected to be a valid hexadecimal color string (got ${ti(e)})`)}),mde=()=>vt({test:(r,e)=>lK.test(r)?!0:mt(e,`Expected to be a valid base 64 string (got ${ti(r)})`)}),Ede=(r=fK())=>vt({test:(e,t)=>{let i;try{i=JSON.parse(e)}catch(n){return mt(t,`Expected to be a valid JSON string (got ${ti(e)})`)}return r(i,t)}}),Ide=r=>{let e=new Set(r);return vt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?mt(i,`Missing required ${pI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},yde=r=>{let e=new Set(r);return vt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?mt(i,`Forbidden ${pI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},wde=r=>{let e=new Set(r);return vt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?mt(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(r){r.Forbids="Forbids",r.Requires="Requires"})(bc||(bc={}));Bde={[bc.Forbids]:{expect:!1,message:"forbids using"},[bc.Requires]:{expect:!0,message:"requires using"}},tS=(r,e,t,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(t),o=Bde[e];return vt({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(r)||n.has(a[r]))return!0;let u=[];for(let g of s)(c.has(g)&&!n.has(a[g]))!==o.expect&&u.push(g);return u.length>=1?mt(l,`Property "${r}" ${o.message} ${pI(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var FK=w((mZe,RK)=>{"use strict";RK.exports=(r,...e)=>new Promise(t=>{t(r(...e))})});var fg=w((EZe,AS)=>{"use strict";var Kde=FK(),NK=r=>{if(r<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],t=0,i=()=>{t--,e.length>0&&e.shift()()},n=(a,l,...c)=>{t++;let u=Kde(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{t<r?n(a,l,...c):e.push(n.bind(null,a,l,...c))},o=(a,...l)=>new Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>t},pendingCount:{get:()=>e.length}}),o};AS.exports=NK;AS.exports.default=NK});var Ep=w((yZe,LK)=>{var Hde="2.0.0",jde=256,Gde=Number.MAX_SAFE_INTEGER||9007199254740991,Yde=16;LK.exports={SEMVER_SPEC_VERSION:Hde,MAX_LENGTH:jde,MAX_SAFE_INTEGER:Gde,MAX_SAFE_COMPONENT_LENGTH:Yde}});var Ip=w((wZe,TK)=>{var qde=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...r)=>console.error("SEMVER",...r):()=>{};TK.exports=qde});var Qc=w((XA,OK)=>{var{MAX_SAFE_COMPONENT_LENGTH:lS}=Ep(),Jde=Ip();XA=OK.exports={};var Wde=XA.re=[],rt=XA.src=[],it=XA.t={},zde=0,kt=(r,e,t)=>{let i=zde++;Jde(i,e),it[r]=i,rt[i]=e,Wde[i]=new RegExp(e,t?"g":void 0)};kt("NUMERICIDENTIFIER","0|[1-9]\\d*");kt("NUMERICIDENTIFIERLOOSE","[0-9]+");kt("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");kt("MAINVERSION",`(${rt[it.NUMERICIDENTIFIER]})\\.(${rt[it.NUMERICIDENTIFIER]})\\.(${rt[it.NUMERICIDENTIFIER]})`);kt("MAINVERSIONLOOSE",`(${rt[it.NUMERICIDENTIFIERLOOSE]})\\.(${rt[it.NUMERICIDENTIFIERLOOSE]})\\.(${rt[it.NUMERICIDENTIFIERLOOSE]})`);kt("PRERELEASEIDENTIFIER",`(?:${rt[it.NUMERICIDENTIFIER]}|${rt[it.NONNUMERICIDENTIFIER]})`);kt("PRERELEASEIDENTIFIERLOOSE",`(?:${rt[it.NUMERICIDENTIFIERLOOSE]}|${rt[it.NONNUMERICIDENTIFIER]})`);kt("PRERELEASE",`(?:-(${rt[it.PRERELEASEIDENTIFIER]}(?:\\.${rt[it.PRERELEASEIDENTIFIER]})*))`);kt("PRERELEASELOOSE",`(?:-?(${rt[it.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${rt[it.PRERELEASEIDENTIFIERLOOSE]})*))`);kt("BUILDIDENTIFIER","[0-9A-Za-z-]+");kt("BUILD",`(?:\\+(${rt[it.BUILDIDENTIFIER]}(?:\\.${rt[it.BUILDIDENTIFIER]})*))`);kt("FULLPLAIN",`v?${rt[it.MAINVERSION]}${rt[it.PRERELEASE]}?${rt[it.BUILD]}?`);kt("FULL",`^${rt[it.FULLPLAIN]}$`);kt("LOOSEPLAIN",`[v=\\s]*${rt[it.MAINVERSIONLOOSE]}${rt[it.PRERELEASELOOSE]}?${rt[it.BUILD]}?`);kt("LOOSE",`^${rt[it.LOOSEPLAIN]}$`);kt("GTLT","((?:<|>)?=?)");kt("XRANGEIDENTIFIERLOOSE",`${rt[it.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);kt("XRANGEIDENTIFIER",`${rt[it.NUMERICIDENTIFIER]}|x|X|\\*`);kt("XRANGEPLAIN",`[v=\\s]*(${rt[it.XRANGEIDENTIFIER]})(?:\\.(${rt[it.XRANGEIDENTIFIER]})(?:\\.(${rt[it.XRANGEIDENTIFIER]})(?:${rt[it.PRERELEASE]})?${rt[it.BUILD]}?)?)?`);kt("XRANGEPLAINLOOSE",`[v=\\s]*(${rt[it.XRANGEIDENTIFIERLOOSE]})(?:\\.(${rt[it.XRANGEIDENTIFIERLOOSE]})(?:\\.(${rt[it.XRANGEIDENTIFIERLOOSE]})(?:${rt[it.PRERELEASELOOSE]})?${rt[it.BUILD]}?)?)?`);kt("XRANGE",`^${rt[it.GTLT]}\\s*${rt[it.XRANGEPLAIN]}$`);kt("XRANGELOOSE",`^${rt[it.GTLT]}\\s*${rt[it.XRANGEPLAINLOOSE]}$`);kt("COERCE",`(^|[^\\d])(\\d{1,${lS}})(?:\\.(\\d{1,${lS}}))?(?:\\.(\\d{1,${lS}}))?(?:$|[^\\d])`);kt("COERCERTL",rt[it.COERCE],!0);kt("LONETILDE","(?:~>?)");kt("TILDETRIM",`(\\s*)${rt[it.LONETILDE]}\\s+`,!0);XA.tildeTrimReplace="$1~";kt("TILDE",`^${rt[it.LONETILDE]}${rt[it.XRANGEPLAIN]}$`);kt("TILDELOOSE",`^${rt[it.LONETILDE]}${rt[it.XRANGEPLAINLOOSE]}$`);kt("LONECARET","(?:\\^)");kt("CARETTRIM",`(\\s*)${rt[it.LONECARET]}\\s+`,!0);XA.caretTrimReplace="$1^";kt("CARET",`^${rt[it.LONECARET]}${rt[it.XRANGEPLAIN]}$`);kt("CARETLOOSE",`^${rt[it.LONECARET]}${rt[it.XRANGEPLAINLOOSE]}$`);kt("COMPARATORLOOSE",`^${rt[it.GTLT]}\\s*(${rt[it.LOOSEPLAIN]})$|^$`);kt("COMPARATOR",`^${rt[it.GTLT]}\\s*(${rt[it.FULLPLAIN]})$|^$`);kt("COMPARATORTRIM",`(\\s*)${rt[it.GTLT]}\\s*(${rt[it.LOOSEPLAIN]}|${rt[it.XRANGEPLAIN]})`,!0);XA.comparatorTrimReplace="$1$2$3";kt("HYPHENRANGE",`^\\s*(${rt[it.XRANGEPLAIN]})\\s+-\\s+(${rt[it.XRANGEPLAIN]})\\s*$`);kt("HYPHENRANGELOOSE",`^\\s*(${rt[it.XRANGEPLAINLOOSE]})\\s+-\\s+(${rt[it.XRANGEPLAINLOOSE]})\\s*$`);kt("STAR","(<|>)?=?\\s*\\*");kt("GTE0","^\\s*>=\\s*0.0.0\\s*$");kt("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var yp=w((BZe,MK)=>{var _de=["includePrerelease","loose","rtl"],Vde=r=>r?typeof r!="object"?{loose:!0}:_de.filter(e=>r[e]).reduce((e,t)=>(e[t]=!0,e),{}):{};MK.exports=Vde});var wI=w((bZe,UK)=>{var KK=/^[0-9]+$/,HK=(r,e)=>{let t=KK.test(r),i=KK.test(e);return t&&i&&(r=+r,e=+e),r===e?0:t&&!i?-1:i&&!t?1:r<e?-1:1},Xde=(r,e)=>HK(e,r);UK.exports={compareIdentifiers:HK,rcompareIdentifiers:Xde}});var Hi=w((QZe,jK)=>{var BI=Ip(),{MAX_LENGTH:GK,MAX_SAFE_INTEGER:bI}=Ep(),{re:YK,t:qK}=Qc(),Zde=yp(),{compareIdentifiers:wp}=wI(),bs=class{constructor(e,t){if(t=Zde(t),e instanceof bs){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>GK)throw new TypeError(`version is longer than ${GK} characters`);BI("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;let i=e.trim().match(t.loose?YK[qK.LOOSE]:YK[qK.FULL]);if(!i)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>bI||this.major<0)throw new TypeError("Invalid major version");if(this.minor>bI||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>bI||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let s=+n;if(s>=0&&s<bI)return s}return n}):this.prerelease=[],this.build=i[5]?i[5].split("."):[],this.format()}format(){return this.version=`${this.major}.${this.minor}.${this.patch}`,this.prerelease.length&&(this.version+=`-${this.prerelease.join(".")}`),this.version}toString(){return this.version}compare(e){if(BI("SemVer.compare",this.version,this.options,e),!(e instanceof bs)){if(typeof e=="string"&&e===this.version)return 0;e=new bs(e,this.options)}return e.version===this.version?0:this.compareMain(e)||this.comparePre(e)}compareMain(e){return e instanceof bs||(e=new bs(e,this.options)),wp(this.major,e.major)||wp(this.minor,e.minor)||wp(this.patch,e.patch)}comparePre(e){if(e instanceof bs||(e=new bs(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;let t=0;do{let i=this.prerelease[t],n=e.prerelease[t];if(BI("prerelease compare",t,i,n),i===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;if(i===n)continue;return wp(i,n)}while(++t)}compareBuild(e){e instanceof bs||(e=new bs(e,this.options));let t=0;do{let i=this.build[t],n=e.build[t];if(BI("prerelease compare",t,i,n),i===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;if(i===n)continue;return wp(i,n)}while(++t)}inc(e,t){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":this.prerelease.length===0&&this.inc("patch",t),this.inc("pre",t);break;case"major":(this.minor!==0||this.patch!==0||this.prerelease.length===0)&&this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":(this.patch!==0||this.prerelease.length===0)&&this.minor++,this.patch=0,this.prerelease=[];break;case"patch":this.prerelease.length===0&&this.patch++,this.prerelease=[];break;case"pre":if(this.prerelease.length===0)this.prerelease=[0];else{let i=this.prerelease.length;for(;--i>=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};jK.exports=bs});var Sc=w((SZe,JK)=>{var{MAX_LENGTH:$de}=Ep(),{re:WK,t:zK}=Qc(),_K=Hi(),eCe=yp(),tCe=(r,e)=>{if(e=eCe(e),r instanceof _K)return r;if(typeof r!="string"||r.length>$de||!(e.loose?WK[zK.LOOSE]:WK[zK.FULL]).test(r))return null;try{return new _K(r,e)}catch(i){return null}};JK.exports=tCe});var XK=w((vZe,VK)=>{var rCe=Sc(),iCe=(r,e)=>{let t=rCe(r,e);return t?t.version:null};VK.exports=iCe});var $K=w((kZe,ZK)=>{var nCe=Sc(),sCe=(r,e)=>{let t=nCe(r.trim().replace(/^[=v]+/,""),e);return t?t.version:null};ZK.exports=sCe});var t2=w((xZe,e2)=>{var oCe=Hi(),aCe=(r,e,t,i)=>{typeof t=="string"&&(i=t,t=void 0);try{return new oCe(r,t).inc(e,i).version}catch(n){return null}};e2.exports=aCe});var Qs=w((PZe,r2)=>{var i2=Hi(),ACe=(r,e,t)=>new i2(r,t).compare(new i2(e,t));r2.exports=ACe});var QI=w((DZe,n2)=>{var lCe=Qs(),cCe=(r,e,t)=>lCe(r,e,t)===0;n2.exports=cCe});var a2=w((RZe,s2)=>{var o2=Sc(),uCe=QI(),gCe=(r,e)=>{if(uCe(r,e))return null;{let t=o2(r),i=o2(e),n=t.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in t)if((a==="major"||a==="minor"||a==="patch")&&t[a]!==i[a])return s+a;return o}};s2.exports=gCe});var l2=w((FZe,A2)=>{var fCe=Hi(),hCe=(r,e)=>new fCe(r,e).major;A2.exports=hCe});var u2=w((NZe,c2)=>{var pCe=Hi(),dCe=(r,e)=>new pCe(r,e).minor;c2.exports=dCe});var f2=w((LZe,g2)=>{var CCe=Hi(),mCe=(r,e)=>new CCe(r,e).patch;g2.exports=mCe});var p2=w((TZe,h2)=>{var ECe=Sc(),ICe=(r,e)=>{let t=ECe(r,e);return t&&t.prerelease.length?t.prerelease:null};h2.exports=ICe});var C2=w((OZe,d2)=>{var yCe=Qs(),wCe=(r,e,t)=>yCe(e,r,t);d2.exports=wCe});var E2=w((MZe,m2)=>{var BCe=Qs(),bCe=(r,e)=>BCe(r,e,!0);m2.exports=bCe});var SI=w((UZe,I2)=>{var y2=Hi(),QCe=(r,e,t)=>{let i=new y2(r,t),n=new y2(e,t);return i.compare(n)||i.compareBuild(n)};I2.exports=QCe});var B2=w((KZe,w2)=>{var SCe=SI(),vCe=(r,e)=>r.sort((t,i)=>SCe(t,i,e));w2.exports=vCe});var Q2=w((HZe,b2)=>{var kCe=SI(),xCe=(r,e)=>r.sort((t,i)=>kCe(i,t,e));b2.exports=xCe});var Bp=w((jZe,S2)=>{var PCe=Qs(),DCe=(r,e,t)=>PCe(r,e,t)>0;S2.exports=DCe});var vI=w((GZe,v2)=>{var RCe=Qs(),FCe=(r,e,t)=>RCe(r,e,t)<0;v2.exports=FCe});var cS=w((YZe,k2)=>{var NCe=Qs(),LCe=(r,e,t)=>NCe(r,e,t)!==0;k2.exports=LCe});var kI=w((qZe,x2)=>{var TCe=Qs(),OCe=(r,e,t)=>TCe(r,e,t)>=0;x2.exports=OCe});var xI=w((JZe,P2)=>{var MCe=Qs(),UCe=(r,e,t)=>MCe(r,e,t)<=0;P2.exports=UCe});var uS=w((WZe,D2)=>{var KCe=QI(),HCe=cS(),jCe=Bp(),GCe=kI(),YCe=vI(),qCe=xI(),JCe=(r,e,t,i)=>{switch(e){case"===":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r===t;case"!==":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r!==t;case"":case"=":case"==":return KCe(r,t,i);case"!=":return HCe(r,t,i);case">":return jCe(r,t,i);case">=":return GCe(r,t,i);case"<":return YCe(r,t,i);case"<=":return qCe(r,t,i);default:throw new TypeError(`Invalid operator: ${e}`)}};D2.exports=JCe});var F2=w((zZe,R2)=>{var WCe=Hi(),zCe=Sc(),{re:PI,t:DI}=Qc(),_Ce=(r,e)=>{if(r instanceof WCe)return r;if(typeof r=="number"&&(r=String(r)),typeof r!="string")return null;e=e||{};let t=null;if(!e.rtl)t=r.match(PI[DI.COERCE]);else{let i;for(;(i=PI[DI.COERCERTL].exec(r))&&(!t||t.index+t[0].length!==r.length);)(!t||i.index+i[0].length!==t.index+t[0].length)&&(t=i),PI[DI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;PI[DI.COERCERTL].lastIndex=-1}return t===null?null:zCe(`${t[2]}.${t[3]||"0"}.${t[4]||"0"}`,e)};R2.exports=_Ce});var L2=w((_Ze,N2)=>{"use strict";N2.exports=function(r){r.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var bp=w((VZe,T2)=>{"use strict";T2.exports=Gt;Gt.Node=vc;Gt.create=Gt;function Gt(r){var e=this;if(e instanceof Gt||(e=new Gt),e.tail=null,e.head=null,e.length=0,r&&typeof r.forEach=="function")r.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var t=0,i=arguments.length;t<i;t++)e.push(arguments[t]);return e}Gt.prototype.removeNode=function(r){if(r.list!==this)throw new Error("removing node which does not belong to this list");var e=r.next,t=r.prev;return e&&(e.prev=t),t&&(t.next=e),r===this.head&&(this.head=e),r===this.tail&&(this.tail=t),r.list.length--,r.next=null,r.prev=null,r.list=null,e};Gt.prototype.unshiftNode=function(r){if(r!==this.head){r.list&&r.list.removeNode(r);var e=this.head;r.list=this,r.next=e,e&&(e.prev=r),this.head=r,this.tail||(this.tail=r),this.length++}};Gt.prototype.pushNode=function(r){if(r!==this.tail){r.list&&r.list.removeNode(r);var e=this.tail;r.list=this,r.prev=e,e&&(e.next=r),this.tail=r,this.head||(this.head=r),this.length++}};Gt.prototype.push=function(){for(var r=0,e=arguments.length;r<e;r++)VCe(this,arguments[r]);return this.length};Gt.prototype.unshift=function(){for(var r=0,e=arguments.length;r<e;r++)XCe(this,arguments[r]);return this.length};Gt.prototype.pop=function(){if(!!this.tail){var r=this.tail.value;return this.tail=this.tail.prev,this.tail?this.tail.next=null:this.head=null,this.length--,r}};Gt.prototype.shift=function(){if(!!this.head){var r=this.head.value;return this.head=this.head.next,this.head?this.head.prev=null:this.tail=null,this.length--,r}};Gt.prototype.forEach=function(r,e){e=e||this;for(var t=this.head,i=0;t!==null;i++)r.call(e,t.value,i,this),t=t.next};Gt.prototype.forEachReverse=function(r,e){e=e||this;for(var t=this.tail,i=this.length-1;t!==null;i--)r.call(e,t.value,i,this),t=t.prev};Gt.prototype.get=function(r){for(var e=0,t=this.head;t!==null&&e<r;e++)t=t.next;if(e===r&&t!==null)return t.value};Gt.prototype.getReverse=function(r){for(var e=0,t=this.tail;t!==null&&e<r;e++)t=t.prev;if(e===r&&t!==null)return t.value};Gt.prototype.map=function(r,e){e=e||this;for(var t=new Gt,i=this.head;i!==null;)t.push(r.call(e,i.value,this)),i=i.next;return t};Gt.prototype.mapReverse=function(r,e){e=e||this;for(var t=new Gt,i=this.tail;i!==null;)t.push(r.call(e,i.value,this)),i=i.prev;return t};Gt.prototype.reduce=function(r,e){var t,i=this.head;if(arguments.length>1)t=e;else if(this.head)i=this.head.next,t=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)t=r(t,i.value,n),i=i.next;return t};Gt.prototype.reduceReverse=function(r,e){var t,i=this.tail;if(arguments.length>1)t=e;else if(this.tail)i=this.tail.prev,t=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)t=r(t,i.value,n),i=i.prev;return t};Gt.prototype.toArray=function(){for(var r=new Array(this.length),e=0,t=this.head;t!==null;e++)r[e]=t.value,t=t.next;return r};Gt.prototype.toArrayReverse=function(){for(var r=new Array(this.length),e=0,t=this.tail;t!==null;e++)r[e]=t.value,t=t.prev;return r};Gt.prototype.slice=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Gt;if(e<r||e<0)return t;r<0&&(r=0),e>this.length&&(e=this.length);for(var i=0,n=this.head;n!==null&&i<r;i++)n=n.next;for(;n!==null&&i<e;i++,n=n.next)t.push(n.value);return t};Gt.prototype.sliceReverse=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Gt;if(e<r||e<0)return t;r<0&&(r=0),e>this.length&&(e=this.length);for(var i=this.length,n=this.tail;n!==null&&i>e;i--)n=n.prev;for(;n!==null&&i>r;i--,n=n.prev)t.push(n.value);return t};Gt.prototype.splice=function(r,e,...t){r>this.length&&(r=this.length-1),r<0&&(r=this.length+r);for(var i=0,n=this.head;n!==null&&i<r;i++)n=n.next;for(var s=[],i=0;n&&i<e;i++)s.push(n.value),n=this.removeNode(n);n===null&&(n=this.tail),n!==this.head&&n!==this.tail&&(n=n.prev);for(var i=0;i<t.length;i++)n=ZCe(this,n,t[i]);return s};Gt.prototype.reverse=function(){for(var r=this.head,e=this.tail,t=r;t!==null;t=t.prev){var i=t.prev;t.prev=t.next,t.next=i}return this.head=e,this.tail=r,this};function ZCe(r,e,t){var i=e===r.head?new vc(t,null,e,r):new vc(t,e,e.next,r);return i.next===null&&(r.tail=i),i.prev===null&&(r.head=i),r.length++,i}function VCe(r,e){r.tail=new vc(e,r.tail,null,r),r.head||(r.head=r.tail),r.length++}function XCe(r,e){r.head=new vc(e,null,r.head,r),r.tail||(r.tail=r.head),r.length++}function vc(r,e,t,i){if(!(this instanceof vc))return new vc(r,e,t,i);this.list=i,this.value=r,e?(e.next=this,this.prev=e):this.prev=null,t?(t.prev=this,this.next=t):this.next=null}try{L2()(Gt)}catch(r){}});var G2=w((XZe,O2)=>{"use strict";var $Ce=bp(),kc=Symbol("max"),Ha=Symbol("length"),hg=Symbol("lengthCalculator"),Qp=Symbol("allowStale"),xc=Symbol("maxAge"),ja=Symbol("dispose"),M2=Symbol("noDisposeOnSet"),yi=Symbol("lruList"),Ao=Symbol("cache"),U2=Symbol("updateAgeOnGet"),gS=()=>1,K2=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let t=this[kc]=e.max||Infinity,i=e.length||gS;if(this[hg]=typeof i!="function"?gS:i,this[Qp]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[xc]=e.maxAge||0,this[ja]=e.dispose,this[M2]=e.noDisposeOnSet||!1,this[U2]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[kc]=e||Infinity,Sp(this)}get max(){return this[kc]}set allowStale(e){this[Qp]=!!e}get allowStale(){return this[Qp]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[xc]=e,Sp(this)}get maxAge(){return this[xc]}set lengthCalculator(e){typeof e!="function"&&(e=gS),e!==this[hg]&&(this[hg]=e,this[Ha]=0,this[yi].forEach(t=>{t.length=this[hg](t.value,t.key),this[Ha]+=t.length})),Sp(this)}get lengthCalculator(){return this[hg]}get length(){return this[Ha]}get itemCount(){return this[yi].length}rforEach(e,t){t=t||this;for(let i=this[yi].tail;i!==null;){let n=i.prev;j2(this,e,i,t),i=n}}forEach(e,t){t=t||this;for(let i=this[yi].head;i!==null;){let n=i.next;j2(this,e,i,t),i=n}}keys(){return this[yi].toArray().map(e=>e.key)}values(){return this[yi].toArray().map(e=>e.value)}reset(){this[ja]&&this[yi]&&this[yi].length&&this[yi].forEach(e=>this[ja](e.key,e.value)),this[Ao]=new Map,this[yi]=new $Ce,this[Ha]=0}dump(){return this[yi].map(e=>RI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[yi]}set(e,t,i){if(i=i||this[xc],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[hg](t,e);if(this[Ao].has(e)){if(s>this[kc])return pg(this,this[Ao].get(e)),!1;let l=this[Ao].get(e).value;return this[ja]&&(this[M2]||this[ja](e,l.value)),l.now=n,l.maxAge=i,l.value=t,this[Ha]+=s-l.length,l.length=s,this.get(e),Sp(this),!0}let o=new H2(e,t,s,n,i);return o.length>this[kc]?(this[ja]&&this[ja](e,t),!1):(this[Ha]+=o.length,this[yi].unshift(o),this[Ao].set(e,this[yi].head),Sp(this),!0)}has(e){if(!this[Ao].has(e))return!1;let t=this[Ao].get(e).value;return!RI(this,t)}get(e){return fS(this,e,!0)}peek(e){return fS(this,e,!1)}pop(){let e=this[yi].tail;return e?(pg(this,e),e.value):null}del(e){pg(this,this[Ao].get(e))}load(e){this.reset();let t=Date.now();for(let i=e.length-1;i>=0;i--){let n=e[i],s=n.e||0;if(s===0)this.set(n.k,n.v);else{let o=s-t;o>0&&this.set(n.k,n.v,o)}}}prune(){this[Ao].forEach((e,t)=>fS(this,t,!1))}},fS=(r,e,t)=>{let i=r[Ao].get(e);if(i){let n=i.value;if(RI(r,n)){if(pg(r,i),!r[Qp])return}else t&&(r[U2]&&(i.value.now=Date.now()),r[yi].unshiftNode(i));return n.value}},RI=(r,e)=>{if(!e||!e.maxAge&&!r[xc])return!1;let t=Date.now()-e.now;return e.maxAge?t>e.maxAge:r[xc]&&t>r[xc]},Sp=r=>{if(r[Ha]>r[kc])for(let e=r[yi].tail;r[Ha]>r[kc]&&e!==null;){let t=e.prev;pg(r,e),e=t}},pg=(r,e)=>{if(e){let t=e.value;r[ja]&&r[ja](t.key,t.value),r[Ha]-=t.length,r[Ao].delete(t.key),r[yi].removeNode(e)}},H2=class{constructor(e,t,i,n,s){this.key=e,this.value=t,this.length=i,this.now=n,this.maxAge=s||0}},j2=(r,e,t,i)=>{let n=t.value;RI(r,n)&&(pg(r,t),r[Qp]||(n=void 0)),n&&e.call(i,n.value,n.key,r)};O2.exports=K2});var Ss=w((ZZe,Y2)=>{var dg=class{constructor(e,t){if(t=eme(t),e instanceof dg)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new dg(e.raw,t);if(e instanceof hS)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(i=>this.parseRange(i.trim())).filter(i=>i.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let i=this.set[0];if(this.set=this.set.filter(n=>!J2(n[0])),this.set.length===0)this.set=[i];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&sme(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let i=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=q2.get(i);if(n)return n;let s=this.options.loose,o=s?ji[xi.HYPHENRANGELOOSE]:ji[xi.HYPHENRANGE];e=e.replace(o,Ame(this.options.includePrerelease)),zr("hyphen replace",e),e=e.replace(ji[xi.COMPARATORTRIM],rme),zr("comparator trim",e,ji[xi.COMPARATORTRIM]),e=e.replace(ji[xi.TILDETRIM],ime),e=e.replace(ji[xi.CARETTRIM],nme),e=e.split(/\s+/).join(" ");let a=s?ji[xi.COMPARATORLOOSE]:ji[xi.COMPARATOR],l=e.split(" ").map(f=>ome(f,this.options)).join(" ").split(/\s+/).map(f=>ame(f,this.options)).filter(this.options.loose?f=>!!f.match(a):()=>!0).map(f=>new hS(f,this.options)),c=l.length,u=new Map;for(let f of l){if(J2(f))return[f];u.set(f.value,f)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return q2.set(i,g),g}intersects(e,t){if(!(e instanceof dg))throw new TypeError("a Range is required");return this.set.some(i=>W2(i,t)&&e.set.some(n=>W2(n,t)&&i.every(s=>n.every(o=>s.intersects(o,t)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new tme(e,this.options)}catch(t){return!1}for(let t=0;t<this.set.length;t++)if(lme(this.set[t],e,this.options))return!0;return!1}};Y2.exports=dg;var cme=G2(),q2=new cme({max:1e3}),eme=yp(),hS=vp(),zr=Ip(),tme=Hi(),{re:ji,t:xi,comparatorTrimReplace:rme,tildeTrimReplace:ime,caretTrimReplace:nme}=Qc(),J2=r=>r.value==="<0.0.0-0",sme=r=>r.value==="",W2=(r,e)=>{let t=!0,i=r.slice(),n=i.pop();for(;t&&i.length;)t=i.every(s=>n.intersects(s,e)),n=i.pop();return t},ome=(r,e)=>(zr("comp",r,e),r=gme(r,e),zr("caret",r),r=ume(r,e),zr("tildes",r),r=fme(r,e),zr("xrange",r),r=hme(r,e),zr("stars",r),r),on=r=>!r||r.toLowerCase()==="x"||r==="*",ume=(r,e)=>r.trim().split(/\s+/).map(t=>pme(t,e)).join(" "),pme=(r,e)=>{let t=e.loose?ji[xi.TILDELOOSE]:ji[xi.TILDE];return r.replace(t,(i,n,s,o,a)=>{zr("tilde",r,i,n,s,o,a);let l;return on(n)?l="":on(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:on(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(zr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,zr("tilde return",l),l})},gme=(r,e)=>r.trim().split(/\s+/).map(t=>dme(t,e)).join(" "),dme=(r,e)=>{zr("caret",r,e);let t=e.loose?ji[xi.CARETLOOSE]:ji[xi.CARET],i=e.includePrerelease?"-0":"";return r.replace(t,(n,s,o,a,l)=>{zr("caret",r,n,s,o,a,l);let c;return on(s)?c="":on(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:on(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(zr("replaceCaret pr",l),s==="0"?o==="0"?c=`>=${s}.${o}.${a}-${l} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}-${l} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a}-${l} <${+s+1}.0.0-0`):(zr("no pr"),s==="0"?o==="0"?c=`>=${s}.${o}.${a}${i} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a} <${+s+1}.0.0-0`),zr("caret return",c),c})},fme=(r,e)=>(zr("replaceXRanges",r,e),r.split(/\s+/).map(t=>Cme(t,e)).join(" ")),Cme=(r,e)=>{r=r.trim();let t=e.loose?ji[xi.XRANGELOOSE]:ji[xi.XRANGE];return r.replace(t,(i,n,s,o,a,l)=>{zr("xRange",r,i,n,s,o,a,l);let c=on(s),u=c||on(o),g=u||on(a),f=g;return n==="="&&f&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?i="<0.0.0-0":i="*":n&&f?(u&&(o=0),a=0,n===">"?(n=">=",u?(s=+s+1,o=0,a=0):(o=+o+1,a=0)):n==="<="&&(n="<",u?s=+s+1:o=+o+1),n==="<"&&(l="-0"),i=`${n+s}.${o}.${a}${l}`):u?i=`>=${s}.0.0${l} <${+s+1}.0.0-0`:g&&(i=`>=${s}.${o}.0${l} <${s}.${+o+1}.0-0`),zr("xRange return",i),i})},hme=(r,e)=>(zr("replaceStars",r,e),r.trim().replace(ji[xi.STAR],"")),ame=(r,e)=>(zr("replaceGTE0",r,e),r.trim().replace(ji[e.includePrerelease?xi.GTE0PRE:xi.GTE0],"")),Ame=r=>(e,t,i,n,s,o,a,l,c,u,g,f,h)=>(on(i)?t="":on(n)?t=`>=${i}.0.0${r?"-0":""}`:on(s)?t=`>=${i}.${n}.0${r?"-0":""}`:o?t=`>=${t}`:t=`>=${t}${r?"-0":""}`,on(c)?l="":on(u)?l=`<${+c+1}.0.0-0`:on(g)?l=`<${c}.${+u+1}.0-0`:f?l=`<=${c}.${u}.${g}-${f}`:r?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${t} ${l}`.trim()),lme=(r,e,t)=>{for(let i=0;i<r.length;i++)if(!r[i].test(e))return!1;if(e.prerelease.length&&!t.includePrerelease){for(let i=0;i<r.length;i++)if(zr(r[i].semver),r[i].semver!==hS.ANY&&r[i].semver.prerelease.length>0){let n=r[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var vp=w(($Ze,z2)=>{var kp=Symbol("SemVer ANY"),xp=class{static get ANY(){return kp}constructor(e,t){if(t=mme(t),e instanceof xp){if(e.loose===!!t.loose)return e;e=e.value}dS("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===kp?this.value="":this.value=this.operator+this.semver.version,dS("comp",this)}parse(e){let t=this.options.loose?_2[V2.COMPARATORLOOSE]:_2[V2.COMPARATOR],i=e.match(t);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=i[1]!==void 0?i[1]:"",this.operator==="="&&(this.operator=""),i[2]?this.semver=new X2(i[2],this.options.loose):this.semver=kp}toString(){return this.value}test(e){if(dS("Comparator.test",e,this.options.loose),this.semver===kp||e===kp)return!0;if(typeof e=="string")try{e=new X2(e,this.options)}catch(t){return!1}return pS(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof xp))throw new TypeError("a Comparator is required");if((!t||typeof t!="object")&&(t={loose:!!t,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new Z2(e.value,t).test(this.value);if(e.operator==="")return e.value===""?!0:new Z2(this.value,t).test(e.semver);let i=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),s=this.semver.version===e.semver.version,o=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=pS(this.semver,"<",e.semver,t)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=pS(this.semver,">",e.semver,t)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};z2.exports=xp;var mme=yp(),{re:_2,t:V2}=Qc(),pS=uS(),dS=Ip(),X2=Hi(),Z2=Ss()});var Pp=w((e$e,$2)=>{var Eme=Ss(),Ime=(r,e,t)=>{try{e=new Eme(e,t)}catch(i){return!1}return e.test(r)};$2.exports=Ime});var tH=w((t$e,eH)=>{var yme=Ss(),wme=(r,e)=>new yme(r,e).set.map(t=>t.map(i=>i.value).join(" ").trim().split(" "));eH.exports=wme});var iH=w((r$e,rH)=>{var Bme=Hi(),bme=Ss(),Qme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new bme(e,t)}catch(o){return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new Bme(i,t))}),i};rH.exports=Qme});var sH=w((i$e,nH)=>{var Sme=Hi(),vme=Ss(),kme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new vme(e,t)}catch(o){return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new Sme(i,t))}),i};nH.exports=kme});var AH=w((n$e,oH)=>{var CS=Hi(),xme=Ss(),aH=Bp(),Pme=(r,e)=>{r=new xme(r,e);let t=new CS("0.0.0");if(r.test(t)||(t=new CS("0.0.0-0"),r.test(t)))return t;t=null;for(let i=0;i<r.set.length;++i){let n=r.set[i],s=null;n.forEach(o=>{let a=new CS(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||aH(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!t||aH(t,s))&&(t=s)}return t&&r.test(t)?t:null};oH.exports=Pme});var cH=w((s$e,lH)=>{var Dme=Ss(),Rme=(r,e)=>{try{return new Dme(r,e).range||"*"}catch(t){return null}};lH.exports=Rme});var FI=w((o$e,uH)=>{var Fme=Hi(),gH=vp(),{ANY:Nme}=gH,Lme=Ss(),Tme=Pp(),fH=Bp(),hH=vI(),Ome=xI(),Mme=kI(),Ume=(r,e,t,i)=>{r=new Fme(r,i),e=new Lme(e,i);let n,s,o,a,l;switch(t){case">":n=fH,s=Ome,o=hH,a=">",l=">=";break;case"<":n=hH,s=Mme,o=fH,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(Tme(r,e,i))return!1;for(let c=0;c<e.set.length;++c){let u=e.set[c],g=null,f=null;if(u.forEach(h=>{h.semver===Nme&&(h=new gH(">=0.0.0")),g=g||h,f=f||h,n(h.semver,g.semver,i)?g=h:o(h.semver,f.semver,i)&&(f=h)}),g.operator===a||g.operator===l||(!f.operator||f.operator===a)&&s(r,f.semver))return!1;if(f.operator===l&&o(r,f.semver))return!1}return!0};uH.exports=Ume});var dH=w((a$e,pH)=>{var Kme=FI(),Hme=(r,e,t)=>Kme(r,e,">",t);pH.exports=Hme});var mH=w((A$e,CH)=>{var jme=FI(),Gme=(r,e,t)=>jme(r,e,"<",t);CH.exports=Gme});var yH=w((l$e,EH)=>{var IH=Ss(),Yme=(r,e,t)=>(r=new IH(r,t),e=new IH(e,t),r.intersects(e));EH.exports=Yme});var BH=w((c$e,wH)=>{var qme=Pp(),Jme=Qs();wH.exports=(r,e,t)=>{let i=[],n=null,s=null,o=r.sort((u,g)=>Jme(u,g,t));for(let u of o)qme(u,e,t)?(s=u,n||(n=u)):(s&&i.push([n,s]),s=null,n=null);n&&i.push([n,null]);let a=[];for(let[u,g]of i)u===g?a.push(u):!g&&u===o[0]?a.push("*"):g?u===o[0]?a.push(`<=${g}`):a.push(`${u} - ${g}`):a.push(`>=${u}`);let l=a.join(" || "),c=typeof e.raw=="string"?e.raw:String(e);return l.length<c.length?l:e}});var kH=w((u$e,bH)=>{var QH=Ss(),NI=vp(),{ANY:mS}=NI,Dp=Pp(),ES=Qs(),zme=(r,e,t={})=>{if(r===e)return!0;r=new QH(r,t),e=new QH(e,t);let i=!1;e:for(let n of r.set){for(let s of e.set){let o=Wme(n,s,t);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},Wme=(r,e,t)=>{if(r===e)return!0;if(r.length===1&&r[0].semver===mS){if(e.length===1&&e[0].semver===mS)return!0;t.includePrerelease?r=[new NI(">=0.0.0-0")]:r=[new NI(">=0.0.0")]}if(e.length===1&&e[0].semver===mS){if(t.includePrerelease)return!0;e=[new NI(">=0.0.0")]}let i=new Set,n,s;for(let h of r)h.operator===">"||h.operator===">="?n=SH(n,h,t):h.operator==="<"||h.operator==="<="?s=vH(s,h,t):i.add(h.semver);if(i.size>1)return null;let o;if(n&&s){if(o=ES(n.semver,s.semver,t),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let h of i){if(n&&!Dp(h,String(n),t)||s&&!Dp(h,String(s),t))return null;for(let p of e)if(!Dp(h,String(p),t))return!1;return!0}let a,l,c,u,g=s&&!t.includePrerelease&&s.semver.prerelease.length?s.semver:!1,f=n&&!t.includePrerelease&&n.semver.prerelease.length?n.semver:!1;g&&g.prerelease.length===1&&s.operator==="<"&&g.prerelease[0]===0&&(g=!1);for(let h of e){if(u=u||h.operator===">"||h.operator===">=",c=c||h.operator==="<"||h.operator==="<=",n){if(f&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===f.major&&h.semver.minor===f.minor&&h.semver.patch===f.patch&&(f=!1),h.operator===">"||h.operator===">="){if(a=SH(n,h,t),a===h&&a!==n)return!1}else if(n.operator===">="&&!Dp(n.semver,String(h),t))return!1}if(s){if(g&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===g.major&&h.semver.minor===g.minor&&h.semver.patch===g.patch&&(g=!1),h.operator==="<"||h.operator==="<="){if(l=vH(s,h,t),l===h&&l!==s)return!1}else if(s.operator==="<="&&!Dp(s.semver,String(h),t))return!1}if(!h.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||f||g)},SH=(r,e,t)=>{if(!r)return e;let i=ES(r.semver,e.semver,t);return i>0?r:i<0||e.operator===">"&&r.operator===">="?e:r},vH=(r,e,t)=>{if(!r)return e;let i=ES(r.semver,e.semver,t);return i<0?r:i>0||e.operator==="<"&&r.operator==="<="?e:r};bH.exports=zme});var ri=w((g$e,xH)=>{var IS=Qc();xH.exports={re:IS.re,src:IS.src,tokens:IS.t,SEMVER_SPEC_VERSION:Ep().SEMVER_SPEC_VERSION,SemVer:Hi(),compareIdentifiers:wI().compareIdentifiers,rcompareIdentifiers:wI().rcompareIdentifiers,parse:Sc(),valid:XK(),clean:$K(),inc:t2(),diff:a2(),major:l2(),minor:u2(),patch:f2(),prerelease:p2(),compare:Qs(),rcompare:C2(),compareLoose:E2(),compareBuild:SI(),sort:B2(),rsort:Q2(),gt:Bp(),lt:vI(),eq:QI(),neq:cS(),gte:kI(),lte:xI(),cmp:uS(),coerce:F2(),Comparator:vp(),Range:Ss(),satisfies:Pp(),toComparators:tH(),maxSatisfying:iH(),minSatisfying:sH(),minVersion:AH(),validRange:cH(),outside:FI(),gtr:dH(),ltr:mH(),intersects:yH(),simplifyRange:BH(),subset:kH()}});var yS=w(LI=>{"use strict";Object.defineProperty(LI,"__esModule",{value:!0});LI.VERSION=void 0;LI.VERSION="9.1.0"});var Yt=w((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(r,e,t){if(t||arguments.length===2)for(var i=0,n=e.length,s;i<n;i++)(s||!(i in e))&&(s||(s=Array.prototype.slice.call(e,0,i)),s[i]=e[i]);return r.concat(s||Array.prototype.slice.call(e))};Object.defineProperty(exports,"__esModule",{value:!0});exports.toFastProperties=exports.timer=exports.peek=exports.isES2015MapSupported=exports.PRINT_WARNING=exports.PRINT_ERROR=exports.packArray=exports.IDENTITY=exports.NOOP=exports.merge=exports.groupBy=exports.defaults=exports.assignNoOverwrite=exports.assign=exports.zipObject=exports.sortBy=exports.indexOf=exports.some=exports.difference=exports.every=exports.isObject=exports.isRegExp=exports.isArray=exports.partial=exports.uniq=exports.compact=exports.reduce=exports.findAll=exports.find=exports.cloneObj=exports.cloneArr=exports.contains=exports.has=exports.pick=exports.reject=exports.filter=exports.dropRight=exports.drop=exports.isFunction=exports.isUndefined=exports.isString=exports.forEach=exports.last=exports.first=exports.flatten=exports.map=exports.mapValues=exports.values=exports.keys=exports.isEmpty=void 0;exports.upperFirst=void 0;function isEmpty(r){return r&&r.length===0}exports.isEmpty=isEmpty;function keys(r){return r==null?[]:Object.keys(r)}exports.keys=keys;function values(r){for(var e=[],t=Object.keys(r),i=0;i<t.length;i++)e.push(r[t[i]]);return e}exports.values=values;function mapValues(r,e){for(var t=[],i=keys(r),n=0;n<i.length;n++){var s=i[n];t.push(e.call(null,r[s],s))}return t}exports.mapValues=mapValues;function map(r,e){for(var t=[],i=0;i<r.length;i++)t.push(e.call(null,r[i],i));return t}exports.map=map;function flatten(r){for(var e=[],t=0;t<r.length;t++){var i=r[t];Array.isArray(i)?e=e.concat(flatten(i)):e.push(i)}return e}exports.flatten=flatten;function first(r){return isEmpty(r)?void 0:r[0]}exports.first=first;function last(r){var e=r&&r.length;return e?r[e-1]:void 0}exports.last=last;function forEach(r,e){if(Array.isArray(r))for(var t=0;t<r.length;t++)e.call(null,r[t],t);else if(isObject(r))for(var i=keys(r),t=0;t<i.length;t++){var n=i[t],s=r[n];e.call(null,s,n)}else throw Error("non exhaustive match")}exports.forEach=forEach;function isString(r){return typeof r=="string"}exports.isString=isString;function isUndefined(r){return r===void 0}exports.isUndefined=isUndefined;function isFunction(r){return r instanceof Function}exports.isFunction=isFunction;function drop(r,e){return e===void 0&&(e=1),r.slice(e,r.length)}exports.drop=drop;function dropRight(r,e){return e===void 0&&(e=1),r.slice(0,r.length-e)}exports.dropRight=dropRight;function filter(r,e){var t=[];if(Array.isArray(r))for(var i=0;i<r.length;i++){var n=r[i];e.call(null,n)&&t.push(n)}return t}exports.filter=filter;function reject(r,e){return filter(r,function(t){return!e(t)})}exports.reject=reject;function pick(r,e){for(var t=Object.keys(r),i={},n=0;n<t.length;n++){var s=t[n],o=r[s];e(o)&&(i[s]=o)}return i}exports.pick=pick;function has(r,e){return isObject(r)?r.hasOwnProperty(e):!1}exports.has=has;function contains(r,e){return find(r,function(t){return t===e})!==void 0}exports.contains=contains;function cloneArr(r){for(var e=[],t=0;t<r.length;t++)e.push(r[t]);return e}exports.cloneArr=cloneArr;function cloneObj(r){var e={};for(var t in r)Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=r[t]);return e}exports.cloneObj=cloneObj;function find(r,e){for(var t=0;t<r.length;t++){var i=r[t];if(e.call(null,i))return i}}exports.find=find;function findAll(r,e){for(var t=[],i=0;i<r.length;i++){var n=r[i];e.call(null,n)&&t.push(n)}return t}exports.findAll=findAll;function reduce(r,e,t){for(var i=Array.isArray(r),n=i?r:values(r),s=i?[]:keys(r),o=t,a=0;a<n.length;a++)o=e.call(null,o,n[a],i?a:s[a]);return o}exports.reduce=reduce;function compact(r){return reject(r,function(e){return e==null})}exports.compact=compact;function uniq(r,e){e===void 0&&(e=function(i){return i});var t=[];return reduce(r,function(i,n){var s=e(n);return contains(t,s)?i:(t.push(s),i.concat(n))},[])}exports.uniq=uniq;function partial(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];var i=[null],n=i.concat(e);return Function.bind.apply(r,n)}exports.partial=partial;function isArray(r){return Array.isArray(r)}exports.isArray=isArray;function isRegExp(r){return r instanceof RegExp}exports.isRegExp=isRegExp;function isObject(r){return r instanceof Object}exports.isObject=isObject;function every(r,e){for(var t=0;t<r.length;t++)if(!e(r[t],t))return!1;return!0}exports.every=every;function difference(r,e){return reject(r,function(t){return contains(e,t)})}exports.difference=difference;function some(r,e){for(var t=0;t<r.length;t++)if(e(r[t]))return!0;return!1}exports.some=some;function indexOf(r,e){for(var t=0;t<r.length;t++)if(r[t]===e)return t;return-1}exports.indexOf=indexOf;function sortBy(r,e){var t=cloneArr(r);return t.sort(function(i,n){return e(i)-e(n)}),t}exports.sortBy=sortBy;function zipObject(r,e){if(r.length!==e.length)throw Error("can't zipObject with different number of keys and values!");for(var t={},i=0;i<r.length;i++)t[r[i]]=e[i];return t}exports.zipObject=zipObject;function assign(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];for(var i=0;i<e.length;i++)for(var n=e[i],s=keys(n),o=0;o<s.length;o++){var a=s[o];r[a]=n[a]}return r}exports.assign=assign;function assignNoOverwrite(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];for(var i=0;i<e.length;i++)for(var n=e[i],s=keys(n),o=0;o<s.length;o++){var a=s[o];has(r,a)||(r[a]=n[a])}return r}exports.assignNoOverwrite=assignNoOverwrite;function defaults(){for(var r=[],e=0;e<arguments.length;e++)r[e]=arguments[e];return assignNoOverwrite.apply(void 0,__spreadArray([{}],r,!1))}exports.defaults=defaults;function groupBy(r,e){var t={};return forEach(r,function(i){var n=e(i),s=t[n];s?s.push(i):t[n]=[i]}),t}exports.groupBy=groupBy;function merge(r,e){for(var t=cloneObj(r),i=keys(e),n=0;n<i.length;n++){var s=i[n],o=e[s];t[s]=o}return t}exports.merge=merge;function NOOP(){}exports.NOOP=NOOP;function IDENTITY(r){return r}exports.IDENTITY=IDENTITY;function packArray(r){for(var e=[],t=0;t<r.length;t++){var i=r[t];e.push(i!==void 0?i:void 0)}return e}exports.packArray=packArray;function PRINT_ERROR(r){console&&console.error&&console.error("Error: "+r)}exports.PRINT_ERROR=PRINT_ERROR;function PRINT_WARNING(r){console&&console.warn&&console.warn("Warning: "+r)}exports.PRINT_WARNING=PRINT_WARNING;function isES2015MapSupported(){return typeof Map=="function"}exports.isES2015MapSupported=isES2015MapSupported;function peek(r){return r[r.length-1]}exports.peek=peek;function timer(r){var e=new Date().getTime(),t=r(),i=new Date().getTime(),n=i-e;return{time:n,value:t}}exports.timer=timer;function toFastProperties(toBecomeFast){function FakeConstructor(){}FakeConstructor.prototype=toBecomeFast;var fakeInstance=new FakeConstructor;function fakeAccess(){return typeof fakeInstance.bar}return fakeAccess(),fakeAccess(),toBecomeFast;eval(toBecomeFast)}exports.toFastProperties=toFastProperties;function upperFirst(r){if(!r)return r;var e=getCharacterFromCodePointAt(r,0);return e.toUpperCase()+r.substring(e.length)}exports.upperFirst=upperFirst;var surrogatePairPattern=/[\uD800-\uDBFF][\uDC00-\uDFFF]/;function getCharacterFromCodePointAt(r,e){var t=r.substring(e,e+1);return surrogatePairPattern.test(t)?t:r[e]}});var OI=w((PH,TI)=>{(function(r,e){typeof define=="function"&&define.amd?define([],e):typeof TI=="object"&&TI.exports?TI.exports=e():r.regexpToAst=e()})(typeof self!="undefined"?self:PH,function(){function r(){}r.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},r.prototype.restoreState=function(p){this.idx=p.idx,this.input=p.input,this.groupIdx=p.groupIdx},r.prototype.pattern=function(p){this.idx=0,this.input=p,this.groupIdx=0,this.consumeChar("/");var m=this.disjunction();this.consumeChar("/");for(var y={type:"Flags",loc:{begin:this.idx,end:p.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":o(y,"global");break;case"i":o(y,"ignoreCase");break;case"m":o(y,"multiLine");break;case"u":o(y,"unicode");break;case"y":o(y,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:y,value:m,loc:this.loc(0)}},r.prototype.disjunction=function(){var p=[],m=this.idx;for(p.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),p.push(this.alternative());return{type:"Disjunction",value:p,loc:this.loc(m)}},r.prototype.alternative=function(){for(var p=[],m=this.idx;this.isTerm();)p.push(this.term());return{type:"Alternative",value:p,loc:this.loc(m)}},r.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},r.prototype.assertion=function(){var p=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(p)};case"$":return{type:"EndAnchor",loc:this.loc(p)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(p)};case"B":return{type:"NonWordBoundary",loc:this.loc(p)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");var m;switch(this.popChar()){case"=":m="Lookahead";break;case"!":m="NegativeLookahead";break}a(m);var y=this.disjunction();return this.consumeChar(")"),{type:m,value:y,loc:this.loc(p)}}l()},r.prototype.quantifier=function(p){var m,y=this.idx;switch(this.popChar()){case"*":m={atLeast:0,atMost:Infinity};break;case"+":m={atLeast:1,atMost:Infinity};break;case"?":m={atLeast:0,atMost:1};break;case"{":var b=this.integerIncludingZero();switch(this.popChar()){case"}":m={atLeast:b,atMost:b};break;case",":var v;this.isDigit()?(v=this.integerIncludingZero(),m={atLeast:b,atMost:v}):m={atLeast:b,atMost:Infinity},this.consumeChar("}");break}if(p===!0&&m===void 0)return;a(m);break}if(!(p===!0&&m===void 0))return a(m),this.peekChar(0)==="?"?(this.consumeChar("?"),m.greedy=!1):m.greedy=!0,m.type="Quantifier",m.loc=this.loc(y),m},r.prototype.atom=function(){var p,m=this.idx;switch(this.peekChar()){case".":p=this.dotAll();break;case"\\":p=this.atomEscape();break;case"[":p=this.characterClass();break;case"(":p=this.group();break}return p===void 0&&this.isPatternCharacter()&&(p=this.patternCharacter()),a(p),p.loc=this.loc(m),this.isQuantifier()&&(p.quantifier=this.quantifier()),p},r.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` -`),n("\r"),n("\u2028"),n("\u2029")]}},r.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.decimalEscapeAtom=function(){var p=this.positiveInteger();return{type:"GroupBackReference",value:p}},r.prototype.characterClassEscape=function(){var p,m=!1;switch(this.popChar()){case"d":p=u;break;case"D":p=u,m=!0;break;case"s":p=f;break;case"S":p=f,m=!0;break;case"w":p=g;break;case"W":p=g,m=!0;break}return a(p),{type:"Set",value:p,complement:m}},r.prototype.controlEscapeAtom=function(){var p;switch(this.popChar()){case"f":p=n("\f");break;case"n":p=n(` -`);break;case"r":p=n("\r");break;case"t":p=n(" ");break;case"v":p=n("\v");break}return a(p),{type:"Character",value:p}},r.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var p=this.popChar();if(/[a-zA-Z]/.test(p)===!1)throw Error("Invalid ");var m=p.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:m}},r.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},r.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},r.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},r.prototype.identityEscapeAtom=function(){var p=this.popChar();return{type:"Character",value:n(p)}},r.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case` -`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var p=this.popChar();return{type:"Character",value:n(p)}}},r.prototype.characterClass=function(){var p=[],m=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),m=!0);this.isClassAtom();){var y=this.classAtom(),b=y.type==="Character";if(b&&this.isRangeDash()){this.consumeChar("-");var v=this.classAtom(),k=v.type==="Character";if(k){if(v.value<y.value)throw Error("Range out of order in character class");p.push({from:y.value,to:v.value})}else s(y.value,p),p.push(n("-")),s(v.value,p)}else s(y.value,p)}return this.consumeChar("]"),{type:"Set",complement:m,value:p}},r.prototype.classAtom=function(){switch(this.peekChar()){case"]":case` -`:case"\r":case"\u2028":case"\u2029":throw Error("TBD");case"\\":return this.classEscape();default:return this.classPatternCharacterAtom()}},r.prototype.classEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"b":return this.consumeChar("b"),{type:"Character",value:n("\b")};case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.group=function(){var p=!0;switch(this.consumeChar("("),this.peekChar(0)){case"?":this.consumeChar("?"),this.consumeChar(":"),p=!1;break;default:this.groupIdx++;break}var m=this.disjunction();this.consumeChar(")");var y={type:"Group",capturing:p,value:m};return p&&(y.idx=this.groupIdx),y},r.prototype.positiveInteger=function(){var p=this.popChar();if(i.test(p)===!1)throw Error("Expecting a positive integer");for(;t.test(this.peekChar(0));)p+=this.popChar();return parseInt(p,10)},r.prototype.integerIncludingZero=function(){var p=this.popChar();if(t.test(p)===!1)throw Error("Expecting an integer");for(;t.test(this.peekChar(0));)p+=this.popChar();return parseInt(p,10)},r.prototype.patternCharacter=function(){var p=this.popChar();switch(p){case` -`:case"\r":case"\u2028":case"\u2029":case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":throw Error("TBD");default:return{type:"Character",value:n(p)}}},r.prototype.isRegExpFlag=function(){switch(this.peekChar(0)){case"g":case"i":case"m":case"u":case"y":return!0;default:return!1}},r.prototype.isRangeDash=function(){return this.peekChar()==="-"&&this.isClassAtom(1)},r.prototype.isDigit=function(){return t.test(this.peekChar(0))},r.prototype.isClassAtom=function(p){switch(p===void 0&&(p=0),this.peekChar(p)){case"]":case` -`:case"\r":case"\u2028":case"\u2029":return!1;default:return!0}},r.prototype.isTerm=function(){return this.isAtom()||this.isAssertion()},r.prototype.isAtom=function(){if(this.isPatternCharacter())return!0;switch(this.peekChar(0)){case".":case"\\":case"[":case"(":return!0;default:return!1}},r.prototype.isAssertion=function(){switch(this.peekChar(0)){case"^":case"$":return!0;case"\\":switch(this.peekChar(1)){case"b":case"B":return!0;default:return!1}case"(":return this.peekChar(1)==="?"&&(this.peekChar(2)==="="||this.peekChar(2)==="!");default:return!1}},r.prototype.isQuantifier=function(){var p=this.saveState();try{return this.quantifier(!0)!==void 0}catch(m){return!1}finally{this.restoreState(p)}},r.prototype.isPatternCharacter=function(){switch(this.peekChar()){case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":case"/":case` -`:case"\r":case"\u2028":case"\u2029":return!1;default:return!0}},r.prototype.parseHexDigits=function(p){for(var m="",y=0;y<p;y++){var b=this.popChar();if(e.test(b)===!1)throw Error("Expecting a HexDecimal digits");m+=b}var v=parseInt(m,16);return{type:"Character",value:v}},r.prototype.peekChar=function(p){return p===void 0&&(p=0),this.input[this.idx+p]},r.prototype.popChar=function(){var p=this.peekChar(0);return this.consumeChar(),p},r.prototype.consumeChar=function(p){if(p!==void 0&&this.input[this.idx]!==p)throw Error("Expected: '"+p+"' but found: '"+this.input[this.idx]+"' at offset: "+this.idx);if(this.idx>=this.input.length)throw Error("Unexpected end of input");this.idx++},r.prototype.loc=function(p){return{begin:p,end:this.idx}};var e=/[0-9a-fA-F]/,t=/[0-9]/,i=/[1-9]/;function n(p){return p.charCodeAt(0)}function s(p,m){p.length!==void 0?p.forEach(function(y){m.push(y)}):m.push(p)}function o(p,m){if(p[m]===!0)throw"duplicate flag "+m;p[m]=!0}function a(p){if(p===void 0)throw Error("Internal Error - Should never get here!")}function l(){throw Error("Internal Error - Should never get here!")}var c,u=[];for(c=n("0");c<=n("9");c++)u.push(c);var g=[n("_")].concat(u);for(c=n("a");c<=n("z");c++)g.push(c);for(c=n("A");c<=n("Z");c++)g.push(c);var f=[n(" "),n("\f"),n(` -`),n("\r"),n(" "),n("\v"),n(" "),n("\xA0"),n("\u1680"),n("\u2000"),n("\u2001"),n("\u2002"),n("\u2003"),n("\u2004"),n("\u2005"),n("\u2006"),n("\u2007"),n("\u2008"),n("\u2009"),n("\u200A"),n("\u2028"),n("\u2029"),n("\u202F"),n("\u205F"),n("\u3000"),n("\uFEFF")];function h(){}return h.prototype.visitChildren=function(p){for(var m in p){var y=p[m];p.hasOwnProperty(m)&&(y.type!==void 0?this.visit(y):Array.isArray(y)&&y.forEach(function(b){this.visit(b)},this))}},h.prototype.visit=function(p){switch(p.type){case"Pattern":this.visitPattern(p);break;case"Flags":this.visitFlags(p);break;case"Disjunction":this.visitDisjunction(p);break;case"Alternative":this.visitAlternative(p);break;case"StartAnchor":this.visitStartAnchor(p);break;case"EndAnchor":this.visitEndAnchor(p);break;case"WordBoundary":this.visitWordBoundary(p);break;case"NonWordBoundary":this.visitNonWordBoundary(p);break;case"Lookahead":this.visitLookahead(p);break;case"NegativeLookahead":this.visitNegativeLookahead(p);break;case"Character":this.visitCharacter(p);break;case"Set":this.visitSet(p);break;case"Group":this.visitGroup(p);break;case"GroupBackReference":this.visitGroupBackReference(p);break;case"Quantifier":this.visitQuantifier(p);break}this.visitChildren(p)},h.prototype.visitPattern=function(p){},h.prototype.visitFlags=function(p){},h.prototype.visitDisjunction=function(p){},h.prototype.visitAlternative=function(p){},h.prototype.visitStartAnchor=function(p){},h.prototype.visitEndAnchor=function(p){},h.prototype.visitWordBoundary=function(p){},h.prototype.visitNonWordBoundary=function(p){},h.prototype.visitLookahead=function(p){},h.prototype.visitNegativeLookahead=function(p){},h.prototype.visitCharacter=function(p){},h.prototype.visitSet=function(p){},h.prototype.visitGroup=function(p){},h.prototype.visitGroupBackReference=function(p){},h.prototype.visitQuantifier=function(p){},{RegExpParser:r,BaseRegExpVisitor:h,VERSION:"0.5.0"}})});var UI=w(Cg=>{"use strict";Object.defineProperty(Cg,"__esModule",{value:!0});Cg.clearRegExpParserCache=Cg.getRegExpAst=void 0;var _me=OI(),MI={},Vme=new _me.RegExpParser;function Xme(r){var e=r.toString();if(MI.hasOwnProperty(e))return MI[e];var t=Vme.pattern(e);return MI[e]=t,t}Cg.getRegExpAst=Xme;function Zme(){MI={}}Cg.clearRegExpParserCache=Zme});var LH=w(Bn=>{"use strict";var $me=Bn&&Bn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Bn,"__esModule",{value:!0});Bn.canMatchCharCode=Bn.firstCharOptimizedIndices=Bn.getOptimizedStartCodesIndices=Bn.failedOptimizationPrefixMsg=void 0;var DH=OI(),vs=Yt(),RH=UI(),Ga=wS(),FH="Complement Sets are not supported for first char optimization";Bn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: -`;function eEe(r,e){e===void 0&&(e=!1);try{var t=(0,RH.getRegExpAst)(r),i=KI(t.value,{},t.flags.ignoreCase);return i}catch(s){if(s.message===FH)e&&(0,vs.PRINT_WARNING)(""+Bn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+r.toString()+` > -`)+` Complement Sets cannot be automatically optimized. - This will disable the lexer's first char optimizations. - See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{var n="";e&&(n=` - This will disable the lexer's first char optimizations. - See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),(0,vs.PRINT_ERROR)(Bn.failedOptimizationPrefixMsg+` -`+(" Failed parsing: < "+r.toString()+` > -`)+(" Using the regexp-to-ast library version: "+DH.VERSION+` -`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}Bn.getOptimizedStartCodesIndices=eEe;function KI(r,e,t){switch(r.type){case"Disjunction":for(var i=0;i<r.value.length;i++)KI(r.value[i],e,t);break;case"Alternative":for(var n=r.value,i=0;i<n.length;i++){var s=n[i];switch(s.type){case"EndAnchor":case"GroupBackReference":case"Lookahead":case"NegativeLookahead":case"StartAnchor":case"WordBoundary":case"NonWordBoundary":continue}var o=s;switch(o.type){case"Character":HI(o.value,e,t);break;case"Set":if(o.complement===!0)throw Error(FH);(0,vs.forEach)(o.value,function(c){if(typeof c=="number")HI(c,e,t);else{var u=c;if(t===!0)for(var g=u.from;g<=u.to;g++)HI(g,e,t);else{for(var g=u.from;g<=u.to&&g<Ga.minOptimizationVal;g++)HI(g,e,t);if(u.to>=Ga.minOptimizationVal)for(var f=u.from>=Ga.minOptimizationVal?u.from:Ga.minOptimizationVal,h=u.to,p=(0,Ga.charCodeToOptimizedIndex)(f),m=(0,Ga.charCodeToOptimizedIndex)(h),y=p;y<=m;y++)e[y]=y}}});break;case"Group":KI(o.value,e,t);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&BS(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,vs.values)(e)}Bn.firstCharOptimizedIndices=KI;function HI(r,e,t){var i=(0,Ga.charCodeToOptimizedIndex)(r);e[i]=i,t===!0&&tEe(r,e)}function tEe(r,e){var t=String.fromCharCode(r),i=t.toUpperCase();if(i!==t){var n=(0,Ga.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=t.toLowerCase();if(s!==t){var n=(0,Ga.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function NH(r,e){return(0,vs.find)(r.value,function(t){if(typeof t=="number")return(0,vs.contains)(e,t);var i=t;return(0,vs.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function BS(r){return r.quantifier&&r.quantifier.atLeast===0?!0:r.value?(0,vs.isArray)(r.value)?(0,vs.every)(r.value,BS):BS(r.value):!1}var rEe=function(r){$me(e,r);function e(t){var i=r.call(this)||this;return i.targetCharCodes=t,i.found=!1,i}return e.prototype.visitChildren=function(t){if(this.found!==!0){switch(t.type){case"Lookahead":this.visitLookahead(t);return;case"NegativeLookahead":this.visitNegativeLookahead(t);return}r.prototype.visitChildren.call(this,t)}},e.prototype.visitCharacter=function(t){(0,vs.contains)(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?NH(t,this.targetCharCodes)===void 0&&(this.found=!0):NH(t,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(DH.BaseRegExpVisitor);function iEe(r,e){if(e instanceof RegExp){var t=(0,RH.getRegExpAst)(e),i=new rEe(r);return i.visit(t),i.found}else return(0,vs.find)(e,function(n){return(0,vs.contains)(r,n.charCodeAt(0))})!==void 0}Bn.canMatchCharCode=iEe});var wS=w(Ze=>{"use strict";var TH=Ze&&Ze.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Ze,"__esModule",{value:!0});Ze.charCodeToOptimizedIndex=Ze.minOptimizationVal=Ze.buildLineBreakIssueMessage=Ze.LineTerminatorOptimizedTester=Ze.isShortPattern=Ze.isCustomPattern=Ze.cloneEmptyGroups=Ze.performWarningRuntimeChecks=Ze.performRuntimeChecks=Ze.addStickyFlag=Ze.addStartOfInput=Ze.findUnreachablePatterns=Ze.findModesThatDoNotExist=Ze.findInvalidGroupType=Ze.findDuplicatePatterns=Ze.findUnsupportedFlags=Ze.findStartOfInputAnchor=Ze.findEmptyMatchRegExps=Ze.findEndOfInputAnchor=Ze.findInvalidPatterns=Ze.findMissingPatterns=Ze.validatePatterns=Ze.analyzeTokenTypes=Ze.enableSticky=Ze.disableSticky=Ze.SUPPORT_STICKY=Ze.MODES=Ze.DEFAULT_MODE=void 0;var OH=OI(),Ar=Rp(),Ne=Yt(),mg=LH(),MH=UI(),Ko="PATTERN";Ze.DEFAULT_MODE="defaultMode";Ze.MODES="modes";Ze.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function nEe(){Ze.SUPPORT_STICKY=!1}Ze.disableSticky=nEe;function sEe(){Ze.SUPPORT_STICKY=!0}Ze.enableSticky=sEe;function aEe(r,e){e=(0,Ne.defaults)(e,{useSticky:Ze.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` -`],tracer:function(v,k){return k()}});var t=e.tracer;t("initCharCodeToOptimizedIndexMap",function(){oEe()});var i;t("Reject Lexer.NA",function(){i=(0,Ne.reject)(r,function(v){return v[Ko]===Ar.Lexer.NA})});var n=!1,s;t("Transform Patterns",function(){n=!1,s=(0,Ne.map)(i,function(v){var k=v[Ko];if((0,Ne.isRegExp)(k)){var T=k.source;return T.length===1&&T!=="^"&&T!=="$"&&T!=="."&&!k.ignoreCase?T:T.length===2&&T[0]==="\\"&&!(0,Ne.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],T[1])?T[1]:e.useSticky?QS(k):bS(k)}else{if((0,Ne.isFunction)(k))return n=!0,{exec:k};if((0,Ne.has)(k,"exec"))return n=!0,k;if(typeof k=="string"){if(k.length===1)return k;var Y=k.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),q=new RegExp(Y);return e.useSticky?QS(q):bS(q)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;t("misc mapping",function(){o=(0,Ne.map)(i,function(v){return v.tokenTypeIdx}),a=(0,Ne.map)(i,function(v){var k=v.GROUP;if(k!==Ar.Lexer.SKIPPED){if((0,Ne.isString)(k))return k;if((0,Ne.isUndefined)(k))return!1;throw Error("non exhaustive match")}}),l=(0,Ne.map)(i,function(v){var k=v.LONGER_ALT;if(k){var T=(0,Ne.isArray)(k)?(0,Ne.map)(k,function(Y){return(0,Ne.indexOf)(i,Y)}):[(0,Ne.indexOf)(i,k)];return T}}),c=(0,Ne.map)(i,function(v){return v.PUSH_MODE}),u=(0,Ne.map)(i,function(v){return(0,Ne.has)(v,"POP_MODE")})});var g;t("Line Terminator Handling",function(){var v=HH(e.lineTerminatorCharacters);g=(0,Ne.map)(i,function(k){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,Ne.map)(i,function(k){if((0,Ne.has)(k,"LINE_BREAKS"))return k.LINE_BREAKS;if(KH(k,v)===!1)return(0,mg.canMatchCharCode)(v,k.PATTERN)}))});var f,h,p,m;t("Misc Mapping #2",function(){f=(0,Ne.map)(i,SS),h=(0,Ne.map)(s,UH),p=(0,Ne.reduce)(i,function(v,k){var T=k.GROUP;return(0,Ne.isString)(T)&&T!==Ar.Lexer.SKIPPED&&(v[T]=[]),v},{}),m=(0,Ne.map)(s,function(v,k){return{pattern:s[k],longerAlt:l[k],canLineTerminator:g[k],isCustom:f[k],short:h[k],group:a[k],push:c[k],pop:u[k],tokenTypeIdx:o[k],tokenType:i[k]}})});var y=!0,b=[];return e.safeMode||t("First Char Optimization",function(){b=(0,Ne.reduce)(i,function(v,k,T){if(typeof k.PATTERN=="string"){var Y=k.PATTERN.charCodeAt(0),q=kS(Y);vS(v,q,m[T])}else if((0,Ne.isArray)(k.START_CHARS_HINT)){var $;(0,Ne.forEach)(k.START_CHARS_HINT,function(ne){var ee=typeof ne=="string"?ne.charCodeAt(0):ne,A=kS(ee);$!==A&&($=A,vS(v,A,m[T]))})}else if((0,Ne.isRegExp)(k.PATTERN))if(k.PATTERN.unicode)y=!1,e.ensureOptimizations&&(0,Ne.PRINT_ERROR)(""+mg.failedOptimizationPrefixMsg+(" Unable to analyze < "+k.PATTERN.toString()+` > pattern. -`)+` The regexp unicode flag is not currently supported by the regexp-to-ast library. - This will disable the lexer's first char optimizations. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{var z=(0,mg.getOptimizedStartCodesIndices)(k.PATTERN,e.ensureOptimizations);(0,Ne.isEmpty)(z)&&(y=!1),(0,Ne.forEach)(z,function(ne){vS(v,ne,m[T])})}else e.ensureOptimizations&&(0,Ne.PRINT_ERROR)(""+mg.failedOptimizationPrefixMsg+(" TokenType: <"+k.name+`> is using a custom token pattern without providing <start_chars_hint> parameter. -`)+` This will disable the lexer's first char optimizations. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),y=!1;return v},[])}),t("ArrayPacking",function(){b=(0,Ne.packArray)(b)}),{emptyGroups:p,patternIdxToConfig:m,charCodeToPatternIdxToConfig:b,hasCustom:n,canBeOptimized:y}}Ze.analyzeTokenTypes=aEe;function lEe(r,e){var t=[],i=jH(r);t=t.concat(i.errors);var n=GH(i.valid),s=n.valid;return t=t.concat(n.errors),t=t.concat(AEe(s)),t=t.concat(YH(s)),t=t.concat(qH(s,e)),t=t.concat(JH(s)),t}Ze.validatePatterns=lEe;function AEe(r){var e=[],t=(0,Ne.filter)(r,function(i){return(0,Ne.isRegExp)(i[Ko])});return e=e.concat(WH(t)),e=e.concat(_H(t)),e=e.concat(VH(t)),e=e.concat(XH(t)),e=e.concat(zH(t)),e}function jH(r){var e=(0,Ne.filter)(r,function(n){return!(0,Ne.has)(n,Ko)}),t=(0,Ne.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:Ar.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,Ne.difference)(r,e);return{errors:t,valid:i}}Ze.findMissingPatterns=jH;function GH(r){var e=(0,Ne.filter)(r,function(n){var s=n[Ko];return!(0,Ne.isRegExp)(s)&&!(0,Ne.isFunction)(s)&&!(0,Ne.has)(s,"exec")&&!(0,Ne.isString)(s)}),t=(0,Ne.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:Ar.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,Ne.difference)(r,e);return{errors:t,valid:i}}Ze.findInvalidPatterns=GH;var cEe=/[^\\][\$]/;function WH(r){var e=function(n){TH(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitEndAnchor=function(o){this.found=!0},s}(OH.BaseRegExpVisitor),t=(0,Ne.filter)(r,function(n){var s=n[Ko];try{var o=(0,MH.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch(l){return cEe.test(s.source)}}),i=(0,Ne.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: - Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain end of input anchor '$' - See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:Ar.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ze.findEndOfInputAnchor=WH;function zH(r){var e=(0,Ne.filter)(r,function(i){var n=i[Ko];return n.test("")}),t=(0,Ne.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:Ar.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return t}Ze.findEmptyMatchRegExps=zH;var uEe=/[^\\[][\^]|^\^/;function _H(r){var e=function(n){TH(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitStartAnchor=function(o){this.found=!0},s}(OH.BaseRegExpVisitor),t=(0,Ne.filter)(r,function(n){var s=n[Ko];try{var o=(0,MH.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch(l){return uEe.test(s.source)}}),i=(0,Ne.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: - Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain start of input anchor '^' - See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:Ar.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ze.findStartOfInputAnchor=_H;function VH(r){var e=(0,Ne.filter)(r,function(i){var n=i[Ko];return n instanceof RegExp&&(n.multiline||n.global)}),t=(0,Ne.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:Ar.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return t}Ze.findUnsupportedFlags=VH;function XH(r){var e=[],t=(0,Ne.map)(r,function(s){return(0,Ne.reduce)(r,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,Ne.contains)(e,a)&&a.PATTERN!==Ar.Lexer.NA&&(e.push(a),o.push(a)),o},[])});t=(0,Ne.compact)(t);var i=(0,Ne.filter)(t,function(s){return s.length>1}),n=(0,Ne.map)(i,function(s){var o=(0,Ne.map)(s,function(l){return l.name}),a=(0,Ne.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:Ar.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}Ze.findDuplicatePatterns=XH;function YH(r){var e=(0,Ne.filter)(r,function(i){if(!(0,Ne.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==Ar.Lexer.SKIPPED&&n!==Ar.Lexer.NA&&!(0,Ne.isString)(n)}),t=(0,Ne.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:Ar.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return t}Ze.findInvalidGroupType=YH;function qH(r,e){var t=(0,Ne.filter)(r,function(n){return n.PUSH_MODE!==void 0&&!(0,Ne.contains)(e,n.PUSH_MODE)}),i=(0,Ne.map)(t,function(n){var s="Token Type: ->"+n.name+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+n.PUSH_MODE+"<-which does not exist";return{message:s,type:Ar.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}Ze.findModesThatDoNotExist=qH;function JH(r){var e=[],t=(0,Ne.reduce)(r,function(i,n,s){var o=n.PATTERN;return o===Ar.Lexer.NA||((0,Ne.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,Ne.isRegExp)(o)&&fEe(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,Ne.forEach)(r,function(i,n){(0,Ne.forEach)(t,function(s){var o=s.str,a=s.idx,l=s.tokenType;if(n<a&&gEe(o,i.PATTERN)){var c="Token: ->"+l.name+`<- can never be matched. -`+("Because it appears AFTER the Token Type ->"+i.name+"<-")+`in the lexer's definition. -See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:c,type:Ar.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}Ze.findUnreachablePatterns=JH;function gEe(r,e){if((0,Ne.isRegExp)(e)){var t=e.exec(r);return t!==null&&t.index===0}else{if((0,Ne.isFunction)(e))return e(r,0,[],{});if((0,Ne.has)(e,"exec"))return e.exec(r,0,[],{});if(typeof e=="string")return e===r;throw Error("non exhaustive match")}}function fEe(r){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,Ne.find)(e,function(t){return r.source.indexOf(t)!==-1})===void 0}function bS(r){var e=r.ignoreCase?"i":"";return new RegExp("^(?:"+r.source+")",e)}Ze.addStartOfInput=bS;function QS(r){var e=r.ignoreCase?"iy":"y";return new RegExp(""+r.source,e)}Ze.addStickyFlag=QS;function hEe(r,e,t){var i=[];return(0,Ne.has)(r,Ze.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ze.DEFAULT_MODE+`> property in its definition -`,type:Ar.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,Ne.has)(r,Ze.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ze.MODES+`> property in its definition -`,type:Ar.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,Ne.has)(r,Ze.MODES)&&(0,Ne.has)(r,Ze.DEFAULT_MODE)&&!(0,Ne.has)(r.modes,r.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+Ze.DEFAULT_MODE+": <"+r.defaultMode+`>which does not exist -`,type:Ar.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,Ne.has)(r,Ze.MODES)&&(0,Ne.forEach)(r.modes,function(n,s){(0,Ne.forEach)(n,function(o,a){(0,Ne.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> -`),type:Ar.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}Ze.performRuntimeChecks=hEe;function pEe(r,e,t){var i=[],n=!1,s=(0,Ne.compact)((0,Ne.flatten)((0,Ne.mapValues)(r.modes,function(l){return l}))),o=(0,Ne.reject)(s,function(l){return l[Ko]===Ar.Lexer.NA}),a=HH(t);return e&&(0,Ne.forEach)(o,function(l){var c=KH(l,a);if(c!==!1){var u=ZH(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,Ne.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,mg.canMatchCharCode)(a,l.PATTERN)&&(n=!0)}),e&&!n&&i.push({message:`Warning: No LINE_BREAKS Found. - This Lexer has been defined to track line and column information, - But none of the Token Types can be identified as matching a line terminator. - See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS - for details.`,type:Ar.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}Ze.performWarningRuntimeChecks=pEe;function dEe(r){var e={},t=(0,Ne.keys)(r);return(0,Ne.forEach)(t,function(i){var n=r[i];if((0,Ne.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}Ze.cloneEmptyGroups=dEe;function SS(r){var e=r.PATTERN;if((0,Ne.isRegExp)(e))return!1;if((0,Ne.isFunction)(e))return!0;if((0,Ne.has)(e,"exec"))return!0;if((0,Ne.isString)(e))return!1;throw Error("non exhaustive match")}Ze.isCustomPattern=SS;function UH(r){return(0,Ne.isString)(r)&&r.length===1?r.charCodeAt(0):!1}Ze.isShortPattern=UH;Ze.LineTerminatorOptimizedTester={test:function(r){for(var e=r.length,t=this.lastIndex;t<e;t++){var i=r.charCodeAt(t);if(i===10)return this.lastIndex=t+1,!0;if(i===13)return r.charCodeAt(t+1)===10?this.lastIndex=t+2:this.lastIndex=t+1,!0}return!1},lastIndex:0};function KH(r,e){if((0,Ne.has)(r,"LINE_BREAKS"))return!1;if((0,Ne.isRegExp)(r.PATTERN)){try{(0,mg.canMatchCharCode)(e,r.PATTERN)}catch(t){return{issue:Ar.LexerDefinitionErrorType.IDENTIFY_TERMINATOR,errMsg:t.message}}return!1}else{if((0,Ne.isString)(r.PATTERN))return!1;if(SS(r))return{issue:Ar.LexerDefinitionErrorType.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}}function ZH(r,e){if(e.issue===Ar.LexerDefinitionErrorType.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern. -`+(" The problem is in the <"+r.name+`> Token Type -`)+(" Root cause: "+e.errMsg+`. -`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===Ar.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the <line_breaks> option. -`+(" The problem is in the <"+r.name+`> Token Type -`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}Ze.buildLineBreakIssueMessage=ZH;function HH(r){var e=(0,Ne.map)(r,function(t){return(0,Ne.isString)(t)&&t.length>0?t.charCodeAt(0):t});return e}function vS(r,e,t){r[e]===void 0?r[e]=[t]:r[e].push(t)}Ze.minOptimizationVal=256;var jI=[];function kS(r){return r<Ze.minOptimizationVal?r:jI[r]}Ze.charCodeToOptimizedIndex=kS;function oEe(){if((0,Ne.isEmpty)(jI)){jI=new Array(65536);for(var r=0;r<65536;r++)jI[r]=r>255?255+~~(r/255):r}}});var Eg=w(Ft=>{"use strict";Object.defineProperty(Ft,"__esModule",{value:!0});Ft.isTokenType=Ft.hasExtendingTokensTypesMapProperty=Ft.hasExtendingTokensTypesProperty=Ft.hasCategoriesProperty=Ft.hasShortKeyProperty=Ft.singleAssignCategoriesToksMap=Ft.assignCategoriesMapProp=Ft.assignCategoriesTokensProp=Ft.assignTokenDefaultProps=Ft.expandCategories=Ft.augmentTokenTypes=Ft.tokenIdxToClass=Ft.tokenShortNameIdx=Ft.tokenStructuredMatcherNoCategories=Ft.tokenStructuredMatcher=void 0;var ii=Yt();function CEe(r,e){var t=r.tokenTypeIdx;return t===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[t]===!0}Ft.tokenStructuredMatcher=CEe;function mEe(r,e){return r.tokenTypeIdx===e.tokenTypeIdx}Ft.tokenStructuredMatcherNoCategories=mEe;Ft.tokenShortNameIdx=1;Ft.tokenIdxToClass={};function EEe(r){var e=$H(r);ej(e),rj(e),tj(e),(0,ii.forEach)(e,function(t){t.isParent=t.categoryMatches.length>0})}Ft.augmentTokenTypes=EEe;function $H(r){for(var e=(0,ii.cloneArr)(r),t=r,i=!0;i;){t=(0,ii.compact)((0,ii.flatten)((0,ii.map)(t,function(s){return s.CATEGORIES})));var n=(0,ii.difference)(t,e);e=e.concat(n),(0,ii.isEmpty)(n)?i=!1:t=n}return e}Ft.expandCategories=$H;function ej(r){(0,ii.forEach)(r,function(e){ij(e)||(Ft.tokenIdxToClass[Ft.tokenShortNameIdx]=e,e.tokenTypeIdx=Ft.tokenShortNameIdx++),xS(e)&&!(0,ii.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),xS(e)||(e.CATEGORIES=[]),nj(e)||(e.categoryMatches=[]),sj(e)||(e.categoryMatchesMap={})})}Ft.assignTokenDefaultProps=ej;function tj(r){(0,ii.forEach)(r,function(e){e.categoryMatches=[],(0,ii.forEach)(e.categoryMatchesMap,function(t,i){e.categoryMatches.push(Ft.tokenIdxToClass[i].tokenTypeIdx)})})}Ft.assignCategoriesTokensProp=tj;function rj(r){(0,ii.forEach)(r,function(e){PS([],e)})}Ft.assignCategoriesMapProp=rj;function PS(r,e){(0,ii.forEach)(r,function(t){e.categoryMatchesMap[t.tokenTypeIdx]=!0}),(0,ii.forEach)(e.CATEGORIES,function(t){var i=r.concat(e);(0,ii.contains)(i,t)||PS(i,t)})}Ft.singleAssignCategoriesToksMap=PS;function ij(r){return(0,ii.has)(r,"tokenTypeIdx")}Ft.hasShortKeyProperty=ij;function xS(r){return(0,ii.has)(r,"CATEGORIES")}Ft.hasCategoriesProperty=xS;function nj(r){return(0,ii.has)(r,"categoryMatches")}Ft.hasExtendingTokensTypesProperty=nj;function sj(r){return(0,ii.has)(r,"categoryMatchesMap")}Ft.hasExtendingTokensTypesMapProperty=sj;function IEe(r){return(0,ii.has)(r,"tokenTypeIdx")}Ft.isTokenType=IEe});var DS=w(GI=>{"use strict";Object.defineProperty(GI,"__esModule",{value:!0});GI.defaultLexerErrorProvider=void 0;GI.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(r){return"Unable to pop Lexer Mode after encountering Token ->"+r.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(r,e,t,i,n){return"unexpected character: ->"+r.charAt(e)+"<- at offset: "+e+","+(" skipped "+t+" characters.")}}});var Rp=w(Pc=>{"use strict";Object.defineProperty(Pc,"__esModule",{value:!0});Pc.Lexer=Pc.LexerDefinitionErrorType=void 0;var lo=wS(),lr=Yt(),yEe=Eg(),wEe=DS(),BEe=UI(),bEe;(function(r){r[r.MISSING_PATTERN=0]="MISSING_PATTERN",r[r.INVALID_PATTERN=1]="INVALID_PATTERN",r[r.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",r[r.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",r[r.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",r[r.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",r[r.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",r[r.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",r[r.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",r[r.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",r[r.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",r[r.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",r[r.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",r[r.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",r[r.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",r[r.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",r[r.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(bEe=Pc.LexerDefinitionErrorType||(Pc.LexerDefinitionErrorType={}));var Fp={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` -`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:wEe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(Fp);var QEe=function(){function r(e,t){var i=this;if(t===void 0&&(t=Fp),this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},typeof t=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. -a boolean 2nd argument is no longer supported`);this.config=(0,lr.merge)(Fp,t);var n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=Infinity,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",function(){var s,o=!0;i.TRACE_INIT("Lexer Config handling",function(){if(i.config.lineTerminatorsPattern===Fp.lineTerminatorsPattern)i.config.lineTerminatorsPattern=lo.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===Fp.lineTerminatorCharacters)throw Error(`Error: Missing <lineTerminatorCharacters> property on the Lexer config. - For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');i.trackStartLines=/full|onlyStart/i.test(i.config.positionTracking),i.trackEndLines=/full/i.test(i.config.positionTracking),(0,lr.isArray)(e)?(s={modes:{}},s.modes[lo.DEFAULT_MODE]=(0,lr.cloneArr)(e),s[lo.DEFAULT_MODE]=lo.DEFAULT_MODE):(o=!1,s=(0,lr.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,lo.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,lo.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,lr.forEach)(s.modes,function(u,g){s.modes[g]=(0,lr.reject)(u,function(f){return(0,lr.isUndefined)(f)})});var a=(0,lr.keys)(s.modes);if((0,lr.forEach)(s.modes,function(u,g){i.TRACE_INIT("Mode: <"+g+"> processing",function(){if(i.modes.push(g),i.config.skipValidations===!1&&i.TRACE_INIT("validatePatterns",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,lo.validatePatterns)(u,a))}),(0,lr.isEmpty)(i.lexerDefinitionErrors)){(0,yEe.augmentTokenTypes)(u);var f;i.TRACE_INIT("analyzeTokenTypes",function(){f=(0,lo.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=f.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=f.charCodeToPatternIdxToConfig,i.emptyGroups=(0,lr.merge)(i.emptyGroups,f.emptyGroups),i.hasCustom=f.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=f.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,lr.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,lr.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- -`);throw new Error(`Errors detected in definition of Lexer: -`+c)}(0,lr.forEach)(i.lexerDefinitionWarning,function(u){(0,lr.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(lo.SUPPORT_STICKY?(i.chopInput=lr.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=lr.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=lr.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=lr.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=lr.NOOP),/full/i.test(i.config.positionTracking))i.createTokenInstance=i.createFullToken;else if(/onlyStart/i.test(i.config.positionTracking))i.createTokenInstance=i.createStartOnlyToken;else if(/onlyOffset/i.test(i.config.positionTracking))i.createTokenInstance=i.createOffsetOnlyToken;else throw Error('Invalid <positionTracking> config option: "'+i.config.positionTracking+'"');i.hasCustom?(i.addToken=i.addTokenUsingPush,i.handlePayload=i.handlePayloadWithCustom):(i.addToken=i.addTokenUsingMemberAccess,i.handlePayload=i.handlePayloadNoCustom)}),i.TRACE_INIT("Failed Optimization Warnings",function(){var u=(0,lr.reduce)(i.canModeBeOptimized,function(g,f,h){return f===!1&&g.push(h),g},[]);if(t.ensureOptimizations&&!(0,lr.isEmpty)(u))throw Error("Lexer Modes: < "+u.join(", ")+` > cannot be optimized. - Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. - Or inspect the console log for details on how to resolve these issues.`)}),i.TRACE_INIT("clearRegExpParserCache",function(){(0,BEe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,lr.toFastProperties)(i)})})}return r.prototype.tokenize=function(e,t){if(t===void 0&&(t=this.defaultMode),!(0,lr.isEmpty)(this.lexerDefinitionErrors)){var i=(0,lr.map)(this.lexerDefinitionErrors,function(o){return o.message}),n=i.join(`----------------------- -`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: -`+n)}var s=this.tokenizeInternal(e,t);return s},r.prototype.tokenizeInternal=function(e,t){var i=this,n,s,o,a,l,c,u,g,f,h,p,m,y,b,v,k,T=e,Y=T.length,q=0,$=0,z=this.hasCustom?0:Math.floor(e.length/10),ne=new Array(z),ee=[],A=this.trackStartLines?1:void 0,oe=this.trackStartLines?1:void 0,ce=(0,lo.cloneEmptyGroups)(this.emptyGroups),Z=this.trackStartLines,O=this.config.lineTerminatorsPattern,L=0,de=[],Be=[],Ge=[],re=[];Object.freeze(re);var se=void 0;function be(){return de}function he(Sr){var Gn=(0,lo.charCodeToOptimizedIndex)(Sr),fs=Be[Gn];return fs===void 0?re:fs}var Fe=function(Sr){if(Ge.length===1&&Sr.tokenType.PUSH_MODE===void 0){var Gn=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(Sr);ee.push({offset:Sr.startOffset,line:Sr.startLine!==void 0?Sr.startLine:void 0,column:Sr.startColumn!==void 0?Sr.startColumn:void 0,length:Sr.image.length,message:Gn})}else{Ge.pop();var fs=(0,lr.last)(Ge);de=i.patternIdxToConfig[fs],Be=i.charCodeToPatternIdxToConfig[fs],L=de.length;var Qa=i.canModeBeOptimized[fs]&&i.config.safeMode===!1;Be&&Qa?se=he:se=be}};function Ue(Sr){Ge.push(Sr),Be=this.charCodeToPatternIdxToConfig[Sr],de=this.patternIdxToConfig[Sr],L=de.length,L=de.length;var Gn=this.canModeBeOptimized[Sr]&&this.config.safeMode===!1;Be&&Gn?se=he:se=be}Ue.call(this,t);for(var xe;q<Y;){c=null;var ve=T.charCodeAt(q),pe=se(ve),V=pe.length;for(n=0;n<V;n++){xe=pe[n];var Qe=xe.pattern;u=null;var le=xe.short;if(le!==!1?ve===le&&(c=Qe):xe.isCustom===!0?(k=Qe.exec(T,q,ne,ce),k!==null?(c=k[0],k.payload!==void 0&&(u=k.payload)):c=null):(this.updateLastIndex(Qe,q),c=this.match(Qe,e,q)),c!==null){if(l=xe.longerAlt,l!==void 0){var fe=l.length;for(o=0;o<fe;o++){var gt=de[l[o]],Ht=gt.pattern;if(g=null,gt.isCustom===!0?(k=Ht.exec(T,q,ne,ce),k!==null?(a=k[0],k.payload!==void 0&&(g=k.payload)):a=null):(this.updateLastIndex(Ht,q),a=this.match(Ht,e,q)),a&&a.length>c.length){c=a,u=g,xe=gt;break}}}break}}if(c!==null){if(f=c.length,h=xe.group,h!==void 0&&(p=xe.tokenTypeIdx,m=this.createTokenInstance(c,q,p,xe.tokenType,A,oe,f),this.handlePayload(m,u),h===!1?$=this.addToken(ne,$,m):ce[h].push(m)),e=this.chopInput(e,f),q=q+f,oe=this.computeNewColumn(oe,f),Z===!0&&xe.canLineTerminator===!0){var Mt=0,Ei=void 0,jt=void 0;O.lastIndex=0;do Ei=O.test(c),Ei===!0&&(jt=O.lastIndex-1,Mt++);while(Ei===!0);Mt!==0&&(A=A+Mt,oe=f-jt,this.updateTokenEndLineColumnLocation(m,h,jt,Mt,A,oe,f))}this.handleModes(xe,Fe,Ue,m)}else{for(var Qr=q,Oi=A,$s=oe,Hn=!1;!Hn&&q<Y;)for(b=T.charCodeAt(q),e=this.chopInput(e,1),q++,s=0;s<L;s++){var jn=de[s],Qe=jn.pattern,le=jn.short;if(le!==!1?T.charCodeAt(q)===le&&(Hn=!0):jn.isCustom===!0?Hn=Qe.exec(T,q,ne,ce)!==null:(this.updateLastIndex(Qe,q),Hn=Qe.exec(e)!==null),Hn===!0)break}y=q-Qr,v=this.config.errorMessageProvider.buildUnexpectedCharactersMessage(T,Qr,y,Oi,$s),ee.push({offset:Qr,line:Oi,column:$s,length:y,message:v})}}return this.hasCustom||(ne.length=$),{tokens:ne,groups:ce,errors:ee}},r.prototype.handleModes=function(e,t,i,n){if(e.pop===!0){var s=e.push;t(n),s!==void 0&&i.call(this,s)}else e.push!==void 0&&i.call(this,e.push)},r.prototype.chopInput=function(e,t){return e.substring(t)},r.prototype.updateLastIndex=function(e,t){e.lastIndex=t},r.prototype.updateTokenEndLineColumnLocation=function(e,t,i,n,s,o,a){var l,c;t!==void 0&&(l=i===a-1,c=l?-1:0,n===1&&l===!0||(e.endLine=s+c,e.endColumn=o-1+-c))},r.prototype.computeNewColumn=function(e,t){return e+t},r.prototype.createTokenInstance=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return null},r.prototype.createOffsetOnlyToken=function(e,t,i,n){return{image:e,startOffset:t,tokenTypeIdx:i,tokenType:n}},r.prototype.createStartOnlyToken=function(e,t,i,n,s,o){return{image:e,startOffset:t,startLine:s,startColumn:o,tokenTypeIdx:i,tokenType:n}},r.prototype.createFullToken=function(e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:t+a-1,startLine:s,endLine:s,startColumn:o,endColumn:o+a-1,tokenTypeIdx:i,tokenType:n}},r.prototype.addToken=function(e,t,i){return 666},r.prototype.addTokenUsingPush=function(e,t,i){return e.push(i),t},r.prototype.addTokenUsingMemberAccess=function(e,t,i){return e[t]=i,t++,t},r.prototype.handlePayload=function(e,t){},r.prototype.handlePayloadNoCustom=function(e,t){},r.prototype.handlePayloadWithCustom=function(e,t){t!==null&&(e.payload=t)},r.prototype.match=function(e,t,i){return null},r.prototype.matchWithTest=function(e,t,i){var n=e.test(t);return n===!0?t.substring(i,e.lastIndex):null},r.prototype.matchWithExec=function(e,t){var i=e.exec(t);return i!==null?i[0]:i},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent<this.traceInitMaxIdent&&console.log(i+"--> <"+e+">");var n=(0,lr.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&a(i+"<-- <"+e+"> time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",r.NA=/NOT_APPLICABLE/,r}();Pc.Lexer=QEe});var ZA=w(Pi=>{"use strict";Object.defineProperty(Pi,"__esModule",{value:!0});Pi.tokenMatcher=Pi.createTokenInstance=Pi.EOF=Pi.createToken=Pi.hasTokenLabel=Pi.tokenName=Pi.tokenLabel=void 0;var co=Yt(),SEe=Rp(),RS=Eg();function vEe(r){return oj(r)?r.LABEL:r.name}Pi.tokenLabel=vEe;function kEe(r){return r.name}Pi.tokenName=kEe;function oj(r){return(0,co.isString)(r.LABEL)&&r.LABEL!==""}Pi.hasTokenLabel=oj;var xEe="parent",aj="categories",Aj="label",lj="group",cj="push_mode",uj="pop_mode",gj="longer_alt",fj="line_breaks",hj="start_chars_hint";function pj(r){return PEe(r)}Pi.createToken=pj;function PEe(r){var e=r.pattern,t={};if(t.name=r.name,(0,co.isUndefined)(e)||(t.PATTERN=e),(0,co.has)(r,xEe))throw`The parent property is no longer supported. -See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,co.has)(r,aj)&&(t.CATEGORIES=r[aj]),(0,RS.augmentTokenTypes)([t]),(0,co.has)(r,Aj)&&(t.LABEL=r[Aj]),(0,co.has)(r,lj)&&(t.GROUP=r[lj]),(0,co.has)(r,uj)&&(t.POP_MODE=r[uj]),(0,co.has)(r,cj)&&(t.PUSH_MODE=r[cj]),(0,co.has)(r,gj)&&(t.LONGER_ALT=r[gj]),(0,co.has)(r,fj)&&(t.LINE_BREAKS=r[fj]),(0,co.has)(r,hj)&&(t.START_CHARS_HINT=r[hj]),t}Pi.EOF=pj({name:"EOF",pattern:SEe.Lexer.NA});(0,RS.augmentTokenTypes)([Pi.EOF]);function DEe(r,e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:r.tokenTypeIdx,tokenType:r}}Pi.createTokenInstance=DEe;function REe(r,e){return(0,RS.tokenStructuredMatcher)(r,e)}Pi.tokenMatcher=REe});var bn=w(Vt=>{"use strict";var Ya=Vt&&Vt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Vt,"__esModule",{value:!0});Vt.serializeProduction=Vt.serializeGrammar=Vt.Terminal=Vt.Alternation=Vt.RepetitionWithSeparator=Vt.Repetition=Vt.RepetitionMandatoryWithSeparator=Vt.RepetitionMandatory=Vt.Option=Vt.Alternative=Vt.Rule=Vt.NonTerminal=Vt.AbstractProduction=void 0;var fr=Yt(),FEe=ZA(),Ho=function(){function r(e){this._definition=e}return Object.defineProperty(r.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),r.prototype.accept=function(e){e.visit(this),(0,fr.forEach)(this.definition,function(t){t.accept(e)})},r}();Vt.AbstractProduction=Ho;var dj=function(r){Ya(e,r);function e(t){var i=r.call(this,[])||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this.referencedRule!==void 0?this.referencedRule.definition:[]},set:function(t){},enumerable:!1,configurable:!0}),e.prototype.accept=function(t){t.visit(this)},e}(Ho);Vt.NonTerminal=dj;var Cj=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.orgText="",(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.Rule=Cj;var mj=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.ignoreAmbiguities=!1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.Alternative=mj;var Ej=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.Option=Ej;var Ij=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.RepetitionMandatory=Ij;var yj=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.RepetitionMandatoryWithSeparator=yj;var wj=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.Repetition=wj;var Bj=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ho);Vt.RepetitionWithSeparator=Bj;var bj=function(r){Ya(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(t){this._definition=t},enumerable:!1,configurable:!0}),e}(Ho);Vt.Alternation=bj;var YI=function(){function r(e){this.idx=1,(0,fr.assign)(this,(0,fr.pick)(e,function(t){return t!==void 0}))}return r.prototype.accept=function(e){e.visit(this)},r}();Vt.Terminal=YI;function NEe(r){return(0,fr.map)(r,Np)}Vt.serializeGrammar=NEe;function Np(r){function e(s){return(0,fr.map)(s,Np)}if(r instanceof dj){var t={type:"NonTerminal",name:r.nonTerminalName,idx:r.idx};return(0,fr.isString)(r.label)&&(t.label=r.label),t}else{if(r instanceof mj)return{type:"Alternative",definition:e(r.definition)};if(r instanceof Ej)return{type:"Option",idx:r.idx,definition:e(r.definition)};if(r instanceof Ij)return{type:"RepetitionMandatory",idx:r.idx,definition:e(r.definition)};if(r instanceof yj)return{type:"RepetitionMandatoryWithSeparator",idx:r.idx,separator:Np(new YI({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof Bj)return{type:"RepetitionWithSeparator",idx:r.idx,separator:Np(new YI({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof wj)return{type:"Repetition",idx:r.idx,definition:e(r.definition)};if(r instanceof bj)return{type:"Alternation",idx:r.idx,definition:e(r.definition)};if(r instanceof YI){var i={type:"Terminal",name:r.terminalType.name,label:(0,FEe.tokenLabel)(r.terminalType),idx:r.idx};(0,fr.isString)(r.label)&&(i.terminalLabel=r.label);var n=r.terminalType.PATTERN;return r.terminalType.PATTERN&&(i.pattern=(0,fr.isRegExp)(n)?n.source:n),i}else{if(r instanceof Cj)return{type:"Rule",name:r.name,orgText:r.orgText,definition:e(r.definition)};throw Error("non exhaustive match")}}}Vt.serializeProduction=Np});var JI=w(qI=>{"use strict";Object.defineProperty(qI,"__esModule",{value:!0});qI.RestWalker=void 0;var FS=Yt(),Qn=bn(),LEe=function(){function r(){}return r.prototype.walk=function(e,t){var i=this;t===void 0&&(t=[]),(0,FS.forEach)(e.definition,function(n,s){var o=(0,FS.drop)(e.definition,s+1);if(n instanceof Qn.NonTerminal)i.walkProdRef(n,o,t);else if(n instanceof Qn.Terminal)i.walkTerminal(n,o,t);else if(n instanceof Qn.Alternative)i.walkFlat(n,o,t);else if(n instanceof Qn.Option)i.walkOption(n,o,t);else if(n instanceof Qn.RepetitionMandatory)i.walkAtLeastOne(n,o,t);else if(n instanceof Qn.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,t);else if(n instanceof Qn.RepetitionWithSeparator)i.walkManySep(n,o,t);else if(n instanceof Qn.Repetition)i.walkMany(n,o,t);else if(n instanceof Qn.Alternation)i.walkOr(n,o,t);else throw Error("non exhaustive match")})},r.prototype.walkTerminal=function(e,t,i){},r.prototype.walkProdRef=function(e,t,i){},r.prototype.walkFlat=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkOption=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkAtLeastOne=function(e,t,i){var n=[new Qn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkAtLeastOneSep=function(e,t,i){var n=Qj(e,t,i);this.walk(e,n)},r.prototype.walkMany=function(e,t,i){var n=[new Qn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkManySep=function(e,t,i){var n=Qj(e,t,i);this.walk(e,n)},r.prototype.walkOr=function(e,t,i){var n=this,s=t.concat(i);(0,FS.forEach)(e.definition,function(o){var a=new Qn.Alternative({definition:[o]});n.walk(a,s)})},r}();qI.RestWalker=LEe;function Qj(r,e,t){var i=[new Qn.Option({definition:[new Qn.Terminal({terminalType:r.separator})].concat(r.definition)})],n=i.concat(e,t);return n}});var Ig=w(WI=>{"use strict";Object.defineProperty(WI,"__esModule",{value:!0});WI.GAstVisitor=void 0;var jo=bn(),TEe=function(){function r(){}return r.prototype.visit=function(e){var t=e;switch(t.constructor){case jo.NonTerminal:return this.visitNonTerminal(t);case jo.Alternative:return this.visitAlternative(t);case jo.Option:return this.visitOption(t);case jo.RepetitionMandatory:return this.visitRepetitionMandatory(t);case jo.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(t);case jo.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(t);case jo.Repetition:return this.visitRepetition(t);case jo.Alternation:return this.visitAlternation(t);case jo.Terminal:return this.visitTerminal(t);case jo.Rule:return this.visitRule(t);default:throw Error("non exhaustive match")}},r.prototype.visitNonTerminal=function(e){},r.prototype.visitAlternative=function(e){},r.prototype.visitOption=function(e){},r.prototype.visitRepetition=function(e){},r.prototype.visitRepetitionMandatory=function(e){},r.prototype.visitRepetitionMandatoryWithSeparator=function(e){},r.prototype.visitRepetitionWithSeparator=function(e){},r.prototype.visitAlternation=function(e){},r.prototype.visitTerminal=function(e){},r.prototype.visitRule=function(e){},r}();WI.GAstVisitor=TEe});var Tp=w(Gi=>{"use strict";var OEe=Gi&&Gi.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Gi,"__esModule",{value:!0});Gi.collectMethods=Gi.DslMethodsCollectorVisitor=Gi.getProductionDslName=Gi.isBranchingProd=Gi.isOptionalProd=Gi.isSequenceProd=void 0;var Lp=Yt(),kr=bn(),MEe=Ig();function UEe(r){return r instanceof kr.Alternative||r instanceof kr.Option||r instanceof kr.Repetition||r instanceof kr.RepetitionMandatory||r instanceof kr.RepetitionMandatoryWithSeparator||r instanceof kr.RepetitionWithSeparator||r instanceof kr.Terminal||r instanceof kr.Rule}Gi.isSequenceProd=UEe;function NS(r,e){e===void 0&&(e=[]);var t=r instanceof kr.Option||r instanceof kr.Repetition||r instanceof kr.RepetitionWithSeparator;return t?!0:r instanceof kr.Alternation?(0,Lp.some)(r.definition,function(i){return NS(i,e)}):r instanceof kr.NonTerminal&&(0,Lp.contains)(e,r)?!1:r instanceof kr.AbstractProduction?(r instanceof kr.NonTerminal&&e.push(r),(0,Lp.every)(r.definition,function(i){return NS(i,e)})):!1}Gi.isOptionalProd=NS;function KEe(r){return r instanceof kr.Alternation}Gi.isBranchingProd=KEe;function HEe(r){if(r instanceof kr.NonTerminal)return"SUBRULE";if(r instanceof kr.Option)return"OPTION";if(r instanceof kr.Alternation)return"OR";if(r instanceof kr.RepetitionMandatory)return"AT_LEAST_ONE";if(r instanceof kr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(r instanceof kr.RepetitionWithSeparator)return"MANY_SEP";if(r instanceof kr.Repetition)return"MANY";if(r instanceof kr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Gi.getProductionDslName=HEe;var Sj=function(r){OEe(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.separator="-",t.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},t}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(t){var i=t.terminalType.name+this.separator+"Terminal";(0,Lp.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitNonTerminal=function(t){var i=t.nonTerminalName+this.separator+"Terminal";(0,Lp.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(MEe.GAstVisitor);Gi.DslMethodsCollectorVisitor=Sj;var zI=new Sj;function jEe(r){zI.reset(),r.accept(zI);var e=zI.dslMethods;return zI.reset(),e}Gi.collectMethods=jEe});var TS=w(Go=>{"use strict";Object.defineProperty(Go,"__esModule",{value:!0});Go.firstForTerminal=Go.firstForBranching=Go.firstForSequence=Go.first=void 0;var _I=Yt(),vj=bn(),LS=Tp();function VI(r){if(r instanceof vj.NonTerminal)return VI(r.referencedRule);if(r instanceof vj.Terminal)return Pj(r);if((0,LS.isSequenceProd)(r))return kj(r);if((0,LS.isBranchingProd)(r))return xj(r);throw Error("non exhaustive match")}Go.first=VI;function kj(r){for(var e=[],t=r.definition,i=0,n=t.length>i,s,o=!0;n&&o;)s=t[i],o=(0,LS.isOptionalProd)(s),e=e.concat(VI(s)),i=i+1,n=t.length>i;return(0,_I.uniq)(e)}Go.firstForSequence=kj;function xj(r){var e=(0,_I.map)(r.definition,function(t){return VI(t)});return(0,_I.uniq)((0,_I.flatten)(e))}Go.firstForBranching=xj;function Pj(r){return[r.terminalType]}Go.firstForTerminal=Pj});var OS=w(XI=>{"use strict";Object.defineProperty(XI,"__esModule",{value:!0});XI.IN=void 0;XI.IN="_~IN~_"});var Lj=w(ks=>{"use strict";var GEe=ks&&ks.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(ks,"__esModule",{value:!0});ks.buildInProdFollowPrefix=ks.buildBetweenProdsFollowPrefix=ks.computeAllProdsFollows=ks.ResyncFollowsWalker=void 0;var YEe=JI(),qEe=TS(),Dj=Yt(),Rj=OS(),JEe=bn(),Nj=function(r){GEe(e,r);function e(t){var i=r.call(this)||this;return i.topProd=t,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(t,i,n){},e.prototype.walkProdRef=function(t,i,n){var s=Fj(t.referencedRule,t.idx)+this.topProd.name,o=i.concat(n),a=new JEe.Alternative({definition:o}),l=(0,qEe.first)(a);this.follows[s]=l},e}(YEe.RestWalker);ks.ResyncFollowsWalker=Nj;function WEe(r){var e={};return(0,Dj.forEach)(r,function(t){var i=new Nj(t).startWalking();(0,Dj.assign)(e,i)}),e}ks.computeAllProdsFollows=WEe;function Fj(r,e){return r.name+e+Rj.IN}ks.buildBetweenProdsFollowPrefix=Fj;function zEe(r){var e=r.terminalType.name;return e+r.idx+Rj.IN}ks.buildInProdFollowPrefix=zEe});var Op=w(qa=>{"use strict";Object.defineProperty(qa,"__esModule",{value:!0});qa.defaultGrammarValidatorErrorProvider=qa.defaultGrammarResolverErrorProvider=qa.defaultParserErrorProvider=void 0;var yg=ZA(),_Ee=Yt(),uo=Yt(),MS=bn(),Tj=Tp();qa.defaultParserErrorProvider={buildMismatchTokenMessage:function(r){var e=r.expected,t=r.actual,i=r.previous,n=r.ruleName,s=(0,yg.hasTokenLabel)(e),o=s?"--> "+(0,yg.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+t.image+"' <--";return a},buildNotAllInputParsedMessage:function(r){var e=r.firstRedundant,t=r.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(r){var e=r.expectedPathsPerAlt,t=r.actual,i=r.previous,n=r.customUserDescription,s=r.ruleName,o="Expecting: ",a=(0,uo.first)(t).image,l=` -but found: '`+a+"'";if(n)return o+n+l;var c=(0,uo.reduce)(e,function(h,p){return h.concat(p)},[]),u=(0,uo.map)(c,function(h){return"["+(0,uo.map)(h,function(p){return(0,yg.tokenLabel)(p)}).join(", ")+"]"}),g=(0,uo.map)(u,function(h,p){return" "+(p+1)+". "+h}),f=`one of these possible Token sequences: -`+g.join(` -`);return o+f+l},buildEarlyExitMessage:function(r){var e=r.expectedIterationPaths,t=r.actual,i=r.customUserDescription,n=r.ruleName,s="Expecting: ",o=(0,uo.first)(t).image,a=` -but found: '`+o+"'";if(i)return s+i+a;var l=(0,uo.map)(e,function(u){return"["+(0,uo.map)(u,function(g){return(0,yg.tokenLabel)(g)}).join(",")+"]"}),c=`expecting at least one iteration which starts with one of these possible Token sequences:: - `+("<"+l.join(" ,")+">");return s+c+a}};Object.freeze(qa.defaultParserErrorProvider);qa.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(r,e){var t="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- -inside top level rule: ->`+r.name+"<-";return t}};qa.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(r,e){function t(u){return u instanceof MS.Terminal?u.terminalType.name:u instanceof MS.NonTerminal?u.nonTerminalName:""}var i=r.name,n=(0,uo.first)(e),s=n.idx,o=(0,Tj.getProductionDslName)(n),a=t(n),l=s>0,c="->"+o+(l?s:"")+"<- "+(a?"with argument: ->"+a+"<-":"")+` - appears more than once (`+e.length+" times) in the top level rule: ->"+i+`<-. - For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES - `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,` -`),c},buildNamespaceConflictError:function(r){var e=`Namespace conflict found in grammar. -`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+r.name+`>. -`)+`To resolve this make sure each Terminal and Non-Terminal names are unique -This is easy to accomplish by using the convention that Terminal names start with an uppercase letter -and Non-Terminal names start with a lower case letter.`;return e},buildAlternationPrefixAmbiguityError:function(r){var e=(0,uo.map)(r.prefixPath,function(n){return(0,yg.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous alternatives: <"+r.ambiguityIndices.join(" ,")+`> due to common lookahead prefix -`+("in <OR"+t+"> inside <"+r.topLevelRule.name+`> Rule, -`)+("<"+e+`> may appears as a prefix path in all these alternatives. -`)+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX -For Further details.`;return i},buildAlternationAmbiguityError:function(r){var e=(0,uo.map)(r.prefixPath,function(n){return(0,yg.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous Alternatives Detected: <"+r.ambiguityIndices.join(" ,")+"> in <OR"+t+">"+(" inside <"+r.topLevelRule.name+`> Rule, -`)+("<"+e+`> may appears as a prefix path in all these alternatives. -`);return i=i+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES -For Further details.`,i},buildEmptyRepetitionError:function(r){var e=(0,Tj.getProductionDslName)(r.repetition);r.repetition.idx!==0&&(e+=r.repetition.idx);var t="The repetition <"+e+"> within Rule <"+r.topLevelRule.name+`> can never consume any tokens. -This could lead to an infinite loop.`;return t},buildTokenNameError:function(r){return"deprecated"},buildEmptyAlternationError:function(r){var e="Ambiguous empty alternative: <"+(r.emptyChoiceIdx+1)+">"+(" in <OR"+r.alternation.idx+"> inside <"+r.topLevelRule.name+`> Rule. -`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(r){var e=`An Alternation cannot have more than 256 alternatives: -`+("<OR"+r.alternation.idx+"> inside <"+r.topLevelRule.name+`> Rule. - has `+(r.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(r){var e=r.topLevelRule.name,t=_Ee.map(r.leftRecursionPath,function(s){return s.name}),i=e+" --> "+t.concat([e]).join(" --> "),n=`Left Recursion found in grammar. -`+("rule: <"+e+`> can be invoked from itself (directly or indirectly) -`)+(`without consuming any Tokens. The grammar path that causes this is: - `+i+` -`)+` To fix this refactor your grammar to remove the left recursion. -see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.`;return n},buildInvalidRuleNameError:function(r){return"deprecated"},buildDuplicateRuleNameError:function(r){var e;r.topLevelRule instanceof MS.Rule?e=r.topLevelRule.name:e=r.topLevelRule;var t="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+r.grammarName+"<-";return t}}});var Uj=w($A=>{"use strict";var VEe=$A&&$A.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty($A,"__esModule",{value:!0});$A.GastRefResolverVisitor=$A.resolveGrammar=void 0;var XEe=es(),Oj=Yt(),ZEe=Ig();function $Ee(r,e){var t=new Mj(r,e);return t.resolveRefs(),t.errors}$A.resolveGrammar=$Ee;var Mj=function(r){VEe(e,r);function e(t,i){var n=r.call(this)||this;return n.nameToTopRule=t,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var t=this;(0,Oj.forEach)((0,Oj.values)(this.nameToTopRule),function(i){t.currTopLevel=i,i.accept(t)})},e.prototype.visitNonTerminal=function(t){var i=this.nameToTopRule[t.nonTerminalName];if(i)t.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,t);this.errors.push({message:n,type:XEe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:t.nonTerminalName})}},e}(ZEe.GAstVisitor);$A.GastRefResolverVisitor=Mj});var Up=w(Ur=>{"use strict";var Dc=Ur&&Ur.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Ur,"__esModule",{value:!0});Ur.nextPossibleTokensAfter=Ur.possiblePathsFrom=Ur.NextTerminalAfterAtLeastOneSepWalker=Ur.NextTerminalAfterAtLeastOneWalker=Ur.NextTerminalAfterManySepWalker=Ur.NextTerminalAfterManyWalker=Ur.AbstractNextTerminalAfterProductionWalker=Ur.NextAfterTokenWalker=Ur.AbstractNextPossibleTokensWalker=void 0;var Kj=JI(),Ut=Yt(),eIe=TS(),Dt=bn(),Hj=function(r){Dc(e,r);function e(t,i){var n=r.call(this)||this;return n.topProd=t,n.path=i,n.possibleTokTypes=[],n.nextProductionName="",n.nextProductionOccurrence=0,n.found=!1,n.isAtEndOfPath=!1,n}return e.prototype.startWalking=function(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,Ut.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,Ut.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(t,i){i===void 0&&(i=[]),this.found||r.prototype.walk.call(this,t,i)},e.prototype.walkProdRef=function(t,i,n){if(t.referencedRule.name===this.nextProductionName&&t.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(t.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,Ut.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}(Kj.RestWalker);Ur.AbstractNextPossibleTokensWalker=Hj;var tIe=function(r){Dc(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.path=i,n.nextTerminalName="",n.nextTerminalOccurrence=0,n.nextTerminalName=n.path.lastTok.name,n.nextTerminalOccurrence=n.path.lastTokOccurrence,n}return e.prototype.walkTerminal=function(t,i,n){if(this.isAtEndOfPath&&t.terminalType.name===this.nextTerminalName&&t.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new Dt.Alternative({definition:s});this.possibleTokTypes=(0,eIe.first)(o),this.found=!0}},e}(Hj);Ur.NextAfterTokenWalker=tIe;var Mp=function(r){Dc(e,r);function e(t,i){var n=r.call(this)||this;return n.topRule=t,n.occurrence=i,n.result={token:void 0,occurrence:void 0,isEndOfRule:void 0},n}return e.prototype.startWalking=function(){return this.walk(this.topRule),this.result},e}(Kj.RestWalker);Ur.AbstractNextTerminalAfterProductionWalker=Mp;var rIe=function(r){Dc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkMany=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkMany.call(this,t,i,n)},e}(Mp);Ur.NextTerminalAfterManyWalker=rIe;var iIe=function(r){Dc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkManySep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkManySep.call(this,t,i,n)},e}(Mp);Ur.NextTerminalAfterManySepWalker=iIe;var nIe=function(r){Dc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOne.call(this,t,i,n)},e}(Mp);Ur.NextTerminalAfterAtLeastOneWalker=nIe;var sIe=function(r){Dc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOneSep.call(this,t,i,n)},e}(Mp);Ur.NextTerminalAfterAtLeastOneSepWalker=sIe;function jj(r,e,t){t===void 0&&(t=[]),t=(0,Ut.cloneArr)(t);var i=[],n=0;function s(c){return c.concat((0,Ut.drop)(r,n+1))}function o(c){var u=jj(s(c),e,t);return i.concat(u)}for(;t.length<e&&n<r.length;){var a=r[n];if(a instanceof Dt.Alternative)return o(a.definition);if(a instanceof Dt.NonTerminal)return o(a.definition);if(a instanceof Dt.Option)i=o(a.definition);else if(a instanceof Dt.RepetitionMandatory){var l=a.definition.concat([new Dt.Repetition({definition:a.definition})]);return o(l)}else if(a instanceof Dt.RepetitionMandatoryWithSeparator){var l=[new Dt.Alternative({definition:a.definition}),new Dt.Repetition({definition:[new Dt.Terminal({terminalType:a.separator})].concat(a.definition)})];return o(l)}else if(a instanceof Dt.RepetitionWithSeparator){var l=a.definition.concat([new Dt.Repetition({definition:[new Dt.Terminal({terminalType:a.separator})].concat(a.definition)})]);i=o(l)}else if(a instanceof Dt.Repetition){var l=a.definition.concat([new Dt.Repetition({definition:a.definition})]);i=o(l)}else{if(a instanceof Dt.Alternation)return(0,Ut.forEach)(a.definition,function(c){(0,Ut.isEmpty)(c.definition)===!1&&(i=o(c.definition))}),i;if(a instanceof Dt.Terminal)t.push(a.terminalType);else throw Error("non exhaustive match")}n++}return i.push({partialPath:t,suffixDef:(0,Ut.drop)(r,n)}),i}Ur.possiblePathsFrom=jj;function aIe(r,e,t,i){var n="EXIT_NONE_TERMINAL",s=[n],o="EXIT_ALTERNATIVE",a=!1,l=e.length,c=l-i-1,u=[],g=[];for(g.push({idx:-1,def:r,ruleStack:[],occurrenceStack:[]});!(0,Ut.isEmpty)(g);){var f=g.pop();if(f===o){a&&(0,Ut.last)(g).idx<=c&&g.pop();continue}var h=f.def,p=f.idx,m=f.ruleStack,y=f.occurrenceStack;if(!(0,Ut.isEmpty)(h)){var b=h[0];if(b===n){var v={idx:p,def:(0,Ut.drop)(h),ruleStack:(0,Ut.dropRight)(m),occurrenceStack:(0,Ut.dropRight)(y)};g.push(v)}else if(b instanceof Dt.Terminal)if(p<l-1){var k=p+1,T=e[k];if(t(T,b.terminalType)){var v={idx:k,def:(0,Ut.drop)(h),ruleStack:m,occurrenceStack:y};g.push(v)}}else if(p===l-1)u.push({nextTokenType:b.terminalType,nextTokenOccurrence:b.idx,ruleStack:m,occurrenceStack:y}),a=!0;else throw Error("non exhaustive match");else if(b instanceof Dt.NonTerminal){var Y=(0,Ut.cloneArr)(m);Y.push(b.nonTerminalName);var q=(0,Ut.cloneArr)(y);q.push(b.idx);var v={idx:p,def:b.definition.concat(s,(0,Ut.drop)(h)),ruleStack:Y,occurrenceStack:q};g.push(v)}else if(b instanceof Dt.Option){var $={idx:p,def:(0,Ut.drop)(h),ruleStack:m,occurrenceStack:y};g.push($),g.push(o);var z={idx:p,def:b.definition.concat((0,Ut.drop)(h)),ruleStack:m,occurrenceStack:y};g.push(z)}else if(b instanceof Dt.RepetitionMandatory){var ne=new Dt.Repetition({definition:b.definition,idx:b.idx}),ee=b.definition.concat([ne],(0,Ut.drop)(h)),v={idx:p,def:ee,ruleStack:m,occurrenceStack:y};g.push(v)}else if(b instanceof Dt.RepetitionMandatoryWithSeparator){var A=new Dt.Terminal({terminalType:b.separator}),ne=new Dt.Repetition({definition:[A].concat(b.definition),idx:b.idx}),ee=b.definition.concat([ne],(0,Ut.drop)(h)),v={idx:p,def:ee,ruleStack:m,occurrenceStack:y};g.push(v)}else if(b instanceof Dt.RepetitionWithSeparator){var $={idx:p,def:(0,Ut.drop)(h),ruleStack:m,occurrenceStack:y};g.push($),g.push(o);var A=new Dt.Terminal({terminalType:b.separator}),oe=new Dt.Repetition({definition:[A].concat(b.definition),idx:b.idx}),ee=b.definition.concat([oe],(0,Ut.drop)(h)),z={idx:p,def:ee,ruleStack:m,occurrenceStack:y};g.push(z)}else if(b instanceof Dt.Repetition){var $={idx:p,def:(0,Ut.drop)(h),ruleStack:m,occurrenceStack:y};g.push($),g.push(o);var oe=new Dt.Repetition({definition:b.definition,idx:b.idx}),ee=b.definition.concat([oe],(0,Ut.drop)(h)),z={idx:p,def:ee,ruleStack:m,occurrenceStack:y};g.push(z)}else if(b instanceof Dt.Alternation)for(var ce=b.definition.length-1;ce>=0;ce--){var Z=b.definition[ce],O={idx:p,def:Z.definition.concat((0,Ut.drop)(h)),ruleStack:m,occurrenceStack:y};g.push(O),g.push(o)}else if(b instanceof Dt.Alternative)g.push({idx:p,def:b.definition.concat((0,Ut.drop)(h)),ruleStack:m,occurrenceStack:y});else if(b instanceof Dt.Rule)g.push(oIe(b,p,m,y));else throw Error("non exhaustive match")}}return u}Ur.nextPossibleTokensAfter=aIe;function oIe(r,e,t,i){var n=(0,Ut.cloneArr)(t);n.push(r.name);var s=(0,Ut.cloneArr)(i);return s.push(1),{idx:e,def:r.definition,ruleStack:n,occurrenceStack:s}}});var Kp=w(tr=>{"use strict";var Gj=tr&&tr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(tr,"__esModule",{value:!0});tr.areTokenCategoriesNotUsed=tr.isStrictPrefixOfPath=tr.containsPath=tr.getLookaheadPathsForOptionalProd=tr.getLookaheadPathsForOr=tr.lookAheadSequenceFromAlternatives=tr.buildSingleAlternativeLookaheadFunction=tr.buildAlternativesLookAheadFunc=tr.buildLookaheadFuncForOptionalProd=tr.buildLookaheadFuncForOr=tr.getProdType=tr.PROD_TYPE=void 0;var cr=Yt(),Yj=Up(),AIe=JI(),ZI=Eg(),el=bn(),lIe=Ig(),ui;(function(r){r[r.OPTION=0]="OPTION",r[r.REPETITION=1]="REPETITION",r[r.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",r[r.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",r[r.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",r[r.ALTERNATION=5]="ALTERNATION"})(ui=tr.PROD_TYPE||(tr.PROD_TYPE={}));function cIe(r){if(r instanceof el.Option)return ui.OPTION;if(r instanceof el.Repetition)return ui.REPETITION;if(r instanceof el.RepetitionMandatory)return ui.REPETITION_MANDATORY;if(r instanceof el.RepetitionMandatoryWithSeparator)return ui.REPETITION_MANDATORY_WITH_SEPARATOR;if(r instanceof el.RepetitionWithSeparator)return ui.REPETITION_WITH_SEPARATOR;if(r instanceof el.Alternation)return ui.ALTERNATION;throw Error("non exhaustive match")}tr.getProdType=cIe;function uIe(r,e,t,i,n,s){var o=qj(r,e,t),a=US(o)?ZI.tokenStructuredMatcherNoCategories:ZI.tokenStructuredMatcher;return s(o,i,a,n)}tr.buildLookaheadFuncForOr=uIe;function gIe(r,e,t,i,n,s){var o=Jj(r,e,n,t),a=US(o)?ZI.tokenStructuredMatcherNoCategories:ZI.tokenStructuredMatcher;return s(o[0],a,i)}tr.buildLookaheadFuncForOptionalProd=gIe;function fIe(r,e,t,i){var n=r.length,s=(0,cr.every)(r,function(l){return(0,cr.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,cr.map)(l,function(k){return k.GATE}),u=0;u<n;u++){var g=r[u],f=g.length,h=c[u];if(h!==void 0&&h.call(this)===!1)continue;e:for(var p=0;p<f;p++){for(var m=g[p],y=m.length,b=0;b<y;b++){var v=this.LA(b+1);if(t(v,m[b])===!1)continue e}return u}}};if(s&&!i){var o=(0,cr.map)(r,function(l){return(0,cr.flatten)(l)}),a=(0,cr.reduce)(o,function(l,c,u){return(0,cr.forEach)(c,function(g){(0,cr.has)(l,g.tokenTypeIdx)||(l[g.tokenTypeIdx]=u),(0,cr.forEach)(g.categoryMatches,function(f){(0,cr.has)(l,f)||(l[f]=u)})}),l},[]);return function(){var l=this.LA(1);return a[l.tokenTypeIdx]}}else return function(){for(var l=0;l<n;l++){var c=r[l],u=c.length;e:for(var g=0;g<u;g++){for(var f=c[g],h=f.length,p=0;p<h;p++){var m=this.LA(p+1);if(t(m,f[p])===!1)continue e}return l}}}}tr.buildAlternativesLookAheadFunc=fIe;function hIe(r,e,t){var i=(0,cr.every)(r,function(c){return c.length===1}),n=r.length;if(i&&!t){var s=(0,cr.flatten)(r);if(s.length===1&&(0,cr.isEmpty)(s[0].categoryMatches)){var o=s[0],a=o.tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===a}}else{var l=(0,cr.reduce)(s,function(c,u,g){return c[u.tokenTypeIdx]=!0,(0,cr.forEach)(u.categoryMatches,function(f){c[f]=!0}),c},[]);return function(){var c=this.LA(1);return l[c.tokenTypeIdx]===!0}}}else return function(){e:for(var c=0;c<n;c++){for(var u=r[c],g=u.length,f=0;f<g;f++){var h=this.LA(f+1);if(e(h,u[f])===!1)continue e}return!0}return!1}}tr.buildSingleAlternativeLookaheadFunction=hIe;var pIe=function(r){Gj(e,r);function e(t,i,n){var s=r.call(this)||this;return s.topProd=t,s.targetOccurrence=i,s.targetProdType=n,s}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.restDef},e.prototype.checkIsTarget=function(t,i,n,s){return t.idx===this.targetOccurrence&&this.targetProdType===i?(this.restDef=n.concat(s),!0):!1},e.prototype.walkOption=function(t,i,n){this.checkIsTarget(t,ui.OPTION,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkAtLeastOne=function(t,i,n){this.checkIsTarget(t,ui.REPETITION_MANDATORY,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkAtLeastOneSep=function(t,i,n){this.checkIsTarget(t,ui.REPETITION_MANDATORY_WITH_SEPARATOR,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkMany=function(t,i,n){this.checkIsTarget(t,ui.REPETITION,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkManySep=function(t,i,n){this.checkIsTarget(t,ui.REPETITION_WITH_SEPARATOR,i,n)||r.prototype.walkOption.call(this,t,i,n)},e}(AIe.RestWalker),Wj=function(r){Gj(e,r);function e(t,i,n){var s=r.call(this)||this;return s.targetOccurrence=t,s.targetProdType=i,s.targetRef=n,s.result=[],s}return e.prototype.checkIsTarget=function(t,i){t.idx===this.targetOccurrence&&this.targetProdType===i&&(this.targetRef===void 0||t===this.targetRef)&&(this.result=t.definition)},e.prototype.visitOption=function(t){this.checkIsTarget(t,ui.OPTION)},e.prototype.visitRepetition=function(t){this.checkIsTarget(t,ui.REPETITION)},e.prototype.visitRepetitionMandatory=function(t){this.checkIsTarget(t,ui.REPETITION_MANDATORY)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.checkIsTarget(t,ui.REPETITION_MANDATORY_WITH_SEPARATOR)},e.prototype.visitRepetitionWithSeparator=function(t){this.checkIsTarget(t,ui.REPETITION_WITH_SEPARATOR)},e.prototype.visitAlternation=function(t){this.checkIsTarget(t,ui.ALTERNATION)},e}(lIe.GAstVisitor);function zj(r){for(var e=new Array(r),t=0;t<r;t++)e[t]=[];return e}function KS(r){for(var e=[""],t=0;t<r.length;t++){for(var i=r[t],n=[],s=0;s<e.length;s++){var o=e[s];n.push(o+"_"+i.tokenTypeIdx);for(var a=0;a<i.categoryMatches.length;a++){var l="_"+i.categoryMatches[a];n.push(o+l)}}e=n}return e}function dIe(r,e,t){for(var i=0;i<r.length;i++)if(i!==t)for(var n=r[i],s=0;s<e.length;s++){var o=e[s];if(n[o]===!0)return!1}return!0}function HS(r,e){for(var t=(0,cr.map)(r,function(u){return(0,Yj.possiblePathsFrom)([u],1)}),i=zj(t.length),n=(0,cr.map)(t,function(u){var g={};return(0,cr.forEach)(u,function(f){var h=KS(f.partialPath);(0,cr.forEach)(h,function(p){g[p]=!0})}),g}),s=t,o=1;o<=e;o++){var a=s;s=zj(a.length);for(var l=function(u){for(var g=a[u],f=0;f<g.length;f++){var h=g[f].partialPath,p=g[f].suffixDef,m=KS(h),y=dIe(n,m,u);if(y||(0,cr.isEmpty)(p)||h.length===e){var b=i[u];if(_j(b,h)===!1){b.push(h);for(var v=0;v<m.length;v++){var k=m[v];n[u][k]=!0}}}else{var T=(0,Yj.possiblePathsFrom)(p,o+1,h);s[u]=s[u].concat(T),(0,cr.forEach)(T,function(Y){var q=KS(Y.partialPath);(0,cr.forEach)(q,function($){n[u][$]=!0})})}}},c=0;c<a.length;c++)l(c)}return i}tr.lookAheadSequenceFromAlternatives=HS;function qj(r,e,t,i){var n=new Wj(r,ui.ALTERNATION,i);return e.accept(n),HS(n.result,t)}tr.getLookaheadPathsForOr=qj;function Jj(r,e,t,i){var n=new Wj(r,t);e.accept(n);var s=n.result,o=new pIe(e,r,t),a=o.startWalking(),l=new el.Alternative({definition:s}),c=new el.Alternative({definition:a});return HS([l,c],i)}tr.getLookaheadPathsForOptionalProd=Jj;function _j(r,e){e:for(var t=0;t<r.length;t++){var i=r[t];if(i.length===e.length){for(var n=0;n<i.length;n++){var s=e[n],o=i[n],a=s===o||o.categoryMatchesMap[s.tokenTypeIdx]!==void 0;if(a===!1)continue e}return!0}}return!1}tr.containsPath=_j;function CIe(r,e){return r.length<e.length&&(0,cr.every)(r,function(t,i){var n=e[i];return t===n||n.categoryMatchesMap[t.tokenTypeIdx]})}tr.isStrictPrefixOfPath=CIe;function US(r){return(0,cr.every)(r,function(e){return(0,cr.every)(e,function(t){return(0,cr.every)(t,function(i){return(0,cr.isEmpty)(i.categoryMatches)})})})}tr.areTokenCategoriesNotUsed=US});var WS=w(Xt=>{"use strict";var jS=Xt&&Xt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Xt,"__esModule",{value:!0});Xt.checkPrefixAlternativesAmbiguities=Xt.validateSomeNonEmptyLookaheadPath=Xt.validateTooManyAlts=Xt.RepetionCollector=Xt.validateAmbiguousAlternationAlternatives=Xt.validateEmptyOrAlternative=Xt.getFirstNoneTerminal=Xt.validateNoLeftRecursion=Xt.validateRuleIsOverridden=Xt.validateRuleDoesNotAlreadyExist=Xt.OccurrenceValidationCollector=Xt.identifyProductionForDuplicates=Xt.validateGrammar=void 0;var nr=Yt(),xr=Yt(),Yo=es(),GS=Tp(),wg=Kp(),mIe=Up(),go=bn(),YS=Ig();function yIe(r,e,t,i,n){var s=nr.map(r,function(h){return EIe(h,i)}),o=nr.map(r,function(h){return qS(h,h,i)}),a=[],l=[],c=[];(0,xr.every)(o,xr.isEmpty)&&(a=(0,xr.map)(r,function(h){return Xj(h,i)}),l=(0,xr.map)(r,function(h){return Zj(h,e,i)}),c=eG(r,e,i));var u=IIe(r,t,i),g=(0,xr.map)(r,function(h){return $j(h,i)}),f=(0,xr.map)(r,function(h){return Vj(h,r,n,i)});return nr.flatten(s.concat(c,o,a,l,u,g,f))}Xt.validateGrammar=yIe;function EIe(r,e){var t=new iG;r.accept(t);var i=t.allProductions,n=nr.groupBy(i,tG),s=nr.pick(n,function(a){return a.length>1}),o=nr.map(nr.values(s),function(a){var l=nr.first(a),c=e.buildDuplicateFoundError(r,a),u=(0,GS.getProductionDslName)(l),g={message:c,type:Yo.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:r.name,dslName:u,occurrence:l.idx},f=rG(l);return f&&(g.parameter=f),g});return o}function tG(r){return(0,GS.getProductionDslName)(r)+"_#_"+r.idx+"_#_"+rG(r)}Xt.identifyProductionForDuplicates=tG;function rG(r){return r instanceof go.Terminal?r.terminalType.name:r instanceof go.NonTerminal?r.nonTerminalName:""}var iG=function(r){jS(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}(YS.GAstVisitor);Xt.OccurrenceValidationCollector=iG;function Vj(r,e,t,i){var n=[],s=(0,xr.reduce)(e,function(a,l){return l.name===r.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:r,grammarName:t});n.push({message:o,type:Yo.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:r.name})}return n}Xt.validateRuleDoesNotAlreadyExist=Vj;function wIe(r,e,t){var i=[],n;return nr.contains(e,r)||(n="Invalid rule override, rule: ->"+r+"<- cannot be overridden in the grammar: ->"+t+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:Yo.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:r})),i}Xt.validateRuleIsOverridden=wIe;function qS(r,e,t,i){i===void 0&&(i=[]);var n=[],s=Hp(e.definition);if(nr.isEmpty(s))return[];var o=r.name,a=nr.contains(s,r);a&&n.push({message:t.buildLeftRecursionError({topLevelRule:r,leftRecursionPath:i}),type:Yo.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=nr.difference(s,i.concat([r])),c=nr.map(l,function(u){var g=nr.cloneArr(i);return g.push(u),qS(r,u,t,g)});return n.concat(nr.flatten(c))}Xt.validateNoLeftRecursion=qS;function Hp(r){var e=[];if(nr.isEmpty(r))return e;var t=nr.first(r);if(t instanceof go.NonTerminal)e.push(t.referencedRule);else if(t instanceof go.Alternative||t instanceof go.Option||t instanceof go.RepetitionMandatory||t instanceof go.RepetitionMandatoryWithSeparator||t instanceof go.RepetitionWithSeparator||t instanceof go.Repetition)e=e.concat(Hp(t.definition));else if(t instanceof go.Alternation)e=nr.flatten(nr.map(t.definition,function(o){return Hp(o.definition)}));else if(!(t instanceof go.Terminal))throw Error("non exhaustive match");var i=(0,GS.isOptionalProd)(t),n=r.length>1;if(i&&n){var s=nr.drop(r);return e.concat(Hp(s))}else return e}Xt.getFirstNoneTerminal=Hp;var JS=function(r){jS(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.alternations=[],t}return e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}(YS.GAstVisitor);function Xj(r,e){var t=new JS;r.accept(t);var i=t.alternations,n=nr.reduce(i,function(s,o){var a=nr.dropRight(o.definition),l=nr.map(a,function(c,u){var g=(0,mIe.nextPossibleTokensAfter)([c],[],null,1);return nr.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:r,alternation:o,emptyChoiceIdx:u}),type:Yo.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:r.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(nr.compact(l))},[]);return n}Xt.validateEmptyOrAlternative=Xj;function Zj(r,e,t){var i=new JS;r.accept(i);var n=i.alternations;n=(0,xr.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=nr.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,wg.getLookaheadPathsForOr)(l,r,c,a),g=BIe(u,a,r,t),f=nG(u,a,r,t);return o.concat(g,f)},[]);return s}Xt.validateAmbiguousAlternationAlternatives=Zj;var sG=function(r){jS(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}(YS.GAstVisitor);Xt.RepetionCollector=sG;function $j(r,e){var t=new JS;r.accept(t);var i=t.alternations,n=nr.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:r,alternation:o}),type:Yo.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:r.name,occurrence:o.idx}),s},[]);return n}Xt.validateTooManyAlts=$j;function eG(r,e,t){var i=[];return(0,xr.forEach)(r,function(n){var s=new sG;n.accept(s);var o=s.allProductions;(0,xr.forEach)(o,function(a){var l=(0,wg.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,wg.getLookaheadPathsForOptionalProd)(u,n,l,c),f=g[0];if((0,xr.isEmpty)((0,xr.flatten)(f))){var h=t.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:h,type:Yo.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}Xt.validateSomeNonEmptyLookaheadPath=eG;function BIe(r,e,t,i){var n=[],s=(0,xr.reduce)(r,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,xr.forEach)(l,function(u){var g=[c];(0,xr.forEach)(r,function(f,h){c!==h&&(0,wg.containsPath)(f,u)&&e.definition[h].ignoreAmbiguities!==!0&&g.push(h)}),g.length>1&&!(0,wg.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=nr.map(s,function(a){var l=(0,xr.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:Yo.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:t.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function nG(r,e,t,i){var n=[],s=(0,xr.reduce)(r,function(o,a,l){var c=(0,xr.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,xr.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,xr.findAll)(s,function(f){return e.definition[f.idx].ignoreAmbiguities!==!0&&f.idx<l&&(0,wg.isStrictPrefixOfPath)(f.path,c)}),g=(0,xr.map)(u,function(f){var h=[f.idx+1,l+1],p=e.idx===0?"":e.idx,m=i.buildAlternationPrefixAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:h,prefixPath:f.path});return{message:m,type:Yo.ParserDefinitionErrorType.AMBIGUOUS_PREFIX_ALTS,ruleName:t.name,occurrence:p,alternatives:h}});n=n.concat(g)}}),n}Xt.checkPrefixAlternativesAmbiguities=nG;function IIe(r,e,t){var i=[],n=(0,xr.map)(e,function(s){return s.name});return(0,xr.forEach)(r,function(s){var o=s.name;if((0,xr.contains)(n,o)){var a=t.buildNamespaceConflictError(s);i.push({message:a,type:Yo.ParserDefinitionErrorType.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:o})}}),i}});var aG=w(Bg=>{"use strict";Object.defineProperty(Bg,"__esModule",{value:!0});Bg.validateGrammar=Bg.resolveGrammar=void 0;var zS=Yt(),bIe=Uj(),QIe=WS(),oG=Op();function SIe(r){r=(0,zS.defaults)(r,{errMsgProvider:oG.defaultGrammarResolverErrorProvider});var e={};return(0,zS.forEach)(r.rules,function(t){e[t.name]=t}),(0,bIe.resolveGrammar)(e,r.errMsgProvider)}Bg.resolveGrammar=SIe;function vIe(r){return r=(0,zS.defaults)(r,{errMsgProvider:oG.defaultGrammarValidatorErrorProvider}),(0,QIe.validateGrammar)(r.rules,r.maxLookahead,r.tokenTypes,r.errMsgProvider,r.grammarName)}Bg.validateGrammar=vIe});var bg=w(Sn=>{"use strict";var jp=Sn&&Sn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Sn,"__esModule",{value:!0});Sn.EarlyExitException=Sn.NotAllInputParsedException=Sn.NoViableAltException=Sn.MismatchedTokenException=Sn.isRecognitionException=void 0;var kIe=Yt(),AG="MismatchedTokenException",lG="NoViableAltException",cG="EarlyExitException",uG="NotAllInputParsedException",gG=[AG,lG,cG,uG];Object.freeze(gG);function xIe(r){return(0,kIe.contains)(gG,r.name)}Sn.isRecognitionException=xIe;var $I=function(r){jp(e,r);function e(t,i){var n=this.constructor,s=r.call(this,t)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),PIe=function(r){jp(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=AG,s}return e}($I);Sn.MismatchedTokenException=PIe;var DIe=function(r){jp(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=lG,s}return e}($I);Sn.NoViableAltException=DIe;var RIe=function(r){jp(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.name=uG,n}return e}($I);Sn.NotAllInputParsedException=RIe;var FIe=function(r){jp(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=cG,s}return e}($I);Sn.EarlyExitException=FIe});var VS=w(Yi=>{"use strict";Object.defineProperty(Yi,"__esModule",{value:!0});Yi.attemptInRepetitionRecovery=Yi.Recoverable=Yi.InRuleRecoveryException=Yi.IN_RULE_RECOVERY_EXCEPTION=Yi.EOF_FOLLOW_KEY=void 0;var ey=ZA(),xs=Yt(),NIe=bg(),LIe=OS(),TIe=es();Yi.EOF_FOLLOW_KEY={};Yi.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function _S(r){this.name=Yi.IN_RULE_RECOVERY_EXCEPTION,this.message=r}Yi.InRuleRecoveryException=_S;_S.prototype=Error.prototype;var OIe=function(){function r(){}return r.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,xs.has)(e,"recoveryEnabled")?e.recoveryEnabled:TIe.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=fG)},r.prototype.getTokenToInsert=function(e){var t=(0,ey.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t},r.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},r.prototype.tryInRepetitionRecovery=function(e,t,i,n){for(var s=this,o=this.findReSyncTokenType(),a=this.exportLexerState(),l=[],c=!1,u=this.LA(1),g=this.LA(1),f=function(){var h=s.LA(0),p=s.errorMessageProvider.buildMismatchTokenMessage({expected:n,actual:u,previous:h,ruleName:s.getCurrRuleFullName()}),m=new NIe.MismatchedTokenException(p,u,s.LA(0));m.resyncedTokens=(0,xs.dropRight)(l),s.SAVE_ERROR(m)};!c;)if(this.tokenMatcher(g,n)){f();return}else if(i.call(this)){f(),e.apply(this,t);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},r.prototype.shouldInRepetitionRecoveryBeTried=function(e,t,i){return!(i===!1||e===void 0||t===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t)))},r.prototype.getFollowsForInRuleRecovery=function(e,t){var i=this.getCurrentGrammarPath(e,t),n=this.getNextPossibleTokenTypes(i);return n},r.prototype.tryInRuleRecovery=function(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new _S("sad sad panda")},r.prototype.canPerformInRuleRecovery=function(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)},r.prototype.canRecoverWithSingleTokenInsertion=function(e,t){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,xs.isEmpty)(t))return!1;var n=this.LA(1),s=(0,xs.find)(t,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},r.prototype.canRecoverWithSingleTokenDeletion=function(e){var t=this.tokenMatcher(this.LA(2),e);return t},r.prototype.isInCurrentRuleReSyncSet=function(e){var t=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(t);return(0,xs.contains)(i,e)},r.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),t=this.LA(1),i=2;;){var n=t.tokenType;if((0,xs.contains)(e,n))return n;t=this.LA(i),i++}},r.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return Yi.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(i)}},r.prototype.buildFullFollowKeyStack=function(){var e=this,t=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,xs.map)(t,function(n,s){return s===0?Yi.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(t[s-1])}})},r.prototype.flattenFollowSet=function(){var e=this,t=(0,xs.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,xs.flatten)(t)},r.prototype.getFollowSetFromFollowKey=function(e){if(e===Yi.EOF_FOLLOW_KEY)return[ey.EOF];var t=e.ruleName+e.idxInCallingRule+LIe.IN+e.inRule;return this.resyncFollows[t]},r.prototype.addToResyncTokens=function(e,t){return this.tokenMatcher(e,ey.EOF)||t.push(e),t},r.prototype.reSyncTo=function(e){for(var t=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,t);return(0,xs.dropRight)(t)},r.prototype.attemptInRepetitionRecovery=function(e,t,i,n,s,o,a){},r.prototype.getCurrentGrammarPath=function(e,t){var i=this.getHumanReadableRuleStack(),n=(0,xs.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:t};return s},r.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,xs.map)(this.RULE_STACK,function(t){return e.shortRuleNameToFullName(t)})},r}();Yi.Recoverable=OIe;function fG(r,e,t,i,n,s,o){var a=this.getKeyForAutomaticLookahead(i,n),l=this.firstAfterRepMap[a];if(l===void 0){var c=this.getCurrRuleFullName(),u=this.getGAstProductions()[c],g=new s(u,n);l=g.startWalking(),this.firstAfterRepMap[a]=l}var f=l.token,h=l.occurrence,p=l.isEndOfRule;this.RULE_STACK.length===1&&p&&f===void 0&&(f=ey.EOF,h=1),this.shouldInRepetitionRecoveryBeTried(f,h,o)&&this.tryInRepetitionRecovery(r,e,t,f)}Yi.attemptInRepetitionRecovery=fG});var ty=w(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.getKeyForAutomaticLookahead=Jt.AT_LEAST_ONE_SEP_IDX=Jt.MANY_SEP_IDX=Jt.AT_LEAST_ONE_IDX=Jt.MANY_IDX=Jt.OPTION_IDX=Jt.OR_IDX=Jt.BITS_FOR_ALT_IDX=Jt.BITS_FOR_RULE_IDX=Jt.BITS_FOR_OCCURRENCE_IDX=Jt.BITS_FOR_METHOD_TYPE=void 0;Jt.BITS_FOR_METHOD_TYPE=4;Jt.BITS_FOR_OCCURRENCE_IDX=8;Jt.BITS_FOR_RULE_IDX=12;Jt.BITS_FOR_ALT_IDX=8;Jt.OR_IDX=1<<Jt.BITS_FOR_OCCURRENCE_IDX;Jt.OPTION_IDX=2<<Jt.BITS_FOR_OCCURRENCE_IDX;Jt.MANY_IDX=3<<Jt.BITS_FOR_OCCURRENCE_IDX;Jt.AT_LEAST_ONE_IDX=4<<Jt.BITS_FOR_OCCURRENCE_IDX;Jt.MANY_SEP_IDX=5<<Jt.BITS_FOR_OCCURRENCE_IDX;Jt.AT_LEAST_ONE_SEP_IDX=6<<Jt.BITS_FOR_OCCURRENCE_IDX;function MIe(r,e,t){return t|e|r}Jt.getKeyForAutomaticLookahead=MIe;var T$e=32-Jt.BITS_FOR_ALT_IDX});var pG=w(ry=>{"use strict";Object.defineProperty(ry,"__esModule",{value:!0});ry.LooksAhead=void 0;var Ja=Kp(),fo=Yt(),hG=es(),Wa=ty(),Rc=Tp(),UIe=function(){function r(){}return r.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,fo.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:hG.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,fo.has)(e,"maxLookahead")?e.maxLookahead:hG.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,fo.isES2015MapSupported)()?new Map:[],(0,fo.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},r.prototype.preComputeLookaheadFunctions=function(e){var t=this;(0,fo.forEach)(e,function(i){t.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,Rc.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,fo.forEach)(s,function(g){var f=g.idx===0?"":g.idx;t.TRACE_INIT(""+(0,Rc.getProductionDslName)(g)+f,function(){var h=(0,Ja.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||t.maxLookahead,g.hasPredicates,t.dynamicTokensEnabled,t.lookAheadBuilderForAlternatives),p=(0,Wa.getKeyForAutomaticLookahead)(t.fullRuleNameToShort[i.name],Wa.OR_IDX,g.idx);t.setLaFuncCache(p,h)})}),(0,fo.forEach)(o,function(g){t.computeLookaheadFunc(i,g.idx,Wa.MANY_IDX,Ja.PROD_TYPE.REPETITION,g.maxLookahead,(0,Rc.getProductionDslName)(g))}),(0,fo.forEach)(a,function(g){t.computeLookaheadFunc(i,g.idx,Wa.OPTION_IDX,Ja.PROD_TYPE.OPTION,g.maxLookahead,(0,Rc.getProductionDslName)(g))}),(0,fo.forEach)(l,function(g){t.computeLookaheadFunc(i,g.idx,Wa.AT_LEAST_ONE_IDX,Ja.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,Rc.getProductionDslName)(g))}),(0,fo.forEach)(c,function(g){t.computeLookaheadFunc(i,g.idx,Wa.AT_LEAST_ONE_SEP_IDX,Ja.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,Rc.getProductionDslName)(g))}),(0,fo.forEach)(u,function(g){t.computeLookaheadFunc(i,g.idx,Wa.MANY_SEP_IDX,Ja.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,Rc.getProductionDslName)(g))})})})},r.prototype.computeLookaheadFunc=function(e,t,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(t===0?"":t),function(){var l=(0,Ja.buildLookaheadFuncForOptionalProd)(t,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,Wa.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,t);a.setLaFuncCache(c,l)})},r.prototype.lookAheadBuilderForOptional=function(e,t,i){return(0,Ja.buildSingleAlternativeLookaheadFunction)(e,t,i)},r.prototype.lookAheadBuilderForAlternatives=function(e,t,i,n){return(0,Ja.buildAlternativesLookAheadFunc)(e,t,i,n)},r.prototype.getKeyForAutomaticLookahead=function(e,t){var i=this.getLastExplicitRuleShortName();return(0,Wa.getKeyForAutomaticLookahead)(i,e,t)},r.prototype.getLaFuncFromCache=function(e){},r.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},r.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},r.prototype.setLaFuncCache=function(e,t){},r.prototype.setLaFuncCacheUsingMap=function(e,t){this.lookAheadFuncsCache.set(e,t)},r.prototype.setLaFuncUsingObj=function(e,t){this.lookAheadFuncsCache[e]=t},r}();ry.LooksAhead=UIe});var dG=w(qo=>{"use strict";Object.defineProperty(qo,"__esModule",{value:!0});qo.addNoneTerminalToCst=qo.addTerminalToCst=qo.setNodeLocationFull=qo.setNodeLocationOnlyOffset=void 0;function KIe(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.endOffset=e.endOffset):r.endOffset<e.endOffset&&(r.endOffset=e.endOffset)}qo.setNodeLocationOnlyOffset=KIe;function HIe(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.startColumn=e.startColumn,r.startLine=e.startLine,r.endOffset=e.endOffset,r.endColumn=e.endColumn,r.endLine=e.endLine):r.endOffset<e.endOffset&&(r.endOffset=e.endOffset,r.endColumn=e.endColumn,r.endLine=e.endLine)}qo.setNodeLocationFull=HIe;function jIe(r,e,t){r.children[t]===void 0?r.children[t]=[e]:r.children[t].push(e)}qo.addTerminalToCst=jIe;function GIe(r,e,t){r.children[e]===void 0?r.children[e]=[t]:r.children[e].push(t)}qo.addNoneTerminalToCst=GIe});var XS=w(tl=>{"use strict";Object.defineProperty(tl,"__esModule",{value:!0});tl.defineNameProp=tl.functionName=tl.classNameFromInstance=void 0;var YIe=Yt();function qIe(r){return CG(r.constructor)}tl.classNameFromInstance=qIe;var mG="name";function CG(r){var e=r.name;return e||"anonymous"}tl.functionName=CG;function JIe(r,e){var t=Object.getOwnPropertyDescriptor(r,mG);return(0,YIe.isUndefined)(t)||t.configurable?(Object.defineProperty(r,mG,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}tl.defineNameProp=JIe});var BG=w(Di=>{"use strict";Object.defineProperty(Di,"__esModule",{value:!0});Di.validateRedundantMethods=Di.validateMissingCstMethods=Di.validateVisitor=Di.CstVisitorDefinitionError=Di.createBaseVisitorConstructorWithDefaults=Di.createBaseSemanticVisitorConstructor=Di.defaultVisit=void 0;var Ps=Yt(),Gp=XS();function EG(r,e){for(var t=(0,Ps.keys)(r),i=t.length,n=0;n<i;n++)for(var s=t[n],o=r[s],a=o.length,l=0;l<a;l++){var c=o[l];c.tokenTypeIdx===void 0&&this[c.name](c.children,e)}}Di.defaultVisit=EG;function WIe(r,e){var t=function(){};(0,Gp.defineNameProp)(t,r+"BaseSemantics");var i={visit:function(n,s){if((0,Ps.isArray)(n)&&(n=n[0]),!(0,Ps.isUndefined)(n))return this[n.name](n.children,s)},validateVisitor:function(){var n=IG(this,e);if(!(0,Ps.isEmpty)(n)){var s=(0,Ps.map)(n,function(o){return o.msg});throw Error("Errors Detected in CST Visitor <"+(0,Gp.functionName)(this.constructor)+`>: - `+(""+s.join(` - -`).replace(/\n/g,` - `)))}}};return t.prototype=i,t.prototype.constructor=t,t._RULE_NAMES=e,t}Di.createBaseSemanticVisitorConstructor=WIe;function zIe(r,e,t){var i=function(){};(0,Gp.defineNameProp)(i,r+"BaseSemanticsWithDefaults");var n=Object.create(t.prototype);return(0,Ps.forEach)(e,function(s){n[s]=EG}),i.prototype=n,i.prototype.constructor=i,i}Di.createBaseVisitorConstructorWithDefaults=zIe;var ZS;(function(r){r[r.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",r[r.MISSING_METHOD=1]="MISSING_METHOD"})(ZS=Di.CstVisitorDefinitionError||(Di.CstVisitorDefinitionError={}));function IG(r,e){var t=yG(r,e),i=wG(r,e);return t.concat(i)}Di.validateVisitor=IG;function yG(r,e){var t=(0,Ps.map)(e,function(i){if(!(0,Ps.isFunction)(r[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,Gp.functionName)(r.constructor)+" CST Visitor.",type:ZS.MISSING_METHOD,methodName:i}});return(0,Ps.compact)(t)}Di.validateMissingCstMethods=yG;var _Ie=["constructor","visit","validateVisitor"];function wG(r,e){var t=[];for(var i in r)(0,Ps.isFunction)(r[i])&&!(0,Ps.contains)(_Ie,i)&&!(0,Ps.contains)(e,i)&&t.push({msg:"Redundant visitor method: <"+i+"> on "+(0,Gp.functionName)(r.constructor)+` CST Visitor -There is no Grammar Rule corresponding to this method's name. -`,type:ZS.REDUNDANT_METHOD,methodName:i});return t}Di.validateRedundantMethods=wG});var QG=w(iy=>{"use strict";Object.defineProperty(iy,"__esModule",{value:!0});iy.TreeBuilder=void 0;var Qg=dG(),ni=Yt(),bG=BG(),VIe=es(),XIe=function(){function r(){}return r.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,ni.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:VIe.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=ni.NOOP,this.cstFinallyStateUpdate=ni.NOOP,this.cstPostTerminal=ni.NOOP,this.cstPostNonTerminal=ni.NOOP,this.cstPostRule=ni.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=Qg.setNodeLocationFull,this.setNodeLocationFromNode=Qg.setNodeLocationFull,this.cstPostRule=ni.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=ni.NOOP,this.setNodeLocationFromNode=ni.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=Qg.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=Qg.setNodeLocationOnlyOffset,this.cstPostRule=ni.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=ni.NOOP,this.setNodeLocationFromNode=ni.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=ni.NOOP,this.setNodeLocationFromNode=ni.NOOP,this.cstPostRule=ni.NOOP,this.setInitialNodeLocation=ni.NOOP;else throw Error('Invalid <nodeLocationTracking> config option: "'+e.nodeLocationTracking+'"')},r.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},r.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},r.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.setInitialNodeLocationFullRegular=function(e){var t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.cstInvocationStateUpdate=function(e,t){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},r.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},r.prototype.cstPostRuleFull=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?(i.endOffset=t.endOffset,i.endLine=t.endLine,i.endColumn=t.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},r.prototype.cstPostRuleOnlyOffset=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?i.endOffset=t.endOffset:i.startOffset=NaN},r.prototype.cstPostTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,Qg.addTerminalToCst)(i,t,e),this.setNodeLocationFromToken(i.location,t)},r.prototype.cstPostNonTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,Qg.addNoneTerminalToCst)(i,t,e),this.setNodeLocationFromNode(i.location,e.location)},r.prototype.getBaseCstVisitorConstructor=function(){if((0,ni.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,bG.createBaseSemanticVisitorConstructor)(this.className,(0,ni.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},r.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,ni.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,bG.createBaseVisitorConstructorWithDefaults)(this.className,(0,ni.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},r.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},r.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},r.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},r}();iy.TreeBuilder=XIe});var vG=w(ny=>{"use strict";Object.defineProperty(ny,"__esModule",{value:!0});ny.LexerAdapter=void 0;var SG=es(),ZIe=function(){function r(){}return r.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(r.prototype,"input",{get:function(){return this.tokVector},set:function(e){if(this.selfAnalysisDone!==!0)throw Error("Missing <performSelfAnalysis> invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length},enumerable:!1,configurable:!0}),r.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):SG.END_OF_FILE},r.prototype.LA=function(e){var t=this.currIdx+e;return t<0||this.tokVectorLength<=t?SG.END_OF_FILE:this.tokVector[t]},r.prototype.consumeToken=function(){this.currIdx++},r.prototype.exportLexerState=function(){return this.currIdx},r.prototype.importLexerState=function(e){this.currIdx=e},r.prototype.resetLexerState=function(){this.currIdx=-1},r.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},r.prototype.getLexerPosition=function(){return this.exportLexerState()},r}();ny.LexerAdapter=ZIe});var xG=w(sy=>{"use strict";Object.defineProperty(sy,"__esModule",{value:!0});sy.RecognizerApi=void 0;var kG=Yt(),$Ie=bg(),$S=es(),eye=Op(),tye=WS(),rye=bn(),iye=function(){function r(){}return r.prototype.ACTION=function(e){return e.call(this)},r.prototype.consume=function(e,t,i){return this.consumeInternal(t,e,i)},r.prototype.subrule=function(e,t,i){return this.subruleInternal(t,e,i)},r.prototype.option=function(e,t){return this.optionInternal(t,e)},r.prototype.or=function(e,t){return this.orInternal(t,e)},r.prototype.many=function(e,t){return this.manyInternal(e,t)},r.prototype.atLeastOne=function(e,t){return this.atLeastOneInternal(e,t)},r.prototype.CONSUME=function(e,t){return this.consumeInternal(e,0,t)},r.prototype.CONSUME1=function(e,t){return this.consumeInternal(e,1,t)},r.prototype.CONSUME2=function(e,t){return this.consumeInternal(e,2,t)},r.prototype.CONSUME3=function(e,t){return this.consumeInternal(e,3,t)},r.prototype.CONSUME4=function(e,t){return this.consumeInternal(e,4,t)},r.prototype.CONSUME5=function(e,t){return this.consumeInternal(e,5,t)},r.prototype.CONSUME6=function(e,t){return this.consumeInternal(e,6,t)},r.prototype.CONSUME7=function(e,t){return this.consumeInternal(e,7,t)},r.prototype.CONSUME8=function(e,t){return this.consumeInternal(e,8,t)},r.prototype.CONSUME9=function(e,t){return this.consumeInternal(e,9,t)},r.prototype.SUBRULE=function(e,t){return this.subruleInternal(e,0,t)},r.prototype.SUBRULE1=function(e,t){return this.subruleInternal(e,1,t)},r.prototype.SUBRULE2=function(e,t){return this.subruleInternal(e,2,t)},r.prototype.SUBRULE3=function(e,t){return this.subruleInternal(e,3,t)},r.prototype.SUBRULE4=function(e,t){return this.subruleInternal(e,4,t)},r.prototype.SUBRULE5=function(e,t){return this.subruleInternal(e,5,t)},r.prototype.SUBRULE6=function(e,t){return this.subruleInternal(e,6,t)},r.prototype.SUBRULE7=function(e,t){return this.subruleInternal(e,7,t)},r.prototype.SUBRULE8=function(e,t){return this.subruleInternal(e,8,t)},r.prototype.SUBRULE9=function(e,t){return this.subruleInternal(e,9,t)},r.prototype.OPTION=function(e){return this.optionInternal(e,0)},r.prototype.OPTION1=function(e){return this.optionInternal(e,1)},r.prototype.OPTION2=function(e){return this.optionInternal(e,2)},r.prototype.OPTION3=function(e){return this.optionInternal(e,3)},r.prototype.OPTION4=function(e){return this.optionInternal(e,4)},r.prototype.OPTION5=function(e){return this.optionInternal(e,5)},r.prototype.OPTION6=function(e){return this.optionInternal(e,6)},r.prototype.OPTION7=function(e){return this.optionInternal(e,7)},r.prototype.OPTION8=function(e){return this.optionInternal(e,8)},r.prototype.OPTION9=function(e){return this.optionInternal(e,9)},r.prototype.OR=function(e){return this.orInternal(e,0)},r.prototype.OR1=function(e){return this.orInternal(e,1)},r.prototype.OR2=function(e){return this.orInternal(e,2)},r.prototype.OR3=function(e){return this.orInternal(e,3)},r.prototype.OR4=function(e){return this.orInternal(e,4)},r.prototype.OR5=function(e){return this.orInternal(e,5)},r.prototype.OR6=function(e){return this.orInternal(e,6)},r.prototype.OR7=function(e){return this.orInternal(e,7)},r.prototype.OR8=function(e){return this.orInternal(e,8)},r.prototype.OR9=function(e){return this.orInternal(e,9)},r.prototype.MANY=function(e){this.manyInternal(0,e)},r.prototype.MANY1=function(e){this.manyInternal(1,e)},r.prototype.MANY2=function(e){this.manyInternal(2,e)},r.prototype.MANY3=function(e){this.manyInternal(3,e)},r.prototype.MANY4=function(e){this.manyInternal(4,e)},r.prototype.MANY5=function(e){this.manyInternal(5,e)},r.prototype.MANY6=function(e){this.manyInternal(6,e)},r.prototype.MANY7=function(e){this.manyInternal(7,e)},r.prototype.MANY8=function(e){this.manyInternal(8,e)},r.prototype.MANY9=function(e){this.manyInternal(9,e)},r.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},r.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},r.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},r.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},r.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},r.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},r.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},r.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},r.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},r.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},r.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},r.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},r.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},r.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},r.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},r.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},r.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},r.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},r.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},r.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},r.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},r.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},r.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},r.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},r.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},r.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},r.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},r.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},r.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},r.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},r.prototype.RULE=function(e,t,i){if(i===void 0&&(i=$S.DEFAULT_RULE_CONFIG),(0,kG.contains)(this.definedRulesNames,e)){var n=eye.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:$S.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,t,i);return this[e]=o,o},r.prototype.OVERRIDE_RULE=function(e,t,i){i===void 0&&(i=$S.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,tye.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,t,i);return this[e]=s,s},r.prototype.BACKTRACK=function(e,t){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,t),!0}catch(n){if((0,$Ie.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},r.prototype.getGAstProductions=function(){return this.gastProductionsCache},r.prototype.getSerializedGastProductions=function(){return(0,rye.serializeGrammar)((0,kG.values)(this.gastProductionsCache))},r}();sy.RecognizerApi=iye});var FG=w(oy=>{"use strict";Object.defineProperty(oy,"__esModule",{value:!0});oy.RecognizerEngine=void 0;var Fr=Yt(),ts=ty(),ay=bg(),PG=Kp(),Sg=Up(),DG=es(),nye=VS(),RG=ZA(),Yp=Eg(),sye=XS(),oye=function(){function r(){}return r.prototype.initRecognizerEngine=function(e,t){if(this.className=(0,sye.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=Yp.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Fr.has)(t,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a <serializedGrammar> property. - See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 - For Further details.`);if((0,Fr.isArray)(e)){if((0,Fr.isEmpty)(e))throw Error(`A Token Vocabulary cannot be empty. - Note that the first argument for the parser constructor - is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. - See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 - For Further details.`)}if((0,Fr.isArray)(e))this.tokensMap=(0,Fr.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Fr.has)(e,"modes")&&(0,Fr.every)((0,Fr.flatten)((0,Fr.values)(e.modes)),Yp.isTokenType)){var i=(0,Fr.flatten)((0,Fr.values)(e.modes)),n=(0,Fr.uniq)(i);this.tokensMap=(0,Fr.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Fr.isObject)(e))this.tokensMap=(0,Fr.cloneObj)(e);else throw new Error("<tokensDictionary> argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=RG.EOF;var s=(0,Fr.every)((0,Fr.values)(e),function(o){return(0,Fr.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?Yp.tokenStructuredMatcherNoCategories:Yp.tokenStructuredMatcher,(0,Yp.augmentTokenTypes)((0,Fr.values)(this.tokensMap))},r.prototype.defineRule=function(e,t,i){if(this.selfAnalysisDone)throw Error("Grammar rule <"+e+`> may not be defined after the 'performSelfAnalysis' method has been called' -Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);var n=(0,Fr.has)(i,"resyncEnabled")?i.resyncEnabled:DG.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Fr.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:DG.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<<ts.BITS_FOR_METHOD_TYPE+ts.BITS_FOR_OCCURRENCE_IDX;this.ruleShortNameIdx++,this.shortRuleNameToFull[o]=e,this.fullRuleNameToShort[e]=o;function a(u){try{if(this.outputCst===!0){t.apply(this,u);var g=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(g),g}else return t.apply(this,u)}catch(f){return this.invokeRuleCatch(f,n,s)}finally{this.ruleFinallyStateUpdate()}}var l=function(u,g){return u===void 0&&(u=0),this.ruleInvocationStateUpdate(o,e,u),a.call(this,g)},c="ruleName";return l[c]=e,l.originalGrammarAction=t,l},r.prototype.invokeRuleCatch=function(e,t,i){var n=this.RULE_STACK.length===1,s=t&&!this.isBackTracking()&&this.recoveryEnabled;if((0,ay.isRecognitionException)(e)){var o=e;if(s){var a=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(a))if(o.resyncedTokens=this.reSyncTo(a),this.outputCst){var l=this.CST_STACK[this.CST_STACK.length-1];return l.recoveredNode=!0,l}else return i();else{if(this.outputCst){var l=this.CST_STACK[this.CST_STACK.length-1];l.recoveredNode=!0,o.partialCstResult=l}throw o}}else{if(n)return this.moveToTerminatedState(),i();throw o}}else throw e},r.prototype.optionInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(ts.OPTION_IDX,t);return this.optionInternalLogic(e,t,i)},r.prototype.optionInternalLogic=function(e,t,i){var n=this,s=this.getLaFuncFromCache(i),o,a;if(e.DEF!==void 0){if(o=e.DEF,a=e.GATE,a!==void 0){var l=s;s=function(){return a.call(n)&&l.call(n)}}}else o=e;if(s.call(this)===!0)return o.call(this)},r.prototype.atLeastOneInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(ts.AT_LEAST_ONE_IDX,e);return this.atLeastOneInternalLogic(e,t,i)},r.prototype.atLeastOneInternalLogic=function(e,t,i){var n=this,s=this.getLaFuncFromCache(i),o,a;if(t.DEF!==void 0){if(o=t.DEF,a=t.GATE,a!==void 0){var l=s;s=function(){return a.call(n)&&l.call(n)}}}else o=t;if(s.call(this)===!0)for(var c=this.doSingleRepetition(o);s.call(this)===!0&&c===!0;)c=this.doSingleRepetition(o);else throw this.raiseEarlyExitException(e,PG.PROD_TYPE.REPETITION_MANDATORY,t.ERR_MSG);this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,t],s,ts.AT_LEAST_ONE_IDX,e,Sg.NextTerminalAfterAtLeastOneWalker)},r.prototype.atLeastOneSepFirstInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(ts.AT_LEAST_ONE_SEP_IDX,e);this.atLeastOneSepFirstInternalLogic(e,t,i)},r.prototype.atLeastOneSepFirstInternalLogic=function(e,t,i){var n=this,s=t.DEF,o=t.SEP,a=this.getLaFuncFromCache(i);if(a.call(this)===!0){s.call(this);for(var l=function(){return n.tokenMatcher(n.LA(1),o)};this.tokenMatcher(this.LA(1),o)===!0;)this.CONSUME(o),s.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,o,l,s,Sg.NextTerminalAfterAtLeastOneSepWalker],l,ts.AT_LEAST_ONE_SEP_IDX,e,Sg.NextTerminalAfterAtLeastOneSepWalker)}else throw this.raiseEarlyExitException(e,PG.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,t.ERR_MSG)},r.prototype.manyInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(ts.MANY_IDX,e);return this.manyInternalLogic(e,t,i)},r.prototype.manyInternalLogic=function(e,t,i){var n=this,s=this.getLaFuncFromCache(i),o,a;if(t.DEF!==void 0){if(o=t.DEF,a=t.GATE,a!==void 0){var l=s;s=function(){return a.call(n)&&l.call(n)}}}else o=t;for(var c=!0;s.call(this)===!0&&c===!0;)c=this.doSingleRepetition(o);this.attemptInRepetitionRecovery(this.manyInternal,[e,t],s,ts.MANY_IDX,e,Sg.NextTerminalAfterManyWalker,c)},r.prototype.manySepFirstInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(ts.MANY_SEP_IDX,e);this.manySepFirstInternalLogic(e,t,i)},r.prototype.manySepFirstInternalLogic=function(e,t,i){var n=this,s=t.DEF,o=t.SEP,a=this.getLaFuncFromCache(i);if(a.call(this)===!0){s.call(this);for(var l=function(){return n.tokenMatcher(n.LA(1),o)};this.tokenMatcher(this.LA(1),o)===!0;)this.CONSUME(o),s.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,o,l,s,Sg.NextTerminalAfterManySepWalker],l,ts.MANY_SEP_IDX,e,Sg.NextTerminalAfterManySepWalker)}},r.prototype.repetitionSepSecondInternal=function(e,t,i,n,s){for(;i();)this.CONSUME(t),n.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,t,i,n,s],i,ts.AT_LEAST_ONE_SEP_IDX,e,s)},r.prototype.doSingleRepetition=function(e){var t=this.getLexerPosition();e.call(this);var i=this.getLexerPosition();return i>t},r.prototype.orInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(ts.OR_IDX,t),n=(0,Fr.isArray)(e)?e:e.DEF,s=this.getLaFuncFromCache(i),o=s.call(this,n);if(o!==void 0){var a=n[o];return a.ALT.call(this)}this.raiseNoAltException(t,e.ERR_MSG)},r.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){var e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new ay.NotAllInputParsedException(t,e))}},r.prototype.subruleInternal=function(e,t,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,t,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},r.prototype.subruleInternalError=function(e,t,i){throw(0,ay.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,t!==void 0&&t.LABEL!==void 0?t.LABEL:i),delete e.partialCstResult),e},r.prototype.consumeInternal=function(e,t,i){var n;try{var s=this.LA(1);this.tokenMatcher(s,e)===!0?(this.consumeToken(),n=s):this.consumeInternalError(e,s,i)}catch(o){n=this.consumeInternalRecovery(e,t,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},r.prototype.consumeInternalError=function(e,t,i){var n,s=this.LA(0);throw i!==void 0&&i.ERR_MSG?n=i.ERR_MSG:n=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new ay.MismatchedTokenException(n,t,s))},r.prototype.consumeInternalRecovery=function(e,t,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===nye.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},r.prototype.saveRecogState=function(){var e=this.errors,t=(0,Fr.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}},r.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},r.prototype.ruleInvocationStateUpdate=function(e,t,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t,e)},r.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},r.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},r.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},r.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),RG.EOF)},r.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},r}();oy.RecognizerEngine=oye});var LG=w(Ay=>{"use strict";Object.defineProperty(Ay,"__esModule",{value:!0});Ay.ErrorHandler=void 0;var ev=bg(),tv=Yt(),NG=Kp(),aye=es(),Aye=function(){function r(){}return r.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,tv.has)(e,"errorMessageProvider")?e.errorMessageProvider:aye.DEFAULT_PARSER_CONFIG.errorMessageProvider},r.prototype.SAVE_ERROR=function(e){if((0,ev.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,tv.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(r.prototype,"errors",{get:function(){return(0,tv.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),r.prototype.raiseEarlyExitException=function(e,t,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,NG.getLookaheadPathsForOptionalProd)(e,s,t,this.maxLookahead),a=o[0],l=[],c=1;c<=this.maxLookahead;c++)l.push(this.LA(c));var u=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:a,actual:l,previous:this.LA(0),customUserDescription:i,ruleName:n});throw this.SAVE_ERROR(new ev.EarlyExitException(u,this.LA(1),this.LA(0)))},r.prototype.raiseNoAltException=function(e,t){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,NG.getLookaheadPathsForOr)(e,n,this.maxLookahead),o=[],a=1;a<=this.maxLookahead;a++)o.push(this.LA(a));var l=this.LA(0),c=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:s,actual:o,previous:l,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new ev.NoViableAltException(c,this.LA(1),l))},r}();Ay.ErrorHandler=Aye});var MG=w(ly=>{"use strict";Object.defineProperty(ly,"__esModule",{value:!0});ly.ContentAssist=void 0;var TG=Up(),OG=Yt(),lye=function(){function r(){}return r.prototype.initContentAssist=function(){},r.prototype.computeContentAssist=function(e,t){var i=this.gastProductionsCache[e];if((0,OG.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,TG.nextPossibleTokensAfter)([i],t,this.tokenMatcher,this.maxLookahead)},r.prototype.getNextPossibleTokenTypes=function(e){var t=(0,OG.first)(e.ruleStack),i=this.getGAstProductions(),n=i[t],s=new TG.NextAfterTokenWalker(n,e).startWalking();return s},r}();ly.ContentAssist=lye});var JG=w(cy=>{"use strict";Object.defineProperty(cy,"__esModule",{value:!0});cy.GastRecorder=void 0;var vn=Yt(),Jo=bn(),cye=Rp(),UG=Eg(),KG=ZA(),uye=es(),gye=ty(),uy={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(uy);var HG=!0,jG=Math.pow(2,gye.BITS_FOR_OCCURRENCE_IDX)-1,GG=(0,KG.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:cye.Lexer.NA});(0,UG.augmentTokenTypes)([GG]);var YG=(0,KG.createTokenInstance)(GG,`This IToken indicates the Parser is in Recording Phase - See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(YG);var fye={name:`This CSTNode indicates the Parser is in Recording Phase - See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},pye=function(){function r(){}return r.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},r.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var t=function(n){var s=n>0?n:"";e["CONSUME"+s]=function(o,a){return this.consumeInternalRecord(o,n,a)},e["SUBRULE"+s]=function(o,a){return this.subruleInternalRecord(o,n,a)},e["OPTION"+s]=function(o){return this.optionInternalRecord(o,n)},e["OR"+s]=function(o){return this.orInternalRecord(o,n)},e["MANY"+s]=function(o){this.manyInternalRecord(n,o)},e["MANY_SEP"+s]=function(o){this.manySepFirstInternalRecord(n,o)},e["AT_LEAST_ONE"+s]=function(o){this.atLeastOneInternalRecord(n,o)},e["AT_LEAST_ONE_SEP"+s]=function(o){this.atLeastOneSepFirstInternalRecord(n,o)}},i=0;i<10;i++)t(i);e.consume=function(n,s,o){return this.consumeInternalRecord(s,n,o)},e.subrule=function(n,s,o){return this.subruleInternalRecord(s,n,o)},e.option=function(n,s){return this.optionInternalRecord(s,n)},e.or=function(n,s){return this.orInternalRecord(s,n)},e.many=function(n,s){this.manyInternalRecord(n,s)},e.atLeastOne=function(n,s){this.atLeastOneInternalRecord(n,s)},e.ACTION=e.ACTION_RECORD,e.BACKTRACK=e.BACKTRACK_RECORD,e.LA=e.LA_RECORD})},r.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var t=0;t<10;t++){var i=t>0?t:"";delete e["CONSUME"+i],delete e["SUBRULE"+i],delete e["OPTION"+i],delete e["OR"+i],delete e["MANY"+i],delete e["MANY_SEP"+i],delete e["AT_LEAST_ONE"+i],delete e["AT_LEAST_ONE_SEP"+i]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})},r.prototype.ACTION_RECORD=function(e){},r.prototype.BACKTRACK_RECORD=function(e,t){return function(){return!0}},r.prototype.LA_RECORD=function(e){return uye.END_OF_FILE},r.prototype.topLevelRuleRecord=function(e,t){try{var i=new Jo.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),t.call(this),this.recordingProdStack.pop(),i}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` - This error was thrown during the "grammar recording phase" For more info see: - https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch(s){throw n}throw n}},r.prototype.optionInternalRecord=function(e,t){return qp.call(this,Jo.Option,e,t)},r.prototype.atLeastOneInternalRecord=function(e,t){qp.call(this,Jo.RepetitionMandatory,t,e)},r.prototype.atLeastOneSepFirstInternalRecord=function(e,t){qp.call(this,Jo.RepetitionMandatoryWithSeparator,t,e,HG)},r.prototype.manyInternalRecord=function(e,t){qp.call(this,Jo.Repetition,t,e)},r.prototype.manySepFirstInternalRecord=function(e,t){qp.call(this,Jo.RepetitionWithSeparator,t,e,HG)},r.prototype.orInternalRecord=function(e,t){return hye.call(this,e,t)},r.prototype.subruleInternalRecord=function(e,t,i){if(gy(t),!e||(0,vn.has)(e,"ruleName")===!1){var n=new Error("<SUBRULE"+qG(t)+"> argument is invalid"+(" expecting a Parser method reference but got: <"+JSON.stringify(e)+">")+(` - inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,vn.peek)(this.recordingProdStack),o=e.ruleName,a=new Jo.NonTerminal({idx:t,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?fye:uy},r.prototype.consumeInternalRecord=function(e,t,i){if(gy(t),!(0,UG.hasShortKeyProperty)(e)){var n=new Error("<CONSUME"+qG(t)+"> argument is invalid"+(" expecting a TokenType reference but got: <"+JSON.stringify(e)+">")+(` - inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,vn.peek)(this.recordingProdStack),o=new Jo.Terminal({idx:t,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),YG},r}();cy.GastRecorder=pye;function qp(r,e,t,i){i===void 0&&(i=!1),gy(t);var n=(0,vn.peek)(this.recordingProdStack),s=(0,vn.isFunction)(e)?e:e.DEF,o=new r({definition:[],idx:t});return i&&(o.separator=e.SEP),(0,vn.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),uy}function hye(r,e){var t=this;gy(e);var i=(0,vn.peek)(this.recordingProdStack),n=(0,vn.isArray)(r)===!1,s=n===!1?r:r.DEF,o=new Jo.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&r.IGNORE_AMBIGUITIES===!0});(0,vn.has)(r,"MAX_LOOKAHEAD")&&(o.maxLookahead=r.MAX_LOOKAHEAD);var a=(0,vn.some)(s,function(l){return(0,vn.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,vn.forEach)(s,function(l){var c=new Jo.Alternative({definition:[]});o.definition.push(c),(0,vn.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,vn.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),t.recordingProdStack.push(c),l.ALT.call(t),t.recordingProdStack.pop()}),uy}function qG(r){return r===0?"":""+r}function gy(r){if(r<0||r>jG){var e=new Error("Invalid DSL Method idx value: <"+r+`> - `+("Idx value must be a none negative value smaller than "+(jG+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var zG=w(fy=>{"use strict";Object.defineProperty(fy,"__esModule",{value:!0});fy.PerformanceTracer=void 0;var WG=Yt(),dye=es(),Cye=function(){function r(){}return r.prototype.initPerformanceTracer=function(e){if((0,WG.has)(e,"traceInitPerf")){var t=e.traceInitPerf,i=typeof t=="number";this.traceInitMaxIdent=i?t:Infinity,this.traceInitPerf=i?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=dye.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent<this.traceInitMaxIdent&&console.log(i+"--> <"+e+">");var n=(0,WG.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&a(i+"<-- <"+e+"> time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r}();fy.PerformanceTracer=Cye});var _G=w(hy=>{"use strict";Object.defineProperty(hy,"__esModule",{value:!0});hy.applyMixins=void 0;function mye(r,e){e.forEach(function(t){var i=t.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(r.prototype,n,s):r.prototype[n]=t.prototype[n]}})})}hy.applyMixins=mye});var es=w(Er=>{"use strict";var VG=Er&&Er.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Er,"__esModule",{value:!0});Er.EmbeddedActionsParser=Er.CstParser=Er.Parser=Er.EMPTY_ALT=Er.ParserDefinitionErrorType=Er.DEFAULT_RULE_CONFIG=Er.DEFAULT_PARSER_CONFIG=Er.END_OF_FILE=void 0;var an=Yt(),Eye=Lj(),XG=ZA(),ZG=Op(),$G=aG(),Iye=VS(),yye=pG(),wye=QG(),Bye=vG(),bye=xG(),Qye=FG(),Sye=LG(),vye=MG(),kye=JG(),xye=zG(),Pye=_G();Er.END_OF_FILE=(0,XG.createTokenInstance)(XG.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(Er.END_OF_FILE);Er.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:ZG.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});Er.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var Dye;(function(r){r[r.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",r[r.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",r[r.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",r[r.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",r[r.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",r[r.LEFT_RECURSION=5]="LEFT_RECURSION",r[r.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",r[r.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",r[r.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",r[r.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",r[r.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",r[r.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",r[r.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(Dye=Er.ParserDefinitionErrorType||(Er.ParserDefinitionErrorType={}));function Rye(r){return r===void 0&&(r=void 0),function(){return r}}Er.EMPTY_ALT=Rye;var py=function(){function r(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(t),i.initLexerAdapter(),i.initLooksAhead(t),i.initRecognizerEngine(e,t),i.initRecoverable(t),i.initTreeBuilder(t),i.initContentAssist(),i.initGastRecorder(t),i.initPerformanceTracer(t),(0,an.has)(t,"ignoredIssues"))throw new Error(`The <ignoredIssues> IParserConfig property has been deprecated. - Please use the <IGNORE_AMBIGUITIES> flag on the relevant DSL method instead. - See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES - For further details.`);this.skipValidations=(0,an.has)(t,"skipValidations")?t.skipValidations:Er.DEFAULT_PARSER_CONFIG.skipValidations}return r.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},r.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var t;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,an.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,an.forEach)(e.definedRulesNames,function(s){var o=e[s],a=o.originalGrammarAction,l=void 0;e.TRACE_INIT(s+" Rule",function(){l=e.topLevelRuleRecord(s,a)}),e.gastProductionsCache[s]=l})}finally{e.disableRecording()}});var n=[];if(e.TRACE_INIT("Grammar Resolving",function(){n=(0,$G.resolveGrammar)({rules:(0,an.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,an.isEmpty)(n)&&e.skipValidations===!1){var s=(0,$G.validateGrammar)({rules:(0,an.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,an.values)(e.tokensMap),errMsgProvider:ZG.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,an.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,Eye.computeAllProdsFollows)((0,an.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,an.values)(e.gastProductionsCache))})),!r.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,an.isEmpty)(e.definitionErrors))throw t=(0,an.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: - `+t.join(` -------------------------------- -`))})},r.DEFER_DEFINITION_ERRORS_HANDLING=!1,r}();Er.Parser=py;(0,Pye.applyMixins)(py,[Iye.Recoverable,yye.LooksAhead,wye.TreeBuilder,Bye.LexerAdapter,Qye.RecognizerEngine,bye.RecognizerApi,Sye.ErrorHandler,vye.ContentAssist,kye.GastRecorder,xye.PerformanceTracer]);var Fye=function(r){VG(e,r);function e(t,i){i===void 0&&(i=Er.DEFAULT_PARSER_CONFIG);var n=this,s=(0,an.cloneObj)(i);return s.outputCst=!0,n=r.call(this,t,s)||this,n}return e}(py);Er.CstParser=Fye;var Nye=function(r){VG(e,r);function e(t,i){i===void 0&&(i=Er.DEFAULT_PARSER_CONFIG);var n=this,s=(0,an.cloneObj)(i);return s.outputCst=!1,n=r.call(this,t,s)||this,n}return e}(py);Er.EmbeddedActionsParser=Nye});var tY=w(dy=>{"use strict";Object.defineProperty(dy,"__esModule",{value:!0});dy.createSyntaxDiagramsCode=void 0;var eY=yS();function Lye(r,e){var t=e===void 0?{}:e,i=t.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+eY.VERSION+"/diagrams/":i,s=t.css,o=s===void 0?"https://unpkg.com/chevrotain@"+eY.VERSION+"/diagrams/diagrams.css":s,a=` -<!-- This is a generated file --> -<!DOCTYPE html> -<meta charset="utf-8"> -<style> - body { - background-color: hsl(30, 20%, 95%) - } -</style> - -`,l=` -<link rel='stylesheet' href='`+o+`'> -`,c=` -<script src='`+n+`vendor/railroad-diagrams.js'></script> -<script src='`+n+`src/diagrams_builder.js'></script> -<script src='`+n+`src/diagrams_behavior.js'></script> -<script src='`+n+`src/main.js'></script> -`,u=` -<div id="diagrams" align="center"></div> -`,g=` -<script> - window.serializedGrammar = `+JSON.stringify(r,null," ")+`; -</script> -`,f=` -<script> - var diagramsDiv = document.getElementById("diagrams"); - main.drawDiagramsFromSerializedGrammar(serializedGrammar, diagramsDiv); -</script> -`;return a+l+c+u+g+f}dy.createSyntaxDiagramsCode=Lye});var nY=w(Ve=>{"use strict";Object.defineProperty(Ve,"__esModule",{value:!0});Ve.Parser=Ve.createSyntaxDiagramsCode=Ve.clearCache=Ve.GAstVisitor=Ve.serializeProduction=Ve.serializeGrammar=Ve.Terminal=Ve.Rule=Ve.RepetitionWithSeparator=Ve.RepetitionMandatoryWithSeparator=Ve.RepetitionMandatory=Ve.Repetition=Ve.Option=Ve.NonTerminal=Ve.Alternative=Ve.Alternation=Ve.defaultLexerErrorProvider=Ve.NoViableAltException=Ve.NotAllInputParsedException=Ve.MismatchedTokenException=Ve.isRecognitionException=Ve.EarlyExitException=Ve.defaultParserErrorProvider=Ve.tokenName=Ve.tokenMatcher=Ve.tokenLabel=Ve.EOF=Ve.createTokenInstance=Ve.createToken=Ve.LexerDefinitionErrorType=Ve.Lexer=Ve.EMPTY_ALT=Ve.ParserDefinitionErrorType=Ve.EmbeddedActionsParser=Ve.CstParser=Ve.VERSION=void 0;var Tye=yS();Object.defineProperty(Ve,"VERSION",{enumerable:!0,get:function(){return Tye.VERSION}});var Cy=es();Object.defineProperty(Ve,"CstParser",{enumerable:!0,get:function(){return Cy.CstParser}});Object.defineProperty(Ve,"EmbeddedActionsParser",{enumerable:!0,get:function(){return Cy.EmbeddedActionsParser}});Object.defineProperty(Ve,"ParserDefinitionErrorType",{enumerable:!0,get:function(){return Cy.ParserDefinitionErrorType}});Object.defineProperty(Ve,"EMPTY_ALT",{enumerable:!0,get:function(){return Cy.EMPTY_ALT}});var rY=Rp();Object.defineProperty(Ve,"Lexer",{enumerable:!0,get:function(){return rY.Lexer}});Object.defineProperty(Ve,"LexerDefinitionErrorType",{enumerable:!0,get:function(){return rY.LexerDefinitionErrorType}});var vg=ZA();Object.defineProperty(Ve,"createToken",{enumerable:!0,get:function(){return vg.createToken}});Object.defineProperty(Ve,"createTokenInstance",{enumerable:!0,get:function(){return vg.createTokenInstance}});Object.defineProperty(Ve,"EOF",{enumerable:!0,get:function(){return vg.EOF}});Object.defineProperty(Ve,"tokenLabel",{enumerable:!0,get:function(){return vg.tokenLabel}});Object.defineProperty(Ve,"tokenMatcher",{enumerable:!0,get:function(){return vg.tokenMatcher}});Object.defineProperty(Ve,"tokenName",{enumerable:!0,get:function(){return vg.tokenName}});var Oye=Op();Object.defineProperty(Ve,"defaultParserErrorProvider",{enumerable:!0,get:function(){return Oye.defaultParserErrorProvider}});var Jp=bg();Object.defineProperty(Ve,"EarlyExitException",{enumerable:!0,get:function(){return Jp.EarlyExitException}});Object.defineProperty(Ve,"isRecognitionException",{enumerable:!0,get:function(){return Jp.isRecognitionException}});Object.defineProperty(Ve,"MismatchedTokenException",{enumerable:!0,get:function(){return Jp.MismatchedTokenException}});Object.defineProperty(Ve,"NotAllInputParsedException",{enumerable:!0,get:function(){return Jp.NotAllInputParsedException}});Object.defineProperty(Ve,"NoViableAltException",{enumerable:!0,get:function(){return Jp.NoViableAltException}});var Mye=DS();Object.defineProperty(Ve,"defaultLexerErrorProvider",{enumerable:!0,get:function(){return Mye.defaultLexerErrorProvider}});var Wo=bn();Object.defineProperty(Ve,"Alternation",{enumerable:!0,get:function(){return Wo.Alternation}});Object.defineProperty(Ve,"Alternative",{enumerable:!0,get:function(){return Wo.Alternative}});Object.defineProperty(Ve,"NonTerminal",{enumerable:!0,get:function(){return Wo.NonTerminal}});Object.defineProperty(Ve,"Option",{enumerable:!0,get:function(){return Wo.Option}});Object.defineProperty(Ve,"Repetition",{enumerable:!0,get:function(){return Wo.Repetition}});Object.defineProperty(Ve,"RepetitionMandatory",{enumerable:!0,get:function(){return Wo.RepetitionMandatory}});Object.defineProperty(Ve,"RepetitionMandatoryWithSeparator",{enumerable:!0,get:function(){return Wo.RepetitionMandatoryWithSeparator}});Object.defineProperty(Ve,"RepetitionWithSeparator",{enumerable:!0,get:function(){return Wo.RepetitionWithSeparator}});Object.defineProperty(Ve,"Rule",{enumerable:!0,get:function(){return Wo.Rule}});Object.defineProperty(Ve,"Terminal",{enumerable:!0,get:function(){return Wo.Terminal}});var iY=bn();Object.defineProperty(Ve,"serializeGrammar",{enumerable:!0,get:function(){return iY.serializeGrammar}});Object.defineProperty(Ve,"serializeProduction",{enumerable:!0,get:function(){return iY.serializeProduction}});var Uye=Ig();Object.defineProperty(Ve,"GAstVisitor",{enumerable:!0,get:function(){return Uye.GAstVisitor}});function Kye(){console.warn(`The clearCache function was 'soft' removed from the Chevrotain API. - It performs no action other than printing this message. - Please avoid using it as it will be completely removed in the future`)}Ve.clearCache=Kye;var Hye=tY();Object.defineProperty(Ve,"createSyntaxDiagramsCode",{enumerable:!0,get:function(){return Hye.createSyntaxDiagramsCode}});var jye=function(){function r(){throw new Error(`The Parser class has been deprecated, use CstParser or EmbeddedActionsParser instead. -See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_7-0-0`)}return r}();Ve.Parser=jye});var aY=w((eet,sY)=>{var my=nY(),za=my.createToken,oY=my.tokenMatcher,rv=my.Lexer,Gye=my.EmbeddedActionsParser;sY.exports=r=>{let e=za({name:"LogicalOperator",pattern:rv.NA}),t=za({name:"Or",pattern:/\|/,categories:e}),i=za({name:"Xor",pattern:/\^/,categories:e}),n=za({name:"And",pattern:/&/,categories:e}),s=za({name:"Not",pattern:/!/}),o=za({name:"LParen",pattern:/\(/}),a=za({name:"RParen",pattern:/\)/}),l=za({name:"Query",pattern:r}),u=[za({name:"WhiteSpace",pattern:/\s+/,group:rv.SKIPPED}),t,i,n,o,a,s,e,l],g=new rv(u);class f extends Gye{constructor(p){super(u);this.RULE("expression",()=>this.SUBRULE(this.logicalExpression)),this.RULE("logicalExpression",()=>{let y=this.SUBRULE(this.atomicExpression);return this.MANY(()=>{let b=y,v=this.CONSUME(e),k=this.SUBRULE2(this.atomicExpression);oY(v,t)?y=T=>b(T)||k(T):oY(v,i)?y=T=>!!(b(T)^k(T)):y=T=>b(T)&&k(T)}),y}),this.RULE("atomicExpression",()=>this.OR([{ALT:()=>this.SUBRULE(this.parenthesisExpression)},{ALT:()=>{let{image:m}=this.CONSUME(l);return y=>y(m)}},{ALT:()=>{this.CONSUME(s);let m=this.SUBRULE(this.atomicExpression);return y=>!m(y)}}])),this.RULE("parenthesisExpression",()=>{let m;return this.CONSUME(o),m=this.SUBRULE(this.expression),this.CONSUME(a),m}),this.performSelfAnalysis()}}return{TinylogicLexer:g,TinylogicParser:f}}});var AY=w(Ey=>{var Yye=aY();Ey.makeParser=(r=/[a-z]+/)=>{let{TinylogicLexer:e,TinylogicParser:t}=Yye(r),i=new t;return(n,s)=>{let o=e.tokenize(n);return i.input=o.tokens,i.expression()(s)}};Ey.parse=Ey.makeParser()});var cY=w((ret,lY)=>{"use strict";lY.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var iv=w((iet,uY)=>{var Wp=cY(),gY={};for(let r of Object.keys(Wp))gY[Wp[r]]=r;var at={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};uY.exports=at;for(let r of Object.keys(at)){if(!("channels"in at[r]))throw new Error("missing channels property: "+r);if(!("labels"in at[r]))throw new Error("missing channel labels property: "+r);if(at[r].labels.length!==at[r].channels)throw new Error("channel and label counts mismatch: "+r);let{channels:e,labels:t}=at[r];delete at[r].channels,delete at[r].labels,Object.defineProperty(at[r],"channels",{value:e}),Object.defineProperty(at[r],"labels",{value:t})}at.rgb.hsl=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.min(e,t,i),s=Math.max(e,t,i),o=s-n,a,l;s===n?a=0:e===s?a=(t-i)/o:t===s?a=2+(i-e)/o:i===s&&(a=4+(e-t)/o),a=Math.min(a*60,360),a<0&&(a+=360);let c=(n+s)/2;return s===n?l=0:c<=.5?l=o/(s+n):l=o/(2-s-n),[a,l*100,c*100]};at.rgb.hsv=function(r){let e,t,i,n,s,o=r[0]/255,a=r[1]/255,l=r[2]/255,c=Math.max(o,a,l),u=c-Math.min(o,a,l),g=function(f){return(c-f)/6/u+1/2};return u===0?(n=0,s=0):(s=u/c,e=g(o),t=g(a),i=g(l),o===c?n=i-t:a===c?n=1/3+e-i:l===c&&(n=2/3+t-e),n<0?n+=1:n>1&&(n-=1)),[n*360,s*100,c*100]};at.rgb.hwb=function(r){let e=r[0],t=r[1],i=r[2],n=at.rgb.hsl(r)[0],s=1/255*Math.min(e,Math.min(t,i));return i=1-1/255*Math.max(e,Math.max(t,i)),[n,s*100,i*100]};at.rgb.cmyk=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.min(1-e,1-t,1-i),s=(1-e-n)/(1-n)||0,o=(1-t-n)/(1-n)||0,a=(1-i-n)/(1-n)||0;return[s*100,o*100,a*100,n*100]};function qye(r,e){return(r[0]-e[0])**2+(r[1]-e[1])**2+(r[2]-e[2])**2}at.rgb.keyword=function(r){let e=gY[r];if(e)return e;let t=Infinity,i;for(let n of Object.keys(Wp)){let s=Wp[n],o=qye(r,s);o<t&&(t=o,i=n)}return i};at.keyword.rgb=function(r){return Wp[r]};at.rgb.xyz=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255;e=e>.04045?((e+.055)/1.055)**2.4:e/12.92,t=t>.04045?((t+.055)/1.055)**2.4:t/12.92,i=i>.04045?((i+.055)/1.055)**2.4:i/12.92;let n=e*.4124+t*.3576+i*.1805,s=e*.2126+t*.7152+i*.0722,o=e*.0193+t*.1192+i*.9505;return[n*100,s*100,o*100]};at.rgb.lab=function(r){let e=at.rgb.xyz(r),t=e[0],i=e[1],n=e[2];t/=95.047,i/=100,n/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,i=i>.008856?i**(1/3):7.787*i+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;let s=116*i-16,o=500*(t-i),a=200*(i-n);return[s,o,a]};at.hsl.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100,n,s,o;if(t===0)return o=i*255,[o,o,o];i<.5?n=i*(1+t):n=i+t-i*t;let a=2*i-n,l=[0,0,0];for(let c=0;c<3;c++)s=e+1/3*-(c-1),s<0&&s++,s>1&&s--,6*s<1?o=a+(n-a)*6*s:2*s<1?o=n:3*s<2?o=a+(n-a)*(2/3-s)*6:o=a,l[c]=o*255;return l};at.hsl.hsv=function(r){let e=r[0],t=r[1]/100,i=r[2]/100,n=t,s=Math.max(i,.01);i*=2,t*=i<=1?i:2-i,n*=s<=1?s:2-s;let o=(i+t)/2,a=i===0?2*n/(s+n):2*t/(i+t);return[e,a*100,o*100]};at.hsv.rgb=function(r){let e=r[0]/60,t=r[1]/100,i=r[2]/100,n=Math.floor(e)%6,s=e-Math.floor(e),o=255*i*(1-t),a=255*i*(1-t*s),l=255*i*(1-t*(1-s));switch(i*=255,n){case 0:return[i,l,o];case 1:return[a,i,o];case 2:return[o,i,l];case 3:return[o,a,i];case 4:return[l,o,i];case 5:return[i,o,a]}};at.hsv.hsl=function(r){let e=r[0],t=r[1]/100,i=r[2]/100,n=Math.max(i,.01),s,o;o=(2-t)*i;let a=(2-t)*n;return s=t*n,s/=a<=1?a:2-a,s=s||0,o/=2,[e,s*100,o*100]};at.hwb.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100,n=t+i,s;n>1&&(t/=n,i/=n);let o=Math.floor(6*e),a=1-i;s=6*e-o,(o&1)!=0&&(s=1-s);let l=t+s*(a-t),c,u,g;switch(o){default:case 6:case 0:c=a,u=l,g=t;break;case 1:c=l,u=a,g=t;break;case 2:c=t,u=a,g=l;break;case 3:c=t,u=l,g=a;break;case 4:c=l,u=t,g=a;break;case 5:c=a,u=t,g=l;break}return[c*255,u*255,g*255]};at.cmyk.rgb=function(r){let e=r[0]/100,t=r[1]/100,i=r[2]/100,n=r[3]/100,s=1-Math.min(1,e*(1-n)+n),o=1-Math.min(1,t*(1-n)+n),a=1-Math.min(1,i*(1-n)+n);return[s*255,o*255,a*255]};at.xyz.rgb=function(r){let e=r[0]/100,t=r[1]/100,i=r[2]/100,n,s,o;return n=e*3.2406+t*-1.5372+i*-.4986,s=e*-.9689+t*1.8758+i*.0415,o=e*.0557+t*-.204+i*1.057,n=n>.0031308?1.055*n**(1/2.4)-.055:n*12.92,s=s>.0031308?1.055*s**(1/2.4)-.055:s*12.92,o=o>.0031308?1.055*o**(1/2.4)-.055:o*12.92,n=Math.min(Math.max(0,n),1),s=Math.min(Math.max(0,s),1),o=Math.min(Math.max(0,o),1),[n*255,s*255,o*255]};at.xyz.lab=function(r){let e=r[0],t=r[1],i=r[2];e/=95.047,t/=100,i/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,t=t>.008856?t**(1/3):7.787*t+16/116,i=i>.008856?i**(1/3):7.787*i+16/116;let n=116*t-16,s=500*(e-t),o=200*(t-i);return[n,s,o]};at.lab.xyz=function(r){let e=r[0],t=r[1],i=r[2],n,s,o;s=(e+16)/116,n=t/500+s,o=s-i/200;let a=s**3,l=n**3,c=o**3;return s=a>.008856?a:(s-16/116)/7.787,n=l>.008856?l:(n-16/116)/7.787,o=c>.008856?c:(o-16/116)/7.787,n*=95.047,s*=100,o*=108.883,[n,s,o]};at.lab.lch=function(r){let e=r[0],t=r[1],i=r[2],n;n=Math.atan2(i,t)*360/2/Math.PI,n<0&&(n+=360);let o=Math.sqrt(t*t+i*i);return[e,o,n]};at.lch.lab=function(r){let e=r[0],t=r[1],n=r[2]/360*2*Math.PI,s=t*Math.cos(n),o=t*Math.sin(n);return[e,s,o]};at.rgb.ansi16=function(r,e=null){let[t,i,n]=r,s=e===null?at.rgb.hsv(r)[2]:e;if(s=Math.round(s/50),s===0)return 30;let o=30+(Math.round(n/255)<<2|Math.round(i/255)<<1|Math.round(t/255));return s===2&&(o+=60),o};at.hsv.ansi16=function(r){return at.rgb.ansi16(at.hsv.rgb(r),r[2])};at.rgb.ansi256=function(r){let e=r[0],t=r[1],i=r[2];return e===t&&t===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(i/255*5)};at.ansi16.rgb=function(r){let e=r%10;if(e===0||e===7)return r>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let t=(~~(r>50)+1)*.5,i=(e&1)*t*255,n=(e>>1&1)*t*255,s=(e>>2&1)*t*255;return[i,n,s]};at.ansi256.rgb=function(r){if(r>=232){let s=(r-232)*10+8;return[s,s,s]}r-=16;let e,t=Math.floor(r/36)/5*255,i=Math.floor((e=r%36)/6)/5*255,n=e%6/5*255;return[t,i,n]};at.rgb.hex=function(r){let t=(((Math.round(r[0])&255)<<16)+((Math.round(r[1])&255)<<8)+(Math.round(r[2])&255)).toString(16).toUpperCase();return"000000".substring(t.length)+t};at.hex.rgb=function(r){let e=r.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let t=e[0];e[0].length===3&&(t=t.split("").map(a=>a+a).join(""));let i=parseInt(t,16),n=i>>16&255,s=i>>8&255,o=i&255;return[n,s,o]};at.rgb.hcg=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.max(Math.max(e,t),i),s=Math.min(Math.min(e,t),i),o=n-s,a,l;return o<1?a=s/(1-o):a=0,o<=0?l=0:n===e?l=(t-i)/o%6:n===t?l=2+(i-e)/o:l=4+(e-t)/o,l/=6,l%=1,[l*360,o*100,a*100]};at.hsl.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=t<.5?2*e*t:2*e*(1-t),n=0;return i<1&&(n=(t-.5*i)/(1-i)),[r[0],i*100,n*100]};at.hsv.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=e*t,n=0;return i<1&&(n=(t-i)/(1-i)),[r[0],i*100,n*100]};at.hcg.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100;if(t===0)return[i*255,i*255,i*255];let n=[0,0,0],s=e%1*6,o=s%1,a=1-o,l=0;switch(Math.floor(s)){case 0:n[0]=1,n[1]=o,n[2]=0;break;case 1:n[0]=a,n[1]=1,n[2]=0;break;case 2:n[0]=0,n[1]=1,n[2]=o;break;case 3:n[0]=0,n[1]=a,n[2]=1;break;case 4:n[0]=o,n[1]=0,n[2]=1;break;default:n[0]=1,n[1]=0,n[2]=a}return l=(1-t)*i,[(t*n[0]+l)*255,(t*n[1]+l)*255,(t*n[2]+l)*255]};at.hcg.hsv=function(r){let e=r[1]/100,t=r[2]/100,i=e+t*(1-e),n=0;return i>0&&(n=e/i),[r[0],n*100,i*100]};at.hcg.hsl=function(r){let e=r[1]/100,i=r[2]/100*(1-e)+.5*e,n=0;return i>0&&i<.5?n=e/(2*i):i>=.5&&i<1&&(n=e/(2*(1-i))),[r[0],n*100,i*100]};at.hcg.hwb=function(r){let e=r[1]/100,t=r[2]/100,i=e+t*(1-e);return[r[0],(i-e)*100,(1-i)*100]};at.hwb.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=1-t,n=i-e,s=0;return n<1&&(s=(i-n)/(1-n)),[r[0],n*100,s*100]};at.apple.rgb=function(r){return[r[0]/65535*255,r[1]/65535*255,r[2]/65535*255]};at.rgb.apple=function(r){return[r[0]/255*65535,r[1]/255*65535,r[2]/255*65535]};at.gray.rgb=function(r){return[r[0]/100*255,r[0]/100*255,r[0]/100*255]};at.gray.hsl=function(r){return[0,0,r[0]]};at.gray.hsv=at.gray.hsl;at.gray.hwb=function(r){return[0,100,r[0]]};at.gray.cmyk=function(r){return[0,0,0,r[0]]};at.gray.lab=function(r){return[r[0],0,0]};at.gray.hex=function(r){let e=Math.round(r[0]/100*255)&255,i=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(i.length)+i};at.rgb.gray=function(r){return[(r[0]+r[1]+r[2])/3/255*100]}});var hY=w((net,fY)=>{var Iy=iv();function Jye(){let r={},e=Object.keys(Iy);for(let t=e.length,i=0;i<t;i++)r[e[i]]={distance:-1,parent:null};return r}function Wye(r){let e=Jye(),t=[r];for(e[r].distance=0;t.length;){let i=t.pop(),n=Object.keys(Iy[i]);for(let s=n.length,o=0;o<s;o++){let a=n[o],l=e[a];l.distance===-1&&(l.distance=e[i].distance+1,l.parent=i,t.unshift(a))}}return e}function zye(r,e){return function(t){return e(r(t))}}function _ye(r,e){let t=[e[r].parent,r],i=Iy[e[r].parent][r],n=e[r].parent;for(;e[n].parent;)t.unshift(e[n].parent),i=zye(Iy[e[n].parent][n],i),n=e[n].parent;return i.conversion=t,i}fY.exports=function(r){let e=Wye(r),t={},i=Object.keys(e);for(let n=i.length,s=0;s<n;s++){let o=i[s];e[o].parent!==null&&(t[o]=_ye(o,e))}return t}});var dY=w((set,pY)=>{var nv=iv(),Vye=hY(),kg={},Xye=Object.keys(nv);function Zye(r){let e=function(...t){let i=t[0];return i==null?i:(i.length>1&&(t=i),r(t))};return"conversion"in r&&(e.conversion=r.conversion),e}function $ye(r){let e=function(...t){let i=t[0];if(i==null)return i;i.length>1&&(t=i);let n=r(t);if(typeof n=="object")for(let s=n.length,o=0;o<s;o++)n[o]=Math.round(n[o]);return n};return"conversion"in r&&(e.conversion=r.conversion),e}Xye.forEach(r=>{kg[r]={},Object.defineProperty(kg[r],"channels",{value:nv[r].channels}),Object.defineProperty(kg[r],"labels",{value:nv[r].labels});let e=Vye(r);Object.keys(e).forEach(i=>{let n=e[i];kg[r][i]=$ye(n),kg[r][i].raw=Zye(n)})});pY.exports=kg});var wY=w((oet,CY)=>{"use strict";var mY=(r,e)=>(...t)=>`[${r(...t)+e}m`,EY=(r,e)=>(...t)=>{let i=r(...t);return`[${38+e};5;${i}m`},IY=(r,e)=>(...t)=>{let i=r(...t);return`[${38+e};2;${i[0]};${i[1]};${i[2]}m`},yy=r=>r,yY=(r,e,t)=>[r,e,t],xg=(r,e,t)=>{Object.defineProperty(r,e,{get:()=>{let i=t();return Object.defineProperty(r,e,{value:i,enumerable:!0,configurable:!0}),i},enumerable:!0,configurable:!0})},sv,Pg=(r,e,t,i)=>{sv===void 0&&(sv=dY());let n=i?10:0,s={};for(let[o,a]of Object.entries(sv)){let l=o==="ansi16"?"ansi":o;o===e?s[l]=r(t,n):typeof a=="object"&&(s[l]=r(a[e],n))}return s};function ewe(){let r=new Map,e={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};e.color.gray=e.color.blackBright,e.bgColor.bgGray=e.bgColor.bgBlackBright,e.color.grey=e.color.blackBright,e.bgColor.bgGrey=e.bgColor.bgBlackBright;for(let[t,i]of Object.entries(e)){for(let[n,s]of Object.entries(i))e[n]={open:`[${s[0]}m`,close:`[${s[1]}m`},i[n]=e[n],r.set(s[0],s[1]);Object.defineProperty(e,t,{value:i,enumerable:!1})}return Object.defineProperty(e,"codes",{value:r,enumerable:!1}),e.color.close="",e.bgColor.close="",xg(e.color,"ansi",()=>Pg(mY,"ansi16",yy,!1)),xg(e.color,"ansi256",()=>Pg(EY,"ansi256",yy,!1)),xg(e.color,"ansi16m",()=>Pg(IY,"rgb",yY,!1)),xg(e.bgColor,"ansi",()=>Pg(mY,"ansi16",yy,!0)),xg(e.bgColor,"ansi256",()=>Pg(EY,"ansi256",yy,!0)),xg(e.bgColor,"ansi16m",()=>Pg(IY,"rgb",yY,!0)),e}Object.defineProperty(CY,"exports",{enumerable:!0,get:ewe})});var bY=w((aet,BY)=>{"use strict";BY.exports=(r,e=process.argv)=>{let t=r.startsWith("-")?"":r.length===1?"-":"--",i=e.indexOf(t+r),n=e.indexOf("--");return i!==-1&&(n===-1||i<n)}});var vY=w((Aet,QY)=>{"use strict";var twe=require("os"),SY=require("tty"),Ds=bY(),{env:gi}=process,rl;Ds("no-color")||Ds("no-colors")||Ds("color=false")||Ds("color=never")?rl=0:(Ds("color")||Ds("colors")||Ds("color=true")||Ds("color=always"))&&(rl=1);"FORCE_COLOR"in gi&&(gi.FORCE_COLOR==="true"?rl=1:gi.FORCE_COLOR==="false"?rl=0:rl=gi.FORCE_COLOR.length===0?1:Math.min(parseInt(gi.FORCE_COLOR,10),3));function ov(r){return r===0?!1:{level:r,hasBasic:!0,has256:r>=2,has16m:r>=3}}function av(r,e){if(rl===0)return 0;if(Ds("color=16m")||Ds("color=full")||Ds("color=truecolor"))return 3;if(Ds("color=256"))return 2;if(r&&!e&&rl===void 0)return 0;let t=rl||0;if(gi.TERM==="dumb")return t;if(process.platform==="win32"){let i=twe.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in gi)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(i=>i in gi)||gi.CI_NAME==="codeship"?1:t;if("TEAMCITY_VERSION"in gi)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(gi.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in gi)return 1;if(gi.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in gi){let i=parseInt((gi.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(gi.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(gi.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(gi.TERM)||"COLORTERM"in gi?1:t}function rwe(r){let e=av(r,r&&r.isTTY);return ov(e)}QY.exports={supportsColor:rwe,stdout:ov(av(!0,SY.isatty(1))),stderr:ov(av(!0,SY.isatty(2)))}});var xY=w((cet,kY)=>{"use strict";var iwe=(r,e,t)=>{let i=r.indexOf(e);if(i===-1)return r;let n=e.length,s=0,o="";do o+=r.substr(s,i-s)+e+t,s=i+n,i=r.indexOf(e,s);while(i!==-1);return o+=r.substr(s),o},nwe=(r,e,t,i)=>{let n=0,s="";do{let o=r[i-1]==="\r";s+=r.substr(n,(o?i-1:i)-n)+e+(o?`\r -`:` -`)+t,n=i+1,i=r.indexOf(` -`,n)}while(i!==-1);return s+=r.substr(n),s};kY.exports={stringReplaceAll:iwe,stringEncaseCRLFWithFirstIndex:nwe}});var NY=w((uet,PY)=>{"use strict";var swe=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,DY=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,owe=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,awe=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,Awe=new Map([["n",` -`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function RY(r){let e=r[0]==="u",t=r[1]==="{";return e&&!t&&r.length===5||r[0]==="x"&&r.length===3?String.fromCharCode(parseInt(r.slice(1),16)):e&&t?String.fromCodePoint(parseInt(r.slice(2,-1),16)):Awe.get(r)||r}function lwe(r,e){let t=[],i=e.trim().split(/\s*,\s*/g),n;for(let s of i){let o=Number(s);if(!Number.isNaN(o))t.push(o);else if(n=s.match(owe))t.push(n[2].replace(awe,(a,l,c)=>l?RY(l):c));else throw new Error(`Invalid Chalk template style argument: ${s} (in style '${r}')`)}return t}function cwe(r){DY.lastIndex=0;let e=[],t;for(;(t=DY.exec(r))!==null;){let i=t[1];if(t[2]){let n=lwe(i,t[2]);e.push([i].concat(n))}else e.push([i])}return e}function FY(r,e){let t={};for(let n of e)for(let s of n.styles)t[s[0]]=n.inverse?null:s.slice(1);let i=r;for(let[n,s]of Object.entries(t))if(!!Array.isArray(s)){if(!(n in i))throw new Error(`Unknown Chalk style: ${n}`);i=s.length>0?i[n](...s):i[n]}return i}PY.exports=(r,e)=>{let t=[],i=[],n=[];if(e.replace(swe,(s,o,a,l,c,u)=>{if(o)n.push(RY(o));else if(l){let g=n.join("");n=[],i.push(t.length===0?g:FY(r,t)(g)),t.push({inverse:a,styles:cwe(l)})}else if(c){if(t.length===0)throw new Error("Found extraneous } in Chalk template literal");i.push(FY(r,t)(n.join(""))),n=[],t.pop()}else n.push(u)}),i.push(n.join("")),t.length>0){let s=`Chalk template literal is missing ${t.length} closing bracket${t.length===1?"":"s"} (\`}\`)`;throw new Error(s)}return i.join("")}});var gv=w((get,LY)=>{"use strict";var zp=wY(),{stdout:Av,stderr:lv}=vY(),{stringReplaceAll:uwe,stringEncaseCRLFWithFirstIndex:gwe}=xY(),TY=["ansi","ansi","ansi256","ansi16m"],Dg=Object.create(null),fwe=(r,e={})=>{if(e.level>3||e.level<0)throw new Error("The `level` option should be an integer from 0 to 3");let t=Av?Av.level:0;r.level=e.level===void 0?t:e.level},OY=class{constructor(e){return MY(e)}},MY=r=>{let e={};return fwe(e,r),e.template=(...t)=>hwe(e.template,...t),Object.setPrototypeOf(e,wy.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=OY,e.template};function wy(r){return MY(r)}for(let[r,e]of Object.entries(zp))Dg[r]={get(){let t=By(this,cv(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,r,{value:t}),t}};Dg.visible={get(){let r=By(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:r}),r}};var UY=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let r of UY)Dg[r]={get(){let{level:e}=this;return function(...t){let i=cv(zp.color[TY[e]][r](...t),zp.color.close,this._styler);return By(this,i,this._isEmpty)}}};for(let r of UY){let e="bg"+r[0].toUpperCase()+r.slice(1);Dg[e]={get(){let{level:t}=this;return function(...i){let n=cv(zp.bgColor[TY[t]][r](...i),zp.bgColor.close,this._styler);return By(this,n,this._isEmpty)}}}}var pwe=Object.defineProperties(()=>{},te(N({},Dg),{level:{enumerable:!0,get(){return this._generator.level},set(r){this._generator.level=r}}})),cv=(r,e,t)=>{let i,n;return t===void 0?(i=r,n=e):(i=t.openAll+r,n=e+t.closeAll),{open:r,close:e,openAll:i,closeAll:n,parent:t}},By=(r,e,t)=>{let i=(...n)=>dwe(i,n.length===1?""+n[0]:n.join(" "));return i.__proto__=pwe,i._generator=r,i._styler=e,i._isEmpty=t,i},dwe=(r,e)=>{if(r.level<=0||!e)return r._isEmpty?"":e;let t=r._styler;if(t===void 0)return e;let{openAll:i,closeAll:n}=t;if(e.indexOf("")!==-1)for(;t!==void 0;)e=uwe(e,t.close,t.open),t=t.parent;let s=e.indexOf(` -`);return s!==-1&&(e=gwe(e,n,i,s)),i+e+n},uv,hwe=(r,...e)=>{let[t]=e;if(!Array.isArray(t))return e.join(" ");let i=e.slice(1),n=[t.raw[0]];for(let s=1;s<t.length;s++)n.push(String(i[s-1]).replace(/[{}\\]/g,"\\$&"),String(t.raw[s]));return uv===void 0&&(uv=NY()),uv(r,n.join(""))};Object.defineProperties(wy.prototype,Dg);var _p=wy();_p.supportsColor=Av;_p.stderr=wy({level:lv?lv.level:0});_p.stderr.supportsColor=lv;_p.Level={None:0,Basic:1,Ansi256:2,TrueColor:3,0:"None",1:"Basic",2:"Ansi256",3:"TrueColor"};LY.exports=_p});var by=w(Rs=>{"use strict";Rs.isInteger=r=>typeof r=="number"?Number.isInteger(r):typeof r=="string"&&r.trim()!==""?Number.isInteger(Number(r)):!1;Rs.find=(r,e)=>r.nodes.find(t=>t.type===e);Rs.exceedsLimit=(r,e,t=1,i)=>i===!1||!Rs.isInteger(r)||!Rs.isInteger(e)?!1:(Number(e)-Number(r))/Number(t)>=i;Rs.escapeNode=(r,e=0,t)=>{let i=r.nodes[e];!i||(t&&i.type===t||i.type==="open"||i.type==="close")&&i.escaped!==!0&&(i.value="\\"+i.value,i.escaped=!0)};Rs.encloseBrace=r=>r.type!=="brace"?!1:r.commas>>0+r.ranges>>0==0?(r.invalid=!0,!0):!1;Rs.isInvalidBrace=r=>r.type!=="brace"?!1:r.invalid===!0||r.dollar?!0:r.commas>>0+r.ranges>>0==0||r.open!==!0||r.close!==!0?(r.invalid=!0,!0):!1;Rs.isOpenOrClose=r=>r.type==="open"||r.type==="close"?!0:r.open===!0||r.close===!0;Rs.reduce=r=>r.reduce((e,t)=>(t.type==="text"&&e.push(t.value),t.type==="range"&&(t.type="text"),e),[]);Rs.flatten=(...r)=>{let e=[],t=i=>{for(let n=0;n<i.length;n++){let s=i[n];Array.isArray(s)?t(s,e):s!==void 0&&e.push(s)}return e};return t(r),e}});var Qy=w((het,KY)=>{"use strict";var HY=by();KY.exports=(r,e={})=>{let t=(i,n={})=>{let s=e.escapeInvalid&&HY.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a="";if(i.value)return(s||o)&&HY.isOpenOrClose(i)?"\\"+i.value:i.value;if(i.value)return i.value;if(i.nodes)for(let l of i.nodes)a+=t(l);return a};return t(r)}});var GY=w((pet,jY)=>{"use strict";jY.exports=function(r){return typeof r=="number"?r-r==0:typeof r=="string"&&r.trim()!==""?Number.isFinite?Number.isFinite(+r):isFinite(+r):!1}});var ZY=w((det,YY)=>{"use strict";var qY=GY(),Fc=(r,e,t)=>{if(qY(r)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(e===void 0||r===e)return String(r);if(qY(e)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let i=N({relaxZeros:!0},t);typeof i.strictZeros=="boolean"&&(i.relaxZeros=i.strictZeros===!1);let n=String(i.relaxZeros),s=String(i.shorthand),o=String(i.capture),a=String(i.wrap),l=r+":"+e+"="+n+s+o+a;if(Fc.cache.hasOwnProperty(l))return Fc.cache[l].result;let c=Math.min(r,e),u=Math.max(r,e);if(Math.abs(c-u)===1){let m=r+"|"+e;return i.capture?`(${m})`:i.wrap===!1?m:`(?:${m})`}let g=WY(r)||WY(e),f={min:r,max:e,a:c,b:u},h=[],p=[];if(g&&(f.isPadded=g,f.maxLen=String(f.max).length),c<0){let m=u<0?Math.abs(u):1;p=JY(m,Math.abs(c),f,i),c=f.a=0}return u>=0&&(h=JY(c,u,f,i)),f.negatives=p,f.positives=h,f.result=Cwe(p,h,i),i.capture===!0?f.result=`(${f.result})`:i.wrap!==!1&&h.length+p.length>1&&(f.result=`(?:${f.result})`),Fc.cache[l]=f,f.result};function Cwe(r,e,t){let i=fv(r,e,"-",!1,t)||[],n=fv(e,r,"",!1,t)||[],s=fv(r,e,"-?",!0,t)||[];return i.concat(s).concat(n).join("|")}function Ewe(r,e){let t=1,i=1,n=zY(r,t),s=new Set([e]);for(;r<=n&&n<=e;)s.add(n),t+=1,n=zY(r,t);for(n=_Y(e+1,i)-1;r<n&&n<=e;)s.add(n),i+=1,n=_Y(e+1,i)-1;return s=[...s],s.sort(mwe),s}function wwe(r,e,t){if(r===e)return{pattern:r,count:[],digits:0};let i=Iwe(r,e),n=i.length,s="",o=0;for(let a=0;a<n;a++){let[l,c]=i[a];l===c?s+=l:l!=="0"||c!=="9"?s+=ywe(l,c,t):o++}return o&&(s+=t.shorthand===!0?"\\d":"[0-9]"),{pattern:s,count:[o],digits:n}}function JY(r,e,t,i){let n=Ewe(r,e),s=[],o=r,a;for(let l=0;l<n.length;l++){let c=n[l],u=wwe(String(o),String(c),i),g="";if(!t.isPadded&&a&&a.pattern===u.pattern){a.count.length>1&&a.count.pop(),a.count.push(u.count[0]),a.string=a.pattern+VY(a.count),o=c+1;continue}t.isPadded&&(g=Bwe(c,t,i)),u.string=g+u.pattern+VY(u.count),s.push(u),o=c+1,a=u}return s}function fv(r,e,t,i,n){let s=[];for(let o of r){let{string:a}=o;!i&&!XY(e,"string",a)&&s.push(t+a),i&&XY(e,"string",a)&&s.push(t+a)}return s}function Iwe(r,e){let t=[];for(let i=0;i<r.length;i++)t.push([r[i],e[i]]);return t}function mwe(r,e){return r>e?1:e>r?-1:0}function XY(r,e,t){return r.some(i=>i[e]===t)}function zY(r,e){return Number(String(r).slice(0,-e)+"9".repeat(e))}function _Y(r,e){return r-r%Math.pow(10,e)}function VY(r){let[e=0,t=""]=r;return t||e>1?`{${e+(t?","+t:"")}}`:""}function ywe(r,e,t){return`[${r}${e-r==1?"":"-"}${e}]`}function WY(r){return/^-?(0+)\d/.test(r)}function Bwe(r,e,t){if(!e.isPadded)return r;let i=Math.abs(e.maxLen-String(r).length),n=t.relaxZeros!==!1;switch(i){case 0:return"";case 1:return n?"0?":"0";case 2:return n?"0{0,2}":"00";default:return n?`0{0,${i}}`:`0{${i}}`}}Fc.cache={};Fc.clearCache=()=>Fc.cache={};YY.exports=Fc});var dv=w((Cet,$Y)=>{"use strict";var bwe=require("util"),eq=ZY(),tq=r=>r!==null&&typeof r=="object"&&!Array.isArray(r),Qwe=r=>e=>r===!0?Number(e):String(e),hv=r=>typeof r=="number"||typeof r=="string"&&r!=="",Vp=r=>Number.isInteger(+r),pv=r=>{let e=`${r}`,t=-1;if(e[0]==="-"&&(e=e.slice(1)),e==="0")return!1;for(;e[++t]==="0";);return t>0},Swe=(r,e,t)=>typeof r=="string"||typeof e=="string"?!0:t.stringify===!0,vwe=(r,e,t)=>{if(e>0){let i=r[0]==="-"?"-":"";i&&(r=r.slice(1)),r=i+r.padStart(i?e-1:e,"0")}return t===!1?String(r):r},rq=(r,e)=>{let t=r[0]==="-"?"-":"";for(t&&(r=r.slice(1),e--);r.length<e;)r="0"+r;return t?"-"+r:r},kwe=(r,e)=>{r.negatives.sort((o,a)=>o<a?-1:o>a?1:0),r.positives.sort((o,a)=>o<a?-1:o>a?1:0);let t=e.capture?"":"?:",i="",n="",s;return r.positives.length&&(i=r.positives.join("|")),r.negatives.length&&(n=`-(${t}${r.negatives.join("|")})`),i&&n?s=`${i}|${n}`:s=i||n,e.wrap?`(${t}${s})`:s},iq=(r,e,t,i)=>{if(t)return eq(r,e,N({wrap:!1},i));let n=String.fromCharCode(r);if(r===e)return n;let s=String.fromCharCode(e);return`[${n}-${s}]`},nq=(r,e,t)=>{if(Array.isArray(r)){let i=t.wrap===!0,n=t.capture?"":"?:";return i?`(${n}${r.join("|")})`:r.join("|")}return eq(r,e,t)},sq=(...r)=>new RangeError("Invalid range arguments: "+bwe.inspect(...r)),oq=(r,e,t)=>{if(t.strictRanges===!0)throw sq([r,e]);return[]},xwe=(r,e)=>{if(e.strictRanges===!0)throw new TypeError(`Expected step "${r}" to be a number`);return[]},Pwe=(r,e,t=1,i={})=>{let n=Number(r),s=Number(e);if(!Number.isInteger(n)||!Number.isInteger(s)){if(i.strictRanges===!0)throw sq([r,e]);return[]}n===0&&(n=0),s===0&&(s=0);let o=n>s,a=String(r),l=String(e),c=String(t);t=Math.max(Math.abs(t),1);let u=pv(a)||pv(l)||pv(c),g=u?Math.max(a.length,l.length,c.length):0,f=u===!1&&Swe(r,e,i)===!1,h=i.transform||Qwe(f);if(i.toRegex&&t===1)return iq(rq(r,g),rq(e,g),!0,i);let p={negatives:[],positives:[]},m=v=>p[v<0?"negatives":"positives"].push(Math.abs(v)),y=[],b=0;for(;o?n>=s:n<=s;)i.toRegex===!0&&t>1?m(n):y.push(vwe(h(n,b),g,f)),n=o?n-t:n+t,b++;return i.toRegex===!0?t>1?kwe(p,i):nq(y,null,N({wrap:!1},i)):y},Dwe=(r,e,t=1,i={})=>{if(!Vp(r)&&r.length>1||!Vp(e)&&e.length>1)return oq(r,e,i);let n=i.transform||(f=>String.fromCharCode(f)),s=`${r}`.charCodeAt(0),o=`${e}`.charCodeAt(0),a=s>o,l=Math.min(s,o),c=Math.max(s,o);if(i.toRegex&&t===1)return iq(l,c,!1,i);let u=[],g=0;for(;a?s>=o:s<=o;)u.push(n(s,g)),s=a?s-t:s+t,g++;return i.toRegex===!0?nq(u,null,{wrap:!1,options:i}):u},Sy=(r,e,t,i={})=>{if(e==null&&hv(r))return[r];if(!hv(r)||!hv(e))return oq(r,e,i);if(typeof t=="function")return Sy(r,e,1,{transform:t});if(tq(t))return Sy(r,e,0,t);let n=N({},i);return n.capture===!0&&(n.wrap=!0),t=t||n.step||1,Vp(t)?Vp(r)&&Vp(e)?Pwe(r,e,t,n):Dwe(r,e,Math.max(Math.abs(t),1),n):t!=null&&!tq(t)?xwe(t,n):Sy(r,e,1,t)};$Y.exports=Sy});var lq=w((met,aq)=>{"use strict";var Rwe=dv(),Aq=by(),Fwe=(r,e={})=>{let t=(i,n={})=>{let s=Aq.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a=s===!0||o===!0,l=e.escapeInvalid===!0?"\\":"",c="";if(i.isOpen===!0||i.isClose===!0)return l+i.value;if(i.type==="open")return a?l+i.value:"(";if(i.type==="close")return a?l+i.value:")";if(i.type==="comma")return i.prev.type==="comma"?"":a?i.value:"|";if(i.value)return i.value;if(i.nodes&&i.ranges>0){let u=Aq.reduce(i.nodes),g=Rwe(...u,te(N({},e),{wrap:!1,toRegex:!0}));if(g.length!==0)return u.length>1&&g.length>1?`(${g})`:g}if(i.nodes)for(let u of i.nodes)c+=t(u,i);return c};return t(r)};aq.exports=Fwe});var gq=w((Eet,cq)=>{"use strict";var Nwe=dv(),uq=Qy(),Rg=by(),Nc=(r="",e="",t=!1)=>{let i=[];if(r=[].concat(r),e=[].concat(e),!e.length)return r;if(!r.length)return t?Rg.flatten(e).map(n=>`{${n}}`):e;for(let n of r)if(Array.isArray(n))for(let s of n)i.push(Nc(s,e,t));else for(let s of e)t===!0&&typeof s=="string"&&(s=`{${s}}`),i.push(Array.isArray(s)?Nc(n,s,t):n+s);return Rg.flatten(i)},Lwe=(r,e={})=>{let t=e.rangeLimit===void 0?1e3:e.rangeLimit,i=(n,s={})=>{n.queue=[];let o=s,a=s.queue;for(;o.type!=="brace"&&o.type!=="root"&&o.parent;)o=o.parent,a=o.queue;if(n.invalid||n.dollar){a.push(Nc(a.pop(),uq(n,e)));return}if(n.type==="brace"&&n.invalid!==!0&&n.nodes.length===2){a.push(Nc(a.pop(),["{}"]));return}if(n.nodes&&n.ranges>0){let g=Rg.reduce(n.nodes);if(Rg.exceedsLimit(...g,e.step,t))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let f=Nwe(...g,e);f.length===0&&(f=uq(n,e)),a.push(Nc(a.pop(),f)),n.nodes=[];return}let l=Rg.encloseBrace(n),c=n.queue,u=n;for(;u.type!=="brace"&&u.type!=="root"&&u.parent;)u=u.parent,c=u.queue;for(let g=0;g<n.nodes.length;g++){let f=n.nodes[g];if(f.type==="comma"&&n.type==="brace"){g===1&&c.push(""),c.push("");continue}if(f.type==="close"){a.push(Nc(a.pop(),c,l));continue}if(f.value&&f.type!=="open"){c.push(Nc(c.pop(),f.value));continue}f.nodes&&i(f,n)}return c};return Rg.flatten(i(r))};cq.exports=Lwe});var hq=w((Iet,fq)=>{"use strict";fq.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` -`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var Eq=w((yet,pq)=>{"use strict";var Twe=Qy(),{MAX_LENGTH:dq,CHAR_BACKSLASH:Cv,CHAR_BACKTICK:Owe,CHAR_COMMA:Mwe,CHAR_DOT:Uwe,CHAR_LEFT_PARENTHESES:Kwe,CHAR_RIGHT_PARENTHESES:Hwe,CHAR_LEFT_CURLY_BRACE:jwe,CHAR_RIGHT_CURLY_BRACE:Gwe,CHAR_LEFT_SQUARE_BRACKET:Cq,CHAR_RIGHT_SQUARE_BRACKET:mq,CHAR_DOUBLE_QUOTE:Ywe,CHAR_SINGLE_QUOTE:qwe,CHAR_NO_BREAK_SPACE:Jwe,CHAR_ZERO_WIDTH_NOBREAK_SPACE:Wwe}=hq(),zwe=(r,e={})=>{if(typeof r!="string")throw new TypeError("Expected a string");let t=e||{},i=typeof t.maxLength=="number"?Math.min(dq,t.maxLength):dq;if(r.length>i)throw new SyntaxError(`Input length (${r.length}), exceeds max characters (${i})`);let n={type:"root",input:r,nodes:[]},s=[n],o=n,a=n,l=0,c=r.length,u=0,g=0,f,h={},p=()=>r[u++],m=y=>{if(y.type==="text"&&a.type==="dot"&&(a.type="text"),a&&a.type==="text"&&y.type==="text"){a.value+=y.value;return}return o.nodes.push(y),y.parent=o,y.prev=a,a=y,y};for(m({type:"bos"});u<c;)if(o=s[s.length-1],f=p(),!(f===Wwe||f===Jwe)){if(f===Cv){m({type:"text",value:(e.keepEscaping?f:"")+p()});continue}if(f===mq){m({type:"text",value:"\\"+f});continue}if(f===Cq){l++;let y=!0,b;for(;u<c&&(b=p());){if(f+=b,b===Cq){l++;continue}if(b===Cv){f+=p();continue}if(b===mq&&(l--,l===0))break}m({type:"text",value:f});continue}if(f===Kwe){o=m({type:"paren",nodes:[]}),s.push(o),m({type:"text",value:f});continue}if(f===Hwe){if(o.type!=="paren"){m({type:"text",value:f});continue}o=s.pop(),m({type:"text",value:f}),o=s[s.length-1];continue}if(f===Ywe||f===qwe||f===Owe){let y=f,b;for(e.keepQuotes!==!0&&(f="");u<c&&(b=p());){if(b===Cv){f+=b+p();continue}if(b===y){e.keepQuotes===!0&&(f+=b);break}f+=b}m({type:"text",value:f});continue}if(f===jwe){g++;let y=a.value&&a.value.slice(-1)==="$"||o.dollar===!0;o=m({type:"brace",open:!0,close:!1,dollar:y,depth:g,commas:0,ranges:0,nodes:[]}),s.push(o),m({type:"open",value:f});continue}if(f===Gwe){if(o.type!=="brace"){m({type:"text",value:f});continue}let y="close";o=s.pop(),o.close=!0,m({type:y,value:f}),g--,o=s[s.length-1];continue}if(f===Mwe&&g>0){if(o.ranges>0){o.ranges=0;let y=o.nodes.shift();o.nodes=[y,{type:"text",value:Twe(o)}]}m({type:"comma",value:f}),o.commas++;continue}if(f===Uwe&&g>0&&o.commas===0){let y=o.nodes;if(g===0||y.length===0){m({type:"text",value:f});continue}if(a.type==="dot"){if(o.range=[],a.value+=f,a.type="range",o.nodes.length!==3&&o.nodes.length!==5){o.invalid=!0,o.ranges=0,a.type="text";continue}o.ranges++,o.args=[];continue}if(a.type==="range"){y.pop();let b=y[y.length-1];b.value+=a.value+f,a=b,o.ranges--;continue}m({type:"dot",value:f});continue}m({type:"text",value:f})}do if(o=s.pop(),o.type!=="root"){o.nodes.forEach(v=>{v.nodes||(v.type==="open"&&(v.isOpen=!0),v.type==="close"&&(v.isClose=!0),v.nodes||(v.type="text"),v.invalid=!0)});let y=s[s.length-1],b=y.nodes.indexOf(o);y.nodes.splice(b,1,...o.nodes)}while(s.length>0);return m({type:"eos"}),n};pq.exports=zwe});var wq=w((wet,Iq)=>{"use strict";var yq=Qy(),_we=lq(),Vwe=gq(),Xwe=Eq(),rs=(r,e={})=>{let t=[];if(Array.isArray(r))for(let i of r){let n=rs.create(i,e);Array.isArray(n)?t.push(...n):t.push(n)}else t=[].concat(rs.create(r,e));return e&&e.expand===!0&&e.nodupes===!0&&(t=[...new Set(t)]),t};rs.parse=(r,e={})=>Xwe(r,e);rs.stringify=(r,e={})=>typeof r=="string"?yq(rs.parse(r,e),e):yq(r,e);rs.compile=(r,e={})=>(typeof r=="string"&&(r=rs.parse(r,e)),_we(r,e));rs.expand=(r,e={})=>{typeof r=="string"&&(r=rs.parse(r,e));let t=Vwe(r,e);return e.noempty===!0&&(t=t.filter(Boolean)),e.nodupes===!0&&(t=[...new Set(t)]),t};rs.create=(r,e={})=>r===""||r.length<3?[r]:e.expand!==!0?rs.compile(r,e):rs.expand(r,e);Iq.exports=rs});var Xp=w((Bet,Bq)=>{"use strict";var Zwe=require("path"),zo="\\\\/",bq=`[^${zo}]`,_a="\\.",$we="\\+",eBe="\\?",vy="\\/",tBe="(?=.)",Qq="[^/]",mv=`(?:${vy}|$)`,Sq=`(?:^|${vy})`,Ev=`${_a}{1,2}${mv}`,rBe=`(?!${_a})`,iBe=`(?!${Sq}${Ev})`,nBe=`(?!${_a}{0,1}${mv})`,sBe=`(?!${Ev})`,oBe=`[^.${vy}]`,aBe=`${Qq}*?`,vq={DOT_LITERAL:_a,PLUS_LITERAL:$we,QMARK_LITERAL:eBe,SLASH_LITERAL:vy,ONE_CHAR:tBe,QMARK:Qq,END_ANCHOR:mv,DOTS_SLASH:Ev,NO_DOT:rBe,NO_DOTS:iBe,NO_DOT_SLASH:nBe,NO_DOTS_SLASH:sBe,QMARK_NO_DOT:oBe,STAR:aBe,START_ANCHOR:Sq},ABe=te(N({},vq),{SLASH_LITERAL:`[${zo}]`,QMARK:bq,STAR:`${bq}*?`,DOTS_SLASH:`${_a}{1,2}(?:[${zo}]|$)`,NO_DOT:`(?!${_a})`,NO_DOTS:`(?!(?:^|[${zo}])${_a}{1,2}(?:[${zo}]|$))`,NO_DOT_SLASH:`(?!${_a}{0,1}(?:[${zo}]|$))`,NO_DOTS_SLASH:`(?!${_a}{1,2}(?:[${zo}]|$))`,QMARK_NO_DOT:`[^.${zo}]`,START_ANCHOR:`(?:^|[${zo}])`,END_ANCHOR:`(?:[${zo}]|$)`}),lBe={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};Bq.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:lBe,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:Zwe.sep,extglobChars(r){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${r.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(r){return r===!0?ABe:vq}}});var Zp=w(kn=>{"use strict";var cBe=require("path"),uBe=process.platform==="win32",{REGEX_BACKSLASH:gBe,REGEX_REMOVE_BACKSLASH:fBe,REGEX_SPECIAL_CHARS:hBe,REGEX_SPECIAL_CHARS_GLOBAL:pBe}=Xp();kn.isObject=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);kn.hasRegexChars=r=>hBe.test(r);kn.isRegexChar=r=>r.length===1&&kn.hasRegexChars(r);kn.escapeRegex=r=>r.replace(pBe,"\\$1");kn.toPosixSlashes=r=>r.replace(gBe,"/");kn.removeBackslashes=r=>r.replace(fBe,e=>e==="\\"?"":e);kn.supportsLookbehinds=()=>{let r=process.version.slice(1).split(".").map(Number);return r.length===3&&r[0]>=9||r[0]===8&&r[1]>=10};kn.isWindows=r=>r&&typeof r.windows=="boolean"?r.windows:uBe===!0||cBe.sep==="\\";kn.escapeLast=(r,e,t)=>{let i=r.lastIndexOf(e,t);return i===-1?r:r[i-1]==="\\"?kn.escapeLast(r,e,i-1):`${r.slice(0,i)}\\${r.slice(i)}`};kn.removePrefix=(r,e={})=>{let t=r;return t.startsWith("./")&&(t=t.slice(2),e.prefix="./"),t};kn.wrapOutput=(r,e={},t={})=>{let i=t.contains?"":"^",n=t.contains?"":"$",s=`${i}(?:${r})${n}`;return e.negated===!0&&(s=`(?:^(?!${s}).*$)`),s}});var Lq=w((Qet,kq)=>{"use strict";var xq=Zp(),{CHAR_ASTERISK:Iv,CHAR_AT:dBe,CHAR_BACKWARD_SLASH:$p,CHAR_COMMA:CBe,CHAR_DOT:yv,CHAR_EXCLAMATION_MARK:wv,CHAR_FORWARD_SLASH:Pq,CHAR_LEFT_CURLY_BRACE:Bv,CHAR_LEFT_PARENTHESES:bv,CHAR_LEFT_SQUARE_BRACKET:mBe,CHAR_PLUS:EBe,CHAR_QUESTION_MARK:Dq,CHAR_RIGHT_CURLY_BRACE:IBe,CHAR_RIGHT_PARENTHESES:Rq,CHAR_RIGHT_SQUARE_BRACKET:yBe}=Xp(),Fq=r=>r===Pq||r===$p,Nq=r=>{r.isPrefix!==!0&&(r.depth=r.isGlobstar?Infinity:1)},wBe=(r,e)=>{let t=e||{},i=r.length-1,n=t.parts===!0||t.scanToEnd===!0,s=[],o=[],a=[],l=r,c=-1,u=0,g=0,f=!1,h=!1,p=!1,m=!1,y=!1,b=!1,v=!1,k=!1,T=!1,Y=!1,q=0,$,z,ne={value:"",depth:0,isGlob:!1},ee=()=>c>=i,A=()=>l.charCodeAt(c+1),oe=()=>($=z,l.charCodeAt(++c));for(;c<i;){z=oe();let de;if(z===$p){v=ne.backslashes=!0,z=oe(),z===Bv&&(b=!0);continue}if(b===!0||z===Bv){for(q++;ee()!==!0&&(z=oe());){if(z===$p){v=ne.backslashes=!0,oe();continue}if(z===Bv){q++;continue}if(b!==!0&&z===yv&&(z=oe())===yv){if(f=ne.isBrace=!0,p=ne.isGlob=!0,Y=!0,n===!0)continue;break}if(b!==!0&&z===CBe){if(f=ne.isBrace=!0,p=ne.isGlob=!0,Y=!0,n===!0)continue;break}if(z===IBe&&(q--,q===0)){b=!1,f=ne.isBrace=!0,Y=!0;break}}if(n===!0)continue;break}if(z===Pq){if(s.push(c),o.push(ne),ne={value:"",depth:0,isGlob:!1},Y===!0)continue;if($===yv&&c===u+1){u+=2;continue}g=c+1;continue}if(t.noext!==!0&&(z===EBe||z===dBe||z===Iv||z===Dq||z===wv)===!0&&A()===bv){if(p=ne.isGlob=!0,m=ne.isExtglob=!0,Y=!0,z===wv&&c===u&&(T=!0),n===!0){for(;ee()!==!0&&(z=oe());){if(z===$p){v=ne.backslashes=!0,z=oe();continue}if(z===Rq){p=ne.isGlob=!0,Y=!0;break}}continue}break}if(z===Iv){if($===Iv&&(y=ne.isGlobstar=!0),p=ne.isGlob=!0,Y=!0,n===!0)continue;break}if(z===Dq){if(p=ne.isGlob=!0,Y=!0,n===!0)continue;break}if(z===mBe){for(;ee()!==!0&&(de=oe());){if(de===$p){v=ne.backslashes=!0,oe();continue}if(de===yBe){h=ne.isBracket=!0,p=ne.isGlob=!0,Y=!0;break}}if(n===!0)continue;break}if(t.nonegate!==!0&&z===wv&&c===u){k=ne.negated=!0,u++;continue}if(t.noparen!==!0&&z===bv){if(p=ne.isGlob=!0,n===!0){for(;ee()!==!0&&(z=oe());){if(z===bv){v=ne.backslashes=!0,z=oe();continue}if(z===Rq){Y=!0;break}}continue}break}if(p===!0){if(Y=!0,n===!0)continue;break}}t.noext===!0&&(m=!1,p=!1);let ce=l,Z="",O="";u>0&&(Z=l.slice(0,u),l=l.slice(u),g-=u),ce&&p===!0&&g>0?(ce=l.slice(0,g),O=l.slice(g)):p===!0?(ce="",O=l):ce=l,ce&&ce!==""&&ce!=="/"&&ce!==l&&Fq(ce.charCodeAt(ce.length-1))&&(ce=ce.slice(0,-1)),t.unescape===!0&&(O&&(O=xq.removeBackslashes(O)),ce&&v===!0&&(ce=xq.removeBackslashes(ce)));let L={prefix:Z,input:r,start:u,base:ce,glob:O,isBrace:f,isBracket:h,isGlob:p,isExtglob:m,isGlobstar:y,negated:k,negatedExtglob:T};if(t.tokens===!0&&(L.maxDepth=0,Fq(z)||o.push(ne),L.tokens=o),t.parts===!0||t.tokens===!0){let de;for(let Be=0;Be<s.length;Be++){let Ge=de?de+1:u,re=s[Be],se=r.slice(Ge,re);t.tokens&&(Be===0&&u!==0?(o[Be].isPrefix=!0,o[Be].value=Z):o[Be].value=se,Nq(o[Be]),L.maxDepth+=o[Be].depth),(Be!==0||se!=="")&&a.push(se),de=re}if(de&&de+1<r.length){let Be=r.slice(de+1);a.push(Be),t.tokens&&(o[o.length-1].value=Be,Nq(o[o.length-1]),L.maxDepth+=o[o.length-1].depth)}L.slashes=s,L.parts=a}return L};kq.exports=wBe});var Uq=w((vet,Tq)=>{"use strict";var ky=Xp(),is=Zp(),{MAX_LENGTH:xy,POSIX_REGEX_SOURCE:BBe,REGEX_NON_SPECIAL_CHARS:bBe,REGEX_SPECIAL_CHARS_BACKREF:QBe,REPLACEMENTS:Oq}=ky,SBe=(r,e)=>{if(typeof e.expandRange=="function")return e.expandRange(...r,e);r.sort();let t=`[${r.join("-")}]`;try{new RegExp(t)}catch(i){return r.map(n=>is.escapeRegex(n)).join("..")}return t},Fg=(r,e)=>`Missing ${r}: "${e}" - use "\\\\${e}" to match literal characters`,Mq=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");r=Oq[r]||r;let t=N({},e),i=typeof t.maxLength=="number"?Math.min(xy,t.maxLength):xy,n=r.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);let s={type:"bos",value:"",output:t.prepend||""},o=[s],a=t.capture?"":"?:",l=is.isWindows(e),c=ky.globChars(l),u=ky.extglobChars(c),{DOT_LITERAL:g,PLUS_LITERAL:f,SLASH_LITERAL:h,ONE_CHAR:p,DOTS_SLASH:m,NO_DOT:y,NO_DOT_SLASH:b,NO_DOTS_SLASH:v,QMARK:k,QMARK_NO_DOT:T,STAR:Y,START_ANCHOR:q}=c,$=V=>`(${a}(?:(?!${q}${V.dot?m:g}).)*?)`,z=t.dot?"":y,ne=t.dot?k:T,ee=t.bash===!0?$(t):Y;t.capture&&(ee=`(${ee})`),typeof t.noext=="boolean"&&(t.noextglob=t.noext);let A={input:r,index:-1,start:0,dot:t.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:o};r=is.removePrefix(r,A),n=r.length;let oe=[],ce=[],Z=[],O=s,L,de=()=>A.index===n-1,Be=A.peek=(V=1)=>r[A.index+V],Ge=A.advance=()=>r[++A.index]||"",re=()=>r.slice(A.index+1),se=(V="",Qe=0)=>{A.consumed+=V,A.index+=Qe},be=V=>{A.output+=V.output!=null?V.output:V.value,se(V.value)},he=()=>{let V=1;for(;Be()==="!"&&(Be(2)!=="("||Be(3)==="?");)Ge(),A.start++,V++;return V%2==0?!1:(A.negated=!0,A.start++,!0)},Fe=V=>{A[V]++,Z.push(V)},Ue=V=>{A[V]--,Z.pop()},xe=V=>{if(O.type==="globstar"){let Qe=A.braces>0&&(V.type==="comma"||V.type==="brace"),le=V.extglob===!0||oe.length&&(V.type==="pipe"||V.type==="paren");V.type!=="slash"&&V.type!=="paren"&&!Qe&&!le&&(A.output=A.output.slice(0,-O.output.length),O.type="star",O.value="*",O.output=ee,A.output+=O.output)}if(oe.length&&V.type!=="paren"&&(oe[oe.length-1].inner+=V.value),(V.value||V.output)&&be(V),O&&O.type==="text"&&V.type==="text"){O.value+=V.value,O.output=(O.output||"")+V.value;return}V.prev=O,o.push(V),O=V},ve=(V,Qe)=>{let le=te(N({},u[Qe]),{conditions:1,inner:""});le.prev=O,le.parens=A.parens,le.output=A.output;let fe=(t.capture?"(":"")+le.open;Fe("parens"),xe({type:V,value:Qe,output:A.output?"":p}),xe({type:"paren",extglob:!0,value:Ge(),output:fe}),oe.push(le)},pe=V=>{let Qe=V.close+(t.capture?")":""),le;if(V.type==="negate"){let fe=ee;V.inner&&V.inner.length>1&&V.inner.includes("/")&&(fe=$(t)),(fe!==ee||de()||/^\)+$/.test(re()))&&(Qe=V.close=`)$))${fe}`),V.inner.includes("*")&&(le=re())&&/^\.[^\\/.]+$/.test(le)&&(Qe=V.close=`)${le})${fe})`),V.prev.type==="bos"&&(A.negatedExtglob=!0)}xe({type:"paren",extglob:!0,value:L,output:Qe}),Ue("parens")};if(t.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(r)){let V=!1,Qe=r.replace(QBe,(le,fe,gt,Ht,Mt,Ei)=>Ht==="\\"?(V=!0,le):Ht==="?"?fe?fe+Ht+(Mt?k.repeat(Mt.length):""):Ei===0?ne+(Mt?k.repeat(Mt.length):""):k.repeat(gt.length):Ht==="."?g.repeat(gt.length):Ht==="*"?fe?fe+Ht+(Mt?ee:""):ee:fe?le:`\\${le}`);return V===!0&&(t.unescape===!0?Qe=Qe.replace(/\\/g,""):Qe=Qe.replace(/\\+/g,le=>le.length%2==0?"\\\\":le?"\\":"")),Qe===r&&t.contains===!0?(A.output=r,A):(A.output=is.wrapOutput(Qe,A,e),A)}for(;!de();){if(L=Ge(),L==="\0")continue;if(L==="\\"){let le=Be();if(le==="/"&&t.bash!==!0||le==="."||le===";")continue;if(!le){L+="\\",xe({type:"text",value:L});continue}let fe=/^\\+/.exec(re()),gt=0;if(fe&&fe[0].length>2&&(gt=fe[0].length,A.index+=gt,gt%2!=0&&(L+="\\")),t.unescape===!0?L=Ge():L+=Ge(),A.brackets===0){xe({type:"text",value:L});continue}}if(A.brackets>0&&(L!=="]"||O.value==="["||O.value==="[^")){if(t.posix!==!1&&L===":"){let le=O.value.slice(1);if(le.includes("[")&&(O.posix=!0,le.includes(":"))){let fe=O.value.lastIndexOf("["),gt=O.value.slice(0,fe),Ht=O.value.slice(fe+2),Mt=BBe[Ht];if(Mt){O.value=gt+Mt,A.backtrack=!0,Ge(),!s.output&&o.indexOf(O)===1&&(s.output=p);continue}}}(L==="["&&Be()!==":"||L==="-"&&Be()==="]")&&(L=`\\${L}`),L==="]"&&(O.value==="["||O.value==="[^")&&(L=`\\${L}`),t.posix===!0&&L==="!"&&O.value==="["&&(L="^"),O.value+=L,be({value:L});continue}if(A.quotes===1&&L!=='"'){L=is.escapeRegex(L),O.value+=L,be({value:L});continue}if(L==='"'){A.quotes=A.quotes===1?0:1,t.keepQuotes===!0&&xe({type:"text",value:L});continue}if(L==="("){Fe("parens"),xe({type:"paren",value:L});continue}if(L===")"){if(A.parens===0&&t.strictBrackets===!0)throw new SyntaxError(Fg("opening","("));let le=oe[oe.length-1];if(le&&A.parens===le.parens+1){pe(oe.pop());continue}xe({type:"paren",value:L,output:A.parens?")":"\\)"}),Ue("parens");continue}if(L==="["){if(t.nobracket===!0||!re().includes("]")){if(t.nobracket!==!0&&t.strictBrackets===!0)throw new SyntaxError(Fg("closing","]"));L=`\\${L}`}else Fe("brackets");xe({type:"bracket",value:L});continue}if(L==="]"){if(t.nobracket===!0||O&&O.type==="bracket"&&O.value.length===1){xe({type:"text",value:L,output:`\\${L}`});continue}if(A.brackets===0){if(t.strictBrackets===!0)throw new SyntaxError(Fg("opening","["));xe({type:"text",value:L,output:`\\${L}`});continue}Ue("brackets");let le=O.value.slice(1);if(O.posix!==!0&&le[0]==="^"&&!le.includes("/")&&(L=`/${L}`),O.value+=L,be({value:L}),t.literalBrackets===!1||is.hasRegexChars(le))continue;let fe=is.escapeRegex(O.value);if(A.output=A.output.slice(0,-O.value.length),t.literalBrackets===!0){A.output+=fe,O.value=fe;continue}O.value=`(${a}${fe}|${O.value})`,A.output+=O.value;continue}if(L==="{"&&t.nobrace!==!0){Fe("braces");let le={type:"brace",value:L,output:"(",outputIndex:A.output.length,tokensIndex:A.tokens.length};ce.push(le),xe(le);continue}if(L==="}"){let le=ce[ce.length-1];if(t.nobrace===!0||!le){xe({type:"text",value:L,output:L});continue}let fe=")";if(le.dots===!0){let gt=o.slice(),Ht=[];for(let Mt=gt.length-1;Mt>=0&&(o.pop(),gt[Mt].type!=="brace");Mt--)gt[Mt].type!=="dots"&&Ht.unshift(gt[Mt].value);fe=SBe(Ht,t),A.backtrack=!0}if(le.comma!==!0&&le.dots!==!0){let gt=A.output.slice(0,le.outputIndex),Ht=A.tokens.slice(le.tokensIndex);le.value=le.output="\\{",L=fe="\\}",A.output=gt;for(let Mt of Ht)A.output+=Mt.output||Mt.value}xe({type:"brace",value:L,output:fe}),Ue("braces"),ce.pop();continue}if(L==="|"){oe.length>0&&oe[oe.length-1].conditions++,xe({type:"text",value:L});continue}if(L===","){let le=L,fe=ce[ce.length-1];fe&&Z[Z.length-1]==="braces"&&(fe.comma=!0,le="|"),xe({type:"comma",value:L,output:le});continue}if(L==="/"){if(O.type==="dot"&&A.index===A.start+1){A.start=A.index+1,A.consumed="",A.output="",o.pop(),O=s;continue}xe({type:"slash",value:L,output:h});continue}if(L==="."){if(A.braces>0&&O.type==="dot"){O.value==="."&&(O.output=g);let le=ce[ce.length-1];O.type="dots",O.output+=L,O.value+=L,le.dots=!0;continue}if(A.braces+A.parens===0&&O.type!=="bos"&&O.type!=="slash"){xe({type:"text",value:L,output:g});continue}xe({type:"dot",value:L,output:g});continue}if(L==="?"){if(!(O&&O.value==="(")&&t.noextglob!==!0&&Be()==="("&&Be(2)!=="?"){ve("qmark",L);continue}if(O&&O.type==="paren"){let fe=Be(),gt=L;if(fe==="<"&&!is.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(O.value==="("&&!/[!=<:]/.test(fe)||fe==="<"&&!/<([!=]|\w+>)/.test(re()))&&(gt=`\\${L}`),xe({type:"text",value:L,output:gt});continue}if(t.dot!==!0&&(O.type==="slash"||O.type==="bos")){xe({type:"qmark",value:L,output:T});continue}xe({type:"qmark",value:L,output:k});continue}if(L==="!"){if(t.noextglob!==!0&&Be()==="("&&(Be(2)!=="?"||!/[!=<:]/.test(Be(3)))){ve("negate",L);continue}if(t.nonegate!==!0&&A.index===0){he();continue}}if(L==="+"){if(t.noextglob!==!0&&Be()==="("&&Be(2)!=="?"){ve("plus",L);continue}if(O&&O.value==="("||t.regex===!1){xe({type:"plus",value:L,output:f});continue}if(O&&(O.type==="bracket"||O.type==="paren"||O.type==="brace")||A.parens>0){xe({type:"plus",value:L});continue}xe({type:"plus",value:f});continue}if(L==="@"){if(t.noextglob!==!0&&Be()==="("&&Be(2)!=="?"){xe({type:"at",extglob:!0,value:L,output:""});continue}xe({type:"text",value:L});continue}if(L!=="*"){(L==="$"||L==="^")&&(L=`\\${L}`);let le=bBe.exec(re());le&&(L+=le[0],A.index+=le[0].length),xe({type:"text",value:L});continue}if(O&&(O.type==="globstar"||O.star===!0)){O.type="star",O.star=!0,O.value+=L,O.output=ee,A.backtrack=!0,A.globstar=!0,se(L);continue}let V=re();if(t.noextglob!==!0&&/^\([^?]/.test(V)){ve("star",L);continue}if(O.type==="star"){if(t.noglobstar===!0){se(L);continue}let le=O.prev,fe=le.prev,gt=le.type==="slash"||le.type==="bos",Ht=fe&&(fe.type==="star"||fe.type==="globstar");if(t.bash===!0&&(!gt||V[0]&&V[0]!=="/")){xe({type:"star",value:L,output:""});continue}let Mt=A.braces>0&&(le.type==="comma"||le.type==="brace"),Ei=oe.length&&(le.type==="pipe"||le.type==="paren");if(!gt&&le.type!=="paren"&&!Mt&&!Ei){xe({type:"star",value:L,output:""});continue}for(;V.slice(0,3)==="/**";){let jt=r[A.index+4];if(jt&&jt!=="/")break;V=V.slice(3),se("/**",3)}if(le.type==="bos"&&de()){O.type="globstar",O.value+=L,O.output=$(t),A.output=O.output,A.globstar=!0,se(L);continue}if(le.type==="slash"&&le.prev.type!=="bos"&&!Ht&&de()){A.output=A.output.slice(0,-(le.output+O.output).length),le.output=`(?:${le.output}`,O.type="globstar",O.output=$(t)+(t.strictSlashes?")":"|$)"),O.value+=L,A.globstar=!0,A.output+=le.output+O.output,se(L);continue}if(le.type==="slash"&&le.prev.type!=="bos"&&V[0]==="/"){let jt=V[1]!==void 0?"|$":"";A.output=A.output.slice(0,-(le.output+O.output).length),le.output=`(?:${le.output}`,O.type="globstar",O.output=`${$(t)}${h}|${h}${jt})`,O.value+=L,A.output+=le.output+O.output,A.globstar=!0,se(L+Ge()),xe({type:"slash",value:"/",output:""});continue}if(le.type==="bos"&&V[0]==="/"){O.type="globstar",O.value+=L,O.output=`(?:^|${h}|${$(t)}${h})`,A.output=O.output,A.globstar=!0,se(L+Ge()),xe({type:"slash",value:"/",output:""});continue}A.output=A.output.slice(0,-O.output.length),O.type="globstar",O.output=$(t),O.value+=L,A.output+=O.output,A.globstar=!0,se(L);continue}let Qe={type:"star",value:L,output:ee};if(t.bash===!0){Qe.output=".*?",(O.type==="bos"||O.type==="slash")&&(Qe.output=z+Qe.output),xe(Qe);continue}if(O&&(O.type==="bracket"||O.type==="paren")&&t.regex===!0){Qe.output=L,xe(Qe);continue}(A.index===A.start||O.type==="slash"||O.type==="dot")&&(O.type==="dot"?(A.output+=b,O.output+=b):t.dot===!0?(A.output+=v,O.output+=v):(A.output+=z,O.output+=z),Be()!=="*"&&(A.output+=p,O.output+=p)),xe(Qe)}for(;A.brackets>0;){if(t.strictBrackets===!0)throw new SyntaxError(Fg("closing","]"));A.output=is.escapeLast(A.output,"["),Ue("brackets")}for(;A.parens>0;){if(t.strictBrackets===!0)throw new SyntaxError(Fg("closing",")"));A.output=is.escapeLast(A.output,"("),Ue("parens")}for(;A.braces>0;){if(t.strictBrackets===!0)throw new SyntaxError(Fg("closing","}"));A.output=is.escapeLast(A.output,"{"),Ue("braces")}if(t.strictSlashes!==!0&&(O.type==="star"||O.type==="bracket")&&xe({type:"maybe_slash",value:"",output:`${h}?`}),A.backtrack===!0){A.output="";for(let V of A.tokens)A.output+=V.output!=null?V.output:V.value,V.suffix&&(A.output+=V.suffix)}return A};Mq.fastpaths=(r,e)=>{let t=N({},e),i=typeof t.maxLength=="number"?Math.min(xy,t.maxLength):xy,n=r.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);r=Oq[r]||r;let s=is.isWindows(e),{DOT_LITERAL:o,SLASH_LITERAL:a,ONE_CHAR:l,DOTS_SLASH:c,NO_DOT:u,NO_DOTS:g,NO_DOTS_SLASH:f,STAR:h,START_ANCHOR:p}=ky.globChars(s),m=t.dot?g:u,y=t.dot?f:u,b=t.capture?"":"?:",v={negated:!1,prefix:""},k=t.bash===!0?".*?":h;t.capture&&(k=`(${k})`);let T=z=>z.noglobstar===!0?k:`(${b}(?:(?!${p}${z.dot?c:o}).)*?)`,Y=z=>{switch(z){case"*":return`${m}${l}${k}`;case".*":return`${o}${l}${k}`;case"*.*":return`${m}${k}${o}${l}${k}`;case"*/*":return`${m}${k}${a}${l}${y}${k}`;case"**":return m+T(t);case"**/*":return`(?:${m}${T(t)}${a})?${y}${l}${k}`;case"**/*.*":return`(?:${m}${T(t)}${a})?${y}${k}${o}${l}${k}`;case"**/.*":return`(?:${m}${T(t)}${a})?${o}${l}${k}`;default:{let ne=/^(.*?)\.(\w+)$/.exec(z);if(!ne)return;let ee=Y(ne[1]);return ee?ee+o+ne[2]:void 0}}},q=is.removePrefix(r,v),$=Y(q);return $&&t.strictSlashes!==!0&&($+=`${a}?`),$};Tq.exports=Mq});var Hq=w((ket,Kq)=>{"use strict";var vBe=require("path"),kBe=Lq(),Qv=Uq(),Sv=Zp(),xBe=Xp(),PBe=r=>r&&typeof r=="object"&&!Array.isArray(r),_r=(r,e,t=!1)=>{if(Array.isArray(r)){let u=r.map(f=>_r(f,e,t));return f=>{for(let h of u){let p=h(f);if(p)return p}return!1}}let i=PBe(r)&&r.tokens&&r.input;if(r===""||typeof r!="string"&&!i)throw new TypeError("Expected pattern to be a non-empty string");let n=e||{},s=Sv.isWindows(e),o=i?_r.compileRe(r,e):_r.makeRe(r,e,!1,!0),a=o.state;delete o.state;let l=()=>!1;if(n.ignore){let u=te(N({},e),{ignore:null,onMatch:null,onResult:null});l=_r(n.ignore,u,t)}let c=(u,g=!1)=>{let{isMatch:f,match:h,output:p}=_r.test(u,o,e,{glob:r,posix:s}),m={glob:r,state:a,regex:o,posix:s,input:u,output:p,match:h,isMatch:f};return typeof n.onResult=="function"&&n.onResult(m),f===!1?(m.isMatch=!1,g?m:!1):l(u)?(typeof n.onIgnore=="function"&&n.onIgnore(m),m.isMatch=!1,g?m:!1):(typeof n.onMatch=="function"&&n.onMatch(m),g?m:!0)};return t&&(c.state=a),c};_r.test=(r,e,t,{glob:i,posix:n}={})=>{if(typeof r!="string")throw new TypeError("Expected input to be a string");if(r==="")return{isMatch:!1,output:""};let s=t||{},o=s.format||(n?Sv.toPosixSlashes:null),a=r===i,l=a&&o?o(r):r;return a===!1&&(l=o?o(r):r,a=l===i),(a===!1||s.capture===!0)&&(s.matchBase===!0||s.basename===!0?a=_r.matchBase(r,e,t,n):a=e.exec(l)),{isMatch:Boolean(a),match:a,output:l}};_r.matchBase=(r,e,t,i=Sv.isWindows(t))=>(e instanceof RegExp?e:_r.makeRe(e,t)).test(vBe.basename(r));_r.isMatch=(r,e,t)=>_r(e,t)(r);_r.parse=(r,e)=>Array.isArray(r)?r.map(t=>_r.parse(t,e)):Qv(r,te(N({},e),{fastpaths:!1}));_r.scan=(r,e)=>kBe(r,e);_r.compileRe=(r,e,t=!1,i=!1)=>{if(t===!0)return r.output;let n=e||{},s=n.contains?"":"^",o=n.contains?"":"$",a=`${s}(?:${r.output})${o}`;r&&r.negated===!0&&(a=`^(?!${a}).*$`);let l=_r.toRegex(a,e);return i===!0&&(l.state=r),l};_r.makeRe=(r,e={},t=!1,i=!1)=>{if(!r||typeof r!="string")throw new TypeError("Expected a non-empty string");let n={negated:!1,fastpaths:!0};return e.fastpaths!==!1&&(r[0]==="."||r[0]==="*")&&(n.output=Qv.fastpaths(r,e)),n.output||(n=Qv(r,e)),_r.compileRe(n,e,t,i)};_r.toRegex=(r,e)=>{try{let t=e||{};return new RegExp(r,t.flags||(t.nocase?"i":""))}catch(t){if(e&&e.debug===!0)throw t;return/$^/}};_r.constants=xBe;Kq.exports=_r});var vv=w((xet,jq)=>{"use strict";jq.exports=Hq()});var ns=w((Pet,Gq)=>{"use strict";var Yq=require("util"),qq=wq(),_o=vv(),kv=Zp(),Jq=r=>r===""||r==="./",Pr=(r,e,t)=>{e=[].concat(e),r=[].concat(r);let i=new Set,n=new Set,s=new Set,o=0,a=u=>{s.add(u.output),t&&t.onResult&&t.onResult(u)};for(let u=0;u<e.length;u++){let g=_o(String(e[u]),te(N({},t),{onResult:a}),!0),f=g.state.negated||g.state.negatedExtglob;f&&o++;for(let h of r){let p=g(h,!0);!(f?!p.isMatch:p.isMatch)||(f?i.add(p.output):(i.delete(p.output),n.add(p.output)))}}let c=(o===e.length?[...s]:[...n]).filter(u=>!i.has(u));if(t&&c.length===0){if(t.failglob===!0)throw new Error(`No matches found for "${e.join(", ")}"`);if(t.nonull===!0||t.nullglob===!0)return t.unescape?e.map(u=>u.replace(/\\/g,"")):e}return c};Pr.match=Pr;Pr.matcher=(r,e)=>_o(r,e);Pr.isMatch=(r,e,t)=>_o(e,t)(r);Pr.any=Pr.isMatch;Pr.not=(r,e,t={})=>{e=[].concat(e).map(String);let i=new Set,n=[],s=a=>{t.onResult&&t.onResult(a),n.push(a.output)},o=Pr(r,e,te(N({},t),{onResult:s}));for(let a of n)o.includes(a)||i.add(a);return[...i]};Pr.contains=(r,e,t)=>{if(typeof r!="string")throw new TypeError(`Expected a string: "${Yq.inspect(r)}"`);if(Array.isArray(e))return e.some(i=>Pr.contains(r,i,t));if(typeof e=="string"){if(Jq(r)||Jq(e))return!1;if(r.includes(e)||r.startsWith("./")&&r.slice(2).includes(e))return!0}return Pr.isMatch(r,e,te(N({},t),{contains:!0}))};Pr.matchKeys=(r,e,t)=>{if(!kv.isObject(r))throw new TypeError("Expected the first argument to be an object");let i=Pr(Object.keys(r),e,t),n={};for(let s of i)n[s]=r[s];return n};Pr.some=(r,e,t)=>{let i=[].concat(r);for(let n of[].concat(e)){let s=_o(String(n),t);if(i.some(o=>s(o)))return!0}return!1};Pr.every=(r,e,t)=>{let i=[].concat(r);for(let n of[].concat(e)){let s=_o(String(n),t);if(!i.every(o=>s(o)))return!1}return!0};Pr.all=(r,e,t)=>{if(typeof r!="string")throw new TypeError(`Expected a string: "${Yq.inspect(r)}"`);return[].concat(e).every(i=>_o(i,t)(r))};Pr.capture=(r,e,t)=>{let i=kv.isWindows(t),s=_o.makeRe(String(r),te(N({},t),{capture:!0})).exec(i?kv.toPosixSlashes(e):e);if(s)return s.slice(1).map(o=>o===void 0?"":o)};Pr.makeRe=(...r)=>_o.makeRe(...r);Pr.scan=(...r)=>_o.scan(...r);Pr.parse=(r,e)=>{let t=[];for(let i of[].concat(r||[]))for(let n of qq(String(i),e))t.push(_o.parse(n,e));return t};Pr.braces=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");return e&&e.nobrace===!0||!/\{.*\}/.test(r)?[r]:qq(r,e)};Pr.braceExpand=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");return Pr.braces(r,te(N({},e),{expand:!0}))};Gq.exports=Pr});var zq=w((Det,Wq)=>{"use strict";Wq.exports=({onlyFirst:r=!1}={})=>{let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,r?void 0:"g")}});var Vq=w((Ret,_q)=>{"use strict";var DBe=zq();_q.exports=r=>typeof r=="string"?r.replace(DBe(),""):r});var gJ=w((Vet,uJ)=>{"use strict";uJ.exports=(...r)=>[...new Set([].concat(...r))]});var Gv=w((Xet,fJ)=>{"use strict";var GBe=require("stream"),hJ=GBe.PassThrough,YBe=Array.prototype.slice;fJ.exports=qBe;function qBe(){let r=[],e=!1,t=YBe.call(arguments),i=t[t.length-1];i&&!Array.isArray(i)&&i.pipe==null?t.pop():i={};let n=i.end!==!1;i.objectMode==null&&(i.objectMode=!0),i.highWaterMark==null&&(i.highWaterMark=64*1024);let s=hJ(i);function o(){for(let c=0,u=arguments.length;c<u;c++)r.push(pJ(arguments[c],i));return a(),this}function a(){if(e)return;e=!0;let c=r.shift();if(!c){process.nextTick(l);return}Array.isArray(c)||(c=[c]);let u=c.length+1;function g(){--u>0||(e=!1,a())}function f(h){function p(){h.removeListener("merge2UnpipeEnd",p),h.removeListener("end",p),g()}if(h._readableState.endEmitted)return g();h.on("merge2UnpipeEnd",p),h.on("end",p),h.pipe(s,{end:!1}),h.resume()}for(let h=0;h<c.length;h++)f(c[h]);g()}function l(){return e=!1,s.emit("queueDrain"),n&&s.end()}return s.setMaxListeners(0),s.add=o,s.on("unpipe",function(c){c.emit("merge2UnpipeEnd")}),t.length&&o.apply(null,t),s}function pJ(r,e){if(Array.isArray(r))for(let t=0,i=r.length;t<i;t++)r[t]=pJ(r[t],e);else{if(!r._readableState&&r.pipe&&(r=r.pipe(hJ(e))),!r._readableState||!r.pause||!r.pipe)throw new Error("Only readable stream can be merged.");r.pause()}return r}});var dJ=w(Ny=>{"use strict";Object.defineProperty(Ny,"__esModule",{value:!0});function JBe(r){return r.reduce((e,t)=>[].concat(e,t),[])}Ny.flatten=JBe;function WBe(r,e){let t=[[]],i=0;for(let n of r)e(n)?(i++,t[i]=[]):t[i].push(n);return t}Ny.splitWhen=WBe});var CJ=w(Yv=>{"use strict";Object.defineProperty(Yv,"__esModule",{value:!0});function zBe(r){return r.code==="ENOENT"}Yv.isEnoentCodeError=zBe});var EJ=w(qv=>{"use strict";Object.defineProperty(qv,"__esModule",{value:!0});var mJ=class{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}};function _Be(r,e){return new mJ(r,e)}qv.createDirentFromStats=_Be});var IJ=w(Kg=>{"use strict";Object.defineProperty(Kg,"__esModule",{value:!0});var VBe=require("path"),XBe=2,ZBe=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g;function $Be(r){return r.replace(/\\/g,"/")}Kg.unixify=$Be;function e0e(r,e){return VBe.resolve(r,e)}Kg.makeAbsolute=e0e;function t0e(r){return r.replace(ZBe,"\\$2")}Kg.escape=t0e;function r0e(r){if(r.charAt(0)==="."){let e=r.charAt(1);if(e==="/"||e==="\\")return r.slice(XBe)}return r}Kg.removeLeadingDotSegment=r0e});var wJ=w((rtt,yJ)=>{yJ.exports=function(e){if(typeof e!="string"||e==="")return!1;for(var t;t=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(t[2])return!0;e=e.slice(t.index+t[0].length)}return!1}});var QJ=w((itt,BJ)=>{var i0e=wJ(),bJ={"{":"}","(":")","[":"]"},n0e=function(r){if(r[0]==="!")return!0;for(var e=0,t=-2,i=-2,n=-2,s=-2,o=-2;e<r.length;){if(r[e]==="*"||r[e+1]==="?"&&/[\].+)]/.test(r[e])||i!==-1&&r[e]==="["&&r[e+1]!=="]"&&(i<e&&(i=r.indexOf("]",e)),i>e&&(o===-1||o>i||(o=r.indexOf("\\",e),o===-1||o>i)))||n!==-1&&r[e]==="{"&&r[e+1]!=="}"&&(n=r.indexOf("}",e),n>e&&(o=r.indexOf("\\",e),o===-1||o>n))||s!==-1&&r[e]==="("&&r[e+1]==="?"&&/[:!=]/.test(r[e+2])&&r[e+3]!==")"&&(s=r.indexOf(")",e),s>e&&(o=r.indexOf("\\",e),o===-1||o>s))||t!==-1&&r[e]==="("&&r[e+1]!=="|"&&(t<e&&(t=r.indexOf("|",e)),t!==-1&&r[t+1]!==")"&&(s=r.indexOf(")",t),s>t&&(o=r.indexOf("\\",t),o===-1||o>s))))return!0;if(r[e]==="\\"){var a=r[e+1];e+=2;var l=bJ[a];if(l){var c=r.indexOf(l,e);c!==-1&&(e=c+1)}if(r[e]==="!")return!0}else e++}return!1},s0e=function(r){if(r[0]==="!")return!0;for(var e=0;e<r.length;){if(/[*?{}()[\]]/.test(r[e]))return!0;if(r[e]==="\\"){var t=r[e+1];e+=2;var i=bJ[t];if(i){var n=r.indexOf(i,e);n!==-1&&(e=n+1)}if(r[e]==="!")return!0}else e++}return!1};BJ.exports=function(e,t){if(typeof e!="string"||e==="")return!1;if(i0e(e))return!0;var i=n0e;return t&&t.strict===!1&&(i=s0e),i(e)}});var vJ=w((ntt,SJ)=>{"use strict";var o0e=QJ(),a0e=require("path").posix.dirname,A0e=require("os").platform()==="win32",Jv="/",l0e=/\\/g,c0e=/[\{\[].*[\}\]]$/,u0e=/(^|[^\\])([\{\[]|\([^\)]+$)/,g0e=/\\([\!\*\?\|\[\]\(\)\{\}])/g;SJ.exports=function(e,t){var i=Object.assign({flipBackslashes:!0},t);i.flipBackslashes&&A0e&&e.indexOf(Jv)<0&&(e=e.replace(l0e,Jv)),c0e.test(e)&&(e+=Jv),e+="a";do e=a0e(e);while(o0e(e)||u0e.test(e));return e.replace(g0e,"$1")}});var TJ=w(si=>{"use strict";Object.defineProperty(si,"__esModule",{value:!0});var f0e=require("path"),h0e=vJ(),kJ=ns(),p0e=vv(),xJ="**",d0e="\\",C0e=/[*?]|^!/,m0e=/\[.*]/,E0e=/(?:^|[^!*+?@])\(.*\|.*\)/,I0e=/[!*+?@]\(.*\)/,y0e=/{.*(?:,|\.\.).*}/;function DJ(r,e={}){return!PJ(r,e)}si.isStaticPattern=DJ;function PJ(r,e={}){return!!(e.caseSensitiveMatch===!1||r.includes(d0e)||C0e.test(r)||m0e.test(r)||E0e.test(r)||e.extglob!==!1&&I0e.test(r)||e.braceExpansion!==!1&&y0e.test(r))}si.isDynamicPattern=PJ;function w0e(r){return Ly(r)?r.slice(1):r}si.convertToPositivePattern=w0e;function B0e(r){return"!"+r}si.convertToNegativePattern=B0e;function Ly(r){return r.startsWith("!")&&r[1]!=="("}si.isNegativePattern=Ly;function RJ(r){return!Ly(r)}si.isPositivePattern=RJ;function b0e(r){return r.filter(Ly)}si.getNegativePatterns=b0e;function Q0e(r){return r.filter(RJ)}si.getPositivePatterns=Q0e;function S0e(r){return h0e(r,{flipBackslashes:!1})}si.getBaseDirectory=S0e;function v0e(r){return r.includes(xJ)}si.hasGlobStar=v0e;function FJ(r){return r.endsWith("/"+xJ)}si.endsWithSlashGlobStar=FJ;function k0e(r){let e=f0e.basename(r);return FJ(r)||DJ(e)}si.isAffectDepthOfReadingPattern=k0e;function x0e(r){return r.reduce((e,t)=>e.concat(NJ(t)),[])}si.expandPatternsWithBraceExpansion=x0e;function NJ(r){return kJ.braces(r,{expand:!0,nodupes:!0})}si.expandBraceExpansion=NJ;function P0e(r,e){let t=p0e.scan(r,Object.assign(Object.assign({},e),{parts:!0}));return t.parts.length===0?[r]:t.parts}si.getPatternParts=P0e;function LJ(r,e){return kJ.makeRe(r,e)}si.makeRe=LJ;function D0e(r,e){return r.map(t=>LJ(t,e))}si.convertPatternsToRe=D0e;function R0e(r,e){return e.some(t=>t.test(r))}si.matchAny=R0e});var MJ=w(Wv=>{"use strict";Object.defineProperty(Wv,"__esModule",{value:!0});var F0e=Gv();function N0e(r){let e=F0e(r);return r.forEach(t=>{t.once("error",i=>e.emit("error",i))}),e.once("close",()=>OJ(r)),e.once("end",()=>OJ(r)),e}Wv.merge=N0e;function OJ(r){r.forEach(e=>e.emit("close"))}});var UJ=w(Ty=>{"use strict";Object.defineProperty(Ty,"__esModule",{value:!0});function L0e(r){return typeof r=="string"}Ty.isString=L0e;function T0e(r){return r===""}Ty.isEmpty=T0e});var Za=w(Xa=>{"use strict";Object.defineProperty(Xa,"__esModule",{value:!0});var O0e=dJ();Xa.array=O0e;var M0e=CJ();Xa.errno=M0e;var U0e=EJ();Xa.fs=U0e;var K0e=IJ();Xa.path=K0e;var H0e=TJ();Xa.pattern=H0e;var j0e=MJ();Xa.stream=j0e;var G0e=UJ();Xa.string=G0e});var YJ=w($a=>{"use strict";Object.defineProperty($a,"__esModule",{value:!0});var Uc=Za();function Y0e(r,e){let t=KJ(r),i=HJ(r,e.ignore),n=t.filter(l=>Uc.pattern.isStaticPattern(l,e)),s=t.filter(l=>Uc.pattern.isDynamicPattern(l,e)),o=zv(n,i,!1),a=zv(s,i,!0);return o.concat(a)}$a.generate=Y0e;function zv(r,e,t){let i=jJ(r);return"."in i?[_v(".",r,e,t)]:GJ(i,e,t)}$a.convertPatternsToTasks=zv;function KJ(r){return Uc.pattern.getPositivePatterns(r)}$a.getPositivePatterns=KJ;function HJ(r,e){return Uc.pattern.getNegativePatterns(r).concat(e).map(Uc.pattern.convertToPositivePattern)}$a.getNegativePatternsAsPositive=HJ;function jJ(r){let e={};return r.reduce((t,i)=>{let n=Uc.pattern.getBaseDirectory(i);return n in t?t[n].push(i):t[n]=[i],t},e)}$a.groupPatternsByBaseDirectory=jJ;function GJ(r,e,t){return Object.keys(r).map(i=>_v(i,r[i],e,t))}$a.convertPatternGroupsToTasks=GJ;function _v(r,e,t,i){return{dynamic:i,positive:e,negative:t,base:r,patterns:[].concat(e,t.map(Uc.pattern.convertToNegativePattern))}}$a.convertPatternGroupToTask=_v});var JJ=w(Oy=>{"use strict";Object.defineProperty(Oy,"__esModule",{value:!0});Oy.read=void 0;function q0e(r,e,t){e.fs.lstat(r,(i,n)=>{if(i!==null){qJ(t,i);return}if(!n.isSymbolicLink()||!e.followSymbolicLink){Vv(t,n);return}e.fs.stat(r,(s,o)=>{if(s!==null){if(e.throwErrorOnBrokenSymbolicLink){qJ(t,s);return}Vv(t,n);return}e.markSymbolicLink&&(o.isSymbolicLink=()=>!0),Vv(t,o)})})}Oy.read=q0e;function qJ(r,e){r(e)}function Vv(r,e){r(null,e)}});var WJ=w(My=>{"use strict";Object.defineProperty(My,"__esModule",{value:!0});My.read=void 0;function J0e(r,e){let t=e.fs.lstatSync(r);if(!t.isSymbolicLink()||!e.followSymbolicLink)return t;try{let i=e.fs.statSync(r);return e.markSymbolicLink&&(i.isSymbolicLink=()=>!0),i}catch(i){if(!e.throwErrorOnBrokenSymbolicLink)return t;throw i}}My.read=J0e});var zJ=w(il=>{"use strict";Object.defineProperty(il,"__esModule",{value:!0});il.createFileSystemAdapter=il.FILE_SYSTEM_ADAPTER=void 0;var Uy=require("fs");il.FILE_SYSTEM_ADAPTER={lstat:Uy.lstat,stat:Uy.stat,lstatSync:Uy.lstatSync,statSync:Uy.statSync};function W0e(r){return r===void 0?il.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},il.FILE_SYSTEM_ADAPTER),r)}il.createFileSystemAdapter=W0e});var VJ=w(Xv=>{"use strict";Object.defineProperty(Xv,"__esModule",{value:!0});var z0e=zJ(),_J=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=z0e.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,t){return e!=null?e:t}};Xv.default=_J});var Kc=w(nl=>{"use strict";Object.defineProperty(nl,"__esModule",{value:!0});nl.statSync=nl.stat=nl.Settings=void 0;var XJ=JJ(),_0e=WJ(),Zv=VJ();nl.Settings=Zv.default;function V0e(r,e,t){if(typeof e=="function"){XJ.read(r,$v(),e);return}XJ.read(r,$v(e),t)}nl.stat=V0e;function X0e(r,e){let t=$v(e);return _0e.read(r,t)}nl.statSync=X0e;function $v(r={}){return r instanceof Zv.default?r:new Zv.default(r)}});var $J=w((ptt,ZJ)=>{ZJ.exports=Z0e;function Z0e(r,e){var t,i,n,s=!0;Array.isArray(r)?(t=[],i=r.length):(n=Object.keys(r),t={},i=n.length);function o(l){function c(){e&&e(l,t),e=null}s?process.nextTick(c):c()}function a(l,c,u){t[l]=u,(--i==0||c)&&o(c)}i?n?n.forEach(function(l){r[l](function(c,u){a(l,c,u)})}):r.forEach(function(l,c){l(function(u,g){a(c,u,g)})}):o(null),s=!1}});var ek=w(Ky=>{"use strict";Object.defineProperty(Ky,"__esModule",{value:!0});Ky.IS_SUPPORT_READDIR_WITH_FILE_TYPES=void 0;var Hy=process.versions.node.split(".");if(Hy[0]===void 0||Hy[1]===void 0)throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);var eW=Number.parseInt(Hy[0],10),$0e=Number.parseInt(Hy[1],10),tW=10,ebe=10,tbe=eW>tW,rbe=eW===tW&&$0e>=ebe;Ky.IS_SUPPORT_READDIR_WITH_FILE_TYPES=tbe||rbe});var iW=w(jy=>{"use strict";Object.defineProperty(jy,"__esModule",{value:!0});jy.createDirentFromStats=void 0;var rW=class{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}};function ibe(r,e){return new rW(r,e)}jy.createDirentFromStats=ibe});var tk=w(Gy=>{"use strict";Object.defineProperty(Gy,"__esModule",{value:!0});Gy.fs=void 0;var nbe=iW();Gy.fs=nbe});var rk=w(Yy=>{"use strict";Object.defineProperty(Yy,"__esModule",{value:!0});Yy.joinPathSegments=void 0;function sbe(r,e,t){return r.endsWith(t)?r+e:r+t+e}Yy.joinPathSegments=sbe});var lW=w(sl=>{"use strict";Object.defineProperty(sl,"__esModule",{value:!0});sl.readdir=sl.readdirWithFileTypes=sl.read=void 0;var obe=Kc(),nW=$J(),abe=ek(),sW=tk(),oW=rk();function Abe(r,e,t){if(!e.stats&&abe.IS_SUPPORT_READDIR_WITH_FILE_TYPES){aW(r,e,t);return}AW(r,e,t)}sl.read=Abe;function aW(r,e,t){e.fs.readdir(r,{withFileTypes:!0},(i,n)=>{if(i!==null){qy(t,i);return}let s=n.map(a=>({dirent:a,name:a.name,path:oW.joinPathSegments(r,a.name,e.pathSegmentSeparator)}));if(!e.followSymbolicLinks){ik(t,s);return}let o=s.map(a=>lbe(a,e));nW(o,(a,l)=>{if(a!==null){qy(t,a);return}ik(t,l)})})}sl.readdirWithFileTypes=aW;function lbe(r,e){return t=>{if(!r.dirent.isSymbolicLink()){t(null,r);return}e.fs.stat(r.path,(i,n)=>{if(i!==null){if(e.throwErrorOnBrokenSymbolicLink){t(i);return}t(null,r);return}r.dirent=sW.fs.createDirentFromStats(r.name,n),t(null,r)})}}function AW(r,e,t){e.fs.readdir(r,(i,n)=>{if(i!==null){qy(t,i);return}let s=n.map(o=>{let a=oW.joinPathSegments(r,o,e.pathSegmentSeparator);return l=>{obe.stat(a,e.fsStatSettings,(c,u)=>{if(c!==null){l(c);return}let g={name:o,path:a,dirent:sW.fs.createDirentFromStats(o,u)};e.stats&&(g.stats=u),l(null,g)})}});nW(s,(o,a)=>{if(o!==null){qy(t,o);return}ik(t,a)})})}sl.readdir=AW;function qy(r,e){r(e)}function ik(r,e){r(null,e)}});var hW=w(ol=>{"use strict";Object.defineProperty(ol,"__esModule",{value:!0});ol.readdir=ol.readdirWithFileTypes=ol.read=void 0;var cbe=Kc(),ube=ek(),cW=tk(),uW=rk();function gbe(r,e){return!e.stats&&ube.IS_SUPPORT_READDIR_WITH_FILE_TYPES?gW(r,e):fW(r,e)}ol.read=gbe;function gW(r,e){return e.fs.readdirSync(r,{withFileTypes:!0}).map(i=>{let n={dirent:i,name:i.name,path:uW.joinPathSegments(r,i.name,e.pathSegmentSeparator)};if(n.dirent.isSymbolicLink()&&e.followSymbolicLinks)try{let s=e.fs.statSync(n.path);n.dirent=cW.fs.createDirentFromStats(n.name,s)}catch(s){if(e.throwErrorOnBrokenSymbolicLink)throw s}return n})}ol.readdirWithFileTypes=gW;function fW(r,e){return e.fs.readdirSync(r).map(i=>{let n=uW.joinPathSegments(r,i,e.pathSegmentSeparator),s=cbe.statSync(n,e.fsStatSettings),o={name:i,path:n,dirent:cW.fs.createDirentFromStats(i,s)};return e.stats&&(o.stats=s),o})}ol.readdir=fW});var pW=w(al=>{"use strict";Object.defineProperty(al,"__esModule",{value:!0});al.createFileSystemAdapter=al.FILE_SYSTEM_ADAPTER=void 0;var Hg=require("fs");al.FILE_SYSTEM_ADAPTER={lstat:Hg.lstat,stat:Hg.stat,lstatSync:Hg.lstatSync,statSync:Hg.statSync,readdir:Hg.readdir,readdirSync:Hg.readdirSync};function fbe(r){return r===void 0?al.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},al.FILE_SYSTEM_ADAPTER),r)}al.createFileSystemAdapter=fbe});var CW=w(nk=>{"use strict";Object.defineProperty(nk,"__esModule",{value:!0});var hbe=require("path"),pbe=Kc(),dbe=pW(),dW=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=dbe.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,hbe.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new pbe.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return e!=null?e:t}};nk.default=dW});var Jy=w(Al=>{"use strict";Object.defineProperty(Al,"__esModule",{value:!0});Al.Settings=Al.scandirSync=Al.scandir=void 0;var mW=lW(),Cbe=hW(),sk=CW();Al.Settings=sk.default;function mbe(r,e,t){if(typeof e=="function"){mW.read(r,ok(),e);return}mW.read(r,ok(e),t)}Al.scandir=mbe;function Ebe(r,e){let t=ok(e);return Cbe.read(r,t)}Al.scandirSync=Ebe;function ok(r={}){return r instanceof sk.default?r:new sk.default(r)}});var IW=w((Qtt,EW)=>{"use strict";function Ibe(r){var e=new r,t=e;function i(){var s=e;return s.next?e=s.next:(e=new r,t=e),s.next=null,s}function n(s){t.next=s,t=s}return{get:i,release:n}}EW.exports=Ibe});var wW=w((Stt,ak)=>{"use strict";var ybe=IW();function yW(r,e,t){if(typeof r=="function"&&(t=e,e=r,r=null),t<1)throw new Error("fastqueue concurrency must be greater than 1");var i=ybe(wbe),n=null,s=null,o=0,a=null,l={push:m,drain:Ls,saturated:Ls,pause:u,paused:!1,concurrency:t,running:c,resume:h,idle:p,length:g,getQueue:f,unshift:y,empty:Ls,kill:v,killAndDrain:k,error:T};return l;function c(){return o}function u(){l.paused=!0}function g(){for(var Y=n,q=0;Y;)Y=Y.next,q++;return q}function f(){for(var Y=n,q=[];Y;)q.push(Y.value),Y=Y.next;return q}function h(){if(!!l.paused){l.paused=!1;for(var Y=0;Y<l.concurrency;Y++)o++,b()}}function p(){return o===0&&l.length()===0}function m(Y,q){var $=i.get();$.context=r,$.release=b,$.value=Y,$.callback=q||Ls,$.errorHandler=a,o===l.concurrency||l.paused?s?(s.next=$,s=$):(n=$,s=$,l.saturated()):(o++,e.call(r,$.value,$.worked))}function y(Y,q){var $=i.get();$.context=r,$.release=b,$.value=Y,$.callback=q||Ls,o===l.concurrency||l.paused?n?($.next=n,n=$):(n=$,s=$,l.saturated()):(o++,e.call(r,$.value,$.worked))}function b(Y){Y&&i.release(Y);var q=n;q?l.paused?o--:(s===n&&(s=null),n=q.next,q.next=null,e.call(r,q.value,q.worked),s===null&&l.empty()):--o==0&&l.drain()}function v(){n=null,s=null,l.drain=Ls}function k(){n=null,s=null,l.drain(),l.drain=Ls}function T(Y){a=Y}}function Ls(){}function wbe(){this.value=null,this.callback=Ls,this.next=null,this.release=Ls,this.context=null,this.errorHandler=null;var r=this;this.worked=function(t,i){var n=r.callback,s=r.errorHandler,o=r.value;r.value=null,r.callback=Ls,r.errorHandler&&s(t,o),n.call(r.context,t,i),r.release(r)}}function Bbe(r,e,t){typeof r=="function"&&(t=e,e=r,r=null);function i(u,g){e.call(this,u).then(function(f){g(null,f)},g)}var n=yW(r,i,t),s=n.push,o=n.unshift;return n.push=a,n.unshift=l,n.drained=c,n;function a(u){var g=new Promise(function(f,h){s(u,function(p,m){if(p){h(p);return}f(m)})});return g.catch(Ls),g}function l(u){var g=new Promise(function(f,h){o(u,function(p,m){if(p){h(p);return}f(m)})});return g.catch(Ls),g}function c(){var u=n.drain,g=new Promise(function(f){n.drain=function(){u(),f()}});return g}}ak.exports=yW;ak.exports.promise=Bbe});var Wy=w(Zo=>{"use strict";Object.defineProperty(Zo,"__esModule",{value:!0});Zo.joinPathSegments=Zo.replacePathSegmentSeparator=Zo.isAppliedFilter=Zo.isFatalError=void 0;function bbe(r,e){return r.errorFilter===null?!0:!r.errorFilter(e)}Zo.isFatalError=bbe;function Qbe(r,e){return r===null||r(e)}Zo.isAppliedFilter=Qbe;function Sbe(r,e){return r.split(/[/\\]/).join(e)}Zo.replacePathSegmentSeparator=Sbe;function vbe(r,e,t){return r===""?e:r.endsWith(t)?r+e:r+t+e}Zo.joinPathSegments=vbe});var lk=w(Ak=>{"use strict";Object.defineProperty(Ak,"__esModule",{value:!0});var kbe=Wy(),BW=class{constructor(e,t){this._root=e,this._settings=t,this._root=kbe.replacePathSegmentSeparator(e,t.pathSegmentSeparator)}};Ak.default=BW});var uk=w(ck=>{"use strict";Object.defineProperty(ck,"__esModule",{value:!0});var xbe=require("events"),Pbe=Jy(),Dbe=wW(),zy=Wy(),Rbe=lk(),bW=class extends Rbe.default{constructor(e,t){super(e,t);this._settings=t,this._scandir=Pbe.scandir,this._emitter=new xbe.EventEmitter,this._queue=Dbe(this._worker.bind(this),this._settings.concurrency),this._isFatalError=!1,this._isDestroyed=!1,this._queue.drain=()=>{this._isFatalError||this._emitter.emit("end")}}read(){return this._isFatalError=!1,this._isDestroyed=!1,setImmediate(()=>{this._pushToQueue(this._root,this._settings.basePath)}),this._emitter}get isDestroyed(){return this._isDestroyed}destroy(){if(this._isDestroyed)throw new Error("The reader is already destroyed");this._isDestroyed=!0,this._queue.killAndDrain()}onEntry(e){this._emitter.on("entry",e)}onError(e){this._emitter.once("error",e)}onEnd(e){this._emitter.once("end",e)}_pushToQueue(e,t){let i={directory:e,base:t};this._queue.push(i,n=>{n!==null&&this._handleError(n)})}_worker(e,t){this._scandir(e.directory,this._settings.fsScandirSettings,(i,n)=>{if(i!==null){t(i,void 0);return}for(let s of n)this._handleEntry(s,e.base);t(null,void 0)})}_handleError(e){this._isDestroyed||!zy.isFatalError(this._settings,e)||(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,t){if(this._isDestroyed||this._isFatalError)return;let i=e.path;t!==void 0&&(e.path=zy.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),zy.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&zy.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_emitEntry(e){this._emitter.emit("entry",e)}};ck.default=bW});var SW=w(gk=>{"use strict";Object.defineProperty(gk,"__esModule",{value:!0});var Fbe=uk(),QW=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new Fbe.default(this._root,this._settings),this._storage=new Set}read(e){this._reader.onError(t=>{Nbe(e,t)}),this._reader.onEntry(t=>{this._storage.add(t)}),this._reader.onEnd(()=>{Lbe(e,[...this._storage])}),this._reader.read()}};gk.default=QW;function Nbe(r,e){r(e)}function Lbe(r,e){r(null,e)}});var kW=w(fk=>{"use strict";Object.defineProperty(fk,"__esModule",{value:!0});var Tbe=require("stream"),Obe=uk(),vW=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new Obe.default(this._root,this._settings),this._stream=new Tbe.Readable({objectMode:!0,read:()=>{},destroy:()=>{this._reader.isDestroyed||this._reader.destroy()}})}read(){return this._reader.onError(e=>{this._stream.emit("error",e)}),this._reader.onEntry(e=>{this._stream.push(e)}),this._reader.onEnd(()=>{this._stream.push(null)}),this._reader.read(),this._stream}};fk.default=vW});var PW=w(hk=>{"use strict";Object.defineProperty(hk,"__esModule",{value:!0});var Mbe=Jy(),_y=Wy(),Ube=lk(),xW=class extends Ube.default{constructor(){super(...arguments);this._scandir=Mbe.scandirSync,this._storage=new Set,this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),[...this._storage]}_pushToQueue(e,t){this._queue.add({directory:e,base:t})}_handleQueue(){for(let e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,t){try{let i=this._scandir(e,this._settings.fsScandirSettings);for(let n of i)this._handleEntry(n,t)}catch(i){this._handleError(i)}}_handleError(e){if(!!_y.isFatalError(this._settings,e))throw e}_handleEntry(e,t){let i=e.path;t!==void 0&&(e.path=_y.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),_y.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&_y.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_pushToStorage(e){this._storage.add(e)}};hk.default=xW});var RW=w(pk=>{"use strict";Object.defineProperty(pk,"__esModule",{value:!0});var Kbe=PW(),DW=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new Kbe.default(this._root,this._settings)}read(){return this._reader.read()}};pk.default=DW});var NW=w(dk=>{"use strict";Object.defineProperty(dk,"__esModule",{value:!0});var Hbe=require("path"),jbe=Jy(),FW=class{constructor(e={}){this._options=e,this.basePath=this._getValue(this._options.basePath,void 0),this.concurrency=this._getValue(this._options.concurrency,Number.POSITIVE_INFINITY),this.deepFilter=this._getValue(this._options.deepFilter,null),this.entryFilter=this._getValue(this._options.entryFilter,null),this.errorFilter=this._getValue(this._options.errorFilter,null),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,Hbe.sep),this.fsScandirSettings=new jbe.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return e!=null?e:t}};dk.default=FW});var mk=w($o=>{"use strict";Object.defineProperty($o,"__esModule",{value:!0});$o.Settings=$o.walkStream=$o.walkSync=$o.walk=void 0;var LW=SW(),Gbe=kW(),Ybe=RW(),Ck=NW();$o.Settings=Ck.default;function qbe(r,e,t){if(typeof e=="function"){new LW.default(r,Vy()).read(e);return}new LW.default(r,Vy(e)).read(t)}$o.walk=qbe;function Jbe(r,e){let t=Vy(e);return new Ybe.default(r,t).read()}$o.walkSync=Jbe;function Wbe(r,e){let t=Vy(e);return new Gbe.default(r,t).read()}$o.walkStream=Wbe;function Vy(r={}){return r instanceof Ck.default?r:new Ck.default(r)}});var Ik=w(Ek=>{"use strict";Object.defineProperty(Ek,"__esModule",{value:!0});var zbe=require("path"),_be=Kc(),TW=Za(),OW=class{constructor(e){this._settings=e,this._fsStatSettings=new _be.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return zbe.resolve(this._settings.cwd,e)}_makeEntry(e,t){let i={name:t,path:t,dirent:TW.fs.createDirentFromStats(t,e)};return this._settings.stats&&(i.stats=e),i}_isFatalError(e){return!TW.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}};Ek.default=OW});var wk=w(yk=>{"use strict";Object.defineProperty(yk,"__esModule",{value:!0});var Vbe=require("stream"),Xbe=Kc(),Zbe=mk(),$be=Ik(),MW=class extends $be.default{constructor(){super(...arguments);this._walkStream=Zbe.walkStream,this._stat=Xbe.stat}dynamic(e,t){return this._walkStream(e,t)}static(e,t){let i=e.map(this._getFullEntryPath,this),n=new Vbe.PassThrough({objectMode:!0});n._write=(s,o,a)=>this._getEntry(i[s],e[s],t).then(l=>{l!==null&&t.entryFilter(l)&&n.push(l),s===i.length-1&&n.end(),a()}).catch(a);for(let s=0;s<i.length;s++)n.write(s);return n}_getEntry(e,t,i){return this._getStat(e).then(n=>this._makeEntry(n,t)).catch(n=>{if(i.errorFilter(n))return null;throw n})}_getStat(e){return new Promise((t,i)=>{this._stat(e,this._fsStatSettings,(n,s)=>n===null?t(s):i(n))})}};yk.default=MW});var KW=w(Bk=>{"use strict";Object.defineProperty(Bk,"__esModule",{value:!0});var jg=Za(),UW=class{constructor(e,t,i){this._patterns=e,this._settings=t,this._micromatchOptions=i,this._storage=[],this._fillStorage()}_fillStorage(){let e=jg.pattern.expandPatternsWithBraceExpansion(this._patterns);for(let t of e){let i=this._getPatternSegments(t),n=this._splitSegmentsIntoSections(i);this._storage.push({complete:n.length<=1,pattern:t,segments:i,sections:n})}}_getPatternSegments(e){return jg.pattern.getPatternParts(e,this._micromatchOptions).map(i=>jg.pattern.isDynamicPattern(i,this._settings)?{dynamic:!0,pattern:i,patternRe:jg.pattern.makeRe(i,this._micromatchOptions)}:{dynamic:!1,pattern:i})}_splitSegmentsIntoSections(e){return jg.array.splitWhen(e,t=>t.dynamic&&jg.pattern.hasGlobStar(t.pattern))}};Bk.default=UW});var jW=w(bk=>{"use strict";Object.defineProperty(bk,"__esModule",{value:!0});var eQe=KW(),HW=class extends eQe.default{match(e){let t=e.split("/"),i=t.length,n=this._storage.filter(s=>!s.complete||s.segments.length>i);for(let s of n){let o=s.sections[0];if(!s.complete&&i>o.length||t.every((l,c)=>{let u=s.segments[c];return!!(u.dynamic&&u.patternRe.test(l)||!u.dynamic&&u.pattern===l)}))return!0}return!1}};bk.default=HW});var YW=w(Qk=>{"use strict";Object.defineProperty(Qk,"__esModule",{value:!0});var Xy=Za(),tQe=jW(),GW=class{constructor(e,t){this._settings=e,this._micromatchOptions=t}getFilter(e,t,i){let n=this._getMatcher(t),s=this._getNegativePatternsRe(i);return o=>this._filter(e,o,n,s)}_getMatcher(e){return new tQe.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){let t=e.filter(Xy.pattern.isAffectDepthOfReadingPattern);return Xy.pattern.convertPatternsToRe(t,this._micromatchOptions)}_filter(e,t,i,n){let s=this._getEntryLevel(e,t.path);if(this._isSkippedByDeep(s)||this._isSkippedSymbolicLink(t))return!1;let o=Xy.path.removeLeadingDotSegment(t.path);return this._isSkippedByPositivePatterns(o,i)?!1:this._isSkippedByNegativePatterns(o,n)}_isSkippedByDeep(e){return e>=this._settings.deep}_isSkippedSymbolicLink(e){return!this._settings.followSymbolicLinks&&e.dirent.isSymbolicLink()}_getEntryLevel(e,t){let i=e.split("/").length;return t.split("/").length-(e===""?0:i)}_isSkippedByPositivePatterns(e,t){return!this._settings.baseNameMatch&&!t.match(e)}_isSkippedByNegativePatterns(e,t){return!Xy.pattern.matchAny(e,t)}};Qk.default=GW});var JW=w(Sk=>{"use strict";Object.defineProperty(Sk,"__esModule",{value:!0});var od=Za(),qW=class{constructor(e,t){this._settings=e,this._micromatchOptions=t,this.index=new Map}getFilter(e,t){let i=od.pattern.convertPatternsToRe(e,this._micromatchOptions),n=od.pattern.convertPatternsToRe(t,this._micromatchOptions);return s=>this._filter(s,i,n)}_filter(e,t,i){if(this._settings.unique){if(this._isDuplicateEntry(e))return!1;this._createIndexRecord(e)}if(this._onlyFileFilter(e)||this._onlyDirectoryFilter(e)||this._isSkippedByAbsoluteNegativePatterns(e,i))return!1;let n=this._settings.baseNameMatch?e.name:e.path;return this._isMatchToPatterns(n,t)&&!this._isMatchToPatterns(e.path,i)}_isDuplicateEntry(e){return this.index.has(e.path)}_createIndexRecord(e){this.index.set(e.path,void 0)}_onlyFileFilter(e){return this._settings.onlyFiles&&!e.dirent.isFile()}_onlyDirectoryFilter(e){return this._settings.onlyDirectories&&!e.dirent.isDirectory()}_isSkippedByAbsoluteNegativePatterns(e,t){if(!this._settings.absolute)return!1;let i=od.path.makeAbsolute(this._settings.cwd,e.path);return this._isMatchToPatterns(i,t)}_isMatchToPatterns(e,t){let i=od.path.removeLeadingDotSegment(e);return od.pattern.matchAny(i,t)}};Sk.default=qW});var zW=w(vk=>{"use strict";Object.defineProperty(vk,"__esModule",{value:!0});var rQe=Za(),WW=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return rQe.errno.isEnoentCodeError(e)||this._settings.suppressErrors}};vk.default=WW});var XW=w(kk=>{"use strict";Object.defineProperty(kk,"__esModule",{value:!0});var _W=Za(),VW=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let t=e.path;return this._settings.absolute&&(t=_W.path.makeAbsolute(this._settings.cwd,t),t=_W.path.unixify(t)),this._settings.markDirectories&&e.dirent.isDirectory()&&(t+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:t}):t}};kk.default=VW});var Zy=w(xk=>{"use strict";Object.defineProperty(xk,"__esModule",{value:!0});var iQe=require("path"),nQe=YW(),sQe=JW(),oQe=zW(),aQe=XW(),ZW=class{constructor(e){this._settings=e,this.errorFilter=new oQe.default(this._settings),this.entryFilter=new sQe.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new nQe.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new aQe.default(this._settings)}_getRootDirectory(e){return iQe.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){let t=e.base==="."?"":e.base;return{basePath:t,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(t,e.positive,e.negative),entryFilter:this.entryFilter.getFilter(e.positive,e.negative),errorFilter:this.errorFilter.getFilter(),followSymbolicLinks:this._settings.followSymbolicLinks,fs:this._settings.fs,stats:this._settings.stats,throwErrorOnBrokenSymbolicLink:this._settings.throwErrorOnBrokenSymbolicLink,transform:this.entryTransformer.getTransformer()}}_getMicromatchOptions(){return{dot:this._settings.dot,matchBase:this._settings.baseNameMatch,nobrace:!this._settings.braceExpansion,nocase:!this._settings.caseSensitiveMatch,noext:!this._settings.extglob,noglobstar:!this._settings.globstar,posix:!0,strictSlashes:!1}}};xk.default=ZW});var e3=w(Pk=>{"use strict";Object.defineProperty(Pk,"__esModule",{value:!0});var AQe=wk(),lQe=Zy(),$W=class extends lQe.default{constructor(){super(...arguments);this._reader=new AQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e),n=[];return new Promise((s,o)=>{let a=this.api(t,e,i);a.once("error",o),a.on("data",l=>n.push(i.transform(l))),a.once("end",()=>s(n))})}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};Pk.default=$W});var r3=w(Dk=>{"use strict";Object.defineProperty(Dk,"__esModule",{value:!0});var cQe=require("stream"),uQe=wk(),gQe=Zy(),t3=class extends gQe.default{constructor(){super(...arguments);this._reader=new uQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e),n=this.api(t,e,i),s=new cQe.Readable({objectMode:!0,read:()=>{}});return n.once("error",o=>s.emit("error",o)).on("data",o=>s.emit("data",i.transform(o))).once("end",()=>s.emit("end")),s.once("close",()=>n.destroy()),s}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};Dk.default=t3});var n3=w(Rk=>{"use strict";Object.defineProperty(Rk,"__esModule",{value:!0});var fQe=Kc(),hQe=mk(),pQe=Ik(),i3=class extends pQe.default{constructor(){super(...arguments);this._walkSync=hQe.walkSync,this._statSync=fQe.statSync}dynamic(e,t){return this._walkSync(e,t)}static(e,t){let i=[];for(let n of e){let s=this._getFullEntryPath(n),o=this._getEntry(s,n,t);o===null||!t.entryFilter(o)||i.push(o)}return i}_getEntry(e,t,i){try{let n=this._getStat(e);return this._makeEntry(n,t)}catch(n){if(i.errorFilter(n))return null;throw n}}_getStat(e){return this._statSync(e,this._fsStatSettings)}};Rk.default=i3});var o3=w(Fk=>{"use strict";Object.defineProperty(Fk,"__esModule",{value:!0});var dQe=n3(),CQe=Zy(),s3=class extends CQe.default{constructor(){super(...arguments);this._reader=new dQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e);return this.api(t,e,i).map(i.transform)}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};Fk.default=s3});var A3=w(ad=>{"use strict";Object.defineProperty(ad,"__esModule",{value:!0});var Gg=require("fs"),mQe=require("os"),EQe=mQe.cpus().length;ad.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:Gg.lstat,lstatSync:Gg.lstatSync,stat:Gg.stat,statSync:Gg.statSync,readdir:Gg.readdir,readdirSync:Gg.readdirSync};var a3=class{constructor(e={}){this._options=e,this.absolute=this._getValue(this._options.absolute,!1),this.baseNameMatch=this._getValue(this._options.baseNameMatch,!1),this.braceExpansion=this._getValue(this._options.braceExpansion,!0),this.caseSensitiveMatch=this._getValue(this._options.caseSensitiveMatch,!0),this.concurrency=this._getValue(this._options.concurrency,EQe),this.cwd=this._getValue(this._options.cwd,process.cwd()),this.deep=this._getValue(this._options.deep,Infinity),this.dot=this._getValue(this._options.dot,!1),this.extglob=this._getValue(this._options.extglob,!0),this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!0),this.fs=this._getFileSystemMethods(this._options.fs),this.globstar=this._getValue(this._options.globstar,!0),this.ignore=this._getValue(this._options.ignore,[]),this.markDirectories=this._getValue(this._options.markDirectories,!1),this.objectMode=this._getValue(this._options.objectMode,!1),this.onlyDirectories=this._getValue(this._options.onlyDirectories,!1),this.onlyFiles=this._getValue(this._options.onlyFiles,!0),this.stats=this._getValue(this._options.stats,!1),this.suppressErrors=this._getValue(this._options.suppressErrors,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!1),this.unique=this._getValue(this._options.unique,!0),this.onlyDirectories&&(this.onlyFiles=!1),this.stats&&(this.objectMode=!0)}_getValue(e,t){return e===void 0?t:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},ad.DEFAULT_FILE_SYSTEM_ADAPTER),e)}};ad.default=a3});var $y=w((Vtt,l3)=>{"use strict";var c3=YJ(),IQe=e3(),yQe=r3(),wQe=o3(),Nk=A3(),Hc=Za();async function Tk(r,e){Yg(r);let t=Lk(r,IQe.default,e),i=await Promise.all(t);return Hc.array.flatten(i)}(function(r){function e(o,a){Yg(o);let l=Lk(o,wQe.default,a);return Hc.array.flatten(l)}r.sync=e;function t(o,a){Yg(o);let l=Lk(o,yQe.default,a);return Hc.stream.merge(l)}r.stream=t;function i(o,a){Yg(o);let l=[].concat(o),c=new Nk.default(a);return c3.generate(l,c)}r.generateTasks=i;function n(o,a){Yg(o);let l=new Nk.default(a);return Hc.pattern.isDynamicPattern(o,l)}r.isDynamicPattern=n;function s(o){return Yg(o),Hc.path.escape(o)}r.escapePath=s})(Tk||(Tk={}));function Lk(r,e,t){let i=[].concat(r),n=new Nk.default(t),s=c3.generate(i,n),o=new e(n);return s.map(o.read,o)}function Yg(r){if(![].concat(r).every(i=>Hc.string.isString(i)&&!Hc.string.isEmpty(i)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}l3.exports=Tk});var g3=w(jc=>{"use strict";var{promisify:BQe}=require("util"),u3=require("fs");async function Ok(r,e,t){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);try{return(await BQe(u3[r])(t))[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}function Mk(r,e,t){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);try{return u3[r](t)[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}jc.isFile=Ok.bind(null,"stat","isFile");jc.isDirectory=Ok.bind(null,"stat","isDirectory");jc.isSymlink=Ok.bind(null,"lstat","isSymbolicLink");jc.isFileSync=Mk.bind(null,"statSync","isFile");jc.isDirectorySync=Mk.bind(null,"statSync","isDirectory");jc.isSymlinkSync=Mk.bind(null,"lstatSync","isSymbolicLink")});var C3=w((Ztt,Uk)=>{"use strict";var Gc=require("path"),f3=g3(),h3=r=>r.length>1?`{${r.join(",")}}`:r[0],p3=(r,e)=>{let t=r[0]==="!"?r.slice(1):r;return Gc.isAbsolute(t)?t:Gc.join(e,t)},bQe=(r,e)=>Gc.extname(r)?`**/${r}`:`**/${r}.${h3(e)}`,d3=(r,e)=>{if(e.files&&!Array.isArray(e.files))throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof e.files}\``);if(e.extensions&&!Array.isArray(e.extensions))throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof e.extensions}\``);return e.files&&e.extensions?e.files.map(t=>Gc.posix.join(r,bQe(t,e.extensions))):e.files?e.files.map(t=>Gc.posix.join(r,`**/${t}`)):e.extensions?[Gc.posix.join(r,`**/*.${h3(e.extensions)}`)]:[Gc.posix.join(r,"**")]};Uk.exports=async(r,e)=>{if(e=N({cwd:process.cwd()},e),typeof e.cwd!="string")throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof e.cwd}\``);let t=await Promise.all([].concat(r).map(async i=>await f3.isDirectory(p3(i,e.cwd))?d3(i,e):i));return[].concat.apply([],t)};Uk.exports.sync=(r,e)=>{if(e=N({cwd:process.cwd()},e),typeof e.cwd!="string")throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof e.cwd}\``);let t=[].concat(r).map(i=>f3.isDirectorySync(p3(i,e.cwd))?d3(i,e):i);return[].concat.apply([],t)}});var v3=w(($tt,m3)=>{function E3(r){return Array.isArray(r)?r:[r]}var I3="",y3=" ",Kk="\\",QQe=/^\s+$/,SQe=/^\\!/,vQe=/^\\#/,kQe=/\r?\n/g,xQe=/^\.*\/|^\.+$/,Hk="/",w3=typeof Symbol!="undefined"?Symbol.for("node-ignore"):"node-ignore",PQe=(r,e,t)=>Object.defineProperty(r,e,{value:t}),DQe=/([0-z])-([0-z])/g,RQe=r=>r.replace(DQe,(e,t,i)=>t.charCodeAt(0)<=i.charCodeAt(0)?e:I3),FQe=r=>{let{length:e}=r;return r.slice(0,e-e%2)},NQe=[[/\\?\s+$/,r=>r.indexOf("\\")===0?y3:I3],[/\\\s/g,()=>y3],[/[\\$.|*+(){^]/g,r=>`\\${r}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(r,e,t)=>e+6<t.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)\\\*(?=.+)/g,(r,e)=>`${e}[^\\/]*`],[/\\\\\\(?=[$.|*+(){^])/g,()=>Kk],[/\\\\/g,()=>Kk],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(r,e,t,i,n)=>e===Kk?`\\[${t}${FQe(i)}${n}`:n==="]"&&i.length%2==0?`[${RQe(t)}${i}]`:"[]"],[/(?:[^*])$/,r=>/\/$/.test(r)?`${r}$`:`${r}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(r,e)=>`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`]],B3=Object.create(null),LQe=(r,e)=>{let t=B3[r];return t||(t=NQe.reduce((i,n)=>i.replace(n[0],n[1].bind(r)),r),B3[r]=t),e?new RegExp(t,"i"):new RegExp(t)},jk=r=>typeof r=="string",TQe=r=>r&&jk(r)&&!QQe.test(r)&&r.indexOf("#")!==0,OQe=r=>r.split(kQe),b3=class{constructor(e,t,i,n){this.origin=e,this.pattern=t,this.negative=i,this.regex=n}},MQe=(r,e)=>{let t=r,i=!1;r.indexOf("!")===0&&(i=!0,r=r.substr(1)),r=r.replace(SQe,"!").replace(vQe,"#");let n=LQe(r,e);return new b3(t,r,i,n)},UQe=(r,e)=>{throw new e(r)},eA=(r,e,t)=>jk(r)?r?eA.isNotRelative(r)?t(`path should be a \`path.relative()\`d string, but got "${e}"`,RangeError):!0:t("path must not be empty",TypeError):t(`path must be a string, but got \`${e}\``,TypeError),Q3=r=>xQe.test(r);eA.isNotRelative=Q3;eA.convert=r=>r;var S3=class{constructor({ignorecase:e=!0}={}){PQe(this,w3,!0),this._rules=[],this._ignorecase=e,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[w3]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(TQe(e)){let t=MQe(e,this._ignorecase);this._added=!0,this._rules.push(t)}}add(e){return this._added=!1,E3(jk(e)?OQe(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,t){let i=!1,n=!1;return this._rules.forEach(s=>{let{negative:o}=s;if(n===o&&i!==n||o&&!i&&!n&&!t)return;s.regex.test(e)&&(i=!o,n=o)}),{ignored:i,unignored:n}}_test(e,t,i,n){let s=e&&eA.convert(e);return eA(s,e,UQe),this._t(s,t,i,n)}_t(e,t,i,n){if(e in t)return t[e];if(n||(n=e.split(Hk)),n.pop(),!n.length)return t[e]=this._testOne(e,i);let s=this._t(n.join(Hk)+Hk,t,i,n);return t[e]=s.ignored?s:this._testOne(e,i)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return E3(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},ew=r=>new S3(r),KQe=()=>!1,HQe=r=>eA(r&&eA.convert(r),r,KQe);ew.isPathValid=HQe;ew.default=ew;m3.exports=ew;if(typeof process!="undefined"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let r=t=>/^\\\\\?\\/.test(t)||/["<>|\u0000-\u001F]+/u.test(t)?t:t.replace(/\\/g,"/");eA.convert=r;let e=/^[a-z]:\//i;eA.isNotRelative=t=>e.test(t)||Q3(t)}});var x3=w((ert,k3)=>{"use strict";k3.exports=r=>{let e=/^\\\\\?\\/.test(r),t=/[^\u0000-\u0080]+/.test(r);return e||t?r:r.replace(/\\/g,"/")}});var T3=w((trt,Gk)=>{"use strict";var{promisify:jQe}=require("util"),P3=require("fs"),tA=require("path"),D3=$y(),GQe=v3(),Ad=x3(),R3=["**/node_modules/**","**/flow-typed/**","**/coverage/**","**/.git"],YQe=jQe(P3.readFile),qQe=r=>e=>e.startsWith("!")?"!"+tA.posix.join(r,e.slice(1)):tA.posix.join(r,e),JQe=(r,e)=>{let t=Ad(tA.relative(e.cwd,tA.dirname(e.fileName)));return r.split(/\r?\n/).filter(Boolean).filter(i=>!i.startsWith("#")).map(qQe(t))},F3=r=>{let e=GQe();for(let t of r)e.add(JQe(t.content,{cwd:t.cwd,fileName:t.filePath}));return e},WQe=(r,e)=>{if(r=Ad(r),tA.isAbsolute(e)){if(Ad(e).startsWith(r))return e;throw new Error(`Path ${e} is not in cwd ${r}`)}return tA.join(r,e)},N3=(r,e)=>t=>r.ignores(Ad(tA.relative(e,WQe(e,t.path||t)))),zQe=async(r,e)=>{let t=tA.join(e,r),i=await YQe(t,"utf8");return{cwd:e,filePath:t,content:i}},_Qe=(r,e)=>{let t=tA.join(e,r),i=P3.readFileSync(t,"utf8");return{cwd:e,filePath:t,content:i}},L3=({ignore:r=[],cwd:e=Ad(process.cwd())}={})=>({ignore:r,cwd:e});Gk.exports=async r=>{r=L3(r);let e=await D3("**/.gitignore",{ignore:R3.concat(r.ignore),cwd:r.cwd}),t=await Promise.all(e.map(n=>zQe(n,r.cwd))),i=F3(t);return N3(i,r.cwd)};Gk.exports.sync=r=>{r=L3(r);let t=D3.sync("**/.gitignore",{ignore:R3.concat(r.ignore),cwd:r.cwd}).map(n=>_Qe(n,r.cwd)),i=F3(t);return N3(i,r.cwd)}});var K3=w((rrt,O3)=>{"use strict";var{Transform:VQe}=require("stream"),Yk=class extends VQe{constructor(){super({objectMode:!0})}},M3=class extends Yk{constructor(e){super();this._filter=e}_transform(e,t,i){this._filter(e)&&this.push(e),i()}},U3=class extends Yk{constructor(){super();this._pushed=new Set}_transform(e,t,i){this._pushed.has(e)||(this.push(e),this._pushed.add(e)),i()}};O3.exports={FilterStream:M3,UniqueStream:U3}});var zk=w((irt,Yc)=>{"use strict";var H3=require("fs"),tw=gJ(),XQe=Gv(),rw=$y(),iw=C3(),qk=T3(),{FilterStream:ZQe,UniqueStream:$Qe}=K3(),j3=()=>!1,G3=r=>r[0]==="!",eSe=r=>{if(!r.every(e=>typeof e=="string"))throw new TypeError("Patterns must be a string or an array of strings")},tSe=(r={})=>{if(!r.cwd)return;let e;try{e=H3.statSync(r.cwd)}catch{return}if(!e.isDirectory())throw new Error("The `cwd` option must be a path to a directory")},rSe=r=>r.stats instanceof H3.Stats?r.path:r,nw=(r,e)=>{r=tw([].concat(r)),eSe(r),tSe(e);let t=[];e=N({ignore:[],expandDirectories:!0},e);for(let[i,n]of r.entries()){if(G3(n))continue;let s=r.slice(i).filter(a=>G3(a)).map(a=>a.slice(1)),o=te(N({},e),{ignore:e.ignore.concat(s)});t.push({pattern:n,options:o})}return t},iSe=(r,e)=>{let t={};return r.options.cwd&&(t.cwd=r.options.cwd),Array.isArray(r.options.expandDirectories)?t=te(N({},t),{files:r.options.expandDirectories}):typeof r.options.expandDirectories=="object"&&(t=N(N({},t),r.options.expandDirectories)),e(r.pattern,t)},Jk=(r,e)=>r.options.expandDirectories?iSe(r,e):[r.pattern],Y3=r=>r&&r.gitignore?qk.sync({cwd:r.cwd,ignore:r.ignore}):j3,Wk=r=>e=>{let{options:t}=r;return t.ignore&&Array.isArray(t.ignore)&&t.expandDirectories&&(t.ignore=iw.sync(t.ignore)),{pattern:e,options:t}};Yc.exports=async(r,e)=>{let t=nw(r,e),i=async()=>e&&e.gitignore?qk({cwd:e.cwd,ignore:e.ignore}):j3,n=async()=>{let l=await Promise.all(t.map(async c=>{let u=await Jk(c,iw);return Promise.all(u.map(Wk(c)))}));return tw(...l)},[s,o]=await Promise.all([i(),n()]),a=await Promise.all(o.map(l=>rw(l.pattern,l.options)));return tw(...a).filter(l=>!s(rSe(l)))};Yc.exports.sync=(r,e)=>{let t=nw(r,e),i=[];for(let o of t){let a=Jk(o,iw.sync).map(Wk(o));i.push(...a)}let n=Y3(e),s=[];for(let o of i)s=tw(s,rw.sync(o.pattern,o.options));return s.filter(o=>!n(o))};Yc.exports.stream=(r,e)=>{let t=nw(r,e),i=[];for(let a of t){let l=Jk(a,iw.sync).map(Wk(a));i.push(...l)}let n=Y3(e),s=new ZQe(a=>!n(a)),o=new $Qe;return XQe(i.map(a=>rw.stream(a.pattern,a.options))).pipe(s).pipe(o)};Yc.exports.generateGlobTasks=nw;Yc.exports.hasMagic=(r,e)=>[].concat(r).some(t=>rw.isDynamicPattern(t,e));Yc.exports.gitignore=qk});var Fn=w((Prt,s4)=>{function dSe(r){var e=typeof r;return r!=null&&(e=="object"||e=="function")}s4.exports=dSe});var ix=w((Drt,o4)=>{var CSe=typeof global=="object"&&global&&global.Object===Object&&global;o4.exports=CSe});var Ts=w((Rrt,a4)=>{var mSe=ix(),ESe=typeof self=="object"&&self&&self.Object===Object&&self,ISe=mSe||ESe||Function("return this")();a4.exports=ISe});var l4=w((Frt,A4)=>{var ySe=Ts(),wSe=function(){return ySe.Date.now()};A4.exports=wSe});var u4=w((Nrt,c4)=>{var BSe=/\s/;function bSe(r){for(var e=r.length;e--&&BSe.test(r.charAt(e)););return e}c4.exports=bSe});var f4=w((Lrt,g4)=>{var QSe=u4(),SSe=/^\s+/;function vSe(r){return r&&r.slice(0,QSe(r)+1).replace(SSe,"")}g4.exports=vSe});var Wc=w((Trt,h4)=>{var kSe=Ts(),xSe=kSe.Symbol;h4.exports=xSe});var m4=w((Ort,p4)=>{var d4=Wc(),C4=Object.prototype,PSe=C4.hasOwnProperty,DSe=C4.toString,Id=d4?d4.toStringTag:void 0;function RSe(r){var e=PSe.call(r,Id),t=r[Id];try{r[Id]=void 0;var i=!0}catch(s){}var n=DSe.call(r);return i&&(e?r[Id]=t:delete r[Id]),n}p4.exports=RSe});var I4=w((Mrt,E4)=>{var FSe=Object.prototype,NSe=FSe.toString;function LSe(r){return NSe.call(r)}E4.exports=LSe});var zc=w((Urt,y4)=>{var w4=Wc(),TSe=m4(),OSe=I4(),MSe="[object Null]",USe="[object Undefined]",B4=w4?w4.toStringTag:void 0;function KSe(r){return r==null?r===void 0?USe:MSe:B4&&B4 in Object(r)?TSe(r):OSe(r)}y4.exports=KSe});var ra=w((Krt,b4)=>{function HSe(r){return r!=null&&typeof r=="object"}b4.exports=HSe});var yd=w((Hrt,Q4)=>{var jSe=zc(),GSe=ra(),YSe="[object Symbol]";function qSe(r){return typeof r=="symbol"||GSe(r)&&jSe(r)==YSe}Q4.exports=qSe});var x4=w((jrt,S4)=>{var JSe=f4(),v4=Fn(),WSe=yd(),k4=0/0,zSe=/^[-+]0x[0-9a-f]+$/i,_Se=/^0b[01]+$/i,VSe=/^0o[0-7]+$/i,XSe=parseInt;function ZSe(r){if(typeof r=="number")return r;if(WSe(r))return k4;if(v4(r)){var e=typeof r.valueOf=="function"?r.valueOf():r;r=v4(e)?e+"":e}if(typeof r!="string")return r===0?r:+r;r=JSe(r);var t=_Se.test(r);return t||VSe.test(r)?XSe(r.slice(2),t?2:8):zSe.test(r)?k4:+r}S4.exports=ZSe});var R4=w((Grt,P4)=>{var $Se=Fn(),nx=l4(),D4=x4(),eve="Expected a function",tve=Math.max,rve=Math.min;function ive(r,e,t){var i,n,s,o,a,l,c=0,u=!1,g=!1,f=!0;if(typeof r!="function")throw new TypeError(eve);e=D4(e)||0,$Se(t)&&(u=!!t.leading,g="maxWait"in t,s=g?tve(D4(t.maxWait)||0,e):s,f="trailing"in t?!!t.trailing:f);function h(q){var $=i,z=n;return i=n=void 0,c=q,o=r.apply(z,$),o}function p(q){return c=q,a=setTimeout(b,e),u?h(q):o}function m(q){var $=q-l,z=q-c,ne=e-$;return g?rve(ne,s-z):ne}function y(q){var $=q-l,z=q-c;return l===void 0||$>=e||$<0||g&&z>=s}function b(){var q=nx();if(y(q))return v(q);a=setTimeout(b,m(q))}function v(q){return a=void 0,f&&i?h(q):(i=n=void 0,o)}function k(){a!==void 0&&clearTimeout(a),c=0,i=l=n=a=void 0}function T(){return a===void 0?o:v(nx())}function Y(){var q=nx(),$=y(q);if(i=arguments,n=this,l=q,$){if(a===void 0)return p(l);if(g)return clearTimeout(a),a=setTimeout(b,e),h(l)}return a===void 0&&(a=setTimeout(b,e)),o}return Y.cancel=k,Y.flush=T,Y}P4.exports=ive});var N4=w((Yrt,F4)=>{var nve=R4(),sve=Fn(),ove="Expected a function";function ave(r,e,t){var i=!0,n=!0;if(typeof r!="function")throw new TypeError(ove);return sve(t)&&(i="leading"in t?!!t.leading:i,n="trailing"in t?!!t.trailing:n),nve(r,e,{leading:i,maxWait:e,trailing:n})}F4.exports=ave});var nA=w((iA,bw)=>{"use strict";Object.defineProperty(iA,"__esModule",{value:!0});var j4=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];function Ive(r){return j4.includes(r)}var yve=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","FormData","URLSearchParams","HTMLElement",...j4];function wve(r){return yve.includes(r)}var Bve=["null","undefined","string","number","bigint","boolean","symbol"];function bve(r){return Bve.includes(r)}function Zg(r){return e=>typeof e===r}var{toString:G4}=Object.prototype,kd=r=>{let e=G4.call(r).slice(8,-1);if(/HTML\w+Element/.test(e)&&W.domElement(r))return"HTMLElement";if(wve(e))return e},hr=r=>e=>kd(e)===r;function W(r){if(r===null)return"null";switch(typeof r){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"function":return"Function";case"bigint":return"bigint";case"symbol":return"symbol";default:}if(W.observable(r))return"Observable";if(W.array(r))return"Array";if(W.buffer(r))return"Buffer";let e=kd(r);if(e)return e;if(r instanceof String||r instanceof Boolean||r instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}W.undefined=Zg("undefined");W.string=Zg("string");var Qve=Zg("number");W.number=r=>Qve(r)&&!W.nan(r);W.bigint=Zg("bigint");W.function_=Zg("function");W.null_=r=>r===null;W.class_=r=>W.function_(r)&&r.toString().startsWith("class ");W.boolean=r=>r===!0||r===!1;W.symbol=Zg("symbol");W.numericString=r=>W.string(r)&&!W.emptyStringOrWhitespace(r)&&!Number.isNaN(Number(r));W.array=(r,e)=>Array.isArray(r)?W.function_(e)?r.every(e):!0:!1;W.buffer=r=>{var e,t,i,n;return(n=(i=(t=(e=r)===null||e===void 0?void 0:e.constructor)===null||t===void 0?void 0:t.isBuffer)===null||i===void 0?void 0:i.call(t,r))!==null&&n!==void 0?n:!1};W.nullOrUndefined=r=>W.null_(r)||W.undefined(r);W.object=r=>!W.null_(r)&&(typeof r=="object"||W.function_(r));W.iterable=r=>{var e;return W.function_((e=r)===null||e===void 0?void 0:e[Symbol.iterator])};W.asyncIterable=r=>{var e;return W.function_((e=r)===null||e===void 0?void 0:e[Symbol.asyncIterator])};W.generator=r=>W.iterable(r)&&W.function_(r.next)&&W.function_(r.throw);W.asyncGenerator=r=>W.asyncIterable(r)&&W.function_(r.next)&&W.function_(r.throw);W.nativePromise=r=>hr("Promise")(r);var Sve=r=>{var e,t;return W.function_((e=r)===null||e===void 0?void 0:e.then)&&W.function_((t=r)===null||t===void 0?void 0:t.catch)};W.promise=r=>W.nativePromise(r)||Sve(r);W.generatorFunction=hr("GeneratorFunction");W.asyncGeneratorFunction=r=>kd(r)==="AsyncGeneratorFunction";W.asyncFunction=r=>kd(r)==="AsyncFunction";W.boundFunction=r=>W.function_(r)&&!r.hasOwnProperty("prototype");W.regExp=hr("RegExp");W.date=hr("Date");W.error=hr("Error");W.map=r=>hr("Map")(r);W.set=r=>hr("Set")(r);W.weakMap=r=>hr("WeakMap")(r);W.weakSet=r=>hr("WeakSet")(r);W.int8Array=hr("Int8Array");W.uint8Array=hr("Uint8Array");W.uint8ClampedArray=hr("Uint8ClampedArray");W.int16Array=hr("Int16Array");W.uint16Array=hr("Uint16Array");W.int32Array=hr("Int32Array");W.uint32Array=hr("Uint32Array");W.float32Array=hr("Float32Array");W.float64Array=hr("Float64Array");W.bigInt64Array=hr("BigInt64Array");W.bigUint64Array=hr("BigUint64Array");W.arrayBuffer=hr("ArrayBuffer");W.sharedArrayBuffer=hr("SharedArrayBuffer");W.dataView=hr("DataView");W.directInstanceOf=(r,e)=>Object.getPrototypeOf(r)===e.prototype;W.urlInstance=r=>hr("URL")(r);W.urlString=r=>{if(!W.string(r))return!1;try{return new URL(r),!0}catch(e){return!1}};W.truthy=r=>Boolean(r);W.falsy=r=>!r;W.nan=r=>Number.isNaN(r);W.primitive=r=>W.null_(r)||bve(typeof r);W.integer=r=>Number.isInteger(r);W.safeInteger=r=>Number.isSafeInteger(r);W.plainObject=r=>{if(G4.call(r)!=="[object Object]")return!1;let e=Object.getPrototypeOf(r);return e===null||e===Object.getPrototypeOf({})};W.typedArray=r=>Ive(kd(r));var vve=r=>W.safeInteger(r)&&r>=0;W.arrayLike=r=>!W.nullOrUndefined(r)&&!W.function_(r)&&vve(r.length);W.inRange=(r,e)=>{if(W.number(e))return r>=Math.min(0,e)&&r<=Math.max(e,0);if(W.array(e)&&e.length===2)return r>=Math.min(...e)&&r<=Math.max(...e);throw new TypeError(`Invalid range: ${JSON.stringify(e)}`)};var kve=1,xve=["innerHTML","ownerDocument","style","attributes","nodeValue"];W.domElement=r=>W.object(r)&&r.nodeType===kve&&W.string(r.nodeName)&&!W.plainObject(r)&&xve.every(e=>e in r);W.observable=r=>{var e,t,i,n;return r?r===((t=(e=r)[Symbol.observable])===null||t===void 0?void 0:t.call(e))||r===((n=(i=r)["@@observable"])===null||n===void 0?void 0:n.call(i)):!1};W.nodeStream=r=>W.object(r)&&W.function_(r.pipe)&&!W.observable(r);W.infinite=r=>r===Infinity||r===-Infinity;var Y4=r=>e=>W.integer(e)&&Math.abs(e%2)===r;W.evenInteger=Y4(0);W.oddInteger=Y4(1);W.emptyArray=r=>W.array(r)&&r.length===0;W.nonEmptyArray=r=>W.array(r)&&r.length>0;W.emptyString=r=>W.string(r)&&r.length===0;W.nonEmptyString=r=>W.string(r)&&r.length>0;var Pve=r=>W.string(r)&&!/\S/.test(r);W.emptyStringOrWhitespace=r=>W.emptyString(r)||Pve(r);W.emptyObject=r=>W.object(r)&&!W.map(r)&&!W.set(r)&&Object.keys(r).length===0;W.nonEmptyObject=r=>W.object(r)&&!W.map(r)&&!W.set(r)&&Object.keys(r).length>0;W.emptySet=r=>W.set(r)&&r.size===0;W.nonEmptySet=r=>W.set(r)&&r.size>0;W.emptyMap=r=>W.map(r)&&r.size===0;W.nonEmptyMap=r=>W.map(r)&&r.size>0;W.propertyKey=r=>W.any([W.string,W.number,W.symbol],r);W.formData=r=>hr("FormData")(r);W.urlSearchParams=r=>hr("URLSearchParams")(r);var q4=(r,e,t)=>{if(!W.function_(e))throw new TypeError(`Invalid predicate: ${JSON.stringify(e)}`);if(t.length===0)throw new TypeError("Invalid number of values");return r.call(t,e)};W.any=(r,...e)=>(W.array(r)?r:[r]).some(i=>q4(Array.prototype.some,i,e));W.all=(r,...e)=>q4(Array.prototype.every,r,e);var We=(r,e,t,i={})=>{if(!r){let{multipleValues:n}=i,s=n?`received values of types ${[...new Set(t.map(o=>`\`${W(o)}\``))].join(", ")}`:`received value of type \`${W(t)}\``;throw new TypeError(`Expected value which is \`${e}\`, ${s}.`)}};iA.assert={undefined:r=>We(W.undefined(r),"undefined",r),string:r=>We(W.string(r),"string",r),number:r=>We(W.number(r),"number",r),bigint:r=>We(W.bigint(r),"bigint",r),function_:r=>We(W.function_(r),"Function",r),null_:r=>We(W.null_(r),"null",r),class_:r=>We(W.class_(r),"Class",r),boolean:r=>We(W.boolean(r),"boolean",r),symbol:r=>We(W.symbol(r),"symbol",r),numericString:r=>We(W.numericString(r),"string with a number",r),array:(r,e)=>{We(W.array(r),"Array",r),e&&r.forEach(e)},buffer:r=>We(W.buffer(r),"Buffer",r),nullOrUndefined:r=>We(W.nullOrUndefined(r),"null or undefined",r),object:r=>We(W.object(r),"Object",r),iterable:r=>We(W.iterable(r),"Iterable",r),asyncIterable:r=>We(W.asyncIterable(r),"AsyncIterable",r),generator:r=>We(W.generator(r),"Generator",r),asyncGenerator:r=>We(W.asyncGenerator(r),"AsyncGenerator",r),nativePromise:r=>We(W.nativePromise(r),"native Promise",r),promise:r=>We(W.promise(r),"Promise",r),generatorFunction:r=>We(W.generatorFunction(r),"GeneratorFunction",r),asyncGeneratorFunction:r=>We(W.asyncGeneratorFunction(r),"AsyncGeneratorFunction",r),asyncFunction:r=>We(W.asyncFunction(r),"AsyncFunction",r),boundFunction:r=>We(W.boundFunction(r),"Function",r),regExp:r=>We(W.regExp(r),"RegExp",r),date:r=>We(W.date(r),"Date",r),error:r=>We(W.error(r),"Error",r),map:r=>We(W.map(r),"Map",r),set:r=>We(W.set(r),"Set",r),weakMap:r=>We(W.weakMap(r),"WeakMap",r),weakSet:r=>We(W.weakSet(r),"WeakSet",r),int8Array:r=>We(W.int8Array(r),"Int8Array",r),uint8Array:r=>We(W.uint8Array(r),"Uint8Array",r),uint8ClampedArray:r=>We(W.uint8ClampedArray(r),"Uint8ClampedArray",r),int16Array:r=>We(W.int16Array(r),"Int16Array",r),uint16Array:r=>We(W.uint16Array(r),"Uint16Array",r),int32Array:r=>We(W.int32Array(r),"Int32Array",r),uint32Array:r=>We(W.uint32Array(r),"Uint32Array",r),float32Array:r=>We(W.float32Array(r),"Float32Array",r),float64Array:r=>We(W.float64Array(r),"Float64Array",r),bigInt64Array:r=>We(W.bigInt64Array(r),"BigInt64Array",r),bigUint64Array:r=>We(W.bigUint64Array(r),"BigUint64Array",r),arrayBuffer:r=>We(W.arrayBuffer(r),"ArrayBuffer",r),sharedArrayBuffer:r=>We(W.sharedArrayBuffer(r),"SharedArrayBuffer",r),dataView:r=>We(W.dataView(r),"DataView",r),urlInstance:r=>We(W.urlInstance(r),"URL",r),urlString:r=>We(W.urlString(r),"string with a URL",r),truthy:r=>We(W.truthy(r),"truthy",r),falsy:r=>We(W.falsy(r),"falsy",r),nan:r=>We(W.nan(r),"NaN",r),primitive:r=>We(W.primitive(r),"primitive",r),integer:r=>We(W.integer(r),"integer",r),safeInteger:r=>We(W.safeInteger(r),"integer",r),plainObject:r=>We(W.plainObject(r),"plain object",r),typedArray:r=>We(W.typedArray(r),"TypedArray",r),arrayLike:r=>We(W.arrayLike(r),"array-like",r),domElement:r=>We(W.domElement(r),"HTMLElement",r),observable:r=>We(W.observable(r),"Observable",r),nodeStream:r=>We(W.nodeStream(r),"Node.js Stream",r),infinite:r=>We(W.infinite(r),"infinite number",r),emptyArray:r=>We(W.emptyArray(r),"empty array",r),nonEmptyArray:r=>We(W.nonEmptyArray(r),"non-empty array",r),emptyString:r=>We(W.emptyString(r),"empty string",r),nonEmptyString:r=>We(W.nonEmptyString(r),"non-empty string",r),emptyStringOrWhitespace:r=>We(W.emptyStringOrWhitespace(r),"empty string or whitespace",r),emptyObject:r=>We(W.emptyObject(r),"empty object",r),nonEmptyObject:r=>We(W.nonEmptyObject(r),"non-empty object",r),emptySet:r=>We(W.emptySet(r),"empty set",r),nonEmptySet:r=>We(W.nonEmptySet(r),"non-empty set",r),emptyMap:r=>We(W.emptyMap(r),"empty map",r),nonEmptyMap:r=>We(W.nonEmptyMap(r),"non-empty map",r),propertyKey:r=>We(W.propertyKey(r),"PropertyKey",r),formData:r=>We(W.formData(r),"FormData",r),urlSearchParams:r=>We(W.urlSearchParams(r),"URLSearchParams",r),evenInteger:r=>We(W.evenInteger(r),"even integer",r),oddInteger:r=>We(W.oddInteger(r),"odd integer",r),directInstanceOf:(r,e)=>We(W.directInstanceOf(r,e),"T",r),inRange:(r,e)=>We(W.inRange(r,e),"in range",r),any:(r,...e)=>We(W.any(r,...e),"predicate returns truthy for any value",e,{multipleValues:!0}),all:(r,...e)=>We(W.all(r,...e),"predicate returns truthy for all values",e,{multipleValues:!0})};Object.defineProperties(W,{class:{value:W.class_},function:{value:W.function_},null:{value:W.null_}});Object.defineProperties(iA.assert,{class:{value:iA.assert.class_},function:{value:iA.assert.function_},null:{value:iA.assert.null_}});iA.default=W;bw.exports=W;bw.exports.default=W;bw.exports.assert=iA.assert});var J4=w((_it,bx)=>{"use strict";var Qx=class extends Error{constructor(e){super(e||"Promise was canceled");this.name="CancelError"}get isCanceled(){return!0}},xd=class{static fn(e){return(...t)=>new xd((i,n,s)=>{t.push(s),e(...t).then(i,n)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((t,i)=>{this._reject=i;let n=a=>{this._isPending=!1,t(a)},s=a=>{this._isPending=!1,i(a)},o=a=>{if(!this._isPending)throw new Error("The `onCancel` handler was attached after the promise settled.");this._cancelHandlers.push(a)};return Object.defineProperties(o,{shouldReject:{get:()=>this._rejectOnCancel,set:a=>{this._rejectOnCancel=a}}}),e(n,s,o)})}then(e,t){return this._promise.then(e,t)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}cancel(e){if(!(!this._isPending||this._isCanceled)){if(this._cancelHandlers.length>0)try{for(let t of this._cancelHandlers)t()}catch(t){this._reject(t)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new Qx(e))}}get isCanceled(){return this._isCanceled}};Object.setPrototypeOf(xd.prototype,Promise.prototype);bx.exports=xd;bx.exports.CancelError=Qx});var W4=w((Sx,vx)=>{"use strict";Object.defineProperty(Sx,"__esModule",{value:!0});var Dve=require("tls"),kx=(r,e)=>{let t;typeof e=="function"?t={connect:e}:t=e;let i=typeof t.connect=="function",n=typeof t.secureConnect=="function",s=typeof t.close=="function",o=()=>{i&&t.connect(),r instanceof Dve.TLSSocket&&n&&(r.authorized?t.secureConnect():r.authorizationError||r.once("secureConnect",t.secureConnect)),s&&r.once("close",t.close)};r.writable&&!r.connecting?o():r.connecting?r.once("connect",o):r.destroyed&&s&&t.close(r._hadError)};Sx.default=kx;vx.exports=kx;vx.exports.default=kx});var z4=w((xx,Px)=>{"use strict";Object.defineProperty(xx,"__esModule",{value:!0});var Rve=W4(),Fve=Number(process.versions.node.split(".")[0]),Dx=r=>{let e={start:Date.now(),socket:void 0,lookup:void 0,connect:void 0,secureConnect:void 0,upload:void 0,response:void 0,end:void 0,error:void 0,abort:void 0,phases:{wait:void 0,dns:void 0,tcp:void 0,tls:void 0,request:void 0,firstByte:void 0,download:void 0,total:void 0}};r.timings=e;let t=o=>{let a=o.emit.bind(o);o.emit=(l,...c)=>(l==="error"&&(e.error=Date.now(),e.phases.total=e.error-e.start,o.emit=a),a(l,...c))};t(r),r.prependOnceListener("abort",()=>{e.abort=Date.now(),(!e.response||Fve>=13)&&(e.phases.total=Date.now()-e.start)});let i=o=>{e.socket=Date.now(),e.phases.wait=e.socket-e.start;let a=()=>{e.lookup=Date.now(),e.phases.dns=e.lookup-e.socket};o.prependOnceListener("lookup",a),Rve.default(o,{connect:()=>{e.connect=Date.now(),e.lookup===void 0&&(o.removeListener("lookup",a),e.lookup=e.connect,e.phases.dns=e.lookup-e.socket),e.phases.tcp=e.connect-e.lookup},secureConnect:()=>{e.secureConnect=Date.now(),e.phases.tls=e.secureConnect-e.connect}})};r.socket?i(r.socket):r.prependOnceListener("socket",i);let n=()=>{var o;e.upload=Date.now(),e.phases.request=e.upload-(o=e.secureConnect,o!=null?o:e.connect)};return(()=>typeof r.writableFinished=="boolean"?r.writableFinished:r.finished&&r.outputSize===0&&(!r.socket||r.socket.writableLength===0))()?n():r.prependOnceListener("finish",n),r.prependOnceListener("response",o=>{e.response=Date.now(),e.phases.firstByte=e.response-e.upload,o.timings=e,t(o),o.prependOnceListener("end",()=>{e.end=Date.now(),e.phases.download=e.end-e.response,e.phases.total=e.end-e.start})}),e};xx.default=Dx;Px.exports=Dx;Px.exports.default=Dx});var tz=w((Vit,Rx)=>{"use strict";var{V4MAPPED:Nve,ADDRCONFIG:Lve,ALL:_4,promises:{Resolver:V4},lookup:Tve}=require("dns"),{promisify:Fx}=require("util"),Ove=require("os"),$g=Symbol("cacheableLookupCreateConnection"),Nx=Symbol("cacheableLookupInstance"),X4=Symbol("expires"),Mve=typeof _4=="number",Z4=r=>{if(!(r&&typeof r.createConnection=="function"))throw new Error("Expected an Agent instance as the first argument")},Uve=r=>{for(let e of r)e.family!==6&&(e.address=`::ffff:${e.address}`,e.family=6)},$4=()=>{let r=!1,e=!1;for(let t of Object.values(Ove.networkInterfaces()))for(let i of t)if(!i.internal&&(i.family==="IPv6"?e=!0:r=!0,r&&e))return{has4:r,has6:e};return{has4:r,has6:e}},Kve=r=>Symbol.iterator in r,ez={ttl:!0},Hve={all:!0},Lx=class{constructor({cache:e=new Map,maxTtl:t=Infinity,fallbackDuration:i=3600,errorTtl:n=.15,resolver:s=new V4,lookup:o=Tve}={}){if(this.maxTtl=t,this.errorTtl=n,this._cache=e,this._resolver=s,this._dnsLookup=Fx(o),this._resolver instanceof V4?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=Fx(this._resolver.resolve4.bind(this._resolver)),this._resolve6=Fx(this._resolver.resolve6.bind(this._resolver))),this._iface=$4(),this._pending={},this._nextRemovalTime=!1,this._hostnamesToFallback=new Set,i<1)this._fallback=!1;else{this._fallback=!0;let a=setInterval(()=>{this._hostnamesToFallback.clear()},i*1e3);a.unref&&a.unref()}this.lookup=this.lookup.bind(this),this.lookupAsync=this.lookupAsync.bind(this)}set servers(e){this.clear(),this._resolver.setServers(e)}get servers(){return this._resolver.getServers()}lookup(e,t,i){if(typeof t=="function"?(i=t,t={}):typeof t=="number"&&(t={family:t}),!i)throw new Error("Callback must be a function.");this.lookupAsync(e,t).then(n=>{t.all?i(null,n):i(null,n.address,n.family,n.expires,n.ttl)},i)}async lookupAsync(e,t={}){typeof t=="number"&&(t={family:t});let i=await this.query(e);if(t.family===6){let n=i.filter(s=>s.family===6);t.hints&Nve&&(Mve&&t.hints&_4||n.length===0)?Uve(i):i=n}else t.family===4&&(i=i.filter(n=>n.family===4));if(t.hints&Lve){let{_iface:n}=this;i=i.filter(s=>s.family===6?n.has6:n.has4)}if(i.length===0){let n=new Error(`cacheableLookup ENOTFOUND ${e}`);throw n.code="ENOTFOUND",n.hostname=e,n}return t.all?i:i[0]}async query(e){let t=await this._cache.get(e);if(!t){let i=this._pending[e];if(i)t=await i;else{let n=this.queryAndCache(e);this._pending[e]=n,t=await n}}return t=t.map(i=>N({},i)),t}async _resolve(e){let t=async c=>{try{return await c}catch(u){if(u.code==="ENODATA"||u.code==="ENOTFOUND")return[];throw u}},[i,n]=await Promise.all([this._resolve4(e,ez),this._resolve6(e,ez)].map(c=>t(c))),s=0,o=0,a=0,l=Date.now();for(let c of i)c.family=4,c.expires=l+c.ttl*1e3,s=Math.max(s,c.ttl);for(let c of n)c.family=6,c.expires=l+c.ttl*1e3,o=Math.max(o,c.ttl);return i.length>0?n.length>0?a=Math.min(s,o):a=s:a=o,{entries:[...i,...n],cacheTtl:a}}async _lookup(e){try{return{entries:await this._dnsLookup(e,{all:!0}),cacheTtl:0}}catch(t){return{entries:[],cacheTtl:0}}}async _set(e,t,i){if(this.maxTtl>0&&i>0){i=Math.min(i,this.maxTtl)*1e3,t[X4]=Date.now()+i;try{await this._cache.set(e,t,i)}catch(n){this.lookupAsync=async()=>{let s=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw s.cause=n,s}}Kve(this._cache)&&this._tick(i)}}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,Hve);try{let t=await this._resolve(e);t.entries.length===0&&this._fallback&&(t=await this._lookup(e),t.entries.length!==0&&this._hostnamesToFallback.add(e));let i=t.entries.length===0?this.errorTtl:t.cacheTtl;return await this._set(e,t.entries,i),delete this._pending[e],t.entries}catch(t){throw delete this._pending[e],t}}_tick(e){let t=this._nextRemovalTime;(!t||e<t)&&(clearTimeout(this._removalTimeout),this._nextRemovalTime=e,this._removalTimeout=setTimeout(()=>{this._nextRemovalTime=!1;let i=Infinity,n=Date.now();for(let[s,o]of this._cache){let a=o[X4];n>=a?this._cache.delete(s):a<i&&(i=a)}i!==Infinity&&this._tick(i-n)},e),this._removalTimeout.unref&&this._removalTimeout.unref())}install(e){if(Z4(e),$g in e)throw new Error("CacheableLookup has been already installed");e[$g]=e.createConnection,e[Nx]=this,e.createConnection=(t,i)=>("lookup"in t||(t.lookup=this.lookup),e[$g](t,i))}uninstall(e){if(Z4(e),e[$g]){if(e[Nx]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[$g],delete e[$g],delete e[Nx]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=$4(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){if(e){this._cache.delete(e);return}this._cache.clear()}};Rx.exports=Lx;Rx.exports.default=Lx});var nz=w((Xit,Tx)=>{"use strict";var jve=typeof URL=="undefined"?require("url").URL:URL,Gve="text/plain",Yve="us-ascii",rz=(r,e)=>e.some(t=>t instanceof RegExp?t.test(r):t===r),qve=(r,{stripHash:e})=>{let t=r.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!t)throw new Error(`Invalid URL: ${r}`);let i=t[1].split(";"),n=t[2],s=e?"":t[3],o=!1;i[i.length-1]==="base64"&&(i.pop(),o=!0);let a=(i.shift()||"").toLowerCase(),c=[...i.map(u=>{let[g,f=""]=u.split("=").map(h=>h.trim());return g==="charset"&&(f=f.toLowerCase(),f===Yve)?"":`${g}${f?`=${f}`:""}`}).filter(Boolean)];return o&&c.push("base64"),(c.length!==0||a&&a!==Gve)&&c.unshift(a),`data:${c.join(";")},${o?n.trim():n}${s?`#${s}`:""}`},iz=(r,e)=>{if(e=N({defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0},e),Reflect.has(e,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(e,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(e,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(r=r.trim(),/^data:/i.test(r))return qve(r,e);let t=r.startsWith("//");!t&&/^\.*\//.test(r)||(r=r.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new jve(r);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&n.protocol==="https:"&&(n.protocol="http:"),e.forceHttps&&n.protocol==="http:"&&(n.protocol="https:"),e.stripAuthentication&&(n.username="",n.password=""),e.stripHash&&(n.hash=""),n.pathname&&(n.pathname=n.pathname.replace(/((?!:).|^)\/{2,}/g,(s,o)=>/^(?!\/)/g.test(o)?`${o}/`:"/")),n.pathname&&(n.pathname=decodeURI(n.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let s=n.pathname.split("/"),o=s[s.length-1];rz(o,e.removeDirectoryIndex)&&(s=s.slice(0,s.length-1),n.pathname=s.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let s of[...n.searchParams.keys()])rz(s,e.removeQueryParameters)&&n.searchParams.delete(s);return e.sortQueryParameters&&n.searchParams.sort(),e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,"")),r=n.toString(),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&(r=r.replace(/\/$/,"")),t&&!e.normalizeProtocol&&(r=r.replace(/^http:\/\//,"//")),e.stripProtocol&&(r=r.replace(/^(?:https?:)?\/\//,"")),r};Tx.exports=iz;Tx.exports.default=iz});var az=w((Zit,sz)=>{sz.exports=oz;function oz(r,e){if(r&&e)return oz(r)(e);if(typeof r!="function")throw new TypeError("need wrapper function");return Object.keys(r).forEach(function(i){t[i]=r[i]}),t;function t(){for(var i=new Array(arguments.length),n=0;n<i.length;n++)i[n]=arguments[n];var s=r.apply(this,i),o=i[i.length-1];return typeof s=="function"&&s!==o&&Object.keys(o).forEach(function(a){s[a]=o[a]}),s}}});var Mx=w(($it,Ox)=>{var Az=az();Ox.exports=Az(Qw);Ox.exports.strict=Az(lz);Qw.proto=Qw(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return Qw(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return lz(this)},configurable:!0})});function Qw(r){var e=function(){return e.called?e.value:(e.called=!0,e.value=r.apply(this,arguments))};return e.called=!1,e}function lz(r){var e=function(){if(e.called)throw new Error(e.onceError);return e.called=!0,e.value=r.apply(this,arguments)},t=r.name||"Function wrapped with `once`";return e.onceError=t+" shouldn't be called more than once",e.called=!1,e}});var Ux=w((ent,cz)=>{var Jve=Mx(),Wve=function(){},zve=function(r){return r.setHeader&&typeof r.abort=="function"},_ve=function(r){return r.stdio&&Array.isArray(r.stdio)&&r.stdio.length===3},uz=function(r,e,t){if(typeof e=="function")return uz(r,null,e);e||(e={}),t=Jve(t||Wve);var i=r._writableState,n=r._readableState,s=e.readable||e.readable!==!1&&r.readable,o=e.writable||e.writable!==!1&&r.writable,a=function(){r.writable||l()},l=function(){o=!1,s||t.call(r)},c=function(){s=!1,o||t.call(r)},u=function(p){t.call(r,p?new Error("exited with error code: "+p):null)},g=function(p){t.call(r,p)},f=function(){if(s&&!(n&&n.ended))return t.call(r,new Error("premature close"));if(o&&!(i&&i.ended))return t.call(r,new Error("premature close"))},h=function(){r.req.on("finish",l)};return zve(r)?(r.on("complete",l),r.on("abort",f),r.req?h():r.on("request",h)):o&&!i&&(r.on("end",a),r.on("close",a)),_ve(r)&&r.on("exit",u),r.on("end",c),r.on("finish",l),e.error!==!1&&r.on("error",g),r.on("close",f),function(){r.removeListener("complete",l),r.removeListener("abort",f),r.removeListener("request",h),r.req&&r.req.removeListener("finish",l),r.removeListener("end",a),r.removeListener("close",a),r.removeListener("finish",l),r.removeListener("exit",u),r.removeListener("end",c),r.removeListener("error",g),r.removeListener("close",f)}};cz.exports=uz});var hz=w((tnt,gz)=>{var Vve=Mx(),Xve=Ux(),Kx=require("fs"),Pd=function(){},Zve=/^v?\.0/.test(process.version),Sw=function(r){return typeof r=="function"},$ve=function(r){return!Zve||!Kx?!1:(r instanceof(Kx.ReadStream||Pd)||r instanceof(Kx.WriteStream||Pd))&&Sw(r.close)},eke=function(r){return r.setHeader&&Sw(r.abort)},tke=function(r,e,t,i){i=Vve(i);var n=!1;r.on("close",function(){n=!0}),Xve(r,{readable:e,writable:t},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,$ve(r))return r.close(Pd);if(eke(r))return r.abort();if(Sw(r.destroy))return r.destroy();i(o||new Error("stream was destroyed"))}}},fz=function(r){r()},rke=function(r,e){return r.pipe(e)},ike=function(){var r=Array.prototype.slice.call(arguments),e=Sw(r[r.length-1]||Pd)&&r.pop()||Pd;if(Array.isArray(r[0])&&(r=r[0]),r.length<2)throw new Error("pump requires two streams per minimum");var t,i=r.map(function(n,s){var o=s<r.length-1,a=s>0;return tke(n,o,a,function(l){t||(t=l),l&&i.forEach(fz),!o&&(i.forEach(fz),e(t))})});return r.reduce(rke)};gz.exports=ike});var dz=w((rnt,pz)=>{"use strict";var{PassThrough:nke}=require("stream");pz.exports=r=>{r=N({},r);let{array:e}=r,{encoding:t}=r,i=t==="buffer",n=!1;e?n=!(t||i):t=t||"utf8",i&&(t=null);let s=new nke({objectMode:n});t&&s.setEncoding(t);let o=0,a=[];return s.on("data",l=>{a.push(l),n?o=a.length:o+=l.length}),s.getBufferedValue=()=>e?a:i?Buffer.concat(a,o):a.join(""),s.getBufferedLength=()=>o,s}});var Cz=w((int,ef)=>{"use strict";var ske=hz(),oke=dz(),Hx=class extends Error{constructor(){super("maxBuffer exceeded");this.name="MaxBufferError"}};async function vw(r,e){if(!r)return Promise.reject(new Error("Expected a stream"));e=N({maxBuffer:Infinity},e);let{maxBuffer:t}=e,i;return await new Promise((n,s)=>{let o=a=>{a&&(a.bufferedData=i.getBufferedValue()),s(a)};i=ske(r,oke(e),a=>{if(a){o(a);return}n()}),i.on("data",()=>{i.getBufferedLength()>t&&o(new Hx)})}),i.getBufferedValue()}ef.exports=vw;ef.exports.default=vw;ef.exports.buffer=(r,e)=>vw(r,te(N({},e),{encoding:"buffer"}));ef.exports.array=(r,e)=>vw(r,te(N({},e),{array:!0}));ef.exports.MaxBufferError=Hx});var Ez=w((snt,mz)=>{"use strict";var ake=[200,203,204,206,300,301,404,405,410,414,501],Ake=[200,203,204,300,301,302,303,307,308,404,405,410,414,501],lke={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},cke={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function jx(r){let e={};if(!r)return e;let t=r.trim().split(/\s*,\s*/);for(let i of t){let[n,s]=i.split(/\s*=\s*/,2);e[n]=s===void 0?!0:s.replace(/^"|"$/g,"")}return e}function uke(r){let e=[];for(let t in r){let i=r[t];e.push(i===!0?t:t+"="+i)}if(!!e.length)return e.join(", ")}mz.exports=class{constructor(e,t,{shared:i,cacheHeuristic:n,immutableMinTimeToLive:s,ignoreCargoCult:o,trustServerDate:a,_fromObject:l}={}){if(l){this._fromObject(l);return}if(!t||!t.headers)throw Error("Response headers missing");this._assertRequestHasHeaders(e),this._responseTime=this.now(),this._isShared=i!==!1,this._trustServerDate=a!==void 0?a:!0,this._cacheHeuristic=n!==void 0?n:.1,this._immutableMinTtl=s!==void 0?s:24*3600*1e3,this._status="status"in t?t.status:200,this._resHeaders=t.headers,this._rescc=jx(t.headers["cache-control"]),this._method="method"in e?e.method:"GET",this._url=e.url,this._host=e.headers.host,this._noAuthorization=!e.headers.authorization,this._reqHeaders=t.headers.vary?e.headers:null,this._reqcc=jx(e.headers["cache-control"]),o&&"pre-check"in this._rescc&&"post-check"in this._rescc&&(delete this._rescc["pre-check"],delete this._rescc["post-check"],delete this._rescc["no-cache"],delete this._rescc["no-store"],delete this._rescc["must-revalidate"],this._resHeaders=Object.assign({},this._resHeaders,{"cache-control":uke(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),!t.headers["cache-control"]&&/no-cache/.test(t.headers.pragma)&&(this._rescc["no-cache"]=!0)}now(){return Date.now()}storable(){return!!(!this._reqcc["no-store"]&&(this._method==="GET"||this._method==="HEAD"||this._method==="POST"&&this._hasExplicitExpiration())&&Ake.indexOf(this._status)!==-1&&!this._rescc["no-store"]&&(!this._isShared||!this._rescc.private)&&(!this._isShared||this._noAuthorization||this._allowsStoringAuthenticated())&&(this._resHeaders.expires||this._rescc.public||this._rescc["max-age"]||this._rescc["s-maxage"]||ake.indexOf(this._status)!==-1))}_hasExplicitExpiration(){return this._isShared&&this._rescc["s-maxage"]||this._rescc["max-age"]||this._resHeaders.expires}_assertRequestHasHeaders(e){if(!e||!e.headers)throw Error("Request headers missing")}satisfiesWithoutRevalidation(e){this._assertRequestHasHeaders(e);let t=jx(e.headers["cache-control"]);return t["no-cache"]||/no-cache/.test(e.headers.pragma)||t["max-age"]&&this.age()>t["max-age"]||t["min-fresh"]&&this.timeToLive()<1e3*t["min-fresh"]||this.stale()&&!(t["max-stale"]&&!this._rescc["must-revalidate"]&&(t["max-stale"]===!0||t["max-stale"]>this.age()-this.maxAge()))?!1:this._requestMatches(e,!1)}_requestMatches(e,t){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||t&&e.method==="HEAD")&&this._varyMatches(e)}_allowsStoringAuthenticated(){return this._rescc["must-revalidate"]||this._rescc.public||this._rescc["s-maxage"]}_varyMatches(e){if(!this._resHeaders.vary)return!0;if(this._resHeaders.vary==="*")return!1;let t=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(let i of t)if(e.headers[i]!==this._reqHeaders[i])return!1;return!0}_copyWithoutHopByHopHeaders(e){let t={};for(let i in e)lke[i]||(t[i]=e[i]);if(e.connection){let i=e.connection.trim().split(/\s*,\s*/);for(let n of i)delete t[n]}if(t.warning){let i=t.warning.split(/,/).filter(n=>!/^\s*1[0-9][0-9]/.test(n));i.length?t.warning=i.join(",").trim():delete t.warning}return t}responseHeaders(){let e=this._copyWithoutHopByHopHeaders(this._resHeaders),t=this.age();return t>3600*24&&!this._hasExplicitExpiration()&&this.maxAge()>3600*24&&(e.warning=(e.warning?`${e.warning}, `:"")+'113 - "rfc7234 5.5.4"'),e.age=`${Math.round(t)}`,e.date=new Date(this.now()).toUTCString(),e}date(){return this._trustServerDate?this._serverDate():this._responseTime}_serverDate(){let e=Date.parse(this._resHeaders.date);if(isFinite(e)){let t=8*3600*1e3;if(Math.abs(this._responseTime-e)<t)return e}return this._responseTime}age(){let e=Math.max(0,(this._responseTime-this.date())/1e3);if(this._resHeaders.age){let i=this._ageValue();i>e&&(e=i)}let t=(this.now()-this._responseTime)/1e3;return e+t}_ageValue(){let e=parseInt(this._resHeaders.age);return isFinite(e)?e:0}maxAge(){if(!this.storable()||this._rescc["no-cache"]||this._isShared&&this._resHeaders["set-cookie"]&&!this._rescc.public&&!this._rescc.immutable||this._resHeaders.vary==="*")return 0;if(this._isShared){if(this._rescc["proxy-revalidate"])return 0;if(this._rescc["s-maxage"])return parseInt(this._rescc["s-maxage"],10)}if(this._rescc["max-age"])return parseInt(this._rescc["max-age"],10);let e=this._rescc.immutable?this._immutableMinTtl:0,t=this._serverDate();if(this._resHeaders.expires){let i=Date.parse(this._resHeaders.expires);return Number.isNaN(i)||i<t?0:Math.max(e,(i-t)/1e3)}if(this._resHeaders["last-modified"]){let i=Date.parse(this._resHeaders["last-modified"]);if(isFinite(i)&&t>i)return Math.max(e,(t-i)/1e3*this._cacheHeuristic)}return e}timeToLive(){return Math.max(0,this.maxAge()-this.age())*1e3}stale(){return this.maxAge()<=this.age()}static fromObject(e){return new this(void 0,void 0,{_fromObject:e})}_fromObject(e){if(this._responseTime)throw Error("Reinitialized");if(!e||e.v!==1)throw Error("Invalid serialization");this._responseTime=e.t,this._isShared=e.sh,this._cacheHeuristic=e.ch,this._immutableMinTtl=e.imm!==void 0?e.imm:24*3600*1e3,this._status=e.st,this._resHeaders=e.resh,this._rescc=e.rescc,this._method=e.m,this._url=e.u,this._host=e.h,this._noAuthorization=e.a,this._reqHeaders=e.reqh,this._reqcc=e.reqcc}toObject(){return{v:1,t:this._responseTime,sh:this._isShared,ch:this._cacheHeuristic,imm:this._immutableMinTtl,st:this._status,resh:this._resHeaders,rescc:this._rescc,m:this._method,u:this._url,h:this._host,a:this._noAuthorization,reqh:this._reqHeaders,reqcc:this._reqcc}}revalidationHeaders(e){this._assertRequestHasHeaders(e);let t=this._copyWithoutHopByHopHeaders(e.headers);if(delete t["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete t["if-none-match"],delete t["if-modified-since"],t;if(this._resHeaders.etag&&(t["if-none-match"]=t["if-none-match"]?`${t["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag),t["accept-ranges"]||t["if-match"]||t["if-unmodified-since"]||this._method&&this._method!="GET"){if(delete t["if-modified-since"],t["if-none-match"]){let n=t["if-none-match"].split(/,/).filter(s=>!/^\s*W\//.test(s));n.length?t["if-none-match"]=n.join(",").trim():delete t["if-none-match"]}}else this._resHeaders["last-modified"]&&!t["if-modified-since"]&&(t["if-modified-since"]=this._resHeaders["last-modified"]);return t}revalidatedPolicy(e,t){if(this._assertRequestHasHeaders(e),!t||!t.headers)throw Error("Response headers missing");let i=!1;if(t.status!==void 0&&t.status!=304?i=!1:t.headers.etag&&!/^\s*W\//.test(t.headers.etag)?i=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag:this._resHeaders.etag&&t.headers.etag?i=this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?i=this._resHeaders["last-modified"]===t.headers["last-modified"]:!this._resHeaders.etag&&!this._resHeaders["last-modified"]&&!t.headers.etag&&!t.headers["last-modified"]&&(i=!0),!i)return{policy:new this.constructor(e,t),modified:t.status!=304,matches:!1};let n={};for(let o in this._resHeaders)n[o]=o in t.headers&&!cke[o]?t.headers[o]:this._resHeaders[o];let s=Object.assign({},t,{status:this._status,method:this._method,headers:n});return{policy:new this.constructor(e,s,{shared:this._isShared,cacheHeuristic:this._cacheHeuristic,immutableMinTimeToLive:this._immutableMinTtl,trustServerDate:this._trustServerDate}),modified:!1,matches:!0}}}});var kw=w((ont,Iz)=>{"use strict";Iz.exports=r=>{let e={};for(let[t,i]of Object.entries(r))e[t.toLowerCase()]=i;return e}});var Bz=w((ant,yz)=>{"use strict";var gke=require("stream").Readable,fke=kw(),wz=class extends gke{constructor(e,t,i,n){if(typeof e!="number")throw new TypeError("Argument `statusCode` should be a number");if(typeof t!="object")throw new TypeError("Argument `headers` should be an object");if(!(i instanceof Buffer))throw new TypeError("Argument `body` should be a buffer");if(typeof n!="string")throw new TypeError("Argument `url` should be a string");super();this.statusCode=e,this.headers=fke(t),this.body=i,this.url=n}_read(){this.push(this.body),this.push(null)}};yz.exports=wz});var Qz=w((Ant,bz)=>{"use strict";var hke=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];bz.exports=(r,e)=>{let t=new Set(Object.keys(r).concat(hke));for(let i of t)i in e||(e[i]=typeof r[i]=="function"?r[i].bind(r):r[i])}});var vz=w((lnt,Sz)=>{"use strict";var pke=require("stream").PassThrough,dke=Qz(),Cke=r=>{if(!(r&&r.pipe))throw new TypeError("Parameter `response` must be a response stream.");let e=new pke;return dke(r,e),r.pipe(e)};Sz.exports=Cke});var kz=w(Gx=>{Gx.stringify=function r(e){if(typeof e=="undefined")return e;if(e&&Buffer.isBuffer(e))return JSON.stringify(":base64:"+e.toString("base64"));if(e&&e.toJSON&&(e=e.toJSON()),e&&typeof e=="object"){var t="",i=Array.isArray(e);t=i?"[":"{";var n=!0;for(var s in e){var o=typeof e[s]=="function"||!i&&typeof e[s]=="undefined";Object.hasOwnProperty.call(e,s)&&!o&&(n||(t+=","),n=!1,i?e[s]==null?t+="null":t+=r(e[s]):e[s]!==void 0&&(t+=r(s)+":"+r(e[s])))}return t+=i?"]":"}",t}else return typeof e=="string"?JSON.stringify(/^:/.test(e)?":"+e:e):typeof e=="undefined"?"null":JSON.stringify(e)};Gx.parse=function(r){return JSON.parse(r,function(e,t){return typeof t=="string"?/^:base64:/.test(t)?Buffer.from(t.substring(8),"base64"):/^:/.test(t)?t.substring(1):t:t})}});var Rz=w((unt,xz)=>{"use strict";var mke=require("events"),Pz=kz(),Eke=r=>{let e={redis:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql"};if(r.adapter||r.uri){let t=r.adapter||/^[^:]*/.exec(r.uri)[0];return new(require(e[t]))(r)}return new Map},Dz=class extends mke{constructor(e,t){super();if(this.opts=Object.assign({namespace:"keyv",serialize:Pz.stringify,deserialize:Pz.parse},typeof e=="string"?{uri:e}:e,t),!this.opts.store){let i=Object.assign({},this.opts);this.opts.store=Eke(i)}typeof this.opts.store.on=="function"&&this.opts.store.on("error",i=>this.emit("error",i)),this.opts.store.namespace=this.opts.namespace}_getKeyPrefix(e){return`${this.opts.namespace}:${e}`}get(e,t){e=this._getKeyPrefix(e);let{store:i}=this.opts;return Promise.resolve().then(()=>i.get(e)).then(n=>typeof n=="string"?this.opts.deserialize(n):n).then(n=>{if(n!==void 0){if(typeof n.expires=="number"&&Date.now()>n.expires){this.delete(e);return}return t&&t.raw?n:n.value}})}set(e,t,i){e=this._getKeyPrefix(e),typeof i=="undefined"&&(i=this.opts.ttl),i===0&&(i=void 0);let{store:n}=this.opts;return Promise.resolve().then(()=>{let s=typeof i=="number"?Date.now()+i:null;return t={value:t,expires:s},this.opts.serialize(t)}).then(s=>n.set(e,s,i)).then(()=>!0)}delete(e){e=this._getKeyPrefix(e);let{store:t}=this.opts;return Promise.resolve().then(()=>t.delete(e))}clear(){let{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}};xz.exports=Dz});var Lz=w((gnt,Fz)=>{"use strict";var Ike=require("events"),xw=require("url"),yke=nz(),wke=Cz(),Yx=Ez(),Nz=Bz(),Bke=kw(),bke=vz(),Qke=Rz(),na=class{constructor(e,t){if(typeof e!="function")throw new TypeError("Parameter `request` must be a function");return this.cache=new Qke({uri:typeof t=="string"&&t,store:typeof t!="string"&&t,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(t,i)=>{let n;if(typeof t=="string")n=qx(xw.parse(t)),t={};else if(t instanceof xw.URL)n=qx(xw.parse(t.toString())),t={};else{let[g,...f]=(t.path||"").split("?"),h=f.length>0?`?${f.join("?")}`:"";n=qx(te(N({},t),{pathname:g,search:h}))}t=N(N({headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1},t),Ske(n)),t.headers=Bke(t.headers);let s=new Ike,o=yke(xw.format(n),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),a=`${t.method}:${o}`,l=!1,c=!1,u=g=>{c=!0;let f=!1,h,p=new Promise(y=>{h=()=>{f||(f=!0,y())}}),m=y=>{if(l&&!g.forceRefresh){y.status=y.statusCode;let v=Yx.fromObject(l.cachePolicy).revalidatedPolicy(g,y);if(!v.modified){let k=v.policy.responseHeaders();y=new Nz(l.statusCode,k,l.body,l.url),y.cachePolicy=v.policy,y.fromCache=!0}}y.fromCache||(y.cachePolicy=new Yx(g,y,g),y.fromCache=!1);let b;g.cache&&y.cachePolicy.storable()?(b=bke(y),(async()=>{try{let v=wke.buffer(y);if(await Promise.race([p,new Promise(q=>y.once("end",q))]),f)return;let k=await v,T={cachePolicy:y.cachePolicy.toObject(),url:y.url,statusCode:y.fromCache?l.statusCode:y.statusCode,body:k},Y=g.strictTtl?y.cachePolicy.timeToLive():void 0;g.maxTtl&&(Y=Y?Math.min(Y,g.maxTtl):g.maxTtl),await this.cache.set(a,T,Y)}catch(v){s.emit("error",new na.CacheError(v))}})()):g.cache&&l&&(async()=>{try{await this.cache.delete(a)}catch(v){s.emit("error",new na.CacheError(v))}})(),s.emit("response",b||y),typeof i=="function"&&i(b||y)};try{let y=e(g,m);y.once("error",h),y.once("abort",h),s.emit("request",y)}catch(y){s.emit("error",new na.RequestError(y))}};return(async()=>{let g=async h=>{await Promise.resolve();let p=h.cache?await this.cache.get(a):void 0;if(typeof p=="undefined")return u(h);let m=Yx.fromObject(p.cachePolicy);if(m.satisfiesWithoutRevalidation(h)&&!h.forceRefresh){let y=m.responseHeaders(),b=new Nz(p.statusCode,y,p.body,p.url);b.cachePolicy=m,b.fromCache=!0,s.emit("response",b),typeof i=="function"&&i(b)}else l=p,h.headers=m.revalidationHeaders(h),u(h)},f=h=>s.emit("error",new na.CacheError(h));this.cache.once("error",f),s.on("response",()=>this.cache.removeListener("error",f));try{await g(t)}catch(h){t.automaticFailover&&!c&&u(t),s.emit("error",new na.CacheError(h))}})(),s}}};function Ske(r){let e=N({},r);return e.path=`${r.pathname||"/"}${r.search||""}`,delete e.pathname,delete e.search,e}function qx(r){return{protocol:r.protocol,auth:r.auth,hostname:r.hostname||r.host||"localhost",port:r.port,pathname:r.pathname,search:r.search}}na.RequestError=class extends Error{constructor(r){super(r.message);this.name="RequestError",Object.assign(this,r)}};na.CacheError=class extends Error{constructor(r){super(r.message);this.name="CacheError",Object.assign(this,r)}};Fz.exports=na});var Oz=w((fnt,Tz)=>{"use strict";var vke=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];Tz.exports=(r,e)=>{if(e._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");let t=new Set(Object.keys(r).concat(vke)),i={};for(let n of t)n in e||(i[n]={get(){let s=r[n];return typeof s=="function"?s.bind(r):s},set(s){r[n]=s},enumerable:!0,configurable:!1});return Object.defineProperties(e,i),r.once("aborted",()=>{e.destroy(),e.emit("aborted")}),r.once("close",()=>{r.complete&&e.readable?e.once("end",()=>{e.emit("close")}):e.emit("close")}),e}});var Uz=w((hnt,Mz)=>{"use strict";var{Transform:kke,PassThrough:xke}=require("stream"),Jx=require("zlib"),Pke=Oz();Mz.exports=r=>{let e=(r.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(e))return r;let t=e==="br";if(t&&typeof Jx.createBrotliDecompress!="function")return r.destroy(new Error("Brotli is not supported on Node.js < 12")),r;let i=!0,n=new kke({transform(a,l,c){i=!1,c(null,a)},flush(a){a()}}),s=new xke({autoDestroy:!1,destroy(a,l){r.destroy(),l(a)}}),o=t?Jx.createBrotliDecompress():Jx.createUnzip();return o.once("error",a=>{if(i&&!r.readable){s.end();return}s.destroy(a)}),Pke(r,s),r.pipe(n).pipe(o).pipe(s),s}});var Wx=w((pnt,Kz)=>{"use strict";var Hz=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,t){if(this.cache.set(e,t),this._size++,this._size>=this.maxSize){if(this._size=0,typeof this.onEviction=="function")for(let[i,n]of this.oldCache.entries())this.onEviction(i,n);this.oldCache=this.cache,this.cache=new Map}}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){let t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e))return this.oldCache.get(e)}delete(e){let t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache)yield e;for(let e of this.oldCache){let[t]=e;this.cache.has(t)||(yield e)}}get size(){let e=0;for(let t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}};Kz.exports=Hz});var _x=w((dnt,jz)=>{"use strict";var Dke=require("events"),Rke=require("tls"),Fke=require("http2"),Nke=Wx(),gn=Symbol("currentStreamsCount"),Gz=Symbol("request"),Os=Symbol("cachedOriginSet"),tf=Symbol("gracefullyClosing"),Lke=["maxDeflateDynamicTableSize","maxSessionMemory","maxHeaderListPairs","maxOutstandingPings","maxReservedRemoteStreams","maxSendHeaderBlockLength","paddingStrategy","localAddress","path","rejectUnauthorized","minDHSize","ca","cert","clientCertEngine","ciphers","key","pfx","servername","minVersion","maxVersion","secureProtocol","crl","honorCipherOrder","ecdhCurve","dhparam","secureOptions","sessionIdContext"],Tke=(r,e,t)=>{let i=0,n=r.length;for(;i<n;){let s=i+n>>>1;t(r[s],e)?i=s+1:n=s}return i},Oke=(r,e)=>r.remoteSettings.maxConcurrentStreams>e.remoteSettings.maxConcurrentStreams,zx=(r,e)=>{for(let t of r)t[Os].length<e[Os].length&&t[Os].every(i=>e[Os].includes(i))&&t[gn]+e[gn]<=e.remoteSettings.maxConcurrentStreams&&Yz(t)},Mke=(r,e)=>{for(let t of r)e[Os].length<t[Os].length&&e[Os].every(i=>t[Os].includes(i))&&e[gn]+t[gn]<=t.remoteSettings.maxConcurrentStreams&&Yz(e)},qz=({agent:r,isFree:e})=>{let t={};for(let i in r.sessions){let s=r.sessions[i].filter(o=>{let a=o[sA.kCurrentStreamsCount]<o.remoteSettings.maxConcurrentStreams;return e?a:!a});s.length!==0&&(t[i]=s)}return t},Yz=r=>{r[tf]=!0,r[gn]===0&&r.close()},sA=class extends Dke{constructor({timeout:e=6e4,maxSessions:t=Infinity,maxFreeSessions:i=10,maxCachedTlsSessions:n=100}={}){super();this.sessions={},this.queue={},this.timeout=e,this.maxSessions=t,this.maxFreeSessions=i,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new Nke({maxSize:n})}static normalizeOrigin(e,t){return typeof e=="string"&&(e=new URL(e)),t&&e.hostname!==t&&(e.hostname=t),e.origin}normalizeOptions(e){let t="";if(e)for(let i of Lke)e[i]&&(t+=`:${e[i]}`);return t}_tryToCreateNewSession(e,t){if(!(e in this.queue)||!(t in this.queue[e]))return;let i=this.queue[e][t];this._sessionsCount<this.maxSessions&&!i.completed&&(i.completed=!0,i())}getSession(e,t,i){return new Promise((n,s)=>{Array.isArray(i)?(i=[...i],n()):i=[{resolve:n,reject:s}];let o=this.normalizeOptions(t),a=sA.normalizeOrigin(e,t&&t.servername);if(a===void 0){for(let{reject:u}of i)u(new TypeError("The `origin` argument needs to be a string or an URL object"));return}if(o in this.sessions){let u=this.sessions[o],g=-1,f=-1,h;for(let p of u){let m=p.remoteSettings.maxConcurrentStreams;if(m<g)break;if(p[Os].includes(a)){let y=p[gn];if(y>=m||p[tf]||p.destroyed)continue;h||(g=m),y>f&&(h=p,f=y)}}if(h){if(i.length!==1){for(let{reject:p}of i){let m=new Error(`Expected the length of listeners to be 1, got ${i.length}. -Please report this to https://github.com/szmarczak/http2-wrapper/`);p(m)}return}i[0].resolve(h);return}}if(o in this.queue){if(a in this.queue[o]){this.queue[o][a].listeners.push(...i),this._tryToCreateNewSession(o,a);return}}else this.queue[o]={};let l=()=>{o in this.queue&&this.queue[o][a]===c&&(delete this.queue[o][a],Object.keys(this.queue[o]).length===0&&delete this.queue[o])},c=()=>{let u=`${a}:${o}`,g=!1;try{let f=Fke.connect(e,N({createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(u)},t));f[gn]=0,f[tf]=!1;let h=()=>f[gn]<f.remoteSettings.maxConcurrentStreams,p=!0;f.socket.once("session",y=>{this.tlsSessionCache.set(u,y)}),f.once("error",y=>{for(let{reject:b}of i)b(y);this.tlsSessionCache.delete(u)}),f.setTimeout(this.timeout,()=>{f.destroy()}),f.once("close",()=>{if(g){p&&this._freeSessionsCount--,this._sessionsCount--;let y=this.sessions[o];y.splice(y.indexOf(f),1),y.length===0&&delete this.sessions[o]}else{let y=new Error("Session closed without receiving a SETTINGS frame");y.code="HTTP2WRAPPER_NOSETTINGS";for(let{reject:b}of i)b(y);l()}this._tryToCreateNewSession(o,a)});let m=()=>{if(!(!(o in this.queue)||!h())){for(let y of f[Os])if(y in this.queue[o]){let{listeners:b}=this.queue[o][y];for(;b.length!==0&&h();)b.shift().resolve(f);let v=this.queue[o];if(v[y].listeners.length===0&&(delete v[y],Object.keys(v).length===0)){delete this.queue[o];break}if(!h())break}}};f.on("origin",()=>{f[Os]=f.originSet,!!h()&&(m(),zx(this.sessions[o],f))}),f.once("remoteSettings",()=>{if(f.ref(),f.unref(),this._sessionsCount++,c.destroyed){let y=new Error("Agent has been destroyed");for(let b of i)b.reject(y);f.destroy();return}f[Os]=f.originSet;{let y=this.sessions;if(o in y){let b=y[o];b.splice(Tke(b,f,Oke),0,f)}else y[o]=[f]}this._freeSessionsCount+=1,g=!0,this.emit("session",f),m(),l(),f[gn]===0&&this._freeSessionsCount>this.maxFreeSessions&&f.close(),i.length!==0&&(this.getSession(a,t,i),i.length=0),f.on("remoteSettings",()=>{m(),zx(this.sessions[o],f)})}),f[Gz]=f.request,f.request=(y,b)=>{if(f[tf])throw new Error("The session is gracefully closing. No new streams are allowed.");let v=f[Gz](y,b);return f.ref(),++f[gn],f[gn]===f.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,v.once("close",()=>{if(p=h(),--f[gn],!f.destroyed&&!f.closed&&(Mke(this.sessions[o],f),h()&&!f.closed)){p||(this._freeSessionsCount++,p=!0);let k=f[gn]===0;k&&f.unref(),k&&(this._freeSessionsCount>this.maxFreeSessions||f[tf])?f.close():(zx(this.sessions[o],f),m())}}),v}}catch(f){for(let h of i)h.reject(f);l()}};c.listeners=i,c.completed=!1,c.destroyed=!1,this.queue[o][a]=c,this._tryToCreateNewSession(o,a)})}request(e,t,i,n){return new Promise((s,o)=>{this.getSession(e,t,[{reject:o,resolve:a=>{try{s(a.request(i,n))}catch(l){o(l)}}}])})}createConnection(e,t){return sA.connect(e,t)}static connect(e,t){t.ALPNProtocols=["h2"];let i=e.port||443,n=e.hostname||e.host;return typeof t.servername=="undefined"&&(t.servername=n),Rke.connect(i,n,t)}closeFreeSessions(){for(let e of Object.values(this.sessions))for(let t of e)t[gn]===0&&t.close()}destroy(e){for(let t of Object.values(this.sessions))for(let i of t)i.destroy(e);for(let t of Object.values(this.queue))for(let i of Object.values(t))i.destroyed=!0;this.queue={}}get freeSessions(){return qz({agent:this,isFree:!0})}get busySessions(){return qz({agent:this,isFree:!1})}};sA.kCurrentStreamsCount=gn;sA.kGracefullyClosing=tf;jz.exports={Agent:sA,globalAgent:new sA}});var Vx=w((Cnt,Jz)=>{"use strict";var{Readable:Uke}=require("stream"),Wz=class extends Uke{constructor(e,t){super({highWaterMark:t,autoDestroy:!1});this.statusCode=null,this.statusMessage="",this.httpVersion="2.0",this.httpVersionMajor=2,this.httpVersionMinor=0,this.headers={},this.trailers={},this.req=null,this.aborted=!1,this.complete=!1,this.upgrade=null,this.rawHeaders=[],this.rawTrailers=[],this.socket=e,this.connection=e,this._dumped=!1}_destroy(e){this.req._request.destroy(e)}setTimeout(e,t){return this.req.setTimeout(e,t),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}};Jz.exports=Wz});var Xx=w((mnt,zz)=>{"use strict";zz.exports=r=>{let e={protocol:r.protocol,hostname:typeof r.hostname=="string"&&r.hostname.startsWith("[")?r.hostname.slice(1,-1):r.hostname,host:r.host,hash:r.hash,search:r.search,pathname:r.pathname,href:r.href,path:`${r.pathname||""}${r.search||""}`};return typeof r.port=="string"&&r.port.length!==0&&(e.port=Number(r.port)),(r.username||r.password)&&(e.auth=`${r.username||""}:${r.password||""}`),e}});var Vz=w((Ent,_z)=>{"use strict";_z.exports=(r,e,t)=>{for(let i of t)r.on(i,(...n)=>e.emit(i,...n))}});var Zz=w((Int,Xz)=>{"use strict";Xz.exports=r=>{switch(r){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}});var e8=w((wnt,$z)=>{"use strict";var rf=(r,e,t)=>{$z.exports[e]=class extends r{constructor(...n){super(typeof t=="string"?t:t(n));this.name=`${super.name} [${e}]`,this.code=e}}};rf(TypeError,"ERR_INVALID_ARG_TYPE",r=>{let e=r[0].includes(".")?"property":"argument",t=r[1],i=Array.isArray(t);return i&&(t=`${t.slice(0,-1).join(", ")} or ${t.slice(-1)}`),`The "${r[0]}" ${e} must be ${i?"one of":"of"} type ${t}. Received ${typeof r[2]}`});rf(TypeError,"ERR_INVALID_PROTOCOL",r=>`Protocol "${r[0]}" not supported. Expected "${r[1]}"`);rf(Error,"ERR_HTTP_HEADERS_SENT",r=>`Cannot ${r[0]} headers after they are sent to the client`);rf(TypeError,"ERR_INVALID_HTTP_TOKEN",r=>`${r[0]} must be a valid HTTP token [${r[1]}]`);rf(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",r=>`Invalid value "${r[0]} for header "${r[1]}"`);rf(TypeError,"ERR_INVALID_CHAR",r=>`Invalid character in ${r[0]} [${r[1]}]`)});var tP=w((Bnt,t8)=>{"use strict";var Kke=require("http2"),{Writable:Hke}=require("stream"),{Agent:r8,globalAgent:jke}=_x(),Gke=Vx(),Yke=Xx(),qke=Vz(),Jke=Zz(),{ERR_INVALID_ARG_TYPE:Zx,ERR_INVALID_PROTOCOL:Wke,ERR_HTTP_HEADERS_SENT:i8,ERR_INVALID_HTTP_TOKEN:zke,ERR_HTTP_INVALID_HEADER_VALUE:_ke,ERR_INVALID_CHAR:Vke}=e8(),{HTTP2_HEADER_STATUS:n8,HTTP2_HEADER_METHOD:s8,HTTP2_HEADER_PATH:o8,HTTP2_METHOD_CONNECT:Xke}=Kke.constants,Wi=Symbol("headers"),$x=Symbol("origin"),eP=Symbol("session"),a8=Symbol("options"),Pw=Symbol("flushedHeaders"),Dd=Symbol("jobs"),Zke=/^[\^`\-\w!#$%&*+.|~]+$/,$ke=/[^\t\u0020-\u007E\u0080-\u00FF]/,A8=class extends Hke{constructor(e,t,i){super({autoDestroy:!1});let n=typeof e=="string"||e instanceof URL;if(n&&(e=Yke(e instanceof URL?e:new URL(e))),typeof t=="function"||t===void 0?(i=t,t=n?e:N({},e)):t=N(N({},e),t),t.h2session)this[eP]=t.h2session;else if(t.agent===!1)this.agent=new r8({maxFreeSessions:0});else if(typeof t.agent=="undefined"||t.agent===null)typeof t.createConnection=="function"?(this.agent=new r8({maxFreeSessions:0}),this.agent.createConnection=t.createConnection):this.agent=jke;else if(typeof t.agent.request=="function")this.agent=t.agent;else throw new Zx("options.agent",["Agent-like Object","undefined","false"],t.agent);if(t.protocol&&t.protocol!=="https:")throw new Wke(t.protocol,"https:");let s=t.port||t.defaultPort||this.agent&&this.agent.defaultPort||443,o=t.hostname||t.host||"localhost";delete t.hostname,delete t.host,delete t.port;let{timeout:a}=t;if(t.timeout=void 0,this[Wi]=Object.create(null),this[Dd]=[],this.socket=null,this.connection=null,this.method=t.method||"GET",this.path=t.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,t.headers)for(let[l,c]of Object.entries(t.headers))this.setHeader(l,c);t.auth&&!("authorization"in this[Wi])&&(this[Wi].authorization="Basic "+Buffer.from(t.auth).toString("base64")),t.session=t.tlsSession,t.path=t.socketPath,this[a8]=t,s===443?(this[$x]=`https://${o}`,":authority"in this[Wi]||(this[Wi][":authority"]=o)):(this[$x]=`https://${o}:${s}`,":authority"in this[Wi]||(this[Wi][":authority"]=`${o}:${s}`)),a&&this.setTimeout(a),i&&this.once("response",i),this[Pw]=!1}get method(){return this[Wi][s8]}set method(e){e&&(this[Wi][s8]=e.toUpperCase())}get path(){return this[Wi][o8]}set path(e){e&&(this[Wi][o8]=e)}get _mustNotHaveABody(){return this.method==="GET"||this.method==="HEAD"||this.method==="DELETE"}_write(e,t,i){if(this._mustNotHaveABody){i(new Error("The GET, HEAD and DELETE methods must NOT have a body"));return}this.flushHeaders();let n=()=>this._request.write(e,t,i);this._request?n():this[Dd].push(n)}_final(e){if(this.destroyed)return;this.flushHeaders();let t=()=>{if(this._mustNotHaveABody){e();return}this._request.end(e)};this._request?t():this[Dd].push(t)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,t){this.res&&this.res._dump(),this._request&&this._request.destroy(),t(e)}async flushHeaders(){if(this[Pw]||this.destroyed)return;this[Pw]=!0;let e=this.method===Xke,t=i=>{if(this._request=i,this.destroyed){i.destroy();return}e||qke(i,this,["timeout","continue","close","error"]);let n=o=>(...a)=>{!this.writable&&!this.destroyed?o(...a):this.once("finish",()=>{o(...a)})};i.once("response",n((o,a,l)=>{let c=new Gke(this.socket,i.readableHighWaterMark);this.res=c,c.req=this,c.statusCode=o[n8],c.headers=o,c.rawHeaders=l,c.once("end",()=>{this.aborted?(c.aborted=!0,c.emit("aborted")):(c.complete=!0,c.socket=null,c.connection=null)}),e?(c.upgrade=!0,this.emit("connect",c,i,Buffer.alloc(0))?this.emit("close"):i.destroy()):(i.on("data",u=>{!c._dumped&&!c.push(u)&&i.pause()}),i.once("end",()=>{c.push(null)}),this.emit("response",c)||c._dump())})),i.once("headers",n(o=>this.emit("information",{statusCode:o[n8]}))),i.once("trailers",n((o,a,l)=>{let{res:c}=this;c.trailers=o,c.rawTrailers=l}));let{socket:s}=i.session;this.socket=s,this.connection=s;for(let o of this[Dd])o();this.emit("socket",this.socket)};if(this[eP])try{t(this[eP].request(this[Wi]))}catch(i){this.emit("error",i)}else{this.reusedSocket=!0;try{t(await this.agent.request(this[$x],this[a8],this[Wi]))}catch(i){this.emit("error",i)}}}getHeader(e){if(typeof e!="string")throw new Zx("name","string",e);return this[Wi][e.toLowerCase()]}get headersSent(){return this[Pw]}removeHeader(e){if(typeof e!="string")throw new Zx("name","string",e);if(this.headersSent)throw new i8("remove");delete this[Wi][e.toLowerCase()]}setHeader(e,t){if(this.headersSent)throw new i8("set");if(typeof e!="string"||!Zke.test(e)&&!Jke(e))throw new zke("Header name",e);if(typeof t=="undefined")throw new _ke(t,e);if($ke.test(t))throw new Vke("header content",e);this[Wi][e.toLowerCase()]=t}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,t){let i=()=>this._request.setTimeout(e,t);return this._request?i():this[Dd].push(i),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}};t8.exports=A8});var c8=w((bnt,l8)=>{"use strict";var exe=require("tls");l8.exports=(r={})=>new Promise((e,t)=>{let i=exe.connect(r,()=>{r.resolveSocket?(i.off("error",t),e({alpnProtocol:i.alpnProtocol,socket:i})):(i.destroy(),e({alpnProtocol:i.alpnProtocol}))});i.on("error",t)})});var g8=w((Qnt,u8)=>{"use strict";var txe=require("net");u8.exports=r=>{let e=r.host,t=r.headers&&r.headers.host;return t&&(t.startsWith("[")?t.indexOf("]")===-1?e=t:e=t.slice(1,-1):e=t.split(":",1)[0]),txe.isIP(e)?"":e}});var p8=w((Snt,rP)=>{"use strict";var f8=require("http"),iP=require("https"),rxe=c8(),ixe=Wx(),nxe=tP(),sxe=g8(),oxe=Xx(),Dw=new ixe({maxSize:100}),Rd=new Map,h8=(r,e,t)=>{e._httpMessage={shouldKeepAlive:!0};let i=()=>{r.emit("free",e,t)};e.on("free",i);let n=()=>{r.removeSocket(e,t)};e.on("close",n);let s=()=>{r.removeSocket(e,t),e.off("close",n),e.off("free",i),e.off("agentRemove",s)};e.on("agentRemove",s),r.emit("free",e,t)},axe=async r=>{let e=`${r.host}:${r.port}:${r.ALPNProtocols.sort()}`;if(!Dw.has(e)){if(Rd.has(e))return(await Rd.get(e)).alpnProtocol;let{path:t,agent:i}=r;r.path=r.socketPath;let n=rxe(r);Rd.set(e,n);try{let{socket:s,alpnProtocol:o}=await n;if(Dw.set(e,o),r.path=t,o==="h2")s.destroy();else{let{globalAgent:a}=iP,l=iP.Agent.prototype.createConnection;i?i.createConnection===l?h8(i,s,r):s.destroy():a.createConnection===l?h8(a,s,r):s.destroy()}return Rd.delete(e),o}catch(s){throw Rd.delete(e),s}}return Dw.get(e)};rP.exports=async(r,e,t)=>{if((typeof r=="string"||r instanceof URL)&&(r=oxe(new URL(r))),typeof e=="function"&&(t=e,e=void 0),e=te(N(N({ALPNProtocols:["h2","http/1.1"]},r),e),{resolveSocket:!0}),!Array.isArray(e.ALPNProtocols)||e.ALPNProtocols.length===0)throw new Error("The `ALPNProtocols` option must be an Array with at least one entry");e.protocol=e.protocol||"https:";let i=e.protocol==="https:";e.host=e.hostname||e.host||"localhost",e.session=e.tlsSession,e.servername=e.servername||sxe(e),e.port=e.port||(i?443:80),e._defaultAgent=i?iP.globalAgent:f8.globalAgent;let n=e.agent;if(n){if(n.addRequest)throw new Error("The `options.agent` object can contain only `http`, `https` or `http2` properties");e.agent=n[i?"https":"http"]}return i&&await axe(e)==="h2"?(n&&(e.agent=n.http2),new nxe(e,t)):f8.request(e,t)};rP.exports.protocolCache=Dw});var C8=w((vnt,d8)=>{"use strict";var Axe=require("http2"),lxe=_x(),nP=tP(),cxe=Vx(),uxe=p8(),gxe=(r,e,t)=>new nP(r,e,t),fxe=(r,e,t)=>{let i=new nP(r,e,t);return i.end(),i};d8.exports=te(N(te(N({},Axe),{ClientRequest:nP,IncomingMessage:cxe}),lxe),{request:gxe,get:fxe,auto:uxe})});var oP=w(sP=>{"use strict";Object.defineProperty(sP,"__esModule",{value:!0});var m8=nA();sP.default=r=>m8.default.nodeStream(r)&&m8.default.function_(r.getBoundary)});var w8=w(aP=>{"use strict";Object.defineProperty(aP,"__esModule",{value:!0});var E8=require("fs"),I8=require("util"),y8=nA(),hxe=oP(),pxe=I8.promisify(E8.stat);aP.default=async(r,e)=>{if(e&&"content-length"in e)return Number(e["content-length"]);if(!r)return 0;if(y8.default.string(r))return Buffer.byteLength(r);if(y8.default.buffer(r))return r.length;if(hxe.default(r))return I8.promisify(r.getLength.bind(r))();if(r instanceof E8.ReadStream){let{size:t}=await pxe(r.path);return t===0?void 0:t}}});var lP=w(AP=>{"use strict";Object.defineProperty(AP,"__esModule",{value:!0});function dxe(r,e,t){let i={};for(let n of t)i[n]=(...s)=>{e.emit(n,...s)},r.on(n,i[n]);return()=>{for(let n of t)r.off(n,i[n])}}AP.default=dxe});var B8=w(cP=>{"use strict";Object.defineProperty(cP,"__esModule",{value:!0});cP.default=()=>{let r=[];return{once(e,t,i){e.once(t,i),r.push({origin:e,event:t,fn:i})},unhandleAll(){for(let e of r){let{origin:t,event:i,fn:n}=e;t.removeListener(i,n)}r.length=0}}}});var Q8=w(Fd=>{"use strict";Object.defineProperty(Fd,"__esModule",{value:!0});Fd.TimeoutError=void 0;var Cxe=require("net"),mxe=B8(),b8=Symbol("reentry"),Exe=()=>{},uP=class extends Error{constructor(e,t){super(`Timeout awaiting '${t}' for ${e}ms`);this.event=t,this.name="TimeoutError",this.code="ETIMEDOUT"}};Fd.TimeoutError=uP;Fd.default=(r,e,t)=>{if(b8 in r)return Exe;r[b8]=!0;let i=[],{once:n,unhandleAll:s}=mxe.default(),o=(g,f,h)=>{var p;let m=setTimeout(f,g,g,h);(p=m.unref)===null||p===void 0||p.call(m);let y=()=>{clearTimeout(m)};return i.push(y),y},{host:a,hostname:l}=t,c=(g,f)=>{r.destroy(new uP(g,f))},u=()=>{for(let g of i)g();s()};if(r.once("error",g=>{if(u(),r.listenerCount("error")===0)throw g}),r.once("close",u),n(r,"response",g=>{n(g,"end",u)}),typeof e.request!="undefined"&&o(e.request,c,"request"),typeof e.socket!="undefined"){let g=()=>{c(e.socket,"socket")};r.setTimeout(e.socket,g),i.push(()=>{r.removeListener("timeout",g)})}return n(r,"socket",g=>{var f;let{socketPath:h}=r;if(g.connecting){let p=Boolean(h!=null?h:Cxe.isIP((f=l!=null?l:a)!==null&&f!==void 0?f:"")!==0);if(typeof e.lookup!="undefined"&&!p&&typeof g.address().address=="undefined"){let m=o(e.lookup,c,"lookup");n(g,"lookup",m)}if(typeof e.connect!="undefined"){let m=()=>o(e.connect,c,"connect");p?n(g,"connect",m()):n(g,"lookup",y=>{y===null&&n(g,"connect",m())})}typeof e.secureConnect!="undefined"&&t.protocol==="https:"&&n(g,"connect",()=>{let m=o(e.secureConnect,c,"secureConnect");n(g,"secureConnect",m)})}if(typeof e.send!="undefined"){let p=()=>o(e.send,c,"send");g.connecting?n(g,"connect",()=>{n(r,"upload-complete",p())}):n(r,"upload-complete",p())}}),typeof e.response!="undefined"&&n(r,"upload-complete",()=>{let g=o(e.response,c,"response");n(r,"response",g)}),u}});var v8=w(gP=>{"use strict";Object.defineProperty(gP,"__esModule",{value:!0});var S8=nA();gP.default=r=>{r=r;let e={protocol:r.protocol,hostname:S8.default.string(r.hostname)&&r.hostname.startsWith("[")?r.hostname.slice(1,-1):r.hostname,host:r.host,hash:r.hash,search:r.search,pathname:r.pathname,href:r.href,path:`${r.pathname||""}${r.search||""}`};return S8.default.string(r.port)&&r.port.length>0&&(e.port=Number(r.port)),(r.username||r.password)&&(e.auth=`${r.username||""}:${r.password||""}`),e}});var k8=w(fP=>{"use strict";Object.defineProperty(fP,"__esModule",{value:!0});var Ixe=require("url"),yxe=["protocol","host","hostname","port","pathname","search"];fP.default=(r,e)=>{var t,i;if(e.path){if(e.pathname)throw new TypeError("Parameters `path` and `pathname` are mutually exclusive.");if(e.search)throw new TypeError("Parameters `path` and `search` are mutually exclusive.");if(e.searchParams)throw new TypeError("Parameters `path` and `searchParams` are mutually exclusive.")}if(e.search&&e.searchParams)throw new TypeError("Parameters `search` and `searchParams` are mutually exclusive.");if(!r){if(!e.protocol)throw new TypeError("No URL protocol specified");r=`${e.protocol}//${(i=(t=e.hostname)!==null&&t!==void 0?t:e.host)!==null&&i!==void 0?i:""}`}let n=new Ixe.URL(r);if(e.path){let s=e.path.indexOf("?");s===-1?e.pathname=e.path:(e.pathname=e.path.slice(0,s),e.search=e.path.slice(s+1)),delete e.path}for(let s of yxe)e[s]&&(n[s]=e[s].toString());return n}});var P8=w(hP=>{"use strict";Object.defineProperty(hP,"__esModule",{value:!0});var x8=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,t){typeof e=="object"?this.weakMap.set(e,t):this.map.set(e,t)}get(e){return typeof e=="object"?this.weakMap.get(e):this.map.get(e)}has(e){return typeof e=="object"?this.weakMap.has(e):this.map.has(e)}};hP.default=x8});var dP=w(pP=>{"use strict";Object.defineProperty(pP,"__esModule",{value:!0});var wxe=async r=>{let e=[],t=0;for await(let i of r)e.push(i),t+=Buffer.byteLength(i);return Buffer.isBuffer(e[0])?Buffer.concat(e,t):Buffer.from(e.join(""))};pP.default=wxe});var R8=w(Xc=>{"use strict";Object.defineProperty(Xc,"__esModule",{value:!0});Xc.dnsLookupIpVersionToFamily=Xc.isDnsLookupIpVersion=void 0;var D8={auto:0,ipv4:4,ipv6:6};Xc.isDnsLookupIpVersion=r=>r in D8;Xc.dnsLookupIpVersionToFamily=r=>{if(Xc.isDnsLookupIpVersion(r))return D8[r];throw new Error("Invalid DNS lookup IP version")}});var CP=w(Rw=>{"use strict";Object.defineProperty(Rw,"__esModule",{value:!0});Rw.isResponseOk=void 0;Rw.isResponseOk=r=>{let{statusCode:e}=r,t=r.request.options.followRedirect?299:399;return e>=200&&e<=t||e===304}});var N8=w(mP=>{"use strict";Object.defineProperty(mP,"__esModule",{value:!0});var F8=new Set;mP.default=r=>{F8.has(r)||(F8.add(r),process.emitWarning(`Got: ${r}`,{type:"DeprecationWarning"}))}});var L8=w(EP=>{"use strict";Object.defineProperty(EP,"__esModule",{value:!0});var Ir=nA(),Bxe=(r,e)=>{if(Ir.default.null_(r.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");Ir.assert.any([Ir.default.string,Ir.default.undefined],r.encoding),Ir.assert.any([Ir.default.boolean,Ir.default.undefined],r.resolveBodyOnly),Ir.assert.any([Ir.default.boolean,Ir.default.undefined],r.methodRewriting),Ir.assert.any([Ir.default.boolean,Ir.default.undefined],r.isStream),Ir.assert.any([Ir.default.string,Ir.default.undefined],r.responseType),r.responseType===void 0&&(r.responseType="text");let{retry:t}=r;if(e?r.retry=N({},e.retry):r.retry={calculateDelay:i=>i.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},Ir.default.object(t)?(r.retry=N(N({},r.retry),t),r.retry.methods=[...new Set(r.retry.methods.map(i=>i.toUpperCase()))],r.retry.statusCodes=[...new Set(r.retry.statusCodes)],r.retry.errorCodes=[...new Set(r.retry.errorCodes)]):Ir.default.number(t)&&(r.retry.limit=t),Ir.default.undefined(r.retry.maxRetryAfter)&&(r.retry.maxRetryAfter=Math.min(...[r.timeout.request,r.timeout.connect].filter(Ir.default.number))),Ir.default.object(r.pagination)){e&&(r.pagination=N(N({},e.pagination),r.pagination));let{pagination:i}=r;if(!Ir.default.function_(i.transform))throw new Error("`options.pagination.transform` must be implemented");if(!Ir.default.function_(i.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!Ir.default.function_(i.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!Ir.default.function_(i.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return r.responseType==="json"&&r.headers.accept===void 0&&(r.headers.accept="application/json"),r};EP.default=Bxe});var T8=w(Nd=>{"use strict";Object.defineProperty(Nd,"__esModule",{value:!0});Nd.retryAfterStatusCodes=void 0;Nd.retryAfterStatusCodes=new Set([413,429,503]);var bxe=({attemptCount:r,retryOptions:e,error:t,retryAfter:i})=>{if(r>e.limit)return 0;let n=e.methods.includes(t.options.method),s=e.errorCodes.includes(t.code),o=t.response&&e.statusCodes.includes(t.response.statusCode);if(!n||!s&&!o)return 0;if(t.response){if(i)return e.maxRetryAfter===void 0||i>e.maxRetryAfter?0:i;if(t.response.statusCode===413)return 0}let a=Math.random()*100;return 2**(r-1)*1e3+a};Nd.default=bxe});var Td=w(qt=>{"use strict";Object.defineProperty(qt,"__esModule",{value:!0});qt.UnsupportedProtocolError=qt.ReadError=qt.TimeoutError=qt.UploadError=qt.CacheError=qt.HTTPError=qt.MaxRedirectsError=qt.RequestError=qt.setNonEnumerableProperties=qt.knownHookEvents=qt.withoutBody=qt.kIsNormalizedAlready=void 0;var O8=require("util"),M8=require("stream"),Qxe=require("fs"),fl=require("url"),U8=require("http"),IP=require("http"),Sxe=require("https"),vxe=z4(),kxe=tz(),K8=Lz(),xxe=Uz(),Pxe=C8(),Dxe=kw(),Ee=nA(),Rxe=w8(),H8=oP(),Fxe=lP(),j8=Q8(),Nxe=v8(),G8=k8(),Lxe=P8(),Txe=dP(),Y8=R8(),Oxe=CP(),hl=N8(),Mxe=L8(),Uxe=T8(),yP,Fi=Symbol("request"),Fw=Symbol("response"),nf=Symbol("responseSize"),sf=Symbol("downloadedSize"),of=Symbol("bodySize"),af=Symbol("uploadedSize"),Nw=Symbol("serverResponsesPiped"),q8=Symbol("unproxyEvents"),J8=Symbol("isFromCache"),wP=Symbol("cancelTimeouts"),W8=Symbol("startedReading"),Af=Symbol("stopReading"),Lw=Symbol("triggerRead"),pl=Symbol("body"),Ld=Symbol("jobs"),z8=Symbol("originalResponse"),_8=Symbol("retryTimeout");qt.kIsNormalizedAlready=Symbol("isNormalizedAlready");var Kxe=Ee.default.string(process.versions.brotli);qt.withoutBody=new Set(["GET","HEAD"]);qt.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];function Hxe(r){for(let e in r){let t=r[e];if(!Ee.default.string(t)&&!Ee.default.number(t)&&!Ee.default.boolean(t)&&!Ee.default.null_(t)&&!Ee.default.undefined(t))throw new TypeError(`The \`searchParams\` value '${String(t)}' must be a string, number, boolean or null`)}}function jxe(r){return Ee.default.object(r)&&!("statusCode"in r)}var BP=new Lxe.default,Gxe=async r=>new Promise((e,t)=>{let i=n=>{t(n)};r.pending||e(),r.once("error",i),r.once("ready",()=>{r.off("error",i),e()})}),Yxe=new Set([300,301,302,303,304,307,308]),qxe=["context","body","json","form"];qt.setNonEnumerableProperties=(r,e)=>{let t={};for(let i of r)if(!!i)for(let n of qxe)n in i&&(t[n]={writable:!0,configurable:!0,enumerable:!1,value:i[n]});Object.defineProperties(e,t)};var hi=class extends Error{constructor(e,t,i){var n;super(e);if(Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=t.code,i instanceof bP?(Object.defineProperty(this,"request",{enumerable:!1,value:i}),Object.defineProperty(this,"response",{enumerable:!1,value:i[Fw]}),Object.defineProperty(this,"options",{enumerable:!1,value:i.options})):Object.defineProperty(this,"options",{enumerable:!1,value:i}),this.timings=(n=this.request)===null||n===void 0?void 0:n.timings,Ee.default.string(t.stack)&&Ee.default.string(this.stack)){let s=this.stack.indexOf(this.message)+this.message.length,o=this.stack.slice(s).split(` -`).reverse(),a=t.stack.slice(t.stack.indexOf(t.message)+t.message.length).split(` -`).reverse();for(;a.length!==0&&a[0]===o[0];)o.shift();this.stack=`${this.stack.slice(0,s)}${o.reverse().join(` -`)}${a.reverse().join(` -`)}`}}};qt.RequestError=hi;var QP=class extends hi{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e);this.name="MaxRedirectsError"}};qt.MaxRedirectsError=QP;var SP=class extends hi{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request);this.name="HTTPError"}};qt.HTTPError=SP;var vP=class extends hi{constructor(e,t){super(e.message,e,t);this.name="CacheError"}};qt.CacheError=vP;var kP=class extends hi{constructor(e,t){super(e.message,e,t);this.name="UploadError"}};qt.UploadError=kP;var xP=class extends hi{constructor(e,t,i){super(e.message,e,i);this.name="TimeoutError",this.event=e.event,this.timings=t}};qt.TimeoutError=xP;var Tw=class extends hi{constructor(e,t){super(e.message,e,t);this.name="ReadError"}};qt.ReadError=Tw;var PP=class extends hi{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e);this.name="UnsupportedProtocolError"}};qt.UnsupportedProtocolError=PP;var Jxe=["socket","connect","continue","information","upgrade","timeout"],bP=class extends M8.Duplex{constructor(e,t={},i){super({autoDestroy:!1,highWaterMark:0});this[sf]=0,this[af]=0,this.requestInitialized=!1,this[Nw]=new Set,this.redirects=[],this[Af]=!1,this[Lw]=!1,this[Ld]=[],this.retryCount=0,this._progressCallbacks=[];let n=()=>this._unlockWrite(),s=()=>this._lockWrite();this.on("pipe",c=>{c.prependListener("data",n),c.on("data",s),c.prependListener("end",n),c.on("end",s)}),this.on("unpipe",c=>{c.off("data",n),c.off("data",s),c.off("end",n),c.off("end",s)}),this.on("pipe",c=>{c instanceof IP.IncomingMessage&&(this.options.headers=N(N({},c.headers),this.options.headers))});let{json:o,body:a,form:l}=t;if((o||a||l)&&this._lockWrite(),qt.kIsNormalizedAlready in t)this.options=t;else try{this.options=this.constructor.normalizeArguments(e,t,i)}catch(c){Ee.default.nodeStream(t.body)&&t.body.destroy(),this.destroy(c);return}(async()=>{var c;try{this.options.body instanceof Qxe.ReadStream&&await Gxe(this.options.body);let{url:u}=this.options;if(!u)throw new TypeError("Missing `url` property");if(this.requestUrl=u.toString(),decodeURI(this.requestUrl),await this._finalizeBody(),await this._makeRequest(),this.destroyed){(c=this[Fi])===null||c===void 0||c.destroy();return}for(let g of this[Ld])g();this[Ld].length=0,this.requestInitialized=!0}catch(u){if(u instanceof hi){this._beforeError(u);return}this.destroyed||this.destroy(u)}})()}static normalizeArguments(e,t,i){var n,s,o,a,l;let c=t;if(Ee.default.object(e)&&!Ee.default.urlInstance(e))t=N(N(N({},i),e),t);else{if(e&&t&&t.url!==void 0)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");t=N(N({},i),t),e!==void 0&&(t.url=e),Ee.default.urlInstance(t.url)&&(t.url=new fl.URL(t.url.toString()))}if(t.cache===!1&&(t.cache=void 0),t.dnsCache===!1&&(t.dnsCache=void 0),Ee.assert.any([Ee.default.string,Ee.default.undefined],t.method),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.headers),Ee.assert.any([Ee.default.string,Ee.default.urlInstance,Ee.default.undefined],t.prefixUrl),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.cookieJar),Ee.assert.any([Ee.default.object,Ee.default.string,Ee.default.undefined],t.searchParams),Ee.assert.any([Ee.default.object,Ee.default.string,Ee.default.undefined],t.cache),Ee.assert.any([Ee.default.object,Ee.default.number,Ee.default.undefined],t.timeout),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.context),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.hooks),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.decompress),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.ignoreInvalidCookies),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.followRedirect),Ee.assert.any([Ee.default.number,Ee.default.undefined],t.maxRedirects),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.throwHttpErrors),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.http2),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.allowGetBody),Ee.assert.any([Ee.default.string,Ee.default.undefined],t.localAddress),Ee.assert.any([Y8.isDnsLookupIpVersion,Ee.default.undefined],t.dnsLookupIpVersion),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.https),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.rejectUnauthorized),t.https&&(Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.https.rejectUnauthorized),Ee.assert.any([Ee.default.function_,Ee.default.undefined],t.https.checkServerIdentity),Ee.assert.any([Ee.default.string,Ee.default.object,Ee.default.array,Ee.default.undefined],t.https.certificateAuthority),Ee.assert.any([Ee.default.string,Ee.default.object,Ee.default.array,Ee.default.undefined],t.https.key),Ee.assert.any([Ee.default.string,Ee.default.object,Ee.default.array,Ee.default.undefined],t.https.certificate),Ee.assert.any([Ee.default.string,Ee.default.undefined],t.https.passphrase),Ee.assert.any([Ee.default.string,Ee.default.buffer,Ee.default.array,Ee.default.undefined],t.https.pfx)),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.cacheOptions),Ee.default.string(t.method)?t.method=t.method.toUpperCase():t.method="GET",t.headers===(i==null?void 0:i.headers)?t.headers=N({},t.headers):t.headers=Dxe(N(N({},i==null?void 0:i.headers),t.headers)),"slashes"in t)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in t)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in t&&t.searchParams&&t.searchParams!==(i==null?void 0:i.searchParams)){let h;if(Ee.default.string(t.searchParams)||t.searchParams instanceof fl.URLSearchParams)h=new fl.URLSearchParams(t.searchParams);else{Hxe(t.searchParams),h=new fl.URLSearchParams;for(let p in t.searchParams){let m=t.searchParams[p];m===null?h.append(p,""):m!==void 0&&h.append(p,m)}}(n=i==null?void 0:i.searchParams)===null||n===void 0||n.forEach((p,m)=>{h.has(m)||h.append(m,p)}),t.searchParams=h}if(t.username=(s=t.username)!==null&&s!==void 0?s:"",t.password=(o=t.password)!==null&&o!==void 0?o:"",Ee.default.undefined(t.prefixUrl)?t.prefixUrl=(a=i==null?void 0:i.prefixUrl)!==null&&a!==void 0?a:"":(t.prefixUrl=t.prefixUrl.toString(),t.prefixUrl!==""&&!t.prefixUrl.endsWith("/")&&(t.prefixUrl+="/")),Ee.default.string(t.url)){if(t.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");t.url=G8.default(t.prefixUrl+t.url,t)}else(Ee.default.undefined(t.url)&&t.prefixUrl!==""||t.protocol)&&(t.url=G8.default(t.prefixUrl,t));if(t.url){"port"in t&&delete t.port;let{prefixUrl:h}=t;Object.defineProperty(t,"prefixUrl",{set:m=>{let y=t.url;if(!y.href.startsWith(m))throw new Error(`Cannot change \`prefixUrl\` from ${h} to ${m}: ${y.href}`);t.url=new fl.URL(m+y.href.slice(h.length)),h=m},get:()=>h});let{protocol:p}=t.url;if(p==="unix:"&&(p="http:",t.url=new fl.URL(`http://unix${t.url.pathname}${t.url.search}`)),t.searchParams&&(t.url.search=t.searchParams.toString()),p!=="http:"&&p!=="https:")throw new PP(t);t.username===""?t.username=t.url.username:t.url.username=t.username,t.password===""?t.password=t.url.password:t.url.password=t.password}let{cookieJar:u}=t;if(u){let{setCookie:h,getCookieString:p}=u;Ee.assert.function_(h),Ee.assert.function_(p),h.length===4&&p.length===0&&(h=O8.promisify(h.bind(t.cookieJar)),p=O8.promisify(p.bind(t.cookieJar)),t.cookieJar={setCookie:h,getCookieString:p})}let{cache:g}=t;if(g&&(BP.has(g)||BP.set(g,new K8((h,p)=>{let m=h[Fi](h,p);return Ee.default.promise(m)&&(m.once=(y,b)=>{if(y==="error")m.catch(b);else if(y==="abort")(async()=>{try{(await m).once("abort",b)}catch(v){}})();else throw new Error(`Unknown HTTP2 promise event: ${y}`);return m}),m},g))),t.cacheOptions=N({},t.cacheOptions),t.dnsCache===!0)yP||(yP=new kxe.default),t.dnsCache=yP;else if(!Ee.default.undefined(t.dnsCache)&&!t.dnsCache.lookup)throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${Ee.default(t.dnsCache)}`);Ee.default.number(t.timeout)?t.timeout={request:t.timeout}:i&&t.timeout!==i.timeout?t.timeout=N(N({},i.timeout),t.timeout):t.timeout=N({},t.timeout),t.context||(t.context={});let f=t.hooks===(i==null?void 0:i.hooks);t.hooks=N({},t.hooks);for(let h of qt.knownHookEvents)if(h in t.hooks)if(Ee.default.array(t.hooks[h]))t.hooks[h]=[...t.hooks[h]];else throw new TypeError(`Parameter \`${h}\` must be an Array, got ${Ee.default(t.hooks[h])}`);else t.hooks[h]=[];if(i&&!f)for(let h of qt.knownHookEvents)i.hooks[h].length>0&&(t.hooks[h]=[...i.hooks[h],...t.hooks[h]]);if("family"in t&&hl.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),(i==null?void 0:i.https)&&(t.https=N(N({},i.https),t.https)),"rejectUnauthorized"in t&&hl.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in t&&hl.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in t&&hl.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in t&&hl.default('"options.key" was never documented, please use "options.https.key"'),"cert"in t&&hl.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in t&&hl.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in t&&hl.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in t)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(t.agent){for(let h in t.agent)if(h!=="http"&&h!=="https"&&h!=="http2")throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${h}\``)}return t.maxRedirects=(l=t.maxRedirects)!==null&&l!==void 0?l:0,qt.setNonEnumerableProperties([i,c],t),Mxe.default(t,i)}_lockWrite(){let e=()=>{throw new TypeError("The payload has been already provided")};this.write=e,this.end=e}_unlockWrite(){this.write=super.write,this.end=super.end}async _finalizeBody(){let{options:e}=this,{headers:t}=e,i=!Ee.default.undefined(e.form),n=!Ee.default.undefined(e.json),s=!Ee.default.undefined(e.body),o=i||n||s,a=qt.withoutBody.has(e.method)&&!(e.method==="GET"&&e.allowGetBody);if(this._cannotHaveBody=a,o){if(a)throw new TypeError(`The \`${e.method}\` method cannot be used with a body`);if([s,i,n].filter(l=>l).length>1)throw new TypeError("The `body`, `json` and `form` options are mutually exclusive");if(s&&!(e.body instanceof M8.Readable)&&!Ee.default.string(e.body)&&!Ee.default.buffer(e.body)&&!H8.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(i&&!Ee.default.object(e.form))throw new TypeError("The `form` option must be an Object");{let l=!Ee.default.string(t["content-type"]);s?(H8.default(e.body)&&l&&(t["content-type"]=`multipart/form-data; boundary=${e.body.getBoundary()}`),this[pl]=e.body):i?(l&&(t["content-type"]="application/x-www-form-urlencoded"),this[pl]=new fl.URLSearchParams(e.form).toString()):(l&&(t["content-type"]="application/json"),this[pl]=e.stringifyJson(e.json));let c=await Rxe.default(this[pl],e.headers);Ee.default.undefined(t["content-length"])&&Ee.default.undefined(t["transfer-encoding"])&&!a&&!Ee.default.undefined(c)&&(t["content-length"]=String(c))}}else a?this._lockWrite():this._unlockWrite();this[of]=Number(t["content-length"])||void 0}async _onResponseBase(e){let{options:t}=this,{url:i}=t;this[z8]=e,t.decompress&&(e=xxe(e));let n=e.statusCode,s=e;s.statusMessage=s.statusMessage?s.statusMessage:U8.STATUS_CODES[n],s.url=t.url.toString(),s.requestUrl=this.requestUrl,s.redirectUrls=this.redirects,s.request=this,s.isFromCache=e.fromCache||!1,s.ip=this.ip,s.retryCount=this.retryCount,this[J8]=s.isFromCache,this[nf]=Number(e.headers["content-length"])||void 0,this[Fw]=e,e.once("end",()=>{this[nf]=this[sf],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",a=>{e.destroy(),this._beforeError(new Tw(a,this))}),e.once("aborted",()=>{this._beforeError(new Tw({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);let o=e.headers["set-cookie"];if(Ee.default.object(t.cookieJar)&&o){let a=o.map(async l=>t.cookieJar.setCookie(l,i.toString()));t.ignoreInvalidCookies&&(a=a.map(async l=>l.catch(()=>{})));try{await Promise.all(a)}catch(l){this._beforeError(l);return}}if(t.followRedirect&&e.headers.location&&Yxe.has(n)){if(e.resume(),this[Fi]&&(this[wP](),delete this[Fi],this[q8]()),(n===303&&t.method!=="GET"&&t.method!=="HEAD"||!t.methodRewriting)&&(t.method="GET","body"in t&&delete t.body,"json"in t&&delete t.json,"form"in t&&delete t.form,this[pl]=void 0,delete t.headers["content-length"]),this.redirects.length>=t.maxRedirects){this._beforeError(new QP(this));return}try{let l=Buffer.from(e.headers.location,"binary").toString(),c=new fl.URL(l,i),u=c.toString();decodeURI(u),c.hostname!==i.hostname||c.port!==i.port?("host"in t.headers&&delete t.headers.host,"cookie"in t.headers&&delete t.headers.cookie,"authorization"in t.headers&&delete t.headers.authorization,(t.username||t.password)&&(t.username="",t.password="")):(c.username=t.username,c.password=t.password),this.redirects.push(u),t.url=c;for(let g of t.hooks.beforeRedirect)await g(t,s);this.emit("redirect",s,t),await this._makeRequest()}catch(l){this._beforeError(l);return}return}if(t.isStream&&t.throwHttpErrors&&!Oxe.isResponseOk(s)){this._beforeError(new SP(s));return}e.on("readable",()=>{this[Lw]&&this._read()}),this.on("resume",()=>{e.resume()}),this.on("pause",()=>{e.pause()}),e.once("end",()=>{this.push(null)}),this.emit("response",e);for(let a of this[Nw])if(!a.headersSent){for(let l in e.headers){let c=t.decompress?l!=="content-encoding":!0,u=e.headers[l];c&&a.setHeader(l,u)}a.statusCode=n}}async _onResponse(e){try{await this._onResponseBase(e)}catch(t){this._beforeError(t)}}_onRequest(e){let{options:t}=this,{timeout:i,url:n}=t;vxe.default(e),this[wP]=j8.default(e,i,n);let s=t.cache?"cacheableResponse":"response";e.once(s,l=>{this._onResponse(l)}),e.once("error",l=>{var c;e.destroy(),(c=e.res)===null||c===void 0||c.removeAllListeners("end"),l=l instanceof j8.TimeoutError?new xP(l,this.timings,this):new hi(l.message,l,this),this._beforeError(l)}),this[q8]=Fxe.default(e,this,Jxe),this[Fi]=e,this.emit("uploadProgress",this.uploadProgress);let o=this[pl],a=this.redirects.length===0?this:e;Ee.default.nodeStream(o)?(o.pipe(a),o.once("error",l=>{this._beforeError(new kP(l,this))})):(this._unlockWrite(),Ee.default.undefined(o)?(this._cannotHaveBody||this._noPipe)&&(a.end(),this._lockWrite()):(this._writeRequest(o,void 0,()=>{}),a.end(),this._lockWrite())),this.emit("request",e)}async _createCacheableRequest(e,t){return new Promise((i,n)=>{Object.assign(t,Nxe.default(e)),delete t.url;let s,o=BP.get(t.cache)(t,async a=>{a._readableState.autoDestroy=!1,s&&(await s).emit("cacheableResponse",a),i(a)});t.url=e,o.once("error",n),o.once("request",async a=>{s=a,i(s)})})}async _makeRequest(){var e,t,i,n,s;let{options:o}=this,{headers:a}=o;for(let b in a)if(Ee.default.undefined(a[b]))delete a[b];else if(Ee.default.null_(a[b]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${b}\` header`);if(o.decompress&&Ee.default.undefined(a["accept-encoding"])&&(a["accept-encoding"]=Kxe?"gzip, deflate, br":"gzip, deflate"),o.cookieJar){let b=await o.cookieJar.getCookieString(o.url.toString());Ee.default.nonEmptyString(b)&&(o.headers.cookie=b)}for(let b of o.hooks.beforeRequest){let v=await b(o);if(!Ee.default.undefined(v)){o.request=()=>v;break}}o.body&&this[pl]!==o.body&&(this[pl]=o.body);let{agent:l,request:c,timeout:u,url:g}=o;if(o.dnsCache&&!("lookup"in o)&&(o.lookup=o.dnsCache.lookup),g.hostname==="unix"){let b=/(?<socketPath>.+?):(?<path>.+)/.exec(`${g.pathname}${g.search}`);if(b==null?void 0:b.groups){let{socketPath:v,path:k}=b.groups;Object.assign(o,{socketPath:v,path:k,host:""})}}let f=g.protocol==="https:",h;o.http2?h=Pxe.auto:h=f?Sxe.request:U8.request;let p=(e=o.request)!==null&&e!==void 0?e:h,m=o.cache?this._createCacheableRequest:p;l&&!o.http2&&(o.agent=l[f?"https":"http"]),o[Fi]=p,delete o.request,delete o.timeout;let y=o;if(y.shared=(t=o.cacheOptions)===null||t===void 0?void 0:t.shared,y.cacheHeuristic=(i=o.cacheOptions)===null||i===void 0?void 0:i.cacheHeuristic,y.immutableMinTimeToLive=(n=o.cacheOptions)===null||n===void 0?void 0:n.immutableMinTimeToLive,y.ignoreCargoCult=(s=o.cacheOptions)===null||s===void 0?void 0:s.ignoreCargoCult,o.dnsLookupIpVersion!==void 0)try{y.family=Y8.dnsLookupIpVersionToFamily(o.dnsLookupIpVersion)}catch(b){throw new Error("Invalid `dnsLookupIpVersion` option value")}o.https&&("rejectUnauthorized"in o.https&&(y.rejectUnauthorized=o.https.rejectUnauthorized),o.https.checkServerIdentity&&(y.checkServerIdentity=o.https.checkServerIdentity),o.https.certificateAuthority&&(y.ca=o.https.certificateAuthority),o.https.certificate&&(y.cert=o.https.certificate),o.https.key&&(y.key=o.https.key),o.https.passphrase&&(y.passphrase=o.https.passphrase),o.https.pfx&&(y.pfx=o.https.pfx));try{let b=await m(g,y);Ee.default.undefined(b)&&(b=h(g,y)),o.request=c,o.timeout=u,o.agent=l,o.https&&("rejectUnauthorized"in o.https&&delete y.rejectUnauthorized,o.https.checkServerIdentity&&delete y.checkServerIdentity,o.https.certificateAuthority&&delete y.ca,o.https.certificate&&delete y.cert,o.https.key&&delete y.key,o.https.passphrase&&delete y.passphrase,o.https.pfx&&delete y.pfx),jxe(b)?this._onRequest(b):this.writable?(this.once("finish",()=>{this._onResponse(b)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(b)}catch(b){throw b instanceof K8.CacheError?new vP(b,this):new hi(b.message,b,this)}}async _error(e){try{for(let t of this.options.hooks.beforeError)e=await t(e)}catch(t){e=new hi(t.message,t,this)}this.destroy(e)}_beforeError(e){if(this[Af])return;let{options:t}=this,i=this.retryCount+1;this[Af]=!0,e instanceof hi||(e=new hi(e.message,e,this));let n=e,{response:s}=n;(async()=>{if(s&&!s.body){s.setEncoding(this._readableState.encoding);try{s.rawBody=await Txe.default(s),s.body=s.rawBody.toString()}catch(o){}}if(this.listenerCount("retry")!==0){let o;try{let a;s&&"retry-after"in s.headers&&(a=Number(s.headers["retry-after"]),Number.isNaN(a)?(a=Date.parse(s.headers["retry-after"])-Date.now(),a<=0&&(a=1)):a*=1e3),o=await t.retry.calculateDelay({attemptCount:i,retryOptions:t.retry,error:n,retryAfter:a,computedValue:Uxe.default({attemptCount:i,retryOptions:t.retry,error:n,retryAfter:a,computedValue:0})})}catch(a){this._error(new hi(a.message,a,this));return}if(o){let a=async()=>{try{for(let l of this.options.hooks.beforeRetry)await l(this.options,n,i)}catch(l){this._error(new hi(l.message,e,this));return}this.destroyed||(this.destroy(),this.emit("retry",i,e))};this[_8]=setTimeout(a,o);return}}this._error(n)})()}_read(){this[Lw]=!0;let e=this[Fw];if(e&&!this[Af]){e.readableLength&&(this[Lw]=!1);let t;for(;(t=e.read())!==null;){this[sf]+=t.length,this[W8]=!0;let i=this.downloadProgress;i.percent<1&&this.emit("downloadProgress",i),this.push(t)}}}_write(e,t,i){let n=()=>{this._writeRequest(e,t,i)};this.requestInitialized?n():this[Ld].push(n)}_writeRequest(e,t,i){this[Fi].destroyed||(this._progressCallbacks.push(()=>{this[af]+=Buffer.byteLength(e,t);let n=this.uploadProgress;n.percent<1&&this.emit("uploadProgress",n)}),this[Fi].write(e,t,n=>{!n&&this._progressCallbacks.length>0&&this._progressCallbacks.shift()(),i(n)}))}_final(e){let t=()=>{for(;this._progressCallbacks.length!==0;)this._progressCallbacks.shift()();if(!(Fi in this)){e();return}if(this[Fi].destroyed){e();return}this[Fi].end(i=>{i||(this[of]=this[af],this.emit("uploadProgress",this.uploadProgress),this[Fi].emit("upload-complete")),e(i)})};this.requestInitialized?t():this[Ld].push(t)}_destroy(e,t){var i;this[Af]=!0,clearTimeout(this[_8]),Fi in this&&(this[wP](),((i=this[Fw])===null||i===void 0?void 0:i.complete)||this[Fi].destroy()),e!==null&&!Ee.default.undefined(e)&&!(e instanceof hi)&&(e=new hi(e.message,e,this)),t(e)}get _isAboutToError(){return this[Af]}get ip(){var e;return(e=this.socket)===null||e===void 0?void 0:e.remoteAddress}get aborted(){var e,t,i;return((t=(e=this[Fi])===null||e===void 0?void 0:e.destroyed)!==null&&t!==void 0?t:this.destroyed)&&!((i=this[z8])===null||i===void 0?void 0:i.complete)}get socket(){var e,t;return(t=(e=this[Fi])===null||e===void 0?void 0:e.socket)!==null&&t!==void 0?t:void 0}get downloadProgress(){let e;return this[nf]?e=this[sf]/this[nf]:this[nf]===this[sf]?e=1:e=0,{percent:e,transferred:this[sf],total:this[nf]}}get uploadProgress(){let e;return this[of]?e=this[af]/this[of]:this[of]===this[af]?e=1:e=0,{percent:e,transferred:this[af],total:this[of]}}get timings(){var e;return(e=this[Fi])===null||e===void 0?void 0:e.timings}get isFromCache(){return this[J8]}pipe(e,t){if(this[W8])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof IP.ServerResponse&&this[Nw].add(e),super.pipe(e,t)}unpipe(e){return e instanceof IP.ServerResponse&&this[Nw].delete(e),super.unpipe(e),this}};qt.default=bP});var Od=w(Eo=>{"use strict";var Wxe=Eo&&Eo.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),zxe=Eo&&Eo.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Wxe(e,r,t)};Object.defineProperty(Eo,"__esModule",{value:!0});Eo.CancelError=Eo.ParseError=void 0;var V8=Td(),X8=class extends V8.RequestError{constructor(e,t){let{options:i}=t.request;super(`${e.message} in "${i.url.toString()}"`,e,t.request);this.name="ParseError"}};Eo.ParseError=X8;var Z8=class extends V8.RequestError{constructor(e){super("Promise was canceled",{},e);this.name="CancelError"}get isCanceled(){return!0}};Eo.CancelError=Z8;zxe(Td(),Eo)});var e5=w(DP=>{"use strict";Object.defineProperty(DP,"__esModule",{value:!0});var $8=Od(),_xe=(r,e,t,i)=>{let{rawBody:n}=r;try{if(e==="text")return n.toString(i);if(e==="json")return n.length===0?"":t(n.toString());if(e==="buffer")return n;throw new $8.ParseError({message:`Unknown body type '${e}'`,name:"Error"},r)}catch(s){throw new $8.ParseError(s,r)}};DP.default=_xe});var RP=w(dl=>{"use strict";var Vxe=dl&&dl.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),Xxe=dl&&dl.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Vxe(e,r,t)};Object.defineProperty(dl,"__esModule",{value:!0});var Zxe=require("events"),$xe=nA(),ePe=J4(),Ow=Od(),t5=e5(),r5=Td(),tPe=lP(),rPe=dP(),i5=CP(),iPe=["request","response","redirect","uploadProgress","downloadProgress"];function n5(r){let e,t,i=new Zxe.EventEmitter,n=new ePe((o,a,l)=>{let c=u=>{let g=new r5.default(void 0,r);g.retryCount=u,g._noPipe=!0,l(()=>g.destroy()),l.shouldReject=!1,l(()=>a(new Ow.CancelError(g))),e=g,g.once("response",async p=>{var m;if(p.retryCount=u,p.request.aborted)return;let y;try{y=await rPe.default(g),p.rawBody=y}catch(T){return}if(g._isAboutToError)return;let b=((m=p.headers["content-encoding"])!==null&&m!==void 0?m:"").toLowerCase(),v=["gzip","deflate","br"].includes(b),{options:k}=g;if(v&&!k.decompress)p.body=y;else try{p.body=t5.default(p,k.responseType,k.parseJson,k.encoding)}catch(T){if(p.body=y.toString(),i5.isResponseOk(p)){g._beforeError(T);return}}try{for(let[T,Y]of k.hooks.afterResponse.entries())p=await Y(p,async q=>{let $=r5.default.normalizeArguments(void 0,te(N({},q),{retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1}),k);$.hooks.afterResponse=$.hooks.afterResponse.slice(0,T);for(let ne of $.hooks.beforeRetry)await ne($);let z=n5($);return l(()=>{z.catch(()=>{}),z.cancel()}),z})}catch(T){g._beforeError(new Ow.RequestError(T.message,T,g));return}if(!i5.isResponseOk(p)){g._beforeError(new Ow.HTTPError(p));return}t=p,o(g.options.resolveBodyOnly?p.body:p)});let f=p=>{if(n.isCanceled)return;let{options:m}=g;if(p instanceof Ow.HTTPError&&!m.throwHttpErrors){let{response:y}=p;o(g.options.resolveBodyOnly?y.body:y);return}a(p)};g.once("error",f);let h=g.options.body;g.once("retry",(p,m)=>{var y,b;if(h===((y=m.request)===null||y===void 0?void 0:y.options.body)&&$xe.default.nodeStream((b=m.request)===null||b===void 0?void 0:b.options.body)){f(m);return}c(p)}),tPe.default(g,i,iPe)};c(0)});n.on=(o,a)=>(i.on(o,a),n);let s=o=>{let a=(async()=>{await n;let{options:l}=t.request;return t5.default(t,o,l.parseJson,l.encoding)})();return Object.defineProperties(a,Object.getOwnPropertyDescriptors(n)),a};return n.json=()=>{let{headers:o}=e.options;return!e.writableFinished&&o.accept===void 0&&(o.accept="application/json"),s("json")},n.buffer=()=>s("buffer"),n.text=()=>s("text"),n}dl.default=n5;Xxe(Od(),dl)});var s5=w(FP=>{"use strict";Object.defineProperty(FP,"__esModule",{value:!0});var nPe=Od();function sPe(r,...e){let t=(async()=>{if(r instanceof nPe.RequestError)try{for(let n of e)if(n)for(let s of n)r=await s(r)}catch(n){r=n}throw r})(),i=()=>t;return t.json=i,t.text=i,t.buffer=i,t.on=i,t}FP.default=sPe});var A5=w(NP=>{"use strict";Object.defineProperty(NP,"__esModule",{value:!0});var o5=nA();function a5(r){for(let e of Object.values(r))(o5.default.plainObject(e)||o5.default.array(e))&&a5(e);return Object.freeze(r)}NP.default=a5});var c5=w(l5=>{"use strict";Object.defineProperty(l5,"__esModule",{value:!0})});var LP=w(Ms=>{"use strict";var oPe=Ms&&Ms.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),aPe=Ms&&Ms.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&oPe(e,r,t)};Object.defineProperty(Ms,"__esModule",{value:!0});Ms.defaultHandler=void 0;var u5=nA(),Us=RP(),APe=s5(),Mw=Td(),lPe=A5(),cPe={RequestError:Us.RequestError,CacheError:Us.CacheError,ReadError:Us.ReadError,HTTPError:Us.HTTPError,MaxRedirectsError:Us.MaxRedirectsError,TimeoutError:Us.TimeoutError,ParseError:Us.ParseError,CancelError:Us.CancelError,UnsupportedProtocolError:Us.UnsupportedProtocolError,UploadError:Us.UploadError},uPe=async r=>new Promise(e=>{setTimeout(e,r)}),{normalizeArguments:Uw}=Mw.default,g5=(...r)=>{let e;for(let t of r)e=Uw(void 0,t,e);return e},gPe=r=>r.isStream?new Mw.default(void 0,r):Us.default(r),fPe=r=>"defaults"in r&&"options"in r.defaults,hPe=["get","post","put","patch","head","delete"];Ms.defaultHandler=(r,e)=>e(r);var f5=(r,e)=>{if(r)for(let t of r)t(e)},h5=r=>{r._rawHandlers=r.handlers,r.handlers=r.handlers.map(i=>(n,s)=>{let o,a=i(n,l=>(o=s(l),o));if(a!==o&&!n.isStream&&o){let l=a,{then:c,catch:u,finally:g}=l;Object.setPrototypeOf(l,Object.getPrototypeOf(o)),Object.defineProperties(l,Object.getOwnPropertyDescriptors(o)),l.then=c,l.catch=u,l.finally=g}return a});let e=(i,n={},s)=>{var o,a;let l=0,c=u=>r.handlers[l++](u,l===r.handlers.length?gPe:c);if(u5.default.plainObject(i)){let u=N(N({},i),n);Mw.setNonEnumerableProperties([i,n],u),n=u,i=void 0}try{let u;try{f5(r.options.hooks.init,n),f5((o=n.hooks)===null||o===void 0?void 0:o.init,n)}catch(f){u=f}let g=Uw(i,n,s!=null?s:r.options);if(g[Mw.kIsNormalizedAlready]=!0,u)throw new Us.RequestError(u.message,u,g);return c(g)}catch(u){if(n.isStream)throw u;return APe.default(u,r.options.hooks.beforeError,(a=n.hooks)===null||a===void 0?void 0:a.beforeError)}};e.extend=(...i)=>{let n=[r.options],s=[...r._rawHandlers],o;for(let a of i)fPe(a)?(n.push(a.defaults.options),s.push(...a.defaults._rawHandlers),o=a.defaults.mutableDefaults):(n.push(a),"handlers"in a&&s.push(...a.handlers),o=a.mutableDefaults);return s=s.filter(a=>a!==Ms.defaultHandler),s.length===0&&s.push(Ms.defaultHandler),h5({options:g5(...n),handlers:s,mutableDefaults:Boolean(o)})};let t=async function*(i,n){let s=Uw(i,n,r.options);s.resolveBodyOnly=!1;let o=s.pagination;if(!u5.default.object(o))throw new TypeError("`options.pagination` must be implemented");let a=[],{countLimit:l}=o,c=0;for(;c<o.requestLimit;){c!==0&&await uPe(o.backoff);let u=await e(void 0,void 0,s),g=await o.transform(u),f=[];for(let p of g)if(o.filter(p,a,f)&&(!o.shouldContinue(p,a,f)||(yield p,o.stackAllItems&&a.push(p),f.push(p),--l<=0)))return;let h=o.paginate(u,a,f);if(h===!1)return;h===u.request.options?s=u.request.options:h!==void 0&&(s=Uw(void 0,h,s)),c++}};e.paginate=t,e.paginate.all=async(i,n)=>{let s=[];for await(let o of t(i,n))s.push(o);return s},e.paginate.each=t,e.stream=(i,n)=>e(i,te(N({},n),{isStream:!0}));for(let i of hPe)e[i]=(n,s)=>e(n,te(N({},s),{method:i})),e.stream[i]=(n,s)=>e(n,te(N({},s),{method:i,isStream:!0}));return Object.assign(e,cPe),Object.defineProperty(e,"defaults",{value:r.mutableDefaults?r:lPe.default(r),writable:r.mutableDefaults,configurable:r.mutableDefaults,enumerable:!0}),e.mergeOptions=g5,e};Ms.default=h5;aPe(c5(),Ms)});var Hw=w((oA,Kw)=>{"use strict";var pPe=oA&&oA.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),p5=oA&&oA.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&pPe(e,r,t)};Object.defineProperty(oA,"__esModule",{value:!0});var dPe=require("url"),d5=LP(),CPe={options:{method:"GET",retry:{limit:2,methods:["GET","PUT","HEAD","DELETE","OPTIONS","TRACE"],statusCodes:[408,413,429,500,502,503,504,521,522,524],errorCodes:["ETIMEDOUT","ECONNRESET","EADDRINUSE","ECONNREFUSED","EPIPE","ENOTFOUND","ENETUNREACH","EAI_AGAIN"],maxRetryAfter:void 0,calculateDelay:({computedValue:r})=>r},timeout:{},headers:{"user-agent":"got (https://github.com/sindresorhus/got)"},hooks:{init:[],beforeRequest:[],beforeRedirect:[],beforeRetry:[],beforeError:[],afterResponse:[]},cache:void 0,dnsCache:void 0,decompress:!0,throwHttpErrors:!0,followRedirect:!0,isStream:!1,responseType:"text",resolveBodyOnly:!1,maxRedirects:10,prefixUrl:"",methodRewriting:!0,ignoreInvalidCookies:!1,context:{},http2:!1,allowGetBody:!1,https:void 0,pagination:{transform:r=>r.request.options.responseType==="json"?r.body:JSON.parse(r.body),paginate:r=>{if(!Reflect.has(r.headers,"link"))return!1;let e=r.headers.link.split(","),t;for(let i of e){let n=i.split(";");if(n[1].includes("next")){t=n[0].trimStart().trim(),t=t.slice(1,-1);break}}return t?{url:new dPe.URL(t)}:!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:Infinity,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:r=>JSON.parse(r),stringifyJson:r=>JSON.stringify(r),cacheOptions:{}},handlers:[d5.defaultHandler],mutableDefaults:!1},TP=d5.default(CPe);oA.default=TP;Kw.exports=TP;Kw.exports.default=TP;Kw.exports.__esModule=!0;p5(LP(),oA);p5(RP(),oA)});var I5=w(lf=>{"use strict";var Vnt=require("net"),mPe=require("tls"),OP=require("http"),C5=require("https"),EPe=require("events"),Xnt=require("assert"),IPe=require("util");lf.httpOverHttp=yPe;lf.httpsOverHttp=wPe;lf.httpOverHttps=BPe;lf.httpsOverHttps=bPe;function yPe(r){var e=new aA(r);return e.request=OP.request,e}function wPe(r){var e=new aA(r);return e.request=OP.request,e.createSocket=m5,e.defaultPort=443,e}function BPe(r){var e=new aA(r);return e.request=C5.request,e}function bPe(r){var e=new aA(r);return e.request=C5.request,e.createSocket=m5,e.defaultPort=443,e}function aA(r){var e=this;e.options=r||{},e.proxyOptions=e.options.proxy||{},e.maxSockets=e.options.maxSockets||OP.Agent.defaultMaxSockets,e.requests=[],e.sockets=[],e.on("free",function(i,n,s,o){for(var a=E5(n,s,o),l=0,c=e.requests.length;l<c;++l){var u=e.requests[l];if(u.host===a.host&&u.port===a.port){e.requests.splice(l,1),u.request.onSocket(i);return}}i.destroy(),e.removeSocket(i)})}IPe.inherits(aA,EPe.EventEmitter);aA.prototype.addRequest=function(e,t,i,n){var s=this,o=MP({request:e},s.options,E5(t,i,n));if(s.sockets.length>=this.maxSockets){s.requests.push(o);return}s.createSocket(o,function(a){a.on("free",l),a.on("close",c),a.on("agentRemove",c),e.onSocket(a);function l(){s.emit("free",a,o)}function c(u){s.removeSocket(a),a.removeListener("free",l),a.removeListener("close",c),a.removeListener("agentRemove",c)}})};aA.prototype.createSocket=function(e,t){var i=this,n={};i.sockets.push(n);var s=MP({},i.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:!1,headers:{host:e.host+":"+e.port}});e.localAddress&&(s.localAddress=e.localAddress),s.proxyAuth&&(s.headers=s.headers||{},s.headers["Proxy-Authorization"]="Basic "+new Buffer(s.proxyAuth).toString("base64")),Cl("making CONNECT request");var o=i.request(s);o.useChunkedEncodingByDefault=!1,o.once("response",a),o.once("upgrade",l),o.once("connect",c),o.once("error",u),o.end();function a(g){g.upgrade=!0}function l(g,f,h){process.nextTick(function(){c(g,f,h)})}function c(g,f,h){if(o.removeAllListeners(),f.removeAllListeners(),g.statusCode!==200){Cl("tunneling socket could not be established, statusCode=%d",g.statusCode),f.destroy();var p=new Error("tunneling socket could not be established, statusCode="+g.statusCode);p.code="ECONNRESET",e.request.emit("error",p),i.removeSocket(n);return}if(h.length>0){Cl("got illegal response body from proxy"),f.destroy();var p=new Error("got illegal response body from proxy");p.code="ECONNRESET",e.request.emit("error",p),i.removeSocket(n);return}return Cl("tunneling connection has established"),i.sockets[i.sockets.indexOf(n)]=f,t(f)}function u(g){o.removeAllListeners(),Cl(`tunneling socket could not be established, cause=%s -`,g.message,g.stack);var f=new Error("tunneling socket could not be established, cause="+g.message);f.code="ECONNRESET",e.request.emit("error",f),i.removeSocket(n)}};aA.prototype.removeSocket=function(e){var t=this.sockets.indexOf(e);if(t!==-1){this.sockets.splice(t,1);var i=this.requests.shift();i&&this.createSocket(i,function(n){i.request.onSocket(n)})}};function m5(r,e){var t=this;aA.prototype.createSocket.call(t,r,function(i){var n=r.request.getHeader("host"),s=MP({},t.options,{socket:i,servername:n?n.replace(/:.*$/,""):r.host}),o=mPe.connect(0,s);t.sockets[t.sockets.indexOf(i)]=o,e(o)})}function E5(r,e,t){return typeof r=="string"?{host:r,port:e,localAddress:t}:r}function MP(r){for(var e=1,t=arguments.length;e<t;++e){var i=arguments[e];if(typeof i=="object")for(var n=Object.keys(i),s=0,o=n.length;s<o;++s){var a=n[s];i[a]!==void 0&&(r[a]=i[a])}}return r}var Cl;process.env.NODE_DEBUG&&/\btunnel\b/.test(process.env.NODE_DEBUG)?Cl=function(){var r=Array.prototype.slice.call(arguments);typeof r[0]=="string"?r[0]="TUNNEL: "+r[0]:r.unshift("TUNNEL:"),console.error.apply(console,r)}:Cl=function(){};lf.debug=Cl});var w5=w(($nt,y5)=>{y5.exports=I5()});var R5=w((Yw,GP)=>{var D5=Object.assign({},require("fs")),YP=function(){var r=typeof document!="undefined"&&document.currentScript?document.currentScript.src:void 0;return typeof __filename!="undefined"&&(r=r||__filename),function(e){e=e||{};var t=typeof e!="undefined"?e:{},i,n;t.ready=new Promise(function(d,E){i=d,n=E});var s={},o;for(o in t)t.hasOwnProperty(o)&&(s[o]=t[o]);var a=[],l="./this.program",c=function(d,E){throw E},u=!1,g=!0,f="";function h(d){return t.locateFile?t.locateFile(d,f):f+d}var p,m,y,b;g&&(u?f=require("path").dirname(f)+"/":f=__dirname+"/",p=function(E,I){var D=xa(E);return D?I?D:D.toString():(y||(y=D5),b||(b=require("path")),E=b.normalize(E),y.readFileSync(E,I?null:"utf8"))},m=function(E){var I=p(E,!0);return I.buffer||(I=new Uint8Array(I)),Z(I.buffer),I},process.argv.length>1&&(l=process.argv[1].replace(/\\/g,"/")),a=process.argv.slice(2),c=function(d){process.exit(d)},t.inspect=function(){return"[Emscripten Module object]"});var v=t.print||console.log.bind(console),k=t.printErr||console.warn.bind(console);for(o in s)s.hasOwnProperty(o)&&(t[o]=s[o]);s=null,t.arguments&&(a=t.arguments),t.thisProgram&&(l=t.thisProgram),t.quit&&(c=t.quit);var T=16;function Y(d,E){return E||(E=T),Math.ceil(d/E)*E}var q=0,$=function(d){q=d},z;t.wasmBinary&&(z=t.wasmBinary);var ne=t.noExitRuntime||!0;typeof WebAssembly!="object"&&vr("no native wasm support detected");function ee(d,E,I){switch(E=E||"i8",E.charAt(E.length-1)==="*"&&(E="i32"),E){case"i1":return pe[d>>0];case"i8":return pe[d>>0];case"i16":return Qe[d>>1];case"i32":return fe[d>>2];case"i64":return fe[d>>2];case"float":return Ht[d>>2];case"double":return Mt[d>>3];default:vr("invalid type for getValue: "+E)}return null}var A,oe=!1,ce;function Z(d,E){d||vr("Assertion failed: "+E)}function O(d){var E=t["_"+d];return Z(E,"Cannot call unknown function "+d+", make sure it is exported"),E}function L(d,E,I,D,M){var _={string:function(st){var yt=0;if(st!=null&&st!==0){var ke=(st.length<<2)+1;yt=B(ke),be(st,yt,ke)}return yt},array:function(st){var yt=B(st.length);return Ue(st,yt),yt}};function ie(st){return E==="string"?re(st):E==="boolean"?Boolean(st):st}var we=O(d),me=[],_e=0;if(D)for(var ot=0;ot<D.length;ot++){var Bt=_[I[ot]];Bt?(_e===0&&(_e=kE()),me[ot]=Bt(D[ot])):me[ot]=D[ot]}var ut=we.apply(null,me);return ut=ie(ut),_e!==0&&xE(_e),ut}function de(d,E,I,D){I=I||[];var M=I.every(function(ie){return ie==="number"}),_=E!=="string";return _&&M&&!D?O(d):function(){return L(d,E,I,arguments,D)}}var Be=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):void 0;function Ge(d,E,I){for(var D=E+I,M=E;d[M]&&!(M>=D);)++M;if(M-E>16&&d.subarray&&Be)return Be.decode(d.subarray(E,M));for(var _="";E<M;){var ie=d[E++];if(!(ie&128)){_+=String.fromCharCode(ie);continue}var we=d[E++]&63;if((ie&224)==192){_+=String.fromCharCode((ie&31)<<6|we);continue}var me=d[E++]&63;if((ie&240)==224?ie=(ie&15)<<12|we<<6|me:ie=(ie&7)<<18|we<<12|me<<6|d[E++]&63,ie<65536)_+=String.fromCharCode(ie);else{var _e=ie-65536;_+=String.fromCharCode(55296|_e>>10,56320|_e&1023)}}return _}function re(d,E){return d?Ge(V,d,E):""}function se(d,E,I,D){if(!(D>0))return 0;for(var M=I,_=I+D-1,ie=0;ie<d.length;++ie){var we=d.charCodeAt(ie);if(we>=55296&&we<=57343){var me=d.charCodeAt(++ie);we=65536+((we&1023)<<10)|me&1023}if(we<=127){if(I>=_)break;E[I++]=we}else if(we<=2047){if(I+1>=_)break;E[I++]=192|we>>6,E[I++]=128|we&63}else if(we<=65535){if(I+2>=_)break;E[I++]=224|we>>12,E[I++]=128|we>>6&63,E[I++]=128|we&63}else{if(I+3>=_)break;E[I++]=240|we>>18,E[I++]=128|we>>12&63,E[I++]=128|we>>6&63,E[I++]=128|we&63}}return E[I]=0,I-M}function be(d,E,I){return se(d,V,E,I)}function he(d){for(var E=0,I=0;I<d.length;++I){var D=d.charCodeAt(I);D>=55296&&D<=57343&&(D=65536+((D&1023)<<10)|d.charCodeAt(++I)&1023),D<=127?++E:D<=2047?E+=2:D<=65535?E+=3:E+=4}return E}function Fe(d){var E=he(d)+1,I=Et(E);return I&&se(d,pe,I,E),I}function Ue(d,E){pe.set(d,E)}function xe(d,E){return d%E>0&&(d+=E-d%E),d}var ve,pe,V,Qe,le,fe,gt,Ht,Mt;function Ei(d){ve=d,t.HEAP8=pe=new Int8Array(d),t.HEAP16=Qe=new Int16Array(d),t.HEAP32=fe=new Int32Array(d),t.HEAPU8=V=new Uint8Array(d),t.HEAPU16=le=new Uint16Array(d),t.HEAPU32=gt=new Uint32Array(d),t.HEAPF32=Ht=new Float32Array(d),t.HEAPF64=Mt=new Float64Array(d)}var jt=t.INITIAL_MEMORY||16777216,Qr,Oi=[],$s=[],Hn=[],jn=!1;function Sr(){if(t.preRun)for(typeof t.preRun=="function"&&(t.preRun=[t.preRun]);t.preRun.length;)Qa(t.preRun.shift());Do(Oi)}function Gn(){jn=!0,!t.noFSInit&&!S.init.initialized&&S.init(),ps.init(),Do($s)}function fs(){if(t.postRun)for(typeof t.postRun=="function"&&(t.postRun=[t.postRun]);t.postRun.length;)Lu(t.postRun.shift());Do(Hn)}function Qa(d){Oi.unshift(d)}function RA(d){$s.unshift(d)}function Lu(d){Hn.unshift(d)}var hs=0,FA=null,Sa=null;function Tu(d){return d}function NA(d){hs++,t.monitorRunDependencies&&t.monitorRunDependencies(hs)}function LA(d){if(hs--,t.monitorRunDependencies&&t.monitorRunDependencies(hs),hs==0&&(FA!==null&&(clearInterval(FA),FA=null),Sa)){var E=Sa;Sa=null,E()}}t.preloadedImages={},t.preloadedAudios={};function vr(d){t.onAbort&&t.onAbort(d),d+="",k(d),oe=!0,ce=1,d="abort("+d+"). Build with -s ASSERTIONS=1 for more info.";var E=new WebAssembly.RuntimeError(d);throw n(E),E}var _l="data:application/octet-stream;base64,";function Ou(d){return d.startsWith(_l)}var Po="data:application/octet-stream;base64,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ACgCFC0AAiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQADIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAQgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABSAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAGIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAcgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAJIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAogACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACyAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAMIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAA0gACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ADiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAPIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhRBEGo2AhQgACAAKAIIQQFrIgE2AgggAQ0ACyAAIAAoAhhB8f8DcDYCGCAAIAAoAgxB8f8DcDYCDAwBCwsgACgCEARAA0AgACgCEEEQTwRAIAAgACgCEEEQazYCECAAIAAoAhQtAAAgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AASAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQACIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAMgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAFIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAYgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AByAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAIIAAoAhhqNgIYIAAgACgCGCAAKAIMajYC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NgIYIAEoAgxCADcDICABKAIMQgA3AyggASgCDEEANgIwIAEoAgxBADYCNCABKAIMQQA2AjggASgCDEEANgI8IAEoAgxBADsBQCABKAIMQYCA2I14NgJEIAEoAgxCADcDSCABKAIMQQA7AVAgASgCDEEAOwFSIAEoAgxBADYCVAvSEwEBfyMAQbABayIDJAAgAyAANgKoASADIAE2AqQBIAMgAjYCoAEgA0EANgKQASADIAMoAqQBKAIwQQAQOjYClAEgAyADKAKkASgCOEEAEDo2ApgBAkACQAJAAkAgAygClAFBAkYEQCADKAKYAUEBRg0BCyADKAKUAUEBRgRAIAMoApgBQQJGDQELIAMoApQBQQJHDQEgAygCmAFBAkcNAQsgAygCpAEiACAALwEMQYAQcjsBDAwBCyADKAKkASIAIAAvAQxB/+8DcTsBDCADKAKUAUECRgRAIANB9eABIAMoAqQBKAIwIAMoAqgBQQhqEI4BNgKQASADKAKQAUUEQCADQX82AqwBDAMLCwJAIAMoAqABQYACcQ0AIAMoApgBQQJHDQAgA0H1xgEgAygCpAEoAjggAygCqAFBCGoQjgE2AkggAygCSEUEQCADKAKQARAjIANBfzYCrAEMAwsgAygCSCADKAKQATYCACADIAMoAkg2ApABCwsCQCADKAKkAS8BUkUEQCADKAKkASIAIAAvAQxB/v8DcTsBDAwBCyADKAKkASIAIAAvAQxBAXI7AQwLIAMgAygCpAEgAygCoAEQZUEBcToAhgEgAyADKAKgAUGACnFBgApHBH8gAy0AhgEFQQELQQFxOgCHASADAn9BASADKAKkAS8BUkGBAkYNABpBASADKAKkAS8BUkGCAkYNABogAygCpAEvAVJBgwJGC0EBcToAhQEgAy0AhwFBAXEEQCADIANBIGpCHBApNgIcIAMoAhxFBEAgAygCqAFBCGpBDkEAEBQgAygCkAEQIyADQX82AqwBDAILAkAgAygCoAFBgAJxBEACQCADKAKgAUGACHENACADKAKkASkDIEL/////D1YNACADKAKkASkDKEL/////D1gNAgsgAygCHCADKAKkASkDKBAtIAMoAhwgAygCpAEpAyAQLQwBCwJAAkAgAygCoAFBgAhxDQAgAygCpAEpAyBC/////w9WDQAgAygCpAEpAyhC/////w9WDQAgAygCpAEpA0hC/////w9YDQELIAMoAqQBKQMoQv////8PWgRAIAMoAhwgAygCpAEpAygQLQsgAygCpAEpAyBC/////w9aBEAgAygCHCADKAKkASkDIBAtCyADKAKkASkDSEL/////D1oEQCADKAIcIAMoAqQBKQNIEC0LCwsCfyMAQRBrIgAgAygCHDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIcEBYgAygCkAEQIyADQX82AqwBDAILIANBAQJ/IwBBEGsiACADKAIcNgIMAn4gACgCDC0AAEEBcQRAIAAoAgwpAxAMAQtCAAunQf//A3ELIANBIGpBgAYQVTYCjAEgAygCHBAWIAMoAowBIAMoApABNgIAIAMgAygCjAE2ApABCyADLQCFAUEBcQRAIAMgA0EVakIHECk2AhAgAygCEEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAgsgAygCEEECEB8gAygCEEG9EkECEEEgAygCECADKAKkAS8BUkH/AXEQlgEgAygCECADKAKkASgCEEH//wNxEB8CfyMAQRBrIgAgAygCEDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIQEBYgAygCkAEQIyADQX82AqwBDAILIANBgbICQQcgA0EVakGABhBVNgIMIAMoAhAQFiADKAIMIAMoApABNgIAIAMgAygCDDYCkAELIAMgA0HQAGpCLhApIgA2AkwgAEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAQsgAygCTEHxEkH2EiADKAKgAUGAAnEbQQQQQSADKAKgAUGAAnFFBEAgAygCTCADLQCGAUEBcQR/QS0FIAMoAqQBLwEIC0H//wNxEB8LIAMoAkwgAy0AhgFBAXEEf0EtBSADKAKkAS8BCgtB//8DcRAfIAMoAkwgAygCpAEvAQwQHwJAIAMtAIUBQQFxBEAgAygCTEHjABAfDAELIAMoAkwgAygCpAEoAhBB//8DcRAfCyADKAKkASgCFCADQZ4BaiADQZwBahCNASADKAJMIAMvAZ4BEB8gAygCTCADLwGcARAfAkACQCADLQCFAUEBcUUNACADKAKkASkDKEIUWg0AIAMoAkxBABAhDAELIAMoAkwgAygCpAEoAhgQIQsCQAJAIAMoAqABQYACcUGAAkcNACADKAKkASkDIEL/////D1QEQCADKAKkASkDKEL/////D1QNAQsgAygCTEF/ECEgAygCTEF/ECEMAQsCQCADKAKkASkDIEL/////D1QEQCADKAJMIAMoAqQBKQMgpxAhDAELIAMoAkxBfxAhCwJAIAMoAqQBKQMoQv////8PVARAIAMoAkwgAygCpAEpAyinECEMAQsgAygCTEF/ECELCyADKAJMIAMoAqQBKAIwEFFB//8DcRAfIAMgAygCpAEoAjQgAygCoAEQkgFB//8DcSADKAKQAUGABhCSAUH//wNxajYCiAEgAygCTCADKAKIAUH//wNxEB8gAygCoAFBgAJxRQRAIAMoAkwgAygCpAEoAjgQUUH//wNxEB8gAygCTCADKAKkASgCPEH//wNxEB8gAygCTCADKAKkAS8BQBAfIAMoAkwgAygCpAEoAkQQIQJAIAMoAqQBKQNIQv////8PVARAIAMoAkwgAygCpAEpA0inECEMAQsgAygCTEF/ECELCwJ/IwBBEGsiACADKAJMNgIMIAAoAgwtAABBAXFFCwRAIAMoAqgBQQhqQRRBABAUIAMoAkwQFiADKAKQARAjIANBfzYCrAEMAQsgAygCqAEgA0HQAGoCfiMAQRBrIgAgAygCTDYCDAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALCxA2QQBIBEAgAygCTBAWIAMoApABECMgA0F/NgKsAQwBCyADKAJMEBYgAygCpAEoAjAEQCADKAKoASADKAKkASgCMBCFAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEEQCADKAKoASADKAKQAUGABhCRAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEQIyADKAKkASgCNARAIAMoAqgBIAMoAqQBKAI0IAMoAqABEJEBQQBIBEAgA0F/NgKsAQwCCwsgAygCoAFBgAJxRQRAIAMoAqQBKAI4BEAgAygCqAEgAygCpAEoAjgQhQFBAEgEQCADQX82AqwBDAMLCwsgAyADLQCHAUEBcTYCrAELIAMoAqwBIQAgA0GwAWokACAAC+ACAQF/IwBBIGsiBCQAIAQgADsBGiAEIAE7ARggBCACNgIUIAQgAzYCECAEQRAQGCIANgIMAkAg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AAAgAygCHEHcFmogAygCDEECdGooAgAgAygCHEHYKGpqLQAASg0ADAELIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhxB3BZqIAMoAgxBAnRqKAIANgIAIAMgAygCDDYCFCADIAMoAgxBAXQ2AgwMAQsLIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhA2AgAL1xMBA38jAEEwayICJAAgAiAANgIsIAIgATYCKCACIAIoAigoAgA2AiQgAiACKAIoKAIIKAIANgIgIAIgAigCKCgCCCgCDDYCHCACQX82AhAgAigCLEEANgLQKCACKAIsQb0ENgLUKCACQQA2AhgDQCACKAIYIAIoAhxIBEACQCACKAIkIAIoAhhBAnRqLwEABEAgAiACKAIYIgE2AhAgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQAgBCAANgLQKCAAQQJ0IANqIAE2AgAgAigCGCACKAIsQdgoampBADoAAAwBCyACKAIkIAIoAhhBAnRqQQA7AQILIAIgAigCGEEBajYCGAwBCwsDQCACKAIsKALQKEECSARAAkAgAigCEEECSARAIAIgAigCEEEBaiIANgIQDAELQQAhAAsgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQEgBCABNgLQKCABQQJ0IANqIAA2AgAgAiAANgIMIAIoAiQgAigCDEECdGpBATsBACACKAIMIAIoAixB2ChqakEAOgAAIAIoAiwiACAAKAKoLUEBazYCqC0gAigCIARAIAIoAiwiACAAKAKsLSACKAIgIAIoAgxBAnRqLwECazYCrC0LDAELCyACKAIoIAIoAhA2AgQgAiACKAIsKALQKEECbTYCGANAIAIoAhhBAU4EQCACKAIsIAIoAiQgAigCGBB5IAIgAigCGEEBazYCGAwBCwsgAiACKAIcNgIMA0AgAiACKAIsKALgFjYCGCACKAIsQdwWaiEBIAIoAiwiAygC0CghACADIABBAWs2AtAoIAIoAiwgAEECdCABaigCADYC4BYgAigCLCACKAIkQQEQeSACIAIoAiwoAuAWNgIUIAIoAhghASACKAIsQdwWaiEDIAIoAiwiBCgC1ChBAWshACAEIAA2AtQoIABBAnQgA2ogATYCACACKAIUIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQQFrIQAgBCAANgLUKCAA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AQsgAigCCEEANgIAIAIoAghCADcDECACKAIIQgA3AwggAigCCEIANwMgIAIoAghCADcDGCACKAIIQQA2AiggAigCCEEAOgAsIAIoAgggAikDECACKAIMEI8BQQFxRQRAIAIoAggQJSACQQA2AhwMAQsgAiACKAIINgIcCyACKAIcIQEgAkEgaiQAIAEL1gIBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADQQxqQgQQKTYCCAJAIAMoAghFBEAgA0F/NgIcDAELA0AgAygCFARAIAMoAhQoAgQgAygCEHFBgAZxBEAgAygCCEIAECwaIAMoAgggAygCFC8BCBAfIAMoAgggAygCFC8BChAfAn8jAEEQayIAIAMoAgg2AgwgACgCDC0AAEEBcUULBEAgAygCGEEIakEUQQAQFCADKAIIEBYgA0F/NgIcDAQLIAMoAhggA0EMakIEEDZBAEgEQCADKAIIEBYgA0F/NgIcDAQLIAMoAhQvAQoEQCADKAIYIAMoAhQoAgwgAygCFC8BCq0QNkEASARAIAMoAggQFiADQX82AhwMBQsLCyADIAMoAhQoAgA2AhQMAQsLIAMoAggQFiADQQA2AhwLIAMoAhwhACADQSBqJAAgAAtoAQF/IwBBEGsiAiAANgIMIAIgATYCCCACQQA7AQYDQCACKAIMBEAgAigCDCgCBCACKAIIcUGABnEEQCACIAIoAgwvAQogAi8BBkEEamo7AQYLIAIgAigCDCgCADYCDAwBCwsgAi8BBgvwAQEBfyMAQRBrIgEkACABIAA2AgwgASABKAIMNgIIIAFBADYCBANAIAEoAgwEQAJAAkAgASgCDC8BCEH1xgFGDQAgASgCDC8BCEH14AFGDQAgASgCDC8BCEGBsgJGDQAgASgCDC8BCEEBRw0BCyABIAEoAgwoAgA2AgAgASgCCCABKAIMRgRAIAEgASgCADYCCAsgASgCDEEANgIAIAEoAgwQIyABKAIEBEAgASgCBCABKAIANgIACyABIAEoAgA2AgwMAgsgASABKAIMNgIEIAEgASgCDCgCADYCDAwBCwsgASgCCCEAIAFBEGokACAAC7IEAQF/IwBBQGoiBSQAIAUgADYCOCAFIAE7ATYgBSACNgIwIAUgAzYCLCAFIAQ2AiggBSAFKAI4IAUvATatECkiADYC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IAEoAhBB//8DRgRAIAEgASgCDDYCEAsgASgCCEH//wNGBEAgASABKAIENgIICwJAIAEoApQBQQRxRQ0AIAEoAgggASgCBEYEQCABKAIQIAEoAgxGDQELIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELAkAgASgCEEUEQCABKAIIRQ0BCyABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AyggASABKAKkARAxNwMgIAEpAyggASkDIFIEQCABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AzAgASABKAKkARAxNwOAAQJ/IwBBEGsiBSABKAKkATYCDCAFKAIMLQAAQQFxRQsEQCABKAKQAUEUQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABLQAXQQFxBEAgASgCpAEQFgsCQCABKQOAAUL///////////8AWARAIAEpA4ABIAEpA4ABIAEpAzB8WA0BCyABKAKQAUEEQRYQFCABQQA2AqwBDAELIAEpA4ABIAEpAzB8IAEpA5gBIAEpAzh8VgRAIAEoApABQRVBABAUIAFBADYCrAEMAQsCQCABKAKUAUEEcUUNACABKQOAASABKQMwfCABKQOYASABKQM4fFENACABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEpAyggASkDMEIugFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEgASkDKCABKAKQARCQASIFNgKMASAFRQRAIAFBADYCrAEMAQsgASgCjAFBAToALCABKAKMASABKQMwNwMYIAEoAowBIAEpA4ABNwMgIAEgASgCjAE2AqwBCyABKAKsASEFIAFBsAFqJAAgACAFNgJQDAELIAAoAmQgACkDMBAsGiAAKAJkIQUgACkDWCEJIAAoAmgoAhQhBiAAKAJUIQcjAEHQAGsiASQAIAEgBTYCSCABIAk3A0AgASAGNgI8IAEgBzYCOAJAIAEoAkgQMEIWVARAIAEoAjhBFUEAEBQgAUEANgJMDAELIwBBEGsiBSABKAJINgIMIAECfiAFKAIMLQAAQQFxBEAgBSgCDCkDEAwBC0IACzcDCCABKAJI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ECADQcgAEBgiADYCDAJAIABFBEAgAygCEEEBQbSbASgCABAUIANBADYCHAwBCyADKAIMIAMoAhA2AgAgAygCDCADLQAbQQFxOgAEIAMoAgwgAygCFDYCCAJAIAMoAgwoAghBAU4EQCADKAIMKAIIQQlMDQELIAMoAgxBCTYCCAsgAygCDEEAOgAMIAMoAgxBADYCMCADKAIMQQA2AjQgAygCDEEANgI4IAMgAygCDDYCHAsgAygCHCEAIANBIGokACAACzgBAX8jAEEQayIBIAA2AgwgASgCDEEANgIAIAEoAgxBADYCBCABKAIMQQA2AgggASgCDEEAOgAMC+MIAQF/IwBBQGoiAiAANgI4IAIgATYCNCACIAIoAjgoAnw2AjAgAiACKAI4KAI4IAIoAjgoAmxqNgIsIAIgAigCOCgCeDYCICACIAIoAjgoApABNgIcIAICfyACKAI4KAJsIAIoAjgoAixBhgJrSwRAIAIoAjgoAmwgAigCOCgCLEGGAmtrDAELQQALNgIYIAIgAigCOCgCQDYCFCACIAIoAjgoAjQ2AhAgAiACKAI4KAI4IAIoAjgoAmxqQYICajYCDCACIAIoAiwgAigCIEEBa2otAAA6AAsgAiACKAIsIAIoAiBqLQAAOgAKIAIoAjgoAnggAigCOCgCjAFPBEAgAiACKAIwQQJ2NgIwCyACKAIcIAIoAjgoAnRLBEAgAiACKAI4KAJ0NgIcCwNAAkAgAiACKAI4KAI4IAIoAjRqNgIoAkAgAigCKCACKAIgai0AACACLQAKRw0AIAIoAiggAigCIEEBa2otAAAgAi0AC0cNACACKAIoLQAAIAIoAiwtAABHDQAgAiACKAIoIgBBAWo2AiggAC0AASACKAIsLQABRwRADAELIAIgAigCLEECajYCLCACIAIoAihBAWo2AigDQCACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AigCf0EAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEGCAms2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEEBayIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5IQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAiwgAigCKCgCDEEFa0kEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcTYCECACKAIoQQBBACACKAIQEF0gAigCKCgCCCACKAIoKAIUQQRraiACKAIcOgAAIAIoAigoAgggAigCKCgCFEEDa2ogAigCHEEIdjoAACACKAIoKAIIIAIoAigoAhRBAmtqIAIoAhxBf3M6AAAgAigCKCgCCCACKAIoKAIUQQFraiACKAIcQX9zQQh2OgAAIAIoAigoAgAQHCACKAIYBEAgAigCGCACKAIcSwRAIAIgAigCHDYCGAsgAigCKCgCACgCDCACKAIoKAI4IAIoAigoAlxqIAIoAhgQGRogAigCKCgCACIAIAIoAhggACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCGGs2AhAgAigCKCgCACIAIAIoAhggACgCFGo2AhQgAigCKCIAIAIoAhggACgCXGo2AlwgAiACKAIcIAIoAhhrNgIcCyACKAIcBEAgAigCKCgCACACKAIoKAIAKAIMIAIoAhwQdhogAigCKCgCACIAIAIoAhwgACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCHGs2AhAgAigCKCgCACIAIAIoAhwgACgCFGo2AhQLIAIoAhBFDQELCyACIAIoAgwgAigCKCgCACgCBGs2AgwgAigCDARAAkAgAigCDCACKAIoKAIsTwRAIAIoAihBAjYCsC0gAigCKCgCOCACKAIoKAIAKAIAIAIoAigoAixrIAIoAigoAiwQGRogAigCKCACKAIoKAIsNgJsDAELIAIoAgwgAigCKCgCPCACKAIoKAJsa08EQCACKAIoIgAgACgCbCACKAIoKAIsazYCbCACKAIoKAI4IAIoAigoAjggAigCKCgCLGogAigCKCgCbBAZGiACKAIoKAKwLUECSQRAIAIoAigiACAAKAKwLUEBajYCsC0LCyACKAIoKAI4IAIoAigoAmxqIAIoAigoAgAoAgAgAigCDGsgAigCDBAZGiACKAIoIgAgAigCDCAAKAJsajYCbAsgAigCKCACKAIoKAJsNgJcIAIoAigiAQJ/IAIoAgwgAigCKCgCLCACKAIoKAK0LWtLBEAgAigCKCgCLCACKAIoKAK0LWsMAQsgAigCDAsgASgCtC1qNgK0LQsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCwJAIAIoAhAEQCACQQM2AiwMAQsCQCACKAIkRQ0AIAIoAiRBBEYNACACKAIoKAIAKAIEDQAgAigCKCgCbCACKAIoKAJcRw0AIAJBATYCLAwBCyACIAIoAigoAjwgAigCKCgCbGtBAWs2AhQCQCACKAIoKAIAKAIEIAIoAhRNDQAgAigCKCgCXCACKAIoKAIsSA0AIAIoAigiACAAKAJcIAIoAigoAixrNgJcIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBkaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsgAiACKAIoKAIsIAIoAhRqNgIUCyACKAIUIAIoAigoAgAoAgRLBEAgAiACKAIoKAIAKAIENgIUCyACKAIUBEAgAigCKCgCACACKAIoKAI4IAIoAigoAmxqIAIoAhQQdhogAigCKCIAIAIoAhQgACgCbGo2AmwLIAIoAigoAsAtIAIoAigoAmxJBEAgAigCKCACKAIoKAJsNgLALQsgAiACKAIoKAK8LUEqakEDdTYCFCACIAIoAigoAgwgAigCFGtB//8DSwR/Qf//AwUgAigCKCgCDCACKAIUaws2AhQgAgJ/IAIoAhQgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAhQLNgIgIAIgAigCKCgCbCACKAIoKAJcazYCGAJAIAIoAhggAigCIEkEQCACKAIYRQRAIAIoAiRBBEcNAgsgAigCJEUNASACKAIoKAIAKAIEDQEgAigCGCACKAIUSw0BCyACAn8gAigCGCACKAIUSwRAIAIoAhQMAQsgAigCGAs2AhwgAgJ/QQAgAigCJEEERw0AGkEAIAIoAigoAgAoAgQNABogAigCHCACKAIYRgtBAXE2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBdIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHAsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHgEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIcKAJABEAgASgCCCgCKCABKAIIKAIcKAJAIAEoAggoAiQRBAALIAEoAggoAhwoAjgEQCABKAIIKAIoIAEoAggoAhwoAjggASgCCCgCJBEEAAsgASgCCCgCKCABKAIIKAIcIAEoAggoAiQRBAAgASgCCEEANgIcIAFBfUEAIAEoAgRB8QBGGzYCDAsgASgCDCEAIAFBEGokACAAC+sXAQJ/IwBB8ABrIgMgADYCbCADIAE2AmggAyACNgJkIANBfzYCXCADIAMoAmgvAQI2AlQgA0EANgJQIANBBzYCTCADQQQ2AkggAygCVEUEQCADQYoBNgJMIANBAzYCSAsgA0EANgJgA0AgAygCYCADKAJkSkUEQCADIAMoAlQ2AlggAyADKAJoIAMoAmBBAWpBAnRqLwECNgJUIAMgAygCUEEBaiIANgJQAkACQCADKAJMIABMDQAgAygCWCADKAJURw0ADAELAkAgAygCUCADKAJISARAA0AgAyADKAJsQfwUaiADKAJYQQJ0ai8BAjYCRAJAIAMoAmwoArwtQRAgAygCRGtKBEAgAyADKAJsQfwUaiADKAJYQQJ0ai8BADYCQCADKAJsIgAgAC8BuC0gAygCQEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAJAQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCREEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsQfwUaiADKAJYQQJ0ai8BACADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCRCAAKAK8LWo2ArwtCyADIAMoAlBBAWsiADYCUCAADQALDAELAkAgAygCWARAIAMoAlggAygCXEcEQCADIAMoAmxB/BRqIAMoAlhBAnRqLwECNgI8AkAgAygCbCgCvC1BECADKAI8a0oEQCADIAMoAmxB/BRqIAMoAlhBAnRqLwEANgI4IAMoAmwiACAALwG4LSADKAI4Qf//A3EgAygCbCgCvC10cjsBuC0gAygCbC8BuC1B/wFxIQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbC8BuC1BCHYhASADKAJsKAIIIQIgAygCbCIEKAIUIQAgBCAAQQFqNgIUIAAgAmogAToAACADKAJsIAMoAjhB//8DcUEQIAMoAmwoArwta3U7AbgtIAMoAmwiACAAKAK8LSADKAI8QRBrajYCvC0MAQsgAygCbCIAIAAvAbgtIAMoAmxB/BRqIAMoAlhBAnRqLwEAIAMoAmwoArwtdHI7AbgtIAMoAmwiACADKAI8IAAoArwtajYCvC0LIAMgAygCUEEBazYCUAsgAyADKAJsLwG+FTYCNAJAIAMoAmwoArwtQRAgAygCNGtKBEAgAyADKAJsLwG8FTYCMCADKAJsIgAgAC8BuC0gAygCMEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIwQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCNEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwG8FSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCNCAAKAK8LWo2ArwtCyADQQI2AiwCQCADKAJsKAK8LUEQIAMoAixrSgRAIAMgAygCUEEDazYCKCADKAJsIgAgAC8BuC0gAygCKEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIoQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCLEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQNrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAiwgACgCvC1qNgK8LQsMAQsCQCADKAJQQQpMBEAgAyADKAJsLwHCFTYCJAJAIAMoAmwoArwtQRAgAygCJGtKBEAgAyADKAJsLwHAFTYCICADKAJsIgAgAC8BuC0gAygCIEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIgQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCJEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwHAFSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCJCAAKAK8LWo2ArwtCyADQQM2AhwCQCADKAJsKAK8LUEQIAMoAhxrSgRAIAMgAygCUEEDazYCGCADKAJsIgAgAC8BuC0gAygCGEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIYQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCHEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQNrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAhwgACgCvC1qNgK8LQsMAQsgAyADKAJsLwHGFTYCFAJAIAMoAmwoArwtQRAgAygCFGtKBEAgAyADKAJsLwHEFTYCECADKAJsIgAgAC8BuC0gAygCEEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIQQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCFEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJsLwHEFSADKAJsKAK8LXRyOwG4LSADKAJsIgAgAygCFCAAKAK8LWo2ArwtCyADQQc2AgwCQCADKAJsKAK8LUEQIAMoAgxrSgRAIAMgAygCUEELazYCCCADKAJsIgAgAC8BuC0gAygCCEH//wNxIAMoAmwoArwtdHI7AbgtIAMoAmwvAbgtQf8BcSEBIAMoAmwoAgghAiADKAJsIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAmwvAbgtQQh2IQEgAygCbCgCCCECIAMoAmwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCbCADKAIIQf//A3FBECADKAJsKAK8LWt1OwG4LSADKAJsIgAgACgCvC0gAygCDEEQa2o2ArwtDAELIAMoAmwiACAALwG4LSADKAJQQQtrQf//A3EgAygCbCgCvC10cjsBuC0gAygCbCIAIAMoAgwgACgCvC1qNgK8LQsLCwsgA0EANgJQIAMgAygCWDYCXAJAIAMoAlRFBEAgA0GKATYCTCADQQM2AkgMAQsCQCADKAJYIAMoAlRGBEAgA0EGNgJMIANBAzYCSAwBCyADQQc2AkwgA0EENgJICwsLIAMgAygCYEEBajYCYAwBCwsLkQQBAX8jAEEwayIDIAA2AiwgAyABNgIoIAMgAjYCJCADQX82AhwgAyADKAIoLwECNgIUIANBADYCECADQQc2AgwgA0EENgIIIAMoAhRFBEAgA0GKATYCDCADQQM2AggLIAMoAiggAygCJEEBakECdGpB//8DOwECIANBADYCIANAIAMoAiAgAygCJEpFBEAgAyADKAIUNgIYIAMgAygCKCADKAIgQQFqQQJ0ai8BAjYCFCADIAMoAhBBAWoiADYCEAJAAkAgAygCDCAATA0AIAMoAhggAygCFEcNAAwBCwJAIAMoAhAgAygCCEgEQCADKAIsQfwUaiADKAIYQQJ0aiIAIAMoAhAgAC8BAGo7AQAMAQsCQCADKAIYBEAgAygCGCADKAIcRwRAIAMoAiwgAygCGEECdGpB/BRqIgAgAC8BAEEBajsBAAsgAygCLCIAIABBvBVqLwEAQQFqOwG8FQwBCwJAIAMoAhBBCkwEQCADKAIsIgAgAEHAFWovAQBBAWo7AcAVDAELIAMoAiwiACAAQcQVai8BAEEBajsBxBULCwsgA0EANgIQIAMgAygCGDYCHAJAIAMoAhRFBEAgA0GKATYCDCADQQM2AggMAQsCQCADKAIYIAMoAhRGBEAgA0EGNgIMIANBAzYCCAwBCyADQQc2AgwgA0EENgIICwsLIAMgAygCIEEBajYCIAwBCwsLpxIBAn8jAEHQAGsiAyAANgJMIAMgATYCSCADIAI2AkQgA0EANgI4IAMoAkwoAqAtBEADQCADIAMoAkwoAqQtIAMoAjhBAXRqLwEANgJAIAMoAkwoApgtIQAgAyADKAI4IgFBAWo2AjggAyAAIAFqLQAANgI8AkAgAygCQEUEQCADIAMoAkggAygCPEECdGovAQI2AiwCQCADKAJMKAK8LUEQIAMoAixrSgRAIAMgAygCSCADKAI8QQJ0ai8BADYCKCADKAJMIgAgAC8BuC0gAygCKEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIoQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCLEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJIIAMoAjxBAnRqLwEAIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIsIAAoArwtajYCvC0LDAELIAMgAygCPC0A0F02AjQgAyADKAJIIAMoAjRBgQJqQQJ0ai8BAjYCJAJAIAMoAkwoArwtQRAgAygCJGtKBEAgAyADKAJIIAMoAjRBgQJqQQJ0ai8BADYCICADKAJMIgAgAC8BuC0gAygCIEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIgQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCJEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJIIAMoAjRBgQJqQQJ0ai8BACADKAJMKAK8LXRyOwG4LSADKAJMIgAgAygCJCAAKAK8LWo2ArwtCyADIAMoAjRBAnRBkOoAaigCADYCMCADKAIwBEAgAyADKAI8IAMoAjRBAnRBgO0AaigCAGs2AjwgAyADKAIwNgIcAkAgAygCTCgCvC1BECADKAIca0oEQCADIAMoAjw2AhggAygCTCIAIAAvAbgtIAMoAhhB//8DcSADKAJMKAK8LXRyOwG4LSADKAJMLwG4LUH/AXEhASADKAJMKAIIIQIgAygCTCIEKAIUIQAgBCAAQQFqNgIUIAAgAmogAToAACADKAJMLwG4LUEIdiEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwgAygCGEH//wNxQRAgAygCTCgCvC1rdTsBuC0gAygCTCIAIAAoArwtIAMoAhxBEGtqNgK8LQwBCyADKAJMIgAgAC8BuC0gAygCPEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIcIAAoArwtajYCvC0LCyADIAMoAkBBAWs2AkAgAwJ/IAMoAkBBgAJJBEAgAygCQC0A0FkMAQsgAygCQEEHdkGAAmotANBZCzYCNCADIAMoAkQgAygCNEECdGovAQI2AhQCQCADKAJMKAK8LUEQIAMoAhRrSgRAIAMgAygCRCADKAI0QQJ0ai8BADYCECADKAJMIgAgAC8BuC0gAygCEEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIQQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCFEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJEIAMoAjRBAnRqLwEAIAMoAkwoArwtdHI7AbgtIAMoAkwiACADKAIUIAAoArwtajYCvC0LIAMgAygCNEECdEGQ6wBqKAIANgIwIAMoAjAEQCADIAMoAkAgAygCNEECdEGA7gBqKAIAazYCQCADIAMoAjA2AgwCQCADKAJMKAK8LUEQIAMoAgxrSgRAIAMgAygCQDYCCCADKAJMIgAgAC8BuC0gAygCCEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIIQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCDEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJAQf//A3EgAygCTCgCvC10cjsBuC0gAygCTCIAIAMoAgwgACgCvC1qNgK8LQsLCyADKAI4IAMoAkwoAqAtSQ0ACwsgAyADKAJILwGCCDYCBAJAIAMoAkwoArwtQRAgAygCBGtKBEAgAyADKAJILwGACDYCACADKAJMIgAgAC8BuC0gAygCAEH//wNxIAMoAkwoArwtdHI7AbgtIAMoAkwvAbgtQf8BcSEBIAMoAkwoAgghAiADKAJMIgQoAhQhACAEIABBAWo2AhQgACACaiABOgAAIAMoAkwvAbgtQQh2IQEgAygCTCgCCCECIAMoAkwiBCgCFCEAIAQgAEEBajYCFCAAIAJqIAE6AAAgAygCTCADKAIAQf//A3FBECADKAJMKAK8LWt1OwG4LSADKAJMIgAgACgCvC0gAygCBEEQa2o2ArwtDAELIAMoAkwiACAALwG4LSADKAJILwGACCADKAJMKAK8LXRyOwG4LSADKAJMIgAgAygCBCAAKAK8LWo2ArwtCwuXAgEEfyMAQRBrIgEgADYCDAJAIAEoAgwoArwtQRBGBEAgASgCDC8BuC1B/wFxIQIgASgCDCgCCCEDIAEoAgwiBCgCFCEAIAQgAEEBajYCFCAAIANqIAI6AAAgASgCDC8BuC1BCHYhAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIMQQA7AbgtIAEoAgxBADYCvC0MAQsgASgCDCgCvC1BCE4EQCABKAIMLwG4LSECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAAIAEoAgwiACAALwG4LUEIdjsBuC0gASgCDCIAIAAoArwtQQhrNgK8LQsLC+8BAQR/IwBBEGsiASAANgIMAkAgASgCDCgCvC1BCEoEQCABKAIMLwG4LUH/AXEhAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAACABKAIMLwG4LUEIdiECIAEoAgwoAgghAyABKAIMIgQoAhQhACAEIABBAWo2AhQgACADaiACOgAADAELIAEoAgwoArwtQQBKBEAgASgCDC8BuC0hAiABKAIMKAIIIQMgASgCDCIEKAIUIQAgBCAAQQFqNgIUIAAgA2ogAjoAAAsLIAEoAgxBADsBuC0gASgCDEEANgK8LQv8AQEBfyMAQRBrIgEgADYCDCABQQA2AggDQCABKAIIQZ4CTkUEQCABKAIMQZQBaiABKAIIQQJ0akEAOwEAIAEgASgCCEEBajYCCAwBCwsgAUEANgIIA0AgASgCCEEeTkUEQCABKAIMQYgTaiABKAIIQQJ0akEAOwEAIAEgASgCCEEBajYCCAwBCwsgAUEANgIIA0AgASgCCEETTkUEQCABKAIMQfwUaiABKAIIQQJ0akEAOwEAIAEgASgCCEEBajYCCAwBCwsgASgCDEEBOwGUCSABKAIMQQA2AqwtIAEoAgxBADYCqC0gASgCDEEANgKwLSABKAIMQQA2AqAtCyIBAX8jAEEQayIBJAAgASAANgIMIAEoAgwQFSABQRBqJAAL6QEBAX8jAEEwayICIAA2AiQgAiABNwMYIAJCADcDECACIAIoAiQpAwhCAX03AwgCQANAIAIpAxAgAikDCFQEQCACIAIpAxAgAikDCCACKQMQfUIBiHw3AwACQCACKAIkKAIEIAIpAwCnQQN0aikDACACKQMYVgRAIAIgAikDAEIBfTcDCAwBCwJAIAIpAwAgAigCJCkDCFIEQCACKAIkKAIEIAIpAwBCAXynQQN0aikDACACKQMYWA0BCyACIAIpAwA3AygMBAsgAiACKQMAQgF8NwMQCwwBCwsgAiACKQMQNwMoCyACKQMoC6cBAQF/IwBBMGsiBCQAIAQgADYCKCAEIAE2AiQgBCACNwMYIAQgAzYCFCAEIAQoAigpAzggBCgCKCkDMCAEKAIkIAQpAxggBCgCFBCIATcDCAJAIAQpAwhCAFMEQCAEQX82AiwMAQsgBCgCKCAEKQMINwM4IAQoAiggBCgCKCkDOBDAASECIAQoAiggAjcDQCAEQQA2AiwLIAQoAiwhACAEQTBqJAAgAAvrAQEBfyMAQSBrIgMkACADIAA2AhggAyABNwMQIAMgAjYCDAJAIAMpAxAgAygCGCkDEFQEQCADQQE6AB8MAQsgAyADKAIYKAIAIAMpAxBCBIanEE4iADYCCCAARQRAIAMoAgxBDkEAEBQgA0EAOgAfDAELIAMoAhggAygCCDYCACADIAMoAhgoAgQgAykDEEIBfEIDhqcQTiIANgIEIABFBEAgAygCDEEOQQAQFCADQQA6AB8MAQsgAygCGCADKAIENgIEIAMoAhggAykDEDcDECADQQE6AB8LIAMtAB9BAXEhACADQSBqJAAgAAvOAgEBfyMAQTBrIgQkACAEIAA2AiggBCABNwMgIAQgAjYCHCAEIAM2AhgCQAJAIAQoAigNACAEKQMgUA0AIAQoAhhBEkEAEBQgBEEANgIsDAELIAQgBCgCKCAEKQMgIAQoAhwgBCgCGBBMIgA2AgwgAEUEQCAEQQA2AiwMAQsgBEEYEBgiADYCFCAARQRAIAQoAhhBDkEAEBQgBCgCDBAyIARBADYCLAwBCyAEKAIUIAQoAgw2AhAgBCgCFEEANgIUQQAQASEAIAQoAhQgADYCDCMAQRBrIgAgBCgCFDYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCAEQQIgBCgCFCAEKAIYEIMBIgA2AhAgAEUEQCAEKAIUKAIQEDIgBCgCFBAVIARBADYCLAwBCyAEIAQoAhA2AiwLIAQoAiwhACAEQTBqJAAgAAupAQEBfyMAQTBrIgQkACAEIAA2AiggBCABNwMgIAQgAjYCHCAEIAM2AhgCQCAEKAIoRQRAIAQpAyBCAFIEQCAEKAIYQRJBABAUIARBADYCLAwCCyAEQQBCACAEKAIcIAQoAhgQwwE2AiwMAQsgBCAEKAIoNgIIIAQgBCkDIDcDECAEIARBCGpCASAEKAIcIAQoAhgQwwE2AiwLIAQoAiwhACAEQTBqJAAgAAtGAQF/IwBBIGsiAyQAIAMgADYCHCADIAE3AxAgAyACNgIMIAMoAhwgAykDECADKAIMIAMoAhxBCGoQTSEAIANBIGokACAAC4sMAQZ/IAAgAWohBQJAAkAgACgCBCICQQFxDQAgAkEDcUUNASAAKAIAIgIgAWohAQJAIAAgAmsiAEH4mwEoAgBHBEAgAkH/AU0EQCAAKAIIIgQgAkEDdiICQQN0QYycAWpGGiAAKAIMIgMgBEcNAkHkmwFB5JsBKAIAQX4gAndxNgIADAMLIAAoAhghBgJAIAAgACgCDCIDRwRAIAAoAggiAkH0mwEoAgBJGiACIAM2AgwgAyACNgIIDAELAkAgAEEUaiICKAIAIgQNACAAQRBqIgIoAgAiBA0AQQAhAwwBCwNAIAIhByAEIgNBFGoiAigCACIEDQAgA0EQaiECIAMoAhAiBA0ACyAHQQA2AgALIAZFDQICQCAAIAAoAhwiBEECdEGUngFqIgIoAgBGBEAgAiADNgIAIAMNAUHomwFB6JsBKAIAQX4gBHdxNgIADAQLIAZBEEEUIAYoAhAgAEYbaiADNgIAIANFDQMLIAMgBjYCGCAAKAIQIgIEQCADIAI2AhAgAiADNgIYCyAAKAIUIgJFDQIgAyACNgIUIAIgAzYCGAwCCyAFKAIEIgJBA3FBA0cNAUHsmwEgATYCACAFIAJBfnE2AgQgACABQQFyNgIEIAUgATYCAA8LIAQgAzYCDCADIAQ2AggLAkAgBSgCBCICQQJxRQRAIAVB/JsBKAIARgRAQfybASAANgIAQfCbAUHwmwEoAgAgAWoiATYCACAAIAFBAXI2AgQgAEH4mwEoAgBHDQNB7JsBQQA2AgBB+JsBQQA2AgAPCyAFQfibASgCAEYEQEH4mwEgADYCAEHsmwFB7JsBKAIAIAFqIgE2AgAgACABQQFyNgIEIAAgAWogATYCAA8LIAJBeHEgAWohAQJAIAJB/wFNBEAgBSgCCCIEIAJBA3YiAkEDdEGMnAFqRhogBCAFKAIMIgNGBEBB5JsBQeSbASgCAEF+IAJ3cTYCAAwCCyAEIAM2AgwgAyAENgIIDAELIAUoAhghBgJAIAUgBSgCDCIDRwRAIAUoAggiAkH0mwEoAgBJGiACIAM2AgwgAyACNgIIDAELAkAgBUEUaiIEKAIAIgINACAFQRBqIgQoAgAiAg0AQQAhAwwBCwNAIAQhByACIgNBFGoiBCgCACICDQAgA0EQaiEEIAMoAhAiAg0ACyAHQQA2AgALIAZFDQACQCAFIAUoAhwiBEECdEGUngFqIgIoAgBGBEAgAiADNgIAIAMNAUHomwFB6JsBKAIAQX4gBHdxNgIADAILIAZBEEEUIAYoAhAgBUYbaiADNgIAIANFDQELIAMgBjYCGCAFKAIQIgIEQCADIAI2AhAgAiADNgIYCyAFKAIUIgJFDQAgAyACNgIUIAIgAzYCGAsgACABQQFyNgIEIAAgAWogATYCACAAQfibASgCAEcNAUHsmwEgATYCAA8LIAUgAkF+cTYCBCAAIAFBAXI2AgQgACABaiABNgIACyABQf8BTQRAIAFBA3YiAkEDdEGMnAFqIQECf0HkmwEoAgAiA0EBIAJ0IgJxRQRAQeSbASACIANyNgIAIAEMAQsgASgCCAshAiABIAA2AgggAiAANgIMIAAgATYCDCAAIAI2AggPC0EfIQIgAEIANwIQIAFB////B00EQCABQQh2IgIgAkGA/j9qQRB2QQhxIgR0IgIgAkGA4B9qQRB2QQRxIgN0IgIgAkGAgA9qQRB2QQJxIgJ0QQ92IAMgBHIgAnJrIgJBAXQgASACQRVqdkEBcXJBHGohAgsgACACNgIcIAJBAnRBlJ4BaiEHAkACQEHomwEoAgAiBEEBIAJ0IgNxRQRAQeibASADIARyNgIAIAcgADYCACAAIAc2AhgMAQsgAUEAQRkgAkEBdmsgAkEfRht0IQIgBygCACEDA0AgAyIEKAIEQXhxIAFGDQIgAkEddiEDIAJBAXQhAiAEIANBBHFqIgdBEGooAgAiAw0ACyAHIAA2AhAgACAENgIYCyAAIAA2AgwgACAANgIIDwsgBCgCCCIBIAA2AgwgBCAANgIIIABBADYCGCAAIAQ2AgwgACABNgIICwsGAEG0mwELtQkBAX8jAEHgwABrIgUkACAFIAA2AtRAIAUgATYC0EAgBSACNgLMQCAFIAM3A8BAIAUgBDYCvEAgBSAFKALQQDYCuEACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBSgCvEAOEQMEAAYBAgUJCgoKCgoKCAoHCgsgBUIANwPYQAwKCyAFIAUoArhAQeQAaiAFKALMQCAFKQPAQBBDNwPYQAwJCyAFKAK4QBAVIAVCADcD2EAMCAsgBSgCuEAoAhAEQCAFIAUoArhAKAIQIAUoArhAKQMYIAUoArhAQeQAahBgIgM3A5hAIANQBEAgBUJ/NwPYQAwJCyAFKAK4QCkDCCAFKAK4QCkDCCAFKQOYQHxWBEAgBSgCuEBB5ABqQRVBABAUIAVCfzcD2EAMCQsgBSgCuEAiACAFKQOYQCAAKQMAfDcDACAFKAK4QCIAIAUpA5hAIAApAwh8NwMIIAUoArhAQQA2AhALIAUoArhALQB4QQFxRQRAIAVCADcDqEADQCAFKQOoQCAFKAK4QCkDAFQEQCAFIAUoArhAKQMAIAUpA6hAfUKAwABWBH5CgMAABSAFKAK4QCkDACAFKQOoQH0LNwOgQCAFIAUoAtRAIAVBEGogBSkDoEAQKyIDNwOwQCADQgBTBEAgBSgCuEBB5ABqIAUoAtRAEBcgBUJ/NwPYQAwLCyAFKQOwQFAEQCAFKAK4QEHkAGpBEUEAEBQgBUJ/NwPYQAwLBSAFIAUpA7BAIAUpA6hAfDcDqEAMAgsACwsLIAUoArhAIAUoArhAKQMANwMgIAVCADcD2EAMBwsgBSkDwEAgBSgCuEApAwggBSgCuEApAyB9VgRAIAUgBSgCuEApAwggBSgCuEApAyB9NwPAQAsgBSkDwEBQBEAgBUIANwPYQAwHCyAFKAK4QC0AeEEBcQRAIAUoAtRAIAUoArhAKQMgQQAQJ0EASARAIAUoArhAQeQAaiAFKALUQBAXIAVCfzcD2EAMCAsLIAUgBSgC1EAgBSgCzEAgBSkDwEAQKyIDNwOwQCADQgBTBEAgBSgCuEBB5ABqQRFBABAUIAVCfzcD2EAMBwsgBSgCuEAiACAFKQOwQCAAKQMgfDcDICAFKQOwQFAEQCAFKAK4QCkDICAFKAK4QCkDCFQEQCAFKAK4QEHkAGpBEUEAEBQgBUJ/NwPYQAwICwsgBSAFKQOwQDcD2EAMBgsgBSAFKAK4QCkDICAFKAK4QCkDAH0gBSgCuEApAwggBSgCuEApAwB9IAUoAsxAIAUpA8BAIAUoArhAQeQAahCIATcDCCAFKQMIQgBTBEAgBUJ/NwPYQAwGCyAFKAK4QCAFKQMIIAUoArhAKQMAfDcDICAFQgA3A9hADAULIAUgBSgCzEA2AgQgBSgCBCAFKAK4QEEoaiAFKAK4QEHkAGoQhAFBAEgEQCAFQn83A9hADAULIAVCADcD2EAMBAsgBSAFKAK4QCwAYKw3A9hADAMLIAUgBSgCuEApA3A3A9hADAILIAUgBSgCuEApAyAgBSgCuEApAwB9NwPYQAwBCyAFKAK4QEHkAGpBHEEAEBQgBUJ/NwPYQAsgBSkD2EAhAyAFQeDAAGokACADCwgAQQFBDBB/CyIBAX8jAEEQayIBIAA2AgwgASgCDCIAIAAoAjBBAWo2AjALBwAgACgCLAsHACAAKAIoCxgBAX8jAEEQayIBIAA2AgwgASgCDEEMagsHACAAKAIYCwcAIAAoAhALBwAgACgCCAtFAEGgmwFCADcDAEGYmwFCADcDAEGQmwFCADcDAEGImwFCADcDAEGAmwFCADcDAEH4mgFCADcDAEHwmgFCADcDAEHwmgELFAAgACABrSACrUIghoQgAyAEEH4LEwEBfiAAEEkiAUIgiKcQACABpwsVACAAIAGtIAKtQiCGhCADIAQQxAELFAAgACABIAKtIAOtQiCGhCAEEH0LrQQBAX8jAEEgayIFJAAgBSAANgIYIAUgAa0gAq1CIIaENwMQIAUgAzYCDCAFIAQ2AggCQAJAIAUpAxAgBSgCGCkDMFQEQCAFKAIIQQlNDQELIAUoAhhBCGpBEkEAEBQgBUF/NgIcDAELIAUoAhgoAhhBAnEEQCAFKAIYQQhqQRlBABAUIAVBfzYCHAwBCwJ/IAUoAgwhASMAQRBrIgAkACAAIAE2AgggAEEBOgAHAkAgACgCCEUEQCAAQQE6AA8MAQsgACAAKAIIIAAtAAdBAXEQswFBAEc6AA8LIAAtAA9BAXEhASAAQRBqJAAgAUULBEAgBSgCGEEIakEQQQAQFCAFQX82AhwMAQsgBSAFKAIYKAJAIAUpAxCnQQR0ajYCBCAFIAUoAgQoAgAEfyAFKAIEKAIAKAIQBUF/CzYCAAJAIAUoAgwgBSgCAEYEQCAFKAIEKAIEBEAgBSgCBCgCBCIAIAAoAgBBfnE2AgAgBSgCBCgCBEEAOwFQIAUoAgQoAgQoAgBFBEAgBSgCBCgCBBA3IAUoAgRBADYCBAsLDAELIAUoAgQoAgRFBEAgBSgCBCgCABBAIQAgBSgCBCAANgIEIABFBEAgBSgCGEEIakEOQQAQFCAFQX82AhwMAwsLIAUoAgQoAgQgBSgCDDYCECAFKAIEKAIEIAUoAgg7AVAgBSgCBCgCBCIAIAAoAgBBAXI2AgALIAVBADYCHAsgBSgCHCEAIAVBIGokACAACxcBAX4gACABIAIQciIDQiCIpxAAIAOnCx8BAX4gACABIAKtIAOtQiCGhBArIgRCIIinEAAgBKcLrgECAX8BfgJ/IwBBIGsiAiAANgIUIAIgATYCEAJAIAIoAhRFBEAgAkJ/NwMYDAELIAIoAhBBCHEEQCACIAIoAhQpAzA3AwgDQCACKQMIQgBSBH8gAigCFCgCQCACKQMIQgF9p0EEdGooAgAFQQELRQRAIAIgAikDCEIBfTcDCAwBCwsgAiACKQMINwMYDAELIAIgAigCFCkDMDcDGAsgAikDGCIDQiCIpwsQACADpwsTACAAIAGtIAKtQiCGhCADEMUBC4gCAgF/AX4CfyMAQSBrIgQkACAEIAA2AhQgBCABNgIQIAQgAq0gA61CIIaENwMIAkAgBCgCFEUEQCAEQn83AxgMAQsgBCgCFCgCBARAIARCfzcDGAwBCyAEKQMIQv///////////wBWBEAgBCgCFEEEakESQQAQFCAEQn83AxgMAQsCQCAEKAIULQAQQQFxRQRAIAQpAwhQRQ0BCyAEQgA3AxgMAQsgBCAEKAIUKAIUIAQoAhAgBCkDCBArIgU3AwAgBUIAUwRAIAQoAhRBBGogBCgCFCgCFBAXIARCfzcDGAwBCyAEIAQpAwA3AxgLIAQpAxghBSAEQSBqJAAgBUIgiKcLEAAgBacLTwEBfyMAQSBrIgQkACAEIAA2AhwgBCABrSACrUIghoQ3AxAgBCADNgIMIAQoAhwgBCkDECAEKAIMIAQoAhwoAhwQrQEhACAEQSBqJAAgAAvZAwEBfyMAQSBrIgUkACAFIAA2AhggBSABrSACrUIghoQ3AxAgBSADNgIMIAUgBDYCCAJAIAUoAhggBSkDEEEAQQAQP0UEQCAFQX82AhwMAQsgBSgCGCgCGEECcQRAIAUoAhhBCGpBGUEAEBQgBUF/NgIcDAELIAUoAhgoAkAgBSkDEKdBBHRqKAIIBEAgBSgCGCgCQCAFKQMQp0EEdGooAgggBSgCDBBnQQBIBEAgBSgCGEEIakEPQQAQFCAFQX82AhwMAgsgBUEANgIcDAELIAUgBSgCGCgCQCAFKQMQp0EEdGo2AgQgBSAFKAIEKAIABH8gBSgCDCAFKAIEKAIAKAIURwVBAQtBAXE2AgACQCAFKAIABEAgBSgCBCgCBEUEQCAFKAIEKAIAEEAhACAFKAIEIAA2AgQgAEUEQCAFKAIYQQhqQQ5BABAUIAVBfzYCHAwECwsgBSgCBCgCBCAFKAIMNgIUIAUoAgQoAgQiACAAKAIAQSByNgIADAELIAUoAgQoAgQEQCAFKAIEKAIEIgAgACgCAEFfcTYCACAFKAIEKAIEKAIARQRAIAUoAgQoAgQQNyAFKAIEQQA2AgQLCwsgBUEANgIcCyAFKAIcIQAgBUEgaiQAIAALFwAgACABrSACrUIghoQgAyAEIAUQmQELEgAgACABrSACrUIghoQgAxAnC48BAgF/AX4CfyMAQSBrIgQkACAEIAA2AhQgBCABNgIQIAQgAjYCDCAEIAM2AggCQAJAIAQoAhAEQCAEKAIMDQELIAQoAhRBCGpBEkEAEBQgBEJ/NwMYDAELIAQgBCgCFCAEKAIQIAQoAgwgBCgCCBCaATcDGAsgBCkDGCEFIARBIGokACAFQiCIpwsQACAFpwuFBQIBfwF+An8jAEEwayIDJAAgAyAANgIkIAMgATYCICADIAI2AhwCQCADKAIkKAIYQQJxBEAgAygCJEEIakEZQQAQFCADQn83AygMAQsgAygCIEUEQCADKAIkQQhqQRJBABAUIANCfzcDKAwBCyADQQA2AgwgAyADKAIgEC42AhggAygCICADKAIYQQFraiwAAEEvRwRAIAMgAygCGEECahAYIgA2AgwgAEUEQCADKAIkQQhqQQ5BABAUIANCfzcDKAwCCwJAAkAgAygCDCIBIAMoAiAiAHNBA3ENACAAQQNxBEADQCABIAAtAAAiAjoAACACRQ0DIAFBAWohASAAQQFqIgBBA3ENAAsLIAAoAgAiAkF/cyACQYGChAhrcUGAgYKEeHENAANAIAEgAjYCACAAKAIEIQIgAUEEaiEBIABBBGohACACQYGChAhrIAJBf3NxQYCBgoR4cUUNAAsLIAEgAC0AACICOgAAIAJFDQADQCABIAAtAAEiAjoAASABQQFqIQEgAEEBaiEAIAINAAsLIAMoAgwgAygCGGpBLzoAACADKAIMIAMoAhhBAWpqQQA6AAALIAMgAygCJEEAQgBBABB9IgA2AgggAEUEQCADKAIMEBUgA0J/NwMoDAELIAMgAygCJAJ/IAMoAgwEQCADKAIMDAELIAMoAiALIAMoAgggAygCHBCaATcDECADKAIMEBUCQCADKQMQQgBTBEAgAygCCBAbDAELIAMoAiQgAykDEEEAQQNBgID8jwQQmQFBAEgEQCADKAIkIAMpAxAQmAEaIANCfzcDKAwCCwsgAyADKQMQNwMoCyADKQMoIQQgA0EwaiQAIARCIIinCxAAIASnCxEAIAAgAa0gAq1CIIaEEJgBCxcAIAAgAa0gAq1CIIaEIAMgBCAFEIoBC38CAX8BfiMAQSBrIgMkACADIAA2AhggAyABNgIUIAMgAjYCECADIAMoAhggAygCFCADKAIQEHIiBDcDCAJAIARCAFMEQCADQQA2AhwMAQsgAyADKAIYIAMpAwggAygCECADKAIYKAIcEK0BNgIcCyADKAIcIQAgA0EgaiQAIAALEAAjACAAa0FwcSIAJAAgAAsGACAAJAALBAAjAAuCAQIBfwF+IwBBIGsiBCQAIAQgADYCGCAEIAE2AhQgBCACNgIQIAQgAzYCDCAEIAQoAhggBCgCFCAEKAIQEHIiBTcDAAJAIAVCAFMEQCAEQX82AhwMAQsgBCAEKAIYIAQpAwAgBCgCECAEKAIMEH42AhwLIAQoAhwhACAEQSBqJAAgAAvQRQMGfwF+AnwjAEHgAGsiASQAIAEgADYCWAJAIAEoAlhFBEAgAUF/NgJcDAELIwBBIGsiACABKAJYNgIcIAAgAUFAazYCGCAAQQA2AhQgAEIANwMAAkAgACgCHC0AKEEBcUUEQCAAKAIcKAIYIAAoAhwoAhRGDQELIABBATYCFAsgAEIANwMIA0AgACkDCCAAKAIcKQMwVARAAkACQCAAKAIcKAJAIAApAwinQQR0aigCCA0AIAAoAhwoAkAgACkDCKdBBHRqLQAMQQFxDQAgACgCHCgCQCAAKQMIp0EEdGooAgRFDQEgACgCHCgCQCAAKQMIp0EEdGooAgQoAgBFDQELIABBATYCFAsgACgCHCgCQCAAKQMIp0EEdGotAAxBAXFFBEAgACAAKQMAQgF8NwMACyAAIAApAwhCAXw3AwgMAQsLIAAoAhgEQCAAKAIYIAApAwA3AwALIAEgACgCFDYCJCABKQNAUARAAkAgASgCWCgCBEEIcUUEQCABKAIkRQ0BCwJ/IAEoAlgoAgAhAiMAQRBrIgAkACAAIAI2AggCQCAAKAIIKAIkQQNGBEAgAEEANgIMDAELIAAoAggoAiAEQCAAKAIIEC9BAEgEQCAAQX82AgwMAgsLIAAoAggoAiQEQCAAKAIIEGILIAAoAghBAEIAQQ8QIEIAUwRAIABBfzYCDAwBCyAAKAIIQQM2AiQgAEEANgIMCyAAKAIMIQIgAEEQaiQAIAJBAEgLBEACQAJ/IwBBEGsiACABKAJYKAIANgIMIwBBEGsiAiAAKAIMQQxqNgIMIAIoAgwoAgBBFkYLBEAjAEEQayIAIAEoAlgoAgA2AgwjAEEQayICIAAoAgxBDGo2AgwgAigCDCgCBEEsRg0BCyABKAJYQQhqIAEoAlgoAgAQFyABQX82AlwMBAsLCyABKAJYEDwgAUEANgJcDAELIAEoAiRFBEAgASgCWBA8IAFBADYCXAwBCyABKQNAIAEoAlgpAzBWBEAgASgCWEEIakEUQQAQFCABQX82AlwMAQsgASABKQNAp0EDdBAYIgA2AiggAEUEQCABQX82AlwMAQsgAUJ/NwM4IAFCADcDSCABQgA3A1ADQCABKQNQIAEoAlgpAzBUBEACQCABKAJYKAJAIAEpA1CnQQR0aigCAEUNAAJAIAEoAlgoAkAgASkDUKdBBHRqKAIIDQAgASgCWCgCQCABKQNQp0EEdGotAAxBAXENACABKAJYKAJAIAEpA1CnQQR0aigCBEUNASABKAJYKAJAIAEpA1CnQQR0aigCBCgCAEUNAQsgAQJ+IAEpAzggASgCWCgCQCABKQNQp0EEdGooAgApA0hUBEAgASkDOAwBCyABKAJYKAJAIAEpA1CnQQR0aigCACkDSAs3AzgLIAEoAlgoAkAgASkDUKdBBHRqLQAMQQFxRQRAIAEpA0ggASkDQFoEQCABKAIoEBUgASgCWEEIakEUQQAQFCABQX82AlwMBAsgASgCKCABKQNIp0EDdGogASkDUDcDACABIAEpA0hCAXw3A0gLIAEgASkDUEIBfDcDUAwBCwsgASkDSCABKQNAVARAIAEoAigQFSABKAJYQQhqQRRBABAUIAFBfzYCXAwBCwJAAn8jAEEQayIAIAEoAlgoAgA2AgwgACgCDCkDGEKAgAiDUAsEQCABQgA3AzgMAQsgASkDOEJ/UQRAIAFCfzcDGCABQgA3AzggAUIANwNQA0AgASkDUCABKAJYKQMwVARAIAEoAlgoAkAgASkDUKdBBHRqKAIABEAgASgCWCgCQCABKQNQp0EEdGooAgApA0ggASkDOFoEQCABIAEoAlgoAkAgASkDUKdBBHRqKAIAKQNINwM4IAEgASkDUDcDGAsLIAEgASkDUEIBfDcDUAwBCwsgASkDGEJ/UgRAIAEoAlghAiABKQMYIQcgASgCWEEIaiEDIwBBMGsiACQAIAAgAjYCJCAAIAc3AxggACADNgIUIAAgACgCJCAAKQMYIAAoAhQQYCIHNwMIAkAgB1AEQCAAQgA3AygMAQsgACAAKAIkKAJAIAApAxinQQR0aigCADYCBAJAIAApAwggACkDCCAAKAIEKQMgfFgEQCAAKQMIIAAoAgQpAyB8Qv///////////wBYDQELIAAoAhRBBEEWEBQgAEIANwMoDAELIAAgACgCBCkDICAAKQMIfDcDCCAAKAIELwEMQQhxBEAgACgCJCgCACAAKQMIQQAQJ0EASARAIAAoAhQgACgCJCgCABAXIABCADcDKAwCCyAAKAIkKAIAIABCBBArQgRSBEAgACgCFCAAKAIkKAIAEBcgAEIANwMoDAILIAAoAABB0JadwABGBEAgACAAKQMIQgR8NwMICyAAIAApAwhCDHw3AwggACgCBEEAEGVBAXEEQCAAIAApAwhCCHw3AwgLIAApAwhC////////////AFYEQCAAKAIUQQRBFhAUIABCADcDKAwCCwsgACAAKQMINwMoCyAAKQMoIQcgAEEwaiQAIAEgBzcDOCAHUARAIAEoAigQFSABQX82AlwMBAsLCyABKQM4QgBSBEACfyABKAJYKAIAIQIgASkDOCEHIwBBEGsiACQAIAAgAjYCCCAAIAc3AwACQCAAKAIIKAIkQQFGBEAgACgCCEEMakESQQAQFCAAQX82AgwMAQsgACgCCEEAIAApAwBBERAgQgBTBEAgAEF/NgIMDAELIAAoAghBATYCJCAAQQA2AgwLIAAoAgwhAiAAQRBqJAAgAkEASAsEQCABQgA3AzgLCwsgASkDOFAEQAJ/IAEoAlgoAgAhAiMAQRBrIgAkACAAIAI2AggCQCAAKAIIKAIkQQFGBEAgACgCCEEMakESQQAQFCAAQX82AgwMAQsgACgCCEEAQgBBCBAgQgBTBEAgAEF/NgIMDAELIAAoAghBATYCJCAAQQA2AgwLIAAoAgwhAiAAQRBqJAAgAkEASAsEQCABKAJYQQhqIAEoAlgoAgAQFyABKAIoEBUgAUF/NgJcDAILCyABKAJYKAJUIQIjAEEQayIAJAAgACACNgIMIAAoAgwEQCAAKAIMRAAAAAAAAAAAOQMYIAAoAgwoAgBEAAAAAAAAAAAgACgCDCgCDCAAKAIMKAIEERYACyAAQRBqJAAgAUEANgIsIAFCADcDSANAAkAgASkDSCABKQNAWg0AIAEoAlgoAlQhAiABKQNIIge6IAEpA0C6IgijIQkjAEEgayIAJAAgACACNgIcIAAgCTkDECAAIAdCAXy6IAijOQMIIAAoAhwEQCAAKAIcIAArAxA5AyAgACgCHCAAKwMIOQMoIAAoAhxEAAAAAAAAAAAQVwsgAEEgaiQAIAEgASgCKCABKQNIp0EDdGopAwA3A1AgASABKAJYKAJAIAEpA1CnQQR0ajYCEAJAAkAgASgCECgCAEUNACABKAIQKAIAKQNIIAEpAzhaDQAMAQsgAQJ/QQEgASgCECgCCA0AGiABKAIQKAIEBEBBASABKAIQKAIEKAIAQQFxDQEaCyABKAIQKAIEBH8gASgCECgCBCgCAEHAAHFBAEcFQQALC0EBcTYCFCABKAIQKAIERQRAIAEoAhAoAgAQQCEAIAEoAhAgADYCBCAARQRAIAEoAlhBCGpBDkEAEBQgAUEBNgIsDAMLCyABIAEoAhAoAgQ2AgwCfyABKAJYIQIgASkDUCEHIwBBMGsiACQAIAAgAjYCKCAAIAc3AyACQCAAKQMgIAAoAigpAzBaBEAgACgCKEEIakESQQAQFCAAQX82AiwMAQsgACAAKAIoKAJAIAApAyCnQQR0ajYCHAJAIAAoAhwoAgAEQCAAKAIcKAIALQAEQQFxRQ0BCyAAQQA2AiwMAQsgACgCHCgCACkDSEIafEL///////////8AVgRAIAAoAihBCGpBBEEWEBQgAEF/NgIsDAELIAAoAigoAgAgACgCHCgCACkDSEIafEEAECdBAEgEQCAAKAIoQQhqIAAoAigoAgAQFyAAQX82AiwMAQsgACAAKAIoKAIAQgQgAEEYaiAAKAIoQQhqEEIiAjYCFCACRQRAIABBfzYCLAwBCyAAIAAoAhQQHTsBEiAAIAAoAhQQHTsBECAAKAIUEEdBAXFFBEAgACgCFBAWIAAoAihBCGpBFEEAEBQgAEF/NgIsDAELIAAoAhQQFiAALwEQBEAgACgCKCgCACAALwESrUEBECdBAEgEQCAAKAIoQQhqQQRBtJsBKAIAEBQgAEF/NgIsDAILIABBACAAKAIoKAIAIAAvARBBACAAKAIoQQhqEGM2AgggACgCCEUEQCAAQX82AiwMAgsgACgCCCAALwEQQYACIABBDGogACgCKEEIahCUAUEBcUUEQCAAKAIIEBUgAEF/NgIsDAILIAAoAggQFSAAKAIMBEAgACAAKAIMEJMBNgIMIAAoAhwoAgAoAjQgACgCDBCVASECIAAoAhwoAgAgAjYCNAsLIAAoAhwoAgBBAToABAJAIAAoAhwoAgRFDQAgACgCHCgCBC0ABEEBcQ0AIAAoAhwoAgQgACgCHCgCACgCNDYCNCAAKAIcKAIEQQE6AAQLIABBADYCLAsgACgCLCECIABBMGokACACQQBICwRAIAFBATYCLAwCCyABIAEoAlgoAgAQNSIHNwMwIAdCAFMEQCABQQE2AiwMAgsgASgCDCABKQMwNwNIAkAgASgCFARAIAFBADYCCCABKAIQKAIIRQRAIAEgASgCWCABKAJYIAEpA1BBCEEAEK4BIgA2AgggAEUEQCABQQE2AiwMBQsLAn8gASgCWCECAn8gASgCCARAIAEoAggMAQsgASgCECgCCAshAyABKAIMIQQjAEGgAWsiACQAIAAgAjYCmAEgACADNgKUASAAIAQ2ApABAkAgACgClAEgAEE4ahA5QQBIBEAgACgCmAFBCGogACgClAEQFyAAQX82ApwBDAELIAApAzhCwACDUARAIAAgACkDOELAAIQ3AzggAEEAOwFoCwJAAkAgACgCkAEoAhBBf0cEQCAAKAKQASgCEEF+Rw0BCyAALwFoRQ0AIAAoApABIAAvAWg2AhAMAQsCQAJAIAAoApABKAIQDQAgACkDOEIEg1ANACAAIAApAzhCCIQ3AzggACAAKQNQNwNYDAELIAAgACkDOEL3////D4M3AzgLCyAAKQM4QoABg1AEQCAAIAApAzhCgAGENwM4IABBADsBagsgAEGAAjYCJAJAIAApAzhCBINQBEAgACAAKAIkQYAIcjYCJCAAQn83A3AMAQsgACgCkAEgACkDUDcDKCAAIAApA1A3A3ACQCAAKQM4QgiDUARAAkACQAJAAkACQAJ/AkAgACgCkAEoAhBBf0cEQCAAKAKQASgCEEF+Rw0BC0EIDAELIAAoApABKAIQC0H//wNxDg0CAwMDAwMDAwEDAwMAAwsgAEKUwuTzDzcDEAwDCyAAQoODsP8PNwMQDAILIABC/////w83AxAMAQsgAEIANwMQCyAAKQNQIAApAxBWBEAgACAAKAIkQYAIcjYCJAsMAQsgACgCkAEgACkDWDcDIAsLIAAgACgCmAEoAgAQNSIHNwOIASAHQgBTBEAgACgCmAFBCGogACgCmAEoAgAQFyAAQX82ApwBDAELIAAoApABIgIgAi8BDEH3/wNxOwEMIAAgACgCmAEgACgCkAEgACgCJBBUIgI2AiggAkEASARAIABBfzYCnAEMAQsgACAALwFoAn8CQCAAKAKQASgCEEF/RwRAIAAoApABKAIQQX5HDQELQQgMAQsgACgCkAEoAhALQf//A3FHOgAiIAAgAC0AIkEBcQR/IAAvAWhBAEcFQQALQQFxOgAhIAAgAC8BaAR/IAAtACEFQQELQQFxOgAgIAAgAC0AIkEBcQR/IAAoApABKAIQQQBHBUEAC0EBcToAHyAAAn9BASAALQAiQQFxDQAaQQEgACgCkAEoAgBBgAFxDQAaIAAoApABLwFSIAAvAWpHC0EBcToAHiAAIAAtAB5BAXEEfyAALwFqQQBHBUEAC0EBcToAHSAAIAAtAB5BAXEEfyAAKAKQAS8BUkEARwVBAAtBAXE6ABwgACAAKAKUATYCNCMAQRBrIgIgACgCNDYCDCACKAIMIgIgAigCMEEBajYCMCAALQAdQQFxBEAgACAALwFqQQAQeyICNgIMIAJFBEAgACgCmAFBCGpBGEEAEBQgACgCNBAbIABBfzYCnAEMAgsgACAAKAKYASAAKAI0IAAvAWpBACAAKAKYASgCHCAAKAIMEQUAIgI2AjAgAkUEQCAAKAI0EBsgAEF/NgKcAQwCCyAAKAI0EBsgACAAKAIwNgI0CyAALQAhQQFxBEAgACAAKAKYASAAKAI0IAAvAWgQsAEiAjYCMCACRQRAIAAoAjQQGyAAQX82ApwBDAILIAAoAjQQGyAAIAAoAjA2AjQLIAAtACBBAXEEQCAAIAAoApgBIAAoAjRBABCvASICNgIwIAJFBEAgACgCNBAbIABBfzYCnAEMAgsgACgCNBAbIAAgACgCMDYCNAsgAC0AH0EBcQRAIAAoApgBIQMgACgCNCEEIAAoApABKAIQIQUgACgCkAEvAVAhBiMAQRBrIgIkACACIAM2AgwgAiAENgIIIAIgBTYCBCACIAY2AgAgAigCDCACKAIIIAIoAgRBASACKAIAELIBIQMgAkEQaiQAIAAgAyICNgIwIAJFBEAgACgCNBAbIABBfzYCnAEMAgsgACgCNBAbIAAgACgCMDYCNAsgAC0AHEEBcQRAIABBADYCBAJAIAAoApABKAJUBEAgACAAKAKQASgCVDYCBAwBCyAAKAKYASgCHARAIAAgACgCmAEoAhw2AgQLCyAAIAAoApABLwFSQQEQeyICNgIIIAJFBEAgACgCmAFBCGpBGEEAEBQgACgCNBAbIABBfzYCnAEMAgsgACAAKAKYASAAKAI0IAAoApABLwFSQQEgACgCBCAAKAIIEQUAIgI2AjAgAkUEQCAAKAI0EBsgAEF/NgKcAQwCCyAAKAI0EBsgACAAKAIwNgI0CyAAIAAoApgBKAIAEDUiBzcDgAEgB0IAUwRAIAAoApgBQQhqIAAoApgBKAIAEBcgAEF/NgKcAQwBCyAAKAKYASEDIAAoAjQhBCAAKQNwIQcjAEHAwABrIgIkACACIAM2ArhAIAIgBDYCtEAgAiAHNwOoQAJAIAIoArRAEEhBAEgEQCACKAK4QEEIaiACKAK0QBAXIAJBfzYCvEAMAQsgAkEANgIMIAJCADcDEANAAkAgAiACKAK0QCACQSBqQoDAABArIgc3AxggB0IAVw0AIAIoArhAIAJBIGogAikDGBA2QQBIBEAgAkF/NgIMBSACKQMYQoDAAFINAiACKAK4QCgCVEUNAiACKQOoQEIAVw0CIAIgAikDGCACKQMQfDcDECACKAK4QCgCVCACKQMQuSACKQOoQLmjEFcMAgsLCyACKQMYQgBTBEAgAigCuEBBCGogAigCtEAQFyACQX82AgwLIAIoArRAEC8aIAIgAigCDDYCvEALIAIoArxAIQMgAkHAwABqJAAgACADNgIsIAAoAjQgAEE4ahA5QQBIBEAgACgCmAFBCGogACgCNBAXIABBfzYCLAsgACgCNCEDIwBBEGsiAiQAIAIgAzYCCAJAA0AgAigCCARAIAIoAggpAxhCgIAEg0IAUgRAIAIgAigCCEEAQgBBEBAgNwMAIAIpAwBCAFMEQCACQf8BOgAPDAQLIAIpAwBCA1UEQCACKAIIQQxqQRRBABAUIAJB/wE6AA8MBAsgAiACKQMAPAAPDAMFIAIgAigCCCgCADYCCAwCCwALCyACQQA6AA8LIAIsAA8hAyACQRBqJAAgACADIgI6ACMgAkEYdEEYdUEASARAIAAoApgBQQhqIAAoAjQQFyAAQX82AiwLIAAoAjQQGyAAKAIsQQBIBEAgAEF/NgKcAQwBCyAAIAAoApgBKAIAEDUiBzcDeCAHQgBTBEAgACgCmAFBCGogACgCmAEoAgAQFyAAQX82ApwBDAELIAAoApgBKAIAIAApA4gBEJsBQQBIBEAgACgCmAFBCGogACgCmAEoAgAQFyAAQX82ApwBDAELIAApAzhC5ACDQuQAUgRAIAAoApgBQQhqQRRBABAUIABBfzYCnAEMAQsgACgCkAEoAgBBIHFFBEACQCAAKQM4QhCDQgBSBEAgACgCkAEgACgCYDYCFAwBCyAAKAKQAUEUahABGgsLIAAoApABIAAvAWg2AhAgACgCkAEgACgCZDYCGCAAKAKQASAAKQNQNwMoIAAoApABIAApA3ggACkDgAF9NwMgIAAoApABIAAoApABLwEMQfn/A3EgAC0AI0EBdHI7AQwgACgCkAEhAyAAKAIkQYAIcUEARyEEIwBBEGsiAiQAIAIgAzYCDCACIAQ6AAsCQCACKAIMKAIQQQ5GBEAgAigCDEE/OwEKDAELIAIoAgwoAhBBDEYEQCACKAIMQS47AQoMAQsCQCACLQALQQFxRQRAIAIoAgxBABBlQQFxRQ0BCyACKAIMQS07AQoMAQsCQCACKAIMKAIQQQhHBEAgAigCDC8BUkEBRw0BCyACKAIMQRQ7AQoMAQsgAiACKAIMKAIwEFEiAzsBCCADQf//A3EEQCACKAIMKAIwKAIAIAIvAQhBAWtqLQAAQS9GBEAgAigCDEEUOwEKDAILCyACKAIMQQo7AQoLIAJBEGokACAAIAAoApgBIAAoApABIAAoAiQQVCICNgIsIAJBAEgEQCAAQX82ApwBDAELIAAoAiggACgCLEcEQCAAKAKYAUEIakEUQQAQFCAAQX82ApwBDAELIAAoApgBKAIAIAApA3gQmwFBAEgEQCAAKAKYAUEIaiAAKAKYASgCABAXIABBfzYCnAEMAQsgAEEANgKcAQsgACgCnAEhAiAAQaABaiQAIAJBAEgLBEAgAUEBNgIsIAEoAggEQCABKAIIEBsLDAQLIAEoAggEQCABKAIIEBsLDAELIAEoAgwiACAALwEMQff/A3E7AQwgASgCWCABKAIMQYACEFRBAEgEQCABQQE2AiwMAwsgASABKAJYIAEpA1AgASgCWEEIahBgIgc3AwAgB1AEQCABQQE2AiwMAwsgASgCWCgCACABKQMAQQAQJ0EASARAIAEoAlhBCGogASgCWCgCABAXIAFBATYCLAwDCwJ/IAEoAlghAiABKAIMKQMgIQcjAEGgwABrIgAkACAAIAI2AphAIAAgBzcDkEAgACAAKQOQQLo5AwACQANAIAApA5BAUEUEQCAAIAApA5BAQoDAAFYEfkKAwAAFIAApA5BACz4CDCAAKAKYQCgCACAAQRBqIAAoAgytIAAoAphAQQhqEGRBAEgEQCAAQX82ApxADAMLIAAoAphAIABBEGogACgCDK0QNkEASARAIABBfzYCnEAMAwUgACAAKQOQQCAANQIMfTcDkEAgACgCmEAoAlQgACsDACAAKQOQQLqhIAArAwCjEFcMAgsACwsgAEEANgKcQAsgACgCnEAhAiAAQaDAAGokACACQQBICwRAIAFBATYCLAwDCwsLIAEgASkDSEIBfDcDSAwBCwsgASgCLEUEQAJ/IAEoAlghACABKAIoIQMgASkDQCEHIwBBMGsiAiQAIAIgADYCKCACIAM2AiQgAiAHNwMYIAIgAigCKCgCABA1Igc3AxACQCAHQgBTBEAgAkF/NgIsDAELIAIoAighAyACKAIkIQQgAikDGCEHIwBBwAFrIgAkACAAIAM2ArQBIAAgBDYCsAEgACAHNwOoASAAIAAoArQBKAIAEDUiBzcDIAJAIAdCAFMEQCAAKAK0AUEIaiAAKAK0ASgCABAXIABCfzcDuAEMAQsgACAAKQMgNwOgASAAQQA6ABcgAEIANwMYA0AgACkDGCAAKQOoAVQEQCAAIAAoArQBKAJAIAAoArABIAApAxinQQN0aikDAKdBBHRqNgIMIAAgACgCtAECfyAAKAIMKAIEBEAgACgCDCgCBAwBCyAAKAIMKAIAC0GABBBUIgM2AhAgA0EASARAIABCfzcDuAEMAwsgACgCEARAIABBAToAFwsgACAAKQMYQgF8NwMYDAELCyAAIAAoArQBKAIAEDUiBzcDICAHQgBTBEAgACgCtAFBCGogACgCtAEoAgAQFyAAQn83A7gBDAELIAAgACkDICAAKQOgAX03A5gBAkAgACkDoAFC/////w9YBEAgACkDqAFC//8DWA0BCyAAQQE6ABcLIAAgAEEwakLiABApIgM2AiwgA0UEQCAAKAK0AUEIakEOQQAQFCAAQn83A7gBDAELIAAtABdBAXEEQCAAKAIsQecSQQQQQSAAKAIsQiwQLSAAKAIsQS0QHyAAKAIsQS0QHyAAKAIsQQAQISAAKAIsQQAQISAAKAIsIAApA6gBEC0gACgCLCAAKQOoARAtIAAoAiwgACkDmAEQLSAAKAIsIAApA6ABEC0gACgCLEHiEkEEEEEgACgCLEEAECEgACgCLCAAKQOgASAAKQOYAXwQLSAAKAIsQQEQIQsgACgCLEHsEkEEEEEgACgCLEEAECEgACgCLCAAKQOoAUL//wNaBH5C//8DBSAAKQOoAQunQf//A3EQHyAAKAIsIAApA6gBQv//A1oEfkL//wMFIAApA6gBC6dB//8DcRAfIAAoAiwgACkDmAFC/////w9aBH9BfwUgACkDmAGnCxAhIAAoAiwgACkDoAFC/////w9aBH9BfwUgACkDoAGnCxAhIAACfyAAKAK0AS0AKEEBcQRAIAAoArQBKAIkDAELIAAoArQBKAIgCzYClAEgACgCLAJ/IAAoApQBBEAgACgClAEvAQQMAQtBAAtB//8DcRAfAn8jAEEQayIDIAAoAiw2AgwgAygCDC0AAEEBcUULBEAgACgCtAFBCGpBFEEAEBQgACgCLBAWIABCfzcDuAEMAQsgACgCtAECfyMAQRBrIgMgACgCLDYCDCADKAIMKAIECwJ+IwBBEGsiAyAAKAIsNgIMAn4gAygCDC0AAEEBcQRAIAMoAgwpAxAMAQtCAAsLEDZBAEgEQCAAKAIsEBYgAEJ/NwO4AQwBCyAAKAIsEBYgACgClAEEQCAAKAK0ASAAKAKUASgCACAAKAKUAS8BBK0QNkEASARAIABCfzcDuAEMAgsLIAAgACkDmAE3A7gBCyAAKQO4ASEHIABBwAFqJAAgAiAHNwMAIAdCAFMEQCACQX82AiwMAQsgAiACKAIoKAIAEDUiBzcDCCAHQgBTBEAgAkF/NgIsDAELIAJBADYCLAsgAigCLCEAIAJBMGokACAAQQBICwRAIAFBATYCLAsLIAEoAigQFSABKAIsRQRAAn8gASgCWCgCACECIwBBEGsiACQAIAAgAjYCCAJAIAAoAggoAiRBAUcEQCAAKAIIQQxqQRJBABAUIABBfzYCDAwBCyAAKAIIKAIgQQFLBEAgACgCCEEMakEdQQAQFCAAQX82AgwMAQsgACgCCCgCIARAIAAoAggQL0EASARAIABBfzYCDAwCCwsgACgCCEEAQgBBCRAgQgBTBEAgACgCCEECNgIkIABBfzYCDAwBCyAAKAIIQQA2AiQgAEEANgIMCyAAKAIMIQIgAEEQaiQAIAILBEAgASgCWEEIaiABKAJYKAIAEBcgAUEBNgIsCwsgASgCWCgCVCECIwBBEGsiACQAIAAgAjYCDCAAKAIMRAAAAAAAAPA/EFcgAEEQaiQAIAEoAiwEQCABKAJYKAIAEGIgAUF/NgJcDAELIAEoAlgQPCABQQA2AlwLIAEoAlwhACABQeAAaiQAIAAL0g4CB38CfiMAQTBrIgMkACADIAA2AiggAyABNgIkIAMgAjYCICMAQRBrIgAgA0EIajYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCADKAIoIQAjAEEgayIEJAAgBCAANgIYIARCADcDECAEQn83AwggBCADQQhqNgIEAkACQCAEKAIYBEAgBCkDCEJ/WQ0BCyAEKAIEQRJBABAUIARBADYCHAwBCyAEKAIYIQAgBCkDECEKIAQpAwghCyAEKAIEIQEjAEGgAWsiAiQAIAIgADYCmAEgAkEANgKUASACIAo3A4gBIAIgCzcDgAEgAkEANgJ8IAIgATYCeAJAAkAgAigClAENACACKAKYAQ0AIAIoAnhBEkEAEBQgAkEANgKcAQwBCyACKQOAAUIAUwRAIAJCADcDgAELAkAgAikDiAFC////////////AFgEQCACKQOIASACKQOIASACKQOAAXxYDQELIAIoAnhBEkEAEBQgAkEANgKcAQwBCyACQYgBEBgiADYCdCAARQRAIAIoAnhBDkEAEBQgAkEANgKcAQwBCyACKAJ0QQA2AhggAigCmAEEQCACKAKYASIAEC5BAWoiARAYIgUEfyAFIAAgARAZBUEACyEAIAIoAnQgADYCGCAARQRAIAIoAnhBDkEAEBQgAigCdBAVIAJBADYCnAEMAgsLIAIoAnQgAigClAE2AhwgAigCdCACKQOIATcDaCACKAJ0IAIpA4ABNwNwAkAgAigCfARAIAIoAnQiACACKAJ8IgEpAwA3AyAgACABKQMwNwNQIAAgASkDKDcDSCAAIAEpAyA3A0AgACABKQMYNwM4IAAgASkDEDcDMCAAIAEpAwg3AyggAigCdEEANgIoIAIoAnQiACAAKQMgQv7///8PgzcDIAwBCyACKAJ0QSBqEDsLIAIoAnQpA3BCAFIEQCACKAJ0IAIoAnQpA3A3AzggAigCdCIAIAApAyBCBIQ3AyALIwBBEGsiACACKAJ0QdgAajYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCACKAJ0QQA2AoABIAIoAnRBADYChAEjAEEQayIAIAIoAnQ2AgwgACgCDEEANgIAIAAoAgxBADYCBCAAKAIMQQA2AgggAkF/NgIEIAJBBzYCAEEOIAIQNEI/hCEKIAIoAnQgCjcDEAJAIAIoAnQoAhgEQCACIAIoAnQoAhggAkEYahCmAUEATjoAFyACLQAXQQFxRQRAAkAgAigCdCkDaFBFDQAgAigCdCkDcFBFDQAgAigCdEL//wM3AxALCwwBCwJAIAIoAnQoAhwiACgCTEEASA0ACyAAKAI8IQBBACEFIwBBIGsiBiQAAn8CQCAAIAJBGGoiCRAKIgFBeEYEQCMAQSBrIgckACAAIAdBCGoQCSIIBH9BtJsBIAg2AgBBAAVBAQshCCAHQSBqJAAgCA0BCyABQYFgTwR/QbSbAUEAIAFrNgIAQX8FIAELDAELA0AgBSAGaiIBIAVBxxJqLQAAOgAAIAVBDkchByAFQQFqIQUgBw0ACwJAIAAEQEEPIQUgACEBA0AgAUEKTwRAIAVBAWohBSABQQpuIQEMAQsLIAUgBmpBADoAAANAIAYgBUEBayIFaiAAIABBCm4iAUEKbGtBMHI6AAAgAEEJSyEHIAEhACAHDQALDAELIAFBMDoAACAGQQA6AA8LIAYgCRACIgBBgWBPBH9BtJsBQQAgAGs2AgBBfwUgAAsLIQAgBkEgaiQAIAIgAEEATjoAFwsCQCACLQAXQQFxRQRAIAIoAnRB2ABqQQVBtJsBKAIAEBQMAQsgAigCdCkDIEIQg1AEQCACKAJ0IAIoAlg2AkggAigCdCIAIAApAyBCEIQ3AyALIAIoAiRBgOADcUGAgAJGBEAgAigCdEL/gQE3AxAgAikDQCACKAJ0KQNoIAIoAnQpA3B8VARAIAIoAnhBEkEAEBQgAigCdCgCGBAVIAIoAnQQFSACQQA2ApwBDAMLIAIoAnQpA3BQBEAgAigCdCACKQNAIAIoAnQpA2h9NwM4IAIoAnQiACAAKQMgQgSENwMgAkAgAigCdCgCGEUNACACKQOIAVBFDQAgAigCdEL//wM3AxALCwsLIAIoAnQiACAAKQMQQoCAEIQ3AxAgAkEeIAIoAnQgAigCeBCDASIANgJwIABFBEAgAigCdCgCGBAVIAIoAnQQFSACQQA2ApwBDAELIAIgAigCcDYCnAELIAIoApwBIQAgAkGgAWokACAEIAA2AhwLIAQoAhwhACAEQSBqJAAgAyAANgIYAkAgAEUEQCADKAIgIANBCGoQnQEgA0EIahA4IANBADYCLAwBCyADIAMoAhggAygCJCADQQhqEJwBIgA2AhwgAEUEQCADKAIYEBsgAygCICADQQhqEJ0BIANBCGoQOCADQQA2AiwMAQsgA0EIahA4IAMgAygCHDYCLAsgAygCLCEAIANBMGokACAAC5IfAQZ/IwBB4ABrIgQkACAEIAA2AlQgBCABNgJQIAQgAjcDSCAEIAM2AkQgBCAEKAJUNgJAIAQgBCgCUDYCPAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAQoAkQOEwYHAgwEBQoOAQMJEAsPDQgREQARCyAEQgA3A1gMEQsgBCgCQCgCGEUEQCAEKAJAQRxBABAUIARCfzcDWAwRCyAEKAJAIQAjAEGAAWsiASQAIAEgADYCeCABIAEoAngoAhgQLkEIahAYIgA2AnQCQCAARQRAIAEoAnhBDkEAEBQgAUF/NgJ8DAELAkAgASgCeCgCGCABQRBqEKYBRQRAIAEgASgCHDYCbAwBCyABQX82AmwLIAEoAnQhACABIAEoAngoAhg2AgAgAEGrEiABEG8gASgCdCEDIAEoAmwhByMAQTBrIgAkACAAIAM2AiggACAHNgIkIABBADYCECAAIAAoAiggACgCKBAuajYCGCAAIAAoAhhBAWs2AhwDQCAAKAIcIAAoAihPBH8gACgCHCwAAEHYAEYFQQALQQFxBEAgACAAKAIQQQFqNgIQIAAgACgCHEEBazYCHAwBCwsCQCAAKAIQRQRAQbSbAUEcNgIAIABBfzYCLAwBCyAAIAAoAhxBAWo2AhwDQCMAQRBrIgckAAJAAn8jAEEQayIDJAAgAyAHQQhqNgIIIANBBDsBBiADQegLQQBBABBsIgU2AgACQCAFQQBIBEAgA0EAOgAPDAELAn8gAygCACEGIAMoAgghCCADLwEGIQkjAEEQayIFJAAgBSAJNgIMIAUgCDYCCCAGIAVBCGpBASAFQQRqEAYiBgR/QbSbASAGNgIAQX8FQQALIQYgBSgCBCEIIAVBEGokACADLwEGQX8gCCAGG0cLBEAgAygCABBrIANBADoADwwBCyADKAIAEGsgA0EBOgAPCyADLQAPQQFxIQUgA0EQaiQAIAULBEAgByAHKAIINgIMDAELQcCgAS0AAEEBcUUEQEEAEAEhBgJAQciZASgCACIDRQRAQcyZASgCACAGNgIADAELQdCZAUEDQQNBASADQQdGGyADQR9GGzYCAEG8oAFBADYCAEHMmQEoAgAhBSADQQFOBEAgBq0hAkEAIQYDQCAFIAZBAnRqIAJCrf7V5NSF/ajYAH5CAXwiAkIgiD4CACAGQQFqIgYgA0cNAAsLIAUgBSgCAEEBcjYCAAsLQcyZASgCACEDAkBByJkBKAIAIgVFBEAgAyADKAIAQe2cmY4EbEG54ABqQf////8HcSIDNgIADAELIANB0JkBKAIAIgZBAnRqIgggCCgCACADQbygASgCACIIQQJ0aigCAGoiAzYCAEG8oAFBACAIQQFqIgggBSAIRhs2AgBB0JkBQQAgBkEBaiIGIAUgBkYbNgIAIANBAXYhAwsgByADNgIMCyAHKAIMIQMgB0EQaiQAIAAgAzYCDCAAIAAoAhw2AhQDQCAAKAIUIAAoAhhJBEAgACAAKAIMQSRwOgALAn8gACwAC0EKSARAIAAsAAtBMGoMAQsgACwAC0HXAGoLIQMgACAAKAIUIgdBAWo2AhQgByADOgAAIAAgACgCDEEkbjYCDAwBCwsgACgCKCEDIAAgACgCJEF/RgR/QbYDBSAAKAIkCzYCACAAIANBwoEgIAAQbCIDNgIgIANBAE4EQCAAKAIkQX9HBEAgACgCKCAAKAIkEA8iA0GBYE8Ef0G0mwFBACADazYCAEEABSADCxoLIAAgACgCIDYCLAwCC0G0mwEoAgBBFEYNAAsgAEF/NgIsCyAAKAIsIQMgAEEwaiQAIAEgAyIANgJwIABBf0YEQCABKAJ4QQxBtJsBKAIAEBQgASgCdBAVIAFBfzYCfAwBCyABIAEoAnBBoxIQoQEiADYCaCAARQRAIAEoAnhBDEG0mwEoAgAQFCABKAJwEGsgASgCdBBtGiABKAJ0EBUgAUF/NgJ8DAELIAEoAnggASgCaDYChAEgASgCeCABKAJ0NgKAASABQQA2AnwLIAEoAnwhACABQYABaiQAIAQgAKw3A1gMEAsgBCgCQCgCGARAIAQoAkAoAhwQVhogBCgCQEEANgIcCyAEQgA3A1gMDwsgBCgCQCgChAEQVkEASARAIAQoAkBBADYChAEgBCgCQEEGQbSbASgCABAUCyAEKAJAQQA2AoQBIAQoAkAoAoABIAQoAkAoAhgQCCIAQYFgTwR/QbSbAUEAIABrNgIAQX8FIAALQQBIBEAgBCgCQEECQbSbASgCABAUIARCfzcDWAwPCyAEKAJAKAKAARAVIAQoAkBBADYCgAEgBEIANwNYDA4LIAQgBCgCQCAEKAJQIAQpA0gQQzcDWAwNCyAEKAJAKAIYEBUgBCgCQCgCgAEQFSAEKAJAKAIcBEAgBCgCQCgCHBBWGgsgBCgCQBAVIARCADcDWAwMCyAEKAJAKAIYBEAgBCgCQCgCGCEBIwBBIGsiACQAIAAgATYCGCAAQQA6ABcgAEGAgCA2AgwCQCAALQAXQQFxBEAgACAAKAIMQQJyNgIMDAELIAAgACgCDDYCDAsgACgCGCEBIAAoAgwhAyAAQbYDNgIAIAAgASADIAAQbCIBNgIQAkAgAUEASARAIABBADYCHAwBCyAAIAAoAhBBoxJBoBIgAC0AF0EBcRsQoQEiATYCCCABRQRAIABBADYCHAwBCyAAIAAoAgg2AhwLIAAoAhwhASAAQSBqJAAgBCgCQCABNgIcIAFFBEAgBCgCQEELQbSbASgCABAUIARCfzcDWAwNCwsgBCgCQCkDaEIAUgRAIAQoAkAoAhwgBCgCQCkDaCAEKAJAEJ8BQQBIBEAgBEJ/NwNYDA0LCyAEKAJAQgA3A3ggBEIANwNYDAsLAkAgBCgCQCkDcEIAUgRAIAQgBCgCQCkDcCAEKAJAKQN4fTcDMCAEKQMwIAQpA0hWBEAgBCAEKQNINwMwCwwBCyAEIAQpA0g3AzALIAQpAzBC/////w9WBEAgBEL/////DzcDMAsgBAJ/IAQoAjwhByAEKQMwpyEAIAQoAkAoAhwiAygCTBogAyADLQBKIgFBAWsgAXI6AEogAygCCCADKAIEIgVrIgFBAUgEfyAABSAHIAUgASAAIAAgAUsbIgEQGRogAyADKAIEIAFqNgIEIAEgB2ohByAAIAFrCyIBBEADQAJAAn8gAyADLQBKIgVBAWsgBXI6AEogAygCFCADKAIcSwRAIANBAEEAIAMoAiQRAQAaCyADQQA2AhwgA0IANwMQIAMoAgAiBUEEcQRAIAMgBUEgcjYCAEF/DAELIAMgAygCLCADKAIwaiIGNgIIIAMgBjYCBCAFQRt0QR91C0UEQCADIAcgASADKAIgEQEAIgVBAWpBAUsNAQsgACABawwDCyAFIAdqIQcgASAFayIBDQALCyAACyIANgIsIABFBEACfyAEKAJAKAIcIgAoAkxBf0wEQCAAKAIADAELIAAoAgALQQV2QQFxBEAgBCgCQEEFQbSbASgCABAUIARCfzcDWAwMCwsgBCgCQCIAIAApA3ggBCgCLK18NwN4IAQgBCgCLK03A1gMCgsgBCgCQCgCGBBtQQBIBEAgBCgCQEEWQbSbASgCABAUIARCfzcDWAwKCyAEQgA3A1gMCQsgBCgCQCgChAEEQCAEKAJAKAKEARBWGiAEKAJAQQA2AoQBCyAEKAJAKAKAARBtGiAEKAJAKAKAARAVIAQoAkBBADYCgAEgBEIANwNYDAgLIAQCfyAEKQNIQhBUBEAgBCgCQEESQQAQFEEADAELIAQoAlALNgIYIAQoAhhFBEAgBEJ/NwNYDAgLIARBATYCHAJAAkACQAJAAkAgBCgCGCgCCA4DAAIBAwsgBCAEKAIYKQMANwMgDAMLAkAgBCgCQCkDcFAEQCAEKAJAKAIcIAQoAhgpAwBBAiAEKAJAEGpBAEgEQCAEQn83A1gMDQsgBCAEKAJAKAIcEKMBIgI3AyAgAkIAUwRAIAQoAkBBBEG0mwEoAgAQFCAEQn83A1gMDQsgBCAEKQMgIAQoAkApA2h9NwMgIARBADYCHAwBCyAEIAQoAkApA3AgBCgCGCkDAHw3AyALDAILIAQgBCgCQCkDeCAEKAIYKQMAfDcDIAwBCyAEKAJAQRJBABAUIARCfzcDWAwICwJAAkAgBCkDIEIAUw0AIAQoAkApA3BCAFIEQCAEKQMgIAQoAkApA3BWDQELIAQoAkApA2ggBCkDICAEKAJAKQNofFgNAQsgBCgCQEESQQAQFCAEQn83A1gMCAsgBCgCQCAEKQMgNwN4IAQoAhwEQCAEKAJAKAIcIAQoAkApA3ggBCgCQCkDaHwgBCgCQBCfAUEASARAIARCfzcDWAwJCwsgBEIANwNYDAcLIAQCfyAEKQNIQhBUBEAgBCgCQEESQQAQFEEADAELIAQoAlALNgIUIAQoAhRFBEAgBEJ/NwNYDAcLIAQoAkAoAoQBIAQoAhQpAwAgBCgCFCgCCCAEKAJAEGpBAEgEQCAEQn83A1gMBwsgBEIANwNYDAYLIAQpA0hCOFQEQCAEQn83A1gMBgsCfyMAQRBrIgAgBCgCQEHYAGo2AgwgACgCDCgCAAsEQCAEKAJAAn8jAEEQayIAIAQoAkBB2ABqNgIMIAAoAgwoAgALAn8jAEEQayIAIAQoAkBB2ABqNgIMIAAoAgwoAgQLEBQgBEJ/NwNYDAYLIAQoAlAiACAEKAJAIgEpACA3AAAgACABKQBQNwAwIAAgASkASDcAKCAAIAEpAEA3ACAgACABKQA4NwAYIAAgASkAMDcAECAAIAEpACg3AAggBEI4NwNYDAULIAQgBCgCQCkDEDcDWAwECyAEIAQoAkApA3g3A1gMAwsgBCAEKAJAKAKEARCjATcDCCAEKQMIQgBTBEAgBCgCQEEeQbSbASgCABAUIARCfzcDWAwDCyAEIAQpAwg3A1gMAgsgBCgCQCgChAEiACgCTEEAThogACAAKAIAQU9xNgIAIAQCfyAEKAJQIQEgBCkDSKciACAAAn8gBCgCQCgChAEiAygCTEF/TARAIAEgACADEHEMAQsgASAAIAMQcQsiAUYNABogAQs2AgQCQCAEKQNIIAQoAgStUQRAAn8gBCgCQCgChAEiACgCTEF/TARAIAAoAgAMAQsgACgCAAtBBXZBAXFFDQELIAQoAkBBBkG0mwEoAgAQFCAEQn83A1gMAgsgBCAEKAIErTcDWAwBCyAEKAJAQRxBABAUIARCfzcDWAsgBCkDWCECIARB4ABqJAAgAgsJACAAKAI8EAUL5AEBBH8jAEEgayIDJAAgAyABNgIQIAMgAiAAKAIwIgRBAEdrNgIUIAAoAiwhBSADIAQ2AhwgAyAFNgIYQX8hBAJAAkAgACgCPCADQRBqQQIgA0EMahAGIgUEf0G0mwEgBTYCAEF/BUEAC0UEQCADKAIMIgRBAEoNAQsgACAAKAIAIARBMHFBEHNyNgIADAELIAQgAygCFCIGTQ0AIAAgACgCLCIFNgIEIAAgBSAEIAZrajYCCCAAKAIwBEAgACAFQQFqNgIEIAEgAmpBAWsgBS0AADoAAAsgAiEECyADQSBqJAAgBAv0AgEHfyMAQSBrIgMkACADIAAoAhwiBTYCECAAKAIUIQQgAyACNgIcIAMgATYCGCADIAQgBWsiATYCFCABIAJqIQVBAiEHIANBEGohAQJ/AkACQCAAKAI8IANBEGpBAiADQQxqEAMiBAR/QbSbASAENgIAQX8FQQALRQRAA0AgBSADKAIMIgRGDQIgBEF/TA0DIAEgBCABKAIEIghLIgZBA3RqIgkgBCAIQQAgBhtrIgggCSgCAGo2AgAgAUEMQQQgBhtqIgkgCSgCACAIazYCACAFIARrIQUgACgCPCABQQhqIAEgBhsiASAHIAZrIgcgA0EMahADIgQEf0G0mwEgBDYCAEF/BUEAC0UNAAsLIAVBf0cNAQsgACAAKAIsIgE2AhwgACABNgIUIAAgASAAKAIwajYCECACDAELIABBADYCHCAAQgA3AxAgACAAKAIAQSByNgIAQQAgB0ECRg0AGiACIAEoAgRrCyEAIANBIGokACAAC1IBAX8jAEEQayIDJAAgACgCPCABpyABQiCIpyACQf8BcSADQQhqEA0iAAR/QbSbASAANgIAQX8FQQALIQAgAykDCCEBIANBEGokAEJ/IAEgABsL1QQBBX8jAEGwAWsiASQAIAEgADYCqAEgASgCqAEQOAJAAkAgASgCqAEoAgBBAE4EQCABKAKoASgCAEGAFCgCAEgNAQsgASABKAKoASgCADYCECABQSBqQY8SIAFBEGoQbyABQQA2AqQBIAEgAUEgajYCoAEMAQsgASABKAKoASgCAEECdEGAE2ooAgA2AqQBAkACQAJAAkAgASgCqAEoAgBBAnRBkBRqKAIAQQFrDgIAAQILIAEoAqgBKAIEIQJBkJkBKAIAIQRBACEAAkACQANAIAIgAEGgiAFqLQAARwRAQdcAIQMgAEEBaiIAQdcARw0BDAILCyAAIgMNAEGAiQEhAgwBC0GAiQEhAANAIAAtAAAhBSAAQQFqIgIhACAFDQAgAiEAIANBAWsiAw0ACwsgBCgCFBogASACNgKgAQwCCyMAQRBrIgAgASgCqAEoAgQ2AgwgAUEAIAAoAgxrQQJ0QajZAGooAgA2AqABDAELIAFBADYCoAELCwJAIAEoAqABRQRAIAEgASgCpAE2AqwBDAELIAEgASgCoAEQLgJ/IAEoAqQBBEAgASgCpAEQLkECagwBC0EAC2pBAWoQGCIANgIcIABFBEAgAUG4EygCADYCrAEMAQsgASgCHCEAAn8gASgCpAEEQCABKAKkAQwBC0H6EgshA0HfEkH6EiABKAKkARshAiABIAEoAqABNgIIIAEgAjYCBCABIAM2AgAgAEG+CiABEG8gASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAsIAEEBQTgQfwszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGRogACAAKAIUIAFqNgIUIAILjwUCBn4BfyABIAEoAgBBD2pBcHEiAUEQajYCACAAAnwgASkDACEDIAEpAwghBiMAQSBrIggkAAJAIAZC////////////AIMiBEKAgICAgIDAgDx9IARCgICAgICAwP/DAH1UBEAgBkIEhiADQjyIhCEEIANC//////////8PgyIDQoGAgICAgICACFoEQCAEQoGAgICAgICAwAB8IQIMAgsgBEKAgICAgICAgEB9IQIgA0KAgICAgICAgAiFQgBSDQEgAiAEQgGDfCECDAELIANQIARCgICAgICAwP//AFQgBEKAgICAgIDA//8AURtFBEAgBkIEhiADQjyIhEL/////////A4NCgICAgICAgPz/AIQhAgwBC0KAgICAgICA+P8AIQIgBEL///////+//8MAVg0AQgAhAiAEQjCIpyIAQZH3AEkNACADIQIgBkL///////8/g0KAgICAgIDAAIQiBSEHAkAgAEGB9wBrIgFBwABxBEAgAiABQUBqrYYhB0IAIQIMAQsgAUUNACAHIAGtIgSGIAJBwAAgAWutiIQhByACIASGIQILIAggAjcDECAIIAc3AxgCQEGB+AAgAGsiAEHAAHEEQCAFIABBQGqtiCEDQgAhBQwBCyAARQ0AIAVBwAAgAGuthiADIACtIgKIhCEDIAUgAoghBQsgCCADNwMAIAggBTcDCCAIKQMI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ADYCtC0gASgCFEEERgRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQEQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUECNgIcDAILIAFBAzYCHAwBCyABKAIYKAKgLQRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQAQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUEANgIcDAILCyABQQE2AhwLIAEoAhwhAiABQSBqJAAgAgwBCwJ/IAAoAiwoAogBQQNGBEAgACgCLCECIAAoAjQhAyMAQTBrIgEkACABIAI2AiggASADNgIkAkADQAJAIAEoAigoAnRBggJNBEAgASgCKBBcAkAgASgCKCgCdEGCAksNACABKAIkDQAgAUEANgIsDAQLIAEoAigoAnRFDQELIAEoAihBADYCYAJAIAEoAigoAnRBA0kNACABKAIoKAJsRQ0AIAEgASgCKCgCOCABKAIoKAJsakEBazYCGCABIAEoAhgtAAA2AhwgASgCHCECIAEgASgCGCIDQQFqNgIYAkAgAy0AASACRw0AIAEoAhwhAiABIAEoAhgiA0EBajYCGCADLQABIAJHDQAgASgCHCECIAEgASgCGCIDQQFqNgIYIAMtAAEgAkcNACABIAEoAigoAjggASgCKCgCbGpBggJqNgIUA0AgASgCHCECIAEgASgCGCIDQQFqNgIYAn9BACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABog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AS8BEiECIAEgASgCSCIDQQFqNgJIIAMgAjoAAAwCCyABKAIMQRBxBEAgASABLwESNgIIIAEgASgCDEEPcTYCDCABKAIMBEAgASgCKCABKAIMSQRAIAEgASgCUCICQQFqNgJQIAEgASgCLCACLQAAIAEoAih0ajYCLCABIAEoAihBCGo2AigLIAEgASgCCCABKAIsQQEgASgCDHRBAWtxajYCCCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoCyABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiAgASgCLCABKAIYcUECdGooAQA2ARACQANAIAEgAS0AETYCDCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgAS0AEDYCDCABKAIMQRBxBEAgASABLwESNgIEIAEgASgCDEEPcTYCDCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKAsLIAEgASgCBCABKAIsQQEgASgCDHRBAWtxajYCBCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgASgCSCABKAJEazYCDAJAIAEoAgQgASgCDEsEQCABIAEoAgQgASgCDGs2AgwgASgCDCABKAI4SwRAIAEoAlQoAsQ3BEAgASgCXEHdDDYCGCABKAJUQdH+ADYCBAwKCwsgASABKAIwNgIAAkAgASgCNEUEQCABIAEoAgAgASgCPCABKAIMa2o2AgAgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAkggASgCBGs2AgALDAELAkAgASgCNCABKAIMSQRAIAEgASgCACABKAI8IAEoAjRqIAEoAgxrajYCACABIAEoAgwgASgCNGs2AgwgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAjA2AgAgASgCNCABKAIISQRAIAEgASgCNDYCDCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsMAQsgASABKAIAIAEoAjQgASgCDGtqNgIAIAEoAgwgASgCCEkEQCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsLA0AgASgCCEECSwRAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCCEEDazYCCAwBCwsMAQsgASABKAJIIAEoAgRrNgIAA0AgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIIQQNrNgIIIAEoAghBAksNAAsLIAEoAggEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEoAghBAUsEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAACwsMAgsgASgCDEHAAHFFBEAgASABKAIgIAEvARIgASgCLEEBIAEoAgx0QQFrcWpBAnRqKAEANgEQDAELCyAB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AG5hbgAvZGV2L3VyYW5kb20AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoAGluZgBpbnZhbGlkIHdpbmRvdyBzaXplAFJlYWQtb25seSBhcmNoaXZlAE5vdCBhIHppcCBhcmNoaXZlAFJlc291cmNlIHN0aWxsIGluIHVzZQBNYWxsb2MgZmFpbHVyZQBpbnZhbGlkIGJsb2NrIHR5cGUARmFpbHVyZSB0byBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUAQ2FuJ3Qgb3BlbiBmaWxlAE5vIHN1Y2ggZmlsZQBQcmVtYXR1cmUgZW5kIG9mIGZpbGUAQ2FuJ3QgcmVtb3ZlIGZpbGUAaW52YWxpZCBsaXRlcmFsL2xlbmd0aCBjb2RlAGludmFsaWQgZGlzdGFuY2UgY29kZQB1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZABzdHJlYW0gZW5kAENvbXByZXNzZWQgZGF0YSBpbnZhbGlkAE11bHRpLWRpc2sgemlwIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQAT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQARW5jcnlwdGlvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABFbnRyeSBoYXMgYmVlbiBkZWxldGVkAENvbnRhaW5pbmcgemlwIGFyY2hpdmUgd2FzIGNsb3NlZABDbG9zaW5nIHppcCBhcmNoaXZlIGZhaWxlZABSZW5hbWluZyB0ZW1wb3JhcnkgZmlsZSBmYWlsZWQARW50cnkgaGFzIGJlZW4gY2hhbmdlZABObyBwYXNzd29yZCBwcm92aWRlZABXcm9uZyBwYXNzd29yZCBwcm92aWRlZABVbmtub3duIGVycm9yICVkAHJiAHIrYgByd2EAJXMuWFhYWFhYAE5BTgBJTkYAQUUAMS4yLjExAC9wcm9jL3NlbGYvZmQvAC4AKG51bGwpADogAFBLBgcA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0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJANMBCQAzAAkAMwEJALMACQCzAQkAcwAJAHMBCQDzAAkA8wEJAAsACQALAQkAiwAJAIsBCQBLAAkASwEJAMsACQDLAQkAKwAJACsBCQCrAAkAqwEJAGsACQBrAQkA6wAJAOsBCQAbAAkAGwEJAJsACQCbAQkAWwAJAFsBCQDbAAkA2wEJADsACQA7AQkAuwAJALsBCQB7AAkAewEJAPsACQD7AQkABwAJAAcBCQCHAAkAhwEJAEcACQBHAQkAxwAJAMcBCQAnAAkAJwEJAKcACQCnAQkAZwAJAGcBCQDnAAkA5wEJABcACQAXAQkAlwAJAJcBCQBXAAkAVwEJANcACQDXAQkANwAJADcBCQC3AAkAtwEJAHcACQB3AQkA9wAJAPcBCQAPAAkADwEJAI8ACQCPAQkATwAJAE8BCQDPAAkAzwEJAC8ACQAvAQkArwAJAK8BCQBvAAkAbwEJAO8ACQDvAQkAHwAJAB8BCQCfAAkAnwEJAF8ACQBfAQkA3wAJAN8BCQA/AAkAPwEJAL8ACQC/AQkAfwAJAH8BCQD/AAkA/wEJAAAABwBAAAcAIAAHAGAABwAQAAcAUAAHADAABwBwAAcACAAHAEgABwAoAAcAaAAHABgABwBYAAcAOAAHAHgABwAEAAcARAAHACQABwBkAAcAFAAHAFQABwA0AAcAdAAHAAMACACDAAgAQwAIAMMACAAjAAgAowAIAGMACADjAAgAAAAFABAABQAIAAUAGAAFAAQABQAUAAUADAAFABwABQACAAUAEgAFAAoABQAaAAUABgAFABYABQAOAAUAHgAFAAEABQARAAUACQAFABkABQAFAAUAFQAFAA0ABQAdAAUAAwAFABMABQALAAUAGwAFAAcABQAXAAUAQbDqAAtNAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQaDrAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdDsAAsjAgAAAAMAAAAHAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AQYTtAAtpAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4AAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAEGE7gALegEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAAABAACAAQAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAMS4yLjExAEGI7wALbQcAAAAEAAQACAAEAAgAAAAEAAUAEAAIAAgAAAAEAAYAIAAgAAgAAAAEAAQAEAAQAAkAAAAIABAAIAAgAAkAAAAIABAAgACAAAkAAAAIACAAgAAAAQkAAAAgAIAAAgEABAkAAAAgAAIBAgEAEAkAQYDwAAulAgMABAAFAAYABwAIAAkACgALAA0ADwARABMAFwAbAB8AIwArADMAOwBDAFMAYwBzAIMAowDDAOMAAgEAAAAAAAAQABAAEAAQABAAEAAQABAAEQARABEAEQASABIAEgASABMAEwATABMAFAAUABQAFAAVABUAFQAVABAATQDKAAAAAQACAAMABAAFAAcACQANABEAGQAhADEAQQBhAIEAwQABAYEBAQIBAwEEAQYBCAEMARABGAEgATABQAFgAAAAABAAEAAQABAAEQARABIAEgATABMAFAAUABUAFQAWABYAFwAXABgAGAAZABkAGgAaABsAGwAcABwAHQAdAEAAQAAQABEAEgAAAAgABwAJAAYACgAFAAsABAAMAAMADQACAA4AAQAPAEGw8gALwRFgBwAAAAhQAAAIEAAUCHMAEgcfAAAIcAAACDAAAAnAABAHCgAACGAAAAggAAAJoAAACAAAAAiAAAAIQAAACeAAEAcGAAAIWAAACBgAAAmQABMHOwAACHgAAAg4AAAJ0AARBxEAAAhoAAAIKAAACbAAAAgIAAAIiAAACEgAAAnwABAHBAAACFQAAAgUABUI4wATBysAAAh0AAAINAAACcgAEQcNAAAIZAAACCQAAAmoAAAIBAAACIQAAAhEAAAJ6AAQBwgAAAhcAAAIHAAACZgAFAdTAAAIfAAACDwAAAnYABIHFwAACGwAAAgsAAAJuAAACAwAAAiMAAAITAAACfgAEAcDAAAIUgAACBIAFQijABMHIwAACHIAAAgyAAAJxAARBwsAAAhiAAAIIgAACaQAAAgCAAAIggAACEIAAAnkABAHBwAACFoAAAgaAAAJlAAUB0MAAAh6AAAIOgAACdQAEgcTAAAIagAACCoAAAm0AAAICgAACIoAAAhKAAAJ9AAQBwUAAAhWAAAIFgBACAAAEwczAAAIdgAACDYAAAnMABEHDwAACGYAAAgmAAAJrAAACAYAAAiGAAAIRgAACewAEAcJAAAIXgAACB4AAAmcABQHYwAACH4AAAg+AAAJ3AASBxsAAAhuAAAILgAACbwAAAgOAAAIjgAACE4AAAn8AGAHAAAACFEAAAgRABUIgwASBx8AAAhxAAAIMQAACcIAEAcKAAAIYQAACCEAAAmiAAAIAQAACIEAAAhBAAAJ4gAQBwYAAAhZAAAIGQAACZIAEwc7AAAIeQAACDkAAAnSABEHEQAACGkAAAgpAAAJsgAACAkAAAiJAAAISQAACfIAEAcEAAAIVQAACBUAEAgCARMHKwAACHUAAAg1AAAJygARBw0AAAhlAAAIJQAACaoAAAgFAAAIhQAACEUAAAnqABAHCAAACF0AAAgdAAAJmgAUB1MAAAh9AAAIPQAACdoAEgcXAAAIbQAACC0AAAm6AAAIDQAACI0AAAhNAAAJ+gAQBwMAAAhTAAAIEwAVCMMAEwcjAAAIcwAACDMAAAnGABEHCwAACGMAAAgjAAAJpgAACAMAAAiDAAAIQwAACeYAEAcHAAAIWwAACBsAAAmWABQHQwAACHsAAAg7AAAJ1gASBxMAAAhrAAAIKwAACbYAAAgLAAAIiwAACEsAAAn2ABAHBQAACFcAAAgXAEAIAAATBzMAAAh3AAAINwAACc4AEQcPAAAIZwAACCcAAAmuAAAIBwAACIcAAAhHAAAJ7gAQBwkAAAhfAAAIHwAACZ4AFAdjAAAIfwAACD8AAAneABIHGwAACG8AAAgvAAAJvgAACA8AAAiPAAAITwAACf4AYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwQAQBwoAAAhgAAAIIAAACaEAAAgAAAAIgAAACEAAAAnhABAHBgAACFgAAAgYAAAJkQATBzsAAAh4AAAIOAAACdEAEQcRAAAIaAAACCgAAAmxAAAICAAACIgAAAhIAAAJ8QAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnJABEHDQAACGQAAAgkAAAJqQAACAQAAAiEAAAIRAAACekAEAcIAAAIXAAACBwAAAmZABQHUwAACHwAAAg8AAAJ2QASBxcAAAhsAAAILAAACbkAAAgMAAAIjAAACEwAAAn5ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcUAEQcLAAAIYgAACCIAAAmlAAAIAgAACIIAAAhCAAAJ5QAQBwcAAAhaAAAIGgAACZUAFAdDAAAIegAACDoAAAnVABIHEwAACGoAAAgqAAAJtQAACAoAAAiKAAAISgAACfUAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzQARBw8AAAhmAAAIJgAACa0AAAgGAAAIhgAACEYAAAntABAHCQAACF4AAAgeAAAJnQAUB2MAAAh+AAAIPgAACd0AEgcbAAAIbgAACC4AAAm9AAAIDgAACI4AAAhOAAAJ/QBgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnDABAHCgAACGEAAAghAAAJowAACAEAAAiBAAAIQQAACeMAEAcGAAAIWQAACBkAAAmTABMHOwAACHkAAAg5AAAJ0wARBxEAAAhpAAAIKQAACbMAAAgJAAAIiQAACEkAAAnzABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcsAEQcNAAAIZQAACCUAAAmrAAAIBQAACIUAAAhFAAAJ6wAQBwgAAAhdAAAIHQAACZsAFAdTAAAIfQAACD0AAAnbABIHFwAACG0AAAgtAAAJuwAACA0AAAiNAAAITQAACfsAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxwARBwsAAAhjAAAIIwAACacAAAgDAAAIgwAACEMAAAnnABAHBwAACFsAAAgbAAAJlwAUB0MAAAh7AAAIOwAACdcAEgcTAAAIawAACCsAAAm3AAAICwAACIsAAAhLAAAJ9wAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnPABEHDwAACGcAAAgnAAAJrwAACAcAAAiHAAAIRwAACe8AEAcJAAAIXwAACB8AAAmfABQHYwAACH8AAAg/AAAJ3wASBxsAAAhvAAAILwAACb8AAAgPAAAIjwAACE8AAAn/ABAFAQAXBQEBEwURABsFARARBQUAGQUBBBUFQQAdBQFAEAUDABgFAQIUBSEAHAUBIBIFCQAaBQEIFgWBAEAFAAAQBQIAFwWBARMFGQAbBQEYEQUHABkFAQYVBWEAHQUBYBAFBAAYBQEDFAUxABwFATASBQ0AGgUBDBYFwQBABQAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAQYGEAQshCwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAEG7hAELAQwAQceEAQsVDAAAAAAMAAAAAAkMAAAAAAAMAAAMAEH1hAELAQ4AQYGFAQsVDQAAAAQNAAAAAAkOAAAAAAAOAAAOAEGvhQELARAAQbuFAQseDwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAEHyhQELDhIAAAASEhIAAAAAAAAJAEGjhgELAQsAQa+GAQsVCgAAAAAKAAAAAAkLAAAAAAALAAALAEHdhgELAQwAQemGAQsnDAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGAEG0hwELARkAQduHAQsF//////8AQaCIAQtXGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAEGAiQELig5JbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBObyBlcnJvciBpbmZvcm1hdGlvbgBBkJcBC1JQUFAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAEAAAAIAAAAlEsAALRLAEGQmQELAgxQAEHImQELCR8AAADkTAAAAwBB5JkBC4wBLfRRWM+MscBG9rXLKTEDxwRbcDC0Xf0geH+LmthZKVBoSImrp1YDbP+3zYg/1He0K6WjcPG65Kj8QYP92W/hinovLXSWBx8NCV4Ddixw90ClLKdvV0GoqnTfoFhkA0rHxDxTrq9fGAQVseNtKIarDKS/Q/DpUIE5VxZSN/////////////////////8=";Ou(Po)||(Po=h(Po));function Mu(d){try{if(d==Po&&z)return new Uint8Array(z);var E=xa(d);if(E)return E;if(m)return m(d);throw"sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"}catch(I){vr(I)}}function vh(d,E){var I,D,M;try{M=Mu(d),D=new WebAssembly.Module(M),I=new WebAssembly.Instance(D,E)}catch(ie){var _=ie.toString();throw k("failed to compile wasm module: "+_),(_.includes("imported Memory")||_.includes("memory import"))&&k("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)."),ie}return[I,D]}function kh(){var d={a:Pa};function E(M,_){var ie=M.exports;t.asm=ie,A=t.asm.u,Ei(A.buffer),Qr=t.asm.pa,RA(t.asm.v),LA("wasm-instantiate")}if(NA("wasm-instantiate"),t.instantiateWasm)try{var I=t.instantiateWasm(d,E);return I}catch(M){return k("Module.instantiateWasm callback failed with error: "+M),!1}var D=vh(Po,d);return E(D[0]),t.asm}var Dr,Ae;function Do(d){for(;d.length>0;){var E=d.shift();if(typeof E=="function"){E(t);continue}var I=E.func;typeof I=="number"?E.arg===void 0?Qr.get(I)():Qr.get(I)(E.arg):I(E.arg===void 0?null:E.arg)}}function Yn(d,E){var I=new Date(fe[d>>2]*1e3);fe[E>>2]=I.getUTCSeconds(),fe[E+4>>2]=I.getUTCMinutes(),fe[E+8>>2]=I.getUTCHours(),fe[E+12>>2]=I.getUTCDate(),fe[E+16>>2]=I.getUTCMonth(),fe[E+20>>2]=I.getUTCFullYear()-1900,fe[E+24>>2]=I.getUTCDay(),fe[E+36>>2]=0,fe[E+32>>2]=0;var D=Date.UTC(I.getUTCFullYear(),0,1,0,0,0,0),M=(I.getTime()-D)/(1e3*60*60*24)|0;return fe[E+28>>2]=M,Yn.GMTString||(Yn.GMTString=Fe("GMT")),fe[E+40>>2]=Yn.GMTString,E}function Uu(d,E){return Yn(d,E)}var St={splitPath:function(d){var E=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return E.exec(d).slice(1)},normalizeArray:function(d,E){for(var I=0,D=d.length-1;D>=0;D--){var M=d[D];M==="."?d.splice(D,1):M===".."?(d.splice(D,1),I++):I&&(d.splice(D,1),I--)}if(E)for(;I;I--)d.unshift("..");return d},normalize:function(d){var E=d.charAt(0)==="/",I=d.substr(-1)==="/";return d=St.normalizeArray(d.split("/").filter(function(D){return!!D}),!E).join("/"),!d&&!E&&(d="."),d&&I&&(d+="/"),(E?"/":"")+d},dirname:function(d){var E=St.splitPath(d),I=E[0],D=E[1];return!I&&!D?".":(D&&(D=D.substr(0,D.length-1)),I+D)},basename:function(d){if(d==="/")return"/";d=St.normalize(d),d=d.replace(/\/$/,"");var E=d.lastIndexOf("/");return E===-1?d:d.substr(E+1)},extname:function(d){return St.splitPath(d)[3]},join:function(){var d=Array.prototype.slice.call(arguments,0);return St.normalize(d.join("/"))},join2:function(d,E){return St.normalize(d+"/"+E)}};function Vl(){if(typeof crypto=="object"&&typeof crypto.getRandomValues=="function"){var d=new Uint8Array(1);return function(){return crypto.getRandomValues(d),d[0]}}else if(g)try{var E=require("crypto");return function(){return E.randomBytes(1)[0]}}catch(I){}return function(){vr("randomDevice")}}var qn={resolve:function(){for(var d="",E=!1,I=arguments.length-1;I>=-1&&!E;I--){var D=I>=0?arguments[I]:S.cwd();if(typeof D!="string")throw new TypeError("Arguments to path.resolve must be strings");if(!D)return"";d=D+"/"+d,E=D.charAt(0)==="/"}return d=St.normalizeArray(d.split("/").filter(function(M){return!!M}),!E).join("/"),(E?"/":"")+d||"."},relative:function(d,E){d=qn.resolve(d).substr(1),E=qn.resolve(E).substr(1);function I(_e){for(var ot=0;ot<_e.length&&_e[ot]==="";ot++);for(var Bt=_e.length-1;Bt>=0&&_e[Bt]==="";Bt--);return ot>Bt?[]:_e.slice(ot,Bt-ot+1)}for(var D=I(d.split("/")),M=I(E.split("/")),_=Math.min(D.length,M.length),ie=_,we=0;we<_;we++)if(D[we]!==M[we]){ie=we;break}for(var me=[],we=ie;we<D.length;we++)me.push("..");return me=me.concat(M.slice(ie)),me.join("/")}},ps={ttys:[],init:function(){},shutdown:function(){},register:function(d,E){ps.ttys[d]={input:[],output:[],ops:E},S.registerDevice(d,ps.stream_ops)},stream_ops:{open:function(d){var E=ps.ttys[d.node.rdev];if(!E)throw new S.ErrnoError(43);d.tty=E,d.seekable=!1},close:function(d){d.tty.ops.flush(d.tty)},flush:function(d){d.tty.ops.flush(d.tty)},read:function(d,E,I,D,M){if(!d.tty||!d.tty.ops.get_char)throw new S.ErrnoError(60);for(var _=0,ie=0;ie<D;ie++){var we;try{we=d.tty.ops.get_char(d.tty)}catch(me){throw new S.ErrnoError(29)}if(we===void 0&&_===0)throw new S.ErrnoError(6);if(we==null)break;_++,E[I+ie]=we}return _&&(d.node.timestamp=Date.now()),_},write:function(d,E,I,D,M){if(!d.tty||!d.tty.ops.put_char)throw new S.ErrnoError(60);try{for(var _=0;_<D;_++)d.tty.ops.put_char(d.tty,E[I+_])}catch(ie){throw new S.ErrnoError(29)}return D&&(d.node.timestamp=Date.now()),_}},default_tty_ops:{get_char:function(d){if(!d.input.length){var E=null;if(g){var I=256,D=Buffer.alloc?Buffer.alloc(I):new Buffer(I),M=0;try{M=y.readSync(process.stdin.fd,D,0,I,null)}catch(_){if(_.toString().includes("EOF"))M=0;else throw _}M>0?E=D.slice(0,M).toString("utf-8"):E=null}else typeof window!="undefined"&&typeof window.prompt=="function"?(E=window.prompt("Input: "),E!==null&&(E+=` -`)):typeof readline=="function"&&(E=readline(),E!==null&&(E+=` -`));if(!E)return null;d.input=OA(E,!0)}return d.input.shift()},put_char:function(d,E){E===null||E===10?(v(Ge(d.output,0)),d.output=[]):E!=0&&d.output.push(E)},flush:function(d){d.output&&d.output.length>0&&(v(Ge(d.output,0)),d.output=[])}},default_tty1_ops:{put_char:function(d,E){E===null||E===10?(k(Ge(d.output,0)),d.output=[]):E!=0&&d.output.push(E)},flush:function(d){d.output&&d.output.length>0&&(k(Ge(d.output,0)),d.output=[])}}};function ds(d){for(var E=Y(d,65536),I=Et(E);d<E;)pe[I+d++]=0;return I}var pt={ops_table:null,mount:function(d){return pt.createNode(null,"/",16384|511,0)},createNode:function(d,E,I,D){if(S.isBlkdev(I)||S.isFIFO(I))throw new S.ErrnoError(63);pt.ops_table||(pt.ops_table={dir:{node:{getattr:pt.node_ops.getattr,setattr:pt.node_ops.setattr,lookup:pt.node_ops.lookup,mknod:pt.node_ops.mknod,rename:pt.node_ops.rename,unlink:pt.node_ops.unlink,rmdir:pt.node_ops.rmdir,readdir:pt.node_ops.readdir,symlink:pt.node_ops.symlink},stream:{llseek:pt.stream_ops.llseek}},file:{node:{getattr:pt.node_ops.getattr,setattr:pt.node_ops.setattr},stream:{llseek:pt.stream_ops.llseek,read:pt.stream_ops.read,write:pt.stream_ops.write,allocate:pt.stream_ops.allocate,mmap:pt.stream_ops.mmap,msync:pt.stream_ops.msync}},link:{node:{getattr:pt.node_ops.getattr,setattr:pt.node_ops.setattr,readlink:pt.node_ops.readlink},stream:{}},chrdev:{node:{getattr:pt.node_ops.getattr,setattr:pt.node_ops.setattr},stream:S.chrdev_stream_ops}});var M=S.createNode(d,E,I,D);return S.isDir(M.mode)?(M.node_ops=pt.ops_table.dir.node,M.stream_ops=pt.ops_table.dir.stream,M.contents={}):S.isFile(M.mode)?(M.node_ops=pt.ops_table.file.node,M.stream_ops=pt.ops_table.file.stream,M.usedBytes=0,M.contents=null):S.isLink(M.mode)?(M.node_ops=pt.ops_table.link.node,M.stream_ops=pt.ops_table.link.stream):S.isChrdev(M.mode)&&(M.node_ops=pt.ops_table.chrdev.node,M.stream_ops=pt.ops_table.chrdev.stream),M.timestamp=Date.now(),d&&(d.contents[E]=M,d.timestamp=M.timestamp),M},getFileDataAsTypedArray:function(d){return d.contents?d.contents.subarray?d.contents.subarray(0,d.usedBytes):new Uint8Array(d.contents):new Uint8Array(0)},expandFileStorage:function(d,E){var I=d.contents?d.contents.length:0;if(!(I>=E)){var D=1024*1024;E=Math.max(E,I*(I<D?2:1.125)>>>0),I!=0&&(E=Math.max(E,256));var M=d.contents;d.contents=new Uint8Array(E),d.usedBytes>0&&d.contents.set(M.subarray(0,d.usedBytes),0)}},resizeFileStorage:function(d,E){if(d.usedBytes!=E)if(E==0)d.contents=null,d.usedBytes=0;else{var I=d.contents;d.contents=new Uint8Array(E),I&&d.contents.set(I.subarray(0,Math.min(E,d.usedBytes))),d.usedBytes=E}},node_ops:{getattr:function(d){var E={};return E.dev=S.isChrdev(d.mode)?d.id:1,E.ino=d.id,E.mode=d.mode,E.nlink=1,E.uid=0,E.gid=0,E.rdev=d.rdev,S.isDir(d.mode)?E.size=4096:S.isFile(d.mode)?E.size=d.usedBytes:S.isLink(d.mode)?E.size=d.link.length:E.size=0,E.atime=new Date(d.timestamp),E.mtime=new Date(d.timestamp),E.ctime=new Date(d.timestamp),E.blksize=4096,E.blocks=Math.ceil(E.size/E.blksize),E},setattr:function(d,E){E.mode!==void 0&&(d.mode=E.mode),E.timestamp!==void 0&&(d.timestamp=E.timestamp),E.size!==void 0&&pt.resizeFileStorage(d,E.size)},lookup:function(d,E){throw S.genericErrors[44]},mknod:function(d,E,I,D){return pt.createNode(d,E,I,D)},rename:function(d,E,I){if(S.isDir(d.mode)){var D;try{D=S.lookupNode(E,I)}catch(_){}if(D)for(var M in D.contents)throw new S.ErrnoError(55)}delete d.parent.contents[d.name],d.parent.timestamp=Date.now(),d.name=I,E.contents[I]=d,E.timestamp=d.parent.timestamp,d.parent=E},unlink:function(d,E){delete d.contents[E],d.timestamp=Date.now()},rmdir:function(d,E){var I=S.lookupNode(d,E);for(var D in I.contents)throw new S.ErrnoError(55);delete d.contents[E],d.timestamp=Date.now()},readdir:function(d){var E=[".",".."];for(var I in d.contents)!d.contents.hasOwnProperty(I)||E.push(I);return E},symlink:function(d,E,I){var D=pt.createNode(d,E,511|40960,0);return D.link=I,D},readlink:function(d){if(!S.isLink(d.mode))throw new S.ErrnoError(28);return d.link}},stream_ops:{read:function(d,E,I,D,M){var _=d.node.contents;if(M>=d.node.usedBytes)return 0;var ie=Math.min(d.node.usedBytes-M,D);if(ie>8&&_.subarray)E.set(_.subarray(M,M+ie),I);else for(var we=0;we<ie;we++)E[I+we]=_[M+we];return ie},write:function(d,E,I,D,M,_){if(E.buffer===pe.buffer&&(_=!1),!D)return 0;var ie=d.node;if(ie.timestamp=Date.now(),E.subarray&&(!ie.contents||ie.contents.subarray)){if(_)return ie.contents=E.subarray(I,I+D),ie.usedBytes=D,D;if(ie.usedBytes===0&&M===0)return ie.contents=E.slice(I,I+D),ie.usedBytes=D,D;if(M+D<=ie.usedBytes)return ie.contents.set(E.subarray(I,I+D),M),D}if(pt.expandFileStorage(ie,M+D),ie.contents.subarray&&E.subarray)ie.contents.set(E.subarray(I,I+D),M);else for(var we=0;we<D;we++)ie.contents[M+we]=E[I+we];return ie.usedBytes=Math.max(ie.usedBytes,M+D),D},llseek:function(d,E,I){var D=E;if(I===1?D+=d.position:I===2&&S.isFile(d.node.mode)&&(D+=d.node.usedBytes),D<0)throw new S.ErrnoError(28);return D},allocate:function(d,E,I){pt.expandFileStorage(d.node,E+I),d.node.usedBytes=Math.max(d.node.usedBytes,E+I)},mmap:function(d,E,I,D,M,_){if(E!==0)throw new S.ErrnoError(28);if(!S.isFile(d.node.mode))throw new S.ErrnoError(43);var ie,we,me=d.node.contents;if(!(_&2)&&me.buffer===ve)we=!1,ie=me.byteOffset;else{if((D>0||D+I<me.length)&&(me.subarray?me=me.subarray(D,D+I):me=Array.prototype.slice.call(me,D,D+I)),we=!0,ie=ds(I),!ie)throw new S.ErrnoError(48);pe.set(me,ie)}return{ptr:ie,allocated:we}},msync:function(d,E,I,D,M){if(!S.isFile(d.node.mode))throw new S.ErrnoError(43);if(M&2)return 0;var _=pt.stream_ops.write(d,E,0,D,I,!1);return 0}}},Ro={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135},lt={isWindows:!1,staticInit:function(){lt.isWindows=!!process.platform.match(/^win/);var d={fs:Oe.constants};d.fs&&(d=d.fs),lt.flagsForNodeMap={1024:d.O_APPEND,64:d.O_CREAT,128:d.O_EXCL,256:d.O_NOCTTY,0:d.O_RDONLY,2:d.O_RDWR,4096:d.O_SYNC,512:d.O_TRUNC,1:d.O_WRONLY}},bufferFrom:function(d){return Buffer.alloc?Buffer.from(d):new Buffer(d)},convertNodeCode:function(d){var E=d.code;return Ro[E]},mount:function(d){return lt.createNode(null,"/",lt.getMode(d.opts.root),0)},createNode:function(d,E,I,D){if(!S.isDir(I)&&!S.isFile(I)&&!S.isLink(I))throw new S.ErrnoError(28);var M=S.createNode(d,E,I);return M.node_ops=lt.node_ops,M.stream_ops=lt.stream_ops,M},getMode:function(d){var E;try{E=Oe.lstatSync(d),lt.isWindows&&(E.mode=E.mode|(E.mode&292)>>2)}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}return E.mode},realPath:function(d){for(var E=[];d.parent!==d;)E.push(d.name),d=d.parent;return E.push(d.mount.opts.root),E.reverse(),St.join.apply(null,E)},flagsForNode:function(d){d&=~2097152,d&=~2048,d&=~32768,d&=~524288;var E=0;for(var I in lt.flagsForNodeMap)d&I&&(E|=lt.flagsForNodeMap[I],d^=I);if(d)throw new S.ErrnoError(28);return E},node_ops:{getattr:function(d){var E=lt.realPath(d),I;try{I=Oe.lstatSync(E)}catch(D){throw D.code?new S.ErrnoError(lt.convertNodeCode(D)):D}return lt.isWindows&&!I.blksize&&(I.blksize=4096),lt.isWindows&&!I.blocks&&(I.blocks=(I.size+I.blksize-1)/I.blksize|0),{dev:I.dev,ino:I.ino,mode:I.mode,nlink:I.nlink,uid:I.uid,gid:I.gid,rdev:I.rdev,size:I.size,atime:I.atime,mtime:I.mtime,ctime:I.ctime,blksize:I.blksize,blocks:I.blocks}},setattr:function(d,E){var I=lt.realPath(d);try{if(E.mode!==void 0&&(Oe.chmodSync(I,E.mode),d.mode=E.mode),E.timestamp!==void 0){var D=new Date(E.timestamp);Oe.utimesSync(I,D,D)}E.size!==void 0&&Oe.truncateSync(I,E.size)}catch(M){throw M.code?new S.ErrnoError(lt.convertNodeCode(M)):M}},lookup:function(d,E){var I=St.join2(lt.realPath(d),E),D=lt.getMode(I);return lt.createNode(d,E,D)},mknod:function(d,E,I,D){var M=lt.createNode(d,E,I,D),_=lt.realPath(M);try{S.isDir(M.mode)?Oe.mkdirSync(_,M.mode):Oe.writeFileSync(_,"",{mode:M.mode})}catch(ie){throw ie.code?new S.ErrnoError(lt.convertNodeCode(ie)):ie}return M},rename:function(d,E,I){var D=lt.realPath(d),M=St.join2(lt.realPath(E),I);try{Oe.renameSync(D,M)}catch(_){throw _.code?new S.ErrnoError(lt.convertNodeCode(_)):_}d.name=I},unlink:function(d,E){var I=St.join2(lt.realPath(d),E);try{Oe.unlinkSync(I)}catch(D){throw D.code?new S.ErrnoError(lt.convertNodeCode(D)):D}},rmdir:function(d,E){var I=St.join2(lt.realPath(d),E);try{Oe.rmdirSync(I)}catch(D){throw D.code?new S.ErrnoError(lt.convertNodeCode(D)):D}},readdir:function(d){var E=lt.realPath(d);try{return Oe.readdirSync(E)}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}},symlink:function(d,E,I){var D=St.join2(lt.realPath(d),E);try{Oe.symlinkSync(I,D)}catch(M){throw M.code?new S.ErrnoError(lt.convertNodeCode(M)):M}},readlink:function(d){var E=lt.realPath(d);try{return E=Oe.readlinkSync(E),E=ju.relative(ju.resolve(d.mount.opts.root),E),E}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}}},stream_ops:{open:function(d){var E=lt.realPath(d.node);try{S.isFile(d.node.mode)&&(d.nfd=Oe.openSync(E,lt.flagsForNode(d.flags)))}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}},close:function(d){try{S.isFile(d.node.mode)&&d.nfd&&Oe.closeSync(d.nfd)}catch(E){throw E.code?new S.ErrnoError(lt.convertNodeCode(E)):E}},read:function(d,E,I,D,M){if(D===0)return 0;try{return Oe.readSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M)}catch(_){throw new S.ErrnoError(lt.convertNodeCode(_))}},write:function(d,E,I,D,M){try{return Oe.writeSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M)}catch(_){throw new S.ErrnoError(lt.convertNodeCode(_))}},llseek:function(d,E,I){var D=E;if(I===1)D+=d.position;else if(I===2&&S.isFile(d.node.mode))try{var M=Oe.fstatSync(d.nfd);D+=M.size}catch(_){throw new S.ErrnoError(lt.convertNodeCode(_))}if(D<0)throw new S.ErrnoError(28);return D},mmap:function(d,E,I,D,M,_){if(E!==0)throw new S.ErrnoError(28);if(!S.isFile(d.node.mode))throw new S.ErrnoError(43);var ie=ds(I);return lt.stream_ops.read(d,pe,ie,I,D),{ptr:ie,allocated:!0}},msync:function(d,E,I,D,M){if(!S.isFile(d.node.mode))throw new S.ErrnoError(43);if(M&2)return 0;var _=lt.stream_ops.write(d,E,0,D,I,!1);return 0}}},mn={lookupPath:function(d){return{path:d,node:{mode:lt.getMode(d)}}},createStandardStreams:function(){S.streams[0]={fd:0,nfd:0,position:0,path:"",flags:0,tty:!0,seekable:!1};for(var d=1;d<3;d++)S.streams[d]={fd:d,nfd:d,position:0,path:"",flags:577,tty:!0,seekable:!1}},cwd:function(){return process.cwd()},chdir:function(){process.chdir.apply(void 0,arguments)},mknod:function(d,E){S.isDir(d)?Oe.mkdirSync(d,E):Oe.writeFileSync(d,"",{mode:E})},mkdir:function(){Oe.mkdirSync.apply(void 0,arguments)},symlink:function(){Oe.symlinkSync.apply(void 0,arguments)},rename:function(){Oe.renameSync.apply(void 0,arguments)},rmdir:function(){Oe.rmdirSync.apply(void 0,arguments)},readdir:function(){Oe.readdirSync.apply(void 0,arguments)},unlink:function(){Oe.unlinkSync.apply(void 0,arguments)},readlink:function(){return Oe.readlinkSync.apply(void 0,arguments)},stat:function(){return Oe.statSync.apply(void 0,arguments)},lstat:function(){return Oe.lstatSync.apply(void 0,arguments)},chmod:function(){Oe.chmodSync.apply(void 0,arguments)},fchmod:function(){Oe.fchmodSync.apply(void 0,arguments)},chown:function(){Oe.chownSync.apply(void 0,arguments)},fchown:function(){Oe.fchownSync.apply(void 0,arguments)},truncate:function(){Oe.truncateSync.apply(void 0,arguments)},ftruncate:function(d,E){if(E<0)throw new S.ErrnoError(28);Oe.ftruncateSync.apply(void 0,arguments)},utime:function(){Oe.utimesSync.apply(void 0,arguments)},open:function(d,E,I,D){typeof E=="string"&&(E=to.modeStringToFlags(E));var M=Oe.openSync(d,lt.flagsForNode(E),I),_=D!=null?D:S.nextfd(M),ie={fd:_,nfd:M,position:0,path:d,flags:E,seekable:!0};return S.streams[_]=ie,ie},close:function(d){d.stream_ops||Oe.closeSync(d.nfd),S.closeStream(d.fd)},llseek:function(d,E,I){if(d.stream_ops)return to.llseek(d,E,I);var D=E;if(I===1)D+=d.position;else if(I===2)D+=Oe.fstatSync(d.nfd).size;else if(I!==0)throw new S.ErrnoError(Ro.EINVAL);if(D<0)throw new S.ErrnoError(Ro.EINVAL);return d.position=D,D},read:function(d,E,I,D,M){if(d.stream_ops)return to.read(d,E,I,D,M);var _=typeof M!="undefined";!_&&d.seekable&&(M=d.position);var ie=Oe.readSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M);return _||(d.position+=ie),ie},write:function(d,E,I,D,M){if(d.stream_ops)return to.write(d,E,I,D,M);d.flags&+"1024"&&S.llseek(d,0,+"2");var _=typeof M!="undefined";!_&&d.seekable&&(M=d.position);var ie=Oe.writeSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M);return _||(d.position+=ie),ie},allocate:function(){throw new S.ErrnoError(Ro.EOPNOTSUPP)},mmap:function(d,E,I,D,M,_){if(d.stream_ops)return to.mmap(d,E,I,D,M,_);if(E!==0)throw new S.ErrnoError(28);var ie=ds(I);return S.read(d,pe,ie,I,D),{ptr:ie,allocated:!0}},msync:function(d,E,I,D,M){return d.stream_ops?to.msync(d,E,I,D,M):(M&2||S.write(d,E,0,D,I),0)},munmap:function(){return 0},ioctl:function(){throw new S.ErrnoError(Ro.ENOTTY)}},S={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:!1,ignorePermissions:!0,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:function(d,E){if(d=qn.resolve(S.cwd(),d),E=E||{},!d)return{path:"",node:null};var I={follow_mount:!0,recurse_count:0};for(var D in I)E[D]===void 0&&(E[D]=I[D]);if(E.recurse_count>8)throw new S.ErrnoError(32);for(var M=St.normalizeArray(d.split("/").filter(function(ut){return!!ut}),!1),_=S.root,ie="/",we=0;we<M.length;we++){var me=we===M.length-1;if(me&&E.parent)break;if(_=S.lookupNode(_,M[we]),ie=St.join2(ie,M[we]),S.isMountpoint(_)&&(!me||me&&E.follow_mount)&&(_=_.mounted.root),!me||E.follow)for(var _e=0;S.isLink(_.mode);){var ot=S.readlink(ie);ie=qn.resolve(St.dirname(ie),ot);var Bt=S.lookupPath(ie,{recurse_count:E.recurse_count});if(_=Bt.node,_e++>40)throw new S.ErrnoError(32)}}return{path:ie,node:_}},getPath:function(d){for(var E;;){if(S.isRoot(d)){var I=d.mount.mountpoint;return E?I[I.length-1]!=="/"?I+"/"+E:I+E:I}E=E?d.name+"/"+E:d.name,d=d.parent}},hashName:function(d,E){for(var I=0,D=0;D<E.length;D++)I=(I<<5)-I+E.charCodeAt(D)|0;return(d+I>>>0)%S.nameTable.length},hashAddNode:function(d){var E=S.hashName(d.parent.id,d.name);d.name_next=S.nameTable[E],S.nameTable[E]=d},hashRemoveNode:function(d){var E=S.hashName(d.parent.id,d.name);if(S.nameTable[E]===d)S.nameTable[E]=d.name_next;else for(var I=S.nameTable[E];I;){if(I.name_next===d){I.name_next=d.name_next;break}I=I.name_next}},lookupNode:function(d,E){var I=S.mayLookup(d);if(I)throw new S.ErrnoError(I,d);for(var D=S.hashName(d.id,E),M=S.nameTable[D];M;M=M.name_next){var _=M.name;if(M.parent.id===d.id&&_===E)return M}return S.lookup(d,E)},createNode:function(d,E,I,D){var M=new S.FSNode(d,E,I,D);return S.hashAddNode(M),M},destroyNode:function(d){S.hashRemoveNode(d)},isRoot:function(d){return d===d.parent},isMountpoint:function(d){return!!d.mounted},isFile:function(d){return(d&61440)==32768},isDir:function(d){return(d&61440)==16384},isLink:function(d){return(d&61440)==40960},isChrdev:function(d){return(d&61440)==8192},isBlkdev:function(d){return(d&61440)==24576},isFIFO:function(d){return(d&61440)==4096},isSocket:function(d){return(d&49152)==49152},flagModes:{r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},modeStringToFlags:function(d){var E=S.flagModes[d];if(typeof E=="undefined")throw new Error("Unknown file open mode: "+d);return E},flagsToPermissionString:function(d){var E=["r","w","rw"][d&3];return d&512&&(E+="w"),E},nodePermissions:function(d,E){return S.ignorePermissions?0:E.includes("r")&&!(d.mode&292)||E.includes("w")&&!(d.mode&146)||E.includes("x")&&!(d.mode&73)?2:0},mayLookup:function(d){var E=S.nodePermissions(d,"x");return E||(d.node_ops.lookup?0:2)},mayCreate:function(d,E){try{var I=S.lookupNode(d,E);return 20}catch(D){}return S.nodePermissions(d,"wx")},mayDelete:function(d,E,I){var D;try{D=S.lookupNode(d,E)}catch(_){return _.errno}var M=S.nodePermissions(d,"wx");if(M)return M;if(I){if(!S.isDir(D.mode))return 54;if(S.isRoot(D)||S.getPath(D)===S.cwd())return 10}else if(S.isDir(D.mode))return 31;return 0},mayOpen:function(d,E){return d?S.isLink(d.mode)?32:S.isDir(d.mode)&&(S.flagsToPermissionString(E)!=="r"||E&512)?31:S.nodePermissions(d,S.flagsToPermissionString(E)):44},MAX_OPEN_FDS:4096,nextfd:function(d,E){d=d||0,E=E||S.MAX_OPEN_FDS;for(var I=d;I<=E;I++)if(!S.streams[I])return I;throw new S.ErrnoError(33)},getStream:function(d){return S.streams[d]},createStream:function(d,E,I){S.FSStream||(S.FSStream=function(){},S.FSStream.prototype={object:{get:function(){return this.node},set:function(ie){this.node=ie}},isRead:{get:function(){return(this.flags&2097155)!=1}},isWrite:{get:function(){return(this.flags&2097155)!=0}},isAppend:{get:function(){return this.flags&1024}}});var D=new S.FSStream;for(var M in d)D[M]=d[M];d=D;var _=S.nextfd(E,I);return d.fd=_,S.streams[_]=d,d},closeStream:function(d){S.streams[d]=null},chrdev_stream_ops:{open:function(d){var E=S.getDevice(d.node.rdev);d.stream_ops=E.stream_ops,d.stream_ops.open&&d.stream_ops.open(d)},llseek:function(){throw new S.ErrnoError(70)}},major:function(d){return d>>8},minor:function(d){return d&255},makedev:function(d,E){return d<<8|E},registerDevice:function(d,E){S.devices[d]={stream_ops:E}},getDevice:function(d){return S.devices[d]},getMounts:function(d){for(var E=[],I=[d];I.length;){var D=I.pop();E.push(D),I.push.apply(I,D.mounts)}return E},syncfs:function(d,E){typeof d=="function"&&(E=d,d=!1),S.syncFSRequests++,S.syncFSRequests>1&&k("warning: "+S.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var I=S.getMounts(S.root.mount),D=0;function M(ie){return S.syncFSRequests--,E(ie)}function _(ie){if(ie)return _.errored?void 0:(_.errored=!0,M(ie));++D>=I.length&&M(null)}I.forEach(function(ie){if(!ie.type.syncfs)return _(null);ie.type.syncfs(ie,d,_)})},mount:function(d,E,I){var D=I==="/",M=!I,_;if(D&&S.root)throw new S.ErrnoError(10);if(!D&&!M){var ie=S.lookupPath(I,{follow_mount:!1});if(I=ie.path,_=ie.node,S.isMountpoint(_))throw new S.ErrnoError(10);if(!S.isDir(_.mode))throw new S.ErrnoError(54)}var we={type:d,opts:E,mountpoint:I,mounts:[]},me=d.mount(we);return me.mount=we,we.root=me,D?S.root=me:_&&(_.mounted=we,_.mount&&_.mount.mounts.push(we)),me},unmount:function(d){var E=S.lookupPath(d,{follow_mount:!1});if(!S.isMountpoint(E.node))throw new S.ErrnoError(28);var I=E.node,D=I.mounted,M=S.getMounts(D);Object.keys(S.nameTable).forEach(function(ie){for(var we=S.nameTable[ie];we;){var me=we.name_next;M.includes(we.mount)&&S.destroyNode(we),we=me}}),I.mounted=null;var _=I.mount.mounts.indexOf(D);I.mount.mounts.splice(_,1)},lookup:function(d,E){return d.node_ops.lookup(d,E)},mknod:function(d,E,I){var D=S.lookupPath(d,{parent:!0}),M=D.node,_=St.basename(d);if(!_||_==="."||_==="..")throw new S.ErrnoError(28);var ie=S.mayCreate(M,_);if(ie)throw new S.ErrnoError(ie);if(!M.node_ops.mknod)throw new S.ErrnoError(63);return M.node_ops.mknod(M,_,E,I)},create:function(d,E){return E=E!==void 0?E:438,E&=4095,E|=32768,S.mknod(d,E,0)},mkdir:function(d,E){return E=E!==void 0?E:511,E&=511|512,E|=16384,S.mknod(d,E,0)},mkdirTree:function(d,E){for(var I=d.split("/"),D="",M=0;M<I.length;++M)if(!!I[M]){D+="/"+I[M];try{S.mkdir(D,E)}catch(_){if(_.errno!=20)throw _}}},mkdev:function(d,E,I){return typeof I=="undefined"&&(I=E,E=438),E|=8192,S.mknod(d,E,I)},symlink:function(d,E){if(!qn.resolve(d))throw new S.ErrnoError(44);var I=S.lookupPath(E,{parent:!0}),D=I.node;if(!D)throw new S.ErrnoError(44);var M=St.basename(E),_=S.mayCreate(D,M);if(_)throw new S.ErrnoError(_);if(!D.node_ops.symlink)throw new S.ErrnoError(63);return D.node_ops.symlink(D,M,d)},rename:function(d,E){var I=St.dirname(d),D=St.dirname(E),M=St.basename(d),_=St.basename(E),ie,we,me;if(ie=S.lookupPath(d,{parent:!0}),we=ie.node,ie=S.lookupPath(E,{parent:!0}),me=ie.node,!we||!me)throw new S.ErrnoError(44);if(we.mount!==me.mount)throw new S.ErrnoError(75);var _e=S.lookupNode(we,M),ot=qn.relative(d,D);if(ot.charAt(0)!==".")throw new S.ErrnoError(28);if(ot=qn.relative(E,I),ot.charAt(0)!==".")throw new S.ErrnoError(55);var Bt;try{Bt=S.lookupNode(me,_)}catch(yt){}if(_e!==Bt){var ut=S.isDir(_e.mode),st=S.mayDelete(we,M,ut);if(st)throw new S.ErrnoError(st);if(st=Bt?S.mayDelete(me,_,ut):S.mayCreate(me,_),st)throw new S.ErrnoError(st);if(!we.node_ops.rename)throw new S.ErrnoError(63);if(S.isMountpoint(_e)||Bt&&S.isMountpoint(Bt))throw new S.ErrnoError(10);if(me!==we&&(st=S.nodePermissions(we,"w"),st))throw new S.ErrnoError(st);try{S.trackingDelegate.willMovePath&&S.trackingDelegate.willMovePath(d,E)}catch(yt){k("FS.trackingDelegate['willMovePath']('"+d+"', '"+E+"') threw an exception: "+yt.message)}S.hashRemoveNode(_e);try{we.node_ops.rename(_e,me,_)}catch(yt){throw yt}finally{S.hashAddNode(_e)}try{S.trackingDelegate.onMovePath&&S.trackingDelegate.onMovePath(d,E)}catch(yt){k("FS.trackingDelegate['onMovePath']('"+d+"', '"+E+"') threw an exception: "+yt.message)}}},rmdir:function(d){var E=S.lookupPath(d,{parent:!0}),I=E.node,D=St.basename(d),M=S.lookupNode(I,D),_=S.mayDelete(I,D,!0);if(_)throw new S.ErrnoError(_);if(!I.node_ops.rmdir)throw new S.ErrnoError(63);if(S.isMountpoint(M))throw new S.ErrnoError(10);try{S.trackingDelegate.willDeletePath&&S.trackingDelegate.willDeletePath(d)}catch(ie){k("FS.trackingDelegate['willDeletePath']('"+d+"') threw an exception: "+ie.message)}I.node_ops.rmdir(I,D),S.destroyNode(M);try{S.trackingDelegate.onDeletePath&&S.trackingDelegate.onDeletePath(d)}catch(ie){k("FS.trackingDelegate['onDeletePath']('"+d+"') threw an exception: "+ie.message)}},readdir:function(d){var E=S.lookupPath(d,{follow:!0}),I=E.node;if(!I.node_ops.readdir)throw new S.ErrnoError(54);return I.node_ops.readdir(I)},unlink:function(d){var E=S.lookupPath(d,{parent:!0}),I=E.node,D=St.basename(d),M=S.lookupNode(I,D),_=S.mayDelete(I,D,!1);if(_)throw new S.ErrnoError(_);if(!I.node_ops.unlink)throw new S.ErrnoError(63);if(S.isMountpoint(M))throw new S.ErrnoError(10);try{S.trackingDelegate.willDeletePath&&S.trackingDelegate.willDeletePath(d)}catch(ie){k("FS.trackingDelegate['willDeletePath']('"+d+"') threw an exception: "+ie.message)}I.node_ops.unlink(I,D),S.destroyNode(M);try{S.trackingDelegate.onDeletePath&&S.trackingDelegate.onDeletePath(d)}catch(ie){k("FS.trackingDelegate['onDeletePath']('"+d+"') threw an exception: "+ie.message)}},readlink:function(d){var E=S.lookupPath(d),I=E.node;if(!I)throw new S.ErrnoError(44);if(!I.node_ops.readlink)throw new S.ErrnoError(28);return qn.resolve(S.getPath(I.parent),I.node_ops.readlink(I))},stat:function(d,E){var I=S.lookupPath(d,{follow:!E}),D=I.node;if(!D)throw new S.ErrnoError(44);if(!D.node_ops.getattr)throw new S.ErrnoError(63);return D.node_ops.getattr(D)},lstat:function(d){return S.stat(d,!0)},chmod:function(d,E,I){var D;if(typeof d=="string"){var M=S.lookupPath(d,{follow:!I});D=M.node}else D=d;if(!D.node_ops.setattr)throw new S.ErrnoError(63);D.node_ops.setattr(D,{mode:E&4095|D.mode&~4095,timestamp:Date.now()})},lchmod:function(d,E){S.chmod(d,E,!0)},fchmod:function(d,E){var I=S.getStream(d);if(!I)throw new S.ErrnoError(8);S.chmod(I.node,E)},chown:function(d,E,I,D){var M;if(typeof d=="string"){var _=S.lookupPath(d,{follow:!D});M=_.node}else M=d;if(!M.node_ops.setattr)throw new S.ErrnoError(63);M.node_ops.setattr(M,{timestamp:Date.now()})},lchown:function(d,E,I){S.chown(d,E,I,!0)},fchown:function(d,E,I){var D=S.getStream(d);if(!D)throw new S.ErrnoError(8);S.chown(D.node,E,I)},truncate:function(d,E){if(E<0)throw new S.ErrnoError(28);var I;if(typeof d=="string"){var D=S.lookupPath(d,{follow:!0});I=D.node}else I=d;if(!I.node_ops.setattr)throw new S.ErrnoError(63);if(S.isDir(I.mode))throw new S.ErrnoError(31);if(!S.isFile(I.mode))throw new S.ErrnoError(28);var M=S.nodePermissions(I,"w");if(M)throw new S.ErrnoError(M);I.node_ops.setattr(I,{size:E,timestamp:Date.now()})},ftruncate:function(d,E){var I=S.getStream(d);if(!I)throw new S.ErrnoError(8);if((I.flags&2097155)==0)throw new S.ErrnoError(28);S.truncate(I.node,E)},utime:function(d,E,I){var D=S.lookupPath(d,{follow:!0}),M=D.node;M.node_ops.setattr(M,{timestamp:Math.max(E,I)})},open:function(d,E,I,D,M){if(d==="")throw new S.ErrnoError(44);E=typeof E=="string"?S.modeStringToFlags(E):E,I=typeof I=="undefined"?438:I,E&64?I=I&4095|32768:I=0;var _;if(typeof d=="object")_=d;else{d=St.normalize(d);try{var ie=S.lookupPath(d,{follow:!(E&131072)});_=ie.node}catch(Bt){}}var we=!1;if(E&64)if(_){if(E&128)throw new S.ErrnoError(20)}else _=S.mknod(d,I,0),we=!0;if(!_)throw new S.ErrnoError(44);if(S.isChrdev(_.mode)&&(E&=~512),E&65536&&!S.isDir(_.mode))throw new S.ErrnoError(54);if(!we){var me=S.mayOpen(_,E);if(me)throw new S.ErrnoError(me)}E&512&&S.truncate(_,0),E&=~(128|512|131072);var _e=S.createStream({node:_,path:S.getPath(_),flags:E,seekable:!0,position:0,stream_ops:_.stream_ops,ungotten:[],error:!1},D,M);_e.stream_ops.open&&_e.stream_ops.open(_e),t.logReadFiles&&!(E&1)&&(S.readFiles||(S.readFiles={}),d in S.readFiles||(S.readFiles[d]=1,k("FS.trackingDelegate error on read file: "+d)));try{if(S.trackingDelegate.onOpenFile){var ot=0;(E&2097155)!=1&&(ot|=S.tracking.openFlags.READ),(E&2097155)!=0&&(ot|=S.tracking.openFlags.WRITE),S.trackingDelegate.onOpenFile(d,ot)}}catch(Bt){k("FS.trackingDelegate['onOpenFile']('"+d+"', flags) threw an exception: "+Bt.message)}return _e},close:function(d){if(S.isClosed(d))throw new S.ErrnoError(8);d.getdents&&(d.getdents=null);try{d.stream_ops.close&&d.stream_ops.close(d)}catch(E){throw E}finally{S.closeStream(d.fd)}d.fd=null},isClosed:function(d){return d.fd===null},llseek:function(d,E,I){if(S.isClosed(d))throw new S.ErrnoError(8);if(!d.seekable||!d.stream_ops.llseek)throw new S.ErrnoError(70);if(I!=0&&I!=1&&I!=2)throw new S.ErrnoError(28);return d.position=d.stream_ops.llseek(d,E,I),d.ungotten=[],d.position},read:function(d,E,I,D,M){if(D<0||M<0)throw new S.ErrnoError(28);if(S.isClosed(d))throw new S.ErrnoError(8);if((d.flags&2097155)==1)throw new S.ErrnoError(8);if(S.isDir(d.node.mode))throw new S.ErrnoError(31);if(!d.stream_ops.read)throw new S.ErrnoError(28);var _=typeof M!="undefined";if(!_)M=d.position;else if(!d.seekable)throw new S.ErrnoError(70);var ie=d.stream_ops.read(d,E,I,D,M);return _||(d.position+=ie),ie},write:function(d,E,I,D,M,_){if(D<0||M<0)throw new S.ErrnoError(28);if(S.isClosed(d))throw new S.ErrnoError(8);if((d.flags&2097155)==0)throw new S.ErrnoError(8);if(S.isDir(d.node.mode))throw new S.ErrnoError(31);if(!d.stream_ops.write)throw new S.ErrnoError(28);d.seekable&&d.flags&1024&&S.llseek(d,0,2);var ie=typeof M!="undefined";if(!ie)M=d.position;else if(!d.seekable)throw new S.ErrnoError(70);var we=d.stream_ops.write(d,E,I,D,M,_);ie||(d.position+=we);try{d.path&&S.trackingDelegate.onWriteToFile&&S.trackingDelegate.onWriteToFile(d.path)}catch(me){k("FS.trackingDelegate['onWriteToFile']('"+d.path+"') threw an exception: "+me.message)}return we},allocate:function(d,E,I){if(S.isClosed(d))throw new S.ErrnoError(8);if(E<0||I<=0)throw new S.ErrnoError(28);if((d.flags&2097155)==0)throw new S.ErrnoError(8);if(!S.isFile(d.node.mode)&&!S.isDir(d.node.mode))throw new S.ErrnoError(43);if(!d.stream_ops.allocate)throw new S.ErrnoError(138);d.stream_ops.allocate(d,E,I)},mmap:function(d,E,I,D,M,_){if((M&2)!=0&&(_&2)==0&&(d.flags&2097155)!=2)throw new S.ErrnoError(2);if((d.flags&2097155)==1)throw new S.ErrnoError(2);if(!d.stream_ops.mmap)throw new S.ErrnoError(43);return d.stream_ops.mmap(d,E,I,D,M,_)},msync:function(d,E,I,D,M){return!d||!d.stream_ops.msync?0:d.stream_ops.msync(d,E,I,D,M)},munmap:function(d){return 0},ioctl:function(d,E,I){if(!d.stream_ops.ioctl)throw new S.ErrnoError(59);return d.stream_ops.ioctl(d,E,I)},readFile:function(d,E){if(E=E||{},E.flags=E.flags||0,E.encoding=E.encoding||"binary",E.encoding!=="utf8"&&E.encoding!=="binary")throw new Error('Invalid encoding type "'+E.encoding+'"');var I,D=S.open(d,E.flags),M=S.stat(d),_=M.size,ie=new Uint8Array(_);return S.read(D,ie,0,_,0),E.encoding==="utf8"?I=Ge(ie,0):E.encoding==="binary"&&(I=ie),S.close(D),I},writeFile:function(d,E,I){I=I||{},I.flags=I.flags||577;var D=S.open(d,I.flags,I.mode);if(typeof E=="string"){var M=new Uint8Array(he(E)+1),_=se(E,M,0,M.length);S.write(D,M,0,_,void 0,I.canOwn)}else if(ArrayBuffer.isView(E))S.write(D,E,0,E.byteLength,void 0,I.canOwn);else throw new Error("Unsupported data type");S.close(D)},cwd:function(){return S.currentPath},chdir:function(d){var E=S.lookupPath(d,{follow:!0});if(E.node===null)throw new S.ErrnoError(44);if(!S.isDir(E.node.mode))throw new S.ErrnoError(54);var I=S.nodePermissions(E.node,"x");if(I)throw new S.ErrnoError(I);S.currentPath=E.path},createDefaultDirectories:function(){S.mkdir("/tmp"),S.mkdir("/home"),S.mkdir("/home/web_user")},createDefaultDevices:function(){S.mkdir("/dev"),S.registerDevice(S.makedev(1,3),{read:function(){return 0},write:function(E,I,D,M,_){return M}}),S.mkdev("/dev/null",S.makedev(1,3)),ps.register(S.makedev(5,0),ps.default_tty_ops),ps.register(S.makedev(6,0),ps.default_tty1_ops),S.mkdev("/dev/tty",S.makedev(5,0)),S.mkdev("/dev/tty1",S.makedev(6,0));var d=Vl();S.createDevice("/dev","random",d),S.createDevice("/dev","urandom",d),S.mkdir("/dev/shm"),S.mkdir("/dev/shm/tmp")},createSpecialDirectories:function(){S.mkdir("/proc");var d=S.mkdir("/proc/self");S.mkdir("/proc/self/fd"),S.mount({mount:function(){var E=S.createNode(d,"fd",16384|511,73);return E.node_ops={lookup:function(I,D){var M=+D,_=S.getStream(M);if(!_)throw new S.ErrnoError(8);var ie={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:function(){return _.path}}};return ie.parent=ie,ie}},E}},{},"/proc/self/fd")},createStandardStreams:function(){t.stdin?S.createDevice("/dev","stdin",t.stdin):S.symlink("/dev/tty","/dev/stdin"),t.stdout?S.createDevice("/dev","stdout",null,t.stdout):S.symlink("/dev/tty","/dev/stdout"),t.stderr?S.createDevice("/dev","stderr",null,t.stderr):S.symlink("/dev/tty1","/dev/stderr");var d=S.open("/dev/stdin",0),E=S.open("/dev/stdout",1),I=S.open("/dev/stderr",1)},ensureErrnoError:function(){S.ErrnoError||(S.ErrnoError=function(E,I){this.node=I,this.setErrno=function(D){this.errno=D},this.setErrno(E),this.message="FS error"},S.ErrnoError.prototype=new Error,S.ErrnoError.prototype.constructor=S.ErrnoError,[44].forEach(function(d){S.genericErrors[d]=new S.ErrnoError(d),S.genericErrors[d].stack="<generic error, no stack>"}))},staticInit:function(){S.ensureErrnoError(),S.nameTable=new Array(4096),S.mount(pt,{},"/"),S.createDefaultDirectories(),S.createDefaultDevices(),S.createSpecialDirectories(),S.filesystems={MEMFS:pt,NODEFS:lt}},init:function(d,E,I){S.init.initialized=!0,S.ensureErrnoError(),t.stdin=d||t.stdin,t.stdout=E||t.stdout,t.stderr=I||t.stderr,S.createStandardStreams()},quit:function(){S.init.initialized=!1;var d=t._fflush;d&&d(0);for(var E=0;E<S.streams.length;E++){var I=S.streams[E];!I||S.close(I)}},getMode:function(d,E){var I=0;return d&&(I|=292|73),E&&(I|=146),I},findObject:function(d,E){var I=S.analyzePath(d,E);return I.exists?I.object:null},analyzePath:function(d,E){try{var I=S.lookupPath(d,{follow:!E});d=I.path}catch(M){}var D={isRoot:!1,exists:!1,error:0,name:null,path:null,object:null,parentExists:!1,parentPath:null,parentObject:null};try{var I=S.lookupPath(d,{parent:!0});D.parentExists=!0,D.parentPath=I.path,D.parentObject=I.node,D.name=St.basename(d),I=S.lookupPath(d,{follow:!E}),D.exists=!0,D.path=I.path,D.object=I.node,D.name=I.node.name,D.isRoot=I.path==="/"}catch(M){D.error=M.errno}return D},createPath:function(d,E,I,D){d=typeof d=="string"?d:S.getPath(d);for(var M=E.split("/").reverse();M.length;){var _=M.pop();if(!!_){var ie=St.join2(d,_);try{S.mkdir(ie)}catch(we){}d=ie}}return ie},createFile:function(d,E,I,D,M){var _=St.join2(typeof d=="string"?d:S.getPath(d),E),ie=S.getMode(D,M);return S.create(_,ie)},createDataFile:function(d,E,I,D,M,_){var ie=E?St.join2(typeof d=="string"?d:S.getPath(d),E):d,we=S.getMode(D,M),me=S.create(ie,we);if(I){if(typeof I=="string"){for(var _e=new Array(I.length),ot=0,Bt=I.length;ot<Bt;++ot)_e[ot]=I.charCodeAt(ot);I=_e}S.chmod(me,we|146);var ut=S.open(me,577);S.write(ut,I,0,I.length,0,_),S.close(ut),S.chmod(me,we)}return me},createDevice:function(d,E,I,D){var M=St.join2(typeof d=="string"?d:S.getPath(d),E),_=S.getMode(!!I,!!D);S.createDevice.major||(S.createDevice.major=64);var ie=S.makedev(S.createDevice.major++,0);return S.registerDevice(ie,{open:function(we){we.seekable=!1},close:function(we){D&&D.buffer&&D.buffer.length&&D(10)},read:function(we,me,_e,ot,Bt){for(var ut=0,st=0;st<ot;st++){var yt;try{yt=I()}catch(ke){throw new S.ErrnoError(29)}if(yt===void 0&&ut===0)throw new S.ErrnoError(6);if(yt==null)break;ut++,me[_e+st]=yt}return ut&&(we.node.timestamp=Date.now()),ut},write:function(we,me,_e,ot,Bt){for(var ut=0;ut<ot;ut++)try{D(me[_e+ut])}catch(st){throw new S.ErrnoError(29)}return ot&&(we.node.timestamp=Date.now()),ut}}),S.mkdev(M,_,ie)},forceLoadFile:function(d){if(d.isDevice||d.isFolder||d.link||d.contents)return!0;if(typeof XMLHttpRequest!="undefined")throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");if(p)try{d.contents=OA(p(d.url),!0),d.usedBytes=d.contents.length}catch(E){throw new S.ErrnoError(29)}else throw new Error("Cannot load without read() or XMLHttpRequest.")},createLazyFile:function(d,E,I,D,M){function _(){this.lengthKnown=!1,this.chunks=[]}if(_.prototype.get=function(ut){if(!(ut>this.length-1||ut<0)){var st=ut%this.chunkSize,yt=ut/this.chunkSize|0;return this.getter(yt)[st]}},_.prototype.setDataGetter=function(ut){this.getter=ut},_.prototype.cacheLength=function(){var ut=new XMLHttpRequest;if(ut.open("HEAD",I,!1),ut.send(null),!(ut.status>=200&&ut.status<300||ut.status===304))throw new Error("Couldn't load "+I+". Status: "+ut.status);var st=Number(ut.getResponseHeader("Content-length")),yt,ke=(yt=ut.getResponseHeader("Accept-Ranges"))&&yt==="bytes",zn=(yt=ut.getResponseHeader("Content-Encoding"))&&yt==="gzip",Mi=1024*1024;ke||(Mi=st);var jA=function(Cs,Da){if(Cs>Da)throw new Error("invalid range ("+Cs+", "+Da+") or no bytes requested!");if(Da>st-1)throw new Error("only "+st+" bytes available! programmer error!");var qr=new XMLHttpRequest;if(qr.open("GET",I,!1),st!==Mi&&qr.setRequestHeader("Range","bytes="+Cs+"-"+Da),typeof Uint8Array!="undefined"&&(qr.responseType="arraybuffer"),qr.overrideMimeType&&qr.overrideMimeType("text/plain; charset=x-user-defined"),qr.send(null),!(qr.status>=200&&qr.status<300||qr.status===304))throw new Error("Couldn't load "+I+". Status: "+qr.status);return qr.response!==void 0?new Uint8Array(qr.response||[]):OA(qr.responseText||"",!0)},Yr=this;Yr.setDataGetter(function(Cs){var Da=Cs*Mi,qr=(Cs+1)*Mi-1;if(qr=Math.min(qr,st-1),typeof Yr.chunks[Cs]=="undefined"&&(Yr.chunks[Cs]=jA(Da,qr)),typeof Yr.chunks[Cs]=="undefined")throw new Error("doXHR failed!");return Yr.chunks[Cs]}),(zn||!st)&&(Mi=st=1,st=this.getter(0).length,Mi=st,v("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=st,this._chunkSize=Mi,this.lengthKnown=!0},typeof XMLHttpRequest!="undefined"){if(!u)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var ie=new _;Object.defineProperties(ie,{length:{get:function(){return this.lengthKnown||this.cacheLength(),this._length}},chunkSize:{get:function(){return this.lengthKnown||this.cacheLength(),this._chunkSize}}});var we={isDevice:!1,contents:ie}}else var we={isDevice:!1,url:I};var me=S.createFile(d,E,we,D,M);we.contents?me.contents=we.contents:we.url&&(me.contents=null,me.url=we.url),Object.defineProperties(me,{usedBytes:{get:function(){return this.contents.length}}});var _e={},ot=Object.keys(me.stream_ops);return ot.forEach(function(Bt){var ut=me.stream_ops[Bt];_e[Bt]=function(){return S.forceLoadFile(me),ut.apply(null,arguments)}}),_e.read=function(ut,st,yt,ke,zn){S.forceLoadFile(me);var Mi=ut.node.contents;if(zn>=Mi.length)return 0;var jA=Math.min(Mi.length-zn,ke);if(Mi.slice)for(var Yr=0;Yr<jA;Yr++)st[yt+Yr]=Mi[zn+Yr];else for(var Yr=0;Yr<jA;Yr++)st[yt+Yr]=Mi.get(zn+Yr);return jA},me.stream_ops=_e,me},createPreloadedFile:function(d,E,I,D,M,_,ie,we,me,_e){Browser.init();var ot=E?qn.resolve(St.join2(d,E)):d,Bt=Tu("cp "+ot);function ut(st){function yt(zn){_e&&_e(),we||S.createDataFile(d,E,zn,D,M,me),_&&_(),LA(Bt)}var ke=!1;t.preloadPlugins.forEach(function(zn){ke||zn.canHandle(ot)&&(zn.handle(st,ot,yt,function(){ie&&ie(),LA(Bt)}),ke=!0)}),ke||yt(st)}NA(Bt),typeof I=="string"?Browser.asyncLoad(I,function(st){ut(st)},ie):ut(I)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:function(){return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(d,E,I){E=E||function(){},I=I||function(){};var D=S.indexedDB();try{var M=D.open(S.DB_NAME(),S.DB_VERSION)}catch(_){return I(_)}M.onupgradeneeded=function(){v("creating db");var ie=M.result;ie.createObjectStore(S.DB_STORE_NAME)},M.onsuccess=function(){var ie=M.result,we=ie.transaction([S.DB_STORE_NAME],"readwrite"),me=we.objectStore(S.DB_STORE_NAME),_e=0,ot=0,Bt=d.length;function ut(){ot==0?E():I()}d.forEach(function(st){var yt=me.put(S.analyzePath(st).object.contents,st);yt.onsuccess=function(){_e++,_e+ot==Bt&&ut()},yt.onerror=function(){ot++,_e+ot==Bt&&ut()}}),we.onerror=I},M.onerror=I},loadFilesFromDB:function(d,E,I){E=E||function(){},I=I||function(){};var D=S.indexedDB();try{var M=D.open(S.DB_NAME(),S.DB_VERSION)}catch(_){return I(_)}M.onupgradeneeded=I,M.onsuccess=function(){var ie=M.result;try{var we=ie.transaction([S.DB_STORE_NAME],"readonly")}catch(st){I(st);return}var me=we.objectStore(S.DB_STORE_NAME),_e=0,ot=0,Bt=d.length;function ut(){ot==0?E():I()}d.forEach(function(st){var yt=me.get(st);yt.onsuccess=function(){S.analyzePath(st).exists&&S.unlink(st),S.createDataFile(St.dirname(st),St.basename(st),yt.result,!0,!0,!0),_e++,_e+ot==Bt&&ut()},yt.onerror=function(){ot++,_e+ot==Bt&&ut()}}),we.onerror=I},M.onerror=I}},Tt={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(d,E,I){if(E[0]==="/")return E;var D;if(d===-100)D=S.cwd();else{var M=S.getStream(d);if(!M)throw new S.ErrnoError(8);D=M.path}if(E.length==0){if(!I)throw new S.ErrnoError(44);return D}return St.join2(D,E)},doStat:function(d,E,I){try{var D=d(E)}catch(M){if(M&&M.node&&St.normalize(E)!==St.normalize(S.getPath(M.node)))return-54;throw M}return fe[I>>2]=D.dev,fe[I+4>>2]=0,fe[I+8>>2]=D.ino,fe[I+12>>2]=D.mode,fe[I+16>>2]=D.nlink,fe[I+20>>2]=D.uid,fe[I+24>>2]=D.gid,fe[I+28>>2]=D.rdev,fe[I+32>>2]=0,Ae=[D.size>>>0,(Dr=D.size,+Math.abs(Dr)>=1?Dr>0?(Math.min(+Math.floor(Dr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Dr-+(~~Dr>>>0))/4294967296)>>>0:0)],fe[I+40>>2]=Ae[0],fe[I+44>>2]=Ae[1],fe[I+48>>2]=4096,fe[I+52>>2]=D.blocks,fe[I+56>>2]=D.atime.getTime()/1e3|0,fe[I+60>>2]=0,fe[I+64>>2]=D.mtime.getTime()/1e3|0,fe[I+68>>2]=0,fe[I+72>>2]=D.ctime.getTime()/1e3|0,fe[I+76>>2]=0,Ae=[D.ino>>>0,(Dr=D.ino,+Math.abs(Dr)>=1?Dr>0?(Math.min(+Math.floor(Dr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Dr-+(~~Dr>>>0))/4294967296)>>>0:0)],fe[I+80>>2]=Ae[0],fe[I+84>>2]=Ae[1],0},doMsync:function(d,E,I,D,M){var _=V.slice(d,d+I);S.msync(E,_,M,I,D)},doMkdir:function(d,E){return d=St.normalize(d),d[d.length-1]==="/"&&(d=d.substr(0,d.length-1)),S.mkdir(d,E,0),0},doMknod:function(d,E,I){switch(E&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return S.mknod(d,E,I),0},doReadlink:function(d,E,I){if(I<=0)return-28;var D=S.readlink(d),M=Math.min(I,he(D)),_=pe[E+M];return be(D,E,I+1),pe[E+M]=_,M},doAccess:function(d,E){if(E&~7)return-28;var I,D=S.lookupPath(d,{follow:!0});if(I=D.node,!I)return-44;var M="";return E&4&&(M+="r"),E&2&&(M+="w"),E&1&&(M+="x"),M&&S.nodePermissions(I,M)?-2:0},doDup:function(d,E,I){var D=S.getStream(I);return D&&S.close(D),S.open(d,E,0,I,I).fd},doReadv:function(d,E,I,D){for(var M=0,_=0;_<I;_++){var ie=fe[E+_*8>>2],we=fe[E+(_*8+4)>>2],me=S.read(d,pe,ie,we,D);if(me<0)return-1;if(M+=me,me<we)break}return M},doWritev:function(d,E,I,D){for(var M=0,_=0;_<I;_++){var ie=fe[E+_*8>>2],we=fe[E+(_*8+4)>>2],me=S.write(d,pe,ie,we,D);if(me<0)return-1;M+=me}return M},varargs:void 0,get:function(){Tt.varargs+=4;var d=fe[Tt.varargs-4>>2];return d},getStr:function(d){var E=re(d);return E},getStreamFromFD:function(d){var E=S.getStream(d);if(!E)throw new S.ErrnoError(8);return E},get64:function(d,E){return d}};function Ku(d,E){try{return d=Tt.getStr(d),S.chmod(d,E),0}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),-I.errno}}function Xl(d){return fe[Rt()>>2]=d,d}function xh(d,E,I){Tt.varargs=I;try{var D=Tt.getStreamFromFD(d);switch(E){case 0:{var M=Tt.get();if(M<0)return-28;var _;return _=S.open(D.path,D.flags,0,M),_.fd}case 1:case 2:return 0;case 3:return D.flags;case 4:{var M=Tt.get();return D.flags|=M,0}case 12:{var M=Tt.get(),ie=0;return Qe[M+ie>>1]=2,0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:return Xl(28),-1;default:return-28}}catch(we){return(typeof S=="undefined"||!(we instanceof S.ErrnoError))&&vr(we),-we.errno}}function Ph(d,E){try{var I=Tt.getStreamFromFD(d);return Tt.doStat(S.stat,I.path,E)}catch(D){return(typeof S=="undefined"||!(D instanceof S.ErrnoError))&&vr(D),-D.errno}}function Dh(d,E,I){Tt.varargs=I;try{var D=Tt.getStreamFromFD(d);switch(E){case 21509:case 21505:return D.tty?0:-59;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return D.tty?0:-59;case 21519:{if(!D.tty)return-59;var M=Tt.get();return fe[M>>2]=0,0}case 21520:return D.tty?-28:-59;case 21531:{var M=Tt.get();return S.ioctl(D,E,M)}case 21523:return D.tty?0:-59;case 21524:return D.tty?0:-59;default:vr("bad ioctl syscall "+E)}}catch(_){return(typeof S=="undefined"||!(_ instanceof S.ErrnoError))&&vr(_),-_.errno}}function Rh(d,E,I){Tt.varargs=I;try{var D=Tt.getStr(d),M=I?Tt.get():0,_=S.open(D,E,M);return _.fd}catch(ie){return(typeof S=="undefined"||!(ie instanceof S.ErrnoError))&&vr(ie),-ie.errno}}function Fh(d,E){try{return d=Tt.getStr(d),E=Tt.getStr(E),S.rename(d,E),0}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),-I.errno}}function j(d){try{return d=Tt.getStr(d),S.rmdir(d),0}catch(E){return(typeof S=="undefined"||!(E instanceof S.ErrnoError))&&vr(E),-E.errno}}function wt(d,E){try{return d=Tt.getStr(d),Tt.doStat(S.stat,d,E)}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),-I.errno}}function TA(d){try{return d=Tt.getStr(d),S.unlink(d),0}catch(E){return(typeof S=="undefined"||!(E instanceof S.ErrnoError))&&vr(E),-E.errno}}function $i(d,E,I){V.copyWithin(d,E,E+I)}function Zl(d){try{return A.grow(d-ve.byteLength+65535>>>16),Ei(A.buffer),1}catch(E){}}function $e(d){var E=V.length;d=d>>>0;var I=2147483648;if(d>I)return!1;for(var D=1;D<=4;D*=2){var M=E*(1+.2/D);M=Math.min(M,d+100663296);var _=Math.min(I,xe(Math.max(d,M),65536)),ie=Zl(_);if(ie)return!0}return!1}function va(d){try{var E=Tt.getStreamFromFD(d);return S.close(E),0}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),I.errno}}function Hu(d,E){try{var I=Tt.getStreamFromFD(d),D=I.tty?2:S.isDir(I.mode)?3:S.isLink(I.mode)?7:4;return pe[E>>0]=D,0}catch(M){return(typeof S=="undefined"||!(M instanceof S.ErrnoError))&&vr(M),M.errno}}function wE(d,E,I,D){try{var M=Tt.getStreamFromFD(d),_=Tt.doReadv(M,E,I);return fe[D>>2]=_,0}catch(ie){return(typeof S=="undefined"||!(ie instanceof S.ErrnoError))&&vr(ie),ie.errno}}function Nh(d,E,I,D,M){try{var _=Tt.getStreamFromFD(d),ie=4294967296,we=I*ie+(E>>>0),me=9007199254740992;return we<=-me||we>=me?-61:(S.llseek(_,we,D),Ae=[_.position>>>0,(Dr=_.position,+Math.abs(Dr)>=1?Dr>0?(Math.min(+Math.floor(Dr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Dr-+(~~Dr>>>0))/4294967296)>>>0:0)],fe[M>>2]=Ae[0],fe[M+4>>2]=Ae[1],_.getdents&&we===0&&D===0&&(_.getdents=null),0)}catch(_e){return(typeof S=="undefined"||!(_e instanceof S.ErrnoError))&&vr(_e),_e.errno}}function BE(d,E,I,D){try{var M=Tt.getStreamFromFD(d),_=Tt.doWritev(M,E,I);return fe[D>>2]=_,0}catch(ie){return(typeof S=="undefined"||!(ie instanceof S.ErrnoError))&&vr(ie),ie.errno}}function gr(d){$(d)}function Jn(d){var E=Date.now()/1e3|0;return d&&(fe[d>>2]=E),E}function $l(){if($l.called)return;$l.called=!0;var d=new Date().getFullYear(),E=new Date(d,0,1),I=new Date(d,6,1),D=E.getTimezoneOffset(),M=I.getTimezoneOffset(),_=Math.max(D,M);fe[_b()>>2]=_*60,fe[zb()>>2]=Number(D!=M);function ie(Bt){var ut=Bt.toTimeString().match(/\(([A-Za-z ]+)\)$/);return ut?ut[1]:"GMT"}var we=ie(E),me=ie(I),_e=Fe(we),ot=Fe(me);M<D?(fe[zu()>>2]=_e,fe[zu()+4>>2]=ot):(fe[zu()>>2]=ot,fe[zu()+4>>2]=_e)}function Lh(d){$l();var E=Date.UTC(fe[d+20>>2]+1900,fe[d+16>>2],fe[d+12>>2],fe[d+8>>2],fe[d+4>>2],fe[d>>2],0),I=new Date(E);fe[d+24>>2]=I.getUTCDay();var D=Date.UTC(I.getUTCFullYear(),0,1,0,0,0,0),M=(I.getTime()-D)/(1e3*60*60*24)|0;return fe[d+28>>2]=M,I.getTime()/1e3|0}var eo=function(d,E,I,D){d||(d=this),this.parent=d,this.mount=d.mount,this.mounted=null,this.id=S.nextInode++,this.name=E,this.mode=I,this.node_ops={},this.stream_ops={},this.rdev=D},ka=292|73,En=146;if(Object.defineProperties(eo.prototype,{read:{get:function(){return(this.mode&ka)===ka},set:function(d){d?this.mode|=ka:this.mode&=~ka}},write:{get:function(){return(this.mode&En)===En},set:function(d){d?this.mode|=En:this.mode&=~En}},isFolder:{get:function(){return S.isDir(this.mode)}},isDevice:{get:function(){return S.isChrdev(this.mode)}}}),S.FSNode=eo,S.staticInit(),g){var Oe=D5,ju=require("path");lt.staticInit()}if(g){var ec=function(d){return function(){try{return d.apply(this,arguments)}catch(E){throw E.code?new S.ErrnoError(Ro[E.code]):E}}},to=Object.assign({},S);for(var tc in mn)S[tc]=ec(mn[tc])}else throw new Error("NODERAWFS is currently only supported on Node.js environment.");function OA(d,E,I){var D=I>0?I:he(d)+1,M=new Array(D),_=se(d,M,0,M.length);return E&&(M.length=_),M}var Gu=typeof atob=="function"?atob:function(d){var E="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",I="",D,M,_,ie,we,me,_e,ot=0;d=d.replace(/[^A-Za-z0-9\+\/\=]/g,"");do ie=E.indexOf(d.charAt(ot++)),we=E.indexOf(d.charAt(ot++)),me=E.indexOf(d.charAt(ot++)),_e=E.indexOf(d.charAt(ot++)),D=ie<<2|we>>4,M=(we&15)<<4|me>>2,_=(me&3)<<6|_e,I=I+String.fromCharCode(D),me!==64&&(I=I+String.fromCharCode(M)),_e!==64&&(I=I+String.fromCharCode(_));while(ot<d.length);return I};function Yu(d){if(typeof g=="boolean"&&g){var E;try{E=Buffer.from(d,"base64")}catch(_){E=new Buffer(d,"base64")}return new Uint8Array(E.buffer,E.byteOffset,E.byteLength)}try{for(var I=Gu(d),D=new Uint8Array(I.length),M=0;M<I.length;++M)D[M]=I.charCodeAt(M);return D}catch(_){throw new Error("Converting base64 string to bytes failed.")}}function xa(d){if(!!Ou(d))return Yu(d.slice(_l.length))}var Pa={s:Uu,p:Ku,e:xh,k:Ph,o:Dh,q:Rh,i:Fh,r:j,c:wt,h:TA,l:$i,m:$e,f:va,j:Hu,g:wE,n:Nh,d:BE,a:gr,b:Jn,t:Lh},nt=kh(),Fo=t.___wasm_call_ctors=nt.v,MA=t._zip_ext_count_symlinks=nt.w,rc=t._zip_file_get_external_attributes=nt.x,ro=t._zipstruct_stat=nt.y,ic=t._zipstruct_statS=nt.z,bE=t._zipstruct_stat_name=nt.A,Th=t._zipstruct_stat_index=nt.B,qu=t._zipstruct_stat_size=nt.C,Oh=t._zipstruct_stat_mtime=nt.D,QE=t._zipstruct_stat_crc=nt.E,nc=t._zipstruct_error=nt.F,SE=t._zipstruct_errorS=nt.G,Ju=t._zipstruct_error_code_zip=nt.H,UA=t._zipstruct_stat_comp_size=nt.I,Tr=t._zipstruct_stat_comp_method=nt.J,vE=t._zip_close=nt.K,io=t._zip_delete=nt.L,no=t._zip_dir_add=nt.M,Wu=t._zip_discard=nt.N,KA=t._zip_error_init_with_code=nt.O,R=t._zip_get_error=nt.P,G=t._zip_file_get_error=nt.Q,Ce=t._zip_error_strerror=nt.R,je=t._zip_fclose=nt.S,Te=t._zip_file_add=nt.T,Xe=t._free=nt.U,Et=t._malloc=nt.V,Rt=t.___errno_location=nt.W,Wn=t._zip_source_error=nt.X,Mb=t._zip_source_seek=nt.Y,fO=t._zip_file_set_external_attributes=nt.Z,hO=t._zip_file_set_mtime=nt._,Ub=t._zip_fopen=nt.$,pO=t._zip_fopen_index=nt.aa,dO=t._zip_fread=nt.ba,Kb=t._zip_get_name=nt.ca,CO=t._zip_get_num_entries=nt.da,mO=t._zip_source_read=nt.ea,Hb=t._zip_name_locate=nt.fa,EO=t._zip_open=nt.ga,IO=t._zip_open_from_source=nt.ha,jb=t._zip_set_file_compression=nt.ia,yO=t._zip_source_buffer=nt.ja,wO=t._zip_source_buffer_create=nt.ka,BO=t._zip_source_close=nt.la,bO=t._zip_source_free=nt.ma,Gb=t._zip_source_keep=nt.na,Yb=t._zip_source_open=nt.oa,qb=t._zip_source_set_mtime=nt.qa,Jb=t._zip_source_tell=nt.ra,Wb=t._zip_stat=nt.sa,QO=t._zip_stat_index=nt.ta,zu=t.__get_tzname=nt.ua,zb=t.__get_daylight=nt.va,_b=t.__get_timezone=nt.wa,kE=t.stackSave=nt.xa,xE=t.stackRestore=nt.ya,B=t.stackAlloc=nt.za;t.cwrap=de,t.getValue=ee;var Ke;Sa=function d(){Ke||HA(),Ke||(Sa=d)};function HA(d){if(d=d||a,hs>0||(Sr(),hs>0))return;function E(){Ke||(Ke=!0,t.calledRun=!0,!oe&&(Gn(),i(t),t.onRuntimeInitialized&&t.onRuntimeInitialized(),fs()))}t.setStatus?(t.setStatus("Running..."),setTimeout(function(){setTimeout(function(){t.setStatus("")},1),E()},1)):E()}if(t.run=HA,t.preInit)for(typeof t.preInit=="function"&&(t.preInit=[t.preInit]);t.preInit.length>0;)t.preInit.pop()();return HA(),e}}();typeof Yw=="object"&&typeof GP=="object"?GP.exports=YP:typeof define=="function"&&define.amd?define([],function(){return YP}):typeof Yw=="object"&&(Yw.createModule=YP)});var i9=w((Tst,r9)=>{function jPe(r,e){for(var t=-1,i=r==null?0:r.length,n=Array(i);++t<i;)n[t]=e(r[t],t,r);return n}r9.exports=jPe});var Hs=w((Ost,n9)=>{var GPe=Array.isArray;n9.exports=GPe});var c9=w((Mst,s9)=>{var o9=Wc(),YPe=i9(),qPe=Hs(),JPe=yd(),WPe=1/0,a9=o9?o9.prototype:void 0,A9=a9?a9.toString:void 0;function l9(r){if(typeof r=="string")return r;if(qPe(r))return YPe(r,l9)+"";if(JPe(r))return A9?A9.call(r):"";var e=r+"";return e=="0"&&1/r==-WPe?"-0":e}s9.exports=l9});var cf=w((Ust,u9)=>{var zPe=c9();function _Pe(r){return r==null?"":zPe(r)}u9.exports=_Pe});var XP=w((Kst,g9)=>{function VPe(r,e,t){var i=-1,n=r.length;e<0&&(e=-e>n?0:n+e),t=t>n?n:t,t<0&&(t+=n),n=e>t?0:t-e>>>0,e>>>=0;for(var s=Array(n);++i<n;)s[i]=r[i+e];return s}g9.exports=VPe});var h9=w((Hst,f9)=>{var XPe=XP();function ZPe(r,e,t){var i=r.length;return t=t===void 0?i:t,!e&&t>=i?r:XPe(r,e,t)}f9.exports=ZPe});var ZP=w((jst,p9)=>{var $Pe="\\ud800-\\udfff",eDe="\\u0300-\\u036f",tDe="\\ufe20-\\ufe2f",rDe="\\u20d0-\\u20ff",iDe=eDe+tDe+rDe,nDe="\\ufe0e\\ufe0f",sDe="\\u200d",oDe=RegExp("["+sDe+$Pe+iDe+nDe+"]");function aDe(r){return oDe.test(r)}p9.exports=aDe});var C9=w((Gst,d9)=>{function ADe(r){return r.split("")}d9.exports=ADe});var Q9=w((Yst,m9)=>{var E9="\\ud800-\\udfff",lDe="\\u0300-\\u036f",cDe="\\ufe20-\\ufe2f",uDe="\\u20d0-\\u20ff",gDe=lDe+cDe+uDe,fDe="\\ufe0e\\ufe0f",hDe="["+E9+"]",$P="["+gDe+"]",eD="\\ud83c[\\udffb-\\udfff]",pDe="(?:"+$P+"|"+eD+")",I9="[^"+E9+"]",y9="(?:\\ud83c[\\udde6-\\uddff]){2}",w9="[\\ud800-\\udbff][\\udc00-\\udfff]",dDe="\\u200d",B9=pDe+"?",b9="["+fDe+"]?",CDe="(?:"+dDe+"(?:"+[I9,y9,w9].join("|")+")"+b9+B9+")*",mDe=b9+B9+CDe,EDe="(?:"+[I9+$P+"?",$P,y9,w9,hDe].join("|")+")",IDe=RegExp(eD+"(?="+eD+")|"+EDe+mDe,"g");function yDe(r){return r.match(IDe)||[]}m9.exports=yDe});var v9=w((qst,S9)=>{var wDe=C9(),BDe=ZP(),bDe=Q9();function QDe(r){return BDe(r)?bDe(r):wDe(r)}S9.exports=QDe});var x9=w((Jst,k9)=>{var SDe=h9(),vDe=ZP(),kDe=v9(),xDe=cf();function PDe(r){return function(e){e=xDe(e);var t=vDe(e)?kDe(e):void 0,i=t?t[0]:e.charAt(0),n=t?SDe(t,1).join(""):e.slice(1);return i[r]()+n}}k9.exports=PDe});var D9=w((Wst,P9)=>{var DDe=x9(),RDe=DDe("toUpperCase");P9.exports=RDe});var $w=w((zst,R9)=>{var FDe=cf(),NDe=D9();function LDe(r){return NDe(FDe(r).toLowerCase())}R9.exports=LDe});var F9=w((_st,eB)=>{function TDe(){var r=0,e=1,t=2,i=3,n=4,s=5,o=6,a=7,l=8,c=9,u=10,g=11,f=12,h=13,p=14,m=15,y=16,b=17,v=0,k=1,T=2,Y=3,q=4;function $(A,oe){return 55296<=A.charCodeAt(oe)&&A.charCodeAt(oe)<=56319&&56320<=A.charCodeAt(oe+1)&&A.charCodeAt(oe+1)<=57343}function z(A,oe){oe===void 0&&(oe=0);var ce=A.charCodeAt(oe);if(55296<=ce&&ce<=56319&&oe<A.length-1){var Z=ce,O=A.charCodeAt(oe+1);return 56320<=O&&O<=57343?(Z-55296)*1024+(O-56320)+65536:Z}if(56320<=ce&&ce<=57343&&oe>=1){var Z=A.charCodeAt(oe-1),O=ce;return 55296<=Z&&Z<=56319?(Z-55296)*1024+(O-56320)+65536:O}return ce}function ne(A,oe,ce){var Z=[A].concat(oe).concat([ce]),O=Z[Z.length-2],L=ce,de=Z.lastIndexOf(p);if(de>1&&Z.slice(1,de).every(function(re){return re==i})&&[i,h,b].indexOf(A)==-1)return T;var Be=Z.lastIndexOf(n);if(Be>0&&Z.slice(1,Be).every(function(re){return re==n})&&[f,n].indexOf(O)==-1)return Z.filter(function(re){return re==n}).length%2==1?Y:q;if(O==r&&L==e)return v;if(O==t||O==r||O==e)return L==p&&oe.every(function(re){return re==i})?T:k;if(L==t||L==r||L==e)return k;if(O==o&&(L==o||L==a||L==c||L==u))return v;if((O==c||O==a)&&(L==a||L==l))return v;if((O==u||O==l)&&L==l)return v;if(L==i||L==m)return v;if(L==s)return v;if(O==f)return v;var Ge=Z.indexOf(i)!=-1?Z.lastIndexOf(i)-1:Z.length-2;return[h,b].indexOf(Z[Ge])!=-1&&Z.slice(Ge+1,-1).every(function(re){return re==i})&&L==p||O==m&&[y,b].indexOf(L)!=-1?v:oe.indexOf(n)!=-1?T:O==n&&L==n?v:k}this.nextBreak=function(A,oe){if(oe===void 0&&(oe=0),oe<0)return 0;if(oe>=A.length-1)return A.length;for(var ce=ee(z(A,oe)),Z=[],O=oe+1;O<A.length;O++)if(!$(A,O-1)){var L=ee(z(A,O));if(ne(ce,Z,L))return O;Z.push(L)}return A.length},this.splitGraphemes=function(A){for(var oe=[],ce=0,Z;(Z=this.nextBreak(A,ce))<A.length;)oe.push(A.slice(ce,Z)),ce=Z;return ce<A.length&&oe.push(A.slice(ce)),oe},this.iterateGraphemes=function(A){var oe=0,ce={next:function(){var Z,O;return(O=this.nextBreak(A,oe))<A.length?(Z=A.slice(oe,O),oe=O,{value:Z,done:!1}):oe<A.length?(Z=A.slice(oe),oe=A.length,{value:Z,done:!1}):{value:void 0,done:!0}}.bind(this)};return typeof Symbol!="undefined"&&Symbol.iterator&&(ce[Symbol.iterator]=function(){return ce}),ce},this.countGraphemes=function(A){for(var oe=0,ce=0,Z;(Z=this.nextBreak(A,ce))<A.length;)ce=Z,oe++;return ce<A.length&&oe++,oe};function ee(A){return 1536<=A&&A<=1541||A==1757||A==1807||A==2274||A==3406||A==69821||70082<=A&&A<=70083||A==72250||72326<=A&&A<=72329||A==73030?f:A==13?r:A==10?e:0<=A&&A<=9||11<=A&&A<=12||14<=A&&A<=31||127<=A&&A<=159||A==173||A==1564||A==6158||A==8203||8206<=A&&A<=8207||A==8232||A==8233||8234<=A&&A<=8238||8288<=A&&A<=8292||A==8293||8294<=A&&A<=8303||55296<=A&&A<=57343||A==65279||65520<=A&&A<=65528||65529<=A&&A<=65531||113824<=A&&A<=113827||119155<=A&&A<=119162||A==917504||A==917505||917506<=A&&A<=917535||917632<=A&&A<=917759||918e3<=A&&A<=921599?t:768<=A&&A<=879||1155<=A&&A<=1159||1160<=A&&A<=1161||1425<=A&&A<=1469||A==1471||1473<=A&&A<=1474||1476<=A&&A<=1477||A==1479||1552<=A&&A<=1562||1611<=A&&A<=1631||A==1648||1750<=A&&A<=1756||1759<=A&&A<=1764||1767<=A&&A<=1768||1770<=A&&A<=1773||A==1809||1840<=A&&A<=1866||1958<=A&&A<=1968||2027<=A&&A<=2035||2070<=A&&A<=2073||2075<=A&&A<=2083||2085<=A&&A<=2087||2089<=A&&A<=2093||2137<=A&&A<=2139||2260<=A&&A<=2273||2275<=A&&A<=2306||A==2362||A==2364||2369<=A&&A<=2376||A==2381||2385<=A&&A<=2391||2402<=A&&A<=2403||A==2433||A==2492||A==2494||2497<=A&&A<=2500||A==2509||A==2519||2530<=A&&A<=2531||2561<=A&&A<=2562||A==2620||2625<=A&&A<=2626||2631<=A&&A<=2632||2635<=A&&A<=2637||A==2641||2672<=A&&A<=2673||A==2677||2689<=A&&A<=2690||A==2748||2753<=A&&A<=2757||2759<=A&&A<=2760||A==2765||2786<=A&&A<=2787||2810<=A&&A<=2815||A==2817||A==2876||A==2878||A==2879||2881<=A&&A<=2884||A==2893||A==2902||A==2903||2914<=A&&A<=2915||A==2946||A==3006||A==3008||A==3021||A==3031||A==3072||3134<=A&&A<=3136||3142<=A&&A<=3144||3146<=A&&A<=3149||3157<=A&&A<=3158||3170<=A&&A<=3171||A==3201||A==3260||A==3263||A==3266||A==3270||3276<=A&&A<=3277||3285<=A&&A<=3286||3298<=A&&A<=3299||3328<=A&&A<=3329||3387<=A&&A<=3388||A==3390||3393<=A&&A<=3396||A==3405||A==3415||3426<=A&&A<=3427||A==3530||A==3535||3538<=A&&A<=3540||A==3542||A==3551||A==3633||3636<=A&&A<=3642||3655<=A&&A<=3662||A==3761||3764<=A&&A<=3769||3771<=A&&A<=3772||3784<=A&&A<=3789||3864<=A&&A<=3865||A==3893||A==3895||A==3897||3953<=A&&A<=3966||3968<=A&&A<=3972||3974<=A&&A<=3975||3981<=A&&A<=3991||3993<=A&&A<=4028||A==4038||4141<=A&&A<=4144||4146<=A&&A<=4151||4153<=A&&A<=4154||4157<=A&&A<=4158||4184<=A&&A<=4185||4190<=A&&A<=4192||4209<=A&&A<=4212||A==4226||4229<=A&&A<=4230||A==4237||A==4253||4957<=A&&A<=4959||5906<=A&&A<=5908||5938<=A&&A<=5940||5970<=A&&A<=5971||6002<=A&&A<=6003||6068<=A&&A<=6069||6071<=A&&A<=6077||A==6086||6089<=A&&A<=6099||A==6109||6155<=A&&A<=6157||6277<=A&&A<=6278||A==6313||6432<=A&&A<=6434||6439<=A&&A<=6440||A==6450||6457<=A&&A<=6459||6679<=A&&A<=6680||A==6683||A==6742||6744<=A&&A<=6750||A==6752||A==6754||6757<=A&&A<=6764||6771<=A&&A<=6780||A==6783||6832<=A&&A<=6845||A==6846||6912<=A&&A<=6915||A==6964||6966<=A&&A<=6970||A==6972||A==6978||7019<=A&&A<=7027||7040<=A&&A<=7041||7074<=A&&A<=7077||7080<=A&&A<=7081||7083<=A&&A<=7085||A==7142||7144<=A&&A<=7145||A==7149||7151<=A&&A<=7153||7212<=A&&A<=7219||7222<=A&&A<=7223||7376<=A&&A<=7378||7380<=A&&A<=7392||7394<=A&&A<=7400||A==7405||A==7412||7416<=A&&A<=7417||7616<=A&&A<=7673||7675<=A&&A<=7679||A==8204||8400<=A&&A<=8412||8413<=A&&A<=8416||A==8417||8418<=A&&A<=8420||8421<=A&&A<=8432||11503<=A&&A<=11505||A==11647||11744<=A&&A<=11775||12330<=A&&A<=12333||12334<=A&&A<=12335||12441<=A&&A<=12442||A==42607||42608<=A&&A<=42610||42612<=A&&A<=42621||42654<=A&&A<=42655||42736<=A&&A<=42737||A==43010||A==43014||A==43019||43045<=A&&A<=43046||43204<=A&&A<=43205||43232<=A&&A<=43249||43302<=A&&A<=43309||43335<=A&&A<=43345||43392<=A&&A<=43394||A==43443||43446<=A&&A<=43449||A==43452||A==43493||43561<=A&&A<=43566||43569<=A&&A<=43570||43573<=A&&A<=43574||A==43587||A==43596||A==43644||A==43696||43698<=A&&A<=43700||43703<=A&&A<=43704||43710<=A&&A<=43711||A==43713||43756<=A&&A<=43757||A==43766||A==44005||A==44008||A==44013||A==64286||65024<=A&&A<=65039||65056<=A&&A<=65071||65438<=A&&A<=65439||A==66045||A==66272||66422<=A&&A<=66426||68097<=A&&A<=68099||68101<=A&&A<=68102||68108<=A&&A<=68111||68152<=A&&A<=68154||A==68159||68325<=A&&A<=68326||A==69633||69688<=A&&A<=69702||69759<=A&&A<=69761||69811<=A&&A<=69814||69817<=A&&A<=69818||69888<=A&&A<=69890||69927<=A&&A<=69931||69933<=A&&A<=69940||A==70003||70016<=A&&A<=70017||70070<=A&&A<=70078||70090<=A&&A<=70092||70191<=A&&A<=70193||A==70196||70198<=A&&A<=70199||A==70206||A==70367||70371<=A&&A<=70378||70400<=A&&A<=70401||A==70460||A==70462||A==70464||A==70487||70502<=A&&A<=70508||70512<=A&&A<=70516||70712<=A&&A<=70719||70722<=A&&A<=70724||A==70726||A==70832||70835<=A&&A<=70840||A==70842||A==70845||70847<=A&&A<=70848||70850<=A&&A<=70851||A==71087||71090<=A&&A<=71093||71100<=A&&A<=71101||71103<=A&&A<=71104||71132<=A&&A<=71133||71219<=A&&A<=71226||A==71229||71231<=A&&A<=71232||A==71339||A==71341||71344<=A&&A<=71349||A==71351||71453<=A&&A<=71455||71458<=A&&A<=71461||71463<=A&&A<=71467||72193<=A&&A<=72198||72201<=A&&A<=72202||72243<=A&&A<=72248||72251<=A&&A<=72254||A==72263||72273<=A&&A<=72278||72281<=A&&A<=72283||72330<=A&&A<=72342||72344<=A&&A<=72345||72752<=A&&A<=72758||72760<=A&&A<=72765||A==72767||72850<=A&&A<=72871||72874<=A&&A<=72880||72882<=A&&A<=72883||72885<=A&&A<=72886||73009<=A&&A<=73014||A==73018||73020<=A&&A<=73021||73023<=A&&A<=73029||A==73031||92912<=A&&A<=92916||92976<=A&&A<=92982||94095<=A&&A<=94098||113821<=A&&A<=113822||A==119141||119143<=A&&A<=119145||119150<=A&&A<=119154||119163<=A&&A<=119170||119173<=A&&A<=119179||119210<=A&&A<=119213||119362<=A&&A<=119364||121344<=A&&A<=121398||121403<=A&&A<=121452||A==121461||A==121476||121499<=A&&A<=121503||121505<=A&&A<=121519||122880<=A&&A<=122886||122888<=A&&A<=122904||122907<=A&&A<=122913||122915<=A&&A<=122916||122918<=A&&A<=122922||125136<=A&&A<=125142||125252<=A&&A<=125258||917536<=A&&A<=917631||917760<=A&&A<=917999?i:127462<=A&&A<=127487?n:A==2307||A==2363||2366<=A&&A<=2368||2377<=A&&A<=2380||2382<=A&&A<=2383||2434<=A&&A<=2435||2495<=A&&A<=2496||2503<=A&&A<=2504||2507<=A&&A<=2508||A==2563||2622<=A&&A<=2624||A==2691||2750<=A&&A<=2752||A==2761||2763<=A&&A<=2764||2818<=A&&A<=2819||A==2880||2887<=A&&A<=2888||2891<=A&&A<=2892||A==3007||3009<=A&&A<=3010||3014<=A&&A<=3016||3018<=A&&A<=3020||3073<=A&&A<=3075||3137<=A&&A<=3140||3202<=A&&A<=3203||A==3262||3264<=A&&A<=3265||3267<=A&&A<=3268||3271<=A&&A<=3272||3274<=A&&A<=3275||3330<=A&&A<=3331||3391<=A&&A<=3392||3398<=A&&A<=3400||3402<=A&&A<=3404||3458<=A&&A<=3459||3536<=A&&A<=3537||3544<=A&&A<=3550||3570<=A&&A<=3571||A==3635||A==3763||3902<=A&&A<=3903||A==3967||A==4145||4155<=A&&A<=4156||4182<=A&&A<=4183||A==4228||A==6070||6078<=A&&A<=6085||6087<=A&&A<=6088||6435<=A&&A<=6438||6441<=A&&A<=6443||6448<=A&&A<=6449||6451<=A&&A<=6456||6681<=A&&A<=6682||A==6741||A==6743||6765<=A&&A<=6770||A==6916||A==6965||A==6971||6973<=A&&A<=6977||6979<=A&&A<=6980||A==7042||A==7073||7078<=A&&A<=7079||A==7082||A==7143||7146<=A&&A<=7148||A==7150||7154<=A&&A<=7155||7204<=A&&A<=7211||7220<=A&&A<=7221||A==7393||7410<=A&&A<=7411||A==7415||43043<=A&&A<=43044||A==43047||43136<=A&&A<=43137||43188<=A&&A<=43203||43346<=A&&A<=43347||A==43395||43444<=A&&A<=43445||43450<=A&&A<=43451||43453<=A&&A<=43456||43567<=A&&A<=43568||43571<=A&&A<=43572||A==43597||A==43755||43758<=A&&A<=43759||A==43765||44003<=A&&A<=44004||44006<=A&&A<=44007||44009<=A&&A<=44010||A==44012||A==69632||A==69634||A==69762||69808<=A&&A<=69810||69815<=A&&A<=69816||A==69932||A==70018||70067<=A&&A<=70069||70079<=A&&A<=70080||70188<=A&&A<=70190||70194<=A&&A<=70195||A==70197||70368<=A&&A<=70370||70402<=A&&A<=70403||A==70463||70465<=A&&A<=70468||70471<=A&&A<=70472||70475<=A&&A<=70477||70498<=A&&A<=70499||70709<=A&&A<=70711||70720<=A&&A<=70721||A==70725||70833<=A&&A<=70834||A==70841||70843<=A&&A<=70844||A==70846||A==70849||71088<=A&&A<=71089||71096<=A&&A<=71099||A==71102||71216<=A&&A<=71218||71227<=A&&A<=71228||A==71230||A==71340||71342<=A&&A<=71343||A==71350||71456<=A&&A<=71457||A==71462||72199<=A&&A<=72200||A==72249||72279<=A&&A<=72280||A==72343||A==72751||A==72766||A==72873||A==72881||A==72884||94033<=A&&A<=94078||A==119142||A==119149?s:4352<=A&&A<=4447||43360<=A&&A<=43388?o:4448<=A&&A<=4519||55216<=A&&A<=55238?a:4520<=A&&A<=4607||55243<=A&&A<=55291?l:A==44032||A==44060||A==44088||A==44116||A==44144||A==44172||A==44200||A==44228||A==44256||A==44284||A==44312||A==44340||A==44368||A==44396||A==44424||A==44452||A==44480||A==44508||A==44536||A==44564||A==44592||A==44620||A==44648||A==44676||A==44704||A==44732||A==44760||A==44788||A==44816||A==44844||A==44872||A==44900||A==44928||A==44956||A==44984||A==45012||A==45040||A==45068||A==45096||A==45124||A==45152||A==45180||A==45208||A==45236||A==45264||A==45292||A==45320||A==45348||A==45376||A==45404||A==45432||A==45460||A==45488||A==45516||A==45544||A==45572||A==45600||A==45628||A==45656||A==45684||A==45712||A==45740||A==45768||A==45796||A==45824||A==45852||A==45880||A==45908||A==45936||A==45964||A==45992||A==46020||A==46048||A==46076||A==46104||A==46132||A==46160||A==46188||A==46216||A==46244||A==46272||A==46300||A==46328||A==46356||A==46384||A==46412||A==46440||A==46468||A==46496||A==46524||A==46552||A==46580||A==46608||A==46636||A==46664||A==46692||A==46720||A==46748||A==46776||A==46804||A==46832||A==46860||A==46888||A==46916||A==46944||A==46972||A==47e3||A==47028||A==47056||A==47084||A==47112||A==47140||A==47168||A==47196||A==47224||A==47252||A==47280||A==47308||A==47336||A==47364||A==47392||A==47420||A==47448||A==47476||A==47504||A==47532||A==47560||A==47588||A==47616||A==47644||A==47672||A==47700||A==47728||A==47756||A==47784||A==47812||A==47840||A==47868||A==47896||A==47924||A==47952||A==47980||A==48008||A==48036||A==48064||A==48092||A==48120||A==48148||A==48176||A==48204||A==48232||A==48260||A==48288||A==48316||A==48344||A==48372||A==48400||A==48428||A==48456||A==48484||A==48512||A==48540||A==48568||A==48596||A==48624||A==48652||A==48680||A==48708||A==48736||A==48764||A==48792||A==48820||A==48848||A==48876||A==48904||A==48932||A==48960||A==48988||A==49016||A==49044||A==49072||A==49100||A==49128||A==49156||A==49184||A==49212||A==49240||A==49268||A==49296||A==49324||A==49352||A==49380||A==49408||A==49436||A==49464||A==49492||A==49520||A==49548||A==49576||A==49604||A==49632||A==49660||A==49688||A==49716||A==49744||A==49772||A==49800||A==49828||A==49856||A==49884||A==49912||A==49940||A==49968||A==49996||A==50024||A==50052||A==50080||A==50108||A==50136||A==50164||A==50192||A==50220||A==50248||A==50276||A==50304||A==50332||A==50360||A==50388||A==50416||A==50444||A==50472||A==50500||A==50528||A==50556||A==50584||A==50612||A==50640||A==50668||A==50696||A==50724||A==50752||A==50780||A==50808||A==50836||A==50864||A==50892||A==50920||A==50948||A==50976||A==51004||A==51032||A==51060||A==51088||A==51116||A==51144||A==51172||A==51200||A==51228||A==51256||A==51284||A==51312||A==51340||A==51368||A==51396||A==51424||A==51452||A==51480||A==51508||A==51536||A==51564||A==51592||A==51620||A==51648||A==51676||A==51704||A==51732||A==51760||A==51788||A==51816||A==51844||A==51872||A==51900||A==51928||A==51956||A==51984||A==52012||A==52040||A==52068||A==52096||A==52124||A==52152||A==52180||A==52208||A==52236||A==52264||A==52292||A==52320||A==52348||A==52376||A==52404||A==52432||A==52460||A==52488||A==52516||A==52544||A==52572||A==52600||A==52628||A==52656||A==52684||A==52712||A==52740||A==52768||A==52796||A==52824||A==52852||A==52880||A==52908||A==52936||A==52964||A==52992||A==53020||A==53048||A==53076||A==53104||A==53132||A==53160||A==53188||A==53216||A==53244||A==53272||A==53300||A==53328||A==53356||A==53384||A==53412||A==53440||A==53468||A==53496||A==53524||A==53552||A==53580||A==53608||A==53636||A==53664||A==53692||A==53720||A==53748||A==53776||A==53804||A==53832||A==53860||A==53888||A==53916||A==53944||A==53972||A==54e3||A==54028||A==54056||A==54084||A==54112||A==54140||A==54168||A==54196||A==54224||A==54252||A==54280||A==54308||A==54336||A==54364||A==54392||A==54420||A==54448||A==54476||A==54504||A==54532||A==54560||A==54588||A==54616||A==54644||A==54672||A==54700||A==54728||A==54756||A==54784||A==54812||A==54840||A==54868||A==54896||A==54924||A==54952||A==54980||A==55008||A==55036||A==55064||A==55092||A==55120||A==55148||A==55176?c:44033<=A&&A<=44059||44061<=A&&A<=44087||44089<=A&&A<=44115||44117<=A&&A<=44143||44145<=A&&A<=44171||44173<=A&&A<=44199||44201<=A&&A<=44227||44229<=A&&A<=44255||44257<=A&&A<=44283||44285<=A&&A<=44311||44313<=A&&A<=44339||44341<=A&&A<=44367||44369<=A&&A<=44395||44397<=A&&A<=44423||44425<=A&&A<=44451||44453<=A&&A<=44479||44481<=A&&A<=44507||44509<=A&&A<=44535||44537<=A&&A<=44563||44565<=A&&A<=44591||44593<=A&&A<=44619||44621<=A&&A<=44647||44649<=A&&A<=44675||44677<=A&&A<=44703||44705<=A&&A<=44731||44733<=A&&A<=44759||44761<=A&&A<=44787||44789<=A&&A<=44815||44817<=A&&A<=44843||44845<=A&&A<=44871||44873<=A&&A<=44899||44901<=A&&A<=44927||44929<=A&&A<=44955||44957<=A&&A<=44983||44985<=A&&A<=45011||45013<=A&&A<=45039||45041<=A&&A<=45067||45069<=A&&A<=45095||45097<=A&&A<=45123||45125<=A&&A<=45151||45153<=A&&A<=45179||45181<=A&&A<=45207||45209<=A&&A<=45235||45237<=A&&A<=45263||45265<=A&&A<=45291||45293<=A&&A<=45319||45321<=A&&A<=45347||45349<=A&&A<=45375||45377<=A&&A<=45403||45405<=A&&A<=45431||45433<=A&&A<=45459||45461<=A&&A<=45487||45489<=A&&A<=45515||45517<=A&&A<=45543||45545<=A&&A<=45571||45573<=A&&A<=45599||45601<=A&&A<=45627||45629<=A&&A<=45655||45657<=A&&A<=45683||45685<=A&&A<=45711||45713<=A&&A<=45739||45741<=A&&A<=45767||45769<=A&&A<=45795||45797<=A&&A<=45823||45825<=A&&A<=45851||45853<=A&&A<=45879||45881<=A&&A<=45907||45909<=A&&A<=45935||45937<=A&&A<=45963||45965<=A&&A<=45991||45993<=A&&A<=46019||46021<=A&&A<=46047||46049<=A&&A<=46075||46077<=A&&A<=46103||46105<=A&&A<=46131||46133<=A&&A<=46159||46161<=A&&A<=46187||46189<=A&&A<=46215||46217<=A&&A<=46243||46245<=A&&A<=46271||46273<=A&&A<=46299||46301<=A&&A<=46327||46329<=A&&A<=46355||46357<=A&&A<=46383||46385<=A&&A<=46411||46413<=A&&A<=46439||46441<=A&&A<=46467||46469<=A&&A<=46495||46497<=A&&A<=46523||46525<=A&&A<=46551||46553<=A&&A<=46579||46581<=A&&A<=46607||46609<=A&&A<=46635||46637<=A&&A<=46663||46665<=A&&A<=46691||46693<=A&&A<=46719||46721<=A&&A<=46747||46749<=A&&A<=46775||46777<=A&&A<=46803||46805<=A&&A<=46831||46833<=A&&A<=46859||46861<=A&&A<=46887||46889<=A&&A<=46915||46917<=A&&A<=46943||46945<=A&&A<=46971||46973<=A&&A<=46999||47001<=A&&A<=47027||47029<=A&&A<=47055||47057<=A&&A<=47083||47085<=A&&A<=47111||47113<=A&&A<=47139||47141<=A&&A<=47167||47169<=A&&A<=47195||47197<=A&&A<=47223||47225<=A&&A<=47251||47253<=A&&A<=47279||47281<=A&&A<=47307||47309<=A&&A<=47335||47337<=A&&A<=47363||47365<=A&&A<=47391||47393<=A&&A<=47419||47421<=A&&A<=47447||47449<=A&&A<=47475||47477<=A&&A<=47503||47505<=A&&A<=47531||47533<=A&&A<=47559||47561<=A&&A<=47587||47589<=A&&A<=47615||47617<=A&&A<=47643||47645<=A&&A<=47671||47673<=A&&A<=47699||47701<=A&&A<=47727||47729<=A&&A<=47755||47757<=A&&A<=47783||47785<=A&&A<=47811||47813<=A&&A<=47839||47841<=A&&A<=47867||47869<=A&&A<=47895||47897<=A&&A<=47923||47925<=A&&A<=47951||47953<=A&&A<=47979||47981<=A&&A<=48007||48009<=A&&A<=48035||48037<=A&&A<=48063||48065<=A&&A<=48091||48093<=A&&A<=48119||48121<=A&&A<=48147||48149<=A&&A<=48175||48177<=A&&A<=48203||48205<=A&&A<=48231||48233<=A&&A<=48259||48261<=A&&A<=48287||48289<=A&&A<=48315||48317<=A&&A<=48343||48345<=A&&A<=48371||48373<=A&&A<=48399||48401<=A&&A<=48427||48429<=A&&A<=48455||48457<=A&&A<=48483||48485<=A&&A<=48511||48513<=A&&A<=48539||48541<=A&&A<=48567||48569<=A&&A<=48595||48597<=A&&A<=48623||48625<=A&&A<=48651||48653<=A&&A<=48679||48681<=A&&A<=48707||48709<=A&&A<=48735||48737<=A&&A<=48763||48765<=A&&A<=48791||48793<=A&&A<=48819||48821<=A&&A<=48847||48849<=A&&A<=48875||48877<=A&&A<=48903||48905<=A&&A<=48931||48933<=A&&A<=48959||48961<=A&&A<=48987||48989<=A&&A<=49015||49017<=A&&A<=49043||49045<=A&&A<=49071||49073<=A&&A<=49099||49101<=A&&A<=49127||49129<=A&&A<=49155||49157<=A&&A<=49183||49185<=A&&A<=49211||49213<=A&&A<=49239||49241<=A&&A<=49267||49269<=A&&A<=49295||49297<=A&&A<=49323||49325<=A&&A<=49351||49353<=A&&A<=49379||49381<=A&&A<=49407||49409<=A&&A<=49435||49437<=A&&A<=49463||49465<=A&&A<=49491||49493<=A&&A<=49519||49521<=A&&A<=49547||49549<=A&&A<=49575||49577<=A&&A<=49603||49605<=A&&A<=49631||49633<=A&&A<=49659||49661<=A&&A<=49687||49689<=A&&A<=49715||49717<=A&&A<=49743||49745<=A&&A<=49771||49773<=A&&A<=49799||49801<=A&&A<=49827||49829<=A&&A<=49855||49857<=A&&A<=49883||49885<=A&&A<=49911||49913<=A&&A<=49939||49941<=A&&A<=49967||49969<=A&&A<=49995||49997<=A&&A<=50023||50025<=A&&A<=50051||50053<=A&&A<=50079||50081<=A&&A<=50107||50109<=A&&A<=50135||50137<=A&&A<=50163||50165<=A&&A<=50191||50193<=A&&A<=50219||50221<=A&&A<=50247||50249<=A&&A<=50275||50277<=A&&A<=50303||50305<=A&&A<=50331||50333<=A&&A<=50359||50361<=A&&A<=50387||50389<=A&&A<=50415||50417<=A&&A<=50443||50445<=A&&A<=50471||50473<=A&&A<=50499||50501<=A&&A<=50527||50529<=A&&A<=50555||50557<=A&&A<=50583||50585<=A&&A<=50611||50613<=A&&A<=50639||50641<=A&&A<=50667||50669<=A&&A<=50695||50697<=A&&A<=50723||50725<=A&&A<=50751||50753<=A&&A<=50779||50781<=A&&A<=50807||50809<=A&&A<=50835||50837<=A&&A<=50863||50865<=A&&A<=50891||50893<=A&&A<=50919||50921<=A&&A<=50947||50949<=A&&A<=50975||50977<=A&&A<=51003||51005<=A&&A<=51031||51033<=A&&A<=51059||51061<=A&&A<=51087||51089<=A&&A<=51115||51117<=A&&A<=51143||51145<=A&&A<=51171||51173<=A&&A<=51199||51201<=A&&A<=51227||51229<=A&&A<=51255||51257<=A&&A<=51283||51285<=A&&A<=51311||51313<=A&&A<=51339||51341<=A&&A<=51367||51369<=A&&A<=51395||51397<=A&&A<=51423||51425<=A&&A<=51451||51453<=A&&A<=51479||51481<=A&&A<=51507||51509<=A&&A<=51535||51537<=A&&A<=51563||51565<=A&&A<=51591||51593<=A&&A<=51619||51621<=A&&A<=51647||51649<=A&&A<=51675||51677<=A&&A<=51703||51705<=A&&A<=51731||51733<=A&&A<=51759||51761<=A&&A<=51787||51789<=A&&A<=51815||51817<=A&&A<=51843||51845<=A&&A<=51871||51873<=A&&A<=51899||51901<=A&&A<=51927||51929<=A&&A<=51955||51957<=A&&A<=51983||51985<=A&&A<=52011||52013<=A&&A<=52039||52041<=A&&A<=52067||52069<=A&&A<=52095||52097<=A&&A<=52123||52125<=A&&A<=52151||52153<=A&&A<=52179||52181<=A&&A<=52207||52209<=A&&A<=52235||52237<=A&&A<=52263||52265<=A&&A<=52291||52293<=A&&A<=52319||52321<=A&&A<=52347||52349<=A&&A<=52375||52377<=A&&A<=52403||52405<=A&&A<=52431||52433<=A&&A<=52459||52461<=A&&A<=52487||52489<=A&&A<=52515||52517<=A&&A<=52543||52545<=A&&A<=52571||52573<=A&&A<=52599||52601<=A&&A<=52627||52629<=A&&A<=52655||52657<=A&&A<=52683||52685<=A&&A<=52711||52713<=A&&A<=52739||52741<=A&&A<=52767||52769<=A&&A<=52795||52797<=A&&A<=52823||52825<=A&&A<=52851||52853<=A&&A<=52879||52881<=A&&A<=52907||52909<=A&&A<=52935||52937<=A&&A<=52963||52965<=A&&A<=52991||52993<=A&&A<=53019||53021<=A&&A<=53047||53049<=A&&A<=53075||53077<=A&&A<=53103||53105<=A&&A<=53131||53133<=A&&A<=53159||53161<=A&&A<=53187||53189<=A&&A<=53215||53217<=A&&A<=53243||53245<=A&&A<=53271||53273<=A&&A<=53299||53301<=A&&A<=53327||53329<=A&&A<=53355||53357<=A&&A<=53383||53385<=A&&A<=53411||53413<=A&&A<=53439||53441<=A&&A<=53467||53469<=A&&A<=53495||53497<=A&&A<=53523||53525<=A&&A<=53551||53553<=A&&A<=53579||53581<=A&&A<=53607||53609<=A&&A<=53635||53637<=A&&A<=53663||53665<=A&&A<=53691||53693<=A&&A<=53719||53721<=A&&A<=53747||53749<=A&&A<=53775||53777<=A&&A<=53803||53805<=A&&A<=53831||53833<=A&&A<=53859||53861<=A&&A<=53887||53889<=A&&A<=53915||53917<=A&&A<=53943||53945<=A&&A<=53971||53973<=A&&A<=53999||54001<=A&&A<=54027||54029<=A&&A<=54055||54057<=A&&A<=54083||54085<=A&&A<=54111||54113<=A&&A<=54139||54141<=A&&A<=54167||54169<=A&&A<=54195||54197<=A&&A<=54223||54225<=A&&A<=54251||54253<=A&&A<=54279||54281<=A&&A<=54307||54309<=A&&A<=54335||54337<=A&&A<=54363||54365<=A&&A<=54391||54393<=A&&A<=54419||54421<=A&&A<=54447||54449<=A&&A<=54475||54477<=A&&A<=54503||54505<=A&&A<=54531||54533<=A&&A<=54559||54561<=A&&A<=54587||54589<=A&&A<=54615||54617<=A&&A<=54643||54645<=A&&A<=54671||54673<=A&&A<=54699||54701<=A&&A<=54727||54729<=A&&A<=54755||54757<=A&&A<=54783||54785<=A&&A<=54811||54813<=A&&A<=54839||54841<=A&&A<=54867||54869<=A&&A<=54895||54897<=A&&A<=54923||54925<=A&&A<=54951||54953<=A&&A<=54979||54981<=A&&A<=55007||55009<=A&&A<=55035||55037<=A&&A<=55063||55065<=A&&A<=55091||55093<=A&&A<=55119||55121<=A&&A<=55147||55149<=A&&A<=55175||55177<=A&&A<=55203?u:A==9757||A==9977||9994<=A&&A<=9997||A==127877||127938<=A&&A<=127940||A==127943||127946<=A&&A<=127948||128066<=A&&A<=128067||128070<=A&&A<=128080||A==128110||128112<=A&&A<=128120||A==128124||128129<=A&&A<=128131||128133<=A&&A<=128135||A==128170||128372<=A&&A<=128373||A==128378||A==128400||128405<=A&&A<=128406||128581<=A&&A<=128583||128587<=A&&A<=128591||A==128675||128692<=A&&A<=128694||A==128704||A==128716||129304<=A&&A<=129308||129310<=A&&A<=129311||A==129318||129328<=A&&A<=129337||129341<=A&&A<=129342||129489<=A&&A<=129501?h:127995<=A&&A<=127999?p:A==8205?m:A==9792||A==9794||9877<=A&&A<=9878||A==9992||A==10084||A==127752||A==127806||A==127859||A==127891||A==127908||A==127912||A==127979||A==127981||A==128139||128187<=A&&A<=128188||A==128295||A==128300||A==128488||A==128640||A==128658?y:128102<=A&&A<=128105?b:g}return this}typeof eB!="undefined"&&eB.exports&&(eB.exports=TDe)});var L9=w((Vst,N9)=>{var ODe=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,tB;function MDe(){if(tB)return tB;if(typeof Intl.Segmenter!="undefined"){let r=new Intl.Segmenter("en",{granularity:"grapheme"});return tB=e=>Array.from(r.segment(e),({segment:t})=>t)}else{let r=F9(),e=new r;return tB=t=>e.splitGraphemes(t)}}N9.exports=(r,e=0,t=r.length)=>{if(e<0||t<0)throw new RangeError("Negative indices aren't supported by this implementation");let i=t-e,n="",s=0,o=0;for(;r.length>0;){let a=r.match(ODe)||[r,r,void 0],l=MDe()(a[1]),c=Math.min(e-s,l.length);l=l.slice(c);let u=Math.min(i-o,l.length);n+=l.slice(0,u).join(""),s+=c,o+=u,typeof a[2]!="undefined"&&(n+=a[2]),r=r.slice(a[0].length)}return n}});var uf=w((Qot,_9)=>{"use strict";var V9=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"]]),bot=_9.exports=r=>r?Object.keys(r).map(e=>[V9.has(e)?V9.get(e):e,r[e]]).reduce((e,t)=>(e[t[0]]=t[1],e),Object.create(null)):{}});var gf=w((Sot,X9)=>{"use strict";var XDe=require("events"),Z9=require("stream"),Jd=bp(),$9=require("string_decoder").StringDecoder,cA=Symbol("EOF"),Wd=Symbol("maybeEmitEnd"),yl=Symbol("emittedEnd"),aB=Symbol("emittingEnd"),AB=Symbol("closed"),e_=Symbol("read"),nD=Symbol("flush"),t_=Symbol("flushChunk"),Ln=Symbol("encoding"),uA=Symbol("decoder"),lB=Symbol("flowing"),zd=Symbol("paused"),_d=Symbol("resume"),pn=Symbol("bufferLength"),r_=Symbol("bufferPush"),sD=Symbol("bufferShift"),_i=Symbol("objectMode"),Vi=Symbol("destroyed"),i_=global._MP_NO_ITERATOR_SYMBOLS_!=="1",ZDe=i_&&Symbol.asyncIterator||Symbol("asyncIterator not implemented"),$De=i_&&Symbol.iterator||Symbol("iterator not implemented"),n_=r=>r==="end"||r==="finish"||r==="prefinish",eRe=r=>r instanceof ArrayBuffer||typeof r=="object"&&r.constructor&&r.constructor.name==="ArrayBuffer"&&r.byteLength>=0,tRe=r=>!Buffer.isBuffer(r)&&ArrayBuffer.isView(r);X9.exports=class s_ extends Z9{constructor(e){super();this[lB]=!1,this[zd]=!1,this.pipes=new Jd,this.buffer=new Jd,this[_i]=e&&e.objectMode||!1,this[_i]?this[Ln]=null:this[Ln]=e&&e.encoding||null,this[Ln]==="buffer"&&(this[Ln]=null),this[uA]=this[Ln]?new $9(this[Ln]):null,this[cA]=!1,this[yl]=!1,this[aB]=!1,this[AB]=!1,this.writable=!0,this.readable=!0,this[pn]=0,this[Vi]=!1}get bufferLength(){return this[pn]}get encoding(){return this[Ln]}set encoding(e){if(this[_i])throw new Error("cannot set encoding in objectMode");if(this[Ln]&&e!==this[Ln]&&(this[uA]&&this[uA].lastNeed||this[pn]))throw new Error("cannot change encoding");this[Ln]!==e&&(this[uA]=e?new $9(e):null,this.buffer.length&&(this.buffer=this.buffer.map(t=>this[uA].write(t)))),this[Ln]=e}setEncoding(e){this.encoding=e}get objectMode(){return this[_i]}set objectMode(e){this[_i]=this[_i]||!!e}write(e,t,i){if(this[cA])throw new Error("write after end");return this[Vi]?(this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0):(typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8"),!this[_i]&&!Buffer.isBuffer(e)&&(tRe(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):eRe(e)?e=Buffer.from(e):typeof e!="string"&&(this.objectMode=!0)),!this.objectMode&&!e.length?(this[pn]!==0&&this.emit("readable"),i&&i(),this.flowing):(typeof e=="string"&&!this[_i]&&!(t===this[Ln]&&!this[uA].lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[Ln]&&(e=this[uA].write(e)),this.flowing?(this[pn]!==0&&this[nD](!0),this.emit("data",e)):this[r_](e),this[pn]!==0&&this.emit("readable"),i&&i(),this.flowing))}read(e){if(this[Vi])return null;try{return this[pn]===0||e===0||e>this[pn]?null:(this[_i]&&(e=null),this.buffer.length>1&&!this[_i]&&(this.encoding?this.buffer=new Jd([Array.from(this.buffer).join("")]):this.buffer=new Jd([Buffer.concat(Array.from(this.buffer),this[pn])])),this[e_](e||null,this.buffer.head.value))}finally{this[Wd]()}}[e_](e,t){return e===t.length||e===null?this[sD]():(this.buffer.head.value=t.slice(e),t=t.slice(0,e),this[pn]-=e),this.emit("data",t),!this.buffer.length&&!this[cA]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=null),typeof t=="function"&&(i=t,t="utf8"),e&&this.write(e,t),i&&this.once("end",i),this[cA]=!0,this.writable=!1,(this.flowing||!this[zd])&&this[Wd](),this}[_d](){this[Vi]||(this[zd]=!1,this[lB]=!0,this.emit("resume"),this.buffer.length?this[nD]():this[cA]?this[Wd]():this.emit("drain"))}resume(){return this[_d]()}pause(){this[lB]=!1,this[zd]=!0}get destroyed(){return this[Vi]}get flowing(){return this[lB]}get paused(){return this[zd]}[r_](e){return this[_i]?this[pn]+=1:this[pn]+=e.length,this.buffer.push(e)}[sD](){return this.buffer.length&&(this[_i]?this[pn]-=1:this[pn]-=this.buffer.head.value.length),this.buffer.shift()}[nD](e){do;while(this[t_](this[sD]()));!e&&!this.buffer.length&&!this[cA]&&this.emit("drain")}[t_](e){return e?(this.emit("data",e),this.flowing):!1}pipe(e,t){if(this[Vi])return;let i=this[yl];t=t||{},e===process.stdout||e===process.stderr?t.end=!1:t.end=t.end!==!1;let n={dest:e,opts:t,ondrain:s=>this[_d]()};return this.pipes.push(n),e.on("drain",n.ondrain),this[_d](),i&&n.opts.end&&n.dest.end(),e}addListener(e,t){return this.on(e,t)}on(e,t){try{return super.on(e,t)}finally{e==="data"&&!this.pipes.length&&!this.flowing?this[_d]():n_(e)&&this[yl]&&(super.emit(e),this.removeAllListeners(e))}}get emittedEnd(){return this[yl]}[Wd](){!this[aB]&&!this[yl]&&!this[Vi]&&this.buffer.length===0&&this[cA]&&(this[aB]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[AB]&&this.emit("close"),this[aB]=!1)}emit(e,t){if(e!=="error"&&e!=="close"&&e!==Vi&&this[Vi])return;if(e==="data"){if(!t)return;this.pipes.length&&this.pipes.forEach(n=>n.dest.write(t)===!1&&this.pause())}else if(e==="end"){if(this[yl]===!0)return;this[yl]=!0,this.readable=!1,this[uA]&&(t=this[uA].end(),t&&(this.pipes.forEach(n=>n.dest.write(t)),super.emit("data",t))),this.pipes.forEach(n=>{n.dest.removeListener("drain",n.ondrain),n.opts.end&&n.dest.end()})}else if(e==="close"&&(this[AB]=!0,!this[yl]&&!this[Vi]))return;let i=new Array(arguments.length);if(i[0]=e,i[1]=t,arguments.length>2)for(let n=2;n<arguments.length;n++)i[n]=arguments[n];try{return super.emit.apply(this,i)}finally{n_(e)?this.removeAllListeners(e):this[Wd]()}}collect(){let e=[];this[_i]||(e.dataLength=0);let t=this.promise();return this.on("data",i=>{e.push(i),this[_i]||(e.dataLength+=i.length)}),t.then(()=>e)}concat(){return this[_i]?Promise.reject(new Error("cannot concat in objectMode")):this.collect().then(e=>this[_i]?Promise.reject(new Error("cannot concat in objectMode")):this[Ln]?e.join(""):Buffer.concat(e,e.dataLength))}promise(){return new Promise((e,t)=>{this.on(Vi,()=>t(new Error("stream destroyed"))),this.on("end",()=>e()),this.on("error",i=>t(i))})}[ZDe](){return{next:()=>{let t=this.read();if(t!==null)return Promise.resolve({done:!1,value:t});if(this[cA])return Promise.resolve({done:!0});let i=null,n=null,s=c=>{this.removeListener("data",o),this.removeListener("end",a),n(c)},o=c=>{this.removeListener("error",s),this.removeListener("end",a),this.pause(),i({value:c,done:!!this[cA]})},a=()=>{this.removeListener("error",s),this.removeListener("data",o),i({done:!0})},l=()=>s(new Error("stream destroyed"));return new Promise((c,u)=>{n=u,i=c,this.once(Vi,l),this.once("error",s),this.once("end",a),this.once("data",o)})}}}[$De](){return{next:()=>{let t=this.read();return{value:t,done:t===null}}}}destroy(e){return this[Vi]?(e?this.emit("error",e):this.emit(Vi),this):(this[Vi]=!0,this.buffer=new Jd,this[pn]=0,typeof this.close=="function"&&!this[AB]&&this.close(),e?this.emit("error",e):this.emit(Vi),this)}static isStream(e){return!!e&&(e instanceof s_||e instanceof Z9||e instanceof XDe&&(typeof e.pipe=="function"||typeof e.write=="function"&&typeof e.end=="function"))}}});var a_=w((vot,o_)=>{var rRe=require("zlib").constants||{ZLIB_VERNUM:4736};o_.exports=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:Infinity,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},rRe))});var hD=w(as=>{"use strict";var oD=require("assert"),wl=require("buffer").Buffer,A_=require("zlib"),$c=as.constants=a_(),iRe=gf(),l_=wl.concat,eu=Symbol("_superWrite"),Vd=class extends Error{constructor(e){super("zlib: "+e.message);this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,this.constructor)}get name(){return"ZlibError"}},nRe=Symbol("opts"),Xd=Symbol("flushFlag"),c_=Symbol("finishFlushFlag"),aD=Symbol("fullFlushFlag"),pr=Symbol("handle"),cB=Symbol("onError"),ff=Symbol("sawError"),AD=Symbol("level"),lD=Symbol("strategy"),cD=Symbol("ended"),kot=Symbol("_defaultFullFlush"),uD=class extends iRe{constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");super(e);this[ff]=!1,this[cD]=!1,this[nRe]=e,this[Xd]=e.flush,this[c_]=e.finishFlush;try{this[pr]=new A_[t](e)}catch(i){throw new Vd(i)}this[cB]=i=>{this[ff]||(this[ff]=!0,this.close(),this.emit("error",i))},this[pr].on("error",i=>this[cB](new Vd(i))),this.once("end",()=>this.close)}close(){this[pr]&&(this[pr].close(),this[pr]=null,this.emit("close"))}reset(){if(!this[ff])return oD(this[pr],"zlib binding closed"),this[pr].reset()}flush(e){this.ended||(typeof e!="number"&&(e=this[aD]),this.write(Object.assign(wl.alloc(0),{[Xd]:e})))}end(e,t,i){return e&&this.write(e,t),this.flush(this[c_]),this[cD]=!0,super.end(null,null,i)}get ended(){return this[cD]}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=wl.from(e,t)),this[ff])return;oD(this[pr],"zlib binding closed");let n=this[pr]._handle,s=n.close;n.close=()=>{};let o=this[pr].close;this[pr].close=()=>{},wl.concat=c=>c;let a;try{let c=typeof e[Xd]=="number"?e[Xd]:this[Xd];a=this[pr]._processChunk(e,c),wl.concat=l_}catch(c){wl.concat=l_,this[cB](new Vd(c))}finally{this[pr]&&(this[pr]._handle=n,n.close=s,this[pr].close=o,this[pr].removeAllListeners("error"))}this[pr]&&this[pr].on("error",c=>this[cB](new Vd(c)));let l;if(a)if(Array.isArray(a)&&a.length>0){l=this[eu](wl.from(a[0]));for(let c=1;c<a.length;c++)l=this[eu](a[c])}else l=this[eu](wl.from(a));return i&&i(),l}[eu](e){return super.write(e)}},Bl=class extends uD{constructor(e,t){e=e||{},e.flush=e.flush||$c.Z_NO_FLUSH,e.finishFlush=e.finishFlush||$c.Z_FINISH,super(e,t),this[aD]=$c.Z_FULL_FLUSH,this[AD]=e.level,this[lD]=e.strategy}params(e,t){if(!this[ff]){if(!this[pr])throw new Error("cannot switch params when binding is closed");if(!this[pr].params)throw new Error("not supported in this implementation");if(this[AD]!==e||this[lD]!==t){this.flush($c.Z_SYNC_FLUSH),oD(this[pr],"zlib binding closed");let i=this[pr].flush;this[pr].flush=(n,s)=>{this.flush(n),s()};try{this[pr].params(e,t)}finally{this[pr].flush=i}this[pr]&&(this[AD]=e,this[lD]=t)}}}},u_=class extends Bl{constructor(e){super(e,"Deflate")}},g_=class extends Bl{constructor(e){super(e,"Inflate")}},gD=Symbol("_portable"),f_=class extends Bl{constructor(e){super(e,"Gzip");this[gD]=e&&!!e.portable}[eu](e){return this[gD]?(this[gD]=!1,e[9]=255,super[eu](e)):super[eu](e)}},h_=class extends Bl{constructor(e){super(e,"Gunzip")}},p_=class extends Bl{constructor(e){super(e,"DeflateRaw")}},d_=class extends Bl{constructor(e){super(e,"InflateRaw")}},C_=class extends Bl{constructor(e){super(e,"Unzip")}},fD=class extends uD{constructor(e,t){e=e||{},e.flush=e.flush||$c.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||$c.BROTLI_OPERATION_FINISH,super(e,t),this[aD]=$c.BROTLI_OPERATION_FLUSH}},m_=class extends fD{constructor(e){super(e,"BrotliCompress")}},E_=class extends fD{constructor(e){super(e,"BrotliDecompress")}};as.Deflate=u_;as.Inflate=g_;as.Gzip=f_;as.Gunzip=h_;as.DeflateRaw=p_;as.InflateRaw=d_;as.Unzip=C_;typeof A_.BrotliCompress=="function"?(as.BrotliCompress=m_,as.BrotliDecompress=E_):as.BrotliCompress=as.BrotliDecompress=class{constructor(){throw new Error("Brotli is not supported in this version of Node.js")}}});var Zd=w(uB=>{"use strict";uB.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);uB.code=new Map(Array.from(uB.name).map(r=>[r[1],r[0]]))});var $d=w((Fot,I_)=>{"use strict";var Dot=Zd(),sRe=gf(),pD=Symbol("slurp");I_.exports=class extends sRe{constructor(e,t,i){super();switch(this.pause(),this.extended=t,this.globalExtended=i,this.header=e,this.startBlockSize=512*Math.ceil(e.size/512),this.blockRemain=this.startBlockSize,this.remain=e.size,this.type=e.type,this.meta=!1,this.ignore=!1,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}this.path=e.path,this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=e.size,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=e.linkpath,this.uname=e.uname,this.gname=e.gname,t&&this[pD](t),i&&this[pD](i,!0)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,n=this.blockRemain;return this.remain=Math.max(0,i-t),this.blockRemain=Math.max(0,n-t),this.ignore?!0:i>=t?super.write(e):super.write(e.slice(0,i))}[pD](e,t){for(let i in e)e[i]!==null&&e[i]!==void 0&&!(t&&i==="path")&&(this[i]=e[i])}}});var B_=w(dD=>{"use strict";var Not=dD.encode=(r,e)=>{if(Number.isSafeInteger(r))r<0?aRe(r,e):oRe(r,e);else throw Error("cannot encode number outside of javascript safe integer range");return e},oRe=(r,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=r&255,r=Math.floor(r/256)},aRe=(r,e)=>{e[0]=255;var t=!1;r=r*-1;for(var i=e.length;i>1;i--){var n=r&255;r=Math.floor(r/256),t?e[i-1]=y_(n):n===0?e[i-1]=0:(t=!0,e[i-1]=w_(n))}},Lot=dD.parse=r=>{var e=r[r.length-1],t=r[0],i;if(t===128)i=lRe(r.slice(1,r.length));else if(t===255)i=ARe(r);else throw Error("invalid base256 encoding");if(!Number.isSafeInteger(i))throw Error("parsed number outside of javascript safe integer range");return i},ARe=r=>{for(var e=r.length,t=0,i=!1,n=e-1;n>-1;n--){var s=r[n],o;i?o=y_(s):s===0?o=s:(i=!0,o=w_(s)),o!==0&&(t-=o*Math.pow(256,e-n-1))}return t},lRe=r=>{for(var e=r.length,t=0,i=e-1;i>-1;i--){var n=r[i];n!==0&&(t+=n*Math.pow(256,e-i-1))}return t},y_=r=>(255^r)&255,w_=r=>(255^r)+1&255});var pf=w((Oot,b_)=>{"use strict";var CD=Zd(),hf=require("path").posix,Q_=B_(),mD=Symbol("slurp"),As=Symbol("type"),S_=class{constructor(e,t,i,n){this.cksumValid=!1,this.needPax=!1,this.nullBlock=!1,this.block=null,this.path=null,this.mode=null,this.uid=null,this.gid=null,this.size=null,this.mtime=null,this.cksum=null,this[As]="0",this.linkpath=null,this.uname=null,this.gname=null,this.devmaj=0,this.devmin=0,this.atime=null,this.ctime=null,Buffer.isBuffer(e)?this.decode(e,t||0,i,n):e&&this.set(e)}decode(e,t,i,n){if(t||(t=0),!e||!(e.length>=t+512))throw new Error("need 512 bytes for header");if(this.path=tu(e,t,100),this.mode=bl(e,t+100,8),this.uid=bl(e,t+108,8),this.gid=bl(e,t+116,8),this.size=bl(e,t+124,12),this.mtime=ED(e,t+136,12),this.cksum=bl(e,t+148,12),this[mD](i),this[mD](n,!0),this[As]=tu(e,t+156,1),this[As]===""&&(this[As]="0"),this[As]==="0"&&this.path.substr(-1)==="/"&&(this[As]="5"),this[As]==="5"&&(this.size=0),this.linkpath=tu(e,t+157,100),e.slice(t+257,t+265).toString()==="ustar\x0000")if(this.uname=tu(e,t+265,32),this.gname=tu(e,t+297,32),this.devmaj=bl(e,t+329,8),this.devmin=bl(e,t+337,8),e[t+475]!==0){let o=tu(e,t+345,155);this.path=o+"/"+this.path}else{let o=tu(e,t+345,130);o&&(this.path=o+"/"+this.path),this.atime=ED(e,t+476,12),this.ctime=ED(e,t+488,12)}let s=8*32;for(let o=t;o<t+148;o++)s+=e[o];for(let o=t+156;o<t+512;o++)s+=e[o];this.cksumValid=s===this.cksum,this.cksum===null&&s===8*32&&(this.nullBlock=!0)}[mD](e,t){for(let i in e)e[i]!==null&&e[i]!==void 0&&!(t&&i==="path")&&(this[i]=e[i])}encode(e,t){if(e||(e=this.block=Buffer.alloc(512),t=0),t||(t=0),!(e.length>=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,n=cRe(this.path||"",i),s=n[0],o=n[1];this.needPax=n[2],this.needPax=ru(e,t,100,s)||this.needPax,this.needPax=Ql(e,t+100,8,this.mode)||this.needPax,this.needPax=Ql(e,t+108,8,this.uid)||this.needPax,this.needPax=Ql(e,t+116,8,this.gid)||this.needPax,this.needPax=Ql(e,t+124,12,this.size)||this.needPax,this.needPax=ID(e,t+136,12,this.mtime)||this.needPax,e[t+156]=this[As].charCodeAt(0),this.needPax=ru(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=ru(e,t+265,32,this.uname)||this.needPax,this.needPax=ru(e,t+297,32,this.gname)||this.needPax,this.needPax=Ql(e,t+329,8,this.devmaj)||this.needPax,this.needPax=Ql(e,t+337,8,this.devmin)||this.needPax,this.needPax=ru(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=ru(e,t+345,155,o)||this.needPax:(this.needPax=ru(e,t+345,130,o)||this.needPax,this.needPax=ID(e,t+476,12,this.atime)||this.needPax,this.needPax=ID(e,t+488,12,this.ctime)||this.needPax);let a=8*32;for(let l=t;l<t+148;l++)a+=e[l];for(let l=t+156;l<t+512;l++)a+=e[l];return this.cksum=a,Ql(e,t+148,8,this.cksum),this.cksumValid=!0,this.needPax}set(e){for(let t in e)e[t]!==null&&e[t]!==void 0&&(this[t]=e[t])}get type(){return CD.name.get(this[As])||this[As]}get typeKey(){return this[As]}set type(e){CD.code.has(e)?this[As]=CD.code.get(e):this[As]=e}},cRe=(r,e)=>{let t=100,i=r,n="",s,o=hf.parse(r).root||".";if(Buffer.byteLength(i)<t)s=[i,n,!1];else{n=hf.dirname(i),i=hf.basename(i);do Buffer.byteLength(i)<=t&&Buffer.byteLength(n)<=e?s=[i,n,!1]:Buffer.byteLength(i)>t&&Buffer.byteLength(n)<=e?s=[i.substr(0,t-1),n,!0]:(i=hf.join(hf.basename(n),i),n=hf.dirname(n));while(n!==o&&!s);s||(s=[r.substr(0,t-1),"",!0])}return s},tu=(r,e,t)=>r.slice(e,e+t).toString("utf8").replace(/\0.*/,""),ED=(r,e,t)=>uRe(bl(r,e,t)),uRe=r=>r===null?null:new Date(r*1e3),bl=(r,e,t)=>r[e]&128?Q_.parse(r.slice(e,e+t)):gRe(r,e,t),fRe=r=>isNaN(r)?null:r,gRe=(r,e,t)=>fRe(parseInt(r.slice(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),hRe={12:8589934591,8:2097151},Ql=(r,e,t,i)=>i===null?!1:i>hRe[t]||i<0?(Q_.encode(i,r.slice(e,e+t)),!0):(pRe(r,e,t,i),!1),pRe=(r,e,t,i)=>r.write(dRe(i,t),e,t,"ascii"),dRe=(r,e)=>CRe(Math.floor(r).toString(8),e),CRe=(r,e)=>(r.length===e-1?r:new Array(e-r.length-1).join("0")+r+" ")+"\0",ID=(r,e,t,i)=>i===null?!1:Ql(r,e,t,i.getTime()/1e3),mRe=new Array(156).join("\0"),ru=(r,e,t,i)=>i===null?!1:(r.write(i+mRe,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t);b_.exports=S_});var fB=w((Mot,v_)=>{"use strict";var ERe=pf(),IRe=require("path"),gB=class{constructor(e,t){this.atime=e.atime||null,this.charset=e.charset||null,this.comment=e.comment||null,this.ctime=e.ctime||null,this.gid=e.gid||null,this.gname=e.gname||null,this.linkpath=e.linkpath||null,this.mtime=e.mtime||null,this.path=e.path||null,this.size=e.size||null,this.uid=e.uid||null,this.uname=e.uname||null,this.dev=e.dev||null,this.ino=e.ino||null,this.nlink=e.nlink||null,this.global=t||!1}encode(){let e=this.encodeBody();if(e==="")return null;let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),n=Buffer.allocUnsafe(i);for(let s=0;s<512;s++)n[s]=0;new ERe({path:("PaxHeader/"+IRe.basename(this.path)).slice(0,99),mode:this.mode||420,uid:this.uid||null,gid:this.gid||null,size:t,mtime:this.mtime||null,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime||null,ctime:this.ctime||null}).encode(n),n.write(e,512,t,"utf8");for(let s=t+512;s<n.length;s++)n[s]=0;return n}encodeBody(){return this.encodeField("path")+this.encodeField("ctime")+this.encodeField("atime")+this.encodeField("dev")+this.encodeField("ino")+this.encodeField("nlink")+this.encodeField("charset")+this.encodeField("comment")+this.encodeField("gid")+this.encodeField("gname")+this.encodeField("linkpath")+this.encodeField("mtime")+this.encodeField("size")+this.encodeField("uid")+this.encodeField("uname")}encodeField(e){if(this[e]===null||this[e]===void 0)return"";let t=this[e]instanceof Date?this[e].getTime()/1e3:this[e],i=" "+(e==="dev"||e==="ino"||e==="nlink"?"SCHILY.":"")+e+"="+t+` -`,n=Buffer.byteLength(i),s=Math.floor(Math.log(n)/Math.log(10))+1;return n+s>=Math.pow(10,s)&&(s+=1),s+n+i}};gB.parse=(r,e,t)=>new gB(yRe(wRe(r),e),t);var yRe=(r,e)=>e?Object.keys(r).reduce((t,i)=>(t[i]=r[i],t),e):r,wRe=r=>r.replace(/\n$/,"").split(` -`).reduce(BRe,Object.create(null)),BRe=(r,e)=>{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return r;e=e.substr((t+" ").length);let i=e.split("="),n=i.shift().replace(/^SCHILY\.(dev|ino|nlink)/,"$1");if(!n)return r;let s=i.join("=");return r[n]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n)?new Date(s*1e3):/^[0-9]+$/.test(s)?+s:s,r};v_.exports=gB});var hB=w((Uot,k_)=>{"use strict";k_.exports=r=>class extends r{warn(e,t,i={}){this.file&&(i.file=this.file),this.cwd&&(i.cwd=this.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!this.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),this.emit("warn",i.tarCode,t,i)):t instanceof Error?this.emit("error",Object.assign(t,i)):this.emit("error",Object.assign(new Error(`${e}: ${t}`),i))}}});var wD=w((Kot,x_)=>{"use strict";var pB=["|","<",">","?",":"],yD=pB.map(r=>String.fromCharCode(61440+r.charCodeAt(0))),bRe=new Map(pB.map((r,e)=>[r,yD[e]])),QRe=new Map(yD.map((r,e)=>[r,pB[e]]));x_.exports={encode:r=>pB.reduce((e,t)=>e.split(t).join(bRe.get(t)),r),decode:r=>yD.reduce((e,t)=>e.split(t).join(QRe.get(t)),r)}});var D_=w((Hot,P_)=>{"use strict";P_.exports=(r,e,t)=>(r&=4095,t&&(r=(r|384)&~18),e&&(r&256&&(r|=64),r&32&&(r|=8),r&4&&(r|=1)),r)});var xD=w((Jot,R_)=>{"use strict";var F_=gf(),N_=fB(),L_=pf(),jot=$d(),oa=require("fs"),df=require("path"),Got=Zd(),SRe=16*1024*1024,T_=Symbol("process"),O_=Symbol("file"),M_=Symbol("directory"),BD=Symbol("symlink"),U_=Symbol("hardlink"),eC=Symbol("header"),dB=Symbol("read"),bD=Symbol("lstat"),CB=Symbol("onlstat"),QD=Symbol("onread"),SD=Symbol("onreadlink"),vD=Symbol("openfile"),kD=Symbol("onopenfile"),iu=Symbol("close"),mB=Symbol("mode"),K_=hB(),vRe=wD(),H_=D_(),EB=K_(class extends F_{constructor(e,t){if(t=t||{},super(t),typeof e!="string")throw new TypeError("path is required");this.path=e,this.portable=!!t.portable,this.myuid=process.getuid&&process.getuid(),this.myuser=process.env.USER||"",this.maxReadSize=t.maxReadSize||SRe,this.linkCache=t.linkCache||new Map,this.statCache=t.statCache||new Map,this.preservePaths=!!t.preservePaths,this.cwd=t.cwd||process.cwd(),this.strict=!!t.strict,this.noPax=!!t.noPax,this.noMtime=!!t.noMtime,this.mtime=t.mtime||null,typeof t.onwarn=="function"&&this.on("warn",t.onwarn);let i=!1;if(!this.preservePaths&&df.win32.isAbsolute(e)){let n=df.win32.parse(e);this.path=e.substr(n.root.length),i=n.root}this.win32=!!t.win32||process.platform==="win32",this.win32&&(this.path=vRe.decode(this.path.replace(/\\/g,"/")),e=e.replace(/\\/g,"/")),this.absolute=t.absolute||df.resolve(this.cwd,e),this.path===""&&(this.path="./"),i&&this.warn("TAR_ENTRY_INFO",`stripping ${i} from absolute path`,{entry:this,path:i+this.path}),this.statCache.has(this.absolute)?this[CB](this.statCache.get(this.absolute)):this[bD]()}[bD](){oa.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[CB](t)})}[CB](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=kRe(e),this.emit("stat",e),this[T_]()}[T_](){switch(this.type){case"File":return this[O_]();case"Directory":return this[M_]();case"SymbolicLink":return this[BD]();default:return this.end()}}[mB](e){return H_(e,this.type==="Directory",this.portable)}[eC](){this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.header=new L_({path:this.path,linkpath:this.linkpath,mode:this[mB](this.stat.mode),uid:this.portable?null:this.stat.uid,gid:this.portable?null:this.stat.gid,size:this.stat.size,mtime:this.noMtime?null:this.mtime||this.stat.mtime,type:this.type,uname:this.portable?null:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?null:this.stat.atime,ctime:this.portable?null:this.stat.ctime}),this.header.encode()&&!this.noPax&&this.write(new N_({atime:this.portable?null:this.header.atime,ctime:this.portable?null:this.header.ctime,gid:this.portable?null:this.header.gid,mtime:this.noMtime?null:this.mtime||this.header.mtime,path:this.path,linkpath:this.linkpath,size:this.header.size,uid:this.portable?null:this.header.uid,uname:this.portable?null:this.header.uname,dev:this.portable?null:this.stat.dev,ino:this.portable?null:this.stat.ino,nlink:this.portable?null:this.stat.nlink}).encode()),this.write(this.header.block)}[M_](){this.path.substr(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[eC](),this.end()}[BD](){oa.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[SD](t)})}[SD](e){this.linkpath=e.replace(/\\/g,"/"),this[eC](),this.end()}[U_](e){this.type="Link",this.linkpath=df.relative(this.cwd,e).replace(/\\/g,"/"),this.stat.size=0,this[eC](),this.end()}[O_](){if(this.stat.nlink>1){let e=this.stat.dev+":"+this.stat.ino;if(this.linkCache.has(e)){let t=this.linkCache.get(e);if(t.indexOf(this.cwd)===0)return this[U_](t)}this.linkCache.set(e,this.absolute)}if(this[eC](),this.stat.size===0)return this.end();this[vD]()}[vD](){oa.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[kD](t)})}[kD](e){let t=512*Math.ceil(this.stat.size/512),i=Math.min(t,this.maxReadSize),n=Buffer.allocUnsafe(i);this[dB](e,n,0,n.length,0,this.stat.size,t)}[dB](e,t,i,n,s,o,a){oa.read(e,t,i,n,s,(l,c)=>{if(l)return this[iu](e,()=>this.emit("error",l));this[QD](e,t,i,n,s,o,a,c)})}[iu](e,t){oa.close(e,t)}[QD](e,t,i,n,s,o,a,l){if(l<=0&&o>0){let u=new Error("encountered unexpected EOF");return u.path=this.absolute,u.syscall="read",u.code="EOF",this[iu](e,()=>this.emit("error",u))}if(l>o){let u=new Error("did not encounter expected EOF");return u.path=this.absolute,u.syscall="read",u.code="EOF",this[iu](e,()=>this.emit("error",u))}if(l===o)for(let u=l;u<n&&l<a;u++)t[u+i]=0,l++,o++;let c=i===0&&l===t.length?t:t.slice(i,i+l);if(o-=l,a-=l,s+=l,i+=l,this.write(c),!o)return a&&this.write(Buffer.alloc(a)),this[iu](e,u=>u?this.emit("error",u):this.end());i>=n&&(t=Buffer.allocUnsafe(n),i=0),n=t.length-i,this[dB](e,t,i,n,s,o,a)}}),j_=class extends EB{constructor(e,t){super(e,t)}[bD](){this[CB](oa.lstatSync(this.absolute))}[BD](){this[SD](oa.readlinkSync(this.absolute))}[vD](){this[kD](oa.openSync(this.absolute,"r"))}[dB](e,t,i,n,s,o,a){let l=!0;try{let c=oa.readSync(e,t,i,n,s);this[QD](e,t,i,n,s,o,a,c),l=!1}finally{if(l)try{this[iu](e,()=>{})}catch(c){}}}[iu](e,t){oa.closeSync(e),t()}},xRe=K_(class extends F_{constructor(e,t){t=t||{},super(t),this.preservePaths=!!t.preservePaths,this.portable=!!t.portable,this.strict=!!t.strict,this.noPax=!!t.noPax,this.noMtime=!!t.noMtime,this.readEntry=e,this.type=e.type,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.path=e.path,this.mode=this[mB](e.mode),this.uid=this.portable?null:e.uid,this.gid=this.portable?null:e.gid,this.uname=this.portable?null:e.uname,this.gname=this.portable?null:e.gname,this.size=e.size,this.mtime=this.noMtime?null:t.mtime||e.mtime,this.atime=this.portable?null:e.atime,this.ctime=this.portable?null:e.ctime,this.linkpath=e.linkpath,typeof t.onwarn=="function"&&this.on("warn",t.onwarn);let i=!1;if(df.isAbsolute(this.path)&&!this.preservePaths){let n=df.parse(this.path);i=n.root,this.path=this.path.substr(n.root.length)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.header=new L_({path:this.path,linkpath:this.linkpath,mode:this.mode,uid:this.portable?null:this.uid,gid:this.portable?null:this.gid,size:this.size,mtime:this.noMtime?null:this.mtime,type:this.type,uname:this.portable?null:this.uname,atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime}),i&&this.warn("TAR_ENTRY_INFO",`stripping ${i} from absolute path`,{entry:this,path:i+this.path}),this.header.encode()&&!this.noPax&&super.write(new N_({atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime,gid:this.portable?null:this.gid,mtime:this.noMtime?null:this.mtime,path:this.path,linkpath:this.linkpath,size:this.size,uid:this.portable?null:this.uid,uname:this.portable?null:this.uname,dev:this.portable?null:this.readEntry.dev,ino:this.portable?null:this.readEntry.ino,nlink:this.portable?null:this.readEntry.nlink}).encode()),super.write(this.header.block),e.pipe(this)}[mB](e){return H_(e,this.type==="Directory",this.portable)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=t,super.write(e)}end(){return this.blockRemain&&this.write(Buffer.alloc(this.blockRemain)),super.end()}});EB.Sync=j_;EB.Tar=xRe;var kRe=r=>r.isFile()?"File":r.isDirectory()?"Directory":r.isSymbolicLink()?"SymbolicLink":"Unsupported";R_.exports=EB});var vB=w((zot,G_)=>{"use strict";var PD=class{constructor(e,t){this.path=e||"./",this.absolute=t,this.entry=null,this.stat=null,this.readdir=null,this.pending=!1,this.ignore=!1,this.piped=!1}},PRe=gf(),DRe=hD(),RRe=$d(),DD=xD(),FRe=DD.Sync,NRe=DD.Tar,LRe=bp(),Y_=Buffer.alloc(1024),IB=Symbol("onStat"),yB=Symbol("ended"),aa=Symbol("queue"),Cf=Symbol("current"),nu=Symbol("process"),wB=Symbol("processing"),q_=Symbol("processJob"),Aa=Symbol("jobs"),RD=Symbol("jobDone"),BB=Symbol("addFSEntry"),J_=Symbol("addTarEntry"),FD=Symbol("stat"),ND=Symbol("readdir"),bB=Symbol("onreaddir"),QB=Symbol("pipe"),W_=Symbol("entry"),LD=Symbol("entryOpt"),TD=Symbol("writeEntryClass"),z_=Symbol("write"),OD=Symbol("ondrain"),SB=require("fs"),__=require("path"),TRe=hB(),MD=TRe(class extends PRe{constructor(e){super(e);e=e||Object.create(null),this.opt=e,this.file=e.file||"",this.cwd=e.cwd||process.cwd(),this.maxReadSize=e.maxReadSize,this.preservePaths=!!e.preservePaths,this.strict=!!e.strict,this.noPax=!!e.noPax,this.prefix=(e.prefix||"").replace(/(\\|\/)+$/,""),this.linkCache=e.linkCache||new Map,this.statCache=e.statCache||new Map,this.readdirCache=e.readdirCache||new Map,this[TD]=DD,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),this.portable=!!e.portable,this.zip=null,e.gzip?(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new DRe.Gzip(e.gzip),this.zip.on("data",t=>super.write(t)),this.zip.on("end",t=>super.end()),this.zip.on("drain",t=>this[OD]()),this.on("resume",t=>this.zip.resume())):this.on("drain",this[OD]),this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,this.mtime=e.mtime||null,this.filter=typeof e.filter=="function"?e.filter:t=>!0,this[aa]=new LRe,this[Aa]=0,this.jobs=+e.jobs||4,this[wB]=!1,this[yB]=!1}[z_](e){return super.write(e)}add(e){return this.write(e),this}end(e){return e&&this.write(e),this[yB]=!0,this[nu](),this}write(e){if(this[yB])throw new Error("write after end");return e instanceof RRe?this[J_](e):this[BB](e),this.flowing}[J_](e){let t=__.resolve(this.cwd,e.path);if(this.prefix&&(e.path=this.prefix+"/"+e.path.replace(/^\.(\/+|$)/,"")),!this.filter(e.path,e))e.resume();else{let i=new PD(e.path,t,!1);i.entry=new NRe(e,this[LD](i)),i.entry.on("end",n=>this[RD](i)),this[Aa]+=1,this[aa].push(i)}this[nu]()}[BB](e){let t=__.resolve(this.cwd,e);this.prefix&&(e=this.prefix+"/"+e.replace(/^\.(\/+|$)/,"")),this[aa].push(new PD(e,t)),this[nu]()}[FD](e){e.pending=!0,this[Aa]+=1;let t=this.follow?"stat":"lstat";SB[t](e.absolute,(i,n)=>{e.pending=!1,this[Aa]-=1,i?this.emit("error",i):this[IB](e,n)})}[IB](e,t){this.statCache.set(e.absolute,t),e.stat=t,this.filter(e.path,t)||(e.ignore=!0),this[nu]()}[ND](e){e.pending=!0,this[Aa]+=1,SB.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[Aa]-=1,t)return this.emit("error",t);this[bB](e,i)})}[bB](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[nu]()}[nu](){if(!this[wB]){this[wB]=!0;for(let e=this[aa].head;e!==null&&this[Aa]<this.jobs;e=e.next)if(this[q_](e.value),e.value.ignore){let t=e.next;this[aa].removeNode(e),e.next=t}this[wB]=!1,this[yB]&&!this[aa].length&&this[Aa]===0&&(this.zip?this.zip.end(Y_):(super.write(Y_),super.end()))}}get[Cf](){return this[aa]&&this[aa].head&&this[aa].head.value}[RD](e){this[aa].shift(),this[Aa]-=1,this[nu]()}[q_](e){if(!e.pending){if(e.entry){e===this[Cf]&&!e.piped&&this[QB](e);return}if(e.stat||(this.statCache.has(e.absolute)?this[IB](e,this.statCache.get(e.absolute)):this[FD](e)),!!e.stat&&!e.ignore&&!(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir&&(this.readdirCache.has(e.absolute)?this[bB](e,this.readdirCache.get(e.absolute)):this[ND](e),!e.readdir))){if(e.entry=this[W_](e),!e.entry){e.ignore=!0;return}e===this[Cf]&&!e.piped&&this[QB](e)}}}[LD](e){return{onwarn:(t,i,n)=>this.warn(t,i,n),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime}}[W_](e){this[Aa]+=1;try{return new this[TD](e.path,this[LD](e)).on("end",()=>this[RD](e)).on("error",t=>this.emit("error",t))}catch(t){this.emit("error",t)}}[OD](){this[Cf]&&this[Cf].entry&&this[Cf].entry.resume()}[QB](e){e.piped=!0,e.readdir&&e.readdir.forEach(n=>{let s=this.prefix?e.path.slice(this.prefix.length+1)||"./":e.path,o=s==="./"?"":s.replace(/\/*$/,"/");this[BB](o+n)});let t=e.entry,i=this.zip;i?t.on("data",n=>{i.write(n)||t.pause()}):t.on("data",n=>{super.write(n)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}}),V_=class extends MD{constructor(e){super(e);this[TD]=FRe}pause(){}resume(){}[FD](e){let t=this.follow?"statSync":"lstatSync";this[IB](e,SB[t](e.absolute))}[ND](e,t){this[bB](e,SB.readdirSync(e.absolute))}[QB](e){let t=e.entry,i=this.zip;e.readdir&&e.readdir.forEach(n=>{let s=this.prefix?e.path.slice(this.prefix.length+1)||"./":e.path,o=s==="./"?"":s.replace(/\/*$/,"/");this[BB](o+n)}),i?t.on("data",n=>{i.write(n)}):t.on("data",n=>{super[z_](n)})}};MD.Sync=V_;G_.exports=MD});var Bf=w(tC=>{"use strict";var ORe=gf(),MRe=require("events").EventEmitter,js=require("fs"),kB=process.binding("fs"),_ot=kB.writeBuffers,URe=kB.FSReqWrap||kB.FSReqCallback,mf=Symbol("_autoClose"),la=Symbol("_close"),rC=Symbol("_ended"),or=Symbol("_fd"),X_=Symbol("_finished"),su=Symbol("_flags"),UD=Symbol("_flush"),KD=Symbol("_handleChunk"),HD=Symbol("_makeBuf"),jD=Symbol("_mode"),xB=Symbol("_needDrain"),Ef=Symbol("_onerror"),If=Symbol("_onopen"),GD=Symbol("_onread"),ou=Symbol("_onwrite"),Sl=Symbol("_open"),vl=Symbol("_path"),au=Symbol("_pos"),ca=Symbol("_queue"),yf=Symbol("_read"),Z_=Symbol("_readSize"),kl=Symbol("_reading"),PB=Symbol("_remain"),$_=Symbol("_size"),DB=Symbol("_write"),wf=Symbol("_writing"),RB=Symbol("_defaultFlag"),YD=class extends ORe{constructor(e,t){if(t=t||{},super(t),this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[or]=typeof t.fd=="number"?t.fd:null,this[vl]=e,this[Z_]=t.readSize||16*1024*1024,this[kl]=!1,this[$_]=typeof t.size=="number"?t.size:Infinity,this[PB]=this[$_],this[mf]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[or]=="number"?this[yf]():this[Sl]()}get fd(){return this[or]}get path(){return this[vl]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[Sl](){js.open(this[vl],"r",(e,t)=>this[If](e,t))}[If](e,t){e?this[Ef](e):(this[or]=t,this.emit("open",t),this[yf]())}[HD](){return Buffer.allocUnsafe(Math.min(this[Z_],this[PB]))}[yf](){if(!this[kl]){this[kl]=!0;let e=this[HD]();if(e.length===0)return process.nextTick(()=>this[GD](null,0,e));js.read(this[or],e,0,e.length,null,(t,i,n)=>this[GD](t,i,n))}}[GD](e,t,i){this[kl]=!1,e?this[Ef](e):this[KD](t,i)&&this[yf]()}[la](){this[mf]&&typeof this[or]=="number"&&(js.close(this[or],e=>this.emit("close")),this[or]=null)}[Ef](e){this[kl]=!0,this[la](),this.emit("error",e)}[KD](e,t){let i=!1;return this[PB]-=e,e>0&&(i=super.write(e<t.length?t.slice(0,e):t)),(e===0||this[PB]<=0)&&(i=!1,this[la](),super.end()),i}emit(e,t){switch(e){case"prefinish":case"finish":break;case"drain":typeof this[or]=="number"&&this[yf]();break;default:return super.emit(e,t)}}},eV=class extends YD{[Sl](){let e=!0;try{this[If](null,js.openSync(this[vl],"r")),e=!1}finally{e&&this[la]()}}[yf](){let e=!0;try{if(!this[kl]){this[kl]=!0;do{let t=this[HD](),i=t.length===0?0:js.readSync(this[or],t,0,t.length,null);if(!this[KD](i,t))break}while(!0);this[kl]=!1}e=!1}finally{e&&this[la]()}}[la](){if(this[mf]&&typeof this[or]=="number"){try{js.closeSync(this[or])}catch(e){}this[or]=null,this.emit("close")}}},qD=class extends MRe{constructor(e,t){t=t||{},super(t),this.readable=!1,this[wf]=!1,this[rC]=!1,this[xB]=!1,this[ca]=[],this[vl]=e,this[or]=typeof t.fd=="number"?t.fd:null,this[jD]=t.mode===void 0?438:t.mode,this[au]=typeof t.start=="number"?t.start:null,this[mf]=typeof t.autoClose=="boolean"?t.autoClose:!0;let i=this[au]!==null?"r+":"w";this[RB]=t.flags===void 0,this[su]=this[RB]?i:t.flags,this[or]===null&&this[Sl]()}get fd(){return this[or]}get path(){return this[vl]}[Ef](e){this[la](),this[wf]=!0,this.emit("error",e)}[Sl](){js.open(this[vl],this[su],this[jD],(e,t)=>this[If](e,t))}[If](e,t){this[RB]&&this[su]==="r+"&&e&&e.code==="ENOENT"?(this[su]="w",this[Sl]()):e?this[Ef](e):(this[or]=t,this.emit("open",t),this[UD]())}end(e,t){e&&this.write(e,t),this[rC]=!0,!this[wf]&&!this[ca].length&&typeof this[or]=="number"&&this[ou](null,0)}write(e,t){return typeof e=="string"&&(e=new Buffer(e,t)),this[rC]?(this.emit("error",new Error("write() after end()")),!1):this[or]===null||this[wf]||this[ca].length?(this[ca].push(e),this[xB]=!0,!1):(this[wf]=!0,this[DB](e),!0)}[DB](e){js.write(this[or],e,0,e.length,this[au],(t,i)=>this[ou](t,i))}[ou](e,t){e?this[Ef](e):(this[au]!==null&&(this[au]+=t),this[ca].length?this[UD]():(this[wf]=!1,this[rC]&&!this[X_]?(this[X_]=!0,this[la](),this.emit("finish")):this[xB]&&(this[xB]=!1,this.emit("drain"))))}[UD](){if(this[ca].length===0)this[rC]&&this[ou](null,0);else if(this[ca].length===1)this[DB](this[ca].pop());else{let e=this[ca];this[ca]=[],KRe(this[or],e,this[au],(t,i)=>this[ou](t,i))}}[la](){this[mf]&&typeof this[or]=="number"&&(js.close(this[or],e=>this.emit("close")),this[or]=null)}},tV=class extends qD{[Sl](){let e;try{e=js.openSync(this[vl],this[su],this[jD])}catch(t){if(this[RB]&&this[su]==="r+"&&t&&t.code==="ENOENT")return this[su]="w",this[Sl]();throw t}this[If](null,e)}[la](){if(this[mf]&&typeof this[or]=="number"){try{js.closeSync(this[or])}catch(e){}this[or]=null,this.emit("close")}}[DB](e){try{this[ou](null,js.writeSync(this[or],e,0,e.length,this[au]))}catch(t){this[ou](t,0)}}},KRe=(r,e,t,i)=>{let n=(o,a)=>i(o,a,e),s=new URe;s.oncomplete=n,kB.writeBuffers(r,e,t,s)};tC.ReadStream=YD;tC.ReadStreamSync=eV;tC.WriteStream=qD;tC.WriteStreamSync=tV});var sC=w(($ot,rV)=>{"use strict";var HRe=hB(),Xot=require("path"),jRe=pf(),GRe=require("events"),YRe=bp(),qRe=1024*1024,JRe=$d(),iV=fB(),WRe=hD(),JD=Buffer.from([31,139]),Gs=Symbol("state"),Au=Symbol("writeEntry"),gA=Symbol("readEntry"),WD=Symbol("nextEntry"),nV=Symbol("processEntry"),Ys=Symbol("extendedHeader"),iC=Symbol("globalExtendedHeader"),xl=Symbol("meta"),sV=Symbol("emitMeta"),yr=Symbol("buffer"),fA=Symbol("queue"),lu=Symbol("ended"),oV=Symbol("emittedEnd"),cu=Symbol("emit"),Tn=Symbol("unzip"),FB=Symbol("consumeChunk"),NB=Symbol("consumeChunkSub"),zD=Symbol("consumeBody"),aV=Symbol("consumeMeta"),AV=Symbol("consumeHeader"),LB=Symbol("consuming"),_D=Symbol("bufferConcat"),VD=Symbol("maybeEnd"),nC=Symbol("writing"),Pl=Symbol("aborted"),TB=Symbol("onDone"),uu=Symbol("sawValidEntry"),OB=Symbol("sawNullBlock"),MB=Symbol("sawEOF"),zRe=r=>!0;rV.exports=HRe(class extends GRe{constructor(e){e=e||{},super(e),this.file=e.file||"",this[uu]=null,this.on(TB,t=>{(this[Gs]==="begin"||this[uu]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(TB,e.ondone):this.on(TB,t=>{this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||qRe,this.filter=typeof e.filter=="function"?e.filter:zRe,this.writable=!0,this.readable=!1,this[fA]=new YRe,this[yr]=null,this[gA]=null,this[Au]=null,this[Gs]="begin",this[xl]="",this[Ys]=null,this[iC]=null,this[lu]=!1,this[Tn]=null,this[Pl]=!1,this[OB]=!1,this[MB]=!1,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onentry=="function"&&this.on("entry",e.onentry)}[AV](e,t){this[uu]===null&&(this[uu]=!1);let i;try{i=new jRe(e,t,this[Ys],this[iC])}catch(n){return this.warn("TAR_ENTRY_INVALID",n)}if(i.nullBlock)this[OB]?(this[MB]=!0,this[Gs]==="begin"&&(this[Gs]="header"),this[cu]("eof")):(this[OB]=!0,this[cu]("nullBlock"));else if(this[OB]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let n=i.type;if(/^(Symbolic)?Link$/.test(n)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(n)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let s=this[Au]=new JRe(i,this[Ys],this[iC]);if(!this[uu])if(s.remain){let o=()=>{s.invalid||(this[uu]=!0)};s.on("end",o)}else this[uu]=!0;s.meta?s.size>this.maxMetaEntrySize?(s.ignore=!0,this[cu]("ignoredEntry",s),this[Gs]="ignore",s.resume()):s.size>0&&(this[xl]="",s.on("data",o=>this[xl]+=o),this[Gs]="meta"):(this[Ys]=null,s.ignore=s.ignore||!this.filter(s.path,s),s.ignore?(this[cu]("ignoredEntry",s),this[Gs]=s.remain?"ignore":"header",s.resume()):(s.remain?this[Gs]="body":(this[Gs]="header",s.end()),this[gA]?this[fA].push(s):(this[fA].push(s),this[WD]())))}}}[nV](e){let t=!0;return e?Array.isArray(e)?this.emit.apply(this,e):(this[gA]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",i=>this[WD]()),t=!1)):(this[gA]=null,t=!1),t}[WD](){do;while(this[nV](this[fA].shift()));if(!this[fA].length){let e=this[gA];!e||e.flowing||e.size===e.remain?this[nC]||this.emit("drain"):e.once("drain",i=>this.emit("drain"))}}[zD](e,t){let i=this[Au],n=i.blockRemain,s=n>=e.length&&t===0?e:e.slice(t,t+n);return i.write(s),i.blockRemain||(this[Gs]="header",this[Au]=null,i.end()),s.length}[aV](e,t){let i=this[Au],n=this[zD](e,t);return this[Au]||this[sV](i),n}[cu](e,t,i){!this[fA].length&&!this[gA]?this.emit(e,t,i):this[fA].push([e,t,i])}[sV](e){switch(this[cu]("meta",this[xl]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[Ys]=iV.parse(this[xl],this[Ys],!1);break;case"GlobalExtendedHeader":this[iC]=iV.parse(this[xl],this[iC],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":this[Ys]=this[Ys]||Object.create(null),this[Ys].path=this[xl].replace(/\0.*/,"");break;case"NextFileHasLongLinkpath":this[Ys]=this[Ys]||Object.create(null),this[Ys].linkpath=this[xl].replace(/\0.*/,"");break;default:throw new Error("unknown meta: "+e.type)}}abort(e){this[Pl]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e){if(this[Pl])return;if(this[Tn]===null&&e){if(this[yr]&&(e=Buffer.concat([this[yr],e]),this[yr]=null),e.length<JD.length)return this[yr]=e,!0;for(let i=0;this[Tn]===null&&i<JD.length;i++)e[i]!==JD[i]&&(this[Tn]=!1);if(this[Tn]===null){let i=this[lu];this[lu]=!1,this[Tn]=new WRe.Unzip,this[Tn].on("data",s=>this[FB](s)),this[Tn].on("error",s=>this.abort(s)),this[Tn].on("end",s=>{this[lu]=!0,this[FB]()}),this[nC]=!0;let n=this[Tn][i?"end":"write"](e);return this[nC]=!1,n}}this[nC]=!0,this[Tn]?this[Tn].write(e):this[FB](e),this[nC]=!1;let t=this[fA].length?!1:this[gA]?this[gA].flowing:!0;return!t&&!this[fA].length&&this[gA].once("drain",i=>this.emit("drain")),t}[_D](e){e&&!this[Pl]&&(this[yr]=this[yr]?Buffer.concat([this[yr],e]):e)}[VD](){if(this[lu]&&!this[oV]&&!this[Pl]&&!this[LB]){this[oV]=!0;let e=this[Au];if(e&&e.blockRemain){let t=this[yr]?this[yr].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[yr]&&e.write(this[yr]),e.end()}this[cu](TB)}}[FB](e){if(this[LB])this[_D](e);else if(!e&&!this[yr])this[VD]();else{if(this[LB]=!0,this[yr]){this[_D](e);let t=this[yr];this[yr]=null,this[NB](t)}else this[NB](e);for(;this[yr]&&this[yr].length>=512&&!this[Pl]&&!this[MB];){let t=this[yr];this[yr]=null,this[NB](t)}this[LB]=!1}(!this[yr]||this[lu])&&this[VD]()}[NB](e){let t=0,i=e.length;for(;t+512<=i&&!this[Pl]&&!this[MB];)switch(this[Gs]){case"begin":case"header":this[AV](e,t),t+=512;break;case"ignore":case"body":t+=this[zD](e,t);break;case"meta":t+=this[aV](e,t);break;default:throw new Error("invalid state: "+this[Gs])}t<i&&(this[yr]?this[yr]=Buffer.concat([e.slice(t),this[yr]]):this[yr]=e.slice(t))}end(e){this[Pl]||(this[Tn]?this[Tn].end(e):(this[lu]=!0,this.write(e)))}})});var UB=w((tat,lV)=>{"use strict";var _Re=uf(),cV=sC(),bf=require("fs"),VRe=Bf(),uV=require("path"),eat=lV.exports=(r,e,t)=>{typeof r=="function"?(t=r,e=null,r={}):Array.isArray(r)&&(e=r,r={}),typeof e=="function"&&(t=e,e=null),e?e=Array.from(e):e=[];let i=_Re(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return e.length&&ZRe(i,e),i.noResume||XRe(i),i.file&&i.sync?$Re(i):i.file?eFe(i,t):gV(i)},XRe=r=>{let e=r.onentry;r.onentry=e?t=>{e(t),t.resume()}:t=>t.resume()},ZRe=(r,e)=>{let t=new Map(e.map(s=>[s.replace(/\/+$/,""),!0])),i=r.filter,n=(s,o)=>{let a=o||uV.parse(s).root||".",l=s===a?!1:t.has(s)?t.get(s):n(uV.dirname(s),a);return t.set(s,l),l};r.filter=i?(s,o)=>i(s,o)&&n(s.replace(/\/+$/,"")):s=>n(s.replace(/\/+$/,""))},$Re=r=>{let e=gV(r),t=r.file,i=!0,n;try{let s=bf.statSync(t),o=r.maxReadSize||16*1024*1024;if(s.size<o)e.end(bf.readFileSync(t));else{let a=0,l=Buffer.allocUnsafe(o);for(n=bf.openSync(t,"r");a<s.size;){let c=bf.readSync(n,l,0,o,a);a+=c,e.write(l.slice(0,c))}e.end()}i=!1}finally{if(i&&n)try{bf.closeSync(n)}catch(s){}}},eFe=(r,e)=>{let t=new cV(r),i=r.maxReadSize||16*1024*1024,n=r.file,s=new Promise((o,a)=>{t.on("error",a),t.on("end",o),bf.stat(n,(l,c)=>{if(l)a(l);else{let u=new VRe.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(t)}})});return e?s.then(e,e):s},gV=r=>new cV(r)});var mV=w((nat,fV)=>{"use strict";var tFe=uf(),KB=vB(),rat=require("fs"),hV=Bf(),pV=UB(),dV=require("path"),iat=fV.exports=(r,e,t)=>{if(typeof e=="function"&&(t=e),Array.isArray(r)&&(e=r,r={}),!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");e=Array.from(e);let i=tFe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return i.file&&i.sync?rFe(i,e):i.file?iFe(i,e,t):i.sync?nFe(i,e):sFe(i,e)},rFe=(r,e)=>{let t=new KB.Sync(r),i=new hV.WriteStreamSync(r.file,{mode:r.mode||438});t.pipe(i),CV(t,e)},iFe=(r,e,t)=>{let i=new KB(r),n=new hV.WriteStream(r.file,{mode:r.mode||438});i.pipe(n);let s=new Promise((o,a)=>{n.on("error",a),n.on("close",o),i.on("error",a)});return XD(i,e),t?s.then(t,t):s},CV=(r,e)=>{e.forEach(t=>{t.charAt(0)==="@"?pV({file:dV.resolve(r.cwd,t.substr(1)),sync:!0,noResume:!0,onentry:i=>r.add(i)}):r.add(t)}),r.end()},XD=(r,e)=>{for(;e.length;){let t=e.shift();if(t.charAt(0)==="@")return pV({file:dV.resolve(r.cwd,t.substr(1)),noResume:!0,onentry:i=>r.add(i)}).then(i=>XD(r,e));r.add(t)}r.end()},nFe=(r,e)=>{let t=new KB.Sync(r);return CV(t,e),t},sFe=(r,e)=>{let t=new KB(r);return XD(t,e),t}});var ZD=w((aat,EV)=>{"use strict";var oFe=uf(),IV=vB(),sat=sC(),qs=require("fs"),yV=Bf(),wV=UB(),BV=require("path"),bV=pf(),oat=EV.exports=(r,e,t)=>{let i=oFe(r);if(!i.file)throw new TypeError("file is required");if(i.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),i.sync?aFe(i,e):AFe(i,e,t)},aFe=(r,e)=>{let t=new IV.Sync(r),i=!0,n,s;try{try{n=qs.openSync(r.file,"r+")}catch(l){if(l.code==="ENOENT")n=qs.openSync(r.file,"w+");else throw l}let o=qs.fstatSync(n),a=Buffer.alloc(512);e:for(s=0;s<o.size;s+=512){for(let u=0,g=0;u<512;u+=g){if(g=qs.readSync(n,a,u,a.length-u,s+u),s===0&&a[0]===31&&a[1]===139)throw new Error("cannot append to compressed archives");if(!g)break e}let l=new bV(a);if(!l.cksumValid)break;let c=512*Math.ceil(l.size/512);if(s+c+512>o.size)break;s+=c,r.mtimeCache&&r.mtimeCache.set(l.path,l.mtime)}i=!1,lFe(r,t,s,n,e)}finally{if(i)try{qs.closeSync(n)}catch(o){}}},lFe=(r,e,t,i,n)=>{let s=new yV.WriteStreamSync(r.file,{fd:i,start:t});e.pipe(s),cFe(e,n)},AFe=(r,e,t)=>{e=Array.from(e);let i=new IV(r),n=(o,a,l)=>{let c=(p,m)=>{p?qs.close(o,y=>l(p)):l(null,m)},u=0;if(a===0)return c(null,0);let g=0,f=Buffer.alloc(512),h=(p,m)=>{if(p)return c(p);if(g+=m,g<512&&m)return qs.read(o,f,g,f.length-g,u+g,h);if(u===0&&f[0]===31&&f[1]===139)return c(new Error("cannot append to compressed archives"));if(g<512)return c(null,u);let y=new bV(f);if(!y.cksumValid)return c(null,u);let b=512*Math.ceil(y.size/512);if(u+b+512>a||(u+=b+512,u>=a))return c(null,u);r.mtimeCache&&r.mtimeCache.set(y.path,y.mtime),g=0,qs.read(o,f,0,512,u,h)};qs.read(o,f,0,512,u,h)},s=new Promise((o,a)=>{i.on("error",a);let l="r+",c=(u,g)=>{if(u&&u.code==="ENOENT"&&l==="r+")return l="w+",qs.open(r.file,l,c);if(u)return a(u);qs.fstat(g,(f,h)=>{if(f)return a(f);n(g,h.size,(p,m)=>{if(p)return a(p);let y=new yV.WriteStream(r.file,{fd:g,start:m});i.pipe(y),y.on("error",a),y.on("close",o),QV(i,e)})})};qs.open(r.file,l,c)});return t?s.then(t,t):s},cFe=(r,e)=>{e.forEach(t=>{t.charAt(0)==="@"?wV({file:BV.resolve(r.cwd,t.substr(1)),sync:!0,noResume:!0,onentry:i=>r.add(i)}):r.add(t)}),r.end()},QV=(r,e)=>{for(;e.length;){let t=e.shift();if(t.charAt(0)==="@")return wV({file:BV.resolve(r.cwd,t.substr(1)),noResume:!0,onentry:i=>r.add(i)}).then(i=>QV(r,e));r.add(t)}r.end()}});var vV=w((lat,SV)=>{"use strict";var uFe=uf(),gFe=ZD(),Aat=SV.exports=(r,e,t)=>{let i=uFe(r);if(!i.file)throw new TypeError("file is required");if(i.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),fFe(i),gFe(i,e,t)},fFe=r=>{let e=r.filter;r.mtimeCache||(r.mtimeCache=new Map),r.filter=e?(t,i)=>e(t,i)&&!(r.mtimeCache.get(t)>i.mtime):(t,i)=>!(r.mtimeCache.get(t)>i.mtime)}});var PV=w((cat,kV)=>{var{promisify:xV}=require("util"),Dl=require("fs"),hFe=r=>{if(!r)r={mode:511,fs:Dl};else if(typeof r=="object")r=N({mode:511,fs:Dl},r);else if(typeof r=="number")r={mode:r,fs:Dl};else if(typeof r=="string")r={mode:parseInt(r,8),fs:Dl};else throw new TypeError("invalid options argument");return r.mkdir=r.mkdir||r.fs.mkdir||Dl.mkdir,r.mkdirAsync=xV(r.mkdir),r.stat=r.stat||r.fs.stat||Dl.stat,r.statAsync=xV(r.stat),r.statSync=r.statSync||r.fs.statSync||Dl.statSync,r.mkdirSync=r.mkdirSync||r.fs.mkdirSync||Dl.mkdirSync,r};kV.exports=hFe});var RV=w((uat,DV)=>{var pFe=process.env.__TESTING_MKDIRP_PLATFORM__||process.platform,{resolve:dFe,parse:CFe}=require("path"),mFe=r=>{if(/\0/.test(r))throw Object.assign(new TypeError("path must be a string without null bytes"),{path:r,code:"ERR_INVALID_ARG_VALUE"});if(r=dFe(r),pFe==="win32"){let e=/[*|"<>?:]/,{root:t}=CFe(r);if(e.test(r.substr(t.length)))throw Object.assign(new Error("Illegal characters in path."),{path:r,code:"EINVAL"})}return r};DV.exports=mFe});var OV=w((gat,FV)=>{var{dirname:NV}=require("path"),LV=(r,e,t=void 0)=>t===e?Promise.resolve():r.statAsync(e).then(i=>i.isDirectory()?t:void 0,i=>i.code==="ENOENT"?LV(r,NV(e),e):void 0),TV=(r,e,t=void 0)=>{if(t!==e)try{return r.statSync(e).isDirectory()?t:void 0}catch(i){return i.code==="ENOENT"?TV(r,NV(e),e):void 0}};FV.exports={findMade:LV,findMadeSync:TV}});var tR=w((fat,MV)=>{var{dirname:UV}=require("path"),$D=(r,e,t)=>{e.recursive=!1;let i=UV(r);return i===r?e.mkdirAsync(r,e).catch(n=>{if(n.code!=="EISDIR")throw n}):e.mkdirAsync(r,e).then(()=>t||r,n=>{if(n.code==="ENOENT")return $D(i,e).then(s=>$D(r,e,s));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;return e.statAsync(r).then(s=>{if(s.isDirectory())return t;throw n},()=>{throw n})})},eR=(r,e,t)=>{let i=UV(r);if(e.recursive=!1,i===r)try{return e.mkdirSync(r,e)}catch(n){if(n.code!=="EISDIR")throw n;return}try{return e.mkdirSync(r,e),t||r}catch(n){if(n.code==="ENOENT")return eR(r,e,eR(i,e,t));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;try{if(!e.statSync(r).isDirectory())throw n}catch(s){throw n}}};MV.exports={mkdirpManual:$D,mkdirpManualSync:eR}});var jV=w((hat,KV)=>{var{dirname:HV}=require("path"),{findMade:EFe,findMadeSync:IFe}=OV(),{mkdirpManual:yFe,mkdirpManualSync:wFe}=tR(),BFe=(r,e)=>(e.recursive=!0,HV(r)===r?e.mkdirAsync(r,e):EFe(e,r).then(i=>e.mkdirAsync(r,e).then(()=>i).catch(n=>{if(n.code==="ENOENT")return yFe(r,e);throw n}))),bFe=(r,e)=>{if(e.recursive=!0,HV(r)===r)return e.mkdirSync(r,e);let i=IFe(e,r);try{return e.mkdirSync(r,e),i}catch(n){if(n.code==="ENOENT")return wFe(r,e);throw n}};KV.exports={mkdirpNative:BFe,mkdirpNativeSync:bFe}});var JV=w((pat,GV)=>{var YV=require("fs"),QFe=process.env.__TESTING_MKDIRP_NODE_VERSION__||process.version,rR=QFe.replace(/^v/,"").split("."),qV=+rR[0]>10||+rR[0]==10&&+rR[1]>=12,SFe=qV?r=>r.mkdir===YV.mkdir:()=>!1,vFe=qV?r=>r.mkdirSync===YV.mkdirSync:()=>!1;GV.exports={useNative:SFe,useNativeSync:vFe}});var ZV=w((dat,WV)=>{var Qf=PV(),Sf=RV(),{mkdirpNative:zV,mkdirpNativeSync:_V}=jV(),{mkdirpManual:VV,mkdirpManualSync:XV}=tR(),{useNative:kFe,useNativeSync:xFe}=JV(),vf=(r,e)=>(r=Sf(r),e=Qf(e),kFe(e)?zV(r,e):VV(r,e)),PFe=(r,e)=>(r=Sf(r),e=Qf(e),xFe(e)?_V(r,e):XV(r,e));vf.sync=PFe;vf.native=(r,e)=>zV(Sf(r),Qf(e));vf.manual=(r,e)=>VV(Sf(r),Qf(e));vf.nativeSync=(r,e)=>_V(Sf(r),Qf(e));vf.manualSync=(r,e)=>XV(Sf(r),Qf(e));WV.exports=vf});var s6=w((Cat,$V)=>{"use strict";var Js=require("fs"),gu=require("path"),DFe=Js.lchown?"lchown":"chown",RFe=Js.lchownSync?"lchownSync":"chownSync",e6=Js.lchown&&!process.version.match(/v1[1-9]+\./)&&!process.version.match(/v10\.[6-9]/),t6=(r,e,t)=>{try{return Js[RFe](r,e,t)}catch(i){if(i.code!=="ENOENT")throw i}},FFe=(r,e,t)=>{try{return Js.chownSync(r,e,t)}catch(i){if(i.code!=="ENOENT")throw i}},NFe=e6?(r,e,t,i)=>n=>{!n||n.code!=="EISDIR"?i(n):Js.chown(r,e,t,i)}:(r,e,t,i)=>i,iR=e6?(r,e,t)=>{try{return t6(r,e,t)}catch(i){if(i.code!=="EISDIR")throw i;FFe(r,e,t)}}:(r,e,t)=>t6(r,e,t),LFe=process.version,r6=(r,e,t)=>Js.readdir(r,e,t),TFe=(r,e)=>Js.readdirSync(r,e);/^v4\./.test(LFe)&&(r6=(r,e,t)=>Js.readdir(r,t));var HB=(r,e,t,i)=>{Js[DFe](r,e,t,NFe(r,e,t,n=>{i(n&&n.code!=="ENOENT"?n:null)}))},i6=(r,e,t,i,n)=>{if(typeof e=="string")return Js.lstat(gu.resolve(r,e),(s,o)=>{if(s)return n(s.code!=="ENOENT"?s:null);o.name=e,i6(r,o,t,i,n)});if(e.isDirectory())nR(gu.resolve(r,e.name),t,i,s=>{if(s)return n(s);let o=gu.resolve(r,e.name);HB(o,t,i,n)});else{let s=gu.resolve(r,e.name);HB(s,t,i,n)}},nR=(r,e,t,i)=>{r6(r,{withFileTypes:!0},(n,s)=>{if(n){if(n.code==="ENOENT")return i();if(n.code!=="ENOTDIR"&&n.code!=="ENOTSUP")return i(n)}if(n||!s.length)return HB(r,e,t,i);let o=s.length,a=null,l=c=>{if(!a){if(c)return i(a=c);if(--o==0)return HB(r,e,t,i)}};s.forEach(c=>i6(r,c,e,t,l))})},OFe=(r,e,t,i)=>{if(typeof e=="string")try{let n=Js.lstatSync(gu.resolve(r,e));n.name=e,e=n}catch(n){if(n.code==="ENOENT")return;throw n}e.isDirectory()&&n6(gu.resolve(r,e.name),t,i),iR(gu.resolve(r,e.name),t,i)},n6=(r,e,t)=>{let i;try{i=TFe(r,{withFileTypes:!0})}catch(n){if(n.code==="ENOENT")return;if(n.code==="ENOTDIR"||n.code==="ENOTSUP")return iR(r,e,t);throw n}return i&&i.length&&i.forEach(n=>OFe(r,n,e,t)),iR(r,e,t)};$V.exports=nR;nR.sync=n6});var l6=w((Iat,sR)=>{"use strict";var o6=ZV(),Ws=require("fs"),jB=require("path"),a6=s6(),oR=class extends Error{constructor(e,t){super("Cannot extract through symbolic link");this.path=t,this.symlink=e}get name(){return"SylinkError"}},oC=class extends Error{constructor(e,t){super(t+": Cannot cd into '"+e+"'");this.path=e,this.code=t}get name(){return"CwdError"}},mat=sR.exports=(r,e,t)=>{let i=e.umask,n=e.mode|448,s=(n&i)!=0,o=e.uid,a=e.gid,l=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),c=e.preserve,u=e.unlink,g=e.cache,f=e.cwd,h=(y,b)=>{y?t(y):(g.set(r,!0),b&&l?a6(b,o,a,v=>h(v)):s?Ws.chmod(r,n,t):t())};if(g&&g.get(r)===!0)return h();if(r===f)return Ws.stat(r,(y,b)=>{(y||!b.isDirectory())&&(y=new oC(r,y&&y.code||"ENOTDIR")),h(y)});if(c)return o6(r,{mode:n}).then(y=>h(null,y),h);let m=jB.relative(f,r).split(/\/|\\/);GB(f,m,n,g,u,f,null,h)},GB=(r,e,t,i,n,s,o,a)=>{if(!e.length)return a(null,o);let l=e.shift(),c=r+"/"+l;if(i.get(c))return GB(c,e,t,i,n,s,o,a);Ws.mkdir(c,t,A6(c,e,t,i,n,s,o,a))},A6=(r,e,t,i,n,s,o,a)=>l=>{if(l){if(l.path&&jB.dirname(l.path)===s&&(l.code==="ENOTDIR"||l.code==="ENOENT"))return a(new oC(s,l.code));Ws.lstat(r,(c,u)=>{if(c)a(c);else if(u.isDirectory())GB(r,e,t,i,n,s,o,a);else if(n)Ws.unlink(r,g=>{if(g)return a(g);Ws.mkdir(r,t,A6(r,e,t,i,n,s,o,a))});else{if(u.isSymbolicLink())return a(new oR(r,r+"/"+e.join("/")));a(l)}})}else o=o||r,GB(r,e,t,i,n,s,o,a)},Eat=sR.exports.sync=(r,e)=>{let t=e.umask,i=e.mode|448,n=(i&t)!=0,s=e.uid,o=e.gid,a=typeof s=="number"&&typeof o=="number"&&(s!==e.processUid||o!==e.processGid),l=e.preserve,c=e.unlink,u=e.cache,g=e.cwd,f=y=>{u.set(r,!0),y&&a&&a6.sync(y,s,o),n&&Ws.chmodSync(r,i)};if(u&&u.get(r)===!0)return f();if(r===g){let y=!1,b="ENOTDIR";try{y=Ws.statSync(r).isDirectory()}catch(v){b=v.code}finally{if(!y)throw new oC(r,b)}f();return}if(l)return f(o6.sync(r,i));let p=jB.relative(g,r).split(/\/|\\/),m=null;for(let y=p.shift(),b=g;y&&(b+="/"+y);y=p.shift())if(!u.get(b))try{Ws.mkdirSync(b,i),m=m||b,u.set(b,!0)}catch(v){if(v.path&&jB.dirname(v.path)===g&&(v.code==="ENOTDIR"||v.code==="ENOENT"))return new oC(g,v.code);let k=Ws.lstatSync(b);if(k.isDirectory()){u.set(b,!0);continue}else if(c){Ws.unlinkSync(b),Ws.mkdirSync(b,i),m=m||b,u.set(b,!0);continue}else if(k.isSymbolicLink())return new oR(b,b+"/"+p.join("/"))}return f(m)}});var g6=w((yat,c6)=>{var u6=require("assert");c6.exports=()=>{let r=new Map,e=new Map,{join:t}=require("path"),i=u=>t(u).split(/[\\\/]/).slice(0,-1).reduce((g,f)=>g.length?g.concat(t(g[g.length-1],f)):[f],[]),n=new Set,s=u=>{let g=e.get(u);if(!g)throw new Error("function does not have any path reservations");return{paths:g.paths.map(f=>r.get(f)),dirs:[...g.dirs].map(f=>r.get(f))}},o=u=>{let{paths:g,dirs:f}=s(u);return g.every(h=>h[0]===u)&&f.every(h=>h[0]instanceof Set&&h[0].has(u))},a=u=>n.has(u)||!o(u)?!1:(n.add(u),u(()=>l(u)),!0),l=u=>{if(!n.has(u))return!1;let{paths:g,dirs:f}=e.get(u),h=new Set;return g.forEach(p=>{let m=r.get(p);u6.equal(m[0],u),m.length===1?r.delete(p):(m.shift(),typeof m[0]=="function"?h.add(m[0]):m[0].forEach(y=>h.add(y)))}),f.forEach(p=>{let m=r.get(p);u6(m[0]instanceof Set),m[0].size===1&&m.length===1?r.delete(p):m[0].size===1?(m.shift(),h.add(m[0])):m[0].delete(u)}),n.delete(u),h.forEach(p=>a(p)),!0};return{check:o,reserve:(u,g)=>{let f=new Set(u.map(h=>i(h)).reduce((h,p)=>h.concat(p)));return e.set(g,{dirs:f,paths:u}),u.forEach(h=>{let p=r.get(h);p?p.push(g):r.set(h,[g])}),f.forEach(h=>{let p=r.get(h);p?p[p.length-1]instanceof Set?p[p.length-1].add(g):p.push(new Set([g])):r.set(h,[new Set([g])])}),a(g)}}}});var p6=w((wat,f6)=>{var MFe=process.env.__FAKE_PLATFORM__||process.platform,UFe=MFe==="win32",KFe=global.__FAKE_TESTING_FS__||require("fs"),{O_CREAT:HFe,O_TRUNC:jFe,O_WRONLY:GFe,UV_FS_O_FILEMAP:h6=0}=KFe.constants,YFe=UFe&&!!h6,qFe=512*1024,JFe=h6|jFe|HFe|GFe;f6.exports=YFe?r=>r<qFe?JFe:"w":()=>"w"});var pR=w((Sat,d6)=>{"use strict";var WFe=require("assert"),Bat=require("events").EventEmitter,zFe=sC(),$t=require("fs"),_Fe=Bf(),hA=require("path"),aR=l6(),bat=aR.sync,C6=wD(),VFe=g6(),m6=Symbol("onEntry"),AR=Symbol("checkFs"),E6=Symbol("checkFs2"),lR=Symbol("isReusable"),pA=Symbol("makeFs"),cR=Symbol("file"),uR=Symbol("directory"),YB=Symbol("link"),I6=Symbol("symlink"),y6=Symbol("hardlink"),w6=Symbol("unsupported"),Qat=Symbol("unknown"),B6=Symbol("checkPath"),kf=Symbol("mkdir"),dn=Symbol("onError"),qB=Symbol("pending"),b6=Symbol("pend"),xf=Symbol("unpend"),gR=Symbol("ended"),fR=Symbol("maybeClose"),hR=Symbol("skip"),aC=Symbol("doChown"),AC=Symbol("uid"),lC=Symbol("gid"),Q6=require("crypto"),S6=p6(),JB=()=>{throw new Error("sync function called cb somehow?!?")},XFe=(r,e)=>{if(process.platform!=="win32")return $t.unlink(r,e);let t=r+".DELETE."+Q6.randomBytes(16).toString("hex");$t.rename(r,t,i=>{if(i)return e(i);$t.unlink(t,e)})},ZFe=r=>{if(process.platform!=="win32")return $t.unlinkSync(r);let e=r+".DELETE."+Q6.randomBytes(16).toString("hex");$t.renameSync(r,e),$t.unlinkSync(e)},v6=(r,e,t)=>r===r>>>0?r:e===e>>>0?e:t,WB=class extends zFe{constructor(e){if(e||(e={}),e.ondone=t=>{this[gR]=!0,this[fR]()},super(e),this.reservations=VFe(),this.transform=typeof e.transform=="function"?e.transform:null,this.writable=!0,this.readable=!1,this[qB]=0,this[gR]=!1,this.dirCache=e.dirCache||new Map,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=null,this.gid=null,this.setOwner=!1;e.preserveOwner===void 0&&typeof e.uid!="number"?this.preserveOwner=process.getuid&&process.getuid()===0:this.preserveOwner=!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():null,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():null,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||process.platform==="win32",this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=hA.resolve(e.cwd||process.cwd()),this.strip=+e.strip||0,this.processUmask=process.umask(),this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",t=>this[m6](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[fR](){this[gR]&&this[qB]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close"))}[B6](e){if(this.strip){let t=e.path.split(/\/|\\/);if(t.length<this.strip)return!1;if(e.path=t.slice(this.strip).join("/"),e.type==="Link"){let i=e.linkpath.split(/\/|\\/);i.length>=this.strip&&(e.linkpath=i.slice(this.strip).join("/"))}}if(!this.preservePaths){let t=e.path;if(t.match(/(^|\/|\\)\.\.(\\|\/|$)/))return this.warn("TAR_ENTRY_ERROR","path contains '..'",{entry:e,path:t}),!1;if(hA.win32.isAbsolute(t)){let i=hA.win32.parse(t);e.path=t.substr(i.root.length);let n=i.root;this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:e,path:t})}}if(this.win32){let t=hA.win32.parse(e.path);e.path=t.root===""?C6.encode(e.path):t.root+C6.encode(e.path.substr(t.root.length))}return hA.isAbsolute(e.path)?e.absolute=e.path:e.absolute=hA.resolve(this.cwd,e.path),!0}[m6](e){if(!this[B6](e))return e.resume();switch(WFe.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[AR](e);case"CharacterDevice":case"BlockDevice":case"FIFO":return this[w6](e)}}[dn](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[xf](),t.resume())}[kf](e,t,i){aR(e,{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:t},i)}[aC](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[AC](e){return v6(this.uid,e.uid,this.processUid)}[lC](e){return v6(this.gid,e.gid,this.processGid)}[cR](e,t){let i=e.mode&4095||this.fmode,n=new _Fe.WriteStream(e.absolute,{flags:S6(e.size),mode:i,autoClose:!1});n.on("error",l=>this[dn](l,e));let s=1,o=l=>{if(l)return this[dn](l,e);--s==0&&$t.close(n.fd,c=>{t(),c?this[dn](c,e):this[xf]()})};n.on("finish",l=>{let c=e.absolute,u=n.fd;if(e.mtime&&!this.noMtime){s++;let g=e.atime||new Date,f=e.mtime;$t.futimes(u,g,f,h=>h?$t.utimes(c,g,f,p=>o(p&&h)):o())}if(this[aC](e)){s++;let g=this[AC](e),f=this[lC](e);$t.fchown(u,g,f,h=>h?$t.chown(c,g,f,p=>o(p&&h)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",l=>this[dn](l,e)),e.pipe(a)),a.pipe(n)}[uR](e,t){let i=e.mode&4095||this.dmode;this[kf](e.absolute,i,n=>{if(n)return t(),this[dn](n,e);let s=1,o=a=>{--s==0&&(t(),this[xf](),e.resume())};e.mtime&&!this.noMtime&&(s++,$t.utimes(e.absolute,e.atime||new Date,e.mtime,o)),this[aC](e)&&(s++,$t.chown(e.absolute,this[AC](e),this[lC](e),o)),o()})}[w6](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[I6](e,t){this[YB](e,e.linkpath,"symlink",t)}[y6](e,t){this[YB](e,hA.resolve(this.cwd,e.linkpath),"link",t)}[b6](){this[qB]++}[xf](){this[qB]--,this[fR]()}[hR](e){this[xf](),e.resume()}[lR](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&process.platform!=="win32"}[AR](e){this[b6]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[E6](e,i))}[E6](e,t){this[kf](hA.dirname(e.absolute),this.dmode,i=>{if(i)return t(),this[dn](i,e);$t.lstat(e.absolute,(n,s)=>{s&&(this.keep||this.newer&&s.mtime>e.mtime)?(this[hR](e),t()):n||this[lR](e,s)?this[pA](null,e,t):s.isDirectory()?e.type==="Directory"?!e.mode||(s.mode&4095)===e.mode?this[pA](null,e,t):$t.chmod(e.absolute,e.mode,o=>this[pA](o,e,t)):$t.rmdir(e.absolute,o=>this[pA](o,e,t)):XFe(e.absolute,o=>this[pA](o,e,t))})})}[pA](e,t,i){if(e)return this[dn](e,t);switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[cR](t,i);case"Link":return this[y6](t,i);case"SymbolicLink":return this[I6](t,i);case"Directory":case"GNUDumpDir":return this[uR](t,i)}}[YB](e,t,i,n){$t[i](t,e.absolute,s=>{if(s)return this[dn](s,e);n(),this[xf](),e.resume()})}},k6=class extends WB{constructor(e){super(e)}[AR](e){let t=this[kf](hA.dirname(e.absolute),this.dmode,JB);if(t)return this[dn](t,e);try{let i=$t.lstatSync(e.absolute);if(this.keep||this.newer&&i.mtime>e.mtime)return this[hR](e);if(this[lR](e,i))return this[pA](null,e,JB);try{return i.isDirectory()?e.type==="Directory"?e.mode&&(i.mode&4095)!==e.mode&&$t.chmodSync(e.absolute,e.mode):$t.rmdirSync(e.absolute):ZFe(e.absolute),this[pA](null,e,JB)}catch(n){return this[dn](n,e)}}catch(i){return this[pA](null,e,JB)}}[cR](e,t){let i=e.mode&4095||this.fmode,n=l=>{let c;try{$t.closeSync(o)}catch(u){c=u}(l||c)&&this[dn](l||c,e)},s,o;try{o=$t.openSync(e.absolute,S6(e.size),i)}catch(l){return n(l)}let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",l=>this[dn](l,e)),e.pipe(a)),a.on("data",l=>{try{$t.writeSync(o,l,0,l.length)}catch(c){n(c)}}),a.on("end",l=>{let c=null;if(e.mtime&&!this.noMtime){let u=e.atime||new Date,g=e.mtime;try{$t.futimesSync(o,u,g)}catch(f){try{$t.utimesSync(e.absolute,u,g)}catch(h){c=f}}}if(this[aC](e)){let u=this[AC](e),g=this[lC](e);try{$t.fchownSync(o,u,g)}catch(f){try{$t.chownSync(e.absolute,u,g)}catch(h){c=c||f}}}n(c)})}[uR](e,t){let i=e.mode&4095||this.dmode,n=this[kf](e.absolute,i);if(n)return this[dn](n,e);if(e.mtime&&!this.noMtime)try{$t.utimesSync(e.absolute,e.atime||new Date,e.mtime)}catch(s){}if(this[aC](e))try{$t.chownSync(e.absolute,this[AC](e),this[lC](e))}catch(s){}e.resume()}[kf](e,t){try{return aR.sync(e,{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:t})}catch(i){return i}}[YB](e,t,i,n){try{$t[i+"Sync"](t,e.absolute),e.resume()}catch(s){return this[dn](s,e)}}};WB.Sync=k6;d6.exports=WB});var F6=w((kat,x6)=>{"use strict";var $Fe=uf(),zB=pR(),P6=require("fs"),D6=Bf(),R6=require("path"),vat=x6.exports=(r,e,t)=>{typeof r=="function"?(t=r,e=null,r={}):Array.isArray(r)&&(e=r,r={}),typeof e=="function"&&(t=e,e=null),e?e=Array.from(e):e=[];let i=$Fe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return e.length&&eNe(i,e),i.file&&i.sync?tNe(i):i.file?rNe(i,t):i.sync?iNe(i):nNe(i)},eNe=(r,e)=>{let t=new Map(e.map(s=>[s.replace(/\/+$/,""),!0])),i=r.filter,n=(s,o)=>{let a=o||R6.parse(s).root||".",l=s===a?!1:t.has(s)?t.get(s):n(R6.dirname(s),a);return t.set(s,l),l};r.filter=i?(s,o)=>i(s,o)&&n(s.replace(/\/+$/,"")):s=>n(s.replace(/\/+$/,""))},tNe=r=>{let e=new zB.Sync(r),t=r.file,i=!0,n,s=P6.statSync(t),o=r.maxReadSize||16*1024*1024;new D6.ReadStreamSync(t,{readSize:o,size:s.size}).pipe(e)},rNe=(r,e)=>{let t=new zB(r),i=r.maxReadSize||16*1024*1024,n=r.file,s=new Promise((o,a)=>{t.on("error",a),t.on("close",o),P6.stat(n,(l,c)=>{if(l)a(l);else{let u=new D6.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(t)}})});return e?s.then(e,e):s},iNe=r=>new zB.Sync(r),nNe=r=>new zB(r)});var N6=w(pi=>{"use strict";pi.c=pi.create=mV();pi.r=pi.replace=ZD();pi.t=pi.list=UB();pi.u=pi.update=vV();pi.x=pi.extract=F6();pi.Pack=vB();pi.Unpack=pR();pi.Parse=sC();pi.ReadEntry=$d();pi.WriteEntry=xD();pi.Header=pf();pi.Pax=fB();pi.types=Zd()});var U6=w((Dat,M6)=>{var CR;M6.exports.getContent=()=>(typeof CR=="undefined"&&(CR=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),CR)});var q6=w((mR,Y6)=>{(function(r,e){typeof mR=="object"?Y6.exports=e():typeof define=="function"&&define.amd?define(e):r.treeify=e()})(mR,function(){function r(n,s){var o=s?"\u2514":"\u251C";return n?o+="\u2500 ":o+="\u2500\u2500\u2510",o}function e(n,s){var o=[];for(var a in n)!n.hasOwnProperty(a)||s&&typeof n[a]=="function"||o.push(a);return o}function t(n,s,o,a,l,c,u){var g="",f=0,h,p,m=a.slice(0);if(m.push([s,o])&&a.length>0&&(a.forEach(function(b,v){v>0&&(g+=(b[1]?" ":"\u2502")+" "),!p&&b[0]===s&&(p=!0)}),g+=r(n,o)+n,l&&(typeof s!="object"||s instanceof Date)&&(g+=": "+s),p&&(g+=" (circular ref.)"),u(g)),!p&&typeof s=="object"){var y=e(s,c);y.forEach(function(b){h=++f===y.length,t(b,s[b],h,m,l,c,u)})}}var i={};return i.asLines=function(n,s,o,a){var l=typeof o!="function"?o:!1;t(".",n,!1,[],s,l,a||o)},i.asTree=function(n,s,o){var a="";return t(".",n,!1,[],s,o,function(l){a+=l+` -`}),a},i})});var VB=w((aAt,t7)=>{var wNe=Hs(),BNe=yd(),bNe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,QNe=/^\w*$/;function SNe(r,e){if(wNe(r))return!1;var t=typeof r;return t=="number"||t=="symbol"||t=="boolean"||r==null||BNe(r)?!0:QNe.test(r)||!bNe.test(r)||e!=null&&r in Object(e)}t7.exports=SNe});var XB=w((AAt,r7)=>{var vNe=zc(),kNe=Fn(),xNe="[object AsyncFunction]",PNe="[object Function]",DNe="[object GeneratorFunction]",RNe="[object Proxy]";function FNe(r){if(!kNe(r))return!1;var e=vNe(r);return e==PNe||e==DNe||e==xNe||e==RNe}r7.exports=FNe});var n7=w((lAt,i7)=>{var NNe=Ts(),LNe=NNe["__core-js_shared__"];i7.exports=LNe});var a7=w((cAt,s7)=>{var SR=n7(),o7=function(){var r=/[^.]+$/.exec(SR&&SR.keys&&SR.keys.IE_PROTO||"");return r?"Symbol(src)_1."+r:""}();function TNe(r){return!!o7&&o7 in r}s7.exports=TNe});var vR=w((uAt,A7)=>{var ONe=Function.prototype,MNe=ONe.toString;function UNe(r){if(r!=null){try{return MNe.call(r)}catch(e){}try{return r+""}catch(e){}}return""}A7.exports=UNe});var c7=w((gAt,l7)=>{var KNe=XB(),HNe=a7(),jNe=Fn(),GNe=vR(),YNe=/[\\^$.*+?()[\]{}|]/g,qNe=/^\[object .+?Constructor\]$/,JNe=Function.prototype,WNe=Object.prototype,zNe=JNe.toString,_Ne=WNe.hasOwnProperty,VNe=RegExp("^"+zNe.call(_Ne).replace(YNe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function XNe(r){if(!jNe(r)||HNe(r))return!1;var e=KNe(r)?VNe:qNe;return e.test(GNe(r))}l7.exports=XNe});var g7=w((fAt,u7)=>{function ZNe(r,e){return r==null?void 0:r[e]}u7.exports=ZNe});var Fl=w((hAt,f7)=>{var $Ne=c7(),eLe=g7();function tLe(r,e){var t=eLe(r,e);return $Ne(t)?t:void 0}f7.exports=tLe});var uC=w((pAt,h7)=>{var rLe=Fl(),iLe=rLe(Object,"create");h7.exports=iLe});var C7=w((dAt,p7)=>{var d7=uC();function nLe(){this.__data__=d7?d7(null):{},this.size=0}p7.exports=nLe});var E7=w((CAt,m7)=>{function sLe(r){var e=this.has(r)&&delete this.__data__[r];return this.size-=e?1:0,e}m7.exports=sLe});var y7=w((mAt,I7)=>{var oLe=uC(),aLe="__lodash_hash_undefined__",ALe=Object.prototype,lLe=ALe.hasOwnProperty;function cLe(r){var e=this.__data__;if(oLe){var t=e[r];return t===aLe?void 0:t}return lLe.call(e,r)?e[r]:void 0}I7.exports=cLe});var B7=w((EAt,w7)=>{var uLe=uC(),gLe=Object.prototype,fLe=gLe.hasOwnProperty;function hLe(r){var e=this.__data__;return uLe?e[r]!==void 0:fLe.call(e,r)}w7.exports=hLe});var Q7=w((IAt,b7)=>{var pLe=uC(),dLe="__lodash_hash_undefined__";function CLe(r,e){var t=this.__data__;return this.size+=this.has(r)?0:1,t[r]=pLe&&e===void 0?dLe:e,this}b7.exports=CLe});var v7=w((yAt,S7)=>{var mLe=C7(),ELe=E7(),ILe=y7(),yLe=B7(),wLe=Q7();function Pf(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e<t;){var i=r[e];this.set(i[0],i[1])}}Pf.prototype.clear=mLe;Pf.prototype.delete=ELe;Pf.prototype.get=ILe;Pf.prototype.has=yLe;Pf.prototype.set=wLe;S7.exports=Pf});var x7=w((wAt,k7)=>{function BLe(){this.__data__=[],this.size=0}k7.exports=BLe});var Df=w((BAt,P7)=>{function bLe(r,e){return r===e||r!==r&&e!==e}P7.exports=bLe});var gC=w((bAt,D7)=>{var QLe=Df();function SLe(r,e){for(var t=r.length;t--;)if(QLe(r[t][0],e))return t;return-1}D7.exports=SLe});var F7=w((QAt,R7)=>{var vLe=gC(),kLe=Array.prototype,xLe=kLe.splice;function PLe(r){var e=this.__data__,t=vLe(e,r);if(t<0)return!1;var i=e.length-1;return t==i?e.pop():xLe.call(e,t,1),--this.size,!0}R7.exports=PLe});var L7=w((SAt,N7)=>{var DLe=gC();function RLe(r){var e=this.__data__,t=DLe(e,r);return t<0?void 0:e[t][1]}N7.exports=RLe});var O7=w((vAt,T7)=>{var FLe=gC();function NLe(r){return FLe(this.__data__,r)>-1}T7.exports=NLe});var U7=w((kAt,M7)=>{var LLe=gC();function TLe(r,e){var t=this.__data__,i=LLe(t,r);return i<0?(++this.size,t.push([r,e])):t[i][1]=e,this}M7.exports=TLe});var fC=w((xAt,K7)=>{var OLe=x7(),MLe=F7(),ULe=L7(),KLe=O7(),HLe=U7();function Rf(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e<t;){var i=r[e];this.set(i[0],i[1])}}Rf.prototype.clear=OLe;Rf.prototype.delete=MLe;Rf.prototype.get=ULe;Rf.prototype.has=KLe;Rf.prototype.set=HLe;K7.exports=Rf});var ZB=w((PAt,H7)=>{var jLe=Fl(),GLe=Ts(),YLe=jLe(GLe,"Map");H7.exports=YLe});var Y7=w((DAt,j7)=>{var G7=v7(),qLe=fC(),JLe=ZB();function WLe(){this.size=0,this.__data__={hash:new G7,map:new(JLe||qLe),string:new G7}}j7.exports=WLe});var J7=w((RAt,q7)=>{function zLe(r){var e=typeof r;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?r!=="__proto__":r===null}q7.exports=zLe});var hC=w((FAt,W7)=>{var _Le=J7();function VLe(r,e){var t=r.__data__;return _Le(e)?t[typeof e=="string"?"string":"hash"]:t.map}W7.exports=VLe});var _7=w((NAt,z7)=>{var XLe=hC();function ZLe(r){var e=XLe(this,r).delete(r);return this.size-=e?1:0,e}z7.exports=ZLe});var X7=w((LAt,V7)=>{var $Le=hC();function eTe(r){return $Le(this,r).get(r)}V7.exports=eTe});var $7=w((TAt,Z7)=>{var tTe=hC();function rTe(r){return tTe(this,r).has(r)}Z7.exports=rTe});var tX=w((OAt,eX)=>{var iTe=hC();function nTe(r,e){var t=iTe(this,r),i=t.size;return t.set(r,e),this.size+=t.size==i?0:1,this}eX.exports=nTe});var $B=w((MAt,rX)=>{var sTe=Y7(),oTe=_7(),aTe=X7(),ATe=$7(),lTe=tX();function Ff(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e<t;){var i=r[e];this.set(i[0],i[1])}}Ff.prototype.clear=sTe;Ff.prototype.delete=oTe;Ff.prototype.get=aTe;Ff.prototype.has=ATe;Ff.prototype.set=lTe;rX.exports=Ff});var sX=w((UAt,iX)=>{var nX=$B(),cTe="Expected a function";function kR(r,e){if(typeof r!="function"||e!=null&&typeof e!="function")throw new TypeError(cTe);var t=function(){var i=arguments,n=e?e.apply(this,i):i[0],s=t.cache;if(s.has(n))return s.get(n);var o=r.apply(this,i);return t.cache=s.set(n,o)||s,o};return t.cache=new(kR.Cache||nX),t}kR.Cache=nX;iX.exports=kR});var aX=w((KAt,oX)=>{var uTe=sX(),gTe=500;function fTe(r){var e=uTe(r,function(i){return t.size===gTe&&t.clear(),i}),t=e.cache;return e}oX.exports=fTe});var lX=w((HAt,AX)=>{var hTe=aX(),pTe=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,dTe=/\\(\\)?/g,CTe=hTe(function(r){var e=[];return r.charCodeAt(0)===46&&e.push(""),r.replace(pTe,function(t,i,n,s){e.push(n?s.replace(dTe,"$1"):i||t)}),e});AX.exports=CTe});var Nf=w((jAt,cX)=>{var mTe=Hs(),ETe=VB(),ITe=lX(),yTe=cf();function wTe(r,e){return mTe(r)?r:ETe(r,e)?[r]:ITe(yTe(r))}cX.exports=wTe});var fu=w((GAt,uX)=>{var BTe=yd(),bTe=1/0;function QTe(r){if(typeof r=="string"||BTe(r))return r;var e=r+"";return e=="0"&&1/r==-bTe?"-0":e}uX.exports=QTe});var pC=w((YAt,gX)=>{var STe=Nf(),vTe=fu();function kTe(r,e){e=STe(e,r);for(var t=0,i=e.length;r!=null&&t<i;)r=r[vTe(e[t++])];return t&&t==i?r:void 0}gX.exports=kTe});var xR=w((qAt,fX)=>{var xTe=Fl(),PTe=function(){try{var r=xTe(Object,"defineProperty");return r({},"",{}),r}catch(e){}}();fX.exports=PTe});var Lf=w((JAt,hX)=>{var pX=xR();function DTe(r,e,t){e=="__proto__"&&pX?pX(r,e,{configurable:!0,enumerable:!0,value:t,writable:!0}):r[e]=t}hX.exports=DTe});var e0=w((WAt,dX)=>{var RTe=Lf(),FTe=Df(),NTe=Object.prototype,LTe=NTe.hasOwnProperty;function TTe(r,e,t){var i=r[e];(!(LTe.call(r,e)&&FTe(i,t))||t===void 0&&!(e in r))&&RTe(r,e,t)}dX.exports=TTe});var dC=w((zAt,CX)=>{var OTe=9007199254740991,MTe=/^(?:0|[1-9]\d*)$/;function UTe(r,e){var t=typeof r;return e=e==null?OTe:e,!!e&&(t=="number"||t!="symbol"&&MTe.test(r))&&r>-1&&r%1==0&&r<e}CX.exports=UTe});var PR=w((_At,mX)=>{var KTe=e0(),HTe=Nf(),jTe=dC(),EX=Fn(),GTe=fu();function YTe(r,e,t,i){if(!EX(r))return r;e=HTe(e,r);for(var n=-1,s=e.length,o=s-1,a=r;a!=null&&++n<s;){var l=GTe(e[n]),c=t;if(l==="__proto__"||l==="constructor"||l==="prototype")return r;if(n!=o){var u=a[l];c=i?i(u,l,a):void 0,c===void 0&&(c=EX(u)?u:jTe(e[n+1])?[]:{})}KTe(a,l,c),a=a[l]}return r}mX.exports=YTe});var yX=w((VAt,IX)=>{var qTe=pC(),JTe=PR(),WTe=Nf();function zTe(r,e,t){for(var i=-1,n=e.length,s={};++i<n;){var o=e[i],a=qTe(r,o);t(a,o)&&JTe(s,WTe(o,r),a)}return s}IX.exports=zTe});var BX=w((XAt,wX)=>{function _Te(r,e){return r!=null&&e in Object(r)}wX.exports=_Te});var QX=w((ZAt,bX)=>{var VTe=zc(),XTe=ra(),ZTe="[object Arguments]";function $Te(r){return XTe(r)&&VTe(r)==ZTe}bX.exports=$Te});var CC=w(($At,SX)=>{var vX=QX(),eOe=ra(),kX=Object.prototype,tOe=kX.hasOwnProperty,rOe=kX.propertyIsEnumerable,iOe=vX(function(){return arguments}())?vX:function(r){return eOe(r)&&tOe.call(r,"callee")&&!rOe.call(r,"callee")};SX.exports=iOe});var t0=w((elt,xX)=>{var nOe=9007199254740991;function sOe(r){return typeof r=="number"&&r>-1&&r%1==0&&r<=nOe}xX.exports=sOe});var DR=w((tlt,PX)=>{var oOe=Nf(),aOe=CC(),AOe=Hs(),lOe=dC(),cOe=t0(),uOe=fu();function gOe(r,e,t){e=oOe(e,r);for(var i=-1,n=e.length,s=!1;++i<n;){var o=uOe(e[i]);if(!(s=r!=null&&t(r,o)))break;r=r[o]}return s||++i!=n?s:(n=r==null?0:r.length,!!n&&cOe(n)&&lOe(o,n)&&(AOe(r)||aOe(r)))}PX.exports=gOe});var RR=w((rlt,DX)=>{var fOe=BX(),hOe=DR();function pOe(r,e){return r!=null&&hOe(r,e,fOe)}DX.exports=pOe});var FX=w((ilt,RX)=>{var dOe=yX(),COe=RR();function mOe(r,e){return dOe(r,e,function(t,i){return COe(r,i)})}RX.exports=mOe});var r0=w((nlt,NX)=>{function EOe(r,e){for(var t=-1,i=e.length,n=r.length;++t<i;)r[n+t]=e[t];return r}NX.exports=EOe});var MX=w((slt,LX)=>{var TX=Wc(),IOe=CC(),yOe=Hs(),OX=TX?TX.isConcatSpreadable:void 0;function wOe(r){return yOe(r)||IOe(r)||!!(OX&&r&&r[OX])}LX.exports=wOe});var HX=w((olt,UX)=>{var BOe=r0(),bOe=MX();function KX(r,e,t,i,n){var s=-1,o=r.length;for(t||(t=bOe),n||(n=[]);++s<o;){var a=r[s];e>0&&t(a)?e>1?KX(a,e-1,t,i,n):BOe(n,a):i||(n[n.length]=a)}return n}UX.exports=KX});var GX=w((alt,jX)=>{var QOe=HX();function SOe(r){var e=r==null?0:r.length;return e?QOe(r,1):[]}jX.exports=SOe});var qX=w((Alt,YX)=>{function vOe(r,e,t){switch(t.length){case 0:return r.call(e);case 1:return r.call(e,t[0]);case 2:return r.call(e,t[0],t[1]);case 3:return r.call(e,t[0],t[1],t[2])}return r.apply(e,t)}YX.exports=vOe});var FR=w((llt,JX)=>{var kOe=qX(),WX=Math.max;function xOe(r,e,t){return e=WX(e===void 0?r.length-1:e,0),function(){for(var i=arguments,n=-1,s=WX(i.length-e,0),o=Array(s);++n<s;)o[n]=i[e+n];n=-1;for(var a=Array(e+1);++n<e;)a[n]=i[n];return a[e]=t(o),kOe(r,this,a)}}JX.exports=xOe});var _X=w((clt,zX)=>{function POe(r){return function(){return r}}zX.exports=POe});var i0=w((ult,VX)=>{function DOe(r){return r}VX.exports=DOe});var $X=w((glt,XX)=>{var ROe=_X(),ZX=xR(),FOe=i0(),NOe=ZX?function(r,e){return ZX(r,"toString",{configurable:!0,enumerable:!1,value:ROe(e),writable:!0})}:FOe;XX.exports=NOe});var tZ=w((flt,eZ)=>{var LOe=800,TOe=16,OOe=Date.now;function MOe(r){var e=0,t=0;return function(){var i=OOe(),n=TOe-(i-t);if(t=i,n>0){if(++e>=LOe)return arguments[0]}else e=0;return r.apply(void 0,arguments)}}eZ.exports=MOe});var NR=w((hlt,rZ)=>{var UOe=$X(),KOe=tZ(),HOe=KOe(UOe);rZ.exports=HOe});var nZ=w((plt,iZ)=>{var jOe=GX(),GOe=FR(),YOe=NR();function qOe(r){return YOe(GOe(r,void 0,jOe),r+"")}iZ.exports=qOe});var oZ=w((dlt,sZ)=>{var JOe=FX(),WOe=nZ(),zOe=WOe(function(r,e){return r==null?{}:JOe(r,e)});sZ.exports=zOe});var mZ=w((fut,pZ)=>{"use strict";var YR;try{YR=Map}catch(r){}var qR;try{qR=Set}catch(r){}function dZ(r,e,t){if(!r||typeof r!="object"||typeof r=="function")return r;if(r.nodeType&&"cloneNode"in r)return r.cloneNode(!0);if(r instanceof Date)return new Date(r.getTime());if(r instanceof RegExp)return new RegExp(r);if(Array.isArray(r))return r.map(CZ);if(YR&&r instanceof YR)return new Map(Array.from(r.entries()));if(qR&&r instanceof qR)return new Set(Array.from(r.values()));if(r instanceof Object){e.push(r);var i=Object.create(r);t.push(i);for(var n in r){var s=e.findIndex(function(o){return o===r[n]});i[n]=s>-1?t[s]:dZ(r[n],e,t)}return i}return r}function CZ(r){return dZ(r,[],[])}pZ.exports=CZ});var yC=w(JR=>{"use strict";Object.defineProperty(JR,"__esModule",{value:!0});JR.default=iMe;var nMe=Object.prototype.toString,sMe=Error.prototype.toString,oMe=RegExp.prototype.toString,aMe=typeof Symbol!="undefined"?Symbol.prototype.toString:()=>"",AMe=/^Symbol\((.*)\)(.*)$/;function lMe(r){return r!=+r?"NaN":r===0&&1/r<0?"-0":""+r}function EZ(r,e=!1){if(r==null||r===!0||r===!1)return""+r;let t=typeof r;if(t==="number")return lMe(r);if(t==="string")return e?`"${r}"`:r;if(t==="function")return"[Function "+(r.name||"anonymous")+"]";if(t==="symbol")return aMe.call(r).replace(AMe,"Symbol($1)");let i=nMe.call(r).slice(8,-1);return i==="Date"?isNaN(r.getTime())?""+r:r.toISOString(r):i==="Error"||r instanceof Error?"["+sMe.call(r)+"]":i==="RegExp"?oMe.call(r):null}function iMe(r,e){let t=EZ(r,e);return t!==null?t:JSON.stringify(r,function(i,n){let s=EZ(this[i],e);return s!==null?s:n},2)}});var mA=w(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.default=bi.array=bi.object=bi.boolean=bi.date=bi.number=bi.string=bi.mixed=void 0;var IZ=cMe(yC());function cMe(r){return r&&r.__esModule?r:{default:r}}var yZ={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType:({path:r,type:e,value:t,originalValue:i})=>{let n=i!=null&&i!==t,s=`${r} must be a \`${e}\` type, but the final value was: \`${(0,IZ.default)(t,!0)}\``+(n?` (cast from the value \`${(0,IZ.default)(i,!0)}\`).`:".");return t===null&&(s+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),s},defined:"${path} must be defined"};bi.mixed=yZ;var wZ={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"};bi.string=wZ;var BZ={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"};bi.number=BZ;var bZ={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"};bi.date=bZ;var QZ={isValue:"${path} field must be ${value}"};bi.boolean=QZ;var SZ={noUnknown:"${path} field has unspecified keys: ${unknown}"};bi.object=SZ;var vZ={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};bi.array=vZ;var uMe=Object.assign(Object.create(null),{mixed:yZ,string:wZ,number:BZ,date:bZ,object:SZ,array:vZ,boolean:QZ});bi.default=uMe});var xZ=w((dut,kZ)=>{var gMe=Object.prototype,fMe=gMe.hasOwnProperty;function hMe(r,e){return r!=null&&fMe.call(r,e)}kZ.exports=hMe});var wC=w((Cut,PZ)=>{var pMe=xZ(),dMe=DR();function CMe(r,e){return r!=null&&dMe(r,e,pMe)}PZ.exports=CMe});var Of=w(a0=>{"use strict";Object.defineProperty(a0,"__esModule",{value:!0});a0.default=void 0;var mMe=r=>r&&r.__isYupSchema__;a0.default=mMe});var FZ=w(A0=>{"use strict";Object.defineProperty(A0,"__esModule",{value:!0});A0.default=void 0;var EMe=DZ(wC()),IMe=DZ(Of());function DZ(r){return r&&r.__esModule?r:{default:r}}var RZ=class{constructor(e,t){if(this.refs=e,this.refs=e,typeof t=="function"){this.fn=t;return}if(!(0,EMe.default)(t,"is"))throw new TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw new TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:i,then:n,otherwise:s}=t,o=typeof i=="function"?i:(...a)=>a.every(l=>l===i);this.fn=function(...a){let l=a.pop(),c=a.pop(),u=o(...a)?n:s;if(!!u)return typeof u=="function"?u(c):c.concat(u.resolve(l))}}resolve(e,t){let i=this.refs.map(s=>s.getValue(t==null?void 0:t.value,t==null?void 0:t.parent,t==null?void 0:t.context)),n=this.fn.apply(e,i.concat(e,t));if(n===void 0||n===e)return e;if(!(0,IMe.default)(n))throw new TypeError("conditions must return a schema object");return n.resolve(t)}},yMe=RZ;A0.default=yMe});var zR=w(WR=>{"use strict";Object.defineProperty(WR,"__esModule",{value:!0});WR.default=wMe;function wMe(r){return r==null?[]:[].concat(r)}});var hu=w(l0=>{"use strict";Object.defineProperty(l0,"__esModule",{value:!0});l0.default=void 0;var BMe=NZ(yC()),bMe=NZ(zR());function NZ(r){return r&&r.__esModule?r:{default:r}}function _R(){return _R=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},_R.apply(this,arguments)}var QMe=/\$\{\s*(\w+)\s*\}/g,BC=class extends Error{static formatError(e,t){let i=t.label||t.path||"this";return i!==t.path&&(t=_R({},t,{path:i})),typeof e=="string"?e.replace(QMe,(n,s)=>(0,BMe.default)(t[s])):typeof e=="function"?e(t):e}static isError(e){return e&&e.name==="ValidationError"}constructor(e,t,i,n){super();this.name="ValidationError",this.value=t,this.path=i,this.type=n,this.errors=[],this.inner=[],(0,bMe.default)(e).forEach(s=>{BC.isError(s)?(this.errors.push(...s.errors),this.inner=this.inner.concat(s.inner.length?s.inner:s)):this.errors.push(s)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,BC)}};l0.default=BC});var c0=w(VR=>{"use strict";Object.defineProperty(VR,"__esModule",{value:!0});VR.default=SMe;var XR=vMe(hu());function vMe(r){return r&&r.__esModule?r:{default:r}}var kMe=r=>{let e=!1;return(...t)=>{e||(e=!0,r(...t))}};function SMe(r,e){let{endEarly:t,tests:i,args:n,value:s,errors:o,sort:a,path:l}=r,c=kMe(e),u=i.length,g=[];if(o=o||[],!u)return o.length?c(new XR.default(o,s,l)):c(null,s);for(let f=0;f<i.length;f++)i[f](n,function(m){if(m){if(!XR.default.isError(m))return c(m,s);if(t)return m.value=s,c(m,s);g.push(m)}if(--u<=0){if(g.length&&(a&&g.sort(a),o.length&&g.push(...o),o=g),o.length){c(new XR.default(o,s,l),s);return}c(null,s)}})}});var TZ=w((But,LZ)=>{function xMe(r){return function(e,t,i){for(var n=-1,s=Object(e),o=i(e),a=o.length;a--;){var l=o[r?a:++n];if(t(s[l],l,s)===!1)break}return e}}LZ.exports=xMe});var ZR=w((but,OZ)=>{var PMe=TZ(),DMe=PMe();OZ.exports=DMe});var UZ=w((Qut,MZ)=>{function RMe(r,e){for(var t=-1,i=Array(r);++t<r;)i[t]=e(t);return i}MZ.exports=RMe});var HZ=w((Sut,KZ)=>{function FMe(){return!1}KZ.exports=FMe});var QC=w((bC,Mf)=>{var NMe=Ts(),LMe=HZ(),jZ=typeof bC=="object"&&bC&&!bC.nodeType&&bC,GZ=jZ&&typeof Mf=="object"&&Mf&&!Mf.nodeType&&Mf,TMe=GZ&&GZ.exports===jZ,YZ=TMe?NMe.Buffer:void 0,OMe=YZ?YZ.isBuffer:void 0,MMe=OMe||LMe;Mf.exports=MMe});var JZ=w((vut,qZ)=>{var UMe=zc(),KMe=t0(),HMe=ra(),jMe="[object Arguments]",GMe="[object Array]",YMe="[object Boolean]",qMe="[object Date]",JMe="[object Error]",WMe="[object Function]",zMe="[object Map]",_Me="[object Number]",VMe="[object Object]",XMe="[object RegExp]",ZMe="[object Set]",$Me="[object String]",e1e="[object WeakMap]",t1e="[object ArrayBuffer]",r1e="[object DataView]",i1e="[object Float32Array]",n1e="[object Float64Array]",s1e="[object Int8Array]",o1e="[object Int16Array]",a1e="[object Int32Array]",A1e="[object Uint8Array]",l1e="[object Uint8ClampedArray]",c1e="[object Uint16Array]",u1e="[object Uint32Array]",wr={};wr[i1e]=wr[n1e]=wr[s1e]=wr[o1e]=wr[a1e]=wr[A1e]=wr[l1e]=wr[c1e]=wr[u1e]=!0;wr[jMe]=wr[GMe]=wr[t1e]=wr[YMe]=wr[r1e]=wr[qMe]=wr[JMe]=wr[WMe]=wr[zMe]=wr[_Me]=wr[VMe]=wr[XMe]=wr[ZMe]=wr[$Me]=wr[e1e]=!1;function g1e(r){return HMe(r)&&KMe(r.length)&&!!wr[UMe(r)]}qZ.exports=g1e});var u0=w((kut,WZ)=>{function f1e(r){return function(e){return r(e)}}WZ.exports=f1e});var g0=w((SC,Uf)=>{var h1e=ix(),zZ=typeof SC=="object"&&SC&&!SC.nodeType&&SC,vC=zZ&&typeof Uf=="object"&&Uf&&!Uf.nodeType&&Uf,p1e=vC&&vC.exports===zZ,$R=p1e&&h1e.process,d1e=function(){try{var r=vC&&vC.require&&vC.require("util").types;return r||$R&&$R.binding&&$R.binding("util")}catch(e){}}();Uf.exports=d1e});var f0=w((xut,_Z)=>{var C1e=JZ(),m1e=u0(),VZ=g0(),XZ=VZ&&VZ.isTypedArray,E1e=XZ?m1e(XZ):C1e;_Z.exports=E1e});var eF=w((Put,ZZ)=>{var I1e=UZ(),y1e=CC(),w1e=Hs(),B1e=QC(),b1e=dC(),Q1e=f0(),S1e=Object.prototype,v1e=S1e.hasOwnProperty;function k1e(r,e){var t=w1e(r),i=!t&&y1e(r),n=!t&&!i&&B1e(r),s=!t&&!i&&!n&&Q1e(r),o=t||i||n||s,a=o?I1e(r.length,String):[],l=a.length;for(var c in r)(e||v1e.call(r,c))&&!(o&&(c=="length"||n&&(c=="offset"||c=="parent")||s&&(c=="buffer"||c=="byteLength"||c=="byteOffset")||b1e(c,l)))&&a.push(c);return a}ZZ.exports=k1e});var h0=w((Dut,$Z)=>{var x1e=Object.prototype;function P1e(r){var e=r&&r.constructor,t=typeof e=="function"&&e.prototype||x1e;return r===t}$Z.exports=P1e});var tF=w((Rut,e$)=>{function D1e(r,e){return function(t){return r(e(t))}}e$.exports=D1e});var r$=w((Fut,t$)=>{var R1e=tF(),F1e=R1e(Object.keys,Object);t$.exports=F1e});var n$=w((Nut,i$)=>{var N1e=h0(),L1e=r$(),T1e=Object.prototype,O1e=T1e.hasOwnProperty;function M1e(r){if(!N1e(r))return L1e(r);var e=[];for(var t in Object(r))O1e.call(r,t)&&t!="constructor"&&e.push(t);return e}i$.exports=M1e});var kC=w((Lut,s$)=>{var U1e=XB(),K1e=t0();function H1e(r){return r!=null&&K1e(r.length)&&!U1e(r)}s$.exports=H1e});var Kf=w((Tut,o$)=>{var j1e=eF(),G1e=n$(),Y1e=kC();function q1e(r){return Y1e(r)?j1e(r):G1e(r)}o$.exports=q1e});var rF=w((Out,a$)=>{var J1e=ZR(),W1e=Kf();function z1e(r,e){return r&&J1e(r,e,W1e)}a$.exports=z1e});var l$=w((Mut,A$)=>{var _1e=fC();function V1e(){this.__data__=new _1e,this.size=0}A$.exports=V1e});var u$=w((Uut,c$)=>{function X1e(r){var e=this.__data__,t=e.delete(r);return this.size=e.size,t}c$.exports=X1e});var f$=w((Kut,g$)=>{function Z1e(r){return this.__data__.get(r)}g$.exports=Z1e});var p$=w((Hut,h$)=>{function $1e(r){return this.__data__.has(r)}h$.exports=$1e});var C$=w((jut,d$)=>{var eUe=fC(),tUe=ZB(),rUe=$B(),iUe=200;function nUe(r,e){var t=this.__data__;if(t instanceof eUe){var i=t.__data__;if(!tUe||i.length<iUe-1)return i.push([r,e]),this.size=++t.size,this;t=this.__data__=new rUe(i)}return t.set(r,e),this.size=t.size,this}d$.exports=nUe});var xC=w((Gut,m$)=>{var sUe=fC(),oUe=l$(),aUe=u$(),AUe=f$(),lUe=p$(),cUe=C$();function Hf(r){var e=this.__data__=new sUe(r);this.size=e.size}Hf.prototype.clear=oUe;Hf.prototype.delete=aUe;Hf.prototype.get=AUe;Hf.prototype.has=lUe;Hf.prototype.set=cUe;m$.exports=Hf});var I$=w((Yut,E$)=>{var uUe="__lodash_hash_undefined__";function gUe(r){return this.__data__.set(r,uUe),this}E$.exports=gUe});var w$=w((qut,y$)=>{function fUe(r){return this.__data__.has(r)}y$.exports=fUe});var b$=w((Jut,B$)=>{var hUe=$B(),pUe=I$(),dUe=w$();function p0(r){var e=-1,t=r==null?0:r.length;for(this.__data__=new hUe;++e<t;)this.add(r[e])}p0.prototype.add=p0.prototype.push=pUe;p0.prototype.has=dUe;B$.exports=p0});var S$=w((Wut,Q$)=>{function CUe(r,e){for(var t=-1,i=r==null?0:r.length;++t<i;)if(e(r[t],t,r))return!0;return!1}Q$.exports=CUe});var k$=w((zut,v$)=>{function mUe(r,e){return r.has(e)}v$.exports=mUe});var iF=w((_ut,x$)=>{var EUe=b$(),IUe=S$(),yUe=k$(),wUe=1,BUe=2;function bUe(r,e,t,i,n,s){var o=t&wUe,a=r.length,l=e.length;if(a!=l&&!(o&&l>a))return!1;var c=s.get(r),u=s.get(e);if(c&&u)return c==e&&u==r;var g=-1,f=!0,h=t&BUe?new EUe:void 0;for(s.set(r,e),s.set(e,r);++g<a;){var p=r[g],m=e[g];if(i)var y=o?i(m,p,g,e,r,s):i(p,m,g,r,e,s);if(y!==void 0){if(y)continue;f=!1;break}if(h){if(!IUe(e,function(b,v){if(!yUe(h,v)&&(p===b||n(p,b,t,i,s)))return h.push(v)})){f=!1;break}}else if(!(p===m||n(p,m,t,i,s))){f=!1;break}}return s.delete(r),s.delete(e),f}x$.exports=bUe});var nF=w((Vut,P$)=>{var QUe=Ts(),SUe=QUe.Uint8Array;P$.exports=SUe});var R$=w((Xut,D$)=>{function vUe(r){var e=-1,t=Array(r.size);return r.forEach(function(i,n){t[++e]=[n,i]}),t}D$.exports=vUe});var N$=w((Zut,F$)=>{function kUe(r){var e=-1,t=Array(r.size);return r.forEach(function(i){t[++e]=i}),t}F$.exports=kUe});var U$=w(($ut,L$)=>{var T$=Wc(),O$=nF(),xUe=Df(),PUe=iF(),DUe=R$(),RUe=N$(),FUe=1,NUe=2,LUe="[object Boolean]",TUe="[object Date]",OUe="[object Error]",MUe="[object Map]",UUe="[object Number]",KUe="[object RegExp]",HUe="[object Set]",jUe="[object String]",GUe="[object Symbol]",YUe="[object ArrayBuffer]",qUe="[object DataView]",M$=T$?T$.prototype:void 0,sF=M$?M$.valueOf:void 0;function JUe(r,e,t,i,n,s,o){switch(t){case qUe:if(r.byteLength!=e.byteLength||r.byteOffset!=e.byteOffset)return!1;r=r.buffer,e=e.buffer;case YUe:return!(r.byteLength!=e.byteLength||!s(new O$(r),new O$(e)));case LUe:case TUe:case UUe:return xUe(+r,+e);case OUe:return r.name==e.name&&r.message==e.message;case KUe:case jUe:return r==e+"";case MUe:var a=DUe;case HUe:var l=i&FUe;if(a||(a=RUe),r.size!=e.size&&!l)return!1;var c=o.get(r);if(c)return c==e;i|=NUe,o.set(r,e);var u=PUe(a(r),a(e),i,n,s,o);return o.delete(r),u;case GUe:if(sF)return sF.call(r)==sF.call(e)}return!1}L$.exports=JUe});var oF=w((egt,K$)=>{var WUe=r0(),zUe=Hs();function _Ue(r,e,t){var i=e(r);return zUe(r)?i:WUe(i,t(r))}K$.exports=_Ue});var j$=w((tgt,H$)=>{function VUe(r,e){for(var t=-1,i=r==null?0:r.length,n=0,s=[];++t<i;){var o=r[t];e(o,t,r)&&(s[n++]=o)}return s}H$.exports=VUe});var aF=w((rgt,G$)=>{function XUe(){return[]}G$.exports=XUe});var d0=w((igt,Y$)=>{var ZUe=j$(),$Ue=aF(),eKe=Object.prototype,tKe=eKe.propertyIsEnumerable,q$=Object.getOwnPropertySymbols,rKe=q$?function(r){return r==null?[]:(r=Object(r),ZUe(q$(r),function(e){return tKe.call(r,e)}))}:$Ue;Y$.exports=rKe});var AF=w((ngt,J$)=>{var iKe=oF(),nKe=d0(),sKe=Kf();function oKe(r){return iKe(r,sKe,nKe)}J$.exports=oKe});var _$=w((sgt,W$)=>{var z$=AF(),aKe=1,AKe=Object.prototype,lKe=AKe.hasOwnProperty;function cKe(r,e,t,i,n,s){var o=t&aKe,a=z$(r),l=a.length,c=z$(e),u=c.length;if(l!=u&&!o)return!1;for(var g=l;g--;){var f=a[g];if(!(o?f in e:lKe.call(e,f)))return!1}var h=s.get(r),p=s.get(e);if(h&&p)return h==e&&p==r;var m=!0;s.set(r,e),s.set(e,r);for(var y=o;++g<l;){f=a[g];var b=r[f],v=e[f];if(i)var k=o?i(v,b,f,e,r,s):i(b,v,f,r,e,s);if(!(k===void 0?b===v||n(b,v,t,i,s):k)){m=!1;break}y||(y=f=="constructor")}if(m&&!y){var T=r.constructor,Y=e.constructor;T!=Y&&"constructor"in r&&"constructor"in e&&!(typeof T=="function"&&T instanceof T&&typeof Y=="function"&&Y instanceof Y)&&(m=!1)}return s.delete(r),s.delete(e),m}W$.exports=cKe});var X$=w((ogt,V$)=>{var uKe=Fl(),gKe=Ts(),fKe=uKe(gKe,"DataView");V$.exports=fKe});var $$=w((agt,Z$)=>{var hKe=Fl(),pKe=Ts(),dKe=hKe(pKe,"Promise");Z$.exports=dKe});var tee=w((Agt,eee)=>{var CKe=Fl(),mKe=Ts(),EKe=CKe(mKe,"Set");eee.exports=EKe});var iee=w((lgt,ree)=>{var IKe=Fl(),yKe=Ts(),wKe=IKe(yKe,"WeakMap");ree.exports=wKe});var PC=w((cgt,nee)=>{var lF=X$(),cF=ZB(),uF=$$(),gF=tee(),fF=iee(),see=zc(),jf=vR(),oee="[object Map]",BKe="[object Object]",aee="[object Promise]",Aee="[object Set]",lee="[object WeakMap]",cee="[object DataView]",bKe=jf(lF),QKe=jf(cF),SKe=jf(uF),vKe=jf(gF),kKe=jf(fF),pu=see;(lF&&pu(new lF(new ArrayBuffer(1)))!=cee||cF&&pu(new cF)!=oee||uF&&pu(uF.resolve())!=aee||gF&&pu(new gF)!=Aee||fF&&pu(new fF)!=lee)&&(pu=function(r){var e=see(r),t=e==BKe?r.constructor:void 0,i=t?jf(t):"";if(i)switch(i){case bKe:return cee;case QKe:return oee;case SKe:return aee;case vKe:return Aee;case kKe:return lee}return e});nee.exports=pu});var mee=w((ugt,uee)=>{var hF=xC(),xKe=iF(),PKe=U$(),DKe=_$(),gee=PC(),fee=Hs(),hee=QC(),RKe=f0(),FKe=1,pee="[object Arguments]",dee="[object Array]",C0="[object Object]",NKe=Object.prototype,Cee=NKe.hasOwnProperty;function LKe(r,e,t,i,n,s){var o=fee(r),a=fee(e),l=o?dee:gee(r),c=a?dee:gee(e);l=l==pee?C0:l,c=c==pee?C0:c;var u=l==C0,g=c==C0,f=l==c;if(f&&hee(r)){if(!hee(e))return!1;o=!0,u=!1}if(f&&!u)return s||(s=new hF),o||RKe(r)?xKe(r,e,t,i,n,s):PKe(r,e,l,t,i,n,s);if(!(t&FKe)){var h=u&&Cee.call(r,"__wrapped__"),p=g&&Cee.call(e,"__wrapped__");if(h||p){var m=h?r.value():r,y=p?e.value():e;return s||(s=new hF),n(m,y,t,i,s)}}return f?(s||(s=new hF),DKe(r,e,t,i,n,s)):!1}uee.exports=LKe});var pF=w((ggt,Eee)=>{var TKe=mee(),Iee=ra();function yee(r,e,t,i,n){return r===e?!0:r==null||e==null||!Iee(r)&&!Iee(e)?r!==r&&e!==e:TKe(r,e,t,i,yee,n)}Eee.exports=yee});var Bee=w((fgt,wee)=>{var OKe=xC(),MKe=pF(),UKe=1,KKe=2;function HKe(r,e,t,i){var n=t.length,s=n,o=!i;if(r==null)return!s;for(r=Object(r);n--;){var a=t[n];if(o&&a[2]?a[1]!==r[a[0]]:!(a[0]in r))return!1}for(;++n<s;){a=t[n];var l=a[0],c=r[l],u=a[1];if(o&&a[2]){if(c===void 0&&!(l in r))return!1}else{var g=new OKe;if(i)var f=i(c,u,l,r,e,g);if(!(f===void 0?MKe(u,c,UKe|KKe,i,g):f))return!1}}return!0}wee.exports=HKe});var dF=w((hgt,bee)=>{var jKe=Fn();function GKe(r){return r===r&&!jKe(r)}bee.exports=GKe});var See=w((pgt,Qee)=>{var YKe=dF(),qKe=Kf();function JKe(r){for(var e=qKe(r),t=e.length;t--;){var i=e[t],n=r[i];e[t]=[i,n,YKe(n)]}return e}Qee.exports=JKe});var CF=w((dgt,vee)=>{function WKe(r,e){return function(t){return t==null?!1:t[r]===e&&(e!==void 0||r in Object(t))}}vee.exports=WKe});var xee=w((Cgt,kee)=>{var zKe=Bee(),_Ke=See(),VKe=CF();function XKe(r){var e=_Ke(r);return e.length==1&&e[0][2]?VKe(e[0][0],e[0][1]):function(t){return t===r||zKe(t,r,e)}}kee.exports=XKe});var m0=w((mgt,Pee)=>{var ZKe=pC();function $Ke(r,e,t){var i=r==null?void 0:ZKe(r,e);return i===void 0?t:i}Pee.exports=$Ke});var Ree=w((Egt,Dee)=>{var e2e=pF(),t2e=m0(),r2e=RR(),i2e=VB(),n2e=dF(),s2e=CF(),o2e=fu(),a2e=1,A2e=2;function l2e(r,e){return i2e(r)&&n2e(e)?s2e(o2e(r),e):function(t){var i=t2e(t,r);return i===void 0&&i===e?r2e(t,r):e2e(e,i,a2e|A2e)}}Dee.exports=l2e});var Nee=w((Igt,Fee)=>{function c2e(r){return function(e){return e==null?void 0:e[r]}}Fee.exports=c2e});var Tee=w((ygt,Lee)=>{var u2e=pC();function g2e(r){return function(e){return u2e(e,r)}}Lee.exports=g2e});var Mee=w((wgt,Oee)=>{var f2e=Nee(),h2e=Tee(),p2e=VB(),d2e=fu();function C2e(r){return p2e(r)?f2e(d2e(r)):h2e(r)}Oee.exports=C2e});var mF=w((Bgt,Uee)=>{var m2e=xee(),E2e=Ree(),I2e=i0(),y2e=Hs(),w2e=Mee();function B2e(r){return typeof r=="function"?r:r==null?I2e:typeof r=="object"?y2e(r)?E2e(r[0],r[1]):m2e(r):w2e(r)}Uee.exports=B2e});var EF=w((bgt,Kee)=>{var b2e=Lf(),Q2e=rF(),S2e=mF();function v2e(r,e){var t={};return e=S2e(e,3),Q2e(r,function(i,n,s){b2e(t,n,e(i,n,s))}),t}Kee.exports=v2e});var DC=w((Qgt,Hee)=>{"use strict";function du(r){this._maxSize=r,this.clear()}du.prototype.clear=function(){this._size=0,this._values=Object.create(null)};du.prototype.get=function(r){return this._values[r]};du.prototype.set=function(r,e){return this._size>=this._maxSize&&this.clear(),r in this._values||this._size++,this._values[r]=e};var k2e=/[^.^\]^[]+|(?=\[\]|\.\.)/g,jee=/^\d+$/,x2e=/^\d/,P2e=/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,D2e=/^\s*(['"]?)(.*?)(\1)\s*$/,IF=512,Gee=new du(IF),Yee=new du(IF),qee=new du(IF);Hee.exports={Cache:du,split:wF,normalizePath:yF,setter:function(r){var e=yF(r);return Yee.get(r)||Yee.set(r,function(i,n){for(var s=0,o=e.length,a=i;s<o-1;){var l=e[s];if(l==="__proto__"||l==="constructor"||l==="prototype")return i;a=a[e[s++]]}a[e[s]]=n})},getter:function(r,e){var t=yF(r);return qee.get(r)||qee.set(r,function(n){for(var s=0,o=t.length;s<o;)if(n!=null||!e)n=n[t[s++]];else return;return n})},join:function(r){return r.reduce(function(e,t){return e+(BF(t)||jee.test(t)?"["+t+"]":(e?".":"")+t)},"")},forEach:function(r,e,t){R2e(Array.isArray(r)?r:wF(r),e,t)}};function yF(r){return Gee.get(r)||Gee.set(r,wF(r).map(function(e){return e.replace(D2e,"$2")}))}function wF(r){return r.match(k2e)}function R2e(r,e,t){var i=r.length,n,s,o,a;for(s=0;s<i;s++)n=r[s],n&&(F2e(n)&&(n='"'+n+'"'),a=BF(n),o=!a&&/^\d+$/.test(n),e.call(t,n,a,o,s,r))}function BF(r){return typeof r=="string"&&r&&["'",'"'].indexOf(r.charAt(0))!==-1}function N2e(r){return r.match(x2e)&&!r.match(jee)}function L2e(r){return P2e.test(r)}function F2e(r){return!BF(r)&&(N2e(r)||L2e(r))}});var Cu=w(RC=>{"use strict";Object.defineProperty(RC,"__esModule",{value:!0});RC.create=T2e;RC.default=void 0;var O2e=DC(),E0={context:"$",value:"."};function T2e(r,e){return new I0(r,e)}var I0=class{constructor(e,t={}){if(typeof e!="string")throw new TypeError("ref must be a string, got: "+e);if(this.key=e.trim(),e==="")throw new TypeError("ref must be a non-empty string");this.isContext=this.key[0]===E0.context,this.isValue=this.key[0]===E0.value,this.isSibling=!this.isContext&&!this.isValue;let i=this.isContext?E0.context:this.isValue?E0.value:"";this.path=this.key.slice(i.length),this.getter=this.path&&(0,O2e.getter)(this.path,!0),this.map=t.map}getValue(e,t,i){let n=this.isContext?i:this.isValue?e:t;return this.getter&&(n=this.getter(n||{})),this.map&&(n=this.map(n)),n}cast(e,t){return this.getValue(e,t==null?void 0:t.parent,t==null?void 0:t.context)}resolve(){return this}describe(){return{type:"ref",key:this.key}}toString(){return`Ref(${this.key})`}static isRef(e){return e&&e.__isYupRef}};RC.default=I0;I0.prototype.__isYupRef=!0});var Jee=w(bF=>{"use strict";Object.defineProperty(bF,"__esModule",{value:!0});bF.default=M2e;var U2e=QF(EF()),y0=QF(hu()),K2e=QF(Cu());function QF(r){return r&&r.__esModule?r:{default:r}}function w0(){return w0=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},w0.apply(this,arguments)}function H2e(r,e){if(r==null)return{};var t={},i=Object.keys(r),n,s;for(s=0;s<i.length;s++)n=i[s],!(e.indexOf(n)>=0)&&(t[n]=r[n]);return t}function M2e(r){function e(t,i){let{value:n,path:s="",label:o,options:a,originalValue:l,sync:c}=t,u=H2e(t,["value","path","label","options","originalValue","sync"]),{name:g,test:f,params:h,message:p}=r,{parent:m,context:y}=a;function b(q){return K2e.default.isRef(q)?q.getValue(n,m,y):q}function v(q={}){let $=(0,U2e.default)(w0({value:n,originalValue:l,label:o,path:q.path||s},h,q.params),b),z=new y0.default(y0.default.formatError(q.message||p,$),n,$.path,q.type||g);return z.params=$,z}let k=w0({path:s,parent:m,type:g,createError:v,resolve:b,options:a,originalValue:l},u);if(!c){try{Promise.resolve(f.call(k,n,k)).then(q=>{y0.default.isError(q)?i(q):q?i(null,q):i(v())})}catch(q){i(q)}return}let T;try{var Y;if(T=f.call(k,n,k),typeof((Y=T)==null?void 0:Y.then)=="function")throw new Error(`Validation test of type: "${k.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(q){i(q);return}y0.default.isError(T)?i(T):T?i(null,T):i(v())}return e.OPTIONS=r,e}});var SF=w(FC=>{"use strict";Object.defineProperty(FC,"__esModule",{value:!0});FC.getIn=Wee;FC.default=void 0;var j2e=DC(),G2e=r=>r.substr(0,r.length-1).substr(1);function Wee(r,e,t,i=t){let n,s,o;return e?((0,j2e.forEach)(e,(a,l,c)=>{let u=l?G2e(a):a;if(r=r.resolve({context:i,parent:n,value:t}),r.innerType){let g=c?parseInt(u,10):0;if(t&&g>=t.length)throw new Error(`Yup.reach cannot resolve an array item at index: ${a}, in the path: ${e}. because there is no value at that index. `);n=t,t=t&&t[g],r=r.innerType}if(!c){if(!r.fields||!r.fields[u])throw new Error(`The schema does not contain the path: ${e}. (failed at: ${o} which is a type: "${r._type}")`);n=t,t=t&&t[u],r=r.fields[u]}s=u,o=l?"["+a+"]":"."+a}),{schema:r,parent:n,parentPath:s}):{parent:n,parentPath:e,schema:r}}var Y2e=(r,e,t,i)=>Wee(r,e,t,i).schema,q2e=Y2e;FC.default=q2e});var _ee=w(B0=>{"use strict";Object.defineProperty(B0,"__esModule",{value:!0});B0.default=void 0;var zee=J2e(Cu());function J2e(r){return r&&r.__esModule?r:{default:r}}var b0=class{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,t]of this.refs)e.push(t.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){zee.default.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){zee.default.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let i,n=this.refs.values();for(;i=n.next(),!i.done;)if(t(i.value)===e)return!0;return!1}clone(){let e=new b0;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let i=this.clone();return e.list.forEach(n=>i.add(n)),e.refs.forEach(n=>i.add(n)),t.list.forEach(n=>i.delete(n)),t.refs.forEach(n=>i.delete(n)),i}};B0.default=b0});var IA=w(Q0=>{"use strict";Object.defineProperty(Q0,"__esModule",{value:!0});Q0.default=void 0;var Vee=EA(mZ()),Gf=mA(),W2e=EA(FZ()),Xee=EA(c0()),S0=EA(Jee()),Zee=EA(yC()),z2e=EA(Cu()),_2e=SF(),V2e=EA(zR()),$ee=EA(hu()),ete=EA(_ee());function EA(r){return r&&r.__esModule?r:{default:r}}function zs(){return zs=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},zs.apply(this,arguments)}var ga=class{constructor(e){this.deps=[],this.conditions=[],this._whitelist=new ete.default,this._blacklist=new ete.default,this.exclusiveTests=Object.create(null),this.tests=[],this.transforms=[],this.withMutation(()=>{this.typeError(Gf.mixed.notType)}),this.type=(e==null?void 0:e.type)||"mixed",this.spec=zs({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},e==null?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=zs({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=(0,Vee.default)(zs({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(e.length===0)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let i=e(this);return this._mutate=t,i}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&this.type!=="mixed")throw new TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,i=e.clone(),n=zs({},t.spec,i.spec);return i.spec=n,i._typeError||(i._typeError=t._typeError),i._whitelistError||(i._whitelistError=t._whitelistError),i._blacklistError||(i._blacklistError=t._blacklistError),i._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),i._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),i.tests=t.tests,i.exclusiveTests=t.exclusiveTests,i.withMutation(s=>{e.tests.forEach(o=>{s.test(o.OPTIONS)})}),i}isType(e){return this.spec.nullable&&e===null?!0:this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let i=t.conditions;t=t.clone(),t.conditions=[],t=i.reduce((n,s)=>s.resolve(n,e),t),t=t.resolve(e)}return t}cast(e,t={}){let i=this.resolve(zs({value:e},t)),n=i._cast(e,t);if(e!==void 0&&t.assert!==!1&&i.isType(n)!==!0){let s=(0,Zee.default)(e),o=(0,Zee.default)(n);throw new TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${i._type}". - -attempted value: ${s} -`+(o!==s?`result of cast: ${o}`:""))}return n}_cast(e,t){let i=e===void 0?e:this.transforms.reduce((n,s)=>s.call(this,n,e,this),e);return i===void 0&&(i=this.getDefault()),i}_validate(e,t={},i){let{sync:n,path:s,from:o=[],originalValue:a=e,strict:l=this.spec.strict,abortEarly:c=this.spec.abortEarly}=t,u=e;l||(u=this._cast(u,zs({assert:!1},t)));let g={value:u,path:s,options:t,originalValue:a,schema:this,label:this.spec.label,sync:n,from:o},f=[];this._typeError&&f.push(this._typeError),this._whitelistError&&f.push(this._whitelistError),this._blacklistError&&f.push(this._blacklistError),(0,Xee.default)({args:g,value:u,path:s,sync:n,tests:f,endEarly:c},h=>{if(h)return void i(h,u);(0,Xee.default)({tests:this.tests,args:g,path:s,sync:n,value:u,endEarly:c},i)})}validate(e,t,i){let n=this.resolve(zs({},t,{value:e}));return typeof i=="function"?n._validate(e,t,i):new Promise((s,o)=>n._validate(e,t,(a,l)=>{a?o(a):s(l)}))}validateSync(e,t){let i=this.resolve(zs({},t,{value:e})),n;return i._validate(e,zs({},t,{sync:!0}),(s,o)=>{if(s)throw s;n=o}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,i=>{if($ee.default.isError(i))return!1;throw i})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(i){if($ee.default.isError(i))return!1;throw i}}_getDefault(){let e=this.spec.default;return e==null?e:typeof e=="function"?e.call(this):(0,Vee.default)(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return arguments.length===0?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return e!=null}defined(e=Gf.mixed.defined){return this.test({message:e,name:"defined",exclusive:!0,test(t){return t!==void 0}})}required(e=Gf.mixed.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(i){return this.schema._isPresent(i)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(t=>t.OPTIONS.name!=="required"),e}nullable(e=!0){var t=this.clone({nullable:e!==!1});return t}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(e.length===1?typeof e[0]=="function"?t={test:e[0]}:t=e[0]:e.length===2?t={name:e[0],test:e[1]}:t={name:e[0],message:e[1],test:e[2]},t.message===void 0&&(t.message=Gf.mixed.default),typeof t.test!="function")throw new TypeError("`test` is a required parameters");let i=this.clone(),n=(0,S0.default)(t),s=t.exclusive||t.name&&i.exclusiveTests[t.name]===!0;if(t.exclusive&&!t.name)throw new TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(i.exclusiveTests[t.name]=!!t.exclusive),i.tests=i.tests.filter(o=>!(o.OPTIONS.name===t.name&&(s||o.OPTIONS.test===n.OPTIONS.test))),i.tests.push(n),i}when(e,t){!Array.isArray(e)&&typeof e!="string"&&(t=e,e=".");let i=this.clone(),n=(0,V2e.default)(e).map(s=>new z2e.default(s));return n.forEach(s=>{s.isSibling&&i.deps.push(s.key)}),i.conditions.push(new W2e.default(n,t)),i}typeError(e){var t=this.clone();return t._typeError=(0,S0.default)({message:e,name:"typeError",test(i){return i!==void 0&&!this.schema.isType(i)?this.createError({params:{type:this.schema._type}}):!0}}),t}oneOf(e,t=Gf.mixed.oneOf){var i=this.clone();return e.forEach(n=>{i._whitelist.add(n),i._blacklist.delete(n)}),i._whitelistError=(0,S0.default)({message:t,name:"oneOf",test(n){if(n===void 0)return!0;let s=this.schema._whitelist;return s.has(n,this.resolve)?!0:this.createError({params:{values:s.toArray().join(", ")}})}}),i}notOneOf(e,t=Gf.mixed.notOneOf){var i=this.clone();return e.forEach(n=>{i._blacklist.add(n),i._whitelist.delete(n)}),i._blacklistError=(0,S0.default)({message:t,name:"notOneOf",test(n){let s=this.schema._blacklist;return s.has(n,this.resolve)?this.createError({params:{values:s.toArray().join(", ")}}):!0}}),i}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:i}=e.spec;return{meta:i,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(s=>({name:s.OPTIONS.name,params:s.OPTIONS.params})).filter((s,o,a)=>a.findIndex(l=>l.name===s.name)===o)}}};Q0.default=ga;ga.prototype.__isYupSchema__=!0;for(let r of["validate","validateSync"])ga.prototype[`${r}At`]=function(e,t,i={}){let{parent:n,parentPath:s,schema:o}=(0,_2e.getIn)(this,e,t,i.context);return o[r](n&&n[s],zs({},i,{parent:n,path:e}))};for(let r of["equals","is"])ga.prototype[r]=ga.prototype.oneOf;for(let r of["not","nope"])ga.prototype[r]=ga.prototype.notOneOf;ga.prototype.optional=ga.prototype.notRequired});var rte=w(NC=>{"use strict";Object.defineProperty(NC,"__esModule",{value:!0});NC.create=tte;NC.default=void 0;var Z2e=X2e(IA());function X2e(r){return r&&r.__esModule?r:{default:r}}var vF=Z2e.default,$2e=vF;NC.default=$2e;function tte(){return new vF}tte.prototype=vF.prototype});var Yf=w(v0=>{"use strict";Object.defineProperty(v0,"__esModule",{value:!0});v0.default=void 0;var eHe=r=>r==null;v0.default=eHe});var ate=w(LC=>{"use strict";Object.defineProperty(LC,"__esModule",{value:!0});LC.create=ite;LC.default=void 0;var tHe=nte(IA()),ste=mA(),ote=nte(Yf());function nte(r){return r&&r.__esModule?r:{default:r}}function ite(){return new k0}var k0=class extends tHe.default{constructor(){super({type:"boolean"});this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),typeof e=="boolean"}isTrue(e=ste.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test(t){return(0,ote.default)(t)||t===!0}})}isFalse(e=ste.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test(t){return(0,ote.default)(t)||t===!1}})}};LC.default=k0;ite.prototype=k0.prototype});var cte=w(TC=>{"use strict";Object.defineProperty(TC,"__esModule",{value:!0});TC.create=Ate;TC.default=void 0;var fa=mA(),yA=lte(Yf()),rHe=lte(IA());function lte(r){return r&&r.__esModule?r:{default:r}}var iHe=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,nHe=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,sHe=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,oHe=r=>(0,yA.default)(r)||r===r.trim(),aHe={}.toString();function Ate(){return new x0}var x0=class extends rHe.default{constructor(){super({type:"string"});this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=e!=null&&e.toString?e.toString():e;return t===aHe?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),typeof e=="string"}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=fa.string.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(i){return(0,yA.default)(i)||i.length===this.resolve(e)}})}min(e,t=fa.string.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,yA.default)(i)||i.length>=this.resolve(e)}})}max(e,t=fa.string.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(i){return(0,yA.default)(i)||i.length<=this.resolve(e)}})}matches(e,t){let i=!1,n,s;return t&&(typeof t=="object"?{excludeEmptyString:i=!1,message:n,name:s}=t:n=t),this.test({name:s||"matches",message:n||fa.string.matches,params:{regex:e},test:o=>(0,yA.default)(o)||o===""&&i||o.search(e)!==-1})}email(e=fa.string.email){return this.matches(iHe,{name:"email",message:e,excludeEmptyString:!0})}url(e=fa.string.url){return this.matches(nHe,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=fa.string.uuid){return this.matches(sHe,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>e===null?"":e)}trim(e=fa.string.trim){return this.transform(t=>t!=null?t.trim():t).test({message:e,name:"trim",test:oHe})}lowercase(e=fa.string.lowercase){return this.transform(t=>(0,yA.default)(t)?t:t.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:t=>(0,yA.default)(t)||t===t.toLowerCase()})}uppercase(e=fa.string.uppercase){return this.transform(t=>(0,yA.default)(t)?t:t.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:t=>(0,yA.default)(t)||t===t.toUpperCase()})}};TC.default=x0;Ate.prototype=x0.prototype});var fte=w(OC=>{"use strict";Object.defineProperty(OC,"__esModule",{value:!0});OC.create=ute;OC.default=void 0;var mu=mA(),Eu=gte(Yf()),AHe=gte(IA());function gte(r){return r&&r.__esModule?r:{default:r}}var lHe=r=>r!=+r;function ute(){return new P0}var P0=class extends AHe.default{constructor(){super({type:"number"});this.withMutation(()=>{this.transform(function(e){let t=e;if(typeof t=="string"){if(t=t.replace(/\s/g,""),t==="")return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),typeof e=="number"&&!lHe(e)}min(e,t=mu.number.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,Eu.default)(i)||i>=this.resolve(e)}})}max(e,t=mu.number.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(i){return(0,Eu.default)(i)||i<=this.resolve(e)}})}lessThan(e,t=mu.number.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(i){return(0,Eu.default)(i)||i<this.resolve(e)}})}moreThan(e,t=mu.number.moreThan){return this.test({message:t,name:"min",exclusive:!0,params:{more:e},test(i){return(0,Eu.default)(i)||i>this.resolve(e)}})}positive(e=mu.number.positive){return this.moreThan(0,e)}negative(e=mu.number.negative){return this.lessThan(0,e)}integer(e=mu.number.integer){return this.test({name:"integer",message:e,test:t=>(0,Eu.default)(t)||Number.isInteger(t)})}truncate(){return this.transform(e=>(0,Eu.default)(e)?e:e|0)}round(e){var t,i=["ceil","floor","round","trunc"];if(e=((t=e)==null?void 0:t.toLowerCase())||"round",e==="trunc")return this.truncate();if(i.indexOf(e.toLowerCase())===-1)throw new TypeError("Only valid options for round() are: "+i.join(", "));return this.transform(n=>(0,Eu.default)(n)?n:Math[e](n))}};OC.default=P0;ute.prototype=P0.prototype});var hte=w(kF=>{"use strict";Object.defineProperty(kF,"__esModule",{value:!0});kF.default=cHe;var uHe=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function cHe(r){var e=[1,4,5,6,7,10,11],t=0,i,n;if(n=uHe.exec(r)){for(var s=0,o;o=e[s];++s)n[o]=+n[o]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(n[8]===void 0||n[8]==="")&&(n[9]===void 0||n[9]==="")?i=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):(n[8]!=="Z"&&n[9]!==void 0&&(t=n[10]*60+n[11],n[9]==="+"&&(t=0-t)),i=Date.UTC(n[1],n[2],n[3],n[4],n[5]+t,n[6],n[7]))}else i=Date.parse?Date.parse(r):NaN;return i}});var Cte=w(MC=>{"use strict";Object.defineProperty(MC,"__esModule",{value:!0});MC.create=xF;MC.default=void 0;var gHe=D0(hte()),pte=mA(),dte=D0(Yf()),fHe=D0(Cu()),hHe=D0(IA());function D0(r){return r&&r.__esModule?r:{default:r}}var PF=new Date(""),pHe=r=>Object.prototype.toString.call(r)==="[object Date]";function xF(){return new UC}var UC=class extends hHe.default{constructor(){super({type:"date"});this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=(0,gHe.default)(e),isNaN(e)?PF:new Date(e))})})}_typeCheck(e){return pHe(e)&&!isNaN(e.getTime())}prepareParam(e,t){let i;if(fHe.default.isRef(e))i=e;else{let n=this.cast(e);if(!this._typeCheck(n))throw new TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);i=n}return i}min(e,t=pte.date.min){let i=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(n){return(0,dte.default)(n)||n>=this.resolve(i)}})}max(e,t=pte.date.max){var i=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(n){return(0,dte.default)(n)||n<=this.resolve(i)}})}};MC.default=UC;UC.INVALID_DATE=PF;xF.prototype=UC.prototype;xF.INVALID_DATE=PF});var Ete=w((Mgt,mte)=>{function dHe(r,e,t,i){var n=-1,s=r==null?0:r.length;for(i&&s&&(t=r[++n]);++n<s;)t=e(t,r[n],n,r);return t}mte.exports=dHe});var yte=w((Ugt,Ite)=>{function CHe(r){return function(e){return r==null?void 0:r[e]}}Ite.exports=CHe});var Bte=w((Kgt,wte)=>{var mHe=yte(),EHe={\u00C0:"A",\u00C1:"A",\u00C2:"A",\u00C3:"A",\u00C4:"A",\u00C5:"A",\u00E0:"a",\u00E1:"a",\u00E2:"a",\u00E3:"a",\u00E4:"a",\u00E5:"a",\u00C7:"C",\u00E7:"c",\u00D0:"D",\u00F0:"d",\u00C8:"E",\u00C9:"E",\u00CA:"E",\u00CB:"E",\u00E8:"e",\u00E9:"e",\u00EA:"e",\u00EB:"e",\u00CC:"I",\u00CD:"I",\u00CE:"I",\u00CF:"I",\u00EC:"i",\u00ED:"i",\u00EE:"i",\u00EF:"i",\u00D1:"N",\u00F1:"n",\u00D2:"O",\u00D3:"O",\u00D4:"O",\u00D5:"O",\u00D6:"O",\u00D8:"O",\u00F2:"o",\u00F3:"o",\u00F4:"o",\u00F5:"o",\u00F6:"o",\u00F8:"o",\u00D9:"U",\u00DA:"U",\u00DB:"U",\u00DC:"U",\u00F9:"u",\u00FA:"u",\u00FB:"u",\u00FC:"u",\u00DD:"Y",\u00FD:"y",\u00FF:"y",\u00C6:"Ae",\u00E6:"ae",\u00DE:"Th",\u00FE:"th",\u00DF:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010A:"C",\u010C:"C",\u0107:"c",\u0109:"c",\u010B:"c",\u010D:"c",\u010E:"D",\u0110:"D",\u010F:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011A:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011B:"e",\u011C:"G",\u011E:"G",\u0120:"G",\u0122:"G",\u011D:"g",\u011F:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012A:"I",\u012C:"I",\u012E:"I",\u0130:"I",\u0129:"i",\u012B:"i",\u012D:"i",\u012F:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013B:"L",\u013D:"L",\u013F:"L",\u0141:"L",\u013A:"l",\u013C:"l",\u013E:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014A:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014B:"n",\u014C:"O",\u014E:"O",\u0150:"O",\u014D:"o",\u014F:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015A:"S",\u015C:"S",\u015E:"S",\u0160:"S",\u015B:"s",\u015D:"s",\u015F:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016A:"U",\u016C:"U",\u016E:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016B:"u",\u016D:"u",\u016F:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017B:"Z",\u017D:"Z",\u017A:"z",\u017C:"z",\u017E:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017F:"s"},IHe=mHe(EHe);wte.exports=IHe});var Qte=w((Hgt,bte)=>{var yHe=Bte(),wHe=cf(),BHe=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,bHe="\\u0300-\\u036f",QHe="\\ufe20-\\ufe2f",SHe="\\u20d0-\\u20ff",vHe=bHe+QHe+SHe,kHe="["+vHe+"]",xHe=RegExp(kHe,"g");function PHe(r){return r=wHe(r),r&&r.replace(BHe,yHe).replace(xHe,"")}bte.exports=PHe});var vte=w((jgt,Ste)=>{var DHe=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;function RHe(r){return r.match(DHe)||[]}Ste.exports=RHe});var xte=w((Ggt,kte)=>{var FHe=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;function NHe(r){return FHe.test(r)}kte.exports=NHe});var zte=w((Ygt,Pte)=>{var Dte="\\ud800-\\udfff",LHe="\\u0300-\\u036f",THe="\\ufe20-\\ufe2f",OHe="\\u20d0-\\u20ff",MHe=LHe+THe+OHe,Rte="\\u2700-\\u27bf",Fte="a-z\\xdf-\\xf6\\xf8-\\xff",UHe="\\xac\\xb1\\xd7\\xf7",KHe="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",HHe="\\u2000-\\u206f",jHe=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Nte="A-Z\\xc0-\\xd6\\xd8-\\xde",GHe="\\ufe0e\\ufe0f",Lte=UHe+KHe+HHe+jHe,Tte="['\u2019]",Ote="["+Lte+"]",YHe="["+MHe+"]",Mte="\\d+",qHe="["+Rte+"]",Ute="["+Fte+"]",Kte="[^"+Dte+Lte+Mte+Rte+Fte+Nte+"]",JHe="\\ud83c[\\udffb-\\udfff]",WHe="(?:"+YHe+"|"+JHe+")",zHe="[^"+Dte+"]",Hte="(?:\\ud83c[\\udde6-\\uddff]){2}",jte="[\\ud800-\\udbff][\\udc00-\\udfff]",qf="["+Nte+"]",_He="\\u200d",Gte="(?:"+Ute+"|"+Kte+")",VHe="(?:"+qf+"|"+Kte+")",Yte="(?:"+Tte+"(?:d|ll|m|re|s|t|ve))?",qte="(?:"+Tte+"(?:D|LL|M|RE|S|T|VE))?",Jte=WHe+"?",Wte="["+GHe+"]?",XHe="(?:"+_He+"(?:"+[zHe,Hte,jte].join("|")+")"+Wte+Jte+")*",ZHe="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",$He="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",eje=Wte+Jte+XHe,tje="(?:"+[qHe,Hte,jte].join("|")+")"+eje,rje=RegExp([qf+"?"+Ute+"+"+Yte+"(?="+[Ote,qf,"$"].join("|")+")",VHe+"+"+qte+"(?="+[Ote,qf+Gte,"$"].join("|")+")",qf+"?"+Gte+"+"+Yte,qf+"+"+qte,$He,ZHe,Mte,tje].join("|"),"g");function ije(r){return r.match(rje)||[]}Pte.exports=ije});var Vte=w((qgt,_te)=>{var nje=vte(),sje=xte(),oje=cf(),aje=zte();function Aje(r,e,t){return r=oje(r),e=t?void 0:e,e===void 0?sje(r)?aje(r):nje(r):r.match(e)||[]}_te.exports=Aje});var DF=w((Jgt,Xte)=>{var lje=Ete(),cje=Qte(),uje=Vte(),gje="['\u2019]",fje=RegExp(gje,"g");function hje(r){return function(e){return lje(uje(cje(e).replace(fje,"")),r,"")}}Xte.exports=hje});var $te=w((Wgt,Zte)=>{var pje=DF(),dje=pje(function(r,e,t){return r+(t?"_":"")+e.toLowerCase()});Zte.exports=dje});var tre=w((zgt,ere)=>{var Cje=$w(),mje=DF(),Eje=mje(function(r,e,t){return e=e.toLowerCase(),r+(t?Cje(e):e)});ere.exports=Eje});var ire=w((_gt,rre)=>{var Ije=Lf(),yje=rF(),wje=mF();function Bje(r,e){var t={};return e=wje(e,3),yje(r,function(i,n,s){Ije(t,e(i,n,s),i)}),t}rre.exports=Bje});var sre=w((Vgt,RF)=>{RF.exports=function(r){return nre(bje(r),r)};RF.exports.array=nre;function nre(r,e){var t=r.length,i=new Array(t),n={},s=t,o=Qje(e),a=Sje(r);for(e.forEach(function(c){if(!a.has(c[0])||!a.has(c[1]))throw new Error("Unknown node. There is an unknown node in the supplied edges.")});s--;)n[s]||l(r[s],s,new Set);return i;function l(c,u,g){if(g.has(c)){var f;try{f=", node was:"+JSON.stringify(c)}catch(m){f=""}throw new Error("Cyclic dependency"+f)}if(!a.has(c))throw new Error("Found unknown node. Make sure to provided all involved nodes. Unknown node: "+JSON.stringify(c));if(!n[u]){n[u]=!0;var h=o.get(c)||new Set;if(h=Array.from(h),u=h.length){g.add(c);do{var p=h[--u];l(p,a.get(p),g)}while(u);g.delete(c)}i[--t]=c}}}function bje(r){for(var e=new Set,t=0,i=r.length;t<i;t++){var n=r[t];e.add(n[0]),e.add(n[1])}return Array.from(e)}function Qje(r){for(var e=new Map,t=0,i=r.length;t<i;t++){var n=r[t];e.has(n[0])||e.set(n[0],new Set),e.has(n[1])||e.set(n[1],new Set),e.get(n[0]).add(n[1])}return e}function Sje(r){for(var e=new Map,t=0,i=r.length;t<i;t++)e.set(r[t],t);return e}});var ore=w(FF=>{"use strict";Object.defineProperty(FF,"__esModule",{value:!0});FF.default=vje;var kje=R0(wC()),xje=R0(sre()),Pje=DC(),Dje=R0(Cu()),Rje=R0(Of());function R0(r){return r&&r.__esModule?r:{default:r}}function vje(r,e=[]){let t=[],i=[];function n(s,o){var a=(0,Pje.split)(s)[0];~i.indexOf(a)||i.push(a),~e.indexOf(`${o}-${a}`)||t.push([o,a])}for(let s in r)if((0,kje.default)(r,s)){let o=r[s];~i.indexOf(s)||i.push(s),Dje.default.isRef(o)&&o.isSibling?n(o.path,s):(0,Rje.default)(o)&&"deps"in o&&o.deps.forEach(a=>n(a,s))}return xje.default.array(i,t).reverse()}});var Are=w(NF=>{"use strict";Object.defineProperty(NF,"__esModule",{value:!0});NF.default=Fje;function are(r,e){let t=Infinity;return r.some((i,n)=>{var s;if(((s=e.path)==null?void 0:s.indexOf(i))!==-1)return t=n,!0}),t}function Fje(r){return(e,t)=>are(r,e)-are(r,t)}});var pre=w(KC=>{"use strict";Object.defineProperty(KC,"__esModule",{value:!0});KC.create=lre;KC.default=void 0;var cre=ha(wC()),ure=ha($te()),Nje=ha(tre()),Lje=ha(ire()),Tje=ha(EF()),Oje=DC(),gre=mA(),Mje=ha(ore()),fre=ha(Are()),Uje=ha(c0()),Kje=ha(hu()),LF=ha(IA());function ha(r){return r&&r.__esModule?r:{default:r}}function Jf(){return Jf=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},Jf.apply(this,arguments)}var hre=r=>Object.prototype.toString.call(r)==="[object Object]";function Hje(r,e){let t=Object.keys(r.fields);return Object.keys(e).filter(i=>t.indexOf(i)===-1)}var jje=(0,fre.default)([]),F0=class extends LF.default{constructor(e){super({type:"object"});this.fields=Object.create(null),this._sortErrors=jje,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(i){if(typeof i=="string")try{i=JSON.parse(i)}catch(n){i=null}return this.isType(i)?i:null}),e&&this.shape(e)})}_typeCheck(e){return hre(e)||typeof e=="function"}_cast(e,t={}){var i;let n=super._cast(e,t);if(n===void 0)return this.getDefault();if(!this._typeCheck(n))return n;let s=this.fields,o=(i=t.stripUnknown)!=null?i:this.spec.noUnknown,a=this._nodes.concat(Object.keys(n).filter(g=>this._nodes.indexOf(g)===-1)),l={},c=Jf({},t,{parent:l,__validating:t.__validating||!1}),u=!1;for(let g of a){let f=s[g],h=(0,cre.default)(n,g);if(f){let p,m=n[g];c.path=(t.path?`${t.path}.`:"")+g,f=f.resolve({value:m,context:t.context,parent:l});let y="spec"in f?f.spec:void 0,b=y==null?void 0:y.strict;if(y==null?void 0:y.strip){u=u||g in n;continue}p=!t.__validating||!b?f.cast(n[g],c):n[g],p!==void 0&&(l[g]=p)}else h&&!o&&(l[g]=n[g]);l[g]!==n[g]&&(u=!0)}return u?l:n}_validate(e,t={},i){let n=[],{sync:s,from:o=[],originalValue:a=e,abortEarly:l=this.spec.abortEarly,recursive:c=this.spec.recursive}=t;o=[{schema:this,value:a},...o],t.__validating=!0,t.originalValue=a,t.from=o,super._validate(e,t,(u,g)=>{if(u){if(!Kje.default.isError(u)||l)return void i(u,g);n.push(u)}if(!c||!hre(g)){i(n[0]||null,g);return}a=a||g;let f=this._nodes.map(h=>(p,m)=>{let y=h.indexOf(".")===-1?(t.path?`${t.path}.`:"")+h:`${t.path||""}["${h}"]`,b=this.fields[h];if(b&&"validate"in b){b.validate(g[h],Jf({},t,{path:y,from:o,strict:!0,parent:g,originalValue:a[h]}),m);return}m(null)});(0,Uje.default)({sync:s,tests:f,value:g,errors:n,endEarly:l,sort:this._sortErrors,path:t.path},i)})}clone(e){let t=super.clone(e);return t.fields=Jf({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),i=t.fields;for(let[n,s]of Object.entries(this.fields)){let o=i[n];o===void 0?i[n]=s:o instanceof LF.default&&s instanceof LF.default&&(i[n]=s.concat(o))}return t.withMutation(()=>t.shape(i))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let i=this.fields[t];e[t]="default"in i?i.getDefault():void 0}),e}_getDefault(){if("default"in this.spec)return super._getDefault();if(!!this._nodes.length)return this.getDefaultFromShape()}shape(e,t=[]){let i=this.clone(),n=Object.assign(i.fields,e);if(i.fields=n,i._sortErrors=(0,fre.default)(Object.keys(n)),t.length){Array.isArray(t[0])||(t=[t]);let s=t.map(([o,a])=>`${o}-${a}`);i._excludedEdges=i._excludedEdges.concat(s)}return i._nodes=(0,Mje.default)(n,i._excludedEdges),i}pick(e){let t={};for(let i of e)this.fields[i]&&(t[i]=this.fields[i]);return this.clone().withMutation(i=>(i.fields={},i.shape(t)))}omit(e){let t=this.clone(),i=t.fields;t.fields={};for(let n of e)delete i[n];return t.withMutation(()=>t.shape(i))}from(e,t,i){let n=(0,Oje.getter)(e,!0);return this.transform(s=>{if(s==null)return s;let o=s;return(0,cre.default)(s,e)&&(o=Jf({},s),i||delete o[e],o[t]=n(s)),o})}noUnknown(e=!0,t=gre.object.noUnknown){typeof e=="string"&&(t=e,e=!0);let i=this.test({name:"noUnknown",exclusive:!0,message:t,test(n){if(n==null)return!0;let s=Hje(this.schema,n);return!e||s.length===0||this.createError({params:{unknown:s.join(", ")}})}});return i.spec.noUnknown=e,i}unknown(e=!0,t=gre.object.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&(0,Lje.default)(t,(i,n)=>e(n)))}camelCase(){return this.transformKeys(Nje.default)}snakeCase(){return this.transformKeys(ure.default)}constantCase(){return this.transformKeys(e=>(0,ure.default)(e).toUpperCase())}describe(){let e=super.describe();return e.fields=(0,Tje.default)(this.fields,t=>t.describe()),e}};KC.default=F0;function lre(r){return new F0(r)}lre.prototype=F0.prototype});var Cre=w(HC=>{"use strict";Object.defineProperty(HC,"__esModule",{value:!0});HC.create=dre;HC.default=void 0;var TF=Wf(Yf()),Gje=Wf(Of()),Yje=Wf(yC()),OF=mA(),qje=Wf(c0()),Jje=Wf(hu()),Wje=Wf(IA());function Wf(r){return r&&r.__esModule?r:{default:r}}function N0(){return N0=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},N0.apply(this,arguments)}function dre(r){return new L0(r)}var L0=class extends Wje.default{constructor(e){super({type:"array"});this.innerType=e,this.withMutation(()=>{this.transform(function(t){if(typeof t=="string")try{t=JSON.parse(t)}catch(i){t=null}return this.isType(t)?t:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let i=super._cast(e,t);if(!this._typeCheck(i)||!this.innerType)return i;let n=!1,s=i.map((o,a)=>{let l=this.innerType.cast(o,N0({},t,{path:`${t.path||""}[${a}]`}));return l!==o&&(n=!0),l});return n?s:i}_validate(e,t={},i){var n,s;let o=[],a=t.sync,l=t.path,c=this.innerType,u=(n=t.abortEarly)!=null?n:this.spec.abortEarly,g=(s=t.recursive)!=null?s:this.spec.recursive,f=t.originalValue!=null?t.originalValue:e;super._validate(e,t,(h,p)=>{if(h){if(!Jje.default.isError(h)||u)return void i(h,p);o.push(h)}if(!g||!c||!this._typeCheck(p)){i(o[0]||null,p);return}f=f||p;let m=new Array(p.length);for(let y=0;y<p.length;y++){let b=p[y],v=`${t.path||""}[${y}]`,k=N0({},t,{path:v,strict:!0,parent:p,index:y,originalValue:f[y]});m[y]=(T,Y)=>c.validate(b,k,Y)}(0,qje.default)({sync:a,path:l,value:p,errors:o,endEarly:u,tests:m},i)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!(0,Gje.default)(e))throw new TypeError("`array.of()` sub-schema must be a valid yup schema not: "+(0,Yje.default)(e));return t.innerType=e,t}length(e,t=OF.array.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(i){return(0,TF.default)(i)||i.length===this.resolve(e)}})}min(e,t){return t=t||OF.array.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,TF.default)(i)||i.length>=this.resolve(e)}})}max(e,t){return t=t||OF.array.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(i){return(0,TF.default)(i)||i.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:t==null?[]:[].concat(t))}compact(e){let t=e?(i,n,s)=>!e(i,n,s):i=>!!i;return this.transform(i=>i!=null?i.filter(t):i)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}};HC.default=L0;dre.prototype=L0.prototype});var mre=w(jC=>{"use strict";Object.defineProperty(jC,"__esModule",{value:!0});jC.create=zje;jC.default=void 0;var Vje=_je(Of());function _je(r){return r&&r.__esModule?r:{default:r}}function zje(r){return new MF(r)}var MF=class{constructor(e){this.type="lazy",this.__isYupSchema__=!0,this._resolve=(t,i={})=>{let n=this.builder(t,i);if(!(0,Vje.default)(n))throw new TypeError("lazy() functions must return a valid schema");return n.resolve(i)},this.builder=e}resolve(e){return this._resolve(e.value,e)}cast(e,t){return this._resolve(e,t).cast(e,t)}validate(e,t,i){return this._resolve(e,t).validate(e,t,i)}validateSync(e,t){return this._resolve(e,t).validateSync(e,t)}validateAt(e,t,i){return this._resolve(t,i).validateAt(e,t,i)}validateSyncAt(e,t,i){return this._resolve(t,i).validateSyncAt(e,t,i)}describe(){return null}isValid(e,t){return this._resolve(e,t).isValid(e,t)}isValidSync(e,t){return this._resolve(e,t).isValidSync(e,t)}},Xje=MF;jC.default=Xje});var Ere=w(UF=>{"use strict";Object.defineProperty(UF,"__esModule",{value:!0});UF.default=Zje;var eGe=$je(mA());function $je(r){return r&&r.__esModule?r:{default:r}}function Zje(r){Object.keys(r).forEach(e=>{Object.keys(r[e]).forEach(t=>{eGe.default[e][t]=r[e][t]})})}});var HF=w(Br=>{"use strict";Object.defineProperty(Br,"__esModule",{value:!0});Br.addMethod=tGe;Object.defineProperty(Br,"MixedSchema",{enumerable:!0,get:function(){return Ire.default}});Object.defineProperty(Br,"mixed",{enumerable:!0,get:function(){return Ire.create}});Object.defineProperty(Br,"BooleanSchema",{enumerable:!0,get:function(){return KF.default}});Object.defineProperty(Br,"bool",{enumerable:!0,get:function(){return KF.create}});Object.defineProperty(Br,"boolean",{enumerable:!0,get:function(){return KF.create}});Object.defineProperty(Br,"StringSchema",{enumerable:!0,get:function(){return yre.default}});Object.defineProperty(Br,"string",{enumerable:!0,get:function(){return yre.create}});Object.defineProperty(Br,"NumberSchema",{enumerable:!0,get:function(){return wre.default}});Object.defineProperty(Br,"number",{enumerable:!0,get:function(){return wre.create}});Object.defineProperty(Br,"DateSchema",{enumerable:!0,get:function(){return Bre.default}});Object.defineProperty(Br,"date",{enumerable:!0,get:function(){return Bre.create}});Object.defineProperty(Br,"ObjectSchema",{enumerable:!0,get:function(){return bre.default}});Object.defineProperty(Br,"object",{enumerable:!0,get:function(){return bre.create}});Object.defineProperty(Br,"ArraySchema",{enumerable:!0,get:function(){return Qre.default}});Object.defineProperty(Br,"array",{enumerable:!0,get:function(){return Qre.create}});Object.defineProperty(Br,"ref",{enumerable:!0,get:function(){return rGe.create}});Object.defineProperty(Br,"lazy",{enumerable:!0,get:function(){return iGe.create}});Object.defineProperty(Br,"ValidationError",{enumerable:!0,get:function(){return nGe.default}});Object.defineProperty(Br,"reach",{enumerable:!0,get:function(){return sGe.default}});Object.defineProperty(Br,"isSchema",{enumerable:!0,get:function(){return Sre.default}});Object.defineProperty(Br,"setLocale",{enumerable:!0,get:function(){return oGe.default}});Object.defineProperty(Br,"BaseSchema",{enumerable:!0,get:function(){return aGe.default}});var Ire=Iu(rte()),KF=Iu(ate()),yre=Iu(cte()),wre=Iu(fte()),Bre=Iu(Cte()),bre=Iu(pre()),Qre=Iu(Cre()),rGe=Cu(),iGe=mre(),nGe=GC(hu()),sGe=GC(SF()),Sre=GC(Of()),oGe=GC(Ere()),aGe=GC(IA());function GC(r){return r&&r.__esModule?r:{default:r}}function vre(){if(typeof WeakMap!="function")return null;var r=new WeakMap;return vre=function(){return r},r}function Iu(r){if(r&&r.__esModule)return r;if(r===null||typeof r!="object"&&typeof r!="function")return{default:r};var e=vre();if(e&&e.has(r))return e.get(r);var t={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var n in r)if(Object.prototype.hasOwnProperty.call(r,n)){var s=i?Object.getOwnPropertyDescriptor(r,n):null;s&&(s.get||s.set)?Object.defineProperty(t,n,s):t[n]=r[n]}return t.default=r,e&&e.set(r,t),t}function tGe(r,e,t){if(!r||!(0,Sre.default)(r.prototype))throw new TypeError("You must provide a yup schema constructor function");if(typeof e!="string")throw new TypeError("A Method name must be provided");if(typeof t!="function")throw new TypeError("Method function must be provided");r.prototype[e]=t}});var Rre=w((dft,qC)=>{"use strict";var cGe=process.env.TERM_PROGRAM==="Hyper",uGe=process.platform==="win32",xre=process.platform==="linux",jF={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},Pre=Object.assign({},jF,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),Dre=Object.assign({},jF,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",question:"?",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:xre?"\u25B8":"\u276F",pointerSmall:xre?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});qC.exports=uGe&&!cGe?Pre:Dre;Reflect.defineProperty(qC.exports,"common",{enumerable:!1,value:jF});Reflect.defineProperty(qC.exports,"windows",{enumerable:!1,value:Pre});Reflect.defineProperty(qC.exports,"other",{enumerable:!1,value:Dre})});var yo=w((Cft,GF)=>{"use strict";var gGe=r=>r!==null&&typeof r=="object"&&!Array.isArray(r),fGe=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,Fre=()=>{let r={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(r.enabled=process.env.FORCE_COLOR!=="0");let e=s=>{let o=s.open=`[${s.codes[0]}m`,a=s.close=`[${s.codes[1]}m`,l=s.regex=new RegExp(`\\u001b\\[${s.codes[1]}m`,"g");return s.wrap=(c,u)=>{c.includes(a)&&(c=c.replace(l,a+o));let g=o+c+a;return u?g.replace(/\r*\n/g,`${a}$&${o}`):g},s},t=(s,o,a)=>typeof s=="function"?s(o):s.wrap(o,a),i=(s,o)=>{if(s===""||s==null)return"";if(r.enabled===!1)return s;if(r.visible===!1)return"";let a=""+s,l=a.includes(` -`),c=o.length;for(c>0&&o.includes("unstyle")&&(o=[...new Set(["unstyle",...o])].reverse());c-- >0;)a=t(r.styles[o[c]],a,l);return a},n=(s,o,a)=>{r.styles[s]=e({name:s,codes:o}),(r.keys[a]||(r.keys[a]=[])).push(s),Reflect.defineProperty(r,s,{configurable:!0,enumerable:!0,set(c){r.alias(s,c)},get(){let c=u=>i(u,c.stack);return Reflect.setPrototypeOf(c,r),c.stack=this.stack?this.stack.concat(s):[s],c}})};return n("reset",[0,0],"modifier"),n("bold",[1,22],"modifier"),n("dim",[2,22],"modifier"),n("italic",[3,23],"modifier"),n("underline",[4,24],"modifier"),n("inverse",[7,27],"modifier"),n("hidden",[8,28],"modifier"),n("strikethrough",[9,29],"modifier"),n("black",[30,39],"color"),n("red",[31,39],"color"),n("green",[32,39],"color"),n("yellow",[33,39],"color"),n("blue",[34,39],"color"),n("magenta",[35,39],"color"),n("cyan",[36,39],"color"),n("white",[37,39],"color"),n("gray",[90,39],"color"),n("grey",[90,39],"color"),n("bgBlack",[40,49],"bg"),n("bgRed",[41,49],"bg"),n("bgGreen",[42,49],"bg"),n("bgYellow",[43,49],"bg"),n("bgBlue",[44,49],"bg"),n("bgMagenta",[45,49],"bg"),n("bgCyan",[46,49],"bg"),n("bgWhite",[47,49],"bg"),n("blackBright",[90,39],"bright"),n("redBright",[91,39],"bright"),n("greenBright",[92,39],"bright"),n("yellowBright",[93,39],"bright"),n("blueBright",[94,39],"bright"),n("magentaBright",[95,39],"bright"),n("cyanBright",[96,39],"bright"),n("whiteBright",[97,39],"bright"),n("bgBlackBright",[100,49],"bgBright"),n("bgRedBright",[101,49],"bgBright"),n("bgGreenBright",[102,49],"bgBright"),n("bgYellowBright",[103,49],"bgBright"),n("bgBlueBright",[104,49],"bgBright"),n("bgMagentaBright",[105,49],"bgBright"),n("bgCyanBright",[106,49],"bgBright"),n("bgWhiteBright",[107,49],"bgBright"),r.ansiRegex=fGe,r.hasColor=r.hasAnsi=s=>(r.ansiRegex.lastIndex=0,typeof s=="string"&&s!==""&&r.ansiRegex.test(s)),r.alias=(s,o)=>{let a=typeof o=="string"?r[o]:o;if(typeof a!="function")throw new TypeError("Expected alias to be the name of an existing color (string) or a function");a.stack||(Reflect.defineProperty(a,"name",{value:s}),r.styles[s]=a,a.stack=[s]),Reflect.defineProperty(r,s,{configurable:!0,enumerable:!0,set(l){r.alias(s,l)},get(){let l=c=>i(c,l.stack);return Reflect.setPrototypeOf(l,r),l.stack=this.stack?this.stack.concat(a.stack):a.stack,l}})},r.theme=s=>{if(!gGe(s))throw new TypeError("Expected theme to be an object");for(let o of Object.keys(s))r.alias(o,s[o]);return r},r.alias("unstyle",s=>typeof s=="string"&&s!==""?(r.ansiRegex.lastIndex=0,s.replace(r.ansiRegex,"")):""),r.alias("noop",s=>s),r.none=r.clear=r.noop,r.stripColor=r.unstyle,r.symbols=Rre(),r.define=n,r};GF.exports=Fre();GF.exports.create=Fre});var Xi=w(Lt=>{"use strict";var hGe=Object.prototype.toString,_s=yo(),Nre=!1,YF=[],Lre={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};Lt.longest=(r,e)=>r.reduce((t,i)=>Math.max(t,e?i[e].length:i.length),0);Lt.hasColor=r=>!!r&&_s.hasColor(r);var O0=Lt.isObject=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);Lt.nativeType=r=>hGe.call(r).slice(8,-1).toLowerCase().replace(/\s/g,"");Lt.isAsyncFn=r=>Lt.nativeType(r)==="asyncfunction";Lt.isPrimitive=r=>r!=null&&typeof r!="object"&&typeof r!="function";Lt.resolve=(r,e,...t)=>typeof e=="function"?e.call(r,...t):e;Lt.scrollDown=(r=[])=>[...r.slice(1),r[0]];Lt.scrollUp=(r=[])=>[r.pop(),...r];Lt.reorder=(r=[])=>{let e=r.slice();return e.sort((t,i)=>t.index>i.index?1:t.index<i.index?-1:0),e};Lt.swap=(r,e,t)=>{let i=r.length,n=t===i?0:t<0?i-1:t,s=r[e];r[e]=r[n],r[n]=s};Lt.width=(r,e=80)=>{let t=r&&r.columns?r.columns:e;return r&&typeof r.getWindowSize=="function"&&(t=r.getWindowSize()[0]),process.platform==="win32"?t-1:t};Lt.height=(r,e=20)=>{let t=r&&r.rows?r.rows:e;return r&&typeof r.getWindowSize=="function"&&(t=r.getWindowSize()[1]),t};Lt.wordWrap=(r,e={})=>{if(!r)return r;typeof e=="number"&&(e={width:e});let{indent:t="",newline:i=` -`+t,width:n=80}=e;n-=((i+t).match(/[^\S\n]/g)||[]).length;let o=`.{1,${n}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,a=r.trim(),l=new RegExp(o,"g"),c=a.match(l)||[];return c=c.map(u=>u.replace(/\n$/,"")),e.padEnd&&(c=c.map(u=>u.padEnd(n," "))),e.padStart&&(c=c.map(u=>u.padStart(n," "))),t+c.join(i)};Lt.unmute=r=>{let e=r.stack.find(i=>_s.keys.color.includes(i));return e?_s[e]:r.stack.find(i=>i.slice(2)==="bg")?_s[e.slice(2)]:i=>i};Lt.pascal=r=>r?r[0].toUpperCase()+r.slice(1):"";Lt.inverse=r=>{if(!r||!r.stack)return r;let e=r.stack.find(i=>_s.keys.color.includes(i));if(e){let i=_s["bg"+Lt.pascal(e)];return i?i.black:r}let t=r.stack.find(i=>i.slice(0,2)==="bg");return t?_s[t.slice(2).toLowerCase()]||r:_s.none};Lt.complement=r=>{if(!r||!r.stack)return r;let e=r.stack.find(i=>_s.keys.color.includes(i)),t=r.stack.find(i=>i.slice(0,2)==="bg");if(e&&!t)return _s[Lre[e]||e];if(t){let i=t.slice(2).toLowerCase(),n=Lre[i];return n&&_s["bg"+Lt.pascal(n)]||r}return _s.none};Lt.meridiem=r=>{let e=r.getHours(),t=r.getMinutes(),i=e>=12?"pm":"am";e=e%12;let n=e===0?12:e,s=t<10?"0"+t:t;return n+":"+s+" "+i};Lt.set=(r={},e="",t)=>e.split(".").reduce((i,n,s,o)=>{let a=o.length-1>s?i[n]||{}:t;return!Lt.isObject(a)&&s<o.length-1&&(a={}),i[n]=a},r);Lt.get=(r={},e="",t)=>{let i=r[e]==null?e.split(".").reduce((n,s)=>n&&n[s],r):r[e];return i==null?t:i};Lt.mixin=(r,e)=>{if(!O0(r))return e;if(!O0(e))return r;for(let t of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,t);if(i.hasOwnProperty("value"))if(r.hasOwnProperty(t)&&O0(i.value)){let n=Object.getOwnPropertyDescriptor(r,t);O0(n.value)?r[t]=Lt.merge({},r[t],e[t]):Reflect.defineProperty(r,t,i)}else Reflect.defineProperty(r,t,i);else Reflect.defineProperty(r,t,i)}return r};Lt.merge=(...r)=>{let e={};for(let t of r)Lt.mixin(e,t);return e};Lt.mixinEmitter=(r,e)=>{let t=e.constructor.prototype;for(let i of Object.keys(t)){let n=t[i];typeof n=="function"?Lt.define(r,i,n.bind(e)):Lt.define(r,i,n)}};Lt.onExit=r=>{let e=(t,i)=>{Nre||(Nre=!0,YF.forEach(n=>n()),t===!0&&process.exit(128+i))};YF.length===0&&(process.once("SIGTERM",e.bind(null,!0,15)),process.once("SIGINT",e.bind(null,!0,2)),process.once("exit",e)),YF.push(r)};Lt.define=(r,e,t)=>{Reflect.defineProperty(r,e,{value:t})};Lt.defineExport=(r,e,t)=>{let i;Reflect.defineProperty(r,e,{enumerable:!0,configurable:!0,set(n){i=n},get(){return i?i():t()}})}});var Tre=w(_f=>{"use strict";_f.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};_f.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};_f.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};_f.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};_f.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var Ure=w((Ift,Ore)=>{"use strict";var Mre=require("readline"),pGe=Tre(),dGe=/^(?:\x1b)([a-zA-Z0-9])$/,CGe=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,mGe={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function EGe(r){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(r)}function IGe(r){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(r)}var M0=(r="",e={})=>{let t,i=N({name:e.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:r,raw:r},e);if(Buffer.isBuffer(r)?r[0]>127&&r[1]===void 0?(r[0]-=128,r=""+String(r)):r=String(r):r!==void 0&&typeof r!="string"?r=String(r):r||(r=i.sequence||""),i.sequence=i.sequence||r||i.name,r==="\r")i.raw=void 0,i.name="return";else if(r===` -`)i.name="enter";else if(r===" ")i.name="tab";else if(r==="\b"||r==="\x7F"||r==="\x7F"||r==="\b")i.name="backspace",i.meta=r.charAt(0)==="";else if(r===""||r==="")i.name="escape",i.meta=r.length===2;else if(r===" "||r===" ")i.name="space",i.meta=r.length===2;else if(r<="")i.name=String.fromCharCode(r.charCodeAt(0)+"a".charCodeAt(0)-1),i.ctrl=!0;else if(r.length===1&&r>="0"&&r<="9")i.name="number";else if(r.length===1&&r>="a"&&r<="z")i.name=r;else if(r.length===1&&r>="A"&&r<="Z")i.name=r.toLowerCase(),i.shift=!0;else if(t=dGe.exec(r))i.meta=!0,i.shift=/^[A-Z]$/.test(t[1]);else if(t=CGe.exec(r)){let n=[...r];n[0]===""&&n[1]===""&&(i.option=!0);let s=[t[1],t[2],t[4],t[6]].filter(Boolean).join(""),o=(t[3]||t[5]||1)-1;i.ctrl=!!(o&4),i.meta=!!(o&10),i.shift=!!(o&1),i.code=s,i.name=mGe[s],i.shift=EGe(s)||i.shift,i.ctrl=IGe(s)||i.ctrl}return i};M0.listen=(r={},e)=>{let{stdin:t}=r;if(!t||t!==process.stdin&&!t.isTTY)throw new Error("Invalid stream passed");let i=Mre.createInterface({terminal:!0,input:t});Mre.emitKeypressEvents(t,i);let n=(a,l)=>e(a,M0(a,l),i),s=t.isRaw;return t.isTTY&&t.setRawMode(!0),t.on("keypress",n),i.resume(),()=>{t.isTTY&&t.setRawMode(s),t.removeListener("keypress",n),i.pause(),i.close()}};M0.action=(r,e,t)=>{let i=N(N({},pGe),t);return e.ctrl?(e.action=i.ctrl[e.name],e):e.option&&i.option?(e.action=i.option[e.name],e):e.shift?(e.action=i.shift[e.name],e):(e.action=i.keys[e.name],e)};Ore.exports=M0});var Hre=w((yft,Kre)=>{"use strict";Kre.exports=r=>{r.timers=r.timers||{};let e=r.options.timers;if(!!e)for(let t of Object.keys(e)){let i=e[t];typeof i=="number"&&(i={interval:i}),yGe(r,t,i)}};function yGe(r,e,t={}){let i=r.timers[e]={name:e,start:Date.now(),ms:0,tick:0},n=t.interval||120;i.frames=t.frames||[],i.loading=!0;let s=setInterval(()=>{i.ms=Date.now()-i.start,i.tick++,r.render()},n);return i.stop=()=>{i.loading=!1,clearInterval(s)},Reflect.defineProperty(i,"interval",{value:s}),r.once("close",()=>i.stop()),i.stop}});var Yre=w((wft,jre)=>{"use strict";var{define:wGe,width:BGe}=Xi(),Gre=class{constructor(e){let t=e.options;wGe(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=BGe(t.stdout||process.stdout),Object.assign(this,t),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e=N({},this);return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let t=this._color||e[this.status];return typeof t=="function"?t:e.pending}set loading(e){this._loading=e}get loading(){return typeof this._loading=="boolean"?this._loading:this.loadingChoices?"choices":!1}get status(){return this.cancelled?"cancelled":this.submitted?"submitted":"pending"}};jre.exports=Gre});var Jre=w((Bft,qre)=>{"use strict";var qF=Xi(),Ni=yo(),JF={default:Ni.noop,noop:Ni.noop,set inverse(r){this._inverse=r},get inverse(){return this._inverse||qF.inverse(this.primary)},set complement(r){this._complement=r},get complement(){return this._complement||qF.complement(this.primary)},primary:Ni.cyan,success:Ni.green,danger:Ni.magenta,strong:Ni.bold,warning:Ni.yellow,muted:Ni.dim,disabled:Ni.gray,dark:Ni.dim.gray,underline:Ni.underline,set info(r){this._info=r},get info(){return this._info||this.primary},set em(r){this._em=r},get em(){return this._em||this.primary.underline},set heading(r){this._heading=r},get heading(){return this._heading||this.muted.underline},set pending(r){this._pending=r},get pending(){return this._pending||this.primary},set submitted(r){this._submitted=r},get submitted(){return this._submitted||this.success},set cancelled(r){this._cancelled=r},get cancelled(){return this._cancelled||this.danger},set typing(r){this._typing=r},get typing(){return this._typing||this.dim},set placeholder(r){this._placeholder=r},get placeholder(){return this._placeholder||this.primary.dim},set highlight(r){this._highlight=r},get highlight(){return this._highlight||this.inverse}};JF.merge=(r={})=>{r.styles&&typeof r.styles.enabled=="boolean"&&(Ni.enabled=r.styles.enabled),r.styles&&typeof r.styles.visible=="boolean"&&(Ni.visible=r.styles.visible);let e=qF.merge({},JF,r.styles);delete e.merge;for(let t of Object.keys(Ni))e.hasOwnProperty(t)||Reflect.defineProperty(e,t,{get:()=>Ni[t]});for(let t of Object.keys(Ni.styles))e.hasOwnProperty(t)||Reflect.defineProperty(e,t,{get:()=>Ni[t]});return e};qre.exports=JF});var zre=w((bft,Wre)=>{"use strict";var WF=process.platform==="win32",wA=yo(),bGe=Xi(),zF=te(N({},wA.symbols),{upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:wA.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:wA.symbols.question,submitted:wA.symbols.check,cancelled:wA.symbols.cross},separator:{pending:wA.symbols.pointerSmall,submitted:wA.symbols.middot,cancelled:wA.symbols.middot},radio:{off:WF?"( )":"\u25EF",on:WF?"(*)":"\u25C9",disabled:WF?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]});zF.merge=r=>{let e=bGe.merge({},wA.symbols,zF,r.symbols);return delete e.merge,e};Wre.exports=zF});var Vre=w((Qft,_re)=>{"use strict";var QGe=Jre(),SGe=zre(),vGe=Xi();_re.exports=r=>{r.options=vGe.merge({},r.options.theme,r.options),r.symbols=SGe.merge(r.options),r.styles=QGe.merge(r.options)}});var tie=w((Xre,Zre)=>{"use strict";var $re=process.env.TERM_PROGRAM==="Apple_Terminal",kGe=yo(),_F=Xi(),wo=Zre.exports=Xre,Lr="[",eie="\x07",VF=!1,Nl=wo.code={bell:eie,beep:eie,beginning:`${Lr}G`,down:`${Lr}J`,esc:Lr,getPosition:`${Lr}6n`,hide:`${Lr}?25l`,line:`${Lr}2K`,lineEnd:`${Lr}K`,lineStart:`${Lr}1K`,restorePosition:Lr+($re?"8":"u"),savePosition:Lr+($re?"7":"s"),screen:`${Lr}2J`,show:`${Lr}?25h`,up:`${Lr}1J`},yu=wo.cursor={get hidden(){return VF},hide(){return VF=!0,Nl.hide},show(){return VF=!1,Nl.show},forward:(r=1)=>`${Lr}${r}C`,backward:(r=1)=>`${Lr}${r}D`,nextLine:(r=1)=>`${Lr}E`.repeat(r),prevLine:(r=1)=>`${Lr}F`.repeat(r),up:(r=1)=>r?`${Lr}${r}A`:"",down:(r=1)=>r?`${Lr}${r}B`:"",right:(r=1)=>r?`${Lr}${r}C`:"",left:(r=1)=>r?`${Lr}${r}D`:"",to(r,e){return e?`${Lr}${e+1};${r+1}H`:`${Lr}${r+1}G`},move(r=0,e=0){let t="";return t+=r<0?yu.left(-r):r>0?yu.right(r):"",t+=e<0?yu.up(-e):e>0?yu.down(e):"",t},restore(r={}){let{after:e,cursor:t,initial:i,input:n,prompt:s,size:o,value:a}=r;if(i=_F.isPrimitive(i)?String(i):"",n=_F.isPrimitive(n)?String(n):"",a=_F.isPrimitive(a)?String(a):"",o){let l=wo.cursor.up(o)+wo.cursor.to(s.length),c=n.length-t;return c>0&&(l+=wo.cursor.left(c)),l}if(a||e){let l=!n&&!!i?-i.length:-n.length+t;return e&&(l-=e.length),n===""&&i&&!s.includes(i)&&(l+=i.length),wo.cursor.move(l)}}},XF=wo.erase={screen:Nl.screen,up:Nl.up,down:Nl.down,line:Nl.line,lineEnd:Nl.lineEnd,lineStart:Nl.lineStart,lines(r){let e="";for(let t=0;t<r;t++)e+=wo.erase.line+(t<r-1?wo.cursor.up(1):"");return r&&(e+=wo.code.beginning),e}};wo.clear=(r="",e=process.stdout.columns)=>{if(!e)return XF.line+yu.to(0);let t=s=>[...kGe.unstyle(s)].length,i=r.split(/\r?\n/),n=0;for(let s of i)n+=1+Math.floor(Math.max(t(s)-1,0)/e);return(XF.line+yu.prevLine()).repeat(n-1)+XF.line+yu.to(0)}});var Vf=w((Sft,rie)=>{"use strict";var xGe=require("events"),iie=yo(),ZF=Ure(),PGe=Hre(),DGe=Yre(),RGe=Vre(),On=Xi(),wu=tie(),U0=class extends xGe{constructor(e={}){super();this.name=e.name,this.type=e.type,this.options=e,RGe(this),PGe(this),this.state=new DGe(this),this.initial=[e.initial,e.default].find(t=>t!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=NGe(this.options.margin),this.setMaxListeners(0),FGe(this)}async keypress(e,t={}){this.keypressed=!0;let i=ZF.action(e,ZF(e,t),this.options.actions);this.state.keypress=i,this.emit("keypress",e,i),this.emit("state",this.state.clone());let n=this.options[i.action]||this[i.action]||this.dispatch;if(typeof n=="function")return await n.call(this,e,i);this.alert()}alert(){delete this.state.alert,this.options.show===!1?this.emit("alert"):this.stdout.write(wu.code.beep)}cursorHide(){this.stdout.write(wu.cursor.hide()),On.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(wu.cursor.show())}write(e){!e||(this.stdout&&this.state.show!==!1&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let t=this.state.buffer;this.state.buffer="",!(!t&&!e||this.options.show===!1)&&this.stdout.write(wu.cursor.down(e)+wu.clear(t,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:t,rest:i}=this.sections(),{cursor:n,initial:s="",input:o="",value:a=""}=this,l=this.state.size=i.length,c={after:t,cursor:n,initial:s,input:o,prompt:e,size:l,value:a},u=wu.cursor.restore(c);u&&this.stdout.write(u)}sections(){let{buffer:e,input:t,prompt:i}=this.state;i=iie.unstyle(i);let n=iie.unstyle(e),s=n.indexOf(i),o=n.slice(0,s),l=n.slice(s).split(` -`),c=l[0],u=l[l.length-1],f=(i+(t?" "+t:"")).length,h=f<c.length?c.slice(f+1):"";return{header:o,prompt:c,after:h,rest:l.slice(1),last:u}}async submit(){this.state.submitted=!0,this.state.validating=!0,this.options.onSubmit&&await this.options.onSubmit.call(this,this.name,this.value,this);let e=this.state.error||await this.validate(this.value,this.state);if(e!==!0){let t=` -`+this.symbols.pointer+" ";typeof e=="string"?t+=e.trim():t+="Invalid input",this.state.error=` -`+this.styles.danger(t),this.state.submitted=!1,await this.render(),await this.alert(),this.state.validating=!1,this.state.error=void 0;return}this.state.validating=!1,await this.render(),await this.close(),this.value=await this.result(this.value),this.emit("submit",this.value)}async cancel(e){this.state.cancelled=this.state.submitted=!0,await this.render(),await this.close(),typeof this.options.onCancel=="function"&&await this.options.onCancel.call(this,this.name,this.value,this),this.emit("cancel",await this.error(e))}async close(){this.state.closed=!0;try{let e=this.sections(),t=Math.ceil(e.prompt.length/this.width);e.rest&&this.write(wu.cursor.down(e.rest.length)),this.write(` -`.repeat(t))}catch(e){}this.emit("close")}start(){!this.stop&&this.options.show!==!1&&(this.stop=ZF.listen(this,this.keypress.bind(this)),this.once("close",this.stop))}async skip(){return this.skipped=this.options.skip===!0,typeof this.options.skip=="function"&&(this.skipped=await this.options.skip.call(this,this.name,this.value)),this.skipped}async initialize(){let{format:e,options:t,result:i}=this;if(this.format=()=>e.call(this,this.value),this.result=()=>i.call(this,this.value),typeof t.initial=="function"&&(this.initial=await t.initial.call(this,this)),typeof t.onRun=="function"&&await t.onRun.call(this,this),typeof t.onSubmit=="function"){let n=t.onSubmit.bind(this),s=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>(await n(this.name,this.value,this),s())}await this.start(),await this.render()}render(){throw new Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,t)=>{if(this.once("submit",e),this.once("cancel",t),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,t,i){let{options:n,state:s,symbols:o,timers:a}=this,l=a&&a[e];s.timer=l;let c=n[e]||s[e]||o[e],u=t&&t[e]!=null?t[e]:await c;if(u==="")return u;let g=await this.resolve(u,s,t,i);return!g&&t&&t[e]?this.resolve(c,s,t,i):g}async prefix(){let e=await this.element("prefix")||this.symbols,t=this.timers&&this.timers.prefix,i=this.state;return i.timer=t,On.isObject(e)&&(e=e[i.status]||e.pending),On.hasColor(e)?e:(this.styles[i.status]||this.styles.pending)(e)}async message(){let e=await this.element("message");return On.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,t=this.timers&&this.timers.separator,i=this.state;i.timer=t;let n=e[i.status]||e.pending||i.separator,s=await this.resolve(n,i);return On.isObject(s)&&(s=s[i.status]||s.pending),On.hasColor(s)?s:this.styles.muted(s)}async pointer(e,t){let i=await this.element("pointer",e,t);if(typeof i=="string"&&On.hasColor(i))return i;if(i){let n=this.styles,s=this.index===t,o=s?n.primary:c=>c,a=await this.resolve(i[s?"on":"off"]||i,this.state),l=On.hasColor(a)?a:o(a);return s?l:" ".repeat(a.length)}}async indicator(e,t){let i=await this.element("indicator",e,t);if(typeof i=="string"&&On.hasColor(i))return i;if(i){let n=this.styles,s=e.enabled===!0,o=s?n.success:n.dark,a=i[s?"on":"off"]||i;return On.hasColor(a)?a:o(a)}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");return On.hasColor(e)?e:this.styles.muted(e)}}error(e){return this.state.submitted?"":e||this.state.error}format(e){return e}result(e){return e}validate(e){return this.options.required===!0?this.isValue(e):!0}isValue(e){return e!=null&&e!==""}resolve(e,...t){return On.resolve(this,e,...t)}get base(){return U0.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||On.height(this.stdout,25)}get width(){return this.options.columns||On.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:t}=this.state,i=[t,e].find(this.isValue.bind(this));return this.isValue(i)?i:this.initial}static get prompt(){return e=>new this(e).run()}};function FGe(r){let e=n=>r[n]===void 0||typeof r[n]=="function",t=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],i=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let n of Object.keys(r.options)){if(t.includes(n)||/^on[A-Z]/.test(n))continue;let s=r.options[n];typeof s=="function"&&e(n)?i.includes(n)||(r[n]=s.bind(r)):typeof r[n]!="function"&&(r[n]=s)}}function NGe(r){typeof r=="number"&&(r=[r,r,r,r]);let e=[].concat(r||[]),t=n=>n%2==0?` -`:" ",i=[];for(let n=0;n<4;n++){let s=t(n);e[n]?i.push(s.repeat(e[n])):i.push("")}return i}rie.exports=U0});var oie=w((vft,nie)=>{"use strict";var LGe=Xi(),sie={default(r,e){return e},checkbox(r,e){throw new Error("checkbox role is not implemented yet")},editable(r,e){throw new Error("editable role is not implemented yet")},expandable(r,e){throw new Error("expandable role is not implemented yet")},heading(r,e){return e.disabled="",e.indicator=[e.indicator," "].find(t=>t!=null),e.message=e.message||"",e},input(r,e){throw new Error("input role is not implemented yet")},option(r,e){return sie.default(r,e)},radio(r,e){throw new Error("radio role is not implemented yet")},separator(r,e){return e.disabled="",e.indicator=[e.indicator," "].find(t=>t!=null),e.message=e.message||r.symbols.line.repeat(5),e},spacer(r,e){return e}};nie.exports=(r,e={})=>{let t=LGe.merge({},sie,e.roles);return t[r]||t.default}});var JC=w((kft,aie)=>{"use strict";var TGe=yo(),OGe=Vf(),MGe=oie(),K0=Xi(),{reorder:$F,scrollUp:UGe,scrollDown:KGe,isObject:Aie,swap:HGe}=K0,lie=class extends OGe{constructor(e){super(e);this.cursorHide(),this.maxSelected=e.maxSelected||Infinity,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){typeof this.options.initial=="function"&&(this.initial=await this.options.initial.call(this)),await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:t,autofocus:i,suggest:n}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach(s=>s.enabled=!1),typeof n!="function"&&this.selectable.length===0)throw new Error("At least one choice must be selectable");Aie(t)&&(t=Object.keys(t)),Array.isArray(t)?(i!=null&&(this.index=this.findIndex(i)),t.forEach(s=>this.enable(this.find(s))),await this.render()):(i!=null&&(t=i),typeof t=="string"&&(t=this.findIndex(t)),typeof t=="number"&&t>-1&&(this.index=Math.max(0,Math.min(t,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,t){this.state.loadingChoices=!0;let i=[],n=0,s=async(o,a)=>{typeof o=="function"&&(o=await o.call(this)),o instanceof Promise&&(o=await o);for(let l=0;l<o.length;l++){let c=o[l]=await this.toChoice(o[l],n++,a);i.push(c),c.choices&&await s(c.choices,c)}return i};return s(e,t).then(o=>(this.state.loadingChoices=!1,o))}async toChoice(e,t,i){if(typeof e=="function"&&(e=await e.call(this,this)),e instanceof Promise&&(e=await e),typeof e=="string"&&(e={name:e}),e.normalized)return e;e.normalized=!0;let n=e.value;if(e=MGe(e.role,this.options)(this,e),typeof e.disabled=="string"&&!e.hint&&(e.hint=e.disabled,e.disabled=!0),e.disabled===!0&&e.hint==null&&(e.hint="(disabled)"),e.index!=null)return e;e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=t,e.cursor=0,K0.define(e,"parent",i),e.level=i?i.level+1:1,e.indent==null&&(e.indent=i?i.indent+" ":e.indent||""),e.path=i?i.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),this.isDisabled(e)||(this.longest=Math.max(this.longest,TGe.unstyle(e.message).length));let o=N({},e);return e.reset=(a=o.input,l=o.value)=>{for(let c of Object.keys(o))e[c]=o[c];e.input=a,e.value=l},n==null&&typeof e.initial=="function"&&(e.input=await e.initial.call(this,this.state,e,t)),e}async onChoice(e,t){this.emit("choice",e,t,this),typeof e.onChoice=="function"&&await e.onChoice.call(this,this.state,e,t)}async addChoice(e,t,i){let n=await this.toChoice(e,t,i);return this.choices.push(n),this.index=this.choices.length-1,this.limit=this.choices.length,n}async newItem(e,t,i){let n=N({name:"New choice name?",editable:!0,newChoice:!0},e),s=await this.addChoice(n,t,i);return s.updateChoice=()=>{delete s.newChoice,s.name=s.message=s.input,s.input="",s.cursor=0},this.render()}indent(e){return e.indent==null?e.level>1?" ".repeat(e.level-1):"":e.indent}dispatch(e,t){if(this.multiple&&this[t.name])return this[t.name]();this.alert()}focus(e,t){return typeof t!="boolean"&&(t=e.enabled),t&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=t&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelected<this.choices.length)return this.alert();let e=this.selectable.every(t=>t.enabled);return this.choices.forEach(t=>t.enabled=!e),this.render()}i(){return this.choices.length-this.selected.length>this.maxSelected?this.alert():(this.choices.forEach(e=>e.enabled=!e.enabled),this.render())}g(e=this.focused){return this.choices.some(t=>!!t.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,t){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();typeof t!="boolean"&&(t=!e.enabled),e.enabled=t,e.choices&&e.choices.forEach(n=>this.toggle(n,t));let i=e.parent;for(;i;){let n=i.choices.filter(s=>this.isDisabled(s));i.enabled=n.every(s=>s.enabled===!0),i=i.parent}return cie(this,this.choices),this.emit("toggle",e,this),e}enable(e){return this.selected.length>=this.maxSelected?this.alert():(e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e)}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let t=i=>{let n=Number(i);if(n>this.choices.length-1)return this.alert();let s=this.focused,o=this.choices.find(a=>n===a.index);if(!o.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(o)===-1){let a=$F(this.choices),l=a.indexOf(o);if(s.index>l){let c=a.slice(l,l+this.limit),u=a.filter(g=>!c.includes(g));this.choices=c.concat(u)}else{let c=l-this.limit+1;this.choices=a.slice(c).concat(a.slice(0,c))}}return this.index=this.choices.indexOf(o),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise(i=>{let n=this.choices.length,s=this.num,o=(a=!1,l)=>{clearTimeout(this.numberTimeout),a&&(l=t(s)),this.num="",i(l)};if(s==="0"||s.length===1&&Number(s+"0")>n)return o(!0);if(Number(s)>n)return o(!1,this.alert());this.numberTimeout=setTimeout(()=>o(!0),this.delay)})}home(){return this.choices=$F(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,t=$F(this.choices);return this.choices=t.slice(e).concat(t.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){return this.visible.length<=1?this.alert():this.up()}next(){return this.visible.length<=1?this.alert():this.down()}right(){return this.cursor>=this.input.length?this.alert():(this.cursor++,this.render())}left(){return this.cursor<=0?this.alert():(this.cursor--,this.render())}up(){let e=this.choices.length,t=this.visible.length,i=this.index;return this.options.scroll===!1&&i===0?this.alert():e>t&&i===0?this.scrollUp():(this.index=(i-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,t=this.visible.length,i=this.index;return this.options.scroll===!1&&i===t-1?this.alert():e>t&&i===t-1?this.scrollDown():(this.index=(i+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=UGe(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=KGe(this.choices),this.index=e,this.isDisabled()?this.down():this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){return this.visible.length<=1?this.alert():(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled()?this.up():this.render())}pageDown(){return this.visible.length>=this.choices.length?this.alert():(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled()?this.down():this.render())}swap(e){HGe(this.choices,this.index,e)}isDisabled(e=this.focused){return e&&["disabled","collapsed","hidden","completing","readonly"].some(i=>e[i]===!0)?!0:e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every(t=>this.isEnabled(t));if(e.choices){let t=e.choices.filter(i=>!this.isDisabled(i));return e.enabled&&t.every(i=>this.isEnabled(i))}return e.enabled&&!this.isDisabled(e)}isChoice(e,t){return e.name===t||e.index===Number(t)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(t=>this.isChoice(e,t)):this.isChoice(e,this.initial)}map(e=[],t="value"){return[].concat(e||[]).reduce((i,n)=>(i[n]=this.find(n,t),i),{})}filter(e,t){let i=(a,l)=>[a.name,l].includes(e),n=typeof e=="function"?e:i,o=(this.options.multiple?this.state._choices:this.choices).filter(n);return t?o.map(a=>a[t]):o}find(e,t){if(Aie(e))return t?e[t]:e;let i=(o,a)=>[o.name,a].includes(e),n=typeof e=="function"?e:i,s=this.choices.find(n);if(s)return t?s[t]:s}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice)return e.input?(e.updateChoice(),this.render()):this.alert();if(this.choices.some(o=>o.newChoice))return this.alert();let{reorder:t,sort:i}=this.options,n=this.multiple===!0,s=this.selected;return s===void 0?this.alert():(Array.isArray(s)&&t!==!1&&i!==!0&&(s=K0.reorder(s)),this.value=n?s.map(o=>o.name):s.name,super.submit())}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let t of e)this.state._choices.some(i=>i.name===t.name)||this.state._choices.push(t);if(!this._initial&&this.options.initial){this._initial=!0;let t=this.initial;if(typeof t=="string"||typeof t=="number"){let i=this.find(t);i&&(this.initial=i.index,this.focus(i,!0))}}}get choices(){return cie(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:t,choices:i}=this,n=e.limit||this._limit||t.limit||i.length;return Math.min(n,this.height)}set value(e){super.value=e}get value(){return typeof super.value!="string"&&super.value===this.initial?this.input:super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];return e&&this.state.submitted&&this.multiple!==!0&&(e.enabled=!0),e}get selectable(){return this.choices.filter(e=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}};function cie(r,e){if(e instanceof Promise)return e;if(typeof e=="function"){if(K0.isAsyncFn(e))return e;e=e.call(r,r)}for(let t of e){if(Array.isArray(t.choices)){let i=t.choices.filter(n=>!r.isDisabled(n));t.enabled=i.every(n=>n.enabled===!0)}r.isDisabled(t)===!0&&delete t.enabled}return e}aie.exports=lie});var Ll=w((xft,uie)=>{"use strict";var jGe=JC(),eN=Xi(),gie=class extends jGe{constructor(e){super(e);this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,t){return!this.multiple||this.options.pointer?super.pointer(e,t):""}indicator(e,t){return this.multiple?super.indicator(e,t):""}choiceMessage(e,t){let i=this.resolve(e.message,this.state,e,t);return e.role==="heading"&&!eN.hasColor(i)&&(i=this.styles.strong(i)),this.resolve(i,this.state,e,t)}choiceSeparator(){return":"}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=await this.pointer(e,t),s=await this.indicator(e,t)+(e.pad||""),o=await this.resolve(e.hint,this.state,e,t);o&&!eN.hasColor(o)&&(o=this.styles.muted(o));let a=this.indent(e),l=await this.choiceMessage(e,t),c=()=>[this.margin[3],a+n+s,l,this.margin[1],o].filter(Boolean).join(" ");return e.role==="heading"?c():e.disabled?(eN.hasColor(l)||(l=this.styles.disabled(l)),c()):(i&&(l=this.styles.em(l)),c())}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(s,o)=>await this.renderChoice(s,o)),t=await Promise.all(e);t.length||t.push(this.styles.danger("No matching choices"));let i=this.margin[0]+t.join(` -`),n;return this.options.choicesHeader&&(n=await this.resolve(this.options.choicesHeader,this.state)),[n,i].filter(Boolean).join(` -`)}format(){return!this.state.submitted||this.state.cancelled?"":Array.isArray(this.selected)?this.selected.map(e=>this.styles.primary(e.name)).join(", "):this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:t}=this.state,i="",n=await this.header(),s=await this.prefix(),o=await this.separator(),a=await this.message();this.options.promptLine!==!1&&(i=[s,a,o,""].join(" "),this.state.prompt=i);let l=await this.format(),c=await this.error()||await this.hint(),u=await this.renderChoices(),g=await this.footer();l&&(i+=l),c&&!i.includes(c)&&(i+=" "+c),e&&!l&&!u.trim()&&this.multiple&&this.emptyError!=null&&(i+=this.styles.danger(this.emptyError)),this.clear(t),this.write([n,i,u,g].filter(Boolean).join(` -`)),this.write(this.margin[2]),this.restore()}};uie.exports=gie});var pie=w((Pft,fie)=>{"use strict";var GGe=Ll(),YGe=(r,e)=>{let t=r.toLowerCase();return i=>{let s=i.toLowerCase().indexOf(t),o=e(i.slice(s,s+t.length));return s>=0?i.slice(0,s)+o+i.slice(s+t.length):i}},hie=class extends GGe{constructor(e){super(e);this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:t,input:i}=this.state;return this.input=i.slice(0,t)+e+i.slice(t),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:t}=this.state;return t?(this.input=t.slice(0,e-1)+t.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:t}=this.state;return t[e]===void 0?this.alert():(this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.complete())}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,t=this.state._choices){if(typeof this.options.suggest=="function")return this.options.suggest.call(this,e,t);let i=e.toLowerCase();return t.filter(n=>n.message.toLowerCase().includes(i))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map(e=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight?this.options.highlight.bind(this):this.styles.placeholder,t=YGe(this.input,e),i=this.choices;this.choices=i.map(n=>te(N({},n),{message:t(n.message)})),await super.render(),this.choices=i}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}};fie.exports=hie});var rN=w((Dft,die)=>{"use strict";var tN=Xi();die.exports=(r,e={})=>{r.cursorHide();let{input:t="",initial:i="",pos:n,showCursor:s=!0,color:o}=e,a=o||r.styles.placeholder,l=tN.inverse(r.styles.primary),c=m=>l(r.styles.black(m)),u=t,g=" ",f=c(g);if(r.blink&&r.blink.off===!0&&(c=m=>m,f=""),s&&n===0&&i===""&&t==="")return c(g);if(s&&n===0&&(t===i||t===""))return c(i[0])+a(i.slice(1));i=tN.isPrimitive(i)?`${i}`:"",t=tN.isPrimitive(t)?`${t}`:"";let h=i&&i.startsWith(t)&&i!==t,p=h?c(i[t.length]):f;if(n!==t.length&&s===!0&&(u=t.slice(0,n)+c(t[n])+t.slice(n+1),p=""),s===!1&&(p=""),h){let m=r.styles.unstyle(u+p);return u+p+a(i.slice(m.length))}return u+p}});var H0=w((Rft,Cie)=>{"use strict";var qGe=yo(),JGe=Ll(),WGe=rN(),mie=class extends JGe{constructor(e){super(te(N({},e),{multiple:!0}));this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(t=>t!=null),this.emptyError="",this.values={}}async reset(e){return await super.reset(),e===!0&&(this._index=this.index),this.index=this._index,this.values={},this.choices.forEach(t=>t.reset&&t.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let t=this.focused;if(!t)return this.alert();let{cursor:i,input:n}=t;return t.value=t.input=n.slice(0,i)+e+n.slice(i),t.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:t,input:i}=e;return e.value=e.input=i.slice(0,t-1)+i.slice(t),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:t,input:i}=e;if(i[t]===void 0)return this.alert();let n=`${i}`.slice(0,t)+`${i}`.slice(t+1);return e.value=e.input=n,this.render()}right(){let e=this.focused;return e?e.cursor>=e.input.length?this.alert():(e.cursor++,this.render()):this.alert()}left(){let e=this.focused;return e?e.cursor<=0?this.alert():(e.cursor--,this.render()):this.alert()}space(e,t){return this.dispatch(e,t)}number(e,t){return this.dispatch(e,t)}next(){let e=this.focused;if(!e)return this.alert();let{initial:t,input:i}=e;return t&&t.startsWith(i)&&i!==t?(e.value=e.input=t,e.cursor=e.value.length,this.render()):super.next()}prev(){let e=this.focused;return e?e.cursor===0?super.prev():(e.value=e.input="",e.cursor=0,this.render()):this.alert()}separator(){return""}format(e){return this.state.submitted?"":super.format(e)}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,t){let i=await this.resolve(e.separator,this.state,e,t)||":";return i?" "+this.styles.disabled(i):""}async renderChoice(e,t){await this.onChoice(e,t);let{state:i,styles:n}=this,{cursor:s,initial:o="",name:a,hint:l,input:c=""}=e,{muted:u,submitted:g,primary:f,danger:h}=n,p=l,m=this.index===t,y=e.validate||(()=>!0),b=await this.choiceSeparator(e,t),v=e.message;this.align==="right"&&(v=v.padStart(this.longest+1," ")),this.align==="left"&&(v=v.padEnd(this.longest+1," "));let k=this.values[a]=c||o,T=c?"success":"dark";await y.call(e,k,this.state)!==!0&&(T="danger");let q=n[T](await this.indicator(e,t))+(e.pad||""),$=this.indent(e),z=()=>[$,q,v+b,c,p].filter(Boolean).join(" ");if(i.submitted)return v=qGe.unstyle(v),c=g(c),p="",z();if(e.format)c=await e.format.call(this,c,e,t);else{let ne=this.styles.muted;c=WGe(this,{input:c,initial:o,pos:s,showCursor:m,color:ne})}return this.isValue(c)||(c=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[a]=await e.result.call(this,k,e,t)),m&&(v=f(v)),e.error?c+=(c?" ":"")+h(e.error.trim()):e.hint&&(c+=(c?" ":"")+u(e.hint.trim())),z()}async submit(){return this.value=this.values,super.base.submit.call(this)}};Cie.exports=mie});var iN=w((Fft,Eie)=>{"use strict";var zGe=H0(),_Ge=()=>{throw new Error("expected prompt to have a custom authenticate method")},Iie=(r=_Ge)=>{class e extends zGe{constructor(i){super(i)}async submit(){this.value=await r.call(this,this.values,this.state),super.base.submit.call(this)}static create(i){return Iie(i)}}return e};Eie.exports=Iie()});var Bie=w((Nft,yie)=>{"use strict";var VGe=iN();function XGe(r,e){return r.username===this.options.username&&r.password===this.options.password}var wie=(r=XGe)=>{let e=[{name:"username",message:"username"},{name:"password",message:"password",format(i){return this.options.showPassword?i:(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(i.length))}}];class t extends VGe.create(r){constructor(n){super(te(N({},n),{choices:e}))}static create(n){return wie(n)}}return t};yie.exports=wie()});var j0=w((Lft,bie)=>{"use strict";var ZGe=Vf(),{isPrimitive:$Ge,hasColor:eYe}=Xi(),Qie=class extends ZGe{constructor(e){super(e);this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){return this.isValue(e)?(this.input=e,this.submit()):this.alert()}format(e){let{styles:t,state:i}=this;return i.submitted?t.success(e):t.primary(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return $Ge(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");return eYe(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:t}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o=this.styles.muted(this.default),a=[i,s,o,n].filter(Boolean).join(" ");this.state.prompt=a;let l=await this.header(),c=this.value=this.cast(e),u=await this.format(c),g=await this.error()||await this.hint(),f=await this.footer();g&&!a.includes(g)&&(u+=" "+g),a+=" "+u,this.clear(t),this.write([l,a,f].filter(Boolean).join(` -`)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}};bie.exports=Qie});var kie=w((Tft,Sie)=>{"use strict";var tYe=j0(),vie=class extends tYe{constructor(e){super(e);this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}};Sie.exports=vie});var Die=w((Oft,xie)=>{"use strict";var rYe=Ll(),iYe=H0(),Xf=iYe.prototype,Pie=class extends rYe{constructor(e){super(te(N({},e),{multiple:!0}));this.align=[this.options.align,"left"].find(t=>t!=null),this.emptyError="",this.values={}}dispatch(e,t){let i=this.focused,n=i.parent||{};return!i.editable&&!n.editable&&(e==="a"||e==="i")?super[e]():Xf.dispatch.call(this,e,t)}append(e,t){return Xf.append.call(this,e,t)}delete(e,t){return Xf.delete.call(this,e,t)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?Xf.next.call(this):super.next()}prev(){return this.focused.editable?Xf.prev.call(this):super.prev()}async indicator(e,t){let i=e.indicator||"",n=e.editable?i:super.indicator(e,t);return await this.resolve(n,this.state,e,t)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,t){return e.indent="",e.editable?Xf.renderChoice.call(this,e,t):super.renderChoice(e,t)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let t of this.choices){if(typeof t.validate!="function"||t.role==="heading")continue;let i=t.parent?this.value[t.parent.name]:this.value;if(t.editable?i=t.value===t.name?t.initial||"":t.value:this.isDisabled(t)||(i=t.enabled===!0),e=await t.validate(i,this.state),e!==!0)break}return e!==!0&&(this.state.error=typeof e=="string"?e:"Invalid Input"),e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some(e=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let t=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}e.editable?t[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(t[e.name]=e.enabled===!0)}return this.base.submit.call(this)}};xie.exports=Pie});var Bu=w((Mft,Rie)=>{"use strict";var nYe=Vf(),sYe=rN(),{isPrimitive:oYe}=Xi(),Fie=class extends nYe{constructor(e){super(e);this.initial=oYe(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,t={}){let i=this.state.prevKeypress;return this.state.prevKeypress=t,this.options.multiline===!0&&t.name==="return"&&(!i||i.name!=="return")?this.append(` -`,t):super.keypress(e,t)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,t){if(!e||t.ctrl||t.code)return this.alert();this.append(e)}append(e){let{cursor:t,input:i}=this.state;this.input=`${i}`.slice(0,t)+e+`${i}`.slice(t),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:t}=this.state;if(e<=0)return this.alert();this.input=`${t}`.slice(0,e-1)+`${t}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let t=this.input.slice(0,e),i=this.input.slice(e),n=t.split(" ");this.state.clipboard.push(n.pop()),this.input=n.join(" "),this.cursor=this.input.length,this.input+=i,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){this.state.prevCursor?(this.cursor=this.state.prevCursor,this.state.prevCursor=0):(this.state.prevCursor=this.cursor,this.cursor=0),this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){return this.cursor>=this.input.length?this.alert():(this.moveCursor(1),this.render())}left(){return this.cursor<=0?this.alert():(this.moveCursor(-1),this.render())}isValue(e){return!!e}async format(e=this.value){let t=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||t):sYe(this,{input:e,initial:t,pos:this.cursor})}async render(){let e=this.state.size,t=await this.prefix(),i=await this.separator(),n=await this.message(),s=[t,n,i].filter(Boolean).join(" ");this.state.prompt=s;let o=await this.header(),a=await this.format(),l=await this.error()||await this.hint(),c=await this.footer();l&&!a.includes(l)&&(a+=" "+l),s+=" "+a,this.clear(e),this.write([o,s,c].filter(Boolean).join(` -`)),this.restore()}};Rie.exports=Fie});var Lie=w((Uft,Nie)=>{"use strict";var aYe=r=>r.filter((e,t)=>r.lastIndexOf(e)===t),G0=r=>aYe(r).filter(Boolean);Nie.exports=(r,e={},t="")=>{let{past:i=[],present:n=""}=e,s,o;switch(r){case"prev":case"undo":return s=i.slice(0,i.length-1),o=i[i.length-1]||"",{past:G0([t,...s]),present:o};case"next":case"redo":return s=i.slice(1),o=i[0]||"",{past:G0([...s,t]),present:o};case"save":return{past:G0([...i,t]),present:""};case"remove":return o=G0(i.filter(a=>a!==t)),n="",o.length&&(n=o.pop()),{past:o,present:n};default:throw new Error(`Invalid action: "${r}"`)}}});var nN=w((Kft,Tie)=>{"use strict";var AYe=Bu(),Oie=Lie(),Mie=class extends AYe{constructor(e){super(e);let t=this.options.history;if(t&&t.store){let i=t.values||this.initial;this.autosave=!!t.autosave,this.store=t.store,this.data=this.store.get("values")||{past:[],present:i},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){return this.store?(this.data=Oie(e,this.data,this.input),this.data.present?(this.input=this.data.present,this.cursor=this.input.length,this.render()):this.alert()):this.alert()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){!this.store||(this.data=Oie("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&this.autosave===!0&&this.save(),super.submit()}};Tie.exports=Mie});var Hie=w((Hft,Uie)=>{"use strict";var lYe=Bu(),Kie=class extends lYe{format(){return""}};Uie.exports=Kie});var Yie=w((jft,jie)=>{"use strict";var cYe=Bu(),Gie=class extends cYe{constructor(e={}){super(e);this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:t=>t;return this.list.map(e).join(", ")}async submit(e){let t=this.state.error||await this.validate(this.list,this.state);return t!==!0?(this.state.error=t,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}};jie.exports=Gie});var Wie=w((Gft,qie)=>{"use strict";var uYe=Ll(),Jie=class extends uYe{constructor(e){super(te(N({},e),{multiple:!0}))}};qie.exports=Jie});var sN=w((Yft,zie)=>{"use strict";var gYe=Bu(),_ie=class extends gYe{constructor(e={}){super(N({style:"number"},e));this.min=this.isValue(e.min)?this.toNumber(e.min):-Infinity,this.max=this.isValue(e.max)?this.toNumber(e.max):Infinity,this.delay=e.delay!=null?e.delay:1e3,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){return!/[-+.]/.test(e)||e==="."&&this.input.includes(".")?this.alert("invalid number"):super.append(e)}number(e){return super.append(e)}next(){return this.input&&this.input!==this.initial?this.alert():this.isValue(this.initial)?(this.input=this.initial,this.cursor=String(this.initial).length,this.render()):this.alert()}up(e){let t=e||this.minor,i=this.toNumber(this.input);return i>this.max+t?this.alert():(this.input=`${i+t}`,this.render())}down(e){let t=e||this.minor,i=this.toNumber(this.input);return i<this.min-t?this.alert():(this.input=`${i-t}`,this.render())}shiftDown(){return this.down(this.major)}shiftUp(){return this.up(this.major)}format(e=this.input){return typeof this.options.format=="function"?this.options.format.call(this,e):this.styles.info(e)}toNumber(e=""){return this.float?+e:Math.round(+e)}isValue(e){return/^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(e)}submit(){let e=[this.input,this.initial].find(t=>this.isValue(t));return this.value=this.toNumber(e||0),super.submit()}};zie.exports=_ie});var Xie=w((qft,Vie)=>{Vie.exports=sN()});var ene=w((Jft,Zie)=>{"use strict";var fYe=Bu(),$ie=class extends fYe{constructor(e){super(e);this.cursorShow()}format(e=this.input){return this.keypressed?(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length)):""}};Zie.exports=$ie});var nne=w((Wft,tne)=>{"use strict";var hYe=yo(),pYe=JC(),rne=Xi(),ine=class extends pYe{constructor(e={}){super(e);this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||` - `;let t=e.startNumber||1;typeof this.scale=="number"&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((i,n)=>({name:n+t})))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let t of this.choices){e=Math.max(e,t.message.length),t.scaleIndex=t.initial||2,t.scale=[];for(let i=0;i<this.scale.length;i++)t.scale.push({index:i})}this.widths[0]=Math.min(this.widths[0],e+3)}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}heading(e,t,i){return this.styles.strong(e)}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIndex>=this.scale.length-1?this.alert():(e.scaleIndex++,this.render())}left(){let e=this.focused;return e.scaleIndex<=0?this.alert():(e.scaleIndex--,this.render())}indent(){return""}format(){return this.state.submitted?this.choices.map(t=>this.styles.info(t.index)).join(", "):""}pointer(){return""}renderScaleKey(){if(this.scaleKey===!1||this.state.submitted)return"";let e=this.scale.map(i=>` ${i.name} - ${i.message}`);return["",...e].map(i=>this.styles.muted(i)).join(` -`)}renderScaleHeading(e){let t=this.scale.map(l=>l.name);typeof this.options.renderScaleHeading=="function"&&(t=this.options.renderScaleHeading.call(this,e));let i=this.scaleLength-t.join("").length,n=Math.round(i/(t.length-1)),o=t.map(l=>this.styles.strong(l)).join(" ".repeat(n)),a=" ".repeat(this.widths[0]);return this.margin[3]+a+this.margin[1]+o}scaleIndicator(e,t,i){if(typeof this.options.scaleIndicator=="function")return this.options.scaleIndicator.call(this,e,t,i);let n=e.scaleIndex===t.index;return t.disabled?this.styles.hint(this.symbols.radio.disabled):n?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,t){let i=e.scale.map(s=>this.scaleIndicator(e,s,t)),n=this.term==="Hyper"?"":" ";return i.join(n+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=await this.pointer(e,t),s=await e.hint;s&&!rne.hasColor(s)&&(s=this.styles.muted(s));let o=p=>this.margin[3]+p.replace(/\s+$/,"").padEnd(this.widths[0]," "),a=this.newline,l=this.indent(e),c=await this.resolve(e.message,this.state,e,t),u=await this.renderScale(e,t),g=this.margin[1]+this.margin[3];this.scaleLength=hYe.unstyle(u).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-g.length);let h=rne.wordWrap(c,{width:this.widths[0],newline:a}).split(` -`).map(p=>o(p)+this.margin[1]);return i&&(u=this.styles.info(u),h=h.map(p=>this.styles.info(p))),h[0]+=u,this.linebreak&&h.push(""),[l+n,h.join(` -`)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(n,s)=>await this.renderChoice(n,s)),t=await Promise.all(e),i=await this.renderScaleHeading();return this.margin[0]+[i,...t.map(n=>n.join(" "))].join(` -`)}async render(){let{submitted:e,size:t}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o="";this.options.promptLine!==!1&&(o=[i,s,n,""].join(" "),this.state.prompt=o);let a=await this.header(),l=await this.format(),c=await this.renderScaleKey(),u=await this.error()||await this.hint(),g=await this.renderChoices(),f=await this.footer(),h=this.emptyError;l&&(o+=l),u&&!o.includes(u)&&(o+=" "+u),e&&!l&&!g.trim()&&this.multiple&&h!=null&&(o+=this.styles.danger(h)),this.clear(t),this.write([a,o,c,g,f].filter(Boolean).join(` -`)),this.state.submitted||this.write(this.margin[2]),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}};tne.exports=ine});var Ane=w((zft,sne)=>{"use strict";var one=yo(),dYe=(r="")=>typeof r=="string"?r.replace(/^['"]|['"]$/g,""):"",ane=class{constructor(e){this.name=e.key,this.field=e.field||{},this.value=dYe(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}},CYe=async(r={},e={},t=i=>i)=>{let i=new Set,n=r.fields||[],s=r.template,o=[],a=[],l=[],c=1;typeof s=="function"&&(s=await s());let u=-1,g=()=>s[++u],f=()=>s[u+1],h=p=>{p.line=c,o.push(p)};for(h({type:"bos",value:""});u<s.length-1;){let p=g();if(/^[^\S\n ]$/.test(p)){h({type:"text",value:p});continue}if(p===` -`){h({type:"newline",value:p}),c++;continue}if(p==="\\"){p+=g(),h({type:"text",value:p});continue}if((p==="$"||p==="#"||p==="{")&&f()==="{"){p+=g();let b={type:"template",open:p,inner:"",close:"",value:p},v;for(;v=g();){if(v==="}"){f()==="}"&&(v+=g()),b.value+=v,b.close=v;break}v===":"?(b.initial="",b.key=b.inner):b.initial!==void 0&&(b.initial+=v),b.value+=v,b.inner+=v}b.template=b.open+(b.initial||b.inner)+b.close,b.key=b.key||b.inner,e.hasOwnProperty(b.key)&&(b.initial=e[b.key]),b=t(b),h(b),l.push(b.key),i.add(b.key);let k=a.find(T=>T.name===b.key);b.field=n.find(T=>T.name===b.key),k||(k=new ane(b),a.push(k)),k.lines.push(b.line-1);continue}let m=o[o.length-1];m.type==="text"&&m.line===c?m.value+=p:h({type:"text",value:p})}return h({type:"eos",value:""}),{input:s,tabstops:o,unique:i,keys:l,items:a}};sne.exports=async r=>{let e=r.options,t=new Set(e.required===!0?[]:e.required||[]),i=N(N({},e.values),e.initial),{tabstops:n,items:s,keys:o}=await CYe(e,i),a=oN("result",r,e),l=oN("format",r,e),c=oN("validate",r,e,!0),u=r.isValue.bind(r);return async(g={},f=!1)=>{let h=0;g.required=t,g.items=s,g.keys=o,g.output="";let p=async(v,k,T,Y)=>{let q=await c(v,k,T,Y);return q===!1?"Invalid field "+T.name:q};for(let v of n){let k=v.value,T=v.key;if(v.type!=="template"){k&&(g.output+=k);continue}if(v.type==="template"){let Y=s.find(ee=>ee.name===T);e.required===!0&&g.required.add(Y.name);let q=[Y.input,g.values[Y.value],Y.value,k].find(u),z=(Y.field||{}).message||v.inner;if(f){let ee=await p(g.values[T],g,Y,h);if(ee&&typeof ee=="string"||ee===!1){g.invalid.set(T,ee);continue}g.invalid.delete(T);let A=await a(g.values[T],g,Y,h);g.output+=one.unstyle(A);continue}Y.placeholder=!1;let ne=k;k=await l(k,g,Y,h),q!==k?(g.values[T]=q,k=r.styles.typing(q),g.missing.delete(z)):(g.values[T]=void 0,q=`<${z}>`,k=r.styles.primary(q),Y.placeholder=!0,g.required.has(T)&&g.missing.add(z)),g.missing.has(z)&&g.validating&&(k=r.styles.warning(q)),g.invalid.has(T)&&g.validating&&(k=r.styles.danger(q)),h===g.index&&(ne!==k?k=r.styles.underline(k):k=r.styles.heading(one.unstyle(k))),h++}k&&(g.output+=k)}let m=g.output.split(` -`).map(v=>" "+v),y=s.length,b=0;for(let v of s)g.invalid.has(v.name)&&v.lines.forEach(k=>{m[k][0]===" "&&(m[k]=g.styles.danger(g.symbols.bullet)+m[k].slice(1))}),r.isValue(g.values[v.name])&&b++;return g.completed=(b/y*100).toFixed(0),g.output=m.join(` -`),g.output}};function oN(r,e,t,i){return(n,s,o,a)=>typeof o.field[r]=="function"?o.field[r].call(e,n,s,o,a):[i,n].find(l=>e.isValue(l))}});var une=w((_ft,lne)=>{"use strict";var mYe=yo(),EYe=Ane(),IYe=Vf(),cne=class extends IYe{constructor(e){super(e);this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await EYe(this),await super.initialize()}async reset(e){this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0&&(await this.initialize(),await this.render())}moveCursor(e){let t=this.getItem();this.cursor+=e,t.cursor+=e}dispatch(e,t){if(!t.code&&!t.ctrl&&e!=null&&this.getItem()){this.append(e,t);return}this.alert()}append(e,t){let i=this.getItem(),n=i.input.slice(0,this.cursor),s=i.input.slice(this.cursor);this.input=i.input=`${n}${e}${s}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let t=e.input.slice(this.cursor),i=e.input.slice(0,this.cursor-1);this.input=e.input=`${i}${t}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let t=this.state.completed<100?this.styles.warning:this.styles.success;return this.state.submitted===!0&&this.state.completed!==100&&(t=this.styles.danger),t(`${this.state.completed}% completed`)}async render(){let{index:e,keys:t=[],submitted:i,size:n}=this.state,s=[this.options.newline,` -`].find(v=>v!=null),o=await this.prefix(),a=await this.separator(),l=await this.message(),c=[o,l,a].filter(Boolean).join(" ");this.state.prompt=c;let u=await this.header(),g=await this.error()||"",f=await this.hint()||"",h=i?"":await this.interpolate(this.state),p=this.state.key=t[e]||"",m=await this.format(p),y=await this.footer();m&&(c+=" "+m),f&&!m&&this.state.completed===0&&(c+=" "+f),this.clear(n);let b=[u,c,h,y,g.trim()];this.write(b.filter(Boolean).join(s)),this.restore()}getItem(e){let{items:t,keys:i,index:n}=this.state,s=t.find(o=>o.name===i[n]);return s&&s.input!=null&&(this.input=s.input,this.cursor=s.cursor),s}async submit(){typeof this.interpolate!="function"&&await this.initialize(),await this.interpolate(this.state,!0);let{invalid:e,missing:t,output:i,values:n}=this.state;if(e.size){let a="";for(let[l,c]of e)a+=`Invalid ${l}: ${c} -`;return this.state.error=a,super.submit()}if(t.size)return this.state.error="Required: "+[...t.keys()].join(", "),super.submit();let o=mYe.unstyle(i).split(` -`).map(a=>a.slice(1)).join(` -`);return this.value={values:n,result:o},super.submit()}};lne.exports=cne});var hne=w((Vft,gne)=>{"use strict";var yYe="(Use <shift>+<up/down> to sort)",wYe=Ll(),fne=class extends wYe{constructor(e){super(te(N({},e),{reorder:!1,sort:!0,multiple:!0}));this.state.hint=[this.options.hint,yYe].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,t){let i=await super.renderChoice(e,t),n=this.symbols.identicalTo+" ",s=this.index===t&&this.sorting?this.styles.muted(n):" ";return this.options.drag===!1&&(s=""),this.options.numbered===!0?s+`${t+1} - `+i:s+i}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}};gne.exports=fne});var Cne=w((Xft,pne)=>{"use strict";var BYe=JC(),dne=class extends BYe{constructor(e={}){super(e);if(this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let t=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];t=t.map(i=>this.styles.muted(i)),this.state.header=t.join(` - `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let t=await super.toChoices(...e);for(let i of t)i.scale=bYe(5,this.options),i.scaleIdx=2;return t}dispatch(){this.alert()}space(){let e=this.focused,t=e.scale[e.scaleIdx],i=t.selected;return e.scale.forEach(n=>n.selected=!1),t.selected=!i,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIdx>=e.scale.length-1?this.alert():(e.scaleIdx++,this.render())}left(){let e=this.focused;return e.scaleIdx<=0?this.alert():(e.scaleIdx--,this.render())}indent(){return" "}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=this.term==="Hyper",s=n?9:8,o=n?"":" ",a=this.symbols.line.repeat(s),l=" ".repeat(s+(n?0:1)),c=k=>(k?this.styles.success("\u25C9"):"\u25EF")+o,u=t+1+".",g=i?this.styles.heading:this.styles.noop,f=await this.resolve(e.message,this.state,e,t),h=this.indent(e),p=h+e.scale.map((k,T)=>c(T===e.scaleIdx)).join(a),m=k=>k===e.scaleIdx?g(k):k,y=h+e.scale.map((k,T)=>m(T)).join(l),b=()=>[u,f].filter(Boolean).join(" "),v=()=>[b(),p,y," "].filter(Boolean).join(` -`);return i&&(p=this.styles.cyan(p),y=this.styles.cyan(y)),v()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(i,n)=>await this.renderChoice(i,n)),t=await Promise.all(e);return t.length||t.push(this.styles.danger("No matching choices")),t.join(` -`)}format(){return this.state.submitted?this.choices.map(t=>this.styles.info(t.scaleIdx)).join(", "):""}async render(){let{submitted:e,size:t}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o=[i,s,n].filter(Boolean).join(" ");this.state.prompt=o;let a=await this.header(),l=await this.format(),c=await this.error()||await this.hint(),u=await this.renderChoices(),g=await this.footer();(l||!c)&&(o+=" "+l),c&&!o.includes(c)&&(o+=" "+c),e&&!l&&!u&&this.multiple&&this.type!=="form"&&(o+=this.styles.danger(this.emptyError)),this.clear(t),this.write([o,a,u,g].filter(Boolean).join(` -`)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}};function bYe(r,e={}){if(Array.isArray(e.scale))return e.scale.map(i=>N({},i));let t=[];for(let i=1;i<r+1;i++)t.push({i,selected:!1});return t}pne.exports=dne});var Ene=w((Zft,mne)=>{mne.exports=nN()});var wne=w(($ft,Ine)=>{"use strict";var QYe=j0(),yne=class extends QYe{async initialize(){await super.initialize(),this.value=this.initial=!!this.options.initial,this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",t){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=i=>this.styles.primary.underline(i);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,t=await this.header(),i=await this.prefix(),n=await this.separator(),s=await this.message(),o=await this.format(),a=await this.error()||await this.hint(),l=await this.footer(),c=[i,s,n,o].join(" ");this.state.prompt=c,a&&!c.includes(a)&&(c+=" "+a),this.clear(e),this.write([t,c,l].filter(Boolean).join(` -`)),this.write(this.margin[2]),this.restore()}};Ine.exports=yne});var Qne=w((eht,Bne)=>{"use strict";var SYe=Ll(),bne=class extends SYe{constructor(e){super(e);if(typeof this.options.correctChoice!="number"||this.options.correctChoice<0)throw new Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,t){let i=await super.toChoices(e,t);if(i.length<2)throw new Error("Please give at least two choices to the user");if(this.options.correctChoice>i.length)throw new Error("Please specify the index of the correct answer from the list of choices");return i}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}};Bne.exports=bne});var vne=w(aN=>{"use strict";var Sne=Xi(),mi=(r,e)=>{Sne.defineExport(aN,r,e),Sne.defineExport(aN,r.toLowerCase(),e)};mi("AutoComplete",()=>pie());mi("BasicAuth",()=>Bie());mi("Confirm",()=>kie());mi("Editable",()=>Die());mi("Form",()=>H0());mi("Input",()=>nN());mi("Invisible",()=>Hie());mi("List",()=>Yie());mi("MultiSelect",()=>Wie());mi("Numeral",()=>Xie());mi("Password",()=>ene());mi("Scale",()=>nne());mi("Select",()=>Ll());mi("Snippet",()=>une());mi("Sort",()=>hne());mi("Survey",()=>Cne());mi("Text",()=>Ene());mi("Toggle",()=>wne());mi("Quiz",()=>Qne())});var xne=w((rht,kne)=>{kne.exports={ArrayPrompt:JC(),AuthPrompt:iN(),BooleanPrompt:j0(),NumberPrompt:sN(),StringPrompt:Bu()}});var zC=w((iht,Pne)=>{"use strict";var Dne=require("assert"),AN=require("events"),Tl=Xi(),pa=class extends AN{constructor(e,t){super();this.options=Tl.merge({},e),this.answers=N({},t)}register(e,t){if(Tl.isObject(e)){for(let n of Object.keys(e))this.register(n,e[n]);return this}Dne.equal(typeof t,"function","expected a function");let i=e.toLowerCase();return t.prototype instanceof this.Prompt?this.prompts[i]=t:this.prompts[i]=t(this.Prompt,this),this}async prompt(e=[]){for(let t of[].concat(e))try{typeof t=="function"&&(t=await t.call(this)),await this.ask(Tl.merge({},this.options,t))}catch(i){return Promise.reject(i)}return this.answers}async ask(e){typeof e=="function"&&(e=await e.call(this));let t=Tl.merge({},this.options,e),{type:i,name:n}=e,{set:s,get:o}=Tl;if(typeof i=="function"&&(i=await i.call(this,e,this.answers)),!i)return this.answers[n];Dne(this.prompts[i],`Prompt "${i}" is not registered`);let a=new this.prompts[i](t),l=o(this.answers,n);a.state.answers=this.answers,a.enquirer=this,n&&a.on("submit",u=>{this.emit("answer",n,u,a),s(this.answers,n,u)});let c=a.emit.bind(a);return a.emit=(...u)=>(this.emit.call(this,...u),c(...u)),this.emit("prompt",a,this),t.autofill&&l!=null?(a.value=a.input=l,t.autofill==="show"&&await a.submit()):l=a.value=await a.run(),l}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||Vf()}static get prompts(){return vne()}static get types(){return xne()}static get prompt(){let e=(t,...i)=>{let n=new this(...i),s=n.emit.bind(n);return n.emit=(...o)=>(e.emit(...o),s(...o)),n.prompt(t)};return Tl.mixinEmitter(e,new AN),e}};Tl.mixinEmitter(pa,new AN);var lN=pa.prompts;for(let r of Object.keys(lN)){let e=r.toLowerCase(),t=i=>new lN[r](i).run();pa.prompt[e]=t,pa[e]=t,pa[r]||Reflect.defineProperty(pa,r,{get:()=>lN[r]})}var WC=r=>{Tl.defineExport(pa,r,()=>pa.types[r])};WC("ArrayPrompt");WC("AuthPrompt");WC("BooleanPrompt");WC("NumberPrompt");WC("StringPrompt");Pne.exports=pa});var Yne=w((Jht,Gne)=>{function DYe(r,e){for(var t=-1,i=r==null?0:r.length;++t<i&&e(r[t],t,r)!==!1;);return r}Gne.exports=DYe});var $f=w((Wht,qne)=>{var RYe=e0(),FYe=Lf();function NYe(r,e,t,i){var n=!t;t||(t={});for(var s=-1,o=e.length;++s<o;){var a=e[s],l=i?i(t[a],r[a],a,t,r):void 0;l===void 0&&(l=r[a]),n?FYe(t,a,l):RYe(t,a,l)}return t}qne.exports=NYe});var Wne=w((zht,Jne)=>{var LYe=$f(),TYe=Kf();function OYe(r,e){return r&&LYe(e,TYe(e),r)}Jne.exports=OYe});var _ne=w((_ht,zne)=>{function MYe(r){var e=[];if(r!=null)for(var t in Object(r))e.push(t);return e}zne.exports=MYe});var Xne=w((Vht,Vne)=>{var UYe=Fn(),KYe=h0(),HYe=_ne(),jYe=Object.prototype,GYe=jYe.hasOwnProperty;function YYe(r){if(!UYe(r))return HYe(r);var e=KYe(r),t=[];for(var i in r)i=="constructor"&&(e||!GYe.call(r,i))||t.push(i);return t}Vne.exports=YYe});var eh=w((Xht,Zne)=>{var qYe=eF(),JYe=Xne(),WYe=kC();function zYe(r){return WYe(r)?qYe(r,!0):JYe(r)}Zne.exports=zYe});var ese=w((Zht,$ne)=>{var _Ye=$f(),VYe=eh();function XYe(r,e){return r&&_Ye(e,VYe(e),r)}$ne.exports=XYe});var pN=w((tm,th)=>{var ZYe=Ts(),tse=typeof tm=="object"&&tm&&!tm.nodeType&&tm,rse=tse&&typeof th=="object"&&th&&!th.nodeType&&th,$Ye=rse&&rse.exports===tse,ise=$Ye?ZYe.Buffer:void 0,nse=ise?ise.allocUnsafe:void 0;function eqe(r,e){if(e)return r.slice();var t=r.length,i=nse?nse(t):new r.constructor(t);return r.copy(i),i}th.exports=eqe});var dN=w(($ht,sse)=>{function tqe(r,e){var t=-1,i=r.length;for(e||(e=Array(i));++t<i;)e[t]=r[t];return e}sse.exports=tqe});var ase=w((ept,ose)=>{var rqe=$f(),iqe=d0();function nqe(r,e){return rqe(r,iqe(r),e)}ose.exports=nqe});var Y0=w((tpt,Ase)=>{var sqe=tF(),oqe=sqe(Object.getPrototypeOf,Object);Ase.exports=oqe});var CN=w((rpt,lse)=>{var aqe=r0(),Aqe=Y0(),lqe=d0(),cqe=aF(),uqe=Object.getOwnPropertySymbols,gqe=uqe?function(r){for(var e=[];r;)aqe(e,lqe(r)),r=Aqe(r);return e}:cqe;lse.exports=gqe});var use=w((ipt,cse)=>{var fqe=$f(),hqe=CN();function pqe(r,e){return fqe(r,hqe(r),e)}cse.exports=pqe});var fse=w((npt,gse)=>{var dqe=oF(),Cqe=CN(),mqe=eh();function Eqe(r){return dqe(r,mqe,Cqe)}gse.exports=Eqe});var pse=w((spt,hse)=>{var Iqe=Object.prototype,yqe=Iqe.hasOwnProperty;function wqe(r){var e=r.length,t=new r.constructor(e);return e&&typeof r[0]=="string"&&yqe.call(r,"index")&&(t.index=r.index,t.input=r.input),t}hse.exports=wqe});var q0=w((opt,dse)=>{var Cse=nF();function Bqe(r){var e=new r.constructor(r.byteLength);return new Cse(e).set(new Cse(r)),e}dse.exports=Bqe});var Ese=w((apt,mse)=>{var bqe=q0();function Qqe(r,e){var t=e?bqe(r.buffer):r.buffer;return new r.constructor(t,r.byteOffset,r.byteLength)}mse.exports=Qqe});var yse=w((Apt,Ise)=>{var Sqe=/\w*$/;function vqe(r){var e=new r.constructor(r.source,Sqe.exec(r));return e.lastIndex=r.lastIndex,e}Ise.exports=vqe});var Sse=w((lpt,wse)=>{var Bse=Wc(),bse=Bse?Bse.prototype:void 0,Qse=bse?bse.valueOf:void 0;function kqe(r){return Qse?Object(Qse.call(r)):{}}wse.exports=kqe});var mN=w((cpt,vse)=>{var xqe=q0();function Pqe(r,e){var t=e?xqe(r.buffer):r.buffer;return new r.constructor(t,r.byteOffset,r.length)}vse.exports=Pqe});var xse=w((upt,kse)=>{var Dqe=q0(),Rqe=Ese(),Fqe=yse(),Nqe=Sse(),Lqe=mN(),Tqe="[object Boolean]",Oqe="[object Date]",Mqe="[object Map]",Uqe="[object Number]",Kqe="[object RegExp]",Hqe="[object Set]",jqe="[object String]",Gqe="[object Symbol]",Yqe="[object ArrayBuffer]",qqe="[object DataView]",Jqe="[object Float32Array]",Wqe="[object Float64Array]",zqe="[object Int8Array]",_qe="[object Int16Array]",Vqe="[object Int32Array]",Xqe="[object Uint8Array]",Zqe="[object Uint8ClampedArray]",$qe="[object Uint16Array]",eJe="[object Uint32Array]";function tJe(r,e,t){var i=r.constructor;switch(e){case Yqe:return Dqe(r);case Tqe:case Oqe:return new i(+r);case qqe:return Rqe(r,t);case Jqe:case Wqe:case zqe:case _qe:case Vqe:case Xqe:case Zqe:case $qe:case eJe:return Lqe(r,t);case Mqe:return new i;case Uqe:case jqe:return new i(r);case Kqe:return Fqe(r);case Hqe:return new i;case Gqe:return Nqe(r)}}kse.exports=tJe});var Rse=w((gpt,Pse)=>{var rJe=Fn(),Dse=Object.create,iJe=function(){function r(){}return function(e){if(!rJe(e))return{};if(Dse)return Dse(e);r.prototype=e;var t=new r;return r.prototype=void 0,t}}();Pse.exports=iJe});var EN=w((fpt,Fse)=>{var nJe=Rse(),sJe=Y0(),oJe=h0();function aJe(r){return typeof r.constructor=="function"&&!oJe(r)?nJe(sJe(r)):{}}Fse.exports=aJe});var Lse=w((hpt,Nse)=>{var AJe=PC(),lJe=ra(),cJe="[object Map]";function uJe(r){return lJe(r)&&AJe(r)==cJe}Nse.exports=uJe});var Use=w((ppt,Tse)=>{var gJe=Lse(),fJe=u0(),Ose=g0(),Mse=Ose&&Ose.isMap,hJe=Mse?fJe(Mse):gJe;Tse.exports=hJe});var Hse=w((dpt,Kse)=>{var pJe=PC(),dJe=ra(),CJe="[object Set]";function mJe(r){return dJe(r)&&pJe(r)==CJe}Kse.exports=mJe});var qse=w((Cpt,jse)=>{var EJe=Hse(),IJe=u0(),Gse=g0(),Yse=Gse&&Gse.isSet,yJe=Yse?IJe(Yse):EJe;jse.exports=yJe});var Vse=w((mpt,Jse)=>{var wJe=xC(),BJe=Yne(),bJe=e0(),QJe=Wne(),SJe=ese(),vJe=pN(),kJe=dN(),xJe=ase(),PJe=use(),DJe=AF(),RJe=fse(),FJe=PC(),NJe=pse(),LJe=xse(),TJe=EN(),OJe=Hs(),MJe=QC(),UJe=Use(),KJe=Fn(),HJe=qse(),jJe=Kf(),GJe=eh(),YJe=1,qJe=2,JJe=4,Wse="[object Arguments]",WJe="[object Array]",zJe="[object Boolean]",_Je="[object Date]",VJe="[object Error]",zse="[object Function]",XJe="[object GeneratorFunction]",ZJe="[object Map]",$Je="[object Number]",_se="[object Object]",eWe="[object RegExp]",tWe="[object Set]",rWe="[object String]",iWe="[object Symbol]",nWe="[object WeakMap]",sWe="[object ArrayBuffer]",oWe="[object DataView]",aWe="[object Float32Array]",AWe="[object Float64Array]",lWe="[object Int8Array]",cWe="[object Int16Array]",uWe="[object Int32Array]",gWe="[object Uint8Array]",fWe="[object Uint8ClampedArray]",hWe="[object Uint16Array]",pWe="[object Uint32Array]",dr={};dr[Wse]=dr[WJe]=dr[sWe]=dr[oWe]=dr[zJe]=dr[_Je]=dr[aWe]=dr[AWe]=dr[lWe]=dr[cWe]=dr[uWe]=dr[ZJe]=dr[$Je]=dr[_se]=dr[eWe]=dr[tWe]=dr[rWe]=dr[iWe]=dr[gWe]=dr[fWe]=dr[hWe]=dr[pWe]=!0;dr[VJe]=dr[zse]=dr[nWe]=!1;function J0(r,e,t,i,n,s){var o,a=e&YJe,l=e&qJe,c=e&JJe;if(t&&(o=n?t(r,i,n,s):t(r)),o!==void 0)return o;if(!KJe(r))return r;var u=OJe(r);if(u){if(o=NJe(r),!a)return kJe(r,o)}else{var g=FJe(r),f=g==zse||g==XJe;if(MJe(r))return vJe(r,a);if(g==_se||g==Wse||f&&!n){if(o=l||f?{}:TJe(r),!a)return l?PJe(r,SJe(o,r)):xJe(r,QJe(o,r))}else{if(!dr[g])return n?r:{};o=LJe(r,g,a)}}s||(s=new wJe);var h=s.get(r);if(h)return h;s.set(r,o),HJe(r)?r.forEach(function(y){o.add(J0(y,e,t,y,r,s))}):UJe(r)&&r.forEach(function(y,b){o.set(b,J0(y,e,t,b,r,s))});var p=c?l?RJe:DJe:l?GJe:jJe,m=u?void 0:p(r);return BJe(m||r,function(y,b){m&&(b=y,y=r[b]),bJe(o,b,J0(y,e,t,b,r,s))}),o}Jse.exports=J0});var IN=w((Ept,Xse)=>{var dWe=Vse(),CWe=1,mWe=4;function EWe(r){return dWe(r,CWe|mWe)}Xse.exports=EWe});var $se=w((Ipt,Zse)=>{var IWe=PR();function yWe(r,e,t){return r==null?r:IWe(r,e,t)}Zse.exports=yWe});var soe=w((Spt,noe)=>{function wWe(r){var e=r==null?0:r.length;return e?r[e-1]:void 0}noe.exports=wWe});var aoe=w((vpt,ooe)=>{var BWe=pC(),bWe=XP();function QWe(r,e){return e.length<2?r:BWe(r,bWe(e,0,-1))}ooe.exports=QWe});var loe=w((kpt,Aoe)=>{var SWe=Nf(),vWe=soe(),kWe=aoe(),xWe=fu();function PWe(r,e){return e=SWe(e,r),r=kWe(r,e),r==null||delete r[xWe(vWe(e))]}Aoe.exports=PWe});var uoe=w((xpt,coe)=>{var DWe=loe();function RWe(r,e){return r==null?!0:DWe(r,e)}coe.exports=RWe});var Ioe=w((sdt,Eoe)=>{Eoe.exports={name:"@yarnpkg/cli",version:"3.2.3",license:"BSD-2-Clause",main:"./sources/index.ts",dependencies:{"@yarnpkg/core":"workspace:^","@yarnpkg/fslib":"workspace:^","@yarnpkg/libzip":"workspace:^","@yarnpkg/parsers":"workspace:^","@yarnpkg/plugin-compat":"workspace:^","@yarnpkg/plugin-dlx":"workspace:^","@yarnpkg/plugin-essentials":"workspace:^","@yarnpkg/plugin-file":"workspace:^","@yarnpkg/plugin-git":"workspace:^","@yarnpkg/plugin-github":"workspace:^","@yarnpkg/plugin-http":"workspace:^","@yarnpkg/plugin-init":"workspace:^","@yarnpkg/plugin-link":"workspace:^","@yarnpkg/plugin-nm":"workspace:^","@yarnpkg/plugin-npm":"workspace:^","@yarnpkg/plugin-npm-cli":"workspace:^","@yarnpkg/plugin-pack":"workspace:^","@yarnpkg/plugin-patch":"workspace:^","@yarnpkg/plugin-pnp":"workspace:^","@yarnpkg/plugin-pnpm":"workspace:^","@yarnpkg/shell":"workspace:^",chalk:"^3.0.0","ci-info":"^3.2.0",clipanion:"3.2.0-rc.4",semver:"^7.1.2",tslib:"^1.13.0",typanion:"^3.3.0",yup:"^0.32.9"},devDependencies:{"@types/semver":"^7.1.0","@types/yup":"^0","@yarnpkg/builder":"workspace:^","@yarnpkg/monorepo":"workspace:^","@yarnpkg/pnpify":"workspace:^",micromatch:"^4.0.2"},peerDependencies:{"@yarnpkg/core":"workspace:^"},scripts:{postpack:"rm -rf lib",prepack:'run build:compile "$(pwd)"',"build:cli+hook":"run build:pnp:hook && builder build bundle","build:cli":"builder build bundle","run:cli":"builder run","update-local":"run build:cli --no-git-hash && rsync -a --delete bundles/ bin/"},publishConfig:{main:"./lib/index.js",types:"./lib/index.d.ts",bin:null},files:["/lib/**/*","!/lib/pluginConfiguration.*","!/lib/cli.*"],"@yarnpkg/builder":{bundles:{standard:["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm"]}},repository:{type:"git",url:"ssh://git@github.com/yarnpkg/berry.git",directory:"packages/yarnpkg-cli"},engines:{node:">=12 <14 || 14.2 - 14.9 || >14.10.0"}}});var RN=w((OEt,oae)=>{"use strict";oae.exports=function(e,t){t===!0&&(t=0);var i=e.indexOf("://"),n=e.substring(0,i).split("+").filter(Boolean);return typeof t=="number"?n[t]:n}});var FN=w((MEt,aae)=>{"use strict";var $We=RN();function Aae(r){if(Array.isArray(r))return r.indexOf("ssh")!==-1||r.indexOf("rsync")!==-1;if(typeof r!="string")return!1;var e=$We(r);return r=r.substring(r.indexOf("://")+3),Aae(e)?!0:r.indexOf("@")<r.indexOf(":")}aae.exports=Aae});var cae=w((UEt,lae)=>{"use strict";var e3e=RN(),t3e=FN(),r3e=require("querystring");function i3e(r){r=(r||"").trim();var e={protocols:e3e(r),protocol:null,port:null,resource:"",user:"",pathname:"",hash:"",search:"",href:r,query:Object.create(null)},t=r.indexOf("://"),i=-1,n=null,s=null;r.startsWith(".")&&(r.startsWith("./")&&(r=r.substring(2)),e.pathname=r,e.protocol="file");var o=r.charAt(1);return e.protocol||(e.protocol=e.protocols[0],e.protocol||(t3e(r)?e.protocol="ssh":((o==="/"||o==="~")&&(r=r.substring(2)),e.protocol="file"))),t!==-1&&(r=r.substring(t+3)),s=r.split("/"),e.protocol!=="file"?e.resource=s.shift():e.resource="",n=e.resource.split("@"),n.length===2&&(e.user=n[0],e.resource=n[1]),n=e.resource.split(":"),n.length===2&&(e.resource=n[0],n[1]?(e.port=Number(n[1]),isNaN(e.port)&&(e.port=null,s.unshift(n[1]))):e.port=null),s=s.filter(Boolean),e.protocol==="file"?e.pathname=e.href:e.pathname=e.pathname||(e.protocol!=="file"||e.href[0]==="/"?"/":"")+s.join("/"),n=e.pathname.split("#"),n.length===2&&(e.pathname=n[0],e.hash=n[1]),n=e.pathname.split("?"),n.length===2&&(e.pathname=n[0],e.search=n[1]),e.query=r3e.parse(e.search),e.href=e.href.replace(/\/$/,""),e.pathname=e.pathname.replace(/\/$/,""),e}lae.exports=i3e});var fae=w((KEt,uae)=>{"use strict";var n3e="text/plain",s3e="us-ascii",gae=(r,e)=>e.some(t=>t instanceof RegExp?t.test(r):t===r),o3e=(r,{stripHash:e})=>{let t=/^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(r);if(!t)throw new Error(`Invalid URL: ${r}`);let{type:i,data:n,hash:s}=t.groups,o=i.split(";");s=e?"":s;let a=!1;o[o.length-1]==="base64"&&(o.pop(),a=!0);let l=(o.shift()||"").toLowerCase(),u=[...o.map(g=>{let[f,h=""]=g.split("=").map(p=>p.trim());return f==="charset"&&(h=h.toLowerCase(),h===s3e)?"":`${f}${h?`=${h}`:""}`}).filter(Boolean)];return a&&u.push("base64"),(u.length!==0||l&&l!==n3e)&&u.unshift(l),`data:${u.join(";")},${a?n.trim():n}${s?`#${s}`:""}`},a3e=(r,e)=>{if(e=N({defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripTextFragment:!0,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeSingleSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0},e),r=r.trim(),/^data:/i.test(r))return o3e(r,e);if(/^view-source:/i.test(r))throw new Error("`view-source:` is not supported as it is a non-standard protocol");let t=r.startsWith("//");!t&&/^\.*\//.test(r)||(r=r.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new URL(r);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&n.protocol==="https:"&&(n.protocol="http:"),e.forceHttps&&n.protocol==="http:"&&(n.protocol="https:"),e.stripAuthentication&&(n.username="",n.password=""),e.stripHash?n.hash="":e.stripTextFragment&&(n.hash=n.hash.replace(/#?:~:text.*?$/i,"")),n.pathname&&(n.pathname=n.pathname.replace(/(?<!\b(?:[a-z][a-z\d+\-.]{1,50}:))\/{2,}/g,"/")),n.pathname)try{n.pathname=decodeURI(n.pathname)}catch(o){}if(e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let o=n.pathname.split("/"),a=o[o.length-1];gae(a,e.removeDirectoryIndex)&&(o=o.slice(0,o.length-1),n.pathname=o.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.(?!www\.)(?:[a-z\-\d]{1,63})\.(?:[a-z.\-\d]{2,63})$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let o of[...n.searchParams.keys()])gae(o,e.removeQueryParameters)&&n.searchParams.delete(o);e.removeQueryParameters===!0&&(n.search=""),e.sortQueryParameters&&n.searchParams.sort(),e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,""));let s=r;return r=n.toString(),!e.removeSingleSlash&&n.pathname==="/"&&!s.endsWith("/")&&n.hash===""&&(r=r.replace(/\/$/,"")),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&e.removeSingleSlash&&(r=r.replace(/\/$/,"")),t&&!e.normalizeProtocol&&(r=r.replace(/^http:\/\//,"//")),e.stripProtocol&&(r=r.replace(/^(?:https?:)?\/\//,"")),r};uae.exports=a3e});var pae=w((HEt,hae)=>{"use strict";var A3e=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},l3e=cae(),c3e=fae();function u3e(r){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(typeof r!="string"||!r.trim())throw new Error("Invalid url.");e&&((typeof e=="undefined"?"undefined":A3e(e))!=="object"&&(e={stripHash:!1}),r=c3e(r,e));var t=l3e(r);return t}hae.exports=u3e});var mae=w((jEt,dae)=>{"use strict";var g3e=pae(),Cae=FN();function f3e(r){var e=g3e(r);e.token="";var t=e.user.split(":");return t.length===2&&(t[1]==="x-oauth-basic"?e.token=t[0]:t[0]==="x-token-auth"&&(e.token=t[1])),Cae(e.protocols)||Cae(r)?e.protocol="ssh":e.protocols.length?e.protocol=e.protocols[0]:e.protocol="file",e.href=e.href.replace(/\/$/,""),e}dae.exports=f3e});var Iae=w((GEt,Eae)=>{"use strict";var h3e=mae();function NN(r){if(typeof r!="string")throw new Error("The url must be a string.");var e=h3e(r),t=e.resource.split("."),i=null;switch(e.toString=function(l){return NN.stringify(this,l)},e.source=t.length>2?t.slice(1-t.length).join("."):e.source=e.resource,e.git_suffix=/\.git$/.test(e.pathname),e.name=decodeURIComponent(e.pathname.replace(/^\//,"").replace(/\.git$/,"")),e.owner=decodeURIComponent(e.user),e.source){case"git.cloudforge.com":e.owner=e.user,e.organization=t[0],e.source="cloudforge.com";break;case"visualstudio.com":if(e.resource==="vs-ssh.visualstudio.com"){i=e.name.split("/"),i.length===4&&(e.organization=i[1],e.owner=i[2],e.name=i[3],e.full_name=i[2]+"/"+i[3]);break}else{i=e.name.split("/"),i.length===2?(e.owner=i[1],e.name=i[1],e.full_name="_git/"+e.name):i.length===3?(e.name=i[2],i[0]==="DefaultCollection"?(e.owner=i[2],e.organization=i[0],e.full_name=e.organization+"/_git/"+e.name):(e.owner=i[0],e.full_name=e.owner+"/_git/"+e.name)):i.length===4&&(e.organization=i[0],e.owner=i[1],e.name=i[3],e.full_name=e.organization+"/"+e.owner+"/_git/"+e.name);break}case"dev.azure.com":case"azure.com":if(e.resource==="ssh.dev.azure.com"){i=e.name.split("/"),i.length===4&&(e.organization=i[1],e.owner=i[2],e.name=i[3]);break}else{i=e.name.split("/"),i.length===5?(e.organization=i[0],e.owner=i[1],e.name=i[4],e.full_name="_git/"+e.name):i.length===3?(e.name=i[2],i[0]==="DefaultCollection"?(e.owner=i[2],e.organization=i[0],e.full_name=e.organization+"/_git/"+e.name):(e.owner=i[0],e.full_name=e.owner+"/_git/"+e.name)):i.length===4&&(e.organization=i[0],e.owner=i[1],e.name=i[3],e.full_name=e.organization+"/"+e.owner+"/_git/"+e.name);break}default:i=e.name.split("/");var n=i.length-1;if(i.length>=2){var s=i.indexOf("blob",2),o=i.indexOf("tree",2),a=i.indexOf("commit",2);n=s>0?s-1:o>0?o-1:a>0?a-1:n,e.owner=i.slice(0,n).join("/"),e.name=i[n],a&&(e.commit=i[n+2])}e.ref="",e.filepathtype="",e.filepath="",i.length>n+2&&["blob","tree"].indexOf(i[n+1])>=0&&(e.filepathtype=i[n+1],e.ref=i[n+2],i.length>n+3&&(e.filepath=i.slice(n+3).join("/"))),e.organization=e.owner;break}return e.full_name||(e.full_name=e.owner,e.name&&(e.full_name&&(e.full_name+="/"),e.full_name+=e.name)),e}NN.stringify=function(r,e){e=e||(r.protocols&&r.protocols.length?r.protocols.join("+"):r.protocol);var t=r.port?":"+r.port:"",i=r.user||"git",n=r.git_suffix?".git":"";switch(e){case"ssh":return t?"ssh://"+i+"@"+r.resource+t+"/"+r.full_name+n:i+"@"+r.resource+":"+r.full_name+n;case"git+ssh":case"ssh+git":case"ftp":case"ftps":return e+"://"+i+"@"+r.resource+t+"/"+r.full_name+n;case"http":case"https":var s=r.token?p3e(r):r.user&&(r.protocols.includes("http")||r.protocols.includes("https"))?r.user+"@":"";return e+"://"+s+r.resource+t+"/"+r.full_name+n;default:return r.href}};function p3e(r){switch(r.source){case"bitbucket.org":return"x-token-auth:"+r.token+"@";default:return r.token+"@"}}Eae.exports=NN});var uL=w((Zwt,jae)=>{var N3e=Lf(),L3e=Df();function T3e(r,e,t){(t!==void 0&&!L3e(r[e],t)||t===void 0&&!(e in r))&&N3e(r,e,t)}jae.exports=T3e});var Yae=w(($wt,Gae)=>{var O3e=kC(),M3e=ra();function U3e(r){return M3e(r)&&O3e(r)}Gae.exports=U3e});var Wae=w((eBt,qae)=>{var K3e=zc(),H3e=Y0(),j3e=ra(),G3e="[object Object]",Y3e=Function.prototype,q3e=Object.prototype,Jae=Y3e.toString,J3e=q3e.hasOwnProperty,W3e=Jae.call(Object);function z3e(r){if(!j3e(r)||K3e(r)!=G3e)return!1;var e=H3e(r);if(e===null)return!0;var t=J3e.call(e,"constructor")&&e.constructor;return typeof t=="function"&&t instanceof t&&Jae.call(t)==W3e}qae.exports=z3e});var gL=w((tBt,zae)=>{function _3e(r,e){if(!(e==="constructor"&&typeof r[e]=="function")&&e!="__proto__")return r[e]}zae.exports=_3e});var Vae=w((rBt,_ae)=>{var V3e=$f(),X3e=eh();function Z3e(r){return V3e(r,X3e(r))}_ae.exports=Z3e});var rAe=w((iBt,Xae)=>{var Zae=uL(),$3e=pN(),e4e=mN(),t4e=dN(),r4e=EN(),$ae=CC(),eAe=Hs(),i4e=Yae(),n4e=QC(),s4e=XB(),o4e=Fn(),a4e=Wae(),A4e=f0(),tAe=gL(),l4e=Vae();function c4e(r,e,t,i,n,s,o){var a=tAe(r,t),l=tAe(e,t),c=o.get(l);if(c){Zae(r,t,c);return}var u=s?s(a,l,t+"",r,e,o):void 0,g=u===void 0;if(g){var f=eAe(l),h=!f&&n4e(l),p=!f&&!h&&A4e(l);u=l,f||h||p?eAe(a)?u=a:i4e(a)?u=t4e(a):h?(g=!1,u=$3e(l,!0)):p?(g=!1,u=e4e(l,!0)):u=[]:a4e(l)||$ae(l)?(u=a,$ae(a)?u=l4e(a):(!o4e(a)||s4e(a))&&(u=r4e(l))):g=!1}g&&(o.set(l,u),n(u,l,i,s,o),o.delete(l)),Zae(r,t,u)}Xae.exports=c4e});var sAe=w((nBt,iAe)=>{var u4e=xC(),g4e=uL(),f4e=ZR(),h4e=rAe(),p4e=Fn(),d4e=eh(),C4e=gL();function nAe(r,e,t,i,n){r!==e&&f4e(e,function(s,o){if(n||(n=new u4e),p4e(s))h4e(r,e,o,t,nAe,i,n);else{var a=i?i(C4e(r,o),s,o+"",r,e,n):void 0;a===void 0&&(a=s),g4e(r,o,a)}},d4e)}iAe.exports=nAe});var aAe=w((sBt,oAe)=>{var m4e=i0(),E4e=FR(),I4e=NR();function y4e(r,e){return I4e(E4e(r,e,m4e),r+"")}oAe.exports=y4e});var lAe=w((oBt,AAe)=>{var w4e=Df(),B4e=kC(),b4e=dC(),Q4e=Fn();function S4e(r,e,t){if(!Q4e(t))return!1;var i=typeof e;return(i=="number"?B4e(t)&&b4e(e,t.length):i=="string"&&e in t)?w4e(t[e],r):!1}AAe.exports=S4e});var uAe=w((aBt,cAe)=>{var v4e=aAe(),k4e=lAe();function x4e(r){return v4e(function(e,t){var i=-1,n=t.length,s=n>1?t[n-1]:void 0,o=n>2?t[2]:void 0;for(s=r.length>3&&typeof s=="function"?(n--,s):void 0,o&&k4e(t[0],t[1],o)&&(s=n<3?void 0:s,n=1),e=Object(e);++i<n;){var a=t[i];a&&r(e,a,i,s)}return e})}cAe.exports=x4e});var fAe=w((ABt,gAe)=>{var P4e=sAe(),D4e=uAe(),R4e=D4e(function(r,e,t){P4e(r,e,t)});gAe.exports=R4e});var xAe=w((f0t,kAe)=>{var SL;kAe.exports=()=>(typeof SL=="undefined"&&(SL=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),SL)});var KAe=w((J0t,UAe)=>{var PL;UAe.exports=()=>(typeof PL=="undefined"&&(PL=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),PL)});var zAe=w((OL,ML)=>{(function(r){OL&&typeof OL=="object"&&typeof ML!="undefined"?ML.exports=r():typeof define=="function"&&define.amd?define([],r):typeof window!="undefined"?window.isWindows=r():typeof global!="undefined"?global.isWindows=r():typeof self!="undefined"?self.isWindows=r():this.isWindows=r()})(function(){"use strict";return function(){return process&&(process.platform==="win32"||/^(msys|cygwin)$/.test(process.env.OSTYPE))}})});var ZAe=w((Zbt,_Ae)=>{"use strict";UL.ifExists=Ize;var Ah=require("util"),Vs=require("path"),VAe=zAe(),yze=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,wze={createPwshFile:!0,createCmdFile:VAe(),fs:require("fs")},Bze=new Map([[".js","node"],[".cjs","node"],[".mjs","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function XAe(r){let e=N(N({},wze),r),t=e.fs;return e.fs_={chmod:t.chmod?Ah.promisify(t.chmod):async()=>{},mkdir:Ah.promisify(t.mkdir),readFile:Ah.promisify(t.readFile),stat:Ah.promisify(t.stat),unlink:Ah.promisify(t.unlink),writeFile:Ah.promisify(t.writeFile)},e}async function UL(r,e,t){let i=XAe(t);await i.fs_.stat(r),await bze(r,e,i)}function Ize(r,e,t){return UL(r,e,t).catch(()=>{})}function Qze(r,e){return e.fs_.unlink(r).catch(()=>{})}async function bze(r,e,t){let i=await kze(r,t);return await Sze(e,t),vze(r,e,i,t)}function Sze(r,e){return e.fs_.mkdir(Vs.dirname(r),{recursive:!0})}function vze(r,e,t,i){let n=XAe(i),s=[{generator:Dze,extension:""}];return n.createCmdFile&&s.push({generator:Pze,extension:".cmd"}),n.createPwshFile&&s.push({generator:Rze,extension:".ps1"}),Promise.all(s.map(o=>xze(r,e+o.extension,t,o.generator,n)))}function Fze(r,e){return Qze(r,e)}function Lze(r,e){return Nze(r,e)}async function kze(r,e){let n=(await e.fs_.readFile(r,"utf8")).trim().split(/\r*\n/)[0].match(yze);if(!n){let s=Vs.extname(r).toLowerCase();return{program:Bze.get(s)||null,additionalArgs:""}}return{program:n[1],additionalArgs:n[2]}}async function xze(r,e,t,i,n){let s=n.preserveSymlinks?"--preserve-symlinks":"",o=[t.additionalArgs,s].filter(a=>a).join(" ");return n=Object.assign({},n,{prog:t.program,args:o}),await Fze(e,n),await n.fs_.writeFile(e,i(r,e,n),"utf8"),Lze(e,n)}function Pze(r,e,t){let n=Vs.relative(Vs.dirname(e),r).split("/").join("\\"),s=Vs.isAbsolute(n)?`"${n}"`:`"%~dp0\\${n}"`,o,a=t.prog,l=t.args||"",c=KL(t.nodePath).win32;a?(o=`"%~dp0\\${a}.exe"`,n=s):(a=s,l="",n="");let u=t.progArgs?`${t.progArgs.join(" ")} `:"",g=c?`@SET NODE_PATH=${c}\r -`:"";return o?g+=`@IF EXIST ${o} (\r - ${o} ${l} ${n} ${u}%*\r -) ELSE (\r - @SETLOCAL\r - @SET PATHEXT=%PATHEXT:;.JS;=;%\r - ${a} ${l} ${n} ${u}%*\r -)\r -`:g+=`@${a} ${l} ${n} ${u}%*\r -`,g}function Dze(r,e,t){let i=Vs.relative(Vs.dirname(e),r),n=t.prog&&t.prog.split("\\").join("/"),s;i=i.split("\\").join("/");let o=Vs.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,a=t.args||"",l=KL(t.nodePath).posix;n?(s=`"$basedir/${t.prog}"`,i=o):(n=o,a="",i="");let c=t.progArgs?`${t.progArgs.join(" ")} `:"",u=`#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") - -case \`uname\` in - *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;; -esac - -`,g=t.nodePath?`export NODE_PATH="${l}" -`:"";return s?u+=`${g}if [ -x ${s} ]; then - exec ${s} ${a} ${i} ${c}"$@" -else - exec ${n} ${a} ${i} ${c}"$@" -fi -`:u+=`${g}${n} ${a} ${i} ${c}"$@" -exit $? -`,u}function Rze(r,e,t){let i=Vs.relative(Vs.dirname(e),r),n=t.prog&&t.prog.split("\\").join("/"),s=n&&`"${n}$exe"`,o;i=i.split("\\").join("/");let a=Vs.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,l=t.args||"",c=KL(t.nodePath),u=c.win32,g=c.posix;s?(o=`"$basedir/${t.prog}$exe"`,i=a):(s=a,l="",i="");let f=t.progArgs?`${t.progArgs.join(" ")} `:"",h=`#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -${t.nodePath?`$env_node_path=$env:NODE_PATH -$env:NODE_PATH="${u}" -`:""}if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -}`;return t.nodePath&&(h+=` else { - $env:NODE_PATH="${g}" -}`),o?h+=` -$ret=0 -if (Test-Path ${o}) { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & ${o} ${l} ${i} ${f}$args - } else { - & ${o} ${l} ${i} ${f}$args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & ${s} ${l} ${i} ${f}$args - } else { - & ${s} ${l} ${i} ${f}$args - } - $ret=$LASTEXITCODE -} -${t.nodePath?`$env:NODE_PATH=$env_node_path -`:""}exit $ret -`:h+=` -# Support pipeline input -if ($MyInvocation.ExpectingInput) { - $input | & ${s} ${l} ${i} ${f}$args -} else { - & ${s} ${l} ${i} ${f}$args -} -${t.nodePath?`$env:NODE_PATH=$env_node_path -`:""}exit $LASTEXITCODE -`,h}function Nze(r,e){return e.fs_.chmod(r,493)}function KL(r){if(!r)return{win32:"",posix:""};let e=typeof r=="string"?r.split(Vs.delimiter):Array.from(r),t={};for(let i=0;i<e.length;i++){let n=e[i].split("/").join("\\"),s=VAe()?e[i].split("\\").join("/").replace(/^([^:\\/]*):/,(o,a)=>`/mnt/${a.toLowerCase()}`):e[i];t.win32=t.win32?`${t.win32};${n}`:n,t.posix=t.posix?`${t.posix}:${s}`:s,t[i]={win32:n,posix:s}}return t}_Ae.exports=UL});var tT=w((NSt,mle)=>{mle.exports=require("stream")});var wle=w((LSt,Ele)=>{"use strict";function Ile(r,e){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable})),t.push.apply(t,i)}return t}function t8e(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?arguments[e]:{};e%2?Ile(Object(t),!0).forEach(function(i){e8e(r,i,t[i])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(t)):Ile(Object(t)).forEach(function(i){Object.defineProperty(r,i,Object.getOwnPropertyDescriptor(t,i))})}return r}function e8e(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}function r8e(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}function yle(r,e){for(var t=0;t<e.length;t++){var i=e[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(r,i.key,i)}}function i8e(r,e,t){return e&&yle(r.prototype,e),t&&yle(r,t),r}var n8e=require("buffer"),cb=n8e.Buffer,s8e=require("util"),rT=s8e.inspect,o8e=rT&&rT.custom||"inspect";function a8e(r,e,t){cb.prototype.copy.call(r,e,t)}Ele.exports=function(){function r(){r8e(this,r),this.head=null,this.tail=null,this.length=0}return i8e(r,[{key:"push",value:function(t){var i={data:t,next:null};this.length>0?this.tail.next=i:this.head=i,this.tail=i,++this.length}},{key:"unshift",value:function(t){var i={data:t,next:this.head};this.length===0&&(this.tail=i),this.head=i,++this.length}},{key:"shift",value:function(){if(this.length!==0){var t=this.head.data;return this.length===1?this.head=this.tail=null:this.head=this.head.next,--this.length,t}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(t){if(this.length===0)return"";for(var i=this.head,n=""+i.data;i=i.next;)n+=t+i.data;return n}},{key:"concat",value:function(t){if(this.length===0)return cb.alloc(0);for(var i=cb.allocUnsafe(t>>>0),n=this.head,s=0;n;)a8e(n.data,i,s),s+=n.data.length,n=n.next;return i}},{key:"consume",value:function(t,i){var n;return t<this.head.data.length?(n=this.head.data.slice(0,t),this.head.data=this.head.data.slice(t)):t===this.head.data.length?n=this.shift():n=i?this._getString(t):this._getBuffer(t),n}},{key:"first",value:function(){return this.head.data}},{key:"_getString",value:function(t){var i=this.head,n=1,s=i.data;for(t-=s.length;i=i.next;){var o=i.data,a=t>o.length?o.length:t;if(a===o.length?s+=o:s+=o.slice(0,t),t-=a,t===0){a===o.length?(++n,i.next?this.head=i.next:this.head=this.tail=null):(this.head=i,i.data=o.slice(a));break}++n}return this.length-=n,s}},{key:"_getBuffer",value:function(t){var i=cb.allocUnsafe(t),n=this.head,s=1;for(n.data.copy(i),t-=n.data.length;n=n.next;){var o=n.data,a=t>o.length?o.length:t;if(o.copy(i,i.length-t,0,a),t-=a,t===0){a===o.length?(++s,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=o.slice(a));break}++s}return this.length-=s,i}},{key:o8e,value:function(t,i){return rT(this,t8e({},i,{depth:0,customInspect:!1}))}}]),r}()});var nT=w((TSt,Ble)=>{"use strict";function A8e(r,e){var t=this,i=this._readableState&&this._readableState.destroyed,n=this._writableState&&this._writableState.destroyed;return i||n?(e?e(r):r&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(iT,this,r)):process.nextTick(iT,this,r)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(r||null,function(s){!e&&s?t._writableState?t._writableState.errorEmitted?process.nextTick(ub,t):(t._writableState.errorEmitted=!0,process.nextTick(ble,t,s)):process.nextTick(ble,t,s):e?(process.nextTick(ub,t),e(s)):process.nextTick(ub,t)}),this)}function ble(r,e){iT(r,e),ub(r)}function ub(r){r._writableState&&!r._writableState.emitClose||r._readableState&&!r._readableState.emitClose||r.emit("close")}function l8e(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}function iT(r,e){r.emit("error",e)}function c8e(r,e){var t=r._readableState,i=r._writableState;t&&t.autoDestroy||i&&i.autoDestroy?r.destroy(e):r.emit("error",e)}Ble.exports={destroy:A8e,undestroy:l8e,errorOrDestroy:c8e}});var Hl=w((OSt,Qle)=>{"use strict";var Sle={};function Xs(r,e,t){t||(t=Error);function i(s,o,a){return typeof e=="string"?e:e(s,o,a)}class n extends t{constructor(o,a,l){super(i(o,a,l))}}n.prototype.name=t.name,n.prototype.code=r,Sle[r]=n}function vle(r,e){if(Array.isArray(r)){let t=r.length;return r=r.map(i=>String(i)),t>2?`one of ${e} ${r.slice(0,t-1).join(", ")}, or `+r[t-1]:t===2?`one of ${e} ${r[0]} or ${r[1]}`:`of ${e} ${r[0]}`}else return`of ${e} ${String(r)}`}function u8e(r,e,t){return r.substr(!t||t<0?0:+t,e.length)===e}function g8e(r,e,t){return(t===void 0||t>r.length)&&(t=r.length),r.substring(t-e.length,t)===e}function f8e(r,e,t){return typeof t!="number"&&(t=0),t+e.length>r.length?!1:r.indexOf(e,t)!==-1}Xs("ERR_INVALID_OPT_VALUE",function(r,e){return'The value "'+e+'" is invalid for option "'+r+'"'},TypeError);Xs("ERR_INVALID_ARG_TYPE",function(r,e,t){let i;typeof e=="string"&&u8e(e,"not ")?(i="must not be",e=e.replace(/^not /,"")):i="must be";let n;if(g8e(r," argument"))n=`The ${r} ${i} ${vle(e,"type")}`;else{let s=f8e(r,".")?"property":"argument";n=`The "${r}" ${s} ${i} ${vle(e,"type")}`}return n+=`. Received type ${typeof t}`,n},TypeError);Xs("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");Xs("ERR_METHOD_NOT_IMPLEMENTED",function(r){return"The "+r+" method is not implemented"});Xs("ERR_STREAM_PREMATURE_CLOSE","Premature close");Xs("ERR_STREAM_DESTROYED",function(r){return"Cannot call "+r+" after a stream was destroyed"});Xs("ERR_MULTIPLE_CALLBACK","Callback called multiple times");Xs("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");Xs("ERR_STREAM_WRITE_AFTER_END","write after end");Xs("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);Xs("ERR_UNKNOWN_ENCODING",function(r){return"Unknown encoding: "+r},TypeError);Xs("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");Qle.exports.codes=Sle});var sT=w((MSt,kle)=>{"use strict";var h8e=Hl().codes.ERR_INVALID_OPT_VALUE;function p8e(r,e,t){return r.highWaterMark!=null?r.highWaterMark:e?r[t]:null}function d8e(r,e,t,i){var n=p8e(e,i,t);if(n!=null){if(!(isFinite(n)&&Math.floor(n)===n)||n<0){var s=i?t:"highWaterMark";throw new h8e(s,n)}return Math.floor(n)}return r.objectMode?16:16*1024}kle.exports={getHighWaterMark:d8e}});var xle=w((USt,oT)=>{typeof Object.create=="function"?oT.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:oT.exports=function(e,t){if(t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}}});var jl=w((KSt,aT)=>{try{if(AT=require("util"),typeof AT.inherits!="function")throw"";aT.exports=AT.inherits}catch(r){aT.exports=xle()}var AT});var Dle=w((HSt,Ple)=>{Ple.exports=require("util").deprecate});var uT=w((jSt,Rle)=>{"use strict";Rle.exports=Gr;function Fle(r){var e=this;this.next=null,this.entry=null,this.finish=function(){C8e(e,r)}}var uh;Gr.WritableState=Ym;var m8e={deprecate:Dle()},Nle=tT(),gb=require("buffer").Buffer,E8e=global.Uint8Array||function(){};function I8e(r){return gb.from(r)}function y8e(r){return gb.isBuffer(r)||r instanceof E8e}var lT=nT(),w8e=sT(),B8e=w8e.getHighWaterMark,Gl=Hl().codes,b8e=Gl.ERR_INVALID_ARG_TYPE,Q8e=Gl.ERR_METHOD_NOT_IMPLEMENTED,S8e=Gl.ERR_MULTIPLE_CALLBACK,v8e=Gl.ERR_STREAM_CANNOT_PIPE,k8e=Gl.ERR_STREAM_DESTROYED,x8e=Gl.ERR_STREAM_NULL_VALUES,P8e=Gl.ERR_STREAM_WRITE_AFTER_END,D8e=Gl.ERR_UNKNOWN_ENCODING,gh=lT.errorOrDestroy;jl()(Gr,Nle);function R8e(){}function Ym(r,e,t){uh=uh||Pu(),r=r||{},typeof t!="boolean"&&(t=e instanceof uh),this.objectMode=!!r.objectMode,t&&(this.objectMode=this.objectMode||!!r.writableObjectMode),this.highWaterMark=B8e(this,r,"writableHighWaterMark",t),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var i=r.decodeStrings===!1;this.decodeStrings=!i,this.defaultEncoding=r.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(n){F8e(e,n)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=r.emitClose!==!1,this.autoDestroy=!!r.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new Fle(this)}Ym.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t};(function(){try{Object.defineProperty(Ym.prototype,"buffer",{get:m8e.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(r){}})();var fb;typeof Symbol=="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]=="function"?(fb=Function.prototype[Symbol.hasInstance],Object.defineProperty(Gr,Symbol.hasInstance,{value:function(e){return fb.call(this,e)?!0:this!==Gr?!1:e&&e._writableState instanceof Ym}})):fb=function(e){return e instanceof this};function Gr(r){uh=uh||Pu();var e=this instanceof uh;if(!e&&!fb.call(Gr,this))return new Gr(r);this._writableState=new Ym(r,this,e),this.writable=!0,r&&(typeof r.write=="function"&&(this._write=r.write),typeof r.writev=="function"&&(this._writev=r.writev),typeof r.destroy=="function"&&(this._destroy=r.destroy),typeof r.final=="function"&&(this._final=r.final)),Nle.call(this)}Gr.prototype.pipe=function(){gh(this,new v8e)};function N8e(r,e){var t=new P8e;gh(r,t),process.nextTick(e,t)}function L8e(r,e,t,i){var n;return t===null?n=new x8e:typeof t!="string"&&!e.objectMode&&(n=new b8e("chunk",["string","Buffer"],t)),n?(gh(r,n),process.nextTick(i,n),!1):!0}Gr.prototype.write=function(r,e,t){var i=this._writableState,n=!1,s=!i.objectMode&&y8e(r);return s&&!gb.isBuffer(r)&&(r=I8e(r)),typeof e=="function"&&(t=e,e=null),s?e="buffer":e||(e=i.defaultEncoding),typeof t!="function"&&(t=R8e),i.ending?N8e(this,t):(s||L8e(this,i,r,t))&&(i.pendingcb++,n=T8e(this,i,s,r,e,t)),n};Gr.prototype.cork=function(){this._writableState.corked++};Gr.prototype.uncork=function(){var r=this._writableState;r.corked&&(r.corked--,!r.writing&&!r.corked&&!r.bufferProcessing&&r.bufferedRequest&&Lle(this,r))};Gr.prototype.setDefaultEncoding=function(e){if(typeof e=="string"&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new D8e(e);return this._writableState.defaultEncoding=e,this};Object.defineProperty(Gr.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function O8e(r,e,t){return!r.objectMode&&r.decodeStrings!==!1&&typeof e=="string"&&(e=gb.from(e,t)),e}Object.defineProperty(Gr.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function T8e(r,e,t,i,n,s){if(!t){var o=O8e(e,i,n);i!==o&&(t=!0,n="buffer",i=o)}var a=e.objectMode?1:i.length;e.length+=a;var l=e.length<e.highWaterMark;if(l||(e.needDrain=!0),e.writing||e.corked){var c=e.lastBufferedRequest;e.lastBufferedRequest={chunk:i,encoding:n,isBuf:t,callback:s,next:null},c?c.next=e.lastBufferedRequest:e.bufferedRequest=e.lastBufferedRequest,e.bufferedRequestCount+=1}else cT(r,e,!1,a,i,n,s);return l}function cT(r,e,t,i,n,s,o){e.writelen=i,e.writecb=o,e.writing=!0,e.sync=!0,e.destroyed?e.onwrite(new k8e("write")):t?r._writev(n,e.onwrite):r._write(n,s,e.onwrite),e.sync=!1}function M8e(r,e,t,i,n){--e.pendingcb,t?(process.nextTick(n,i),process.nextTick(qm,r,e),r._writableState.errorEmitted=!0,gh(r,i)):(n(i),r._writableState.errorEmitted=!0,gh(r,i),qm(r,e))}function U8e(r){r.writing=!1,r.writecb=null,r.length-=r.writelen,r.writelen=0}function F8e(r,e){var t=r._writableState,i=t.sync,n=t.writecb;if(typeof n!="function")throw new S8e;if(U8e(t),e)M8e(r,t,i,e,n);else{var s=Ole(t)||r.destroyed;!s&&!t.corked&&!t.bufferProcessing&&t.bufferedRequest&&Lle(r,t),i?process.nextTick(Tle,r,t,s,n):Tle(r,t,s,n)}}function Tle(r,e,t,i){t||K8e(r,e),e.pendingcb--,i(),qm(r,e)}function K8e(r,e){e.length===0&&e.needDrain&&(e.needDrain=!1,r.emit("drain"))}function Lle(r,e){e.bufferProcessing=!0;var t=e.bufferedRequest;if(r._writev&&t&&t.next){var i=e.bufferedRequestCount,n=new Array(i),s=e.corkedRequestsFree;s.entry=t;for(var o=0,a=!0;t;)n[o]=t,t.isBuf||(a=!1),t=t.next,o+=1;n.allBuffers=a,cT(r,e,!0,e.length,n,"",s.finish),e.pendingcb++,e.lastBufferedRequest=null,s.next?(e.corkedRequestsFree=s.next,s.next=null):e.corkedRequestsFree=new Fle(e),e.bufferedRequestCount=0}else{for(;t;){var l=t.chunk,c=t.encoding,u=t.callback,g=e.objectMode?1:l.length;if(cT(r,e,!1,g,l,c,u),t=t.next,e.bufferedRequestCount--,e.writing)break}t===null&&(e.lastBufferedRequest=null)}e.bufferedRequest=t,e.bufferProcessing=!1}Gr.prototype._write=function(r,e,t){t(new Q8e("_write()"))};Gr.prototype._writev=null;Gr.prototype.end=function(r,e,t){var i=this._writableState;return typeof r=="function"?(t=r,r=null,e=null):typeof e=="function"&&(t=e,e=null),r!=null&&this.write(r,e),i.corked&&(i.corked=1,this.uncork()),i.ending||H8e(this,i,t),this};Object.defineProperty(Gr.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}});function Ole(r){return r.ending&&r.length===0&&r.bufferedRequest===null&&!r.finished&&!r.writing}function j8e(r,e){r._final(function(t){e.pendingcb--,t&&gh(r,t),e.prefinished=!0,r.emit("prefinish"),qm(r,e)})}function G8e(r,e){!e.prefinished&&!e.finalCalled&&(typeof r._final=="function"&&!e.destroyed?(e.pendingcb++,e.finalCalled=!0,process.nextTick(j8e,r,e)):(e.prefinished=!0,r.emit("prefinish")))}function qm(r,e){var t=Ole(e);if(t&&(G8e(r,e),e.pendingcb===0&&(e.finished=!0,r.emit("finish"),e.autoDestroy))){var i=r._readableState;(!i||i.autoDestroy&&i.endEmitted)&&r.destroy()}return t}function H8e(r,e,t){e.ending=!0,qm(r,e),t&&(e.finished?process.nextTick(t):r.once("finish",t)),e.ended=!0,r.writable=!1}function C8e(r,e,t){var i=r.entry;for(r.entry=null;i;){var n=i.callback;e.pendingcb--,n(t),i=i.next}e.corkedRequestsFree.next=r}Object.defineProperty(Gr.prototype,"destroyed",{enumerable:!1,get:function(){return this._writableState===void 0?!1:this._writableState.destroyed},set:function(e){!this._writableState||(this._writableState.destroyed=e)}});Gr.prototype.destroy=lT.destroy;Gr.prototype._undestroy=lT.undestroy;Gr.prototype._destroy=function(r,e){e(r)}});var Pu=w((GSt,Mle)=>{"use strict";var Y8e=Object.keys||function(r){var e=[];for(var t in r)e.push(t);return e};Mle.exports=Ia;var Ule=gT(),fT=uT();jl()(Ia,Ule);for(hT=Y8e(fT.prototype),hb=0;hb<hT.length;hb++)pb=hT[hb],Ia.prototype[pb]||(Ia.prototype[pb]=fT.prototype[pb]);var hT,pb,hb;function Ia(r){if(!(this instanceof Ia))return new Ia(r);Ule.call(this,r),fT.call(this,r),this.allowHalfOpen=!0,r&&(r.readable===!1&&(this.readable=!1),r.writable===!1&&(this.writable=!1),r.allowHalfOpen===!1&&(this.allowHalfOpen=!1,this.once("end",q8e)))}Object.defineProperty(Ia.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});Object.defineProperty(Ia.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});Object.defineProperty(Ia.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}});function q8e(){this._writableState.ended||process.nextTick(J8e,this)}function J8e(r){r.end()}Object.defineProperty(Ia.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0||this._writableState===void 0?!1:this._readableState.destroyed&&this._writableState.destroyed},set:function(e){this._readableState===void 0||this._writableState===void 0||(this._readableState.destroyed=e,this._writableState.destroyed=e)}})});var jle=w((pT,Kle)=>{var db=require("buffer"),kA=db.Buffer;function Hle(r,e){for(var t in r)e[t]=r[t]}kA.from&&kA.alloc&&kA.allocUnsafe&&kA.allocUnsafeSlow?Kle.exports=db:(Hle(db,pT),pT.Buffer=fh);function fh(r,e,t){return kA(r,e,t)}Hle(kA,fh);fh.from=function(r,e,t){if(typeof r=="number")throw new TypeError("Argument must not be a number");return kA(r,e,t)};fh.alloc=function(r,e,t){if(typeof r!="number")throw new TypeError("Argument must be a number");var i=kA(r);return e!==void 0?typeof t=="string"?i.fill(e,t):i.fill(e):i.fill(0),i};fh.allocUnsafe=function(r){if(typeof r!="number")throw new TypeError("Argument must be a number");return kA(r)};fh.allocUnsafeSlow=function(r){if(typeof r!="number")throw new TypeError("Argument must be a number");return db.SlowBuffer(r)}});var mT=w(Gle=>{"use strict";var dT=jle().Buffer,Yle=dT.isEncoding||function(r){switch(r=""+r,r&&r.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function W8e(r){if(!r)return"utf8";for(var e;;)switch(r){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return r;default:if(e)return;r=(""+r).toLowerCase(),e=!0}}function z8e(r){var e=W8e(r);if(typeof e!="string"&&(dT.isEncoding===Yle||!Yle(r)))throw new Error("Unknown encoding: "+r);return e||r}Gle.StringDecoder=Jm;function Jm(r){this.encoding=z8e(r);var e;switch(this.encoding){case"utf16le":this.text=V8e,this.end=X8e,e=4;break;case"utf8":this.fillLast=_8e,e=4;break;case"base64":this.text=Z8e,this.end=$8e,e=3;break;default:this.write=e5e,this.end=t5e;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=dT.allocUnsafe(e)}Jm.prototype.write=function(r){if(r.length===0)return"";var e,t;if(this.lastNeed){if(e=this.fillLast(r),e===void 0)return"";t=this.lastNeed,this.lastNeed=0}else t=0;return t<r.length?e?e+this.text(r,t):this.text(r,t):e||""};Jm.prototype.end=r5e;Jm.prototype.text=i5e;Jm.prototype.fillLast=function(r){if(this.lastNeed<=r.length)return r.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);r.copy(this.lastChar,this.lastTotal-this.lastNeed,0,r.length),this.lastNeed-=r.length};function CT(r){return r<=127?0:r>>5==6?2:r>>4==14?3:r>>3==30?4:r>>6==2?-1:-2}function n5e(r,e,t){var i=e.length-1;if(i<t)return 0;var n=CT(e[i]);return n>=0?(n>0&&(r.lastNeed=n-1),n):--i<t||n===-2?0:(n=CT(e[i]),n>=0?(n>0&&(r.lastNeed=n-2),n):--i<t||n===-2?0:(n=CT(e[i]),n>=0?(n>0&&(n===2?n=0:r.lastNeed=n-3),n):0))}function s5e(r,e,t){if((e[0]&192)!=128)return r.lastNeed=0,"\uFFFD";if(r.lastNeed>1&&e.length>1){if((e[1]&192)!=128)return r.lastNeed=1,"\uFFFD";if(r.lastNeed>2&&e.length>2&&(e[2]&192)!=128)return r.lastNeed=2,"\uFFFD"}}function _8e(r){var e=this.lastTotal-this.lastNeed,t=s5e(this,r,e);if(t!==void 0)return t;if(this.lastNeed<=r.length)return r.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);r.copy(this.lastChar,e,0,r.length),this.lastNeed-=r.length}function i5e(r,e){var t=n5e(this,r,e);if(!this.lastNeed)return r.toString("utf8",e);this.lastTotal=t;var i=r.length-(t-this.lastNeed);return r.copy(this.lastChar,0,i),r.toString("utf8",e,i)}function r5e(r){var e=r&&r.length?this.write(r):"";return this.lastNeed?e+"\uFFFD":e}function V8e(r,e){if((r.length-e)%2==0){var t=r.toString("utf16le",e);if(t){var i=t.charCodeAt(t.length-1);if(i>=55296&&i<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=r[r.length-2],this.lastChar[1]=r[r.length-1],t.slice(0,-1)}return t}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=r[r.length-1],r.toString("utf16le",e,r.length-1)}function X8e(r){var e=r&&r.length?this.write(r):"";if(this.lastNeed){var t=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,t)}return e}function Z8e(r,e){var t=(r.length-e)%3;return t===0?r.toString("base64",e):(this.lastNeed=3-t,this.lastTotal=3,t===1?this.lastChar[0]=r[r.length-1]:(this.lastChar[0]=r[r.length-2],this.lastChar[1]=r[r.length-1]),r.toString("base64",e,r.length-t))}function $8e(r){var e=r&&r.length?this.write(r):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function e5e(r){return r.toString(this.encoding)}function t5e(r){return r&&r.length?this.write(r):""}});var Cb=w((qSt,qle)=>{"use strict";var Jle=Hl().codes.ERR_STREAM_PREMATURE_CLOSE;function o5e(r){var e=!1;return function(){if(!e){e=!0;for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];r.apply(this,i)}}}function a5e(){}function A5e(r){return r.setHeader&&typeof r.abort=="function"}function Wle(r,e,t){if(typeof e=="function")return Wle(r,null,e);e||(e={}),t=o5e(t||a5e);var i=e.readable||e.readable!==!1&&r.readable,n=e.writable||e.writable!==!1&&r.writable,s=function(){r.writable||a()},o=r._writableState&&r._writableState.finished,a=function(){n=!1,o=!0,i||t.call(r)},l=r._readableState&&r._readableState.endEmitted,c=function(){i=!1,l=!0,n||t.call(r)},u=function(p){t.call(r,p)},g=function(){var p;if(i&&!l)return(!r._readableState||!r._readableState.ended)&&(p=new Jle),t.call(r,p);if(n&&!o)return(!r._writableState||!r._writableState.ended)&&(p=new Jle),t.call(r,p)},f=function(){r.req.on("finish",a)};return A5e(r)?(r.on("complete",a),r.on("abort",g),r.req?f():r.on("request",f)):n&&!r._writableState&&(r.on("end",s),r.on("close",s)),r.on("end",c),r.on("finish",a),e.error!==!1&&r.on("error",u),r.on("close",g),function(){r.removeListener("complete",a),r.removeListener("abort",g),r.removeListener("request",f),r.req&&r.req.removeListener("finish",a),r.removeListener("end",s),r.removeListener("close",s),r.removeListener("finish",a),r.removeListener("end",c),r.removeListener("error",u),r.removeListener("close",g)}}qle.exports=Wle});var _le=w((JSt,zle)=>{"use strict";var mb;function Yl(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var l5e=Cb(),ql=Symbol("lastResolve"),Du=Symbol("lastReject"),Wm=Symbol("error"),Eb=Symbol("ended"),Ru=Symbol("lastPromise"),ET=Symbol("handlePromise"),Fu=Symbol("stream");function Jl(r,e){return{value:r,done:e}}function c5e(r){var e=r[ql];if(e!==null){var t=r[Fu].read();t!==null&&(r[Ru]=null,r[ql]=null,r[Du]=null,e(Jl(t,!1)))}}function u5e(r){process.nextTick(c5e,r)}function g5e(r,e){return function(t,i){r.then(function(){if(e[Eb]){t(Jl(void 0,!0));return}e[ET](t,i)},i)}}var f5e=Object.getPrototypeOf(function(){}),h5e=Object.setPrototypeOf((mb={get stream(){return this[Fu]},next:function(){var e=this,t=this[Wm];if(t!==null)return Promise.reject(t);if(this[Eb])return Promise.resolve(Jl(void 0,!0));if(this[Fu].destroyed)return new Promise(function(o,a){process.nextTick(function(){e[Wm]?a(e[Wm]):o(Jl(void 0,!0))})});var i=this[Ru],n;if(i)n=new Promise(g5e(i,this));else{var s=this[Fu].read();if(s!==null)return Promise.resolve(Jl(s,!1));n=new Promise(this[ET])}return this[Ru]=n,n}},Yl(mb,Symbol.asyncIterator,function(){return this}),Yl(mb,"return",function(){var e=this;return new Promise(function(t,i){e[Fu].destroy(null,function(n){if(n){i(n);return}t(Jl(void 0,!0))})})}),mb),f5e),p5e=function(e){var t,i=Object.create(h5e,(t={},Yl(t,Fu,{value:e,writable:!0}),Yl(t,ql,{value:null,writable:!0}),Yl(t,Du,{value:null,writable:!0}),Yl(t,Wm,{value:null,writable:!0}),Yl(t,Eb,{value:e._readableState.endEmitted,writable:!0}),Yl(t,ET,{value:function(s,o){var a=i[Fu].read();a?(i[Ru]=null,i[ql]=null,i[Du]=null,s(Jl(a,!1))):(i[ql]=s,i[Du]=o)},writable:!0}),t));return i[Ru]=null,l5e(e,function(n){if(n&&n.code!=="ERR_STREAM_PREMATURE_CLOSE"){var s=i[Du];s!==null&&(i[Ru]=null,i[ql]=null,i[Du]=null,s(n)),i[Wm]=n;return}var o=i[ql];o!==null&&(i[Ru]=null,i[ql]=null,i[Du]=null,o(Jl(void 0,!0))),i[Eb]=!0}),e.on("readable",u5e.bind(null,i)),i};zle.exports=p5e});var $le=w((WSt,Vle)=>{"use strict";function Xle(r,e,t,i,n,s,o){try{var a=r[s](o),l=a.value}catch(c){t(c);return}a.done?e(l):Promise.resolve(l).then(i,n)}function d5e(r){return function(){var e=this,t=arguments;return new Promise(function(i,n){var s=r.apply(e,t);function o(l){Xle(s,i,n,o,a,"next",l)}function a(l){Xle(s,i,n,o,a,"throw",l)}o(void 0)})}}function Zle(r,e){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable})),t.push.apply(t,i)}return t}function m5e(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?arguments[e]:{};e%2?Zle(Object(t),!0).forEach(function(i){C5e(r,i,t[i])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(t)):Zle(Object(t)).forEach(function(i){Object.defineProperty(r,i,Object.getOwnPropertyDescriptor(t,i))})}return r}function C5e(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var E5e=Hl().codes.ERR_INVALID_ARG_TYPE;function I5e(r,e,t){var i;if(e&&typeof e.next=="function")i=e;else if(e&&e[Symbol.asyncIterator])i=e[Symbol.asyncIterator]();else if(e&&e[Symbol.iterator])i=e[Symbol.iterator]();else throw new E5e("iterable",["Iterable"],e);var n=new r(m5e({objectMode:!0},t)),s=!1;n._read=function(){s||(s=!0,o())};function o(){return a.apply(this,arguments)}function a(){return a=d5e(function*(){try{var l=yield i.next(),c=l.value,u=l.done;u?n.push(null):n.push(yield c)?o():s=!1}catch(g){n.destroy(g)}}),a.apply(this,arguments)}return n}Vle.exports=I5e});var gT=w((_St,ece)=>{"use strict";ece.exports=Kt;var hh;Kt.ReadableState=tce;var zSt=require("events").EventEmitter,rce=function(e,t){return e.listeners(t).length},zm=tT(),Ib=require("buffer").Buffer,y5e=global.Uint8Array||function(){};function w5e(r){return Ib.from(r)}function B5e(r){return Ib.isBuffer(r)||r instanceof y5e}var IT=require("util"),Pt;IT&&IT.debuglog?Pt=IT.debuglog("stream"):Pt=function(){};var b5e=wle(),yT=nT(),Q5e=sT(),S5e=Q5e.getHighWaterMark,yb=Hl().codes,v5e=yb.ERR_INVALID_ARG_TYPE,k5e=yb.ERR_STREAM_PUSH_AFTER_EOF,x5e=yb.ERR_METHOD_NOT_IMPLEMENTED,P5e=yb.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,ph,wT,BT;jl()(Kt,zm);var _m=yT.errorOrDestroy,bT=["error","close","destroy","pause","resume"];function D5e(r,e,t){if(typeof r.prependListener=="function")return r.prependListener(e,t);!r._events||!r._events[e]?r.on(e,t):Array.isArray(r._events[e])?r._events[e].unshift(t):r._events[e]=[t,r._events[e]]}function tce(r,e,t){hh=hh||Pu(),r=r||{},typeof t!="boolean"&&(t=e instanceof hh),this.objectMode=!!r.objectMode,t&&(this.objectMode=this.objectMode||!!r.readableObjectMode),this.highWaterMark=S5e(this,r,"readableHighWaterMark",t),this.buffer=new b5e,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=r.emitClose!==!1,this.autoDestroy=!!r.autoDestroy,this.destroyed=!1,this.defaultEncoding=r.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,r.encoding&&(ph||(ph=mT().StringDecoder),this.decoder=new ph(r.encoding),this.encoding=r.encoding)}function Kt(r){if(hh=hh||Pu(),!(this instanceof Kt))return new Kt(r);var e=this instanceof hh;this._readableState=new tce(r,this,e),this.readable=!0,r&&(typeof r.read=="function"&&(this._read=r.read),typeof r.destroy=="function"&&(this._destroy=r.destroy)),zm.call(this)}Object.defineProperty(Kt.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0?!1:this._readableState.destroyed},set:function(e){!this._readableState||(this._readableState.destroyed=e)}});Kt.prototype.destroy=yT.destroy;Kt.prototype._undestroy=yT.undestroy;Kt.prototype._destroy=function(r,e){e(r)};Kt.prototype.push=function(r,e){var t=this._readableState,i;return t.objectMode?i=!0:typeof r=="string"&&(e=e||t.defaultEncoding,e!==t.encoding&&(r=Ib.from(r,e),e=""),i=!0),ice(this,r,e,!1,i)};Kt.prototype.unshift=function(r){return ice(this,r,null,!0,!1)};function ice(r,e,t,i,n){Pt("readableAddChunk",e);var s=r._readableState;if(e===null)s.reading=!1,F5e(r,s);else{var o;if(n||(o=R5e(s,e)),o)_m(r,o);else if(s.objectMode||e&&e.length>0)if(typeof e!="string"&&!s.objectMode&&Object.getPrototypeOf(e)!==Ib.prototype&&(e=w5e(e)),i)s.endEmitted?_m(r,new P5e):QT(r,s,e,!0);else if(s.ended)_m(r,new k5e);else{if(s.destroyed)return!1;s.reading=!1,s.decoder&&!t?(e=s.decoder.write(e),s.objectMode||e.length!==0?QT(r,s,e,!1):ST(r,s)):QT(r,s,e,!1)}else i||(s.reading=!1,ST(r,s))}return!s.ended&&(s.length<s.highWaterMark||s.length===0)}function QT(r,e,t,i){e.flowing&&e.length===0&&!e.sync?(e.awaitDrain=0,r.emit("data",t)):(e.length+=e.objectMode?1:t.length,i?e.buffer.unshift(t):e.buffer.push(t),e.needReadable&&wb(r)),ST(r,e)}function R5e(r,e){var t;return!B5e(e)&&typeof e!="string"&&e!==void 0&&!r.objectMode&&(t=new v5e("chunk",["string","Buffer","Uint8Array"],e)),t}Kt.prototype.isPaused=function(){return this._readableState.flowing===!1};Kt.prototype.setEncoding=function(r){ph||(ph=mT().StringDecoder);var e=new ph(r);this._readableState.decoder=e,this._readableState.encoding=this._readableState.decoder.encoding;for(var t=this._readableState.buffer.head,i="";t!==null;)i+=e.write(t.data),t=t.next;return this._readableState.buffer.clear(),i!==""&&this._readableState.buffer.push(i),this._readableState.length=i.length,this};var nce=1073741824;function N5e(r){return r>=nce?r=nce:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r}function sce(r,e){return r<=0||e.length===0&&e.ended?0:e.objectMode?1:r!==r?e.flowing&&e.length?e.buffer.head.data.length:e.length:(r>e.highWaterMark&&(e.highWaterMark=N5e(r)),r<=e.length?r:e.ended?e.length:(e.needReadable=!0,0))}Kt.prototype.read=function(r){Pt("read",r),r=parseInt(r,10);var e=this._readableState,t=r;if(r!==0&&(e.emittedReadable=!1),r===0&&e.needReadable&&((e.highWaterMark!==0?e.length>=e.highWaterMark:e.length>0)||e.ended))return Pt("read: emitReadable",e.length,e.ended),e.length===0&&e.ended?vT(this):wb(this),null;if(r=sce(r,e),r===0&&e.ended)return e.length===0&&vT(this),null;var i=e.needReadable;Pt("need readable",i),(e.length===0||e.length-r<e.highWaterMark)&&(i=!0,Pt("length less than watermark",i)),e.ended||e.reading?(i=!1,Pt("reading or ended",i)):i&&(Pt("do read"),e.reading=!0,e.sync=!0,e.length===0&&(e.needReadable=!0),this._read(e.highWaterMark),e.sync=!1,e.reading||(r=sce(t,e)));var n;return r>0?n=oce(r,e):n=null,n===null?(e.needReadable=e.length<=e.highWaterMark,r=0):(e.length-=r,e.awaitDrain=0),e.length===0&&(e.ended||(e.needReadable=!0),t!==r&&e.ended&&vT(this)),n!==null&&this.emit("data",n),n};function F5e(r,e){if(Pt("onEofChunk"),!e.ended){if(e.decoder){var t=e.decoder.end();t&&t.length&&(e.buffer.push(t),e.length+=e.objectMode?1:t.length)}e.ended=!0,e.sync?wb(r):(e.needReadable=!1,e.emittedReadable||(e.emittedReadable=!0,ace(r)))}}function wb(r){var e=r._readableState;Pt("emitReadable",e.needReadable,e.emittedReadable),e.needReadable=!1,e.emittedReadable||(Pt("emitReadable",e.flowing),e.emittedReadable=!0,process.nextTick(ace,r))}function ace(r){var e=r._readableState;Pt("emitReadable_",e.destroyed,e.length,e.ended),!e.destroyed&&(e.length||e.ended)&&(r.emit("readable"),e.emittedReadable=!1),e.needReadable=!e.flowing&&!e.ended&&e.length<=e.highWaterMark,kT(r)}function ST(r,e){e.readingMore||(e.readingMore=!0,process.nextTick(L5e,r,e))}function L5e(r,e){for(;!e.reading&&!e.ended&&(e.length<e.highWaterMark||e.flowing&&e.length===0);){var t=e.length;if(Pt("maybeReadMore read 0"),r.read(0),t===e.length)break}e.readingMore=!1}Kt.prototype._read=function(r){_m(this,new x5e("_read()"))};Kt.prototype.pipe=function(r,e){var t=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=r;break;case 1:i.pipes=[i.pipes,r];break;default:i.pipes.push(r);break}i.pipesCount+=1,Pt("pipe count=%d opts=%j",i.pipesCount,e);var n=(!e||e.end!==!1)&&r!==process.stdout&&r!==process.stderr,s=n?a:m;i.endEmitted?process.nextTick(s):t.once("end",s),r.on("unpipe",o);function o(y,b){Pt("onunpipe"),y===t&&b&&b.hasUnpiped===!1&&(b.hasUnpiped=!0,u())}function a(){Pt("onend"),r.end()}var l=T5e(t);r.on("drain",l);var c=!1;function u(){Pt("cleanup"),r.removeListener("close",h),r.removeListener("finish",p),r.removeListener("drain",l),r.removeListener("error",f),r.removeListener("unpipe",o),t.removeListener("end",a),t.removeListener("end",m),t.removeListener("data",g),c=!0,i.awaitDrain&&(!r._writableState||r._writableState.needDrain)&&l()}t.on("data",g);function g(y){Pt("ondata");var b=r.write(y);Pt("dest.write",b),b===!1&&((i.pipesCount===1&&i.pipes===r||i.pipesCount>1&&Ace(i.pipes,r)!==-1)&&!c&&(Pt("false write response, pause",i.awaitDrain),i.awaitDrain++),t.pause())}function f(y){Pt("onerror",y),m(),r.removeListener("error",f),rce(r,"error")===0&&_m(r,y)}D5e(r,"error",f);function h(){r.removeListener("finish",p),m()}r.once("close",h);function p(){Pt("onfinish"),r.removeListener("close",h),m()}r.once("finish",p);function m(){Pt("unpipe"),t.unpipe(r)}return r.emit("pipe",t),i.flowing||(Pt("pipe resume"),t.resume()),r};function T5e(r){return function(){var t=r._readableState;Pt("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,t.awaitDrain===0&&rce(r,"data")&&(t.flowing=!0,kT(r))}}Kt.prototype.unpipe=function(r){var e=this._readableState,t={hasUnpiped:!1};if(e.pipesCount===0)return this;if(e.pipesCount===1)return r&&r!==e.pipes?this:(r||(r=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,r&&r.emit("unpipe",this,t),this);if(!r){var i=e.pipes,n=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var s=0;s<n;s++)i[s].emit("unpipe",this,{hasUnpiped:!1});return this}var o=Ace(e.pipes,r);return o===-1?this:(e.pipes.splice(o,1),e.pipesCount-=1,e.pipesCount===1&&(e.pipes=e.pipes[0]),r.emit("unpipe",this,t),this)};Kt.prototype.on=function(r,e){var t=zm.prototype.on.call(this,r,e),i=this._readableState;return r==="data"?(i.readableListening=this.listenerCount("readable")>0,i.flowing!==!1&&this.resume()):r==="readable"&&!i.endEmitted&&!i.readableListening&&(i.readableListening=i.needReadable=!0,i.flowing=!1,i.emittedReadable=!1,Pt("on readable",i.length,i.reading),i.length?wb(this):i.reading||process.nextTick(O5e,this)),t};Kt.prototype.addListener=Kt.prototype.on;Kt.prototype.removeListener=function(r,e){var t=zm.prototype.removeListener.call(this,r,e);return r==="readable"&&process.nextTick(lce,this),t};Kt.prototype.removeAllListeners=function(r){var e=zm.prototype.removeAllListeners.apply(this,arguments);return(r==="readable"||r===void 0)&&process.nextTick(lce,this),e};function lce(r){var e=r._readableState;e.readableListening=r.listenerCount("readable")>0,e.resumeScheduled&&!e.paused?e.flowing=!0:r.listenerCount("data")>0&&r.resume()}function O5e(r){Pt("readable nexttick read 0"),r.read(0)}Kt.prototype.resume=function(){var r=this._readableState;return r.flowing||(Pt("resume"),r.flowing=!r.readableListening,M5e(this,r)),r.paused=!1,this};function M5e(r,e){e.resumeScheduled||(e.resumeScheduled=!0,process.nextTick(U5e,r,e))}function U5e(r,e){Pt("resume",e.reading),e.reading||r.read(0),e.resumeScheduled=!1,r.emit("resume"),kT(r),e.flowing&&!e.reading&&r.read(0)}Kt.prototype.pause=function(){return Pt("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1&&(Pt("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this};function kT(r){var e=r._readableState;for(Pt("flow",e.flowing);e.flowing&&r.read()!==null;);}Kt.prototype.wrap=function(r){var e=this,t=this._readableState,i=!1;r.on("end",function(){if(Pt("wrapped end"),t.decoder&&!t.ended){var o=t.decoder.end();o&&o.length&&e.push(o)}e.push(null)}),r.on("data",function(o){if(Pt("wrapped data"),t.decoder&&(o=t.decoder.write(o)),!(t.objectMode&&o==null)&&!(!t.objectMode&&(!o||!o.length))){var a=e.push(o);a||(i=!0,r.pause())}});for(var n in r)this[n]===void 0&&typeof r[n]=="function"&&(this[n]=function(a){return function(){return r[a].apply(r,arguments)}}(n));for(var s=0;s<bT.length;s++)r.on(bT[s],this.emit.bind(this,bT[s]));return this._read=function(o){Pt("wrapped _read",o),i&&(i=!1,r.resume())},this};typeof Symbol=="function"&&(Kt.prototype[Symbol.asyncIterator]=function(){return wT===void 0&&(wT=_le()),wT(this)});Object.defineProperty(Kt.prototype,"readableHighWaterMark",{enumerable:!1,get:function(){return this._readableState.highWaterMark}});Object.defineProperty(Kt.prototype,"readableBuffer",{enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}});Object.defineProperty(Kt.prototype,"readableFlowing",{enumerable:!1,get:function(){return this._readableState.flowing},set:function(e){this._readableState&&(this._readableState.flowing=e)}});Kt._fromList=oce;Object.defineProperty(Kt.prototype,"readableLength",{enumerable:!1,get:function(){return this._readableState.length}});function oce(r,e){if(e.length===0)return null;var t;return e.objectMode?t=e.buffer.shift():!r||r>=e.length?(e.decoder?t=e.buffer.join(""):e.buffer.length===1?t=e.buffer.first():t=e.buffer.concat(e.length),e.buffer.clear()):t=e.buffer.consume(r,e.decoder),t}function vT(r){var e=r._readableState;Pt("endReadable",e.endEmitted),e.endEmitted||(e.ended=!0,process.nextTick(K5e,e,r))}function K5e(r,e){if(Pt("endReadableNT",r.endEmitted,r.length),!r.endEmitted&&r.length===0&&(r.endEmitted=!0,e.readable=!1,e.emit("end"),r.autoDestroy)){var t=e._writableState;(!t||t.autoDestroy&&t.finished)&&e.destroy()}}typeof Symbol=="function"&&(Kt.from=function(r,e){return BT===void 0&&(BT=$le()),BT(Kt,r,e)});function Ace(r,e){for(var t=0,i=r.length;t<i;t++)if(r[t]===e)return t;return-1}});var xT=w((VSt,cce)=>{"use strict";cce.exports=xA;var Bb=Hl().codes,H5e=Bb.ERR_METHOD_NOT_IMPLEMENTED,j5e=Bb.ERR_MULTIPLE_CALLBACK,G5e=Bb.ERR_TRANSFORM_ALREADY_TRANSFORMING,Y5e=Bb.ERR_TRANSFORM_WITH_LENGTH_0,bb=Pu();jl()(xA,bb);function q5e(r,e){var t=this._transformState;t.transforming=!1;var i=t.writecb;if(i===null)return this.emit("error",new j5e);t.writechunk=null,t.writecb=null,e!=null&&this.push(e),i(r);var n=this._readableState;n.reading=!1,(n.needReadable||n.length<n.highWaterMark)&&this._read(n.highWaterMark)}function xA(r){if(!(this instanceof xA))return new xA(r);bb.call(this,r),this._transformState={afterTransform:q5e.bind(this),needTransform:!1,transforming:!1,writecb:null,writechunk:null,writeencoding:null},this._readableState.needReadable=!0,this._readableState.sync=!1,r&&(typeof r.transform=="function"&&(this._transform=r.transform),typeof r.flush=="function"&&(this._flush=r.flush)),this.on("prefinish",J5e)}function J5e(){var r=this;typeof this._flush=="function"&&!this._readableState.destroyed?this._flush(function(e,t){uce(r,e,t)}):uce(this,null,null)}xA.prototype.push=function(r,e){return this._transformState.needTransform=!1,bb.prototype.push.call(this,r,e)};xA.prototype._transform=function(r,e,t){t(new H5e("_transform()"))};xA.prototype._write=function(r,e,t){var i=this._transformState;if(i.writecb=t,i.writechunk=r,i.writeencoding=e,!i.transforming){var n=this._readableState;(i.needTransform||n.needReadable||n.length<n.highWaterMark)&&this._read(n.highWaterMark)}};xA.prototype._read=function(r){var e=this._transformState;e.writechunk!==null&&!e.transforming?(e.transforming=!0,this._transform(e.writechunk,e.writeencoding,e.afterTransform)):e.needTransform=!0};xA.prototype._destroy=function(r,e){bb.prototype._destroy.call(this,r,function(t){e(t)})};function uce(r,e,t){if(e)return r.emit("error",e);if(t!=null&&r.push(t),r._writableState.length)throw new Y5e;if(r._transformState.transforming)throw new G5e;return r.push(null)}});var hce=w((XSt,gce)=>{"use strict";gce.exports=Vm;var fce=xT();jl()(Vm,fce);function Vm(r){if(!(this instanceof Vm))return new Vm(r);fce.call(this,r)}Vm.prototype._transform=function(r,e,t){t(null,r)}});var Ece=w((ZSt,pce)=>{"use strict";var PT;function W5e(r){var e=!1;return function(){e||(e=!0,r.apply(void 0,arguments))}}var dce=Hl().codes,z5e=dce.ERR_MISSING_ARGS,_5e=dce.ERR_STREAM_DESTROYED;function Cce(r){if(r)throw r}function V5e(r){return r.setHeader&&typeof r.abort=="function"}function X5e(r,e,t,i){i=W5e(i);var n=!1;r.on("close",function(){n=!0}),PT===void 0&&(PT=Cb()),PT(r,{readable:e,writable:t},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,V5e(r))return r.abort();if(typeof r.destroy=="function")return r.destroy();i(o||new _5e("pipe"))}}}function mce(r){r()}function Z5e(r,e){return r.pipe(e)}function $5e(r){return!r.length||typeof r[r.length-1]!="function"?Cce:r.pop()}function e9e(){for(var r=arguments.length,e=new Array(r),t=0;t<r;t++)e[t]=arguments[t];var i=$5e(e);if(Array.isArray(e[0])&&(e=e[0]),e.length<2)throw new z5e("streams");var n,s=e.map(function(o,a){var l=a<e.length-1,c=a>0;return X5e(o,l,c,function(u){n||(n=u),u&&s.forEach(mce),!l&&(s.forEach(mce),i(n))})});return e.reduce(Z5e)}pce.exports=e9e});var dh=w((Zs,Xm)=>{var Zm=require("stream");process.env.READABLE_STREAM==="disable"&&Zm?(Xm.exports=Zm.Readable,Object.assign(Xm.exports,Zm),Xm.exports.Stream=Zm):(Zs=Xm.exports=gT(),Zs.Stream=Zm||Zs,Zs.Readable=Zs,Zs.Writable=uT(),Zs.Duplex=Pu(),Zs.Transform=xT(),Zs.PassThrough=hce(),Zs.finished=Cb(),Zs.pipeline=Ece())});var wce=w(($St,Ice)=>{"use strict";var{Buffer:ko}=require("buffer"),yce=Symbol.for("BufferList");function mr(r){if(!(this instanceof mr))return new mr(r);mr._init.call(this,r)}mr._init=function(e){Object.defineProperty(this,yce,{value:!0}),this._bufs=[],this.length=0,e&&this.append(e)};mr.prototype._new=function(e){return new mr(e)};mr.prototype._offset=function(e){if(e===0)return[0,0];let t=0;for(let i=0;i<this._bufs.length;i++){let n=t+this._bufs[i].length;if(e<n||i===this._bufs.length-1)return[i,e-t];t=n}};mr.prototype._reverseOffset=function(r){let e=r[0],t=r[1];for(let i=0;i<e;i++)t+=this._bufs[i].length;return t};mr.prototype.get=function(e){if(e>this.length||e<0)return;let t=this._offset(e);return this._bufs[t[0]][t[1]]};mr.prototype.slice=function(e,t){return typeof e=="number"&&e<0&&(e+=this.length),typeof t=="number"&&t<0&&(t+=this.length),this.copy(null,0,e,t)};mr.prototype.copy=function(e,t,i,n){if((typeof i!="number"||i<0)&&(i=0),(typeof n!="number"||n>this.length)&&(n=this.length),i>=this.length||n<=0)return e||ko.alloc(0);let s=!!e,o=this._offset(i),a=n-i,l=a,c=s&&t||0,u=o[1];if(i===0&&n===this.length){if(!s)return this._bufs.length===1?this._bufs[0]:ko.concat(this._bufs,this.length);for(let g=0;g<this._bufs.length;g++)this._bufs[g].copy(e,c),c+=this._bufs[g].length;return e}if(l<=this._bufs[o[0]].length-u)return s?this._bufs[o[0]].copy(e,t,u,u+l):this._bufs[o[0]].slice(u,u+l);s||(e=ko.allocUnsafe(a));for(let g=o[0];g<this._bufs.length;g++){let f=this._bufs[g].length-u;if(l>f)this._bufs[g].copy(e,c,u),c+=f;else{this._bufs[g].copy(e,c,u,u+l),c+=f;break}l-=f,u&&(u=0)}return e.length>c?e.slice(0,c):e};mr.prototype.shallowSlice=function(e,t){if(e=e||0,t=typeof t!="number"?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return this._new();let i=this._offset(e),n=this._offset(t),s=this._bufs.slice(i[0],n[0]+1);return n[1]===0?s.pop():s[s.length-1]=s[s.length-1].slice(0,n[1]),i[1]!==0&&(s[0]=s[0].slice(i[1])),this._new(s)};mr.prototype.toString=function(e,t,i){return this.slice(t,i).toString(e)};mr.prototype.consume=function(e){if(e=Math.trunc(e),Number.isNaN(e)||e<=0)return this;for(;this._bufs.length;)if(e>=this._bufs[0].length)e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift();else{this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}return this};mr.prototype.duplicate=function(){let e=this._new();for(let t=0;t<this._bufs.length;t++)e.append(this._bufs[t]);return e};mr.prototype.append=function(e){if(e==null)return this;if(e.buffer)this._appendBuffer(ko.from(e.buffer,e.byteOffset,e.byteLength));else if(Array.isArray(e))for(let t=0;t<e.length;t++)this.append(e[t]);else if(this._isBufferList(e))for(let t=0;t<e._bufs.length;t++)this.append(e._bufs[t]);else typeof e=="number"&&(e=e.toString()),this._appendBuffer(ko.from(e));return this};mr.prototype._appendBuffer=function(e){this._bufs.push(e),this.length+=e.length};mr.prototype.indexOf=function(r,e,t){if(t===void 0&&typeof e=="string"&&(t=e,e=void 0),typeof r=="function"||Array.isArray(r))throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.');if(typeof r=="number"?r=ko.from([r]):typeof r=="string"?r=ko.from(r,t):this._isBufferList(r)?r=r.slice():Array.isArray(r.buffer)?r=ko.from(r.buffer,r.byteOffset,r.byteLength):ko.isBuffer(r)||(r=ko.from(r)),e=Number(e||0),isNaN(e)&&(e=0),e<0&&(e=this.length+e),e<0&&(e=0),r.length===0)return e>this.length?this.length:e;let i=this._offset(e),n=i[0],s=i[1];for(;n<this._bufs.length;n++){let o=this._bufs[n];for(;s<o.length;)if(o.length-s>=r.length){let l=o.indexOf(r,s);if(l!==-1)return this._reverseOffset([n,l]);s=o.length-r.length+1}else{let l=this._reverseOffset([n,s]);if(this._match(l,r))return l;s++}s=0}return-1};mr.prototype._match=function(r,e){if(this.length-r<e.length)return!1;for(let t=0;t<e.length;t++)if(this.get(r+t)!==e[t])return!1;return!0};(function(){let r={readDoubleBE:8,readDoubleLE:8,readFloatBE:4,readFloatLE:4,readInt32BE:4,readInt32LE:4,readUInt32BE:4,readUInt32LE:4,readInt16BE:2,readInt16LE:2,readUInt16BE:2,readUInt16LE:2,readInt8:1,readUInt8:1,readIntBE:null,readIntLE:null,readUIntBE:null,readUIntLE:null};for(let e in r)(function(t){r[t]===null?mr.prototype[t]=function(i,n){return this.slice(i,i+n)[t](0,n)}:mr.prototype[t]=function(i=0){return this.slice(i,i+r[t])[t](0)}})(e)})();mr.prototype._isBufferList=function(e){return e instanceof mr||mr.isBufferList(e)};mr.isBufferList=function(e){return e!=null&&e[yce]};Ice.exports=mr});var Bce=w((evt,Qb)=>{"use strict";var DT=dh().Duplex,t9e=jl(),$m=wce();function Zi(r){if(!(this instanceof Zi))return new Zi(r);if(typeof r=="function"){this._callback=r;let e=function(i){this._callback&&(this._callback(i),this._callback=null)}.bind(this);this.on("pipe",function(i){i.on("error",e)}),this.on("unpipe",function(i){i.removeListener("error",e)}),r=null}$m._init.call(this,r),DT.call(this)}t9e(Zi,DT);Object.assign(Zi.prototype,$m.prototype);Zi.prototype._new=function(e){return new Zi(e)};Zi.prototype._write=function(e,t,i){this._appendBuffer(e),typeof i=="function"&&i()};Zi.prototype._read=function(e){if(!this.length)return this.push(null);e=Math.min(e,this.length),this.push(this.slice(0,e)),this.consume(e)};Zi.prototype.end=function(e){DT.prototype.end.call(this,e),this._callback&&(this._callback(null,this.slice()),this._callback=null)};Zi.prototype._destroy=function(e,t){this._bufs.length=0,this.length=0,t(e)};Zi.prototype._isBufferList=function(e){return e instanceof Zi||e instanceof $m||Zi.isBufferList(e)};Zi.isBufferList=$m.isBufferList;Qb.exports=Zi;Qb.exports.BufferListStream=Zi;Qb.exports.BufferList=$m});var NT=w(Ch=>{var r9e=Buffer.alloc,i9e="0000000000000000000",n9e="7777777777777777777",bce="0".charCodeAt(0),Qce=Buffer.from("ustar\0","binary"),s9e=Buffer.from("00","binary"),o9e=Buffer.from("ustar ","binary"),a9e=Buffer.from(" \0","binary"),A9e=parseInt("7777",8),eE=257,RT=263,l9e=function(r,e,t){return typeof r!="number"?t:(r=~~r,r>=e?e:r>=0||(r+=e,r>=0)?r:0)},c9e=function(r){switch(r){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null},u9e=function(r){switch(r){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0},Sce=function(r,e,t,i){for(;t<i;t++)if(r[t]===e)return t;return i},vce=function(r){for(var e=8*32,t=0;t<148;t++)e+=r[t];for(var i=156;i<512;i++)e+=r[i];return e},Wl=function(r,e){return r=r.toString(8),r.length>e?n9e.slice(0,e)+" ":i9e.slice(0,e-r.length)+r+" "};function g9e(r){var e;if(r[0]===128)e=!0;else if(r[0]===255)e=!1;else return null;for(var t=[],i=r.length-1;i>0;i--){var n=r[i];e?t.push(n):t.push(255-n)}var s=0,o=t.length;for(i=0;i<o;i++)s+=t[i]*Math.pow(256,i);return e?s:-1*s}var zl=function(r,e,t){if(r=r.slice(e,e+t),e=0,r[e]&128)return g9e(r);for(;e<r.length&&r[e]===32;)e++;for(var i=l9e(Sce(r,32,e,r.length),r.length,r.length);e<i&&r[e]===0;)e++;return i===e?0:parseInt(r.slice(e,i).toString(),8)},mh=function(r,e,t,i){return r.slice(e,Sce(r,0,e,e+t)).toString(i)},FT=function(r){var e=Buffer.byteLength(r),t=Math.floor(Math.log(e)/Math.log(10))+1;return e+t>=Math.pow(10,t)&&t++,e+t+r};Ch.decodeLongPath=function(r,e){return mh(r,0,r.length,e)};Ch.encodePax=function(r){var e="";r.name&&(e+=FT(" path="+r.name+` -`)),r.linkname&&(e+=FT(" linkpath="+r.linkname+` -`));var t=r.pax;if(t)for(var i in t)e+=FT(" "+i+"="+t[i]+` -`);return Buffer.from(e)};Ch.decodePax=function(r){for(var e={};r.length;){for(var t=0;t<r.length&&r[t]!==32;)t++;var i=parseInt(r.slice(0,t).toString(),10);if(!i)return e;var n=r.slice(t+1,i-1).toString(),s=n.indexOf("=");if(s===-1)return e;e[n.slice(0,s)]=n.slice(s+1),r=r.slice(i)}return e};Ch.encode=function(r){var e=r9e(512),t=r.name,i="";if(r.typeflag===5&&t[t.length-1]!=="/"&&(t+="/"),Buffer.byteLength(t)!==t.length)return null;for(;Buffer.byteLength(t)>100;){var n=t.indexOf("/");if(n===-1)return null;i+=i?"/"+t.slice(0,n):t.slice(0,n),t=t.slice(n+1)}return Buffer.byteLength(t)>100||Buffer.byteLength(i)>155||r.linkname&&Buffer.byteLength(r.linkname)>100?null:(e.write(t),e.write(Wl(r.mode&A9e,6),100),e.write(Wl(r.uid,6),108),e.write(Wl(r.gid,6),116),e.write(Wl(r.size,11),124),e.write(Wl(r.mtime.getTime()/1e3|0,11),136),e[156]=bce+u9e(r.type),r.linkname&&e.write(r.linkname,157),Qce.copy(e,eE),s9e.copy(e,RT),r.uname&&e.write(r.uname,265),r.gname&&e.write(r.gname,297),e.write(Wl(r.devmajor||0,6),329),e.write(Wl(r.devminor||0,6),337),i&&e.write(i,345),e.write(Wl(vce(e),6),148),e)};Ch.decode=function(r,e,t){var i=r[156]===0?0:r[156]-bce,n=mh(r,0,100,e),s=zl(r,100,8),o=zl(r,108,8),a=zl(r,116,8),l=zl(r,124,12),c=zl(r,136,12),u=c9e(i),g=r[157]===0?null:mh(r,157,100,e),f=mh(r,265,32),h=mh(r,297,32),p=zl(r,329,8),m=zl(r,337,8),y=vce(r);if(y===8*32)return null;if(y!==zl(r,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(Qce.compare(r,eE,eE+6)===0)r[345]&&(n=mh(r,345,155,e)+"/"+n);else if(!(o9e.compare(r,eE,eE+6)===0&&a9e.compare(r,RT,RT+2)===0)){if(!t)throw new Error("Invalid tar header: unknown format.")}return i===0&&n&&n[n.length-1]==="/"&&(i=5),{name:n,mode:s,uid:o,gid:a,size:l,mtime:new Date(1e3*c),type:u,linkname:g,uname:f,gname:h,devmajor:p,devminor:m}}});var Nce=w((rvt,kce)=>{var xce=require("util"),f9e=Bce(),tE=NT(),Pce=dh().Writable,Dce=dh().PassThrough,Rce=function(){},Fce=function(r){return r&=511,r&&512-r},h9e=function(r,e){var t=new Sb(r,e);return t.end(),t},p9e=function(r,e){return e.path&&(r.name=e.path),e.linkpath&&(r.linkname=e.linkpath),e.size&&(r.size=parseInt(e.size,10)),r.pax=e,r},Sb=function(r,e){this._parent=r,this.offset=e,Dce.call(this,{autoDestroy:!1})};xce.inherits(Sb,Dce);Sb.prototype.destroy=function(r){this._parent.destroy(r)};var PA=function(r){if(!(this instanceof PA))return new PA(r);Pce.call(this,r),r=r||{},this._offset=0,this._buffer=f9e(),this._missing=0,this._partial=!1,this._onparse=Rce,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var e=this,t=e._buffer,i=function(){e._continue()},n=function(f){if(e._locked=!1,f)return e.destroy(f);e._stream||i()},s=function(){e._stream=null;var f=Fce(e._header.size);f?e._parse(f,o):e._parse(512,g),e._locked||i()},o=function(){e._buffer.consume(Fce(e._header.size)),e._parse(512,g),i()},a=function(){var f=e._header.size;e._paxGlobal=tE.decodePax(t.slice(0,f)),t.consume(f),s()},l=function(){var f=e._header.size;e._pax=tE.decodePax(t.slice(0,f)),e._paxGlobal&&(e._pax=Object.assign({},e._paxGlobal,e._pax)),t.consume(f),s()},c=function(){var f=e._header.size;this._gnuLongPath=tE.decodeLongPath(t.slice(0,f),r.filenameEncoding),t.consume(f),s()},u=function(){var f=e._header.size;this._gnuLongLinkPath=tE.decodeLongPath(t.slice(0,f),r.filenameEncoding),t.consume(f),s()},g=function(){var f=e._offset,h;try{h=e._header=tE.decode(t.slice(0,512),r.filenameEncoding,r.allowUnknownFormat)}catch(p){e.emit("error",p)}if(t.consume(512),!h){e._parse(512,g),i();return}if(h.type==="gnu-long-path"){e._parse(h.size,c),i();return}if(h.type==="gnu-long-link-path"){e._parse(h.size,u),i();return}if(h.type==="pax-global-header"){e._parse(h.size,a),i();return}if(h.type==="pax-header"){e._parse(h.size,l),i();return}if(e._gnuLongPath&&(h.name=e._gnuLongPath,e._gnuLongPath=null),e._gnuLongLinkPath&&(h.linkname=e._gnuLongLinkPath,e._gnuLongLinkPath=null),e._pax&&(e._header=h=p9e(h,e._pax),e._pax=null),e._locked=!0,!h.size||h.type==="directory"){e._parse(512,g),e.emit("entry",h,h9e(e,f),n);return}e._stream=new Sb(e,f),e.emit("entry",h,e._stream,n),e._parse(h.size,s),i()};this._onheader=g,this._parse(512,g)};xce.inherits(PA,Pce);PA.prototype.destroy=function(r){this._destroyed||(this._destroyed=!0,r&&this.emit("error",r),this.emit("close"),this._stream&&this._stream.emit("close"))};PA.prototype._parse=function(r,e){this._destroyed||(this._offset+=r,this._missing=r,e===this._onheader&&(this._partial=!1),this._onparse=e)};PA.prototype._continue=function(){if(!this._destroyed){var r=this._cb;this._cb=Rce,this._overflow?this._write(this._overflow,void 0,r):r()}};PA.prototype._write=function(r,e,t){if(!this._destroyed){var i=this._stream,n=this._buffer,s=this._missing;if(r.length&&(this._partial=!0),r.length<s)return this._missing-=r.length,this._overflow=null,i?i.write(r,t):(n.append(r),t());this._cb=t,this._missing=0;var o=null;r.length>s&&(o=r.slice(s),r=r.slice(0,s)),i?i.end(r):n.append(r),this._overflow=o,this._onparse()}};PA.prototype._final=function(r){if(this._partial)return this.destroy(new Error("Unexpected end of data"));r()};kce.exports=PA});var Tce=w((ivt,Lce)=>{Lce.exports=require("fs").constants||require("constants")});var Hce=w((nvt,Oce)=>{var Eh=Tce(),Mce=Ux(),vb=jl(),d9e=Buffer.alloc,Uce=dh().Readable,Ih=dh().Writable,C9e=require("string_decoder").StringDecoder,kb=NT(),m9e=parseInt("755",8),E9e=parseInt("644",8),Kce=d9e(1024),LT=function(){},TT=function(r,e){e&=511,e&&r.push(Kce.slice(0,512-e))};function I9e(r){switch(r&Eh.S_IFMT){case Eh.S_IFBLK:return"block-device";case Eh.S_IFCHR:return"character-device";case Eh.S_IFDIR:return"directory";case Eh.S_IFIFO:return"fifo";case Eh.S_IFLNK:return"symlink"}return"file"}var xb=function(r){Ih.call(this),this.written=0,this._to=r,this._destroyed=!1};vb(xb,Ih);xb.prototype._write=function(r,e,t){if(this.written+=r.length,this._to.push(r))return t();this._to._drain=t};xb.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var Pb=function(){Ih.call(this),this.linkname="",this._decoder=new C9e("utf-8"),this._destroyed=!1};vb(Pb,Ih);Pb.prototype._write=function(r,e,t){this.linkname+=this._decoder.write(r),t()};Pb.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var rE=function(){Ih.call(this),this._destroyed=!1};vb(rE,Ih);rE.prototype._write=function(r,e,t){t(new Error("No body allowed for this entry"))};rE.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var ya=function(r){if(!(this instanceof ya))return new ya(r);Uce.call(this,r),this._drain=LT,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};vb(ya,Uce);ya.prototype.entry=function(r,e,t){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof e=="function"&&(t=e,e=null),t||(t=LT);var i=this;if((!r.size||r.type==="symlink")&&(r.size=0),r.type||(r.type=I9e(r.mode)),r.mode||(r.mode=r.type==="directory"?m9e:E9e),r.uid||(r.uid=0),r.gid||(r.gid=0),r.mtime||(r.mtime=new Date),typeof e=="string"&&(e=Buffer.from(e)),Buffer.isBuffer(e)){r.size=e.length,this._encode(r);var n=this.push(e);return TT(i,r.size),n?process.nextTick(t):this._drain=t,new rE}if(r.type==="symlink"&&!r.linkname){var s=new Pb;return Mce(s,function(a){if(a)return i.destroy(),t(a);r.linkname=s.linkname,i._encode(r),t()}),s}if(this._encode(r),r.type!=="file"&&r.type!=="contiguous-file")return process.nextTick(t),new rE;var o=new xb(this);return this._stream=o,Mce(o,function(a){if(i._stream=null,a)return i.destroy(),t(a);if(o.written!==r.size)return i.destroy(),t(new Error("size mismatch"));TT(i,r.size),i._finalizing&&i.finalize(),t()}),o}};ya.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push(Kce),this.push(null))};ya.prototype.destroy=function(r){this._destroyed||(this._destroyed=!0,r&&this.emit("error",r),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};ya.prototype._encode=function(r){if(!r.pax){var e=kb.encode(r);if(e){this.push(e);return}}this._encodePax(r)};ya.prototype._encodePax=function(r){var e=kb.encodePax({name:r.name,linkname:r.linkname,pax:r.pax}),t={name:"PaxHeader",mode:r.mode,uid:r.uid,gid:r.gid,size:e.length,mtime:r.mtime,type:"pax-header",linkname:r.linkname&&"PaxHeader",uname:r.uname,gname:r.gname,devmajor:r.devmajor,devminor:r.devminor};this.push(kb.encode(t)),this.push(e),TT(this,e.length),t.size=r.size,t.type=r.type,this.push(kb.encode(t))};ya.prototype._read=function(r){var e=this._drain;this._drain=LT,e()};Oce.exports=ya});var jce=w(OT=>{OT.extract=Nce();OT.pack=Hce()});var tue=w((vvt,Xce)=>{"use strict";var yh=class{constructor(e,t,i){this.__specs=e||{},Object.keys(this.__specs).forEach(n=>{if(typeof this.__specs[n]=="string"){let s=this.__specs[n],o=this.__specs[s];if(o){let a=o.aliases||[];a.push(n,s),o.aliases=[...new Set(a)],this.__specs[n]=o}else throw new Error(`Alias refers to invalid key: ${s} -> ${n}`)}}),this.__opts=t||{},this.__providers=$ce(i.filter(n=>n!=null&&typeof n=="object")),this.__isFiggyPudding=!0}get(e){return GT(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,t=this){for(let[i,n]of this.entries())e.call(t,n,i,this)}toJSON(){let e={};return this.forEach((t,i)=>{e[i]=t}),e}*entries(e){for(let i of Object.keys(this.__specs))yield[i,this.get(i)];let t=e||this.__opts.other;if(t){let i=new Set;for(let n of this.__providers){let s=n.entries?n.entries(t):F9e(n);for(let[o,a]of s)t(o)&&!i.has(o)&&(i.add(o),yield[o,a])}}}*[Symbol.iterator](){for(let[e,t]of this.entries())yield[e,t]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new yh(this.__specs,this.__opts,$ce(this.__providers).concat(e)),Zce)}};try{let r=require("util");yh.prototype[r.inspect.custom]=function(e,t){return this[Symbol.toStringTag]+" "+r.inspect(this.toJSON(),t)}}catch(r){}function N9e(r){throw Object.assign(new Error(`invalid config key requested: ${r}`),{code:"EBADKEY"})}function GT(r,e,t){let i=r.__specs[e];if(t&&!i&&(!r.__opts.other||!r.__opts.other(e)))N9e(e);else{i||(i={});let n;for(let s of r.__providers){if(n=eue(e,s),n===void 0&&i.aliases&&i.aliases.length){for(let o of i.aliases)if(o!==e&&(n=eue(o,s),n!==void 0))break}if(n!==void 0)break}return n===void 0&&i.default!==void 0?typeof i.default=="function"?i.default(r):i.default:n}}function eue(r,e){let t;return e.__isFiggyPudding?t=GT(e,r,!1):typeof e.get=="function"?t=e.get(r):t=e[r],t}var Zce={has(r,e){return e in r.__specs&>(r,e,!1)!==void 0},ownKeys(r){return Object.keys(r.__specs)},get(r,e){return typeof e=="symbol"||e.slice(0,2)==="__"||e in yh.prototype?r[e]:r.get(e)},set(r,e,t){if(typeof e=="symbol"||e.slice(0,2)==="__")return r[e]=t,!0;throw new Error("figgyPudding options cannot be modified. Use .concat() instead.")},deleteProperty(){throw new Error("figgyPudding options cannot be deleted. Use .concat() and shadow them instead.")}};Xce.exports=L9e;function L9e(r,e){function t(...i){return new Proxy(new yh(r,e,i),Zce)}return t}function $ce(r){let e=[];return r.forEach(t=>e.unshift(t)),e}function F9e(r){return Object.keys(r).map(e=>[e,r[e]])}});var nue=w((kvt,wa)=>{"use strict";var nE=require("crypto"),T9e=tue(),O9e=require("stream").Transform,rue=["sha256","sha384","sha512"],M9e=/^[a-z0-9+/]+(?:=?=?)$/i,U9e=/^([^-]+)-([^?]+)([?\S*]*)$/,K9e=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,H9e=/^[\x21-\x7E]+$/,Cn=T9e({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>j9e},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}}),Nu=class{get isHash(){return!0}constructor(e,t){t=Cn(t);let i=!!t.strict;this.source=e.trim();let n=this.source.match(i?K9e:U9e);if(!n||i&&!rue.some(o=>o===n[1]))return;this.algorithm=n[1],this.digest=n[2];let s=n[3];this.options=s?s.slice(1).split("?"):[]}hexDigest(){return this.digest&&Buffer.from(this.digest,"base64").toString("hex")}toJSON(){return this.toString()}toString(e){if(e=Cn(e),e.strict&&!(rue.some(i=>i===this.algorithm)&&this.digest.match(M9e)&&(this.options||[]).every(i=>i.match(H9e))))return"";let t=this.options&&this.options.length?`?${this.options.join("?")}`:"";return`${this.algorithm}-${this.digest}${t}`}},wh=class{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){e=Cn(e);let t=e.sep||" ";return e.strict&&(t=t.replace(/\S+/g," ")),Object.keys(this).map(i=>this[i].map(n=>Nu.prototype.toString.call(n,e)).filter(n=>n.length).join(t)).filter(i=>i.length).join(t)}concat(e,t){t=Cn(t);let i=typeof e=="string"?e:sE(e,t);return Ba(`${this.toString(t)} ${i}`,t)}hexDigest(){return Ba(this,{single:!0}).hexDigest()}match(e,t){t=Cn(t);let i=Ba(e,t),n=i.pickAlgorithm(t);return this[n]&&i[n]&&this[n].find(s=>i[n].find(o=>s.digest===o.digest))||!1}pickAlgorithm(e){e=Cn(e);let t=e.pickAlgorithm,i=Object.keys(this);if(!i.length)throw new Error(`No algorithms available for ${JSON.stringify(this.toString())}`);return i.reduce((n,s)=>t(n,s)||n)}};wa.exports.parse=Ba;function Ba(r,e){if(e=Cn(e),typeof r=="string")return YT(r,e);if(r.algorithm&&r.digest){let t=new wh;return t[r.algorithm]=[r],YT(sE(t,e),e)}else return YT(sE(r,e),e)}function YT(r,e){return e.single?new Nu(r,e):r.trim().split(/\s+/).reduce((t,i)=>{let n=new Nu(i,e);if(n.algorithm&&n.digest){let s=n.algorithm;t[s]||(t[s]=[]),t[s].push(n)}return t},new wh)}wa.exports.stringify=sE;function sE(r,e){return e=Cn(e),r.algorithm&&r.digest?Nu.prototype.toString.call(r,e):typeof r=="string"?sE(Ba(r,e),e):wh.prototype.toString.call(r,e)}wa.exports.fromHex=G9e;function G9e(r,e,t){t=Cn(t);let i=t.options&&t.options.length?`?${t.options.join("?")}`:"";return Ba(`${e}-${Buffer.from(r,"hex").toString("base64")}${i}`,t)}wa.exports.fromData=Y9e;function Y9e(r,e){e=Cn(e);let t=e.algorithms,i=e.options&&e.options.length?`?${e.options.join("?")}`:"";return t.reduce((n,s)=>{let o=nE.createHash(s).update(r).digest("base64"),a=new Nu(`${s}-${o}${i}`,e);if(a.algorithm&&a.digest){let l=a.algorithm;n[l]||(n[l]=[]),n[l].push(a)}return n},new wh)}wa.exports.fromStream=q9e;function q9e(r,e){e=Cn(e);let t=e.Promise||Promise,i=qT(e);return new t((n,s)=>{r.pipe(i),r.on("error",s),i.on("error",s);let o;i.on("integrity",a=>{o=a}),i.on("end",()=>n(o)),i.on("data",()=>{})})}wa.exports.checkData=J9e;function J9e(r,e,t){if(t=Cn(t),e=Ba(e,t),!Object.keys(e).length){if(t.error)throw Object.assign(new Error("No valid integrity hashes to check against"),{code:"EINTEGRITY"});return!1}let i=e.pickAlgorithm(t),n=nE.createHash(i).update(r).digest("base64"),s=Ba({algorithm:i,digest:n}),o=s.match(e,t);if(o||!t.error)return o;if(typeof t.size=="number"&&r.length!==t.size){let a=new Error(`data size mismatch when checking ${e}. - Wanted: ${t.size} - Found: ${r.length}`);throw a.code="EBADSIZE",a.found=r.length,a.expected=t.size,a.sri=e,a}else{let a=new Error(`Integrity checksum failed when using ${i}: Wanted ${e}, but got ${s}. (${r.length} bytes)`);throw a.code="EINTEGRITY",a.found=s,a.expected=e,a.algorithm=i,a.sri=e,a}}wa.exports.checkStream=W9e;function W9e(r,e,t){t=Cn(t);let i=t.Promise||Promise,n=qT(t.concat({integrity:e}));return new i((s,o)=>{r.pipe(n),r.on("error",o),n.on("error",o);let a;n.on("verified",l=>{a=l}),n.on("end",()=>s(a)),n.on("data",()=>{})})}wa.exports.integrityStream=qT;function qT(r){r=Cn(r);let e=r.integrity&&Ba(r.integrity,r),t=e&&Object.keys(e).length,i=t&&e.pickAlgorithm(r),n=t&&e[i],s=Array.from(new Set(r.algorithms.concat(i?[i]:[]))),o=s.map(nE.createHash),a=0,l=new O9e({transform(c,u,g){a+=c.length,o.forEach(f=>f.update(c,u)),g(null,c,u)}}).on("end",()=>{let c=r.options&&r.options.length?`?${r.options.join("?")}`:"",u=Ba(o.map((f,h)=>`${s[h]}-${f.digest("base64")}${c}`).join(" "),r),g=t&&u.match(e,r);if(typeof r.size=="number"&&a!==r.size){let f=new Error(`stream size mismatch when checking ${e}. - Wanted: ${r.size} - Found: ${a}`);f.code="EBADSIZE",f.found=a,f.expected=r.size,f.sri=e,l.emit("error",f)}else if(r.integrity&&!g){let f=new Error(`${e} integrity checksum failed when using ${i}: wanted ${n} but got ${u}. (${a} bytes)`);f.code="EINTEGRITY",f.found=u,f.expected=n,f.algorithm=i,f.sri=e,l.emit("error",f)}else l.emit("size",a),l.emit("integrity",u),g&&l.emit("verified",g)});return l}wa.exports.create=z9e;function z9e(r){r=Cn(r);let e=r.algorithms,t=r.options.length?`?${r.options.join("?")}`:"",i=e.map(nE.createHash);return{update:function(n,s){return i.forEach(o=>o.update(n,s)),this},digest:function(n){return e.reduce((o,a)=>{let l=i.shift().digest("base64"),c=new Nu(`${a}-${l}${t}`,r);if(c.algorithm&&c.digest){let u=c.algorithm;o[u]||(o[u]=[]),o[u].push(c)}return o},new wh)}}}var _9e=new Set(nE.getHashes()),iue=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(r=>_9e.has(r));function j9e(r,e){return iue.indexOf(r.toLowerCase())>=iue.indexOf(e.toLowerCase())?r:e}});var IC={};ft(IC,{BuildType:()=>cs,Cache:()=>Nt,Configuration:()=>ye,DEFAULT_LOCK_FILENAME:()=>hx,DEFAULT_RC_FILENAME:()=>fx,FormatType:()=>Ri,InstallMode:()=>Ci,LightReport:()=>dA,LinkType:()=>Qt,Manifest:()=>At,MessageName:()=>X,MultiFetcher:()=>wd,PackageExtensionStatus:()=>qi,PackageExtensionType:()=>wi,Project:()=>ze,ProjectLookup:()=>gl,Report:()=>Ji,ReportError:()=>ct,SettingsType:()=>Ie,StreamReport:()=>Je,TAG_REGEXP:()=>_g,TelemetryManager:()=>EC,ThrowReport:()=>di,VirtualFetcher:()=>bd,Workspace:()=>mC,WorkspaceFetcher:()=>Qd,WorkspaceResolver:()=>oi,YarnVersion:()=>Kr,execUtils:()=>Nr,folderUtils:()=>ox,formatUtils:()=>ae,hashUtils:()=>Rn,httpUtils:()=>ir,miscUtils:()=>Se,nodeUtils:()=>Xg,parseMessageName:()=>yI,scriptUtils:()=>Zt,semverUtils:()=>Wt,stringifyMessageName:()=>VA,structUtils:()=>P,tgzUtils:()=>Bi,treeUtils:()=>ls});var Nr={};ft(Nr,{EndStrategy:()=>ss,ExecError:()=>yx,PipeError:()=>Bw,execvp:()=>mve,pipevp:()=>ia});var $h={};ft($h,{AliasFS:()=>La,CwdFS:()=>_t,DEFAULT_COMPRESSION_LEVEL:()=>cc,FakeFS:()=>qA,Filename:()=>xt,JailFS:()=>Ta,LazyFS:()=>Vh,LinkStrategy:()=>Yh,NoFS:()=>GE,NodeFS:()=>ar,PortablePath:()=>Me,PosixFS:()=>Xh,ProxiedFS:()=>Qi,VirtualFS:()=>Wr,ZipFS:()=>li,ZipOpenFS:()=>ys,constants:()=>Rr,extendFs:()=>zE,normalizeLineEndings:()=>oc,npath:()=>H,opendir:()=>KE,patchFs:()=>dQ,ppath:()=>x,statUtils:()=>iQ,toFilename:()=>Jr,xfs:()=>U});var Rr={};ft(Rr,{SAFE_TIME:()=>rQ,S_IFDIR:()=>Ra,S_IFLNK:()=>Na,S_IFMT:()=>Vn,S_IFREG:()=>Fa});var Vn=61440,Ra=16384,Fa=32768,Na=40960,rQ=456789e3;var iQ={};ft(iQ,{BigIntStatsEntry:()=>Hh,DEFAULT_MODE:()=>Kh,DirEntry:()=>GO,StatEntry:()=>GA,areStatsEqual:()=>sQ,clearStats:()=>FE,convertToBigIntStats:()=>NE,makeDefaultStats:()=>jh,makeEmptyStats:()=>dge});var nQ=ge(require("util"));var Kh=Fa|420,GO=class{constructor(){this.name="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&Vn)===Ra}isFIFO(){return!1}isFile(){return(this.mode&Vn)===Fa}isSocket(){return!1}isSymbolicLink(){return(this.mode&Vn)===Na}},GA=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=Kh;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&Vn)===Ra}isFIFO(){return!1}isFile(){return(this.mode&Vn)===Fa}isSocket(){return!1}isSymbolicLink(){return(this.mode&Vn)===Na}},Hh=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(Kh);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(Vn))===BigInt(Ra)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(Vn))===BigInt(Fa)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(Vn))===BigInt(Na)}};function jh(){return new GA}function dge(){return FE(jh())}function FE(r){for(let e in r)if(Object.prototype.hasOwnProperty.call(r,e)){let t=r[e];typeof t=="number"?r[e]=0:typeof t=="bigint"?r[e]=BigInt(0):nQ.types.isDate(t)&&(r[e]=new Date(0))}return r}function NE(r){let e=new Hh;for(let t in r)if(Object.prototype.hasOwnProperty.call(r,t)){let i=r[t];typeof i=="number"?e[t]=BigInt(i):nQ.types.isDate(i)&&(e[t]=new Date(i))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function sQ(r,e){if(r.atimeMs!==e.atimeMs||r.birthtimeMs!==e.birthtimeMs||r.blksize!==e.blksize||r.blocks!==e.blocks||r.ctimeMs!==e.ctimeMs||r.dev!==e.dev||r.gid!==e.gid||r.ino!==e.ino||r.isBlockDevice()!==e.isBlockDevice()||r.isCharacterDevice()!==e.isCharacterDevice()||r.isDirectory()!==e.isDirectory()||r.isFIFO()!==e.isFIFO()||r.isFile()!==e.isFile()||r.isSocket()!==e.isSocket()||r.isSymbolicLink()!==e.isSymbolicLink()||r.mode!==e.mode||r.mtimeMs!==e.mtimeMs||r.nlink!==e.nlink||r.rdev!==e.rdev||r.size!==e.size||r.uid!==e.uid)return!1;let t=r,i=e;return!(t.atimeNs!==i.atimeNs||t.mtimeNs!==i.mtimeNs||t.ctimeNs!==i.ctimeNs||t.birthtimeNs!==i.birthtimeNs)}var TE=ge(require("fs"));var Gh=ge(require("path")),YO;(function(i){i[i.File=0]="File",i[i.Portable=1]="Portable",i[i.Native=2]="Native"})(YO||(YO={}));var Me={root:"/",dot:"."},xt={nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",rc:".yarnrc.yml"},H=Object.create(Gh.default),x=Object.create(Gh.default.posix);H.cwd=()=>process.cwd();x.cwd=()=>oQ(process.cwd());x.resolve=(...r)=>r.length>0&&x.isAbsolute(r[0])?Gh.default.posix.resolve(...r):Gh.default.posix.resolve(x.cwd(),...r);var qO=function(r,e,t){return e=r.normalize(e),t=r.normalize(t),e===t?".":(e.endsWith(r.sep)||(e=e+r.sep),t.startsWith(e)?t.slice(e.length):null)};H.fromPortablePath=JO;H.toPortablePath=oQ;H.contains=(r,e)=>qO(H,r,e);x.contains=(r,e)=>qO(x,r,e);var Cge=/^([a-zA-Z]:.*)$/,mge=/^\/\/(\.\/)?(.*)$/,Ege=/^\/([a-zA-Z]:.*)$/,Ige=/^\/unc\/(\.dot\/)?(.*)$/;function JO(r){if(process.platform!=="win32")return r;let e,t;if(e=r.match(Ege))r=e[1];else if(t=r.match(Ige))r=`\\\\${t[1]?".\\":""}${t[2]}`;else return r;return r.replace(/\//g,"\\")}function oQ(r){if(process.platform!=="win32")return r;r=r.replace(/\\/g,"/");let e,t;return(e=r.match(Cge))?r=`/${e[1]}`:(t=r.match(mge))&&(r=`/unc/${t[1]?".dot/":""}${t[2]}`),r}function LE(r,e){return r===H?JO(e):oQ(e)}function Jr(r){if(H.parse(r).dir!==""||x.parse(r).dir!=="")throw new Error(`Invalid filename: "${r}"`);return r}var OE=new Date(rQ*1e3),Yh;(function(t){t.Allow="allow",t.ReadOnly="readOnly"})(Yh||(Yh={}));async function WO(r,e,t,i,n){let s=r.pathUtils.normalize(e),o=t.pathUtils.normalize(i),a=[],l=[],{atime:c,mtime:u}=n.stableTime?{atime:OE,mtime:OE}:await t.lstatPromise(o);await r.mkdirpPromise(r.pathUtils.dirname(e),{utimes:[c,u]});let g=typeof r.lutimesPromise=="function"?r.lutimesPromise.bind(r):r.utimesPromise.bind(r);await aQ(a,l,g,r,s,t,o,te(N({},n),{didParentExist:!0}));for(let f of a)await f();await Promise.all(l.map(f=>f()))}async function aQ(r,e,t,i,n,s,o,a){var h,p;let l=a.didParentExist?await yge(i,n):null,c=await s.lstatPromise(o),{atime:u,mtime:g}=a.stableTime?{atime:OE,mtime:OE}:c,f;switch(!0){case c.isDirectory():f=await wge(r,e,t,i,n,l,s,o,c,a);break;case c.isFile():f=await Bge(r,e,t,i,n,l,s,o,c,a);break;case c.isSymbolicLink():f=await bge(r,e,t,i,n,l,s,o,c,a);break;default:throw new Error(`Unsupported file type (${c.mode})`)}return(f||((h=l==null?void 0:l.mtime)==null?void 0:h.getTime())!==g.getTime()||((p=l==null?void 0:l.atime)==null?void 0:p.getTime())!==u.getTime())&&(e.push(()=>t(n,u,g)),f=!0),(l===null||(l.mode&511)!=(c.mode&511))&&(e.push(()=>i.chmodPromise(n,c.mode&511)),f=!0),f}async function yge(r,e){try{return await r.lstatPromise(e)}catch(t){return null}}async function wge(r,e,t,i,n,s,o,a,l,c){if(s!==null&&!s.isDirectory())if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;let u=!1;s===null&&(r.push(async()=>{try{await i.mkdirPromise(n,{mode:l.mode})}catch(h){if(h.code!=="EEXIST")throw h}}),u=!0);let g=await o.readdirPromise(a),f=c.didParentExist&&!s?te(N({},c),{didParentExist:!1}):c;if(c.stableSort)for(let h of g.sort())await aQ(r,e,t,i,i.pathUtils.join(n,h),o,o.pathUtils.join(a,h),f)&&(u=!0);else(await Promise.all(g.map(async p=>{await aQ(r,e,t,i,i.pathUtils.join(n,p),o,o.pathUtils.join(a,p),f)}))).some(p=>p)&&(u=!0);return u}var AQ=new WeakMap;function lQ(r,e,t,i,n){return async()=>{await r.linkPromise(t,e),n===Yh.ReadOnly&&(i.mode&=~146,await r.chmodPromise(e,i.mode))}}function Qge(r,e,t,i,n){let s=AQ.get(r);return typeof s=="undefined"?async()=>{try{await r.copyFilePromise(t,e,TE.default.constants.COPYFILE_FICLONE_FORCE),AQ.set(r,!0)}catch(o){if(o.code==="ENOSYS"||o.code==="ENOTSUP")AQ.set(r,!1),await lQ(r,e,t,i,n)();else throw o}}:s?async()=>r.copyFilePromise(t,e,TE.default.constants.COPYFILE_FICLONE_FORCE):lQ(r,e,t,i,n)}async function Bge(r,e,t,i,n,s,o,a,l,c){var f;if(s!==null)if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;let u=(f=c.linkStrategy)!=null?f:null,g=i===o?u!==null?Qge(i,n,a,l,u):async()=>i.copyFilePromise(a,n,TE.default.constants.COPYFILE_FICLONE):u!==null?lQ(i,n,a,l,u):async()=>i.writeFilePromise(n,await o.readFilePromise(a));return r.push(async()=>g()),!0}async function bge(r,e,t,i,n,s,o,a,l,c){if(s!==null)if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;return r.push(async()=>{await i.symlinkPromise(LE(i.pathUtils,await o.readlinkPromise(a)),n)}),!0}function Es(r,e){return Object.assign(new Error(`${r}: ${e}`),{code:r})}function ME(r){return Es("EBUSY",r)}function qh(r,e){return Es("ENOSYS",`${r}, ${e}`)}function YA(r){return Es("EINVAL",`invalid argument, ${r}`)}function Ai(r){return Es("EBADF",`bad file descriptor, ${r}`)}function so(r){return Es("ENOENT",`no such file or directory, ${r}`)}function No(r){return Es("ENOTDIR",`not a directory, ${r}`)}function Jh(r){return Es("EISDIR",`illegal operation on a directory, ${r}`)}function UE(r){return Es("EEXIST",`file already exists, ${r}`)}function In(r){return Es("EROFS",`read-only filesystem, ${r}`)}function zO(r){return Es("ENOTEMPTY",`directory not empty, ${r}`)}function _O(r){return Es("EOPNOTSUPP",`operation not supported, ${r}`)}function VO(){return Es("ERR_DIR_CLOSED","Directory handle was closed")}var cQ=class extends Error{constructor(e,t){super(e);this.name="Libzip Error",this.code=t}};var XO=class{constructor(e,t,i={}){this.path=e;this.nextDirent=t;this.opts=i;this.closed=!1}throwIfClosed(){if(this.closed)throw VO()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let t=this.readSync();return typeof e!="undefined"?e(null,t):Promise.resolve(t)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e!="undefined"?e(null):Promise.resolve()}closeSync(){var e,t;this.throwIfClosed(),(t=(e=this.opts).onClose)==null||t.call(e),this.closed=!0}};function KE(r,e,t,i){let n=()=>{let s=t.shift();return typeof s=="undefined"?null:Object.assign(r.statSync(r.pathUtils.join(e,s)),{name:s})};return new XO(e,n,i)}var ZO=ge(require("os"));var qA=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:t=!1}={}){let i=[e];for(;i.length>0;){let n=i.shift();if((await this.lstatPromise(n)).isDirectory()){let o=await this.readdirPromise(n);if(t)for(let a of o.sort())i.push(this.pathUtils.join(n,a));else throw new Error("Not supported")}else yield n}}async removePromise(e,{recursive:t=!0,maxRetries:i=5}={}){let n;try{n=await this.lstatPromise(e)}catch(s){if(s.code==="ENOENT")return;throw s}if(n.isDirectory()){if(t){let s=await this.readdirPromise(e);await Promise.all(s.map(o=>this.removePromise(this.pathUtils.resolve(e,o))))}for(let s=0;s<=i;s++)try{await this.rmdirPromise(e);break}catch(o){if(o.code!=="EBUSY"&&o.code!=="ENOTEMPTY")throw o;s<i&&await new Promise(a=>setTimeout(a,s*100))}}else await this.unlinkPromise(e)}removeSync(e,{recursive:t=!0}={}){let i;try{i=this.lstatSync(e)}catch(n){if(n.code==="ENOENT")return;throw n}if(i.isDirectory()){if(t)for(let n of this.readdirSync(e))this.removeSync(this.pathUtils.resolve(e,n));this.rmdirSync(e)}else this.unlinkSync(e)}async mkdirpPromise(e,{chmod:t,utimes:i}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let n=e.split(this.pathUtils.sep),s;for(let o=2;o<=n.length;++o){let a=n.slice(0,o).join(this.pathUtils.sep);if(!this.existsSync(a)){try{await this.mkdirPromise(a)}catch(l){if(l.code==="EEXIST")continue;throw l}if(s!=null||(s=a),t!=null&&await this.chmodPromise(a,t),i!=null)await this.utimesPromise(a,i[0],i[1]);else{let l=await this.statPromise(this.pathUtils.dirname(a));await this.utimesPromise(a,l.atime,l.mtime)}}}return s}mkdirpSync(e,{chmod:t,utimes:i}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let n=e.split(this.pathUtils.sep),s;for(let o=2;o<=n.length;++o){let a=n.slice(0,o).join(this.pathUtils.sep);if(!this.existsSync(a)){try{this.mkdirSync(a)}catch(l){if(l.code==="EEXIST")continue;throw l}if(s!=null||(s=a),t!=null&&this.chmodSync(a,t),i!=null)this.utimesSync(a,i[0],i[1]);else{let l=this.statSync(this.pathUtils.dirname(a));this.utimesSync(a,l.atime,l.mtime)}}}return s}async copyPromise(e,t,{baseFs:i=this,overwrite:n=!0,stableSort:s=!1,stableTime:o=!1,linkStrategy:a=null}={}){return await WO(this,e,i,t,{overwrite:n,stableSort:s,stableTime:o,linkStrategy:a})}copySync(e,t,{baseFs:i=this,overwrite:n=!0}={}){let s=i.lstatSync(t),o=this.existsSync(e);if(s.isDirectory()){this.mkdirpSync(e);let l=i.readdirSync(t);for(let c of l)this.copySync(this.pathUtils.join(e,c),i.pathUtils.join(t,c),{baseFs:i,overwrite:n})}else if(s.isFile()){if(!o||n){o&&this.removeSync(e);let l=i.readFileSync(t);this.writeFileSync(e,l)}}else if(s.isSymbolicLink()){if(!o||n){o&&this.removeSync(e);let l=i.readlinkSync(t);this.symlinkSync(LE(this.pathUtils,l),e)}}else throw new Error(`Unsupported file type (file: ${t}, mode: 0o${s.mode.toString(8).padStart(6,"0")})`);let a=s.mode&511;this.chmodSync(e,a)}async changeFilePromise(e,t,i={}){return Buffer.isBuffer(t)?this.changeFileBufferPromise(e,t,i):this.changeFileTextPromise(e,t,i)}async changeFileBufferPromise(e,t,{mode:i}={}){let n=Buffer.alloc(0);try{n=await this.readFilePromise(e)}catch(s){}Buffer.compare(n,t)!==0&&await this.writeFilePromise(e,t,{mode:i})}async changeFileTextPromise(e,t,{automaticNewlines:i,mode:n}={}){let s="";try{s=await this.readFilePromise(e,"utf8")}catch(a){}let o=i?oc(s,t):t;s!==o&&await this.writeFilePromise(e,o,{mode:n})}changeFileSync(e,t,i={}){return Buffer.isBuffer(t)?this.changeFileBufferSync(e,t,i):this.changeFileTextSync(e,t,i)}changeFileBufferSync(e,t,{mode:i}={}){let n=Buffer.alloc(0);try{n=this.readFileSync(e)}catch(s){}Buffer.compare(n,t)!==0&&this.writeFileSync(e,t,{mode:i})}changeFileTextSync(e,t,{automaticNewlines:i=!1,mode:n}={}){let s="";try{s=this.readFileSync(e,"utf8")}catch(a){}let o=i?oc(s,t):t;s!==o&&this.writeFileSync(e,o,{mode:n})}async movePromise(e,t){try{await this.renamePromise(e,t)}catch(i){if(i.code==="EXDEV")await this.copyPromise(t,e),await this.removePromise(e);else throw i}}moveSync(e,t){try{this.renameSync(e,t)}catch(i){if(i.code==="EXDEV")this.copySync(t,e),this.removeSync(e);else throw i}}async lockPromise(e,t){let i=`${e}.flock`,n=1e3/60,s=Date.now(),o=null,a=async()=>{let l;try{[l]=await this.readJsonPromise(i)}catch(c){return Date.now()-s<500}try{return process.kill(l,0),!0}catch(c){return!1}};for(;o===null;)try{o=await this.openPromise(i,"wx")}catch(l){if(l.code==="EEXIST"){if(!await a())try{await this.unlinkPromise(i);continue}catch(c){}if(Date.now()-s<60*1e3)await new Promise(c=>setTimeout(c,n));else throw new Error(`Couldn't acquire a lock in a reasonable time (via ${i})`)}else throw l}await this.writePromise(o,JSON.stringify([process.pid]));try{return await t()}finally{try{await this.closePromise(o),await this.unlinkPromise(i)}catch(l){}}}async readJsonPromise(e){let t=await this.readFilePromise(e,"utf8");try{return JSON.parse(t)}catch(i){throw i.message+=` (in ${e})`,i}}readJsonSync(e){let t=this.readFileSync(e,"utf8");try{return JSON.parse(t)}catch(i){throw i.message+=` (in ${e})`,i}}async writeJsonPromise(e,t){return await this.writeFilePromise(e,`${JSON.stringify(t,null,2)} -`)}writeJsonSync(e,t){return this.writeFileSync(e,`${JSON.stringify(t,null,2)} -`)}async preserveTimePromise(e,t){let i=await this.lstatPromise(e),n=await t();typeof n!="undefined"&&(e=n),this.lutimesPromise?await this.lutimesPromise(e,i.atime,i.mtime):i.isSymbolicLink()||await this.utimesPromise(e,i.atime,i.mtime)}async preserveTimeSync(e,t){let i=this.lstatSync(e),n=t();typeof n!="undefined"&&(e=n),this.lutimesSync?this.lutimesSync(e,i.atime,i.mtime):i.isSymbolicLink()||this.utimesSync(e,i.atime,i.mtime)}},ac=class extends qA{constructor(){super(x)}};function Sge(r){let e=r.match(/\r?\n/g);if(e===null)return ZO.EOL;let t=e.filter(n=>n===`\r -`).length,i=e.length-t;return t>i?`\r -`:` -`}function oc(r,e){return e.replace(/\r?\n/g,Sge(r))}var _u=ge(require("fs")),uQ=ge(require("stream")),rM=ge(require("util")),gQ=ge(require("zlib"));var $O=ge(require("fs"));var ar=class extends ac{constructor(e=$O.default){super();this.realFs=e,typeof this.realFs.lutimes!="undefined"&&(this.lutimesPromise=this.lutimesPromiseImpl,this.lutimesSync=this.lutimesSyncImpl)}getExtractHint(){return!1}getRealPath(){return Me.root}resolve(e){return x.resolve(e)}async openPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.open(H.fromPortablePath(e),t,i,this.makeCallback(n,s))})}openSync(e,t,i){return this.realFs.openSync(H.fromPortablePath(e),t,i)}async opendirPromise(e,t){return await new Promise((i,n)=>{typeof t!="undefined"?this.realFs.opendir(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.opendir(H.fromPortablePath(e),this.makeCallback(i,n))}).then(i=>Object.defineProperty(i,"path",{value:e,configurable:!0,writable:!0}))}opendirSync(e,t){let i=typeof t!="undefined"?this.realFs.opendirSync(H.fromPortablePath(e),t):this.realFs.opendirSync(H.fromPortablePath(e));return Object.defineProperty(i,"path",{value:e,configurable:!0,writable:!0})}async readPromise(e,t,i=0,n=0,s=-1){return await new Promise((o,a)=>{this.realFs.read(e,t,i,n,s,(l,c)=>{l?a(l):o(c)})})}readSync(e,t,i,n,s){return this.realFs.readSync(e,t,i,n,s)}async writePromise(e,t,i,n,s){return await new Promise((o,a)=>typeof t=="string"?this.realFs.write(e,t,i,this.makeCallback(o,a)):this.realFs.write(e,t,i,n,s,this.makeCallback(o,a)))}writeSync(e,t,i,n,s){return typeof t=="string"?this.realFs.writeSync(e,t,i):this.realFs.writeSync(e,t,i,n,s)}async closePromise(e){await new Promise((t,i)=>{this.realFs.close(e,this.makeCallback(t,i))})}closeSync(e){this.realFs.closeSync(e)}createReadStream(e,t){let i=e!==null?H.fromPortablePath(e):e;return this.realFs.createReadStream(i,t)}createWriteStream(e,t){let i=e!==null?H.fromPortablePath(e):e;return this.realFs.createWriteStream(i,t)}async realpathPromise(e){return await new Promise((t,i)=>{this.realFs.realpath(H.fromPortablePath(e),{},this.makeCallback(t,i))}).then(t=>H.toPortablePath(t))}realpathSync(e){return H.toPortablePath(this.realFs.realpathSync(H.fromPortablePath(e),{}))}async existsPromise(e){return await new Promise(t=>{this.realFs.exists(H.fromPortablePath(e),t)})}accessSync(e,t){return this.realFs.accessSync(H.fromPortablePath(e),t)}async accessPromise(e,t){return await new Promise((i,n)=>{this.realFs.access(H.fromPortablePath(e),t,this.makeCallback(i,n))})}existsSync(e){return this.realFs.existsSync(H.fromPortablePath(e))}async statPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.stat(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.stat(H.fromPortablePath(e),this.makeCallback(i,n))})}statSync(e,t){return t?this.realFs.statSync(H.fromPortablePath(e),t):this.realFs.statSync(H.fromPortablePath(e))}async fstatPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.fstat(e,t,this.makeCallback(i,n)):this.realFs.fstat(e,this.makeCallback(i,n))})}fstatSync(e,t){return t?this.realFs.fstatSync(e,t):this.realFs.fstatSync(e)}async lstatPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.lstat(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.lstat(H.fromPortablePath(e),this.makeCallback(i,n))})}lstatSync(e,t){return t?this.realFs.lstatSync(H.fromPortablePath(e),t):this.realFs.lstatSync(H.fromPortablePath(e))}async fchmodPromise(e,t){return await new Promise((i,n)=>{this.realFs.fchmod(e,t,this.makeCallback(i,n))})}fchmodSync(e,t){return this.realFs.fchmodSync(e,t)}async chmodPromise(e,t){return await new Promise((i,n)=>{this.realFs.chmod(H.fromPortablePath(e),t,this.makeCallback(i,n))})}chmodSync(e,t){return this.realFs.chmodSync(H.fromPortablePath(e),t)}async chownPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.chown(H.fromPortablePath(e),t,i,this.makeCallback(n,s))})}chownSync(e,t,i){return this.realFs.chownSync(H.fromPortablePath(e),t,i)}async renamePromise(e,t){return await new Promise((i,n)=>{this.realFs.rename(H.fromPortablePath(e),H.fromPortablePath(t),this.makeCallback(i,n))})}renameSync(e,t){return this.realFs.renameSync(H.fromPortablePath(e),H.fromPortablePath(t))}async copyFilePromise(e,t,i=0){return await new Promise((n,s)=>{this.realFs.copyFile(H.fromPortablePath(e),H.fromPortablePath(t),i,this.makeCallback(n,s))})}copyFileSync(e,t,i=0){return this.realFs.copyFileSync(H.fromPortablePath(e),H.fromPortablePath(t),i)}async appendFilePromise(e,t,i){return await new Promise((n,s)=>{let o=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.appendFile(o,t,i,this.makeCallback(n,s)):this.realFs.appendFile(o,t,this.makeCallback(n,s))})}appendFileSync(e,t,i){let n=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.appendFileSync(n,t,i):this.realFs.appendFileSync(n,t)}async writeFilePromise(e,t,i){return await new Promise((n,s)=>{let o=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.writeFile(o,t,i,this.makeCallback(n,s)):this.realFs.writeFile(o,t,this.makeCallback(n,s))})}writeFileSync(e,t,i){let n=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.writeFileSync(n,t,i):this.realFs.writeFileSync(n,t)}async unlinkPromise(e){return await new Promise((t,i)=>{this.realFs.unlink(H.fromPortablePath(e),this.makeCallback(t,i))})}unlinkSync(e){return this.realFs.unlinkSync(H.fromPortablePath(e))}async utimesPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.utimes(H.fromPortablePath(e),t,i,this.makeCallback(n,s))})}utimesSync(e,t,i){this.realFs.utimesSync(H.fromPortablePath(e),t,i)}async lutimesPromiseImpl(e,t,i){let n=this.realFs.lutimes;if(typeof n=="undefined")throw qh("unavailable Node binding",`lutimes '${e}'`);return await new Promise((s,o)=>{n.call(this.realFs,H.fromPortablePath(e),t,i,this.makeCallback(s,o))})}lutimesSyncImpl(e,t,i){let n=this.realFs.lutimesSync;if(typeof n=="undefined")throw qh("unavailable Node binding",`lutimes '${e}'`);n.call(this.realFs,H.fromPortablePath(e),t,i)}async mkdirPromise(e,t){return await new Promise((i,n)=>{this.realFs.mkdir(H.fromPortablePath(e),t,this.makeCallback(i,n))})}mkdirSync(e,t){return this.realFs.mkdirSync(H.fromPortablePath(e),t)}async rmdirPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.rmdir(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.rmdir(H.fromPortablePath(e),this.makeCallback(i,n))})}rmdirSync(e,t){return this.realFs.rmdirSync(H.fromPortablePath(e),t)}async linkPromise(e,t){return await new Promise((i,n)=>{this.realFs.link(H.fromPortablePath(e),H.fromPortablePath(t),this.makeCallback(i,n))})}linkSync(e,t){return this.realFs.linkSync(H.fromPortablePath(e),H.fromPortablePath(t))}async symlinkPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.symlink(H.fromPortablePath(e.replace(/\/+$/,"")),H.fromPortablePath(t),i,this.makeCallback(n,s))})}symlinkSync(e,t,i){return this.realFs.symlinkSync(H.fromPortablePath(e.replace(/\/+$/,"")),H.fromPortablePath(t),i)}async readFilePromise(e,t){return await new Promise((i,n)=>{let s=typeof e=="string"?H.fromPortablePath(e):e;this.realFs.readFile(s,t,this.makeCallback(i,n))})}readFileSync(e,t){let i=typeof e=="string"?H.fromPortablePath(e):e;return this.realFs.readFileSync(i,t)}async readdirPromise(e,t){return await new Promise((i,n)=>{(t==null?void 0:t.withFileTypes)?this.realFs.readdir(H.fromPortablePath(e),{withFileTypes:!0},this.makeCallback(i,n)):this.realFs.readdir(H.fromPortablePath(e),this.makeCallback(s=>i(s),n))})}readdirSync(e,t){return(t==null?void 0:t.withFileTypes)?this.realFs.readdirSync(H.fromPortablePath(e),{withFileTypes:!0}):this.realFs.readdirSync(H.fromPortablePath(e))}async readlinkPromise(e){return await new Promise((t,i)=>{this.realFs.readlink(H.fromPortablePath(e),this.makeCallback(t,i))}).then(t=>H.toPortablePath(t))}readlinkSync(e){return H.toPortablePath(this.realFs.readlinkSync(H.fromPortablePath(e)))}async truncatePromise(e,t){return await new Promise((i,n)=>{this.realFs.truncate(H.fromPortablePath(e),t,this.makeCallback(i,n))})}truncateSync(e,t){return this.realFs.truncateSync(H.fromPortablePath(e),t)}async ftruncatePromise(e,t){return await new Promise((i,n)=>{this.realFs.ftruncate(e,t,this.makeCallback(i,n))})}ftruncateSync(e,t){return this.realFs.ftruncateSync(e,t)}watch(e,t,i){return this.realFs.watch(H.fromPortablePath(e),t,i)}watchFile(e,t,i){return this.realFs.watchFile(H.fromPortablePath(e),t,i)}unwatchFile(e,t){return this.realFs.unwatchFile(H.fromPortablePath(e),t)}makeCallback(e,t){return(i,n)=>{i?t(i):e(n)}}};var eM=ge(require("events"));var Ac;(function(t){t.Change="change",t.Stop="stop"})(Ac||(Ac={}));var lc;(function(i){i.Ready="ready",i.Running="running",i.Stopped="stopped"})(lc||(lc={}));function tM(r,e){if(r!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${r}'`)}var Wh=class extends eM.EventEmitter{constructor(e,t,{bigint:i=!1}={}){super();this.status=lc.Ready;this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=e,this.path=t,this.bigint=i,this.lastStats=this.stat()}static create(e,t,i){let n=new Wh(e,t,i);return n.start(),n}start(){tM(this.status,lc.Ready),this.status=lc.Running,this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit(Ac.Change,this.lastStats,this.lastStats)},3)}stop(){tM(this.status,lc.Running),this.status=lc.Stopped,this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit(Ac.Stop)}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch(e){let t=this.bigint?new Hh:new GA;return FE(t)}}makeInterval(e){let t=setInterval(()=>{let i=this.stat(),n=this.lastStats;sQ(i,n)||(this.lastStats=i,this.emit(Ac.Change,i,n))},e.interval);return e.persistent?t:t.unref()}registerChangeListener(e,t){this.addListener(Ac.Change,e),this.changeListeners.set(e,this.makeInterval(t))}unregisterChangeListener(e){this.removeListener(Ac.Change,e);let t=this.changeListeners.get(e);typeof t!="undefined"&&clearInterval(t),this.changeListeners.delete(e)}unregisterAllChangeListeners(){for(let e of this.changeListeners.keys())this.unregisterChangeListener(e)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let e of this.changeListeners.values())e.ref();return this}unref(){for(let e of this.changeListeners.values())e.unref();return this}};var HE=new WeakMap;function jE(r,e,t,i){let n,s,o,a;switch(typeof t){case"function":n=!1,s=!0,o=5007,a=t;break;default:({bigint:n=!1,persistent:s=!0,interval:o=5007}=t),a=i;break}let l=HE.get(r);typeof l=="undefined"&&HE.set(r,l=new Map);let c=l.get(e);return typeof c=="undefined"&&(c=Wh.create(r,e,{bigint:n}),l.set(e,c)),c.registerChangeListener(a,{persistent:s,interval:o}),c}function zh(r,e,t){let i=HE.get(r);if(typeof i=="undefined")return;let n=i.get(e);typeof n!="undefined"&&(typeof t=="undefined"?n.unregisterAllChangeListeners():n.unregisterChangeListener(t),n.hasChangeListeners()||(n.stop(),i.delete(e)))}function _h(r){let e=HE.get(r);if(typeof e!="undefined")for(let t of e.keys())zh(r,t)}var cc="mixed";function vge(r){if(typeof r=="string"&&String(+r)===r)return+r;if(Number.isFinite(r))return r<0?Date.now()/1e3:r;if(rM.types.isDate(r))return r.getTime()/1e3;throw new Error("Invalid time")}function iM(){return Buffer.from([80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])}var li=class extends ac{constructor(e,t){super();this.lzSource=null;this.listings=new Map;this.entries=new Map;this.fileSources=new Map;this.fds=new Map;this.nextFd=0;this.ready=!1;this.readOnly=!1;this.libzip=t.libzip;let i=t;if(this.level=typeof i.level!="undefined"?i.level:cc,e!=null||(e=iM()),typeof e=="string"){let{baseFs:o=new ar}=i;this.baseFs=o,this.path=e}else this.path=null,this.baseFs=null;if(t.stats)this.stats=t.stats;else if(typeof e=="string")try{this.stats=this.baseFs.statSync(e)}catch(o){if(o.code==="ENOENT"&&i.create)this.stats=jh();else throw o}else this.stats=jh();let n=this.libzip.malloc(4);try{let o=0;if(typeof e=="string"&&i.create&&(o|=this.libzip.ZIP_CREATE|this.libzip.ZIP_TRUNCATE),t.readOnly&&(o|=this.libzip.ZIP_RDONLY,this.readOnly=!0),typeof e=="string")this.zip=this.libzip.open(H.fromPortablePath(e),o,n);else{let a=this.allocateUnattachedSource(e);try{this.zip=this.libzip.openFromSource(a,o,n),this.lzSource=a}catch(l){throw this.libzip.source.free(a),l}}if(this.zip===0){let a=this.libzip.struct.errorS();throw this.libzip.error.initWithCode(a,this.libzip.getValue(n,"i32")),this.makeLibzipError(a)}}finally{this.libzip.free(n)}this.listings.set(Me.root,new Set);let s=this.libzip.getNumEntries(this.zip,0);for(let o=0;o<s;++o){let a=this.libzip.getName(this.zip,o,0);if(x.isAbsolute(a))continue;let l=x.resolve(Me.root,a);this.registerEntry(l,o),a.endsWith("/")&&this.registerListing(l)}if(this.symlinkCount=this.libzip.ext.countSymlinks(this.zip),this.symlinkCount===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.ready=!0}makeLibzipError(e){let t=this.libzip.struct.errorCodeZip(e),i=this.libzip.error.strerror(e),n=new cQ(i,this.libzip.errors[t]);if(t===this.libzip.errors.ZIP_ER_CHANGED)throw new Error(`Assertion failed: Unexpected libzip error: ${n.message}`);return n}getExtractHint(e){for(let t of this.entries.keys()){let i=this.pathUtils.extname(t);if(e.relevantExtensions.has(i))return!0}return!1}getAllFiles(){return Array.from(this.entries.keys())}getRealPath(){if(!this.path)throw new Error("ZipFS don't have real paths when loaded from a buffer");return this.path}getBufferAndClose(){if(this.prepareClose(),!this.lzSource)throw new Error("ZipFS was not created from a Buffer");try{if(this.libzip.source.keep(this.lzSource),this.libzip.close(this.zip)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.libzip.source.open(this.lzSource)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(this.libzip.source.seek(this.lzSource,0,0,this.libzip.SEEK_END)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));let e=this.libzip.source.tell(this.lzSource);if(e===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(this.libzip.source.seek(this.lzSource,0,0,this.libzip.SEEK_SET)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));let t=this.libzip.malloc(e);if(!t)throw new Error("Couldn't allocate enough memory");try{let i=this.libzip.source.read(this.lzSource,t,e);if(i===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(i<e)throw new Error("Incomplete read");if(i>e)throw new Error("Overread");let n=this.libzip.HEAPU8.subarray(t,t+e);return Buffer.from(n)}finally{this.libzip.free(t)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}prepareClose(){if(!this.ready)throw ME("archive closed, close");_h(this)}saveAndClose(){if(!this.path||!this.baseFs)throw new Error("ZipFS cannot be saved and must be discarded when loaded from a buffer");if(this.prepareClose(),this.readOnly){this.discardAndClose();return}let e=this.baseFs.existsSync(this.path)||this.stats.mode===Kh?void 0:this.stats.mode;if(this.entries.size===0)this.discardAndClose(),this.baseFs.writeFileSync(this.path,iM(),{mode:e});else{if(this.libzip.close(this.zip)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));typeof e!="undefined"&&this.baseFs.chmodSync(this.path,e)}this.ready=!1}discardAndClose(){this.prepareClose(),this.libzip.discard(this.zip),this.ready=!1}resolve(e){return x.resolve(Me.root,e)}async openPromise(e,t,i){return this.openSync(e,t,i)}openSync(e,t,i){let n=this.nextFd++;return this.fds.set(n,{cursor:0,p:e}),n}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(e,t){return this.opendirSync(e,t)}opendirSync(e,t={}){let i=this.resolveFilename(`opendir '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw so(`opendir '${e}'`);let n=this.listings.get(i);if(!n)throw No(`opendir '${e}'`);let s=[...n],o=this.openSync(i,"r");return KE(this,i,s,{onClose:()=>{this.closeSync(o)}})}async readPromise(e,t,i,n,s){return this.readSync(e,t,i,n,s)}readSync(e,t,i=0,n=t.byteLength,s=-1){let o=this.fds.get(e);if(typeof o=="undefined")throw Ai("read");let a=s===-1||s===null?o.cursor:s,l=this.readFileSync(o.p);l.copy(t,i,a,a+n);let c=Math.max(0,Math.min(l.length-a,n));return(s===-1||s===null)&&(o.cursor+=c),c}async writePromise(e,t,i,n,s){return typeof t=="string"?this.writeSync(e,t,s):this.writeSync(e,t,i,n,s)}writeSync(e,t,i,n,s){throw typeof this.fds.get(e)=="undefined"?Ai("read"):new Error("Unimplemented")}async closePromise(e){return this.closeSync(e)}closeSync(e){if(typeof this.fds.get(e)=="undefined")throw Ai("read");this.fds.delete(e)}createReadStream(e,{encoding:t}={}){if(e===null)throw new Error("Unimplemented");let i=this.openSync(e,"r"),n=Object.assign(new uQ.PassThrough({emitClose:!0,autoDestroy:!0,destroy:(o,a)=>{clearImmediate(s),this.closeSync(i),a(o)}}),{close(){n.destroy()},bytesRead:0,path:e}),s=setImmediate(async()=>{try{let o=await this.readFilePromise(e,t);n.bytesRead=o.length,n.end(o)}catch(o){n.destroy(o)}});return n}createWriteStream(e,{encoding:t}={}){if(this.readOnly)throw In(`open '${e}'`);if(e===null)throw new Error("Unimplemented");let i=[],n=this.openSync(e,"w"),s=Object.assign(new uQ.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(o,a)=>{try{o?a(o):(this.writeFileSync(e,Buffer.concat(i),t),a(null))}catch(l){a(l)}finally{this.closeSync(n)}}}),{bytesWritten:0,path:e,close(){s.destroy()}});return s.on("data",o=>{let a=Buffer.from(o);s.bytesWritten+=a.length,i.push(a)}),s}async realpathPromise(e){return this.realpathSync(e)}realpathSync(e){let t=this.resolveFilename(`lstat '${e}'`,e);if(!this.entries.has(t)&&!this.listings.has(t))throw so(`lstat '${e}'`);return t}async existsPromise(e){return this.existsSync(e)}existsSync(e){if(!this.ready)throw ME(`archive closed, existsSync '${e}'`);if(this.symlinkCount===0){let i=x.resolve(Me.root,e);return this.entries.has(i)||this.listings.has(i)}let t;try{t=this.resolveFilename(`stat '${e}'`,e,void 0,!1)}catch(i){return!1}return t===void 0?!1:this.entries.has(t)||this.listings.has(t)}async accessPromise(e,t){return this.accessSync(e,t)}accessSync(e,t=_u.constants.F_OK){let i=this.resolveFilename(`access '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw so(`access '${e}'`);if(this.readOnly&&t&_u.constants.W_OK)throw In(`access '${e}'`)}async statPromise(e,t={bigint:!1}){return t.bigint?this.statSync(e,{bigint:!0}):this.statSync(e)}statSync(e,t={bigint:!1,throwIfNoEntry:!0}){let i=this.resolveFilename(`stat '${e}'`,e,void 0,t.throwIfNoEntry);if(i!==void 0){if(!this.entries.has(i)&&!this.listings.has(i)){if(t.throwIfNoEntry===!1)return;throw so(`stat '${e}'`)}if(e[e.length-1]==="/"&&!this.listings.has(i))throw No(`stat '${e}'`);return this.statImpl(`stat '${e}'`,i,t)}}async fstatPromise(e,t){return this.fstatSync(e,t)}fstatSync(e,t){let i=this.fds.get(e);if(typeof i=="undefined")throw Ai("fstatSync");let{p:n}=i,s=this.resolveFilename(`stat '${n}'`,n);if(!this.entries.has(s)&&!this.listings.has(s))throw so(`stat '${n}'`);if(n[n.length-1]==="/"&&!this.listings.has(s))throw No(`stat '${n}'`);return this.statImpl(`fstat '${n}'`,s,t)}async lstatPromise(e,t={bigint:!1}){return t.bigint?this.lstatSync(e,{bigint:!0}):this.lstatSync(e)}lstatSync(e,t={bigint:!1,throwIfNoEntry:!0}){let i=this.resolveFilename(`lstat '${e}'`,e,!1,t.throwIfNoEntry);if(i!==void 0){if(!this.entries.has(i)&&!this.listings.has(i)){if(t.throwIfNoEntry===!1)return;throw so(`lstat '${e}'`)}if(e[e.length-1]==="/"&&!this.listings.has(i))throw No(`lstat '${e}'`);return this.statImpl(`lstat '${e}'`,i,t)}}statImpl(e,t,i={}){let n=this.entries.get(t);if(typeof n!="undefined"){let s=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,n,0,0,s)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let a=this.stats.uid,l=this.stats.gid,c=this.libzip.struct.statSize(s)>>>0,u=512,g=Math.ceil(c/u),f=(this.libzip.struct.statMtime(s)>>>0)*1e3,h=f,p=f,m=f,y=new Date(h),b=new Date(p),v=new Date(m),k=new Date(f),T=this.listings.has(t)?Ra:this.isSymbolicLink(n)?Na:Fa,Y=T===Ra?493:420,q=T|this.getUnixMode(n,Y)&511,$=this.libzip.struct.statCrc(s),z=Object.assign(new GA,{uid:a,gid:l,size:c,blksize:u,blocks:g,atime:y,birthtime:b,ctime:v,mtime:k,atimeMs:h,birthtimeMs:p,ctimeMs:m,mtimeMs:f,mode:q,crc:$});return i.bigint===!0?NE(z):z}if(this.listings.has(t)){let s=this.stats.uid,o=this.stats.gid,a=0,l=512,c=0,u=this.stats.mtimeMs,g=this.stats.mtimeMs,f=this.stats.mtimeMs,h=this.stats.mtimeMs,p=new Date(u),m=new Date(g),y=new Date(f),b=new Date(h),v=Ra|493,k=0,T=Object.assign(new GA,{uid:s,gid:o,size:a,blksize:l,blocks:c,atime:p,birthtime:m,ctime:y,mtime:b,atimeMs:u,birthtimeMs:g,ctimeMs:f,mtimeMs:h,mode:v,crc:k});return i.bigint===!0?NE(T):T}throw new Error("Unreachable")}getUnixMode(e,t){if(this.libzip.file.getExternalAttributes(this.zip,e,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?t:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(e){let t=this.listings.get(e);if(t)return t;this.registerListing(x.dirname(e)).add(x.basename(e));let n=new Set;return this.listings.set(e,n),n}registerEntry(e,t){this.registerListing(x.dirname(e)).add(x.basename(e)),this.entries.set(e,t)}unregisterListing(e){this.listings.delete(e);let t=this.listings.get(x.dirname(e));t==null||t.delete(x.basename(e))}unregisterEntry(e){this.unregisterListing(e);let t=this.entries.get(e);this.entries.delete(e),typeof t!="undefined"&&(this.fileSources.delete(t),this.isSymbolicLink(t)&&this.symlinkCount--)}deleteEntry(e,t){if(this.unregisterEntry(e),this.libzip.delete(this.zip,t)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(e,t,i=!0,n=!0){if(!this.ready)throw ME(`archive closed, ${e}`);let s=x.resolve(Me.root,t);if(s==="/")return Me.root;let o=this.entries.get(s);if(i&&o!==void 0)if(this.symlinkCount!==0&&this.isSymbolicLink(o)){let a=this.getFileSource(o).toString();return this.resolveFilename(e,x.resolve(x.dirname(s),a),!0,n)}else return s;for(;;){let a=this.resolveFilename(e,x.dirname(s),!0,n);if(a===void 0)return a;let l=this.listings.has(a),c=this.entries.has(a);if(!l&&!c){if(n===!1)return;throw so(e)}if(!l)throw No(e);if(s=x.resolve(a,x.basename(s)),!i||this.symlinkCount===0)break;let u=this.libzip.name.locate(this.zip,s.slice(1));if(u===-1)break;if(this.isSymbolicLink(u)){let g=this.getFileSource(u).toString();s=x.resolve(x.dirname(s),g)}else break}return s}allocateBuffer(e){Buffer.isBuffer(e)||(e=Buffer.from(e));let t=this.libzip.malloc(e.byteLength);if(!t)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,t,e.byteLength).set(e),{buffer:t,byteLength:e.byteLength}}allocateUnattachedSource(e){let t=this.libzip.struct.errorS(),{buffer:i,byteLength:n}=this.allocateBuffer(e),s=this.libzip.source.fromUnattachedBuffer(i,n,0,!0,t);if(s===0)throw this.libzip.free(t),this.makeLibzipError(t);return s}allocateSource(e){let{buffer:t,byteLength:i}=this.allocateBuffer(e),n=this.libzip.source.fromBuffer(this.zip,t,i,0,!0);if(n===0)throw this.libzip.free(t),this.makeLibzipError(this.libzip.getError(this.zip));return n}setFileSource(e,t){let i=Buffer.isBuffer(t)?t:Buffer.from(t),n=x.relative(Me.root,e),s=this.allocateSource(t);try{let o=this.libzip.file.add(this.zip,n,s,this.libzip.ZIP_FL_OVERWRITE);if(o===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.level!=="mixed"){let a=this.level===0?this.libzip.ZIP_CM_STORE:this.libzip.ZIP_CM_DEFLATE;if(this.libzip.file.setCompression(this.zip,o,0,a,this.level)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}return this.fileSources.set(o,i),o}catch(o){throw this.libzip.source.free(s),o}}isSymbolicLink(e){if(this.symlinkCount===0)return!1;if(this.libzip.file.getExternalAttributes(this.zip,e,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?!1:(this.libzip.getValue(this.libzip.uint32S,"i32")>>>16&Vn)===Na}getFileSource(e,t={asyncDecompress:!1}){let i=this.fileSources.get(e);if(typeof i!="undefined")return i;let n=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,e,0,0,n)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let o=this.libzip.struct.statCompSize(n),a=this.libzip.struct.statCompMethod(n),l=this.libzip.malloc(o);try{let c=this.libzip.fopenIndex(this.zip,e,0,this.libzip.ZIP_FL_COMPRESSED);if(c===0)throw this.makeLibzipError(this.libzip.getError(this.zip));try{let u=this.libzip.fread(c,l,o,0);if(u===-1)throw this.makeLibzipError(this.libzip.file.getError(c));if(u<o)throw new Error("Incomplete read");if(u>o)throw new Error("Overread");let g=this.libzip.HEAPU8.subarray(l,l+o),f=Buffer.from(g);if(a===0)return this.fileSources.set(e,f),f;if(t.asyncDecompress)return new Promise((h,p)=>{gQ.default.inflateRaw(f,(m,y)=>{m?p(m):(this.fileSources.set(e,y),h(y))})});{let h=gQ.default.inflateRawSync(f);return this.fileSources.set(e,h),h}}finally{this.libzip.fclose(c)}}finally{this.libzip.free(l)}}async fchmodPromise(e,t){return this.chmodPromise(this.fdToPath(e,"fchmod"),t)}fchmodSync(e,t){return this.chmodSync(this.fdToPath(e,"fchmodSync"),t)}async chmodPromise(e,t){return this.chmodSync(e,t)}chmodSync(e,t){if(this.readOnly)throw In(`chmod '${e}'`);t&=493;let i=this.resolveFilename(`chmod '${e}'`,e,!1),n=this.entries.get(i);if(typeof n=="undefined")throw new Error(`Assertion failed: The entry should have been registered (${i})`);let o=this.getUnixMode(n,Fa|0)&~511|t;if(this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,o<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async chownPromise(e,t,i){return this.chownSync(e,t,i)}chownSync(e,t,i){throw new Error("Unimplemented")}async renamePromise(e,t){return this.renameSync(e,t)}renameSync(e,t){throw new Error("Unimplemented")}async copyFilePromise(e,t,i){let{indexSource:n,indexDest:s,resolvedDestP:o}=this.prepareCopyFile(e,t,i),a=await this.getFileSource(n,{asyncDecompress:!0}),l=this.setFileSource(o,a);l!==s&&this.registerEntry(o,l)}copyFileSync(e,t,i=0){let{indexSource:n,indexDest:s,resolvedDestP:o}=this.prepareCopyFile(e,t,i),a=this.getFileSource(n),l=this.setFileSource(o,a);l!==s&&this.registerEntry(o,l)}prepareCopyFile(e,t,i=0){if(this.readOnly)throw In(`copyfile '${e} -> '${t}'`);if((i&_u.constants.COPYFILE_FICLONE_FORCE)!=0)throw qh("unsupported clone operation",`copyfile '${e}' -> ${t}'`);let n=this.resolveFilename(`copyfile '${e} -> ${t}'`,e),s=this.entries.get(n);if(typeof s=="undefined")throw YA(`copyfile '${e}' -> '${t}'`);let o=this.resolveFilename(`copyfile '${e}' -> ${t}'`,t),a=this.entries.get(o);if((i&(_u.constants.COPYFILE_EXCL|_u.constants.COPYFILE_FICLONE_FORCE))!=0&&typeof a!="undefined")throw UE(`copyfile '${e}' -> '${t}'`);return{indexSource:s,resolvedDestP:o,indexDest:a}}async appendFilePromise(e,t,i){if(this.readOnly)throw In(`open '${e}'`);return typeof i=="undefined"?i={flag:"a"}:typeof i=="string"?i={flag:"a",encoding:i}:typeof i.flag=="undefined"&&(i=N({flag:"a"},i)),this.writeFilePromise(e,t,i)}appendFileSync(e,t,i={}){if(this.readOnly)throw In(`open '${e}'`);return typeof i=="undefined"?i={flag:"a"}:typeof i=="string"?i={flag:"a",encoding:i}:typeof i.flag=="undefined"&&(i=N({flag:"a"},i)),this.writeFileSync(e,t,i)}fdToPath(e,t){var n;let i=(n=this.fds.get(e))==null?void 0:n.p;if(typeof i=="undefined")throw Ai(t);return i}async writeFilePromise(e,t,i){let{encoding:n,mode:s,index:o,resolvedP:a}=this.prepareWriteFile(e,i);o!==void 0&&typeof i=="object"&&i.flag&&i.flag.includes("a")&&(t=Buffer.concat([await this.getFileSource(o,{asyncDecompress:!0}),Buffer.from(t)])),n!==null&&(t=t.toString(n));let l=this.setFileSource(a,t);l!==o&&this.registerEntry(a,l),s!==null&&await this.chmodPromise(a,s)}writeFileSync(e,t,i){let{encoding:n,mode:s,index:o,resolvedP:a}=this.prepareWriteFile(e,i);o!==void 0&&typeof i=="object"&&i.flag&&i.flag.includes("a")&&(t=Buffer.concat([this.getFileSource(o),Buffer.from(t)])),n!==null&&(t=t.toString(n));let l=this.setFileSource(a,t);l!==o&&this.registerEntry(a,l),s!==null&&this.chmodSync(a,s)}prepareWriteFile(e,t){if(typeof e=="number"&&(e=this.fdToPath(e,"read")),this.readOnly)throw In(`open '${e}'`);let i=this.resolveFilename(`open '${e}'`,e);if(this.listings.has(i))throw Jh(`open '${e}'`);let n=null,s=null;typeof t=="string"?n=t:typeof t=="object"&&({encoding:n=null,mode:s=null}=t);let o=this.entries.get(i);return{encoding:n,mode:s,resolvedP:i,index:o}}async unlinkPromise(e){return this.unlinkSync(e)}unlinkSync(e){if(this.readOnly)throw In(`unlink '${e}'`);let t=this.resolveFilename(`unlink '${e}'`,e);if(this.listings.has(t))throw Jh(`unlink '${e}'`);let i=this.entries.get(t);if(typeof i=="undefined")throw YA(`unlink '${e}'`);this.deleteEntry(t,i)}async utimesPromise(e,t,i){return this.utimesSync(e,t,i)}utimesSync(e,t,i){if(this.readOnly)throw In(`utimes '${e}'`);let n=this.resolveFilename(`utimes '${e}'`,e);this.utimesImpl(n,i)}async lutimesPromise(e,t,i){return this.lutimesSync(e,t,i)}lutimesSync(e,t,i){if(this.readOnly)throw In(`lutimes '${e}'`);let n=this.resolveFilename(`utimes '${e}'`,e,!1);this.utimesImpl(n,i)}utimesImpl(e,t){this.listings.has(e)&&(this.entries.has(e)||this.hydrateDirectory(e));let i=this.entries.get(e);if(i===void 0)throw new Error("Unreachable");if(this.libzip.file.setMtime(this.zip,i,0,vge(t),0)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(e,t){return this.mkdirSync(e,t)}mkdirSync(e,{mode:t=493,recursive:i=!1}={}){if(i)return this.mkdirpSync(e,{chmod:t});if(this.readOnly)throw In(`mkdir '${e}'`);let n=this.resolveFilename(`mkdir '${e}'`,e);if(this.entries.has(n)||this.listings.has(n))throw UE(`mkdir '${e}'`);this.hydrateDirectory(n),this.chmodSync(n,t)}async rmdirPromise(e,t){return this.rmdirSync(e,t)}rmdirSync(e,{recursive:t=!1}={}){if(this.readOnly)throw In(`rmdir '${e}'`);if(t){this.removeSync(e);return}let i=this.resolveFilename(`rmdir '${e}'`,e),n=this.listings.get(i);if(!n)throw No(`rmdir '${e}'`);if(n.size>0)throw zO(`rmdir '${e}'`);let s=this.entries.get(i);if(typeof s=="undefined")throw YA(`rmdir '${e}'`);this.deleteEntry(e,s)}hydrateDirectory(e){let t=this.libzip.dir.add(this.zip,x.relative(Me.root,e));if(t===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(e),this.registerEntry(e,t),t}async linkPromise(e,t){return this.linkSync(e,t)}linkSync(e,t){throw _O(`link '${e}' -> '${t}'`)}async symlinkPromise(e,t){return this.symlinkSync(e,t)}symlinkSync(e,t){if(this.readOnly)throw In(`symlink '${e}' -> '${t}'`);let i=this.resolveFilename(`symlink '${e}' -> '${t}'`,t);if(this.listings.has(i))throw Jh(`symlink '${e}' -> '${t}'`);if(this.entries.has(i))throw UE(`symlink '${e}' -> '${t}'`);let n=this.setFileSource(i,e);if(this.registerEntry(i,n),this.libzip.file.setExternalAttributes(this.zip,n,0,0,this.libzip.ZIP_OPSYS_UNIX,(Na|511)<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(e,t){typeof t=="object"&&(t=t?t.encoding:void 0);let i=await this.readFileBuffer(e,{asyncDecompress:!0});return t?i.toString(t):i}readFileSync(e,t){typeof t=="object"&&(t=t?t.encoding:void 0);let i=this.readFileBuffer(e);return t?i.toString(t):i}readFileBuffer(e,t={asyncDecompress:!1}){typeof e=="number"&&(e=this.fdToPath(e,"read"));let i=this.resolveFilename(`open '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw so(`open '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(i))throw No(`open '${e}'`);if(this.listings.has(i))throw Jh("read");let n=this.entries.get(i);if(n===void 0)throw new Error("Unreachable");return this.getFileSource(n,t)}async readdirPromise(e,t){return this.readdirSync(e,t)}readdirSync(e,t){let i=this.resolveFilename(`scandir '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw so(`scandir '${e}'`);let n=this.listings.get(i);if(!n)throw No(`scandir '${e}'`);let s=[...n];return(t==null?void 0:t.withFileTypes)?s.map(o=>Object.assign(this.statImpl("lstat",x.join(e,o)),{name:o})):s}async readlinkPromise(e){let t=this.prepareReadlink(e);return(await this.getFileSource(t,{asyncDecompress:!0})).toString()}readlinkSync(e){let t=this.prepareReadlink(e);return this.getFileSource(t).toString()}prepareReadlink(e){let t=this.resolveFilename(`readlink '${e}'`,e,!1);if(!this.entries.has(t)&&!this.listings.has(t))throw so(`readlink '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(t))throw No(`open '${e}'`);if(this.listings.has(t))throw YA(`readlink '${e}'`);let i=this.entries.get(t);if(i===void 0)throw new Error("Unreachable");if(!this.isSymbolicLink(i))throw YA(`readlink '${e}'`);return i}async truncatePromise(e,t=0){let i=this.resolveFilename(`open '${e}'`,e),n=this.entries.get(i);if(typeof n=="undefined")throw YA(`open '${e}'`);let s=await this.getFileSource(n,{asyncDecompress:!0}),o=Buffer.alloc(t,0);return s.copy(o),await this.writeFilePromise(e,o)}truncateSync(e,t=0){let i=this.resolveFilename(`open '${e}'`,e),n=this.entries.get(i);if(typeof n=="undefined")throw YA(`open '${e}'`);let s=this.getFileSource(n),o=Buffer.alloc(t,0);return s.copy(o),this.writeFileSync(e,o)}async ftruncatePromise(e,t){return this.truncatePromise(this.fdToPath(e,"ftruncate"),t)}ftruncateSync(e,t){return this.truncateSync(this.fdToPath(e,"ftruncateSync"),t)}watch(e,t,i){let n;switch(typeof t){case"function":case"string":case"undefined":n=!0;break;default:({persistent:n=!0}=t);break}if(!n)return{on:()=>{},close:()=>{}};let s=setInterval(()=>{},24*60*60*1e3);return{on:()=>{},close:()=>{clearInterval(s)}}}watchFile(e,t,i){let n=x.resolve(Me.root,e);return jE(this,n,t,i)}unwatchFile(e,t){let i=x.resolve(Me.root,e);return zh(this,i,t)}};var Qi=class extends qA{getExtractHint(e){return this.baseFs.getExtractHint(e)}resolve(e){return this.mapFromBase(this.baseFs.resolve(this.mapToBase(e)))}getRealPath(){return this.mapFromBase(this.baseFs.getRealPath())}async openPromise(e,t,i){return this.baseFs.openPromise(this.mapToBase(e),t,i)}openSync(e,t,i){return this.baseFs.openSync(this.mapToBase(e),t,i)}async opendirPromise(e,t){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),t),{path:e})}opendirSync(e,t){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),t),{path:e})}async readPromise(e,t,i,n,s){return await this.baseFs.readPromise(e,t,i,n,s)}readSync(e,t,i,n,s){return this.baseFs.readSync(e,t,i,n,s)}async writePromise(e,t,i,n,s){return typeof t=="string"?await this.baseFs.writePromise(e,t,i):await this.baseFs.writePromise(e,t,i,n,s)}writeSync(e,t,i,n,s){return typeof t=="string"?this.baseFs.writeSync(e,t,i):this.baseFs.writeSync(e,t,i,n,s)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,t){return this.baseFs.createReadStream(e!==null?this.mapToBase(e):e,t)}createWriteStream(e,t){return this.baseFs.createWriteStream(e!==null?this.mapToBase(e):e,t)}async realpathPromise(e){return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(e)))}realpathSync(e){return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(e)))}async existsPromise(e){return this.baseFs.existsPromise(this.mapToBase(e))}existsSync(e){return this.baseFs.existsSync(this.mapToBase(e))}accessSync(e,t){return this.baseFs.accessSync(this.mapToBase(e),t)}async accessPromise(e,t){return this.baseFs.accessPromise(this.mapToBase(e),t)}async statPromise(e,t){return this.baseFs.statPromise(this.mapToBase(e),t)}statSync(e,t){return this.baseFs.statSync(this.mapToBase(e),t)}async fstatPromise(e,t){return this.baseFs.fstatPromise(e,t)}fstatSync(e,t){return this.baseFs.fstatSync(e,t)}lstatPromise(e,t){return this.baseFs.lstatPromise(this.mapToBase(e),t)}lstatSync(e,t){return this.baseFs.lstatSync(this.mapToBase(e),t)}async fchmodPromise(e,t){return this.baseFs.fchmodPromise(e,t)}fchmodSync(e,t){return this.baseFs.fchmodSync(e,t)}async chmodPromise(e,t){return this.baseFs.chmodPromise(this.mapToBase(e),t)}chmodSync(e,t){return this.baseFs.chmodSync(this.mapToBase(e),t)}async chownPromise(e,t,i){return this.baseFs.chownPromise(this.mapToBase(e),t,i)}chownSync(e,t,i){return this.baseFs.chownSync(this.mapToBase(e),t,i)}async renamePromise(e,t){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(t))}renameSync(e,t){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(t))}async copyFilePromise(e,t,i=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(t),i)}copyFileSync(e,t,i=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(t),i)}async appendFilePromise(e,t,i){return this.baseFs.appendFilePromise(this.fsMapToBase(e),t,i)}appendFileSync(e,t,i){return this.baseFs.appendFileSync(this.fsMapToBase(e),t,i)}async writeFilePromise(e,t,i){return this.baseFs.writeFilePromise(this.fsMapToBase(e),t,i)}writeFileSync(e,t,i){return this.baseFs.writeFileSync(this.fsMapToBase(e),t,i)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,t,i){return this.baseFs.utimesPromise(this.mapToBase(e),t,i)}utimesSync(e,t,i){return this.baseFs.utimesSync(this.mapToBase(e),t,i)}async mkdirPromise(e,t){return this.baseFs.mkdirPromise(this.mapToBase(e),t)}mkdirSync(e,t){return this.baseFs.mkdirSync(this.mapToBase(e),t)}async rmdirPromise(e,t){return this.baseFs.rmdirPromise(this.mapToBase(e),t)}rmdirSync(e,t){return this.baseFs.rmdirSync(this.mapToBase(e),t)}async linkPromise(e,t){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(t))}linkSync(e,t){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(t))}async symlinkPromise(e,t,i){let n=this.mapToBase(t);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkPromise(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(t),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkPromise(o,n,i)}symlinkSync(e,t,i){let n=this.mapToBase(t);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkSync(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(t),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkSync(o,n,i)}async readFilePromise(e,t){return t==="utf8"?this.baseFs.readFilePromise(this.fsMapToBase(e),t):this.baseFs.readFilePromise(this.fsMapToBase(e),t)}readFileSync(e,t){return t==="utf8"?this.baseFs.readFileSync(this.fsMapToBase(e),t):this.baseFs.readFileSync(this.fsMapToBase(e),t)}async readdirPromise(e,t){return this.baseFs.readdirPromise(this.mapToBase(e),t)}readdirSync(e,t){return this.baseFs.readdirSync(this.mapToBase(e),t)}async readlinkPromise(e){return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(e)))}readlinkSync(e){return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(e)))}async truncatePromise(e,t){return this.baseFs.truncatePromise(this.mapToBase(e),t)}truncateSync(e,t){return this.baseFs.truncateSync(this.mapToBase(e),t)}async ftruncatePromise(e,t){return this.baseFs.ftruncatePromise(e,t)}ftruncateSync(e,t){return this.baseFs.ftruncateSync(e,t)}watch(e,t,i){return this.baseFs.watch(this.mapToBase(e),t,i)}watchFile(e,t,i){return this.baseFs.watchFile(this.mapToBase(e),t,i)}unwatchFile(e,t){return this.baseFs.unwatchFile(this.mapToBase(e),t)}fsMapToBase(e){return typeof e=="number"?e:this.mapToBase(e)}};var La=class extends Qi{constructor(e,{baseFs:t,pathUtils:i}){super(i);this.target=e,this.baseFs=t}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(e){return e}mapToBase(e){return e}};var _t=class extends Qi{constructor(e,{baseFs:t=new ar}={}){super(x);this.target=this.pathUtils.normalize(e),this.baseFs=t}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(e){return this.pathUtils.isAbsolute(e)?x.normalize(e):this.baseFs.resolve(x.join(this.target,e))}mapFromBase(e){return e}mapToBase(e){return this.pathUtils.isAbsolute(e)?e:this.pathUtils.join(this.target,e)}};var nM=Me.root,Ta=class extends Qi{constructor(e,{baseFs:t=new ar}={}){super(x);this.target=this.pathUtils.resolve(Me.root,e),this.baseFs=t}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(Me.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(e){let t=this.pathUtils.normalize(e);if(this.pathUtils.isAbsolute(e))return this.pathUtils.resolve(this.target,this.pathUtils.relative(nM,e));if(t.match(/^\.\.\/?/))throw new Error(`Resolving this path (${e}) would escape the jail`);return this.pathUtils.resolve(this.target,e)}mapFromBase(e){return this.pathUtils.resolve(nM,this.pathUtils.relative(this.target,e))}};var Vh=class extends Qi{constructor(e,t){super(t);this.instance=null;this.factory=e}get baseFs(){return this.instance||(this.instance=this.factory()),this.instance}set baseFs(e){this.instance=e}mapFromBase(e){return e}mapToBase(e){return e}};var et=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"}),fQ=class extends qA{constructor(){super(x)}getExtractHint(){throw et()}getRealPath(){throw et()}resolve(){throw et()}async openPromise(){throw et()}openSync(){throw et()}async opendirPromise(){throw et()}opendirSync(){throw et()}async readPromise(){throw et()}readSync(){throw et()}async writePromise(){throw et()}writeSync(){throw et()}async closePromise(){throw et()}closeSync(){throw et()}createWriteStream(){throw et()}createReadStream(){throw et()}async realpathPromise(){throw et()}realpathSync(){throw et()}async readdirPromise(){throw et()}readdirSync(){throw et()}async existsPromise(e){throw et()}existsSync(e){throw et()}async accessPromise(){throw et()}accessSync(){throw et()}async statPromise(){throw et()}statSync(){throw et()}async fstatPromise(e){throw et()}fstatSync(e){throw et()}async lstatPromise(e){throw et()}lstatSync(e){throw et()}async fchmodPromise(){throw et()}fchmodSync(){throw et()}async chmodPromise(){throw et()}chmodSync(){throw et()}async chownPromise(){throw et()}chownSync(){throw et()}async mkdirPromise(){throw et()}mkdirSync(){throw et()}async rmdirPromise(){throw et()}rmdirSync(){throw et()}async linkPromise(){throw et()}linkSync(){throw et()}async symlinkPromise(){throw et()}symlinkSync(){throw et()}async renamePromise(){throw et()}renameSync(){throw et()}async copyFilePromise(){throw et()}copyFileSync(){throw et()}async appendFilePromise(){throw et()}appendFileSync(){throw et()}async writeFilePromise(){throw et()}writeFileSync(){throw et()}async unlinkPromise(){throw et()}unlinkSync(){throw et()}async utimesPromise(){throw et()}utimesSync(){throw et()}async readFilePromise(){throw et()}readFileSync(){throw et()}async readlinkPromise(){throw et()}readlinkSync(){throw et()}async truncatePromise(){throw et()}truncateSync(){throw et()}async ftruncatePromise(e,t){throw et()}ftruncateSync(e,t){throw et()}watch(){throw et()}watchFile(){throw et()}unwatchFile(){throw et()}},GE=fQ;GE.instance=new fQ;var Xh=class extends Qi{constructor(e){super(H);this.baseFs=e}mapFromBase(e){return H.fromPortablePath(e)}mapToBase(e){return H.toPortablePath(e)}};var kge=/^[0-9]+$/,hQ=/^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,xge=/^([^/]+-)?[a-f0-9]+$/,Wr=class extends Qi{static makeVirtualPath(e,t,i){if(x.basename(e)!=="__virtual__")throw new Error('Assertion failed: Virtual folders must be named "__virtual__"');if(!x.basename(t).match(xge))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");let s=x.relative(x.dirname(e),i).split("/"),o=0;for(;o<s.length&&s[o]==="..";)o+=1;let a=s.slice(o);return x.join(e,t,String(o),...a)}static resolveVirtual(e){let t=e.match(hQ);if(!t||!t[3]&&t[5])return e;let i=x.dirname(t[1]);if(!t[3]||!t[4])return i;if(!kge.test(t[4]))return e;let s=Number(t[4]),o="../".repeat(s),a=t[5]||".";return Wr.resolveVirtual(x.join(i,o,a))}constructor({baseFs:e=new ar}={}){super(x);this.baseFs=e}getExtractHint(e){return this.baseFs.getExtractHint(e)}getRealPath(){return this.baseFs.getRealPath()}realpathSync(e){let t=e.match(hQ);if(!t)return this.baseFs.realpathSync(e);if(!t[5])return e;let i=this.baseFs.realpathSync(this.mapToBase(e));return Wr.makeVirtualPath(t[1],t[3],i)}async realpathPromise(e){let t=e.match(hQ);if(!t)return await this.baseFs.realpathPromise(e);if(!t[5])return e;let i=await this.baseFs.realpathPromise(this.mapToBase(e));return Wr.makeVirtualPath(t[1],t[3],i)}mapToBase(e){if(e==="")return e;if(this.pathUtils.isAbsolute(e))return Wr.resolveVirtual(e);let t=Wr.resolveVirtual(this.baseFs.resolve(Me.dot)),i=Wr.resolveVirtual(this.baseFs.resolve(e));return x.relative(t,i)||Me.dot}mapFromBase(e){return e}};var Zh=ge(require("fs"));var Is=4278190080,Xn=704643072,sM=(r,e)=>{let t=r.indexOf(e);if(t<=0)return null;let i=t;for(;t>=0&&(i=t+e.length,r[i]!==x.sep);){if(r[t-1]===x.sep)return null;t=r.indexOf(e,i)}return r.length>i&&r[i]!==x.sep?null:r.slice(0,i)},ys=class extends ac{constructor({libzip:e,baseFs:t=new ar,filter:i=null,maxOpenFiles:n=Infinity,readOnlyArchives:s=!1,useCache:o=!0,maxAge:a=5e3,fileExtensions:l=null}){super();this.fdMap=new Map;this.nextFd=3;this.isZip=new Set;this.notZip=new Set;this.realPaths=new Map;this.limitOpenFilesTimeout=null;this.libzipFactory=typeof e!="function"?()=>e:e,this.baseFs=t,this.zipInstances=o?new Map:null,this.filter=i,this.maxOpenFiles=n,this.readOnlyArchives=s,this.maxAge=a,this.fileExtensions=l}static async openPromise(e,t){let i=new ys(t);try{return await e(i)}finally{i.saveAndClose()}}get libzip(){return typeof this.libzipInstance=="undefined"&&(this.libzipInstance=this.libzipFactory()),this.libzipInstance}getExtractHint(e){return this.baseFs.getExtractHint(e)}getRealPath(){return this.baseFs.getRealPath()}saveAndClose(){if(_h(this),this.zipInstances)for(let[e,{zipFs:t}]of this.zipInstances.entries())t.saveAndClose(),this.zipInstances.delete(e)}discardAndClose(){if(_h(this),this.zipInstances)for(let[e,{zipFs:t}]of this.zipInstances.entries())t.discardAndClose(),this.zipInstances.delete(e)}resolve(e){return this.baseFs.resolve(e)}remapFd(e,t){let i=this.nextFd++|Xn;return this.fdMap.set(i,[e,t]),i}async openPromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.openPromise(e,t,i),async(n,{subPath:s})=>this.remapFd(n,await n.openPromise(s,t,i)))}openSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.openSync(e,t,i),(n,{subPath:s})=>this.remapFd(n,n.openSync(s,t,i)))}async opendirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.opendirPromise(e,t),async(i,{subPath:n})=>await i.opendirPromise(n,t),{requireSubpath:!1})}opendirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.opendirSync(e,t),(i,{subPath:n})=>i.opendirSync(n,t),{requireSubpath:!1})}async readPromise(e,t,i,n,s){if((e&Is)!==Xn)return await this.baseFs.readPromise(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("read");let[a,l]=o;return await a.readPromise(l,t,i,n,s)}readSync(e,t,i,n,s){if((e&Is)!==Xn)return this.baseFs.readSync(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("readSync");let[a,l]=o;return a.readSync(l,t,i,n,s)}async writePromise(e,t,i,n,s){if((e&Is)!==Xn)return typeof t=="string"?await this.baseFs.writePromise(e,t,i):await this.baseFs.writePromise(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("write");let[a,l]=o;return typeof t=="string"?await a.writePromise(l,t,i):await a.writePromise(l,t,i,n,s)}writeSync(e,t,i,n,s){if((e&Is)!==Xn)return typeof t=="string"?this.baseFs.writeSync(e,t,i):this.baseFs.writeSync(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("writeSync");let[a,l]=o;return typeof t=="string"?a.writeSync(l,t,i):a.writeSync(l,t,i,n,s)}async closePromise(e){if((e&Is)!==Xn)return await this.baseFs.closePromise(e);let t=this.fdMap.get(e);if(typeof t=="undefined")throw Ai("close");this.fdMap.delete(e);let[i,n]=t;return await i.closePromise(n)}closeSync(e){if((e&Is)!==Xn)return this.baseFs.closeSync(e);let t=this.fdMap.get(e);if(typeof t=="undefined")throw Ai("closeSync");this.fdMap.delete(e);let[i,n]=t;return i.closeSync(n)}createReadStream(e,t){return e===null?this.baseFs.createReadStream(e,t):this.makeCallSync(e,()=>this.baseFs.createReadStream(e,t),(i,{archivePath:n,subPath:s})=>{let o=i.createReadStream(s,t);return o.path=H.fromPortablePath(this.pathUtils.join(n,s)),o})}createWriteStream(e,t){return e===null?this.baseFs.createWriteStream(e,t):this.makeCallSync(e,()=>this.baseFs.createWriteStream(e,t),(i,{subPath:n})=>i.createWriteStream(n,t))}async realpathPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.realpathPromise(e),async(t,{archivePath:i,subPath:n})=>{let s=this.realPaths.get(i);return typeof s=="undefined"&&(s=await this.baseFs.realpathPromise(i),this.realPaths.set(i,s)),this.pathUtils.join(s,this.pathUtils.relative(Me.root,await t.realpathPromise(n)))})}realpathSync(e){return this.makeCallSync(e,()=>this.baseFs.realpathSync(e),(t,{archivePath:i,subPath:n})=>{let s=this.realPaths.get(i);return typeof s=="undefined"&&(s=this.baseFs.realpathSync(i),this.realPaths.set(i,s)),this.pathUtils.join(s,this.pathUtils.relative(Me.root,t.realpathSync(n)))})}async existsPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.existsPromise(e),async(t,{subPath:i})=>await t.existsPromise(i))}existsSync(e){return this.makeCallSync(e,()=>this.baseFs.existsSync(e),(t,{subPath:i})=>t.existsSync(i))}async accessPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.accessPromise(e,t),async(i,{subPath:n})=>await i.accessPromise(n,t))}accessSync(e,t){return this.makeCallSync(e,()=>this.baseFs.accessSync(e,t),(i,{subPath:n})=>i.accessSync(n,t))}async statPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.statPromise(e,t),async(i,{subPath:n})=>await i.statPromise(n,t))}statSync(e,t){return this.makeCallSync(e,()=>this.baseFs.statSync(e,t),(i,{subPath:n})=>i.statSync(n,t))}async fstatPromise(e,t){if((e&Is)!==Xn)return this.baseFs.fstatPromise(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fstat");let[n,s]=i;return n.fstatPromise(s,t)}fstatSync(e,t){if((e&Is)!==Xn)return this.baseFs.fstatSync(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fstatSync");let[n,s]=i;return n.fstatSync(s,t)}async lstatPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.lstatPromise(e,t),async(i,{subPath:n})=>await i.lstatPromise(n,t))}lstatSync(e,t){return this.makeCallSync(e,()=>this.baseFs.lstatSync(e,t),(i,{subPath:n})=>i.lstatSync(n,t))}async fchmodPromise(e,t){if((e&Is)!==Xn)return this.baseFs.fchmodPromise(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fchmod");let[n,s]=i;return n.fchmodPromise(s,t)}fchmodSync(e,t){if((e&Is)!==Xn)return this.baseFs.fchmodSync(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fchmodSync");let[n,s]=i;return n.fchmodSync(s,t)}async chmodPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.chmodPromise(e,t),async(i,{subPath:n})=>await i.chmodPromise(n,t))}chmodSync(e,t){return this.makeCallSync(e,()=>this.baseFs.chmodSync(e,t),(i,{subPath:n})=>i.chmodSync(n,t))}async chownPromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.chownPromise(e,t,i),async(n,{subPath:s})=>await n.chownPromise(s,t,i))}chownSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.chownSync(e,t,i),(n,{subPath:s})=>n.chownSync(s,t,i))}async renamePromise(e,t){return await this.makeCallPromise(e,async()=>await this.makeCallPromise(t,async()=>await this.baseFs.renamePromise(e,t),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(i,{subPath:n})=>await this.makeCallPromise(t,async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},async(s,{subPath:o})=>{if(i!==s)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return await i.renamePromise(n,o)}))}renameSync(e,t){return this.makeCallSync(e,()=>this.makeCallSync(t,()=>this.baseFs.renameSync(e,t),()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(i,{subPath:n})=>this.makeCallSync(t,()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},(s,{subPath:o})=>{if(i!==s)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return i.renameSync(n,o)}))}async copyFilePromise(e,t,i=0){let n=async(s,o,a,l)=>{if((i&Zh.constants.COPYFILE_FICLONE_FORCE)!=0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${o}' -> ${l}'`),{code:"EXDEV"});if(i&Zh.constants.COPYFILE_EXCL&&await this.existsPromise(o))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${o}' -> '${l}'`),{code:"EEXIST"});let c;try{c=await s.readFilePromise(o)}catch(u){throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${o}' -> '${l}'`),{code:"EINVAL"})}await a.writeFilePromise(l,c)};return await this.makeCallPromise(e,async()=>await this.makeCallPromise(t,async()=>await this.baseFs.copyFilePromise(e,t,i),async(s,{subPath:o})=>await n(this.baseFs,e,s,o)),async(s,{subPath:o})=>await this.makeCallPromise(t,async()=>await n(s,o,this.baseFs,t),async(a,{subPath:l})=>s!==a?await n(s,o,a,l):await s.copyFilePromise(o,l,i)))}copyFileSync(e,t,i=0){let n=(s,o,a,l)=>{if((i&Zh.constants.COPYFILE_FICLONE_FORCE)!=0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${o}' -> ${l}'`),{code:"EXDEV"});if(i&Zh.constants.COPYFILE_EXCL&&this.existsSync(o))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${o}' -> '${l}'`),{code:"EEXIST"});let c;try{c=s.readFileSync(o)}catch(u){throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${o}' -> '${l}'`),{code:"EINVAL"})}a.writeFileSync(l,c)};return this.makeCallSync(e,()=>this.makeCallSync(t,()=>this.baseFs.copyFileSync(e,t,i),(s,{subPath:o})=>n(this.baseFs,e,s,o)),(s,{subPath:o})=>this.makeCallSync(t,()=>n(s,o,this.baseFs,t),(a,{subPath:l})=>s!==a?n(s,o,a,l):s.copyFileSync(o,l,i)))}async appendFilePromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.appendFilePromise(e,t,i),async(n,{subPath:s})=>await n.appendFilePromise(s,t,i))}appendFileSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.appendFileSync(e,t,i),(n,{subPath:s})=>n.appendFileSync(s,t,i))}async writeFilePromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.writeFilePromise(e,t,i),async(n,{subPath:s})=>await n.writeFilePromise(s,t,i))}writeFileSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.writeFileSync(e,t,i),(n,{subPath:s})=>n.writeFileSync(s,t,i))}async unlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.unlinkPromise(e),async(t,{subPath:i})=>await t.unlinkPromise(i))}unlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.unlinkSync(e),(t,{subPath:i})=>t.unlinkSync(i))}async utimesPromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.utimesPromise(e,t,i),async(n,{subPath:s})=>await n.utimesPromise(s,t,i))}utimesSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.utimesSync(e,t,i),(n,{subPath:s})=>n.utimesSync(s,t,i))}async mkdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.mkdirPromise(e,t),async(i,{subPath:n})=>await i.mkdirPromise(n,t))}mkdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.mkdirSync(e,t),(i,{subPath:n})=>i.mkdirSync(n,t))}async rmdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.rmdirPromise(e,t),async(i,{subPath:n})=>await i.rmdirPromise(n,t))}rmdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.rmdirSync(e,t),(i,{subPath:n})=>i.rmdirSync(n,t))}async linkPromise(e,t){return await this.makeCallPromise(t,async()=>await this.baseFs.linkPromise(e,t),async(i,{subPath:n})=>await i.linkPromise(e,n))}linkSync(e,t){return this.makeCallSync(t,()=>this.baseFs.linkSync(e,t),(i,{subPath:n})=>i.linkSync(e,n))}async symlinkPromise(e,t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.symlinkPromise(e,t,i),async(n,{subPath:s})=>await n.symlinkPromise(e,s))}symlinkSync(e,t,i){return this.makeCallSync(t,()=>this.baseFs.symlinkSync(e,t,i),(n,{subPath:s})=>n.symlinkSync(e,s))}async readFilePromise(e,t){return this.makeCallPromise(e,async()=>{switch(t){case"utf8":return await this.baseFs.readFilePromise(e,t);default:return await this.baseFs.readFilePromise(e,t)}},async(i,{subPath:n})=>await i.readFilePromise(n,t))}readFileSync(e,t){return this.makeCallSync(e,()=>{switch(t){case"utf8":return this.baseFs.readFileSync(e,t);default:return this.baseFs.readFileSync(e,t)}},(i,{subPath:n})=>i.readFileSync(n,t))}async readdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.readdirPromise(e,t),async(i,{subPath:n})=>await i.readdirPromise(n,t),{requireSubpath:!1})}readdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.readdirSync(e,t),(i,{subPath:n})=>i.readdirSync(n,t),{requireSubpath:!1})}async readlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.readlinkPromise(e),async(t,{subPath:i})=>await t.readlinkPromise(i))}readlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.readlinkSync(e),(t,{subPath:i})=>t.readlinkSync(i))}async truncatePromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.truncatePromise(e,t),async(i,{subPath:n})=>await i.truncatePromise(n,t))}truncateSync(e,t){return this.makeCallSync(e,()=>this.baseFs.truncateSync(e,t),(i,{subPath:n})=>i.truncateSync(n,t))}async ftruncatePromise(e,t){if((e&Is)!==Xn)return this.baseFs.ftruncatePromise(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("ftruncate");let[n,s]=i;return n.ftruncatePromise(s,t)}ftruncateSync(e,t){if((e&Is)!==Xn)return this.baseFs.ftruncateSync(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("ftruncateSync");let[n,s]=i;return n.ftruncateSync(s,t)}watch(e,t,i){return this.makeCallSync(e,()=>this.baseFs.watch(e,t,i),(n,{subPath:s})=>n.watch(s,t,i))}watchFile(e,t,i){return this.makeCallSync(e,()=>this.baseFs.watchFile(e,t,i),()=>jE(this,e,t,i))}unwatchFile(e,t){return this.makeCallSync(e,()=>this.baseFs.unwatchFile(e,t),()=>zh(this,e,t))}async makeCallPromise(e,t,i,{requireSubpath:n=!0}={}){if(typeof e!="string")return await t();let s=this.resolve(e),o=this.findZip(s);return o?n&&o.subPath==="/"?await t():await this.getZipPromise(o.archivePath,async a=>await i(a,o)):await t()}makeCallSync(e,t,i,{requireSubpath:n=!0}={}){if(typeof e!="string")return t();let s=this.resolve(e),o=this.findZip(s);return!o||n&&o.subPath==="/"?t():this.getZipSync(o.archivePath,a=>i(a,o))}findZip(e){if(this.filter&&!this.filter.test(e))return null;let t="";for(;;){let i=e.substring(t.length),n;if(!this.fileExtensions)n=sM(i,".zip");else for(let s of this.fileExtensions)if(n=sM(i,s),n)break;if(!n)return null;if(t=this.pathUtils.join(t,n),this.isZip.has(t)===!1){if(this.notZip.has(t))continue;try{if(!this.baseFs.lstatSync(t).isFile()){this.notZip.add(t);continue}}catch{return null}this.isZip.add(t)}return{archivePath:t,subPath:this.pathUtils.join(Me.root,e.substring(t.length))}}}limitOpenFiles(e){if(this.zipInstances===null)return;let t=Date.now(),i=t+this.maxAge,n=e===null?0:this.zipInstances.size-e;for(let[s,{zipFs:o,expiresAt:a,refCount:l}]of this.zipInstances.entries())if(!(l!==0||o.hasOpenFileHandles())){if(t>=a){o.saveAndClose(),this.zipInstances.delete(s),n-=1;continue}else if(e===null||n<=0){i=a;break}o.saveAndClose(),this.zipInstances.delete(s),n-=1}this.limitOpenFilesTimeout===null&&(e===null&&this.zipInstances.size>0||e!==null)&&(this.limitOpenFilesTimeout=setTimeout(()=>{this.limitOpenFilesTimeout=null,this.limitOpenFiles(null)},i-t).unref())}async getZipPromise(e,t){let i=async()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:await this.baseFs.statPromise(e)});if(this.zipInstances){let n=this.zipInstances.get(e);if(!n){let s=await i();n=this.zipInstances.get(e),n||(n={zipFs:new li(e,s),expiresAt:0,refCount:0})}this.zipInstances.delete(e),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(e,n),n.expiresAt=Date.now()+this.maxAge,n.refCount+=1;try{return await t(n.zipFs)}finally{n.refCount-=1}}else{let n=new li(e,await i());try{return await t(n)}finally{n.saveAndClose()}}}getZipSync(e,t){let i=()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:this.baseFs.statSync(e)});if(this.zipInstances){let n=this.zipInstances.get(e);return n||(n={zipFs:new li(e,i()),expiresAt:0,refCount:0}),this.zipInstances.delete(e),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(e,n),n.expiresAt=Date.now()+this.maxAge,t(n.zipFs)}else{let n=new li(e,i());try{return t(n)}finally{n.saveAndClose()}}}};var Xu=ge(require("util"));var YE=ge(require("url"));var pQ=class extends Qi{constructor(e){super(H);this.baseFs=e}mapFromBase(e){return e}mapToBase(e){return e instanceof YE.URL?(0,YE.fileURLToPath)(e):e}};var en=Symbol("kBaseFs"),Oa=Symbol("kFd"),JA=Symbol("kClosePromise"),qE=Symbol("kCloseResolve"),JE=Symbol("kCloseReject"),Vu=Symbol("kRefs"),Lo=Symbol("kRef"),To=Symbol("kUnref"),v6e,k6e,x6e,P6e,WE=class{constructor(e,t){this[v6e]=1;this[k6e]=void 0;this[x6e]=void 0;this[P6e]=void 0;this[en]=t,this[Oa]=e}get fd(){return this[Oa]}async appendFile(e,t){var i;try{this[Lo](this.appendFile);let n=(i=typeof t=="string"?t:t==null?void 0:t.encoding)!=null?i:void 0;return await this[en].appendFilePromise(this.fd,e,n?{encoding:n}:void 0)}finally{this[To]()}}chown(e,t){throw new Error("Method not implemented.")}async chmod(e){try{return this[Lo](this.chmod),await this[en].fchmodPromise(this.fd,e)}finally{this[To]()}}createReadStream(e){return this[en].createReadStream(null,te(N({},e),{fd:this.fd}))}createWriteStream(e){return this[en].createWriteStream(null,te(N({},e),{fd:this.fd}))}datasync(){throw new Error("Method not implemented.")}sync(){throw new Error("Method not implemented.")}async read(e,t,i,n){var s,o,a;try{this[Lo](this.read);let l;return Buffer.isBuffer(e)?l=e:(e!=null||(e={}),l=(s=e.buffer)!=null?s:Buffer.alloc(16384),t=e.offset||0,i=(o=e.length)!=null?o:l.byteLength,n=(a=e.position)!=null?a:null),t!=null||(t=0),i!=null||(i=0),i===0?{bytesRead:i,buffer:l}:{bytesRead:await this[en].readPromise(this.fd,l,t,i,n),buffer:l}}finally{this[To]()}}async readFile(e){var t;try{this[Lo](this.readFile);let i=(t=typeof e=="string"?e:e==null?void 0:e.encoding)!=null?t:void 0;return await this[en].readFilePromise(this.fd,i)}finally{this[To]()}}async stat(e){try{return this[Lo](this.stat),await this[en].fstatPromise(this.fd,e)}finally{this[To]()}}async truncate(e){try{return this[Lo](this.truncate),await this[en].ftruncatePromise(this.fd,e)}finally{this[To]()}}utimes(e,t){throw new Error("Method not implemented.")}async writeFile(e,t){var i;try{this[Lo](this.writeFile);let n=(i=typeof t=="string"?t:t==null?void 0:t.encoding)!=null?i:void 0;await this[en].writeFilePromise(this.fd,e,n)}finally{this[To]()}}async write(...e){try{if(this[Lo](this.write),ArrayBuffer.isView(e[0])){let[t,i,n,s]=e;return{bytesWritten:await this[en].writePromise(this.fd,t,i!=null?i:void 0,n!=null?n:void 0,s!=null?s:void 0),buffer:t}}else{let[t,i,n]=e;return{bytesWritten:await this[en].writePromise(this.fd,t,i,n),buffer:t}}}finally{this[To]()}}async writev(e,t){try{this[Lo](this.writev);let i=0;if(typeof t!="undefined")for(let n of e){let s=await this.write(n,void 0,void 0,t);i+=s.bytesWritten,t+=s.bytesWritten}else for(let n of e)i+=(await this.write(n)).bytesWritten;return{buffers:e,bytesWritten:i}}finally{this[To]()}}readv(e,t){throw new Error("Method not implemented.")}close(){if(this[Oa]===-1)return Promise.resolve();if(this[JA])return this[JA];if(this[Vu]--,this[Vu]===0){let e=this[Oa];this[Oa]=-1,this[JA]=this[en].closePromise(e).finally(()=>{this[JA]=void 0})}else this[JA]=new Promise((e,t)=>{this[qE]=e,this[JE]=t}).finally(()=>{this[JA]=void 0,this[JE]=void 0,this[qE]=void 0});return this[JA]}[(en,Oa,v6e=Vu,k6e=JA,x6e=qE,P6e=JE,Lo)](e){if(this[Oa]===-1){let t=new Error("file closed");throw t.code="EBADF",t.syscall=e.name,t}this[Vu]++}[To](){if(this[Vu]--,this[Vu]===0){let e=this[Oa];this[Oa]=-1,this[en].closePromise(e).then(this[qE],this[JE])}}};var Pge=new Set(["accessSync","appendFileSync","createReadStream","createWriteStream","chmodSync","fchmodSync","chownSync","closeSync","copyFileSync","linkSync","lstatSync","fstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","statSync","symlinkSync","truncateSync","ftruncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),oM=new Set(["accessPromise","appendFilePromise","fchmodPromise","chmodPromise","chownPromise","closePromise","copyFilePromise","linkPromise","fstatPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","statPromise","symlinkPromise","truncatePromise","ftruncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"]);function dQ(r,e){e=new pQ(e);let t=(i,n,s)=>{let o=i[n];i[n]=s,typeof(o==null?void 0:o[Xu.promisify.custom])!="undefined"&&(s[Xu.promisify.custom]=o[Xu.promisify.custom])};{t(r,"exists",(i,...n)=>{let o=typeof n[n.length-1]=="function"?n.pop():()=>{};process.nextTick(()=>{e.existsPromise(i).then(a=>{o(a)},()=>{o(!1)})})}),t(r,"read",(...i)=>{let[n,s,o,a,l,c]=i;if(i.length<=3){let u={};i.length<3?c=i[1]:(u=i[1],c=i[2]),{buffer:s=Buffer.alloc(16384),offset:o=0,length:a=s.byteLength,position:l}=u}if(o==null&&(o=0),a|=0,a===0){process.nextTick(()=>{c(null,0,s)});return}l==null&&(l=-1),process.nextTick(()=>{e.readPromise(n,s,o,a,l).then(u=>{c(null,u,s)},u=>{c(u,0,s)})})});for(let i of oM){let n=i.replace(/Promise$/,"");if(typeof r[n]=="undefined")continue;let s=e[i];if(typeof s=="undefined")continue;t(r,n,(...a)=>{let c=typeof a[a.length-1]=="function"?a.pop():()=>{};process.nextTick(()=>{s.apply(e,a).then(u=>{c(null,u)},u=>{c(u)})})})}r.realpath.native=r.realpath}{t(r,"existsSync",i=>{try{return e.existsSync(i)}catch(n){return!1}}),t(r,"readSync",(...i)=>{let[n,s,o,a,l]=i;return i.length<=3&&({offset:o=0,length:a=s.byteLength,position:l}=i[2]||{}),o==null&&(o=0),a|=0,a===0?0:(l==null&&(l=-1),e.readSync(n,s,o,a,l))});for(let i of Pge){let n=i;if(typeof r[n]=="undefined")continue;let s=e[i];typeof s!="undefined"&&t(r,n,s.bind(e))}r.realpathSync.native=r.realpathSync}{let i=process.emitWarning;process.emitWarning=()=>{};let n;try{n=r.promises}finally{process.emitWarning=i}if(typeof n!="undefined"){for(let s of oM){let o=s.replace(/Promise$/,"");if(typeof n[o]=="undefined")continue;let a=e[s];typeof a!="undefined"&&s!=="open"&&t(n,o,(l,...c)=>l instanceof WE?l[o].apply(l,c):a.call(e,l,...c))}t(n,"open",async(...s)=>{let o=await e.openPromise(...s);return new WE(o,e)})}}r.read[Xu.promisify.custom]=async(i,n,...s)=>({bytesRead:await e.readPromise(i,n,...s),buffer:n}),r.write[Xu.promisify.custom]=async(i,n,...s)=>({bytesWritten:await e.writePromise(i,n,...s),buffer:n})}function zE(r,e){let t=Object.create(r);return dQ(t,e),t}var aM=ge(require("os"));function AM(r){let e=Math.ceil(Math.random()*4294967296).toString(16).padStart(8,"0");return`${r}${e}`}var oo=new Set,CQ=null;function lM(){if(CQ)return CQ;let r=H.toPortablePath(aM.default.tmpdir()),e=U.realpathSync(r);return process.once("exit",()=>{U.rmtempSync()}),CQ={tmpdir:r,realTmpdir:e}}var U=Object.assign(new ar,{detachTemp(r){oo.delete(r)},mktempSync(r){let{tmpdir:e,realTmpdir:t}=lM();for(;;){let i=AM("xfs-");try{this.mkdirSync(x.join(e,i))}catch(s){if(s.code==="EEXIST")continue;throw s}let n=x.join(t,i);if(oo.add(n),typeof r=="undefined")return n;try{return r(n)}finally{if(oo.has(n)){oo.delete(n);try{this.removeSync(n)}catch{}}}}},async mktempPromise(r){let{tmpdir:e,realTmpdir:t}=lM();for(;;){let i=AM("xfs-");try{await this.mkdirPromise(x.join(e,i))}catch(s){if(s.code==="EEXIST")continue;throw s}let n=x.join(t,i);if(oo.add(n),typeof r=="undefined")return n;try{return await r(n)}finally{if(oo.has(n)){oo.delete(n);try{await this.removePromise(n)}catch{}}}}},async rmtempPromise(){await Promise.all(Array.from(oo.values()).map(async r=>{try{await U.removePromise(r,{maxRetries:0}),oo.delete(r)}catch{}}))},rmtempSync(){for(let r of oo)try{U.removeSync(r),oo.delete(r)}catch{}}});var Ex=ge(vQ());var ap={};ft(ap,{parseResolution:()=>eI,parseShell:()=>VE,parseSyml:()=>Si,stringifyArgument:()=>DQ,stringifyArgumentSegment:()=>RQ,stringifyArithmeticExpression:()=>$E,stringifyCommand:()=>PQ,stringifyCommandChain:()=>tg,stringifyCommandChainThen:()=>xQ,stringifyCommandLine:()=>XE,stringifyCommandLineThen:()=>kQ,stringifyEnvSegment:()=>ZE,stringifyRedirectArgument:()=>ep,stringifyResolution:()=>tI,stringifyShell:()=>eg,stringifyShellLine:()=>eg,stringifySyml:()=>Ua,stringifyValueArgument:()=>gc});var $M=ge(ZM());function VE(r,e={isGlobPattern:()=>!1}){try{return(0,$M.parse)(r,e)}catch(t){throw t.location&&(t.message=t.message.replace(/(\.)?$/,` (line ${t.location.start.line}, column ${t.location.start.column})$1`)),t}}function eg(r,{endSemicolon:e=!1}={}){return r.map(({command:t,type:i},n)=>`${XE(t)}${i===";"?n!==r.length-1||e?";":"":" &"}`).join(" ")}function XE(r){return`${tg(r.chain)}${r.then?` ${kQ(r.then)}`:""}`}function kQ(r){return`${r.type} ${XE(r.line)}`}function tg(r){return`${PQ(r)}${r.then?` ${xQ(r.then)}`:""}`}function xQ(r){return`${r.type} ${tg(r.chain)}`}function PQ(r){switch(r.type){case"command":return`${r.envs.length>0?`${r.envs.map(e=>ZE(e)).join(" ")} `:""}${r.args.map(e=>DQ(e)).join(" ")}`;case"subshell":return`(${eg(r.subshell)})${r.args.length>0?` ${r.args.map(e=>ep(e)).join(" ")}`:""}`;case"group":return`{ ${eg(r.group,{endSemicolon:!0})} }${r.args.length>0?` ${r.args.map(e=>ep(e)).join(" ")}`:""}`;case"envs":return r.envs.map(e=>ZE(e)).join(" ");default:throw new Error(`Unsupported command type: "${r.type}"`)}}function ZE(r){return`${r.name}=${r.args[0]?gc(r.args[0]):""}`}function DQ(r){switch(r.type){case"redirection":return ep(r);case"argument":return gc(r);default:throw new Error(`Unsupported argument type: "${r.type}"`)}}function ep(r){return`${r.subtype} ${r.args.map(e=>gc(e)).join(" ")}`}function gc(r){return r.segments.map(e=>RQ(e)).join("")}function RQ(r){let e=(i,n)=>n?`"${i}"`:i,t=i=>i===""?'""':i.match(/[(){}<>$|&; \t"']/)?`$'${i.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\f/g,"\\f").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v").replace(/\0/g,"\\0")}'`:i;switch(r.type){case"text":return t(r.text);case"glob":return r.pattern;case"shell":return e(`\${${eg(r.shell)}}`,r.quoted);case"variable":return e(typeof r.defaultValue=="undefined"?typeof r.alternativeValue=="undefined"?`\${${r.name}}`:r.alternativeValue.length===0?`\${${r.name}:+}`:`\${${r.name}:+${r.alternativeValue.map(i=>gc(i)).join(" ")}}`:r.defaultValue.length===0?`\${${r.name}:-}`:`\${${r.name}:-${r.defaultValue.map(i=>gc(i)).join(" ")}}`,r.quoted);case"arithmetic":return`$(( ${$E(r.arithmetic)} ))`;default:throw new Error(`Unsupported argument segment type: "${r.type}"`)}}function $E(r){let e=n=>{switch(n){case"addition":return"+";case"subtraction":return"-";case"multiplication":return"*";case"division":return"/";default:throw new Error(`Can't extract operator from arithmetic expression of type "${n}"`)}},t=(n,s)=>s?`( ${n} )`:n,i=n=>t($E(n),!["number","variable"].includes(n.type));switch(r.type){case"number":return String(r.value);case"variable":return r.name;default:return`${i(r.left)} ${e(r.type)} ${i(r.right)}`}}var r1=ge(t1());function eI(r){let e=r.match(/^\*{1,2}\/(.*)/);if(e)throw new Error(`The override for '${r}' includes a glob pattern. Glob patterns have been removed since their behaviours don't match what you'd expect. Set the override to '${e[1]}' instead.`);try{return(0,r1.parse)(r)}catch(t){throw t.location&&(t.message=t.message.replace(/(\.)?$/,` (line ${t.location.start.line}, column ${t.location.start.column})$1`)),t}}function tI(r){let e="";return r.from&&(e+=r.from.fullName,r.from.description&&(e+=`@${r.from.description}`),e+="/"),e+=r.descriptor.fullName,r.descriptor.description&&(e+=`@${r.descriptor.description}`),e}var gI=ge(JU()),_U=ge(zU()),Upe=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,VU=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"],qQ=class{constructor(e){this.data=e}};function XU(r){return r.match(Upe)?r:JSON.stringify(r)}function ZU(r){return typeof r=="undefined"?!0:typeof r=="object"&&r!==null?Object.keys(r).every(e=>ZU(r[e])):!1}function JQ(r,e,t){if(r===null)return`null -`;if(typeof r=="number"||typeof r=="boolean")return`${r.toString()} -`;if(typeof r=="string")return`${XU(r)} -`;if(Array.isArray(r)){if(r.length===0)return`[] -`;let i=" ".repeat(e);return` -${r.map(s=>`${i}- ${JQ(s,e+1,!1)}`).join("")}`}if(typeof r=="object"&&r){let i,n;r instanceof qQ?(i=r.data,n=!1):(i=r,n=!0);let s=" ".repeat(e),o=Object.keys(i);n&&o.sort((l,c)=>{let u=VU.indexOf(l),g=VU.indexOf(c);return u===-1&&g===-1?l<c?-1:l>c?1:0:u!==-1&&g===-1?-1:u===-1&&g!==-1?1:u-g});let a=o.filter(l=>!ZU(i[l])).map((l,c)=>{let u=i[l],g=XU(l),f=JQ(u,e+1,!0),h=c>0||t?s:"",p=g.length>1024?`? ${g} -${h}:`:`${g}:`,m=f.startsWith(` -`)?f:` ${f}`;return`${h}${p}${m}`}).join(e===0?` -`:"")||` -`;return t?` -${a}`:`${a}`}throw new Error(`Unsupported value type (${r})`)}function Ua(r){try{let e=JQ(r,0,!1);return e!==` -`?e:""}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}Ua.PreserveOrdering=qQ;function Kpe(r){return r.endsWith(` -`)||(r+=` -`),(0,_U.parse)(r)}var Hpe=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i;function jpe(r){if(Hpe.test(r))return Kpe(r);let e=(0,gI.safeLoad)(r,{schema:gI.FAILSAFE_SCHEMA,json:!0});if(e==null)return{};if(typeof e!="object")throw new Error(`Expected an indexed object, got a ${typeof e} instead. Does your file follow Yaml's rules?`);if(Array.isArray(e))throw new Error("Expected an indexed object, got an array instead. Does your file follow Yaml's rules?");return e}function Si(r){return jpe(r)}var K4=ge(eK()),Ew=ge(yc());var mp={};ft(mp,{Builtins:()=>aS,Cli:()=>Bs,Command:()=>Re,Option:()=>J,UsageError:()=>Pe,formatMarkdownish:()=>Ki});var wc=0,Ap=1,tn=2,zQ="",vi="\0",cg=-1,_Q=/^(-h|--help)(?:=([0-9]+))?$/,fI=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,sK=/^-[a-zA-Z]{2,}$/,VQ=/^([^=]+)=([\s\S]*)$/,XQ=process.env.DEBUG_CLI==="1";var Pe=class extends Error{constructor(e){super(e);this.clipanion={type:"usage"},this.name="UsageError"}},lp=class extends Error{constructor(e,t){super();if(this.input=e,this.candidates=t,this.clipanion={type:"none"},this.name="UnknownSyntaxError",this.candidates.length===0)this.message="Command not found, but we're not sure what's the alternative.";else if(this.candidates.every(i=>i.reason!==null&&i.reason===t[0].reason)){let[{reason:i}]=this.candidates;this.message=`${i} - -${this.candidates.map(({usage:n})=>`$ ${n}`).join(` -`)}`}else if(this.candidates.length===1){let[{usage:i}]=this.candidates;this.message=`Command not found; did you mean: - -$ ${i} -${ZQ(e)}`}else this.message=`Command not found; did you mean one of: - -${this.candidates.map(({usage:i},n)=>`${`${n}.`.padStart(4)} ${i}`).join(` -`)} - -${ZQ(e)}`}},$Q=class extends Error{constructor(e,t){super();this.input=e,this.usages=t,this.clipanion={type:"none"},this.name="AmbiguousSyntaxError",this.message=`Cannot find which to pick amongst the following alternatives: - -${this.usages.map((i,n)=>`${`${n}.`.padStart(4)} ${i}`).join(` -`)} - -${ZQ(e)}`}},ZQ=r=>`While running ${r.filter(e=>e!==vi).map(e=>{let t=JSON.stringify(e);return e.match(/\s/)||e.length===0||t!==`"${e}"`?t:e}).join(" ")}`;var cp=Symbol("clipanion/isOption");function rn(r){return te(N({},r),{[cp]:!0})}function Uo(r,e){return typeof r=="undefined"?[r,e]:typeof r=="object"&&r!==null&&!Array.isArray(r)?[void 0,r]:[r,e]}function hI(r,e=!1){let t=r.replace(/^\.: /,"");return e&&(t=t[0].toLowerCase()+t.slice(1)),t}function up(r,e){return e.length===1?new Pe(`${r}: ${hI(e[0],!0)}`):new Pe(`${r}: -${e.map(t=>` -- ${hI(t)}`).join("")}`)}function gp(r,e,t){if(typeof t=="undefined")return e;let i=[],n=[],s=a=>{let l=e;return e=a,s.bind(null,l)};if(!t(e,{errors:i,coercions:n,coercion:s}))throw up(`Invalid value for ${r}`,i);for(let[,a]of n)a();return e}var Re=class{constructor(){this.help=!1}static Usage(e){return e}async catch(e){throw e}async validateAndExecute(){let t=this.constructor.schema;if(Array.isArray(t)){let{isDict:n,isUnknown:s,applyCascade:o}=await Promise.resolve().then(()=>(ws(),ug)),a=o(n(s()),t),l=[],c=[];if(!a(this,{errors:l,coercions:c}))throw up("Invalid option schema",l);for(let[,g]of c)g()}else if(t!=null)throw new Error("Invalid command schema");let i=await this.execute();return typeof i!="undefined"?i:0}};Re.isOption=cp;Re.Default=[];var pK=80,rS=Array(pK).fill("\u2501");for(let r=0;r<=24;++r)rS[rS.length-r]=`[38;5;${232+r}m\u2501`;var iS={header:r=>`\u2501\u2501\u2501 ${r}${r.length<pK-5?` ${rS.slice(r.length+5).join("")}`:":"}`,bold:r=>`${r}`,error:r=>`${r}`,code:r=>`${r}`},dK={header:r=>r,bold:r=>r,error:r=>r,code:r=>r};function bde(r){let e=r.split(` -`),t=e.filter(n=>n.match(/\S/)),i=t.length>0?t.reduce((n,s)=>Math.min(n,s.length-s.trimStart().length),Number.MAX_VALUE):0;return e.map(n=>n.slice(i).trimRight()).join(` -`)}function Ki(r,{format:e,paragraphs:t}){return r=r.replace(/\r\n?/g,` -`),r=bde(r),r=r.replace(/^\n+|\n+$/g,""),r=r.replace(/^(\s*)-([^\n]*?)\n+/gm,`$1-$2 - -`),r=r.replace(/\n(\n)?\n*/g,"$1"),t&&(r=r.split(/\n/).map(i=>{let n=i.match(/^\s*[*-][\t ]+(.*)/);if(!n)return i.match(/(.{1,80})(?: |$)/g).join(` -`);let s=i.length-i.trimStart().length;return n[1].match(new RegExp(`(.{1,${78-s}})(?: |$)`,"g")).map((o,a)=>" ".repeat(s)+(a===0?"- ":" ")+o).join(` -`)}).join(` - -`)),r=r.replace(/(`+)((?:.|[\n])*?)\1/g,(i,n,s)=>e.code(n+s+n)),r=r.replace(/(\*\*)((?:.|[\n])*?)\1/g,(i,n,s)=>e.bold(n+s+n)),r?`${r} -`:""}var oS=ge(require("tty"));function wn(r){XQ&&console.log(r)}var CK={candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:cg};function mK(){return{nodes:[sn(),sn(),sn()]}}function Sde(r){let e=mK(),t=[],i=e.nodes.length;for(let n of r){t.push(i);for(let s=0;s<n.nodes.length;++s)EK(s)||e.nodes.push(Qde(n.nodes[s],i));i+=n.nodes.length-2}for(let n of t)gg(e,wc,n);return e}function ao(r,e){return r.nodes.push(e),r.nodes.length-1}function vde(r){let e=new Set,t=i=>{if(e.has(i))return;e.add(i);let n=r.nodes[i];for(let o of Object.values(n.statics))for(let{to:a}of o)t(a);for(let[,{to:o}]of n.dynamics)t(o);for(let{to:o}of n.shortcuts)t(o);let s=new Set(n.shortcuts.map(({to:o})=>o));for(;n.shortcuts.length>0;){let{to:o}=n.shortcuts.shift(),a=r.nodes[o];for(let[l,c]of Object.entries(a.statics)){let u=Object.prototype.hasOwnProperty.call(n.statics,l)?n.statics[l]:n.statics[l]=[];for(let g of c)u.some(({to:f})=>g.to===f)||u.push(g)}for(let[l,c]of a.dynamics)n.dynamics.some(([u,{to:g}])=>l===u&&c.to===g)||n.dynamics.push([l,c]);for(let l of a.shortcuts)s.has(l.to)||(n.shortcuts.push(l),s.add(l.to))}};t(wc)}function kde(r,{prefix:e=""}={}){if(XQ){wn(`${e}Nodes are:`);for(let t=0;t<r.nodes.length;++t)wn(`${e} ${t}: ${JSON.stringify(r.nodes[t])}`)}}function IK(r,e,t=!1){wn(`Running a vm on ${JSON.stringify(e)}`);let i=[{node:wc,state:{candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,options:[],path:[],positionals:[],remainder:null,selectedIndex:null}}];kde(r,{prefix:" "});let n=[zQ,...e];for(let s=0;s<n.length;++s){let o=n[s];wn(` Processing ${JSON.stringify(o)}`);let a=[];for(let{node:l,state:c}of i){wn(` Current node is ${l}`);let u=r.nodes[l];if(l===tn){a.push({node:l,state:c});continue}console.assert(u.shortcuts.length===0,"Shortcuts should have been eliminated by now");let g=Object.prototype.hasOwnProperty.call(u.statics,o);if(!t||s<n.length-1||g)if(g){let f=u.statics[o];for(let{to:h,reducer:p}of f)a.push({node:h,state:typeof p!="undefined"?dI(nS,p,c,o):c}),wn(` Static transition to ${h} found`)}else wn(" No static transition found");else{let f=!1;for(let h of Object.keys(u.statics))if(!!h.startsWith(o)){if(o===h)for(let{to:p,reducer:m}of u.statics[h])a.push({node:p,state:typeof m!="undefined"?dI(nS,m,c,o):c}),wn(` Static transition to ${p} found`);else for(let{to:p}of u.statics[h])a.push({node:p,state:te(N({},c),{remainder:h.slice(o.length)})}),wn(` Static transition to ${p} found (partial match)`);f=!0}f||wn(" No partial static transition found")}if(o!==vi)for(let[f,{to:h,reducer:p}]of u.dynamics)dI(CI,f,c,o)&&(a.push({node:h,state:typeof p!="undefined"?dI(nS,p,c,o):c}),wn(` Dynamic transition to ${h} found (via ${f})`))}if(a.length===0&&o===vi&&e.length===1)return[{node:wc,state:CK}];if(a.length===0)throw new lp(e,i.filter(({node:l})=>l!==tn).map(({state:l})=>({usage:l.candidateUsage,reason:null})));if(a.every(({node:l})=>l===tn))throw new lp(e,a.map(({state:l})=>({usage:l.candidateUsage,reason:l.errorMessage})));i=xde(a)}if(i.length>0){wn(" Results:");for(let s of i)wn(` - ${s.node} -> ${JSON.stringify(s.state)}`)}else wn(" No results");return i}function Pde(r,e){if(e.selectedIndex!==null)return!0;if(Object.prototype.hasOwnProperty.call(r.statics,vi)){for(let{to:t}of r.statics[vi])if(t===Ap)return!0}return!1}function Rde(r,e,t){let i=t&&e.length>0?[""]:[],n=IK(r,e,t),s=[],o=new Set,a=(l,c,u=!0)=>{let g=[c];for(;g.length>0;){let h=g;g=[];for(let p of h){let m=r.nodes[p],y=Object.keys(m.statics);for(let b of Object.keys(m.statics)){let v=y[0];for(let{to:k,reducer:T}of m.statics[v])T==="pushPath"&&(u||l.push(v),g.push(k))}}u=!1}let f=JSON.stringify(l);o.has(f)||(s.push(l),o.add(f))};for(let{node:l,state:c}of n){if(c.remainder!==null){a([c.remainder],l);continue}let u=r.nodes[l],g=Pde(u,c);for(let[f,h]of Object.entries(u.statics))(g&&f!==vi||!f.startsWith("-")&&h.some(({reducer:p})=>p==="pushPath"))&&a([...i,f],l);if(!!g)for(let[f,{to:h}]of u.dynamics){if(h===tn)continue;let p=Dde(f,c);if(p!==null)for(let m of p)a([...i,m],l)}}return[...s].sort()}function Nde(r,e){let t=IK(r,[...e,vi]);return Fde(e,t.map(({state:i})=>i))}function xde(r){let e=0;for(let{state:t}of r)t.path.length>e&&(e=t.path.length);return r.filter(({state:t})=>t.path.length===e)}function Fde(r,e){let t=e.filter(g=>g.selectedIndex!==null);if(t.length===0)throw new Error;let i=t.filter(g=>g.requiredOptions.every(f=>f.some(h=>g.options.find(p=>p.name===h))));if(i.length===0)throw new lp(r,t.map(g=>({usage:g.candidateUsage,reason:null})));let n=0;for(let g of i)g.path.length>n&&(n=g.path.length);let s=i.filter(g=>g.path.length===n),o=g=>g.positionals.filter(({extra:f})=>!f).length+g.options.length,a=s.map(g=>({state:g,positionalCount:o(g)})),l=0;for(let{positionalCount:g}of a)g>l&&(l=g);let c=a.filter(({positionalCount:g})=>g===l).map(({state:g})=>g),u=Lde(c);if(u.length>1)throw new $Q(r,u.map(g=>g.candidateUsage));return u[0]}function Lde(r){let e=[],t=[];for(let i of r)i.selectedIndex===cg?t.push(i):e.push(i);return t.length>0&&e.push(te(N({},CK),{path:yK(...t.map(i=>i.path)),options:t.reduce((i,n)=>i.concat(n.options),[])})),e}function yK(r,e,...t){return e===void 0?Array.from(r):yK(r.filter((i,n)=>i===e[n]),...t)}function sn(){return{dynamics:[],shortcuts:[],statics:{}}}function EK(r){return r===Ap||r===tn}function sS(r,e=0){return{to:EK(r.to)?r.to:r.to>2?r.to+e-2:r.to+e,reducer:r.reducer}}function Qde(r,e=0){let t=sn();for(let[i,n]of r.dynamics)t.dynamics.push([i,sS(n,e)]);for(let i of r.shortcuts)t.shortcuts.push(sS(i,e));for(let[i,n]of Object.entries(r.statics))t.statics[i]=n.map(s=>sS(s,e));return t}function ki(r,e,t,i,n){r.nodes[e].dynamics.push([t,{to:i,reducer:n}])}function gg(r,e,t,i){r.nodes[e].shortcuts.push({to:t,reducer:i})}function Ka(r,e,t,i,n){(Object.prototype.hasOwnProperty.call(r.nodes[e].statics,t)?r.nodes[e].statics[t]:r.nodes[e].statics[t]=[]).push({to:i,reducer:n})}function dI(r,e,t,i){if(Array.isArray(e)){let[n,...s]=e;return r[n](t,i,...s)}else return r[e](t,i)}function Dde(r,e){let t=Array.isArray(r)?CI[r[0]]:CI[r];if(typeof t.suggest=="undefined")return null;let i=Array.isArray(r)?r.slice(1):[];return t.suggest(e,...i)}var CI={always:()=>!0,isOptionLike:(r,e)=>!r.ignoreOptions&&e!=="-"&&e.startsWith("-"),isNotOptionLike:(r,e)=>r.ignoreOptions||e==="-"||!e.startsWith("-"),isOption:(r,e,t,i)=>!r.ignoreOptions&&e===t,isBatchOption:(r,e,t)=>!r.ignoreOptions&&sK.test(e)&&[...e.slice(1)].every(i=>t.includes(`-${i}`)),isBoundOption:(r,e,t,i)=>{let n=e.match(VQ);return!r.ignoreOptions&&!!n&&fI.test(n[1])&&t.includes(n[1])&&i.filter(s=>s.names.includes(n[1])).every(s=>s.allowBinding)},isNegatedOption:(r,e,t)=>!r.ignoreOptions&&e===`--no-${t.slice(2)}`,isHelp:(r,e)=>!r.ignoreOptions&&_Q.test(e),isUnsupportedOption:(r,e,t)=>!r.ignoreOptions&&e.startsWith("-")&&fI.test(e)&&!t.includes(e),isInvalidOption:(r,e)=>!r.ignoreOptions&&e.startsWith("-")&&!fI.test(e)};CI.isOption.suggest=(r,e,t=!0)=>t?null:[e];var nS={setCandidateState:(r,e,t)=>N(N({},r),t),setSelectedIndex:(r,e,t)=>te(N({},r),{selectedIndex:t}),pushBatch:(r,e)=>te(N({},r),{options:r.options.concat([...e.slice(1)].map(t=>({name:`-${t}`,value:!0})))}),pushBound:(r,e)=>{let[,t,i]=e.match(VQ);return te(N({},r),{options:r.options.concat({name:t,value:i})})},pushPath:(r,e)=>te(N({},r),{path:r.path.concat(e)}),pushPositional:(r,e)=>te(N({},r),{positionals:r.positionals.concat({value:e,extra:!1})}),pushExtra:(r,e)=>te(N({},r),{positionals:r.positionals.concat({value:e,extra:!0})}),pushExtraNoLimits:(r,e)=>te(N({},r),{positionals:r.positionals.concat({value:e,extra:$n})}),pushTrue:(r,e,t=e)=>te(N({},r),{options:r.options.concat({name:e,value:!0})}),pushFalse:(r,e,t=e)=>te(N({},r),{options:r.options.concat({name:t,value:!1})}),pushUndefined:(r,e)=>te(N({},r),{options:r.options.concat({name:e,value:void 0})}),pushStringValue:(r,e)=>{var t;let i=te(N({},r),{options:[...r.options]}),n=r.options[r.options.length-1];return n.value=((t=n.value)!==null&&t!==void 0?t:[]).concat([e]),i},setStringValue:(r,e)=>{let t=te(N({},r),{options:[...r.options]}),i=r.options[r.options.length-1];return i.value=e,t},inhibateOptions:r=>te(N({},r),{ignoreOptions:!0}),useHelp:(r,e,t)=>{let[,,i]=e.match(_Q);return typeof i!="undefined"?te(N({},r),{options:[{name:"-c",value:String(t)},{name:"-i",value:i}]}):te(N({},r),{options:[{name:"-c",value:String(t)}]})},setError:(r,e,t)=>e===vi?te(N({},r),{errorMessage:`${t}.`}):te(N({},r),{errorMessage:`${t} ("${e}").`}),setOptionArityError:(r,e)=>{let t=r.options[r.options.length-1];return te(N({},r),{errorMessage:`Not enough arguments to option ${t.name}.`})}},$n=Symbol(),wK=class{constructor(e,t){this.allOptionNames=[],this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=t}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:t=this.arity.trailing,extra:i=this.arity.extra,proxy:n=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:t,extra:i,proxy:n})}addPositional({name:e="arg",required:t=!0}={}){if(!t&&this.arity.extra===$n)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!t&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");!t&&this.arity.extra!==$n?this.arity.extra.push(e):this.arity.extra!==$n&&this.arity.extra.length===0?this.arity.leading.push(e):this.arity.trailing.push(e)}addRest({name:e="arg",required:t=0}={}){if(this.arity.extra===$n)throw new Error("Infinite lists cannot be declared multiple times in the same command");if(this.arity.trailing.length>0)throw new Error("Infinite lists cannot be declared after the required trailing positional arguments");for(let i=0;i<t;++i)this.addPositional({name:e});this.arity.extra=$n}addProxy({required:e=0}={}){this.addRest({required:e}),this.arity.proxy=!0}addOption({names:e,description:t,arity:i=0,hidden:n=!1,required:s=!1,allowBinding:o=!0}){if(!o&&i>1)throw new Error("The arity cannot be higher than 1 when the option only supports the --arg=value syntax");if(!Number.isInteger(i))throw new Error(`The arity must be an integer, got ${i}`);if(i<0)throw new Error(`The arity must be positive, got ${i}`);this.allOptionNames.push(...e),this.options.push({names:e,description:t,arity:i,hidden:n,required:s,allowBinding:o})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:t=!0}={}){let i=[this.cliOpts.binaryName],n=[];if(this.paths.length>0&&i.push(...this.paths[0]),e){for(let{names:o,arity:a,hidden:l,description:c,required:u}of this.options){if(l)continue;let g=[];for(let h=0;h<a;++h)g.push(` #${h}`);let f=`${o.join(",")}${g.join("")}`;!t&&c?n.push({definition:f,description:c,required:u}):i.push(u?`<${f}>`:`[${f}]`)}i.push(...this.arity.leading.map(o=>`<${o}>`)),this.arity.extra===$n?i.push("..."):i.push(...this.arity.extra.map(o=>`[${o}]`)),i.push(...this.arity.trailing.map(o=>`<${o}>`))}return{usage:i.join(" "),options:n}}compile(){if(typeof this.context=="undefined")throw new Error("Assertion failed: No context attached");let e=mK(),t=wc,i=this.usage().usage,n=this.options.filter(a=>a.required).map(a=>a.names);t=ao(e,sn()),Ka(e,wc,zQ,t,["setCandidateState",{candidateUsage:i,requiredOptions:n}]);let s=this.arity.proxy?"always":"isNotOptionLike",o=this.paths.length>0?this.paths:[[]];for(let a of o){let l=t;if(a.length>0){let f=ao(e,sn());gg(e,l,f),this.registerOptions(e,f),l=f}for(let f=0;f<a.length;++f){let h=ao(e,sn());Ka(e,l,a[f],h,"pushPath"),l=h}if(this.arity.leading.length>0||!this.arity.proxy){let f=ao(e,sn());ki(e,l,"isHelp",f,["useHelp",this.cliIndex]),Ka(e,f,vi,Ap,["setSelectedIndex",cg]),this.registerOptions(e,l)}this.arity.leading.length>0&&Ka(e,l,vi,tn,["setError","Not enough positional arguments"]);let c=l;for(let f=0;f<this.arity.leading.length;++f){let h=ao(e,sn());this.arity.proxy||this.registerOptions(e,h),(this.arity.trailing.length>0||f+1!==this.arity.leading.length)&&Ka(e,h,vi,tn,["setError","Not enough positional arguments"]),ki(e,c,"isNotOptionLike",h,"pushPositional"),c=h}let u=c;if(this.arity.extra===$n||this.arity.extra.length>0){let f=ao(e,sn());if(gg(e,c,f),this.arity.extra===$n){let h=ao(e,sn());this.arity.proxy||this.registerOptions(e,h),ki(e,c,s,h,"pushExtraNoLimits"),ki(e,h,s,h,"pushExtraNoLimits"),gg(e,h,f)}else for(let h=0;h<this.arity.extra.length;++h){let p=ao(e,sn());this.arity.proxy||this.registerOptions(e,p),ki(e,u,s,p,"pushExtra"),gg(e,p,f),u=p}u=f}this.arity.trailing.length>0&&Ka(e,u,vi,tn,["setError","Not enough positional arguments"]);let g=u;for(let f=0;f<this.arity.trailing.length;++f){let h=ao(e,sn());this.arity.proxy||this.registerOptions(e,h),f+1<this.arity.trailing.length&&Ka(e,h,vi,tn,["setError","Not enough positional arguments"]),ki(e,g,"isNotOptionLike",h,"pushPositional"),g=h}ki(e,g,s,tn,["setError","Extraneous positional argument"]),Ka(e,g,vi,Ap,["setSelectedIndex",this.cliIndex])}return{machine:e,context:this.context}}registerOptions(e,t){ki(e,t,["isOption","--"],t,"inhibateOptions"),ki(e,t,["isBatchOption",this.allOptionNames],t,"pushBatch"),ki(e,t,["isBoundOption",this.allOptionNames,this.options],t,"pushBound"),ki(e,t,["isUnsupportedOption",this.allOptionNames],tn,["setError","Unsupported option name"]),ki(e,t,["isInvalidOption"],tn,["setError","Invalid option name"]);for(let i of this.options){let n=i.names.reduce((s,o)=>o.length>s.length?o:s,"");if(i.arity===0)for(let s of i.names)ki(e,t,["isOption",s,i.hidden||s!==n],t,"pushTrue"),s.startsWith("--")&&!s.startsWith("--no-")&&ki(e,t,["isNegatedOption",s],t,["pushFalse",s]);else{let s=ao(e,sn());for(let o of i.names)ki(e,t,["isOption",o,i.hidden||o!==n],s,"pushUndefined");for(let o=0;o<i.arity;++o){let a=ao(e,sn());Ka(e,s,vi,tn,"setOptionArityError"),ki(e,s,"isOptionLike",tn,"setOptionArityError");let l=i.arity===1?"setStringValue":"pushStringValue";ki(e,s,"isNotOptionLike",a,l),s=a}gg(e,s,t)}}}},dp=class{constructor({binaryName:e="..."}={}){this.builders=[],this.opts={binaryName:e}}static build(e,t={}){return new dp(t).commands(e).compile()}getBuilderByIndex(e){if(!(e>=0&&e<this.builders.length))throw new Error(`Assertion failed: Out-of-bound command index (${e})`);return this.builders[e]}commands(e){for(let t of e)t(this.command());return this}command(){let e=new wK(this.builders.length,this.opts);return this.builders.push(e),e}compile(){let e=[],t=[];for(let n of this.builders){let{machine:s,context:o}=n.compile();e.push(s),t.push(o)}let i=Sde(e);return vde(i),{machine:i,contexts:t,process:n=>Nde(i,n),suggest:(n,s)=>Rde(i,n,s)}}};var Cp=class extends Re{constructor(e){super();this.contexts=e,this.commands=[]}static from(e,t){let i=new Cp(t);i.path=e.path;for(let n of e.options)switch(n.name){case"-c":i.commands.push(Number(n.value));break;case"-i":i.index=Number(n.value);break}return i}async execute(){let e=this.commands;if(typeof this.index!="undefined"&&this.index>=0&&this.index<e.length&&(e=[e[this.index]]),e.length===0)this.context.stdout.write(this.cli.usage());else if(e.length===1)this.context.stdout.write(this.cli.usage(this.contexts[e[0]].commandClass,{detailed:!0}));else if(e.length>1){this.context.stdout.write(`Multiple commands match your selection: -`),this.context.stdout.write(` -`);let t=0;for(let i of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[i].commandClass,{prefix:`${t++}. `.padStart(5)}));this.context.stdout.write(` -`),this.context.stdout.write(`Run again with -h=<index> to see the longer details of any of those commands. -`)}}};var BK=Symbol("clipanion/errorCommand");function Tde(){return process.env.FORCE_COLOR==="0"?1:process.env.FORCE_COLOR==="1"||typeof process.stdout!="undefined"&&process.stdout.isTTY?8:1}var Bs=class{constructor({binaryLabel:e,binaryName:t="...",binaryVersion:i,enableCapture:n=!1,enableColors:s}={}){this.registrations=new Map,this.builder=new dp({binaryName:t}),this.binaryLabel=e,this.binaryName=t,this.binaryVersion=i,this.enableCapture=n,this.enableColors=s}static from(e,t={}){let i=new Bs(t);for(let n of e)i.register(n);return i}register(e){var t;let i=new Map,n=new e;for(let l in n){let c=n[l];typeof c=="object"&&c!==null&&c[Re.isOption]&&i.set(l,c)}let s=this.builder.command(),o=s.cliIndex,a=(t=e.paths)!==null&&t!==void 0?t:n.paths;if(typeof a!="undefined")for(let l of a)s.addPath(l);this.registrations.set(e,{specs:i,builder:s,index:o});for(let[l,{definition:c}]of i.entries())c(s,l);s.setContext({commandClass:e})}process(e){let{contexts:t,process:i}=this.builder.compile(),n=i(e);switch(n.selectedIndex){case cg:return Cp.from(n,t);default:{let{commandClass:s}=t[n.selectedIndex],o=this.registrations.get(s);if(typeof o=="undefined")throw new Error("Assertion failed: Expected the command class to have been registered.");let a=new s;a.path=n.path;try{for(let[l,{transformer:c}]of o.specs.entries())a[l]=c(o.builder,l,n);return a}catch(l){throw l[BK]=a,l}}break}}async run(e,t){var i;let n,s=N(N({},Bs.defaultContext),t),o=(i=this.enableColors)!==null&&i!==void 0?i:s.colorDepth>1;if(!Array.isArray(e))n=e;else try{n=this.process(e)}catch(c){return s.stdout.write(this.error(c,{colored:o})),1}if(n.help)return s.stdout.write(this.usage(n,{colored:o,detailed:!0})),0;n.context=s,n.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableCapture:this.enableCapture,enableColors:this.enableColors,definitions:()=>this.definitions(),error:(c,u)=>this.error(c,u),format:c=>this.format(c),process:c=>this.process(c),run:(c,u)=>this.run(c,N(N({},s),u)),usage:(c,u)=>this.usage(c,u)};let a=this.enableCapture?Ode(s):bK,l;try{l=await a(()=>n.validateAndExecute().catch(c=>n.catch(c).then(()=>0)))}catch(c){return s.stdout.write(this.error(c,{colored:o,command:n})),1}return l}async runExit(e,t){process.exitCode=await this.run(e,t)}suggest(e,t){let{suggest:i}=this.builder.compile();return i(e,t)}definitions({colored:e=!1}={}){let t=[];for(let[i,{index:n}]of this.registrations){if(typeof i.usage=="undefined")continue;let{usage:s}=this.getUsageByIndex(n,{detailed:!1}),{usage:o,options:a}=this.getUsageByIndex(n,{detailed:!0,inlineOptions:!1}),l=typeof i.usage.category!="undefined"?Ki(i.usage.category,{format:this.format(e),paragraphs:!1}):void 0,c=typeof i.usage.description!="undefined"?Ki(i.usage.description,{format:this.format(e),paragraphs:!1}):void 0,u=typeof i.usage.details!="undefined"?Ki(i.usage.details,{format:this.format(e),paragraphs:!0}):void 0,g=typeof i.usage.examples!="undefined"?i.usage.examples.map(([f,h])=>[Ki(f,{format:this.format(e),paragraphs:!1}),h.replace(/\$0/g,this.binaryName)]):void 0;t.push({path:s,usage:o,category:l,description:c,details:u,examples:g,options:a})}return t}usage(e=null,{colored:t,detailed:i=!1,prefix:n="$ "}={}){var s;if(e===null){for(let l of this.registrations.keys()){let c=l.paths,u=typeof l.usage!="undefined";if(!c||c.length===0||c.length===1&&c[0].length===0||((s=c==null?void 0:c.some(h=>h.length===0))!==null&&s!==void 0?s:!1))if(e){e=null;break}else e=l;else if(u){e=null;continue}}e&&(i=!0)}let o=e!==null&&e instanceof Re?e.constructor:e,a="";if(o)if(i){let{description:l="",details:c="",examples:u=[]}=o.usage||{};l!==""&&(a+=Ki(l,{format:this.format(t),paragraphs:!1}).replace(/^./,h=>h.toUpperCase()),a+=` -`),(c!==""||u.length>0)&&(a+=`${this.format(t).header("Usage")} -`,a+=` -`);let{usage:g,options:f}=this.getUsageByRegistration(o,{inlineOptions:!1});if(a+=`${this.format(t).bold(n)}${g} -`,f.length>0){a+=` -`,a+=`${iS.header("Options")} -`;let h=f.reduce((p,m)=>Math.max(p,m.definition.length),0);a+=` -`;for(let{definition:p,description:m}of f)a+=` ${this.format(t).bold(p.padEnd(h))} ${Ki(m,{format:this.format(t),paragraphs:!1})}`}if(c!==""&&(a+=` -`,a+=`${this.format(t).header("Details")} -`,a+=` -`,a+=Ki(c,{format:this.format(t),paragraphs:!0})),u.length>0){a+=` -`,a+=`${this.format(t).header("Examples")} -`;for(let[h,p]of u)a+=` -`,a+=Ki(h,{format:this.format(t),paragraphs:!1}),a+=`${p.replace(/^/m,` ${this.format(t).bold(n)}`).replace(/\$0/g,this.binaryName)} -`}}else{let{usage:l}=this.getUsageByRegistration(o);a+=`${this.format(t).bold(n)}${l} -`}else{let l=new Map;for(let[f,{index:h}]of this.registrations.entries()){if(typeof f.usage=="undefined")continue;let p=typeof f.usage.category!="undefined"?Ki(f.usage.category,{format:this.format(t),paragraphs:!1}):null,m=l.get(p);typeof m=="undefined"&&l.set(p,m=[]);let{usage:y}=this.getUsageByIndex(h);m.push({commandClass:f,usage:y})}let c=Array.from(l.keys()).sort((f,h)=>f===null?-1:h===null?1:f.localeCompare(h,"en",{usage:"sort",caseFirst:"upper"})),u=typeof this.binaryLabel!="undefined",g=typeof this.binaryVersion!="undefined";u||g?(u&&g?a+=`${this.format(t).header(`${this.binaryLabel} - ${this.binaryVersion}`)} - -`:u?a+=`${this.format(t).header(`${this.binaryLabel}`)} -`:a+=`${this.format(t).header(`${this.binaryVersion}`)} -`,a+=` ${this.format(t).bold(n)}${this.binaryName} <command> -`):a+=`${this.format(t).bold(n)}${this.binaryName} <command> -`;for(let f of c){let h=l.get(f).slice().sort((m,y)=>m.usage.localeCompare(y.usage,"en",{usage:"sort",caseFirst:"upper"})),p=f!==null?f.trim():"General commands";a+=` -`,a+=`${this.format(t).header(`${p}`)} -`;for(let{commandClass:m,usage:y}of h){let b=m.usage.description||"undocumented";a+=` -`,a+=` ${this.format(t).bold(y)} -`,a+=` ${Ki(b,{format:this.format(t),paragraphs:!1})}`}}a+=` -`,a+=Ki("You can also print more details about any of these commands by calling them with the `-h,--help` flag right after the command name.",{format:this.format(t),paragraphs:!0})}return a}error(e,t){var i,{colored:n,command:s=(i=e[BK])!==null&&i!==void 0?i:null}=t===void 0?{}:t;e instanceof Error||(e=new Error(`Execution failed with a non-error rejection (rejected value: ${JSON.stringify(e)})`));let o="",a=e.name.replace(/([a-z])([A-Z])/g,"$1 $2");a==="Error"&&(a="Internal Error"),o+=`${this.format(n).error(a)}: ${e.message} -`;let l=e.clipanion;return typeof l!="undefined"?l.type==="usage"&&(o+=` -`,o+=this.usage(s)):e.stack&&(o+=`${e.stack.replace(/^.*\n/,"")} -`),o}format(e){var t;return((t=e!=null?e:this.enableColors)!==null&&t!==void 0?t:Bs.defaultContext.colorDepth>1)?iS:dK}getUsageByRegistration(e,t){let i=this.registrations.get(e);if(typeof i=="undefined")throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(i.index,t)}getUsageByIndex(e,t){return this.builder.getBuilderByIndex(e).usage(t)}};Bs.defaultContext={stdin:process.stdin,stdout:process.stdout,stderr:process.stderr,colorDepth:"getColorDepth"in oS.default.WriteStream.prototype?oS.default.WriteStream.prototype.getColorDepth():Tde()};var QK;function Ode(r){let e=QK;if(typeof e=="undefined"){if(r.stdout===process.stdout&&r.stderr===process.stderr)return bK;let{AsyncLocalStorage:t}=require("async_hooks");e=QK=new t;let i=process.stdout._write;process.stdout._write=function(s,o,a){let l=e.getStore();return typeof l=="undefined"?i.call(this,s,o,a):l.stdout.write(s,o,a)};let n=process.stderr._write;process.stderr._write=function(s,o,a){let l=e.getStore();return typeof l=="undefined"?n.call(this,s,o,a):l.stderr.write(s,o,a)}}return t=>e.run(r,t)}function bK(r){return r()}var aS={};ft(aS,{DefinitionsCommand:()=>mI,HelpCommand:()=>EI,VersionCommand:()=>II});var mI=class extends Re{async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.definitions(),null,2)} -`)}};mI.paths=[["--clipanion=definitions"]];var EI=class extends Re{async execute(){this.context.stdout.write(this.cli.usage())}};EI.paths=[["-h"],["--help"]];var II=class extends Re{async execute(){var e;this.context.stdout.write(`${(e=this.cli.binaryVersion)!==null&&e!==void 0?e:"<unknown>"} -`)}};II.paths=[["-v"],["--version"]];var J={};ft(J,{Array:()=>SK,Boolean:()=>vK,Counter:()=>kK,Proxy:()=>xK,Rest:()=>PK,String:()=>DK,applyValidator:()=>gp,cleanValidationError:()=>hI,formatError:()=>up,isOptionSymbol:()=>cp,makeCommandOption:()=>rn,rerouteArguments:()=>Uo});function SK(r,e,t){let[i,n]=Uo(e,t!=null?t:{}),{arity:s=1}=n,o=r.split(","),a=new Set(o);return rn({definition(l){l.addOption({names:o,arity:s,hidden:n==null?void 0:n.hidden,description:n==null?void 0:n.description,required:n.required})},transformer(l,c,u){let g=typeof i!="undefined"?[...i]:void 0;for(let{name:f,value:h}of u.options)!a.has(f)||(g=g!=null?g:[],g.push(h));return g}})}function vK(r,e,t){let[i,n]=Uo(e,t!=null?t:{}),s=r.split(","),o=new Set(s);return rn({definition(a){a.addOption({names:s,allowBinding:!1,arity:0,hidden:n.hidden,description:n.description,required:n.required})},transformer(a,l,c){let u=i;for(let{name:g,value:f}of c.options)!o.has(g)||(u=f);return u}})}function kK(r,e,t){let[i,n]=Uo(e,t!=null?t:{}),s=r.split(","),o=new Set(s);return rn({definition(a){a.addOption({names:s,allowBinding:!1,arity:0,hidden:n.hidden,description:n.description,required:n.required})},transformer(a,l,c){let u=i;for(let{name:g,value:f}of c.options)!o.has(g)||(u!=null||(u=0),f?u+=1:u=0);return u}})}function xK(r={}){return rn({definition(e,t){var i;e.addProxy({name:(i=r.name)!==null&&i!==void 0?i:t,required:r.required})},transformer(e,t,i){return i.positionals.map(({value:n})=>n)}})}function PK(r={}){return rn({definition(e,t){var i;e.addRest({name:(i=r.name)!==null&&i!==void 0?i:t,required:r.required})},transformer(e,t,i){let n=o=>{let a=i.positionals[o];return a.extra===$n||a.extra===!1&&o<e.arity.leading.length},s=0;for(;s<i.positionals.length&&n(s);)s+=1;return i.positionals.splice(0,s).map(({value:o})=>o)}})}function Mde(r,e,t){let[i,n]=Uo(e,t!=null?t:{}),{arity:s=1}=n,o=r.split(","),a=new Set(o);return rn({definition(l){l.addOption({names:o,arity:n.tolerateBoolean?0:s,hidden:n.hidden,description:n.description,required:n.required})},transformer(l,c,u){let g,f=i;for(let{name:h,value:p}of u.options)!a.has(h)||(g=h,f=p);return typeof f=="string"?gp(g!=null?g:c,f,n.validator):f}})}function Ude(r={}){let{required:e=!0}=r;return rn({definition(t,i){var n;t.addPositional({name:(n=r.name)!==null&&n!==void 0?n:i,required:r.required})},transformer(t,i,n){var s;for(let o=0;o<n.positionals.length;++o){if(n.positionals[o].extra===$n||e&&n.positionals[o].extra===!0||!e&&n.positionals[o].extra===!1)continue;let[a]=n.positionals.splice(o,1);return gp((s=r.name)!==null&&s!==void 0?s:i,a.value,r.validator)}}})}function DK(r,...e){return typeof r=="string"?Mde(r,...e):Ude(r)}var H4=ge(fg()),gx=ge(require("stream"));var X;(function(Ae){Ae[Ae.UNNAMED=0]="UNNAMED",Ae[Ae.EXCEPTION=1]="EXCEPTION",Ae[Ae.MISSING_PEER_DEPENDENCY=2]="MISSING_PEER_DEPENDENCY",Ae[Ae.CYCLIC_DEPENDENCIES=3]="CYCLIC_DEPENDENCIES",Ae[Ae.DISABLED_BUILD_SCRIPTS=4]="DISABLED_BUILD_SCRIPTS",Ae[Ae.BUILD_DISABLED=5]="BUILD_DISABLED",Ae[Ae.SOFT_LINK_BUILD=6]="SOFT_LINK_BUILD",Ae[Ae.MUST_BUILD=7]="MUST_BUILD",Ae[Ae.MUST_REBUILD=8]="MUST_REBUILD",Ae[Ae.BUILD_FAILED=9]="BUILD_FAILED",Ae[Ae.RESOLVER_NOT_FOUND=10]="RESOLVER_NOT_FOUND",Ae[Ae.FETCHER_NOT_FOUND=11]="FETCHER_NOT_FOUND",Ae[Ae.LINKER_NOT_FOUND=12]="LINKER_NOT_FOUND",Ae[Ae.FETCH_NOT_CACHED=13]="FETCH_NOT_CACHED",Ae[Ae.YARN_IMPORT_FAILED=14]="YARN_IMPORT_FAILED",Ae[Ae.REMOTE_INVALID=15]="REMOTE_INVALID",Ae[Ae.REMOTE_NOT_FOUND=16]="REMOTE_NOT_FOUND",Ae[Ae.RESOLUTION_PACK=17]="RESOLUTION_PACK",Ae[Ae.CACHE_CHECKSUM_MISMATCH=18]="CACHE_CHECKSUM_MISMATCH",Ae[Ae.UNUSED_CACHE_ENTRY=19]="UNUSED_CACHE_ENTRY",Ae[Ae.MISSING_LOCKFILE_ENTRY=20]="MISSING_LOCKFILE_ENTRY",Ae[Ae.WORKSPACE_NOT_FOUND=21]="WORKSPACE_NOT_FOUND",Ae[Ae.TOO_MANY_MATCHING_WORKSPACES=22]="TOO_MANY_MATCHING_WORKSPACES",Ae[Ae.CONSTRAINTS_MISSING_DEPENDENCY=23]="CONSTRAINTS_MISSING_DEPENDENCY",Ae[Ae.CONSTRAINTS_INCOMPATIBLE_DEPENDENCY=24]="CONSTRAINTS_INCOMPATIBLE_DEPENDENCY",Ae[Ae.CONSTRAINTS_EXTRANEOUS_DEPENDENCY=25]="CONSTRAINTS_EXTRANEOUS_DEPENDENCY",Ae[Ae.CONSTRAINTS_INVALID_DEPENDENCY=26]="CONSTRAINTS_INVALID_DEPENDENCY",Ae[Ae.CANT_SUGGEST_RESOLUTIONS=27]="CANT_SUGGEST_RESOLUTIONS",Ae[Ae.FROZEN_LOCKFILE_EXCEPTION=28]="FROZEN_LOCKFILE_EXCEPTION",Ae[Ae.CROSS_DRIVE_VIRTUAL_LOCAL=29]="CROSS_DRIVE_VIRTUAL_LOCAL",Ae[Ae.FETCH_FAILED=30]="FETCH_FAILED",Ae[Ae.DANGEROUS_NODE_MODULES=31]="DANGEROUS_NODE_MODULES",Ae[Ae.NODE_GYP_INJECTED=32]="NODE_GYP_INJECTED",Ae[Ae.AUTHENTICATION_NOT_FOUND=33]="AUTHENTICATION_NOT_FOUND",Ae[Ae.INVALID_CONFIGURATION_KEY=34]="INVALID_CONFIGURATION_KEY",Ae[Ae.NETWORK_ERROR=35]="NETWORK_ERROR",Ae[Ae.LIFECYCLE_SCRIPT=36]="LIFECYCLE_SCRIPT",Ae[Ae.CONSTRAINTS_MISSING_FIELD=37]="CONSTRAINTS_MISSING_FIELD",Ae[Ae.CONSTRAINTS_INCOMPATIBLE_FIELD=38]="CONSTRAINTS_INCOMPATIBLE_FIELD",Ae[Ae.CONSTRAINTS_EXTRANEOUS_FIELD=39]="CONSTRAINTS_EXTRANEOUS_FIELD",Ae[Ae.CONSTRAINTS_INVALID_FIELD=40]="CONSTRAINTS_INVALID_FIELD",Ae[Ae.AUTHENTICATION_INVALID=41]="AUTHENTICATION_INVALID",Ae[Ae.PROLOG_UNKNOWN_ERROR=42]="PROLOG_UNKNOWN_ERROR",Ae[Ae.PROLOG_SYNTAX_ERROR=43]="PROLOG_SYNTAX_ERROR",Ae[Ae.PROLOG_EXISTENCE_ERROR=44]="PROLOG_EXISTENCE_ERROR",Ae[Ae.STACK_OVERFLOW_RESOLUTION=45]="STACK_OVERFLOW_RESOLUTION",Ae[Ae.AUTOMERGE_FAILED_TO_PARSE=46]="AUTOMERGE_FAILED_TO_PARSE",Ae[Ae.AUTOMERGE_IMMUTABLE=47]="AUTOMERGE_IMMUTABLE",Ae[Ae.AUTOMERGE_SUCCESS=48]="AUTOMERGE_SUCCESS",Ae[Ae.AUTOMERGE_REQUIRED=49]="AUTOMERGE_REQUIRED",Ae[Ae.DEPRECATED_CLI_SETTINGS=50]="DEPRECATED_CLI_SETTINGS",Ae[Ae.PLUGIN_NAME_NOT_FOUND=51]="PLUGIN_NAME_NOT_FOUND",Ae[Ae.INVALID_PLUGIN_REFERENCE=52]="INVALID_PLUGIN_REFERENCE",Ae[Ae.CONSTRAINTS_AMBIGUITY=53]="CONSTRAINTS_AMBIGUITY",Ae[Ae.CACHE_OUTSIDE_PROJECT=54]="CACHE_OUTSIDE_PROJECT",Ae[Ae.IMMUTABLE_INSTALL=55]="IMMUTABLE_INSTALL",Ae[Ae.IMMUTABLE_CACHE=56]="IMMUTABLE_CACHE",Ae[Ae.INVALID_MANIFEST=57]="INVALID_MANIFEST",Ae[Ae.PACKAGE_PREPARATION_FAILED=58]="PACKAGE_PREPARATION_FAILED",Ae[Ae.INVALID_RANGE_PEER_DEPENDENCY=59]="INVALID_RANGE_PEER_DEPENDENCY",Ae[Ae.INCOMPATIBLE_PEER_DEPENDENCY=60]="INCOMPATIBLE_PEER_DEPENDENCY",Ae[Ae.DEPRECATED_PACKAGE=61]="DEPRECATED_PACKAGE",Ae[Ae.INCOMPATIBLE_OS=62]="INCOMPATIBLE_OS",Ae[Ae.INCOMPATIBLE_CPU=63]="INCOMPATIBLE_CPU",Ae[Ae.FROZEN_ARTIFACT_EXCEPTION=64]="FROZEN_ARTIFACT_EXCEPTION",Ae[Ae.TELEMETRY_NOTICE=65]="TELEMETRY_NOTICE",Ae[Ae.PATCH_HUNK_FAILED=66]="PATCH_HUNK_FAILED",Ae[Ae.INVALID_CONFIGURATION_VALUE=67]="INVALID_CONFIGURATION_VALUE",Ae[Ae.UNUSED_PACKAGE_EXTENSION=68]="UNUSED_PACKAGE_EXTENSION",Ae[Ae.REDUNDANT_PACKAGE_EXTENSION=69]="REDUNDANT_PACKAGE_EXTENSION",Ae[Ae.AUTO_NM_SUCCESS=70]="AUTO_NM_SUCCESS",Ae[Ae.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK=71]="NM_CANT_INSTALL_EXTERNAL_SOFT_LINK",Ae[Ae.NM_PRESERVE_SYMLINKS_REQUIRED=72]="NM_PRESERVE_SYMLINKS_REQUIRED",Ae[Ae.UPDATE_LOCKFILE_ONLY_SKIP_LINK=73]="UPDATE_LOCKFILE_ONLY_SKIP_LINK",Ae[Ae.NM_HARDLINKS_MODE_DOWNGRADED=74]="NM_HARDLINKS_MODE_DOWNGRADED",Ae[Ae.PROLOG_INSTANTIATION_ERROR=75]="PROLOG_INSTANTIATION_ERROR",Ae[Ae.INCOMPATIBLE_ARCHITECTURE=76]="INCOMPATIBLE_ARCHITECTURE",Ae[Ae.GHOST_ARCHITECTURE=77]="GHOST_ARCHITECTURE",Ae[Ae.PROLOG_LIMIT_EXCEEDED=79]="PROLOG_LIMIT_EXCEEDED"})(X||(X={}));function VA(r){return`YN${r.toString(10).padStart(4,"0")}`}function yI(r){let e=Number(r.slice(2));if(typeof X[e]=="undefined")throw new Error(`Unknown message name: "${r}"`);return e}var P={};ft(P,{areDescriptorsEqual:()=>z3,areIdentsEqual:()=>hd,areLocatorsEqual:()=>pd,areVirtualPackagesEquivalent:()=>cSe,bindDescriptor:()=>ASe,bindLocator:()=>lSe,convertDescriptorToLocator:()=>lw,convertLocatorToDescriptor:()=>Vk,convertPackageToLocator:()=>aSe,convertToIdent:()=>oSe,convertToManifestRange:()=>fSe,copyPackage:()=>ud,devirtualizeDescriptor:()=>gd,devirtualizeLocator:()=>fd,getIdentVendorPath:()=>tx,isPackageCompatible:()=>fw,isVirtualDescriptor:()=>ll,isVirtualLocator:()=>ta,makeDescriptor:()=>rr,makeIdent:()=>ea,makeLocator:()=>cn,makeRange:()=>uw,parseDescriptor:()=>cl,parseFileStyleRange:()=>uSe,parseIdent:()=>An,parseLocator:()=>qc,parseRange:()=>Jg,prettyDependent:()=>Tv,prettyDescriptor:()=>sr,prettyIdent:()=>fi,prettyLocator:()=>It,prettyLocatorNoColors:()=>ex,prettyRange:()=>Aw,prettyReference:()=>Cd,prettyResolution:()=>Ov,prettyWorkspace:()=>md,renamePackage:()=>cd,slugifyIdent:()=>$k,slugifyLocator:()=>Wg,sortDescriptors:()=>zg,stringifyDescriptor:()=>Pn,stringifyIdent:()=>Ot,stringifyLocator:()=>Fs,tryParseDescriptor:()=>dd,tryParseIdent:()=>_3,tryParseLocator:()=>cw,virtualizeDescriptor:()=>Xk,virtualizePackage:()=>Zk});var qg=ge(require("querystring")),q3=ge(ri()),J3=ge(AY());var ae={};ft(ae,{LogLevel:()=>Co,Style:()=>Oc,Type:()=>Ye,addLogFilterSupport:()=>sd,applyColor:()=>Dn,applyHyperlink:()=>Ug,applyStyle:()=>Fy,json:()=>Mc,jsonOrPretty:()=>jBe,mark:()=>jv,pretty:()=>tt,prettyField:()=>Xo,prettyList:()=>Hv,supportsColor:()=>Dy,supportsHyperlinks:()=>Uv,tuple:()=>po});var id=ge(gv()),nd=ge(yc());var lJ=ge(ns()),cJ=ge(Vq());var Se={};ft(Se,{AsyncActions:()=>iJ,BufferStream:()=>rJ,CachingStrategy:()=>Tc,DefaultStream:()=>nJ,allSettledSafe:()=>ho,assertNever:()=>Dv,bufferStream:()=>Og,buildIgnorePattern:()=>MBe,convertMapsToIndexableObjects:()=>Py,dynamicRequire:()=>Mg,escapeRegExp:()=>FBe,getArrayWithDefault:()=>Ng,getFactoryWithDefault:()=>Va,getMapWithDefault:()=>Lg,getSetWithDefault:()=>Lc,isIndexableObject:()=>Rv,isPathLike:()=>UBe,isTaggedYarnVersion:()=>RBe,mapAndFilter:()=>Vo,mapAndFind:()=>ed,overrideType:()=>Pv,parseBoolean:()=>rd,parseOptionalBoolean:()=>AJ,prettifyAsyncErrors:()=>Tg,prettifySyncErrors:()=>Fv,releaseAfterUseAsync:()=>LBe,replaceEnvVariables:()=>Nv,sortMap:()=>xn,tryParseOptionalBoolean:()=>Lv,validateEnum:()=>NBe});var Xq=ge(ns()),Zq=ge(fg()),$q=ge(ri()),xv=ge(require("stream"));function RBe(r){return!!($q.default.valid(r)&&r.match(/^[^-]+(-rc\.[0-9]+)?$/))}function FBe(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Pv(r){}function Dv(r){throw new Error(`Assertion failed: Unexpected object '${r}'`)}function NBe(r,e){let t=Object.values(r);if(!t.includes(e))throw new Pe(`Invalid value for enumeration: ${JSON.stringify(e)} (expected one of ${t.map(i=>JSON.stringify(i)).join(", ")})`);return e}function Vo(r,e){let t=[];for(let i of r){let n=e(i);n!==eJ&&t.push(n)}return t}var eJ=Symbol();Vo.skip=eJ;function ed(r,e){for(let t of r){let i=e(t);if(i!==tJ)return i}}var tJ=Symbol();ed.skip=tJ;function Rv(r){return typeof r=="object"&&r!==null}async function ho(r){let e=await Promise.allSettled(r),t=[];for(let i of e){if(i.status==="rejected")throw i.reason;t.push(i.value)}return t}function Py(r){if(r instanceof Map&&(r=Object.fromEntries(r)),Rv(r))for(let e of Object.keys(r)){let t=r[e];Rv(t)&&(r[e]=Py(t))}return r}function Va(r,e,t){let i=r.get(e);return typeof i=="undefined"&&r.set(e,i=t()),i}function Ng(r,e){let t=r.get(e);return typeof t=="undefined"&&r.set(e,t=[]),t}function Lc(r,e){let t=r.get(e);return typeof t=="undefined"&&r.set(e,t=new Set),t}function Lg(r,e){let t=r.get(e);return typeof t=="undefined"&&r.set(e,t=new Map),t}async function LBe(r,e){if(e==null)return await r();try{return await r()}finally{await e()}}async function Tg(r,e){try{return await r()}catch(t){throw t.message=e(t.message),t}}function Fv(r,e){try{return r()}catch(t){throw t.message=e(t.message),t}}async function Og(r){return await new Promise((e,t)=>{let i=[];r.on("error",n=>{t(n)}),r.on("data",n=>{i.push(n)}),r.on("end",()=>{e(Buffer.concat(i))})})}var rJ=class extends xv.Transform{constructor(){super(...arguments);this.chunks=[]}_transform(e,t,i){if(t!=="buffer"||!Buffer.isBuffer(e))throw new Error("Assertion failed: BufferStream only accept buffers");this.chunks.push(e),i(null,null)}_flush(e){e(null,Buffer.concat(this.chunks))}};function TBe(){let r,e;return{promise:new Promise((i,n)=>{r=i,e=n}),resolve:r,reject:e}}var iJ=class{constructor(e){this.deferred=new Map;this.promises=new Map;this.limit=(0,Zq.default)(e)}set(e,t){let i=this.deferred.get(e);typeof i=="undefined"&&this.deferred.set(e,i=TBe());let n=this.limit(()=>t());return this.promises.set(e,n),n.then(()=>{this.promises.get(e)===n&&i.resolve()},s=>{this.promises.get(e)===n&&i.reject(s)}),i.promise}reduce(e,t){var n;let i=(n=this.promises.get(e))!=null?n:Promise.resolve();this.set(e,()=>t(i))}async wait(){await Promise.all(this.promises.values())}},nJ=class extends xv.Transform{constructor(e=Buffer.alloc(0)){super();this.active=!0;this.ifEmpty=e}_transform(e,t,i){if(t!=="buffer"||!Buffer.isBuffer(e))throw new Error("Assertion failed: DefaultStream only accept buffers");this.active=!1,i(null,e)}_flush(e){this.active&&this.ifEmpty.length>0?e(null,this.ifEmpty):e(null)}},td=eval("require");function sJ(r){return td(H.fromPortablePath(r))}function oJ(path){let physicalPath=H.fromPortablePath(path),currentCacheEntry=td.cache[physicalPath];delete td.cache[physicalPath];let result;try{result=sJ(physicalPath);let freshCacheEntry=td.cache[physicalPath],dynamicModule=eval("module"),freshCacheIndex=dynamicModule.children.indexOf(freshCacheEntry);freshCacheIndex!==-1&&dynamicModule.children.splice(freshCacheIndex,1)}finally{td.cache[physicalPath]=currentCacheEntry}return result}var aJ=new Map;function OBe(r){let e=aJ.get(r),t=U.statSync(r);if((e==null?void 0:e.mtime)===t.mtimeMs)return e.instance;let i=oJ(r);return aJ.set(r,{mtime:t.mtimeMs,instance:i}),i}var Tc;(function(i){i[i.NoCache=0]="NoCache",i[i.FsTime=1]="FsTime",i[i.Node=2]="Node"})(Tc||(Tc={}));function Mg(r,{cachingStrategy:e=2}={}){switch(e){case 0:return oJ(r);case 1:return OBe(r);case 2:return sJ(r);default:throw new Error("Unsupported caching strategy")}}function xn(r,e){let t=Array.from(r);Array.isArray(e)||(e=[e]);let i=[];for(let s of e)i.push(t.map(o=>s(o)));let n=t.map((s,o)=>o);return n.sort((s,o)=>{for(let a of i){let l=a[s]<a[o]?-1:a[s]>a[o]?1:0;if(l!==0)return l}return 0}),n.map(s=>t[s])}function MBe(r){return r.length===0?null:r.map(e=>`(${Xq.default.makeRe(e,{windows:!1,dot:!0}).source})`).join("|")}function Nv(r,{env:e}){let t=/\${(?<variableName>[\d\w_]+)(?<colon>:)?(?:-(?<fallback>[^}]*))?}/g;return r.replace(t,(...i)=>{let{variableName:n,colon:s,fallback:o}=i[i.length-1],a=Object.prototype.hasOwnProperty.call(e,n),l=e[n];if(l||a&&!s)return l;if(o!=null)return o;throw new Pe(`Environment variable not found (${n})`)})}function rd(r){switch(r){case"true":case"1":case 1:case!0:return!0;case"false":case"0":case 0:case!1:return!1;default:throw new Error(`Couldn't parse "${r}" as a boolean`)}}function AJ(r){return typeof r=="undefined"?r:rd(r)}function Lv(r){try{return AJ(r)}catch{return null}}function UBe(r){return!!(H.isAbsolute(r)||r.match(/^(\.{1,2}|~)\//))}var Qt;(function(t){t.HARD="HARD",t.SOFT="SOFT"})(Qt||(Qt={}));var wi;(function(i){i.Dependency="Dependency",i.PeerDependency="PeerDependency",i.PeerDependencyMeta="PeerDependencyMeta"})(wi||(wi={}));var qi;(function(i){i.Inactive="inactive",i.Redundant="redundant",i.Active="active"})(qi||(qi={}));var Ye={NO_HINT:"NO_HINT",NULL:"NULL",SCOPE:"SCOPE",NAME:"NAME",RANGE:"RANGE",REFERENCE:"REFERENCE",NUMBER:"NUMBER",PATH:"PATH",URL:"URL",ADDED:"ADDED",REMOVED:"REMOVED",CODE:"CODE",DURATION:"DURATION",SIZE:"SIZE",IDENT:"IDENT",DESCRIPTOR:"DESCRIPTOR",LOCATOR:"LOCATOR",RESOLUTION:"RESOLUTION",DEPENDENT:"DEPENDENT",PACKAGE_EXTENSION:"PACKAGE_EXTENSION",SETTING:"SETTING",MARKDOWN:"MARKDOWN"},Oc;(function(e){e[e.BOLD=2]="BOLD"})(Oc||(Oc={}));var Mv=nd.default.GITHUB_ACTIONS?{level:2}:id.default.supportsColor?{level:id.default.supportsColor.level}:{level:0},Dy=Mv.level!==0,Uv=Dy&&!nd.default.GITHUB_ACTIONS&&!nd.default.CIRCLE&&!nd.default.GITLAB,Kv=new id.default.Instance(Mv),KBe=new Map([[Ye.NO_HINT,null],[Ye.NULL,["#a853b5",129]],[Ye.SCOPE,["#d75f00",166]],[Ye.NAME,["#d7875f",173]],[Ye.RANGE,["#00afaf",37]],[Ye.REFERENCE,["#87afff",111]],[Ye.NUMBER,["#ffd700",220]],[Ye.PATH,["#d75fd7",170]],[Ye.URL,["#d75fd7",170]],[Ye.ADDED,["#5faf00",70]],[Ye.REMOVED,["#d70000",160]],[Ye.CODE,["#87afff",111]],[Ye.SIZE,["#ffd700",220]]]),Ns=r=>r,Ry={[Ye.NUMBER]:Ns({pretty:(r,e)=>Dn(r,`${e}`,Ye.NUMBER),json:r=>r}),[Ye.IDENT]:Ns({pretty:(r,e)=>fi(r,e),json:r=>Ot(r)}),[Ye.LOCATOR]:Ns({pretty:(r,e)=>It(r,e),json:r=>Fs(r)}),[Ye.DESCRIPTOR]:Ns({pretty:(r,e)=>sr(r,e),json:r=>Pn(r)}),[Ye.RESOLUTION]:Ns({pretty:(r,{descriptor:e,locator:t})=>Ov(r,e,t),json:({descriptor:r,locator:e})=>({descriptor:Pn(r),locator:e!==null?Fs(e):null})}),[Ye.DEPENDENT]:Ns({pretty:(r,{locator:e,descriptor:t})=>Tv(r,e,t),json:({locator:r,descriptor:e})=>({locator:Fs(r),descriptor:Pn(e)})}),[Ye.PACKAGE_EXTENSION]:Ns({pretty:(r,e)=>{switch(e.type){case wi.Dependency:return`${fi(r,e.parentDescriptor)} \u27A4 ${Dn(r,"dependencies",Ye.CODE)} \u27A4 ${fi(r,e.descriptor)}`;case wi.PeerDependency:return`${fi(r,e.parentDescriptor)} \u27A4 ${Dn(r,"peerDependencies",Ye.CODE)} \u27A4 ${fi(r,e.descriptor)}`;case wi.PeerDependencyMeta:return`${fi(r,e.parentDescriptor)} \u27A4 ${Dn(r,"peerDependenciesMeta",Ye.CODE)} \u27A4 ${fi(r,An(e.selector))} \u27A4 ${Dn(r,e.key,Ye.CODE)}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${e.type}`)}},json:r=>{switch(r.type){case wi.Dependency:return`${Ot(r.parentDescriptor)} > ${Ot(r.descriptor)}`;case wi.PeerDependency:return`${Ot(r.parentDescriptor)} >> ${Ot(r.descriptor)}`;case wi.PeerDependencyMeta:return`${Ot(r.parentDescriptor)} >> ${r.selector} / ${r.key}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${r.type}`)}}}),[Ye.SETTING]:Ns({pretty:(r,e)=>(r.get(e),Ug(r,Dn(r,e,Ye.CODE),`https://yarnpkg.com/configuration/yarnrc#${e}`)),json:r=>r}),[Ye.DURATION]:Ns({pretty:(r,e)=>{if(e>1e3*60){let t=Math.floor(e/1e3/60),i=Math.ceil((e-t*60*1e3)/1e3);return i===0?`${t}m`:`${t}m ${i}s`}else{let t=Math.floor(e/1e3),i=e-t*1e3;return i===0?`${t}s`:`${t}s ${i}ms`}},json:r=>r}),[Ye.SIZE]:Ns({pretty:(r,e)=>{let t=["KB","MB","GB","TB"],i=t.length;for(;i>1&&e<1024**i;)i-=1;let n=1024**i,s=Math.floor(e*100/n)/100;return Dn(r,`${s} ${t[i-1]}`,Ye.NUMBER)},json:r=>r}),[Ye.PATH]:Ns({pretty:(r,e)=>Dn(r,H.fromPortablePath(e),Ye.PATH),json:r=>H.fromPortablePath(r)}),[Ye.MARKDOWN]:Ns({pretty:(r,{text:e,format:t,paragraphs:i})=>Ki(e,{format:t,paragraphs:i}),json:({text:r})=>r})};function po(r,e){return[e,r]}function Fy(r,e,t){return r.get("enableColors")&&t&2&&(e=id.default.bold(e)),e}function Dn(r,e,t){if(!r.get("enableColors"))return e;let i=KBe.get(t);if(i===null)return e;let n=typeof i=="undefined"?t:Mv.level>=3?i[0]:i[1],s=typeof n=="number"?Kv.ansi256(n):n.startsWith("#")?Kv.hex(n):Kv[n];if(typeof s!="function")throw new Error(`Invalid format type ${n}`);return s(e)}var HBe=!!process.env.KONSOLE_VERSION;function Ug(r,e,t){return r.get("enableHyperlinks")?HBe?`]8;;${t}\\${e}]8;;\\`:`]8;;${t}\x07${e}]8;;\x07`:e}function tt(r,e,t){if(e===null)return Dn(r,"null",Ye.NULL);if(Object.prototype.hasOwnProperty.call(Ry,t))return Ry[t].pretty(r,e);if(typeof e!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof e}`);return Dn(r,e,t)}function Hv(r,e,t,{separator:i=", "}={}){return[...e].map(n=>tt(r,n,t)).join(i)}function Mc(r,e){if(r===null)return null;if(Object.prototype.hasOwnProperty.call(Ry,e))return Pv(e),Ry[e].json(r);if(typeof r!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof r}`);return r}function jBe(r,e,[t,i]){return r?Mc(t,i):tt(e,t,i)}function jv(r){return{Check:Dn(r,"\u2713","green"),Cross:Dn(r,"\u2718","red"),Question:Dn(r,"?","cyan")}}function Xo(r,{label:e,value:[t,i]}){return`${tt(r,e,Ye.CODE)}: ${tt(r,t,i)}`}var Co;(function(n){n.Error="error",n.Warning="warning",n.Info="info",n.Discard="discard"})(Co||(Co={}));function sd(r,{configuration:e}){let t=e.get("logFilters"),i=new Map,n=new Map,s=[];for(let g of t){let f=g.get("level");if(typeof f=="undefined")continue;let h=g.get("code");typeof h!="undefined"&&i.set(h,f);let p=g.get("text");typeof p!="undefined"&&n.set(p,f);let m=g.get("pattern");typeof m!="undefined"&&s.push([lJ.default.matcher(m,{contains:!0}),f])}s.reverse();let o=(g,f,h)=>{if(g===null||g===X.UNNAMED)return h;let p=n.size>0||s.length>0?(0,cJ.default)(f):f;if(n.size>0){let m=n.get(p);if(typeof m!="undefined")return m!=null?m:h}if(s.length>0){for(let[m,y]of s)if(m(p))return y!=null?y:h}if(i.size>0){let m=i.get(VA(g));if(typeof m!="undefined")return m!=null?m:h}return h},a=r.reportInfo,l=r.reportWarning,c=r.reportError,u=function(g,f,h,p){switch(o(f,h,p)){case Co.Info:a.call(g,f,h);break;case Co.Warning:l.call(g,f!=null?f:X.UNNAMED,h);break;case Co.Error:c.call(g,f!=null?f:X.UNNAMED,h);break}};r.reportInfo=function(...g){return u(this,...g,Co.Info)},r.reportWarning=function(...g){return u(this,...g,Co.Warning)},r.reportError=function(...g){return u(this,...g,Co.Error)}}var Rn={};ft(Rn,{checksumFile:()=>ow,checksumPattern:()=>aw,makeHash:()=>ln});var sw=ge(require("crypto")),_k=ge(zk());function ln(...r){let e=(0,sw.createHash)("sha512"),t="";for(let i of r)typeof i=="string"?t+=i:i&&(t&&(e.update(t),t=""),e.update(i));return t&&e.update(t),e.digest("hex")}async function ow(r,{baseFs:e,algorithm:t}={baseFs:U,algorithm:"sha512"}){let i=await e.openPromise(r,"r");try{let n=65536,s=Buffer.allocUnsafeSlow(n),o=(0,sw.createHash)(t),a=0;for(;(a=await e.readPromise(i,s,0,n))!==0;)o.update(a===n?s:s.slice(0,a));return o.digest("hex")}finally{await e.closePromise(i)}}async function aw(r,{cwd:e}){let i=(await(0,_k.default)(r,{cwd:H.fromPortablePath(e),expandDirectories:!1,onlyDirectories:!0,unique:!0})).map(a=>`${a}/**/*`),n=await(0,_k.default)([r,...i],{cwd:H.fromPortablePath(e),expandDirectories:!1,onlyFiles:!1,unique:!0});n.sort();let s=await Promise.all(n.map(async a=>{let l=[Buffer.from(a)],c=H.toPortablePath(a),u=await U.lstatPromise(c);return u.isSymbolicLink()?l.push(Buffer.from(await U.readlinkPromise(c))):u.isFile()&&l.push(await U.readFilePromise(c)),l.join("\0")})),o=(0,sw.createHash)("sha512");for(let a of s)o.update(a);return o.digest("hex")}var ld="virtual:",nSe=5,W3=/(os|cpu|libc)=([a-z0-9_-]+)/,sSe=(0,J3.makeParser)(W3);function ea(r,e){if(r==null?void 0:r.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:ln(r,e),scope:r,name:e}}function rr(r,e){return{identHash:r.identHash,scope:r.scope,name:r.name,descriptorHash:ln(r.identHash,e),range:e}}function cn(r,e){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:ln(r.identHash,e),reference:e}}function oSe(r){return{identHash:r.identHash,scope:r.scope,name:r.name}}function lw(r){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:r.descriptorHash,reference:r.range}}function Vk(r){return{identHash:r.identHash,scope:r.scope,name:r.name,descriptorHash:r.locatorHash,range:r.reference}}function aSe(r){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:r.locatorHash,reference:r.reference}}function cd(r,e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference,version:r.version,languageName:r.languageName,linkType:r.linkType,conditions:r.conditions,dependencies:new Map(r.dependencies),peerDependencies:new Map(r.peerDependencies),dependenciesMeta:new Map(r.dependenciesMeta),peerDependenciesMeta:new Map(r.peerDependenciesMeta),bin:new Map(r.bin)}}function ud(r){return cd(r,r)}function Xk(r,e){if(e.includes("#"))throw new Error("Invalid entropy");return rr(r,`virtual:${e}#${r.range}`)}function Zk(r,e){if(e.includes("#"))throw new Error("Invalid entropy");return cd(r,cn(r,`virtual:${e}#${r.reference}`))}function ll(r){return r.range.startsWith(ld)}function ta(r){return r.reference.startsWith(ld)}function gd(r){if(!ll(r))throw new Error("Not a virtual descriptor");return rr(r,r.range.replace(/^[^#]*#/,""))}function fd(r){if(!ta(r))throw new Error("Not a virtual descriptor");return cn(r,r.reference.replace(/^[^#]*#/,""))}function ASe(r,e){return r.range.includes("::")?r:rr(r,`${r.range}::${qg.default.stringify(e)}`)}function lSe(r,e){return r.reference.includes("::")?r:cn(r,`${r.reference}::${qg.default.stringify(e)}`)}function hd(r,e){return r.identHash===e.identHash}function z3(r,e){return r.descriptorHash===e.descriptorHash}function pd(r,e){return r.locatorHash===e.locatorHash}function cSe(r,e){if(!ta(r))throw new Error("Invalid package type");if(!ta(e))throw new Error("Invalid package type");if(!hd(r,e)||r.dependencies.size!==e.dependencies.size)return!1;for(let t of r.dependencies.values()){let i=e.dependencies.get(t.identHash);if(!i||!z3(t,i))return!1}return!0}function An(r){let e=_3(r);if(!e)throw new Error(`Invalid ident (${r})`);return e}function _3(r){let e=r.match(/^(?:@([^/]+?)\/)?([^/]+)$/);if(!e)return null;let[,t,i]=e,n=typeof t!="undefined"?t:null;return ea(n,i)}function cl(r,e=!1){let t=dd(r,e);if(!t)throw new Error(`Invalid descriptor (${r})`);return t}function dd(r,e=!1){let t=e?r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!t)return null;let[,i,n,s]=t;if(s==="unknown")throw new Error(`Invalid range (${r})`);let o=typeof i!="undefined"?i:null,a=typeof s!="undefined"?s:"unknown";return rr(ea(o,n),a)}function qc(r,e=!1){let t=cw(r,e);if(!t)throw new Error(`Invalid locator (${r})`);return t}function cw(r,e=!1){let t=e?r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!t)return null;let[,i,n,s]=t;if(s==="unknown")throw new Error(`Invalid reference (${r})`);let o=typeof i!="undefined"?i:null,a=typeof s!="undefined"?s:"unknown";return cn(ea(o,n),a)}function Jg(r,e){let t=r.match(/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/);if(t===null)throw new Error(`Invalid range (${r})`);let i=typeof t[1]!="undefined"?t[1]:null;if(typeof(e==null?void 0:e.requireProtocol)=="string"&&i!==e.requireProtocol)throw new Error(`Invalid protocol (${i})`);if((e==null?void 0:e.requireProtocol)&&i===null)throw new Error(`Missing protocol (${i})`);let n=typeof t[3]!="undefined"?decodeURIComponent(t[2]):null;if((e==null?void 0:e.requireSource)&&n===null)throw new Error(`Missing source (${r})`);let s=typeof t[3]!="undefined"?decodeURIComponent(t[3]):decodeURIComponent(t[2]),o=(e==null?void 0:e.parseSelector)?qg.default.parse(s):s,a=typeof t[4]!="undefined"?qg.default.parse(t[4]):null;return{protocol:i,source:n,selector:o,params:a}}function uSe(r,{protocol:e}){let{selector:t,params:i}=Jg(r,{requireProtocol:e,requireBindings:!0});if(typeof i.locator!="string")throw new Error(`Assertion failed: Invalid bindings for ${r}`);return{parentLocator:qc(i.locator,!0),path:t}}function V3(r){return r=r.replace(/%/g,"%25"),r=r.replace(/:/g,"%3A"),r=r.replace(/#/g,"%23"),r}function gSe(r){return r===null?!1:Object.entries(r).length>0}function uw({protocol:r,source:e,selector:t,params:i}){let n="";return r!==null&&(n+=`${r}`),e!==null&&(n+=`${V3(e)}#`),n+=V3(t),gSe(i)&&(n+=`::${qg.default.stringify(i)}`),n}function fSe(r){let{params:e,protocol:t,source:i,selector:n}=Jg(r);for(let s in e)s.startsWith("__")&&delete e[s];return uw({protocol:t,source:i,params:e,selector:n})}function Ot(r){return r.scope?`@${r.scope}/${r.name}`:`${r.name}`}function Pn(r){return r.scope?`@${r.scope}/${r.name}@${r.range}`:`${r.name}@${r.range}`}function Fs(r){return r.scope?`@${r.scope}/${r.name}@${r.reference}`:`${r.name}@${r.reference}`}function $k(r){return r.scope!==null?`@${r.scope}-${r.name}`:r.name}function Wg(r){let{protocol:e,selector:t}=Jg(r.reference),i=e!==null?e.replace(/:$/,""):"exotic",n=q3.default.valid(t),s=n!==null?`${i}-${n}`:`${i}`,o=10,a=r.scope?`${$k(r)}-${s}-${r.locatorHash.slice(0,o)}`:`${$k(r)}-${s}-${r.locatorHash.slice(0,o)}`;return Jr(a)}function fi(r,e){return e.scope?`${tt(r,`@${e.scope}/`,Ye.SCOPE)}${tt(r,e.name,Ye.NAME)}`:`${tt(r,e.name,Ye.NAME)}`}function gw(r){if(r.startsWith(ld)){let e=gw(r.substring(r.indexOf("#")+1)),t=r.substring(ld.length,ld.length+nSe);return`${e} [${t}]`}else return r.replace(/\?.*/,"?[...]")}function Aw(r,e){return`${tt(r,gw(e),Ye.RANGE)}`}function sr(r,e){return`${fi(r,e)}${tt(r,"@",Ye.RANGE)}${Aw(r,e.range)}`}function Cd(r,e){return`${tt(r,gw(e),Ye.REFERENCE)}`}function It(r,e){return`${fi(r,e)}${tt(r,"@",Ye.REFERENCE)}${Cd(r,e.reference)}`}function ex(r){return`${Ot(r)}@${gw(r.reference)}`}function zg(r){return xn(r,[e=>Ot(e),e=>e.range])}function md(r,e){return fi(r,e.locator)}function Ov(r,e,t){let i=ll(e)?gd(e):e;return t===null?`${sr(r,i)} \u2192 ${jv(r).Cross}`:i.identHash===t.identHash?`${sr(r,i)} \u2192 ${Cd(r,t.reference)}`:`${sr(r,i)} \u2192 ${It(r,t)}`}function Tv(r,e,t){return t===null?`${It(r,e)}`:`${It(r,e)} (via ${Aw(r,t.range)})`}function tx(r){return`node_modules/${Ot(r)}`}function fw(r,e){return r.conditions?sSe(r.conditions,t=>{let[,i,n]=t.match(W3),s=e[i];return s?s.includes(n):!0}):!0}var X3={hooks:{reduceDependency:(r,e,t,i,{resolver:n,resolveOptions:s})=>{for(let{pattern:o,reference:a}of e.topLevelWorkspace.manifest.resolutions){if(o.from&&o.from.fullName!==Ot(t)||o.from&&o.from.description&&o.from.description!==t.reference||o.descriptor.fullName!==Ot(r)||o.descriptor.description&&o.descriptor.description!==r.range)continue;return n.bindDescriptor(rr(r,a),e.topLevelWorkspace.anchoredLocator,s)}return r},validateProject:async(r,e)=>{for(let t of r.workspaces){let i=md(r.configuration,t);await r.configuration.triggerHook(n=>n.validateWorkspace,t,{reportWarning:(n,s)=>e.reportWarning(n,`${i}: ${s}`),reportError:(n,s)=>e.reportError(n,`${i}: ${s}`)})}},validateWorkspace:async(r,e)=>{let{manifest:t}=r;t.resolutions.length&&r.cwd!==r.project.cwd&&t.errors.push(new Error("Resolutions field will be ignored"));for(let i of t.errors)e.reportWarning(X.INVALID_MANIFEST,i.message)}}};var t4=ge(ri());var Ed=class{supportsDescriptor(e,t){return!!(e.range.startsWith(Ed.protocol)||t.project.tryWorkspaceByDescriptor(e)!==null)}supportsLocator(e,t){return!!e.reference.startsWith(Ed.protocol)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){return[i.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,t,i){return null}async resolve(e,t){let i=t.project.getWorkspaceByCwd(e.reference.slice(Ed.protocol.length));return te(N({},e),{version:i.manifest.version||"0.0.0",languageName:"unknown",linkType:Qt.SOFT,conditions:null,dependencies:new Map([...i.manifest.dependencies,...i.manifest.devDependencies]),peerDependencies:new Map([...i.manifest.peerDependencies]),dependenciesMeta:i.manifest.dependenciesMeta,peerDependenciesMeta:i.manifest.peerDependenciesMeta,bin:i.manifest.bin})}},oi=Ed;oi.protocol="workspace:";var Wt={};ft(Wt,{SemVer:()=>Z3.SemVer,clean:()=>pSe,satisfiesWithPrereleases:()=>Jc,validRange:()=>mo});var hw=ge(ri()),Z3=ge(ri()),$3=new Map;function Jc(r,e,t=!1){if(!r)return!1;let i=`${e}${t}`,n=$3.get(i);if(typeof n=="undefined")try{n=new hw.default.Range(e,{includePrerelease:!0,loose:t})}catch{return!1}finally{$3.set(i,n||null)}else if(n===null)return!1;let s;try{s=new hw.default.SemVer(r,n)}catch(o){return!1}return n.test(s)?!0:(s.prerelease&&(s.prerelease=[]),n.set.some(o=>{for(let a of o)a.semver.prerelease&&(a.semver.prerelease=[]);return o.every(a=>a.test(s))}))}var e4=new Map;function mo(r){if(r.indexOf(":")!==-1)return null;let e=e4.get(r);if(typeof e!="undefined")return e;try{e=new hw.default.Range(r)}catch{e=null}return e4.set(r,e),e}var hSe=/^(?:[\sv=]*?)((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\s*)$/;function pSe(r){let e=hSe.exec(r);return e?e[1]:null}var ul=class{constructor(){this.indent=" ";this.name=null;this.version=null;this.os=null;this.cpu=null;this.libc=null;this.type=null;this.packageManager=null;this.private=!1;this.license=null;this.main=null;this.module=null;this.browser=null;this.languageName=null;this.bin=new Map;this.scripts=new Map;this.dependencies=new Map;this.devDependencies=new Map;this.peerDependencies=new Map;this.workspaceDefinitions=[];this.dependenciesMeta=new Map;this.peerDependenciesMeta=new Map;this.resolutions=[];this.files=null;this.publishConfig=null;this.installConfig=null;this.preferUnplugged=null;this.raw={};this.errors=[]}static async tryFind(e,{baseFs:t=new ar}={}){let i=x.join(e,"package.json");try{return await ul.fromFile(i,{baseFs:t})}catch(n){if(n.code==="ENOENT")return null;throw n}}static async find(e,{baseFs:t}={}){let i=await ul.tryFind(e,{baseFs:t});if(i===null)throw new Error("Manifest not found");return i}static async fromFile(e,{baseFs:t=new ar}={}){let i=new ul;return await i.loadFile(e,{baseFs:t}),i}static fromText(e){let t=new ul;return t.loadFromText(e),t}static isManifestFieldCompatible(e,t){if(e===null)return!0;let i=!0,n=!1;for(let s of e)if(s[0]==="!"){if(n=!0,t===s.slice(1))return!1}else if(i=!1,s===t)return!0;return n&&i}loadFromText(e){let t;try{t=JSON.parse(i4(e)||"{}")}catch(i){throw i.message+=` (when parsing ${e})`,i}this.load(t),this.indent=r4(e)}async loadFile(e,{baseFs:t=new ar}){let i=await t.readFilePromise(e,"utf8"),n;try{n=JSON.parse(i4(i)||"{}")}catch(s){throw s.message+=` (when parsing ${e})`,s}this.load(n),this.indent=r4(i)}load(e,{yamlCompatibilityMode:t=!1}={}){if(typeof e!="object"||e===null)throw new Error(`Utterly invalid manifest data (${e})`);this.raw=e;let i=[];if(this.name=null,typeof e.name=="string")try{this.name=An(e.name)}catch(s){i.push(new Error("Parsing failed for the 'name' field"))}if(typeof e.version=="string"?this.version=e.version:this.version=null,Array.isArray(e.os)){let s=[];this.os=s;for(let o of e.os)typeof o!="string"?i.push(new Error("Parsing failed for the 'os' field")):s.push(o)}else this.os=null;if(Array.isArray(e.cpu)){let s=[];this.cpu=s;for(let o of e.cpu)typeof o!="string"?i.push(new Error("Parsing failed for the 'cpu' field")):s.push(o)}else this.cpu=null;if(Array.isArray(e.libc)){let s=[];this.libc=s;for(let o of e.libc)typeof o!="string"?i.push(new Error("Parsing failed for the 'libc' field")):s.push(o)}else this.libc=null;if(typeof e.type=="string"?this.type=e.type:this.type=null,typeof e.packageManager=="string"?this.packageManager=e.packageManager:this.packageManager=null,typeof e.private=="boolean"?this.private=e.private:this.private=!1,typeof e.license=="string"?this.license=e.license:this.license=null,typeof e.languageName=="string"?this.languageName=e.languageName:this.languageName=null,typeof e.main=="string"?this.main=un(e.main):this.main=null,typeof e.module=="string"?this.module=un(e.module):this.module=null,e.browser!=null)if(typeof e.browser=="string")this.browser=un(e.browser);else{this.browser=new Map;for(let[s,o]of Object.entries(e.browser))this.browser.set(un(s),typeof o=="string"?un(o):o)}else this.browser=null;if(this.bin=new Map,typeof e.bin=="string")this.name!==null?this.bin.set(this.name.name,un(e.bin)):i.push(new Error("String bin field, but no attached package name"));else if(typeof e.bin=="object"&&e.bin!==null)for(let[s,o]of Object.entries(e.bin)){if(typeof o!="string"){i.push(new Error(`Invalid bin definition for '${s}'`));continue}let a=An(s);this.bin.set(a.name,un(o))}if(this.scripts=new Map,typeof e.scripts=="object"&&e.scripts!==null)for(let[s,o]of Object.entries(e.scripts)){if(typeof o!="string"){i.push(new Error(`Invalid script definition for '${s}'`));continue}this.scripts.set(s,o)}if(this.dependencies=new Map,typeof e.dependencies=="object"&&e.dependencies!==null)for(let[s,o]of Object.entries(e.dependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=An(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=rr(a,o);this.dependencies.set(l.identHash,l)}if(this.devDependencies=new Map,typeof e.devDependencies=="object"&&e.devDependencies!==null)for(let[s,o]of Object.entries(e.devDependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=An(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=rr(a,o);this.devDependencies.set(l.identHash,l)}if(this.peerDependencies=new Map,typeof e.peerDependencies=="object"&&e.peerDependencies!==null)for(let[s,o]of Object.entries(e.peerDependencies)){let a;try{a=An(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}(typeof o!="string"||!o.startsWith(oi.protocol)&&!mo(o))&&(i.push(new Error(`Invalid dependency range for '${s}'`)),o="*");let l=rr(a,o);this.peerDependencies.set(l.identHash,l)}typeof e.workspaces=="object"&&e.workspaces!==null&&e.workspaces.nohoist&&i.push(new Error("'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead"));let n=Array.isArray(e.workspaces)?e.workspaces:typeof e.workspaces=="object"&&e.workspaces!==null&&Array.isArray(e.workspaces.packages)?e.workspaces.packages:[];this.workspaceDefinitions=[];for(let s of n){if(typeof s!="string"){i.push(new Error(`Invalid workspace definition for '${s}'`));continue}this.workspaceDefinitions.push({pattern:s})}if(this.dependenciesMeta=new Map,typeof e.dependenciesMeta=="object"&&e.dependenciesMeta!==null)for(let[s,o]of Object.entries(e.dependenciesMeta)){if(typeof o!="object"||o===null){i.push(new Error(`Invalid meta field for '${s}`));continue}let a=cl(s),l=this.ensureDependencyMeta(a),c=pw(o.built,{yamlCompatibilityMode:t});if(c===null){i.push(new Error(`Invalid built meta field for '${s}'`));continue}let u=pw(o.optional,{yamlCompatibilityMode:t});if(u===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}let g=pw(o.unplugged,{yamlCompatibilityMode:t});if(g===null){i.push(new Error(`Invalid unplugged meta field for '${s}'`));continue}Object.assign(l,{built:c,optional:u,unplugged:g})}if(this.peerDependenciesMeta=new Map,typeof e.peerDependenciesMeta=="object"&&e.peerDependenciesMeta!==null)for(let[s,o]of Object.entries(e.peerDependenciesMeta)){if(typeof o!="object"||o===null){i.push(new Error(`Invalid meta field for '${s}'`));continue}let a=cl(s),l=this.ensurePeerDependencyMeta(a),c=pw(o.optional,{yamlCompatibilityMode:t});if(c===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}Object.assign(l,{optional:c})}if(this.resolutions=[],typeof e.resolutions=="object"&&e.resolutions!==null)for(let[s,o]of Object.entries(e.resolutions)){if(typeof o!="string"){i.push(new Error(`Invalid resolution entry for '${s}'`));continue}try{this.resolutions.push({pattern:eI(s),reference:o})}catch(a){i.push(a);continue}}if(Array.isArray(e.files)){this.files=new Set;for(let s of e.files){if(typeof s!="string"){i.push(new Error(`Invalid files entry for '${s}'`));continue}this.files.add(s)}}else this.files=null;if(typeof e.publishConfig=="object"&&e.publishConfig!==null){if(this.publishConfig={},typeof e.publishConfig.access=="string"&&(this.publishConfig.access=e.publishConfig.access),typeof e.publishConfig.main=="string"&&(this.publishConfig.main=un(e.publishConfig.main)),typeof e.publishConfig.module=="string"&&(this.publishConfig.module=un(e.publishConfig.module)),e.publishConfig.browser!=null)if(typeof e.publishConfig.browser=="string")this.publishConfig.browser=un(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(let[s,o]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set(un(s),typeof o=="string"?un(o):o)}if(typeof e.publishConfig.registry=="string"&&(this.publishConfig.registry=e.publishConfig.registry),typeof e.publishConfig.bin=="string")this.name!==null?this.publishConfig.bin=new Map([[this.name.name,un(e.publishConfig.bin)]]):i.push(new Error("String bin field, but no attached package name"));else if(typeof e.publishConfig.bin=="object"&&e.publishConfig.bin!==null){this.publishConfig.bin=new Map;for(let[s,o]of Object.entries(e.publishConfig.bin)){if(typeof o!="string"){i.push(new Error(`Invalid bin definition for '${s}'`));continue}this.publishConfig.bin.set(s,un(o))}}if(Array.isArray(e.publishConfig.executableFiles)){this.publishConfig.executableFiles=new Set;for(let s of e.publishConfig.executableFiles){if(typeof s!="string"){i.push(new Error("Invalid executable file definition"));continue}this.publishConfig.executableFiles.add(un(s))}}}else this.publishConfig=null;if(typeof e.installConfig=="object"&&e.installConfig!==null){this.installConfig={};for(let s of Object.keys(e.installConfig))s==="hoistingLimits"?typeof e.installConfig.hoistingLimits=="string"?this.installConfig.hoistingLimits=e.installConfig.hoistingLimits:i.push(new Error("Invalid hoisting limits definition")):s=="selfReferences"?typeof e.installConfig.selfReferences=="boolean"?this.installConfig.selfReferences=e.installConfig.selfReferences:i.push(new Error("Invalid selfReferences definition, must be a boolean value")):i.push(new Error(`Unrecognized installConfig key: ${s}`))}else this.installConfig=null;if(typeof e.optionalDependencies=="object"&&e.optionalDependencies!==null)for(let[s,o]of Object.entries(e.optionalDependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=An(s)}catch(g){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=rr(a,o);this.dependencies.set(l.identHash,l);let c=rr(a,"unknown"),u=this.ensureDependencyMeta(c);Object.assign(u,{optional:!0})}typeof e.preferUnplugged=="boolean"?this.preferUnplugged=e.preferUnplugged:this.preferUnplugged=null,this.errors=i}getForScope(e){switch(e){case"dependencies":return this.dependencies;case"devDependencies":return this.devDependencies;case"peerDependencies":return this.peerDependencies;default:throw new Error(`Unsupported value ("${e}")`)}}hasConsumerDependency(e){return!!(this.dependencies.has(e.identHash)||this.peerDependencies.has(e.identHash))}hasHardDependency(e){return!!(this.dependencies.has(e.identHash)||this.devDependencies.has(e.identHash))}hasSoftDependency(e){return!!this.peerDependencies.has(e.identHash)}hasDependency(e){return!!(this.hasHardDependency(e)||this.hasSoftDependency(e))}getConditions(){let e=[];return this.os&&this.os.length>0&&e.push(rx("os",this.os)),this.cpu&&this.cpu.length>0&&e.push(rx("cpu",this.cpu)),this.libc&&this.libc.length>0&&e.push(rx("libc",this.libc)),e.length>0?e.join(" & "):null}isCompatibleWithOS(e){return ul.isManifestFieldCompatible(this.os,e)}isCompatibleWithCPU(e){return ul.isManifestFieldCompatible(this.cpu,e)}ensureDependencyMeta(e){if(e.range!=="unknown"&&!t4.default.valid(e.range))throw new Error(`Invalid meta field range for '${Pn(e)}'`);let t=Ot(e),i=e.range!=="unknown"?e.range:null,n=this.dependenciesMeta.get(t);n||this.dependenciesMeta.set(t,n=new Map);let s=n.get(i);return s||n.set(i,s={}),s}ensurePeerDependencyMeta(e){if(e.range!=="unknown")throw new Error(`Invalid meta field range for '${Pn(e)}'`);let t=Ot(e),i=this.peerDependenciesMeta.get(t);return i||this.peerDependenciesMeta.set(t,i={}),i}setRawField(e,t,{after:i=[]}={}){let n=new Set(i.filter(s=>Object.prototype.hasOwnProperty.call(this.raw,s)));if(n.size===0||Object.prototype.hasOwnProperty.call(this.raw,e))this.raw[e]=t;else{let s=this.raw,o=this.raw={},a=!1;for(let l of Object.keys(s))o[l]=s[l],a||(n.delete(l),n.size===0&&(o[e]=t,a=!0))}}exportTo(e,{compatibilityMode:t=!0}={}){var s;if(Object.assign(e,this.raw),this.name!==null?e.name=Ot(this.name):delete e.name,this.version!==null?e.version=this.version:delete e.version,this.os!==null?e.os=this.os:delete e.os,this.cpu!==null?e.cpu=this.cpu:delete e.cpu,this.type!==null?e.type=this.type:delete e.type,this.packageManager!==null?e.packageManager=this.packageManager:delete e.packageManager,this.private?e.private=!0:delete e.private,this.license!==null?e.license=this.license:delete e.license,this.languageName!==null?e.languageName=this.languageName:delete e.languageName,this.main!==null?e.main=this.main:delete e.main,this.module!==null?e.module=this.module:delete e.module,this.browser!==null){let o=this.browser;typeof o=="string"?e.browser=o:o instanceof Map&&(e.browser=Object.assign({},...Array.from(o.keys()).sort().map(a=>({[a]:o.get(a)}))))}else delete e.browser;this.bin.size===1&&this.name!==null&&this.bin.has(this.name.name)?e.bin=this.bin.get(this.name.name):this.bin.size>0?e.bin=Object.assign({},...Array.from(this.bin.keys()).sort().map(o=>({[o]:this.bin.get(o)}))):delete e.bin,this.workspaceDefinitions.length>0?this.raw.workspaces&&!Array.isArray(this.raw.workspaces)?e.workspaces=te(N({},this.raw.workspaces),{packages:this.workspaceDefinitions.map(({pattern:o})=>o)}):e.workspaces=this.workspaceDefinitions.map(({pattern:o})=>o):this.raw.workspaces&&!Array.isArray(this.raw.workspaces)&&Object.keys(this.raw.workspaces).length>0?e.workspaces=this.raw.workspaces:delete e.workspaces;let i=[],n=[];for(let o of this.dependencies.values()){let a=this.dependenciesMeta.get(Ot(o)),l=!1;if(t&&a){let c=a.get(null);c&&c.optional&&(l=!0)}l?n.push(o):i.push(o)}i.length>0?e.dependencies=Object.assign({},...zg(i).map(o=>({[Ot(o)]:o.range}))):delete e.dependencies,n.length>0?e.optionalDependencies=Object.assign({},...zg(n).map(o=>({[Ot(o)]:o.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...zg(this.devDependencies.values()).map(o=>({[Ot(o)]:o.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...zg(this.peerDependencies.values()).map(o=>({[Ot(o)]:o.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(let[o,a]of xn(this.dependenciesMeta.entries(),([l,c])=>l))for(let[l,c]of xn(a.entries(),([u,g])=>u!==null?`0${u}`:"1")){let u=l!==null?Pn(rr(An(o),l)):o,g=N({},c);t&&l===null&&delete g.optional,Object.keys(g).length!==0&&(e.dependenciesMeta[u]=g)}if(Object.keys(e.dependenciesMeta).length===0&&delete e.dependenciesMeta,this.peerDependenciesMeta.size>0?e.peerDependenciesMeta=Object.assign({},...xn(this.peerDependenciesMeta.entries(),([o,a])=>o).map(([o,a])=>({[o]:a}))):delete e.peerDependenciesMeta,this.resolutions.length>0?e.resolutions=Object.assign({},...this.resolutions.map(({pattern:o,reference:a})=>({[tI(o)]:a}))):delete e.resolutions,this.files!==null?e.files=Array.from(this.files):delete e.files,this.preferUnplugged!==null?e.preferUnplugged=this.preferUnplugged:delete e.preferUnplugged,this.scripts!==null&&this.scripts.size>0){(s=e.scripts)!=null||(e.scripts={});for(let o of Object.keys(e.scripts))this.scripts.has(o)||delete e.scripts[o];for(let[o,a]of this.scripts.entries())e.scripts[o]=a}else delete e.scripts;return e}},At=ul;At.fileName="package.json",At.allDependencies=["dependencies","devDependencies","peerDependencies"],At.hardDependencies=["dependencies","devDependencies"];function r4(r){let e=r.match(/^[ \t]+/m);return e?e[0]:" "}function i4(r){return r.charCodeAt(0)===65279?r.slice(1):r}function un(r){return r.replace(/\\/g,"/")}function pw(r,{yamlCompatibilityMode:e}){return e?Lv(r):typeof r=="undefined"||typeof r=="boolean"?r:null}function n4(r,e){let t=e.search(/[^!]/);if(t===-1)return"invalid";let i=t%2==0?"":"!",n=e.slice(t);return`${i}${r}=${n}`}function rx(r,e){return e.length===1?n4(r,e[0]):`(${e.map(t=>n4(r,t)).join(" | ")})`}var L4=ge(N4()),T4=ge(require("stream")),O4=ge(require("string_decoder"));var Ave=15,ct=class extends Error{constructor(e,t,i){super(t);this.reportExtra=i;this.reportCode=e}};function lve(r){return typeof r.reportCode!="undefined"}var Ji=class{constructor(){this.reportedInfos=new Set;this.reportedWarnings=new Set;this.reportedErrors=new Set}static progressViaCounter(e){let t=0,i,n=new Promise(l=>{i=l}),s=l=>{let c=i;n=new Promise(u=>{i=u}),t=l,c()},o=(l=0)=>{s(t+1)},a=async function*(){for(;t<e;)await n,yield{progress:t/e}}();return{[Symbol.asyncIterator](){return a},hasProgress:!0,hasTitle:!1,set:s,tick:o}}static progressViaTitle(){let e,t,i=new Promise(o=>{t=o}),n=(0,L4.default)(o=>{let a=t;i=new Promise(l=>{t=l}),e=o,a()},1e3/Ave),s=async function*(){for(;;)await i,yield{title:e}}();return{[Symbol.asyncIterator](){return s},hasProgress:!1,hasTitle:!0,setTitle:n}}async startProgressPromise(e,t){let i=this.reportProgress(e);try{return await t(e)}finally{i.stop()}}startProgressSync(e,t){let i=this.reportProgress(e);try{return t(e)}finally{i.stop()}}reportInfoOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedInfos.has(n)||(this.reportedInfos.add(n),this.reportInfo(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportWarningOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedWarnings.has(n)||(this.reportedWarnings.add(n),this.reportWarning(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportErrorOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedErrors.has(n)||(this.reportedErrors.add(n),this.reportError(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportExceptionOnce(e){lve(e)?this.reportErrorOnce(e.reportCode,e.message,{key:e,reportExtra:e.reportExtra}):this.reportErrorOnce(X.EXCEPTION,e.stack||e.message,{key:e})}createStreamReporter(e=null){let t=new T4.PassThrough,i=new O4.StringDecoder,n="";return t.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` -`),a!==-1){let l=n+o.substring(0,a);o=o.substring(a+1),n="",e!==null?this.reportInfo(null,`${e} ${l}`):this.reportInfo(null,l)}while(a!==-1);n+=o}),t.on("end",()=>{let s=i.end();s!==""&&(e!==null?this.reportInfo(null,`${e} ${s}`):this.reportInfo(null,s))}),t}};var wd=class{constructor(e){this.fetchers=e}supports(e,t){return!!this.tryFetcher(e,t)}getLocalPath(e,t){return this.getFetcher(e,t).getLocalPath(e,t)}async fetch(e,t){return await this.getFetcher(e,t).fetch(e,t)}tryFetcher(e,t){let i=this.fetchers.find(n=>n.supports(e,t));return i||null}getFetcher(e,t){let i=this.fetchers.find(n=>n.supports(e,t));if(!i)throw new ct(X.FETCHER_NOT_FOUND,`${It(t.project.configuration,e)} isn't supported by any available fetcher`);return i}};var Bd=class{constructor(e){this.resolvers=e.filter(t=>t)}supportsDescriptor(e,t){return!!this.tryResolverByDescriptor(e,t)}supportsLocator(e,t){return!!this.tryResolverByLocator(e,t)}shouldPersistResolution(e,t){return this.getResolverByLocator(e,t).shouldPersistResolution(e,t)}bindDescriptor(e,t,i){return this.getResolverByDescriptor(e,i).bindDescriptor(e,t,i)}getResolutionDependencies(e,t){return this.getResolverByDescriptor(e,t).getResolutionDependencies(e,t)}async getCandidates(e,t,i){return await this.getResolverByDescriptor(e,i).getCandidates(e,t,i)}async getSatisfying(e,t,i){return this.getResolverByDescriptor(e,i).getSatisfying(e,t,i)}async resolve(e,t){return await this.getResolverByLocator(e,t).resolve(e,t)}tryResolverByDescriptor(e,t){let i=this.resolvers.find(n=>n.supportsDescriptor(e,t));return i||null}getResolverByDescriptor(e,t){let i=this.resolvers.find(n=>n.supportsDescriptor(e,t));if(!i)throw new Error(`${sr(t.project.configuration,e)} isn't supported by any available resolver`);return i}tryResolverByLocator(e,t){let i=this.resolvers.find(n=>n.supportsLocator(e,t));return i||null}getResolverByLocator(e,t){let i=this.resolvers.find(n=>n.supportsLocator(e,t));if(!i)throw new Error(`${It(t.project.configuration,e)} isn't supported by any available resolver`);return i}};var M4=ge(ri());var _g=/^(?!v)[a-z0-9._-]+$/i,sx=class{supportsDescriptor(e,t){return!!(mo(e.range)||_g.test(e.range))}supportsLocator(e,t){return!!(M4.default.valid(e.reference)||_g.test(e.reference))}shouldPersistResolution(e,t){return t.resolver.shouldPersistResolution(this.forwardLocator(e,t),t)}bindDescriptor(e,t,i){return i.resolver.bindDescriptor(this.forwardDescriptor(e,i),t,i)}getResolutionDependencies(e,t){return t.resolver.getResolutionDependencies(this.forwardDescriptor(e,t),t)}async getCandidates(e,t,i){return await i.resolver.getCandidates(this.forwardDescriptor(e,i),t,i)}async getSatisfying(e,t,i){return await i.resolver.getSatisfying(this.forwardDescriptor(e,i),t,i)}async resolve(e,t){let i=await t.resolver.resolve(this.forwardLocator(e,t),t);return cd(i,e)}forwardDescriptor(e,t){return rr(e,`${t.project.configuration.get("defaultProtocol")}${e.range}`)}forwardLocator(e,t){return cn(e,`${t.project.configuration.get("defaultProtocol")}${e.reference}`)}};var bd=class{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,t){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=cn(e,n);return t.fetcher.getLocalPath(s,t)}async fetch(e,t){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=cn(e,n),o=await t.fetcher.fetch(s,t);return await this.ensureVirtualLink(e,o,t)}getLocatorFilename(e){return Wg(e)}async ensureVirtualLink(e,t,i){let n=t.packageFs.getRealPath(),s=i.project.configuration.get("virtualFolder"),o=this.getLocatorFilename(e),a=Wr.makeVirtualPath(s,o,n),l=new La(a,{baseFs:t.packageFs,pathUtils:x});return te(N({},t),{packageFs:l})}};var Vg=class{static isVirtualDescriptor(e){return!!e.range.startsWith(Vg.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(Vg.protocol)}supportsDescriptor(e,t){return Vg.isVirtualDescriptor(e)}supportsLocator(e,t){return Vg.isVirtualLocator(e)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,t){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,t,i){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,t,i){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,t){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}},dw=Vg;dw.protocol="virtual:";var Qd=class{supports(e){return!!e.reference.startsWith(oi.protocol)}getLocalPath(e,t){return this.getWorkspace(e,t).cwd}async fetch(e,t){let i=this.getWorkspace(e,t).cwd;return{packageFs:new _t(i),prefixPath:Me.dot,localPath:i}}getWorkspace(e,t){return t.project.getWorkspaceByCwd(e.reference.slice(oi.protocol.length))}};var ox={};ft(ox,{getDefaultGlobalFolder:()=>Ax,getHomeFolder:()=>Sd,isFolderInside:()=>lx});var ax=ge(require("os"));function Ax(){if(process.platform==="win32"){let r=H.toPortablePath(process.env.LOCALAPPDATA||H.join((0,ax.homedir)(),"AppData","Local"));return x.resolve(r,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){let r=H.toPortablePath(process.env.XDG_DATA_HOME);return x.resolve(r,"yarn/berry")}return x.resolve(Sd(),".yarn/berry")}function Sd(){return H.toPortablePath((0,ax.homedir)()||"/usr/local/share")}function lx(r,e){let t=x.relative(e,r);return t&&!t.startsWith("..")&&!x.isAbsolute(t)}var Xg={};ft(Xg,{builtinModules:()=>cx,getArchitecture:()=>vd,getArchitectureName:()=>uve,getArchitectureSet:()=>ux});var U4=ge(require("module"));function cx(){return new Set(U4.default.builtinModules||Object.keys(process.binding("natives")))}function cve(){var i,n,s,o;if(process.platform==="win32")return null;let e=(s=((n=(i=process.report)==null?void 0:i.getReport())!=null?n:{}).sharedObjects)!=null?s:[],t=/\/(?:(ld-linux-|[^/]+-linux-gnu\/)|(libc.musl-|ld-musl-))/;return(o=ed(e,a=>{let l=a.match(t);if(!l)return ed.skip;if(l[1])return"glibc";if(l[2])return"musl";throw new Error("Assertion failed: Expected the libc variant to have been detected")}))!=null?o:null}var Cw,mw;function vd(){return Cw=Cw!=null?Cw:{os:process.platform,cpu:process.arch,libc:cve()}}function uve(r=vd()){return r.libc?`${r.os}-${r.cpu}-${r.libc}`:`${r.os}-${r.cpu}`}function ux(){let r=vd();return mw=mw!=null?mw:{os:[r.os],cpu:[r.cpu],libc:r.libc?[r.libc]:[]}}var gve=new Set(["binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput","home","confDir"]),Iw="yarn_",fx=".yarnrc.yml",hx="yarn.lock",fve="********",Ie;(function(u){u.ANY="ANY",u.BOOLEAN="BOOLEAN",u.ABSOLUTE_PATH="ABSOLUTE_PATH",u.LOCATOR="LOCATOR",u.LOCATOR_LOOSE="LOCATOR_LOOSE",u.NUMBER="NUMBER",u.STRING="STRING",u.SECRET="SECRET",u.SHAPE="SHAPE",u.MAP="MAP"})(Ie||(Ie={}));var Ri=Ye,px={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:Ie.STRING,default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:Ie.ABSOLUTE_PATH,default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:Ie.BOOLEAN,default:!1},ignoreCwd:{description:"If true, the `--cwd` flag will be ignored",type:Ie.BOOLEAN,default:!1},cacheKeyOverride:{description:"A global cache key override; used only for test purposes",type:Ie.STRING,default:null},globalFolder:{description:"Folder where all system-global files are stored",type:Ie.ABSOLUTE_PATH,default:Ax()},cacheFolder:{description:"Folder where the cache files must be written",type:Ie.ABSOLUTE_PATH,default:"./.yarn/cache"},compressionLevel:{description:"Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)",type:Ie.NUMBER,values:["mixed",0,1,2,3,4,5,6,7,8,9],default:cc},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named __virtual__)",type:Ie.ABSOLUTE_PATH,default:"./.yarn/__virtual__"},lockfileFilename:{description:"Name of the files where the Yarn dependency tree entries must be stored",type:Ie.STRING,default:hx},installStatePath:{description:"Path of the file where the install state will be persisted",type:Ie.ABSOLUTE_PATH,default:"./.yarn/install-state.gz"},immutablePatterns:{description:"Array of glob patterns; files matching them won't be allowed to change during immutable installs",type:Ie.STRING,default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:Ie.STRING,default:yw()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:Ie.BOOLEAN,default:!1},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:Ie.BOOLEAN,default:Dy,defaultText:"<dynamic>"},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:Ie.BOOLEAN,default:Uv,defaultText:"<dynamic>"},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:Ie.BOOLEAN,default:Ew.isCI,defaultText:"<dynamic>"},enableMessageNames:{description:"If true, the CLI will prefix most messages with codes suitable for search engines",type:Ie.BOOLEAN,default:!0},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:Ie.BOOLEAN,default:!Ew.isCI,defaultText:"<dynamic>"},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:Ie.BOOLEAN,default:!0},preferAggregateCacheInfo:{description:"If true, the CLI will only print a one-line report of any cache changes",type:Ie.BOOLEAN,default:Ew.isCI},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:Ie.BOOLEAN,default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:Ie.BOOLEAN,default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:Ie.STRING,default:void 0,defaultText:"<dynamic>"},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:Ie.STRING,default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:Ie.STRING,default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:Ie.BOOLEAN,default:!0},supportedArchitectures:{description:"Architectures that Yarn will fetch and inject into the resolver",type:Ie.SHAPE,properties:{os:{description:"Array of supported process.platform strings, or null to target them all",type:Ie.STRING,isArray:!0,isNullable:!0,default:["current"]},cpu:{description:"Array of supported process.arch strings, or null to target them all",type:Ie.STRING,isArray:!0,isNullable:!0,default:["current"]},libc:{description:"Array of supported libc libraries, or null to target them all",type:Ie.STRING,isArray:!0,isNullable:!0,default:["current"]}}},enableMirror:{description:"If true, the downloaded packages will be retrieved and stored in both the local and global folders",type:Ie.BOOLEAN,default:!0},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:Ie.BOOLEAN,default:!0},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:Ie.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:Ie.STRING,default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:Ie.STRING,default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:Ie.NUMBER,default:6e4},httpRetry:{description:"Retry times on http failure",type:Ie.NUMBER,default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:Ie.NUMBER,default:50},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:Ie.MAP,valueDefinition:{description:"",type:Ie.SHAPE,properties:{caFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:Ie.ABSOLUTE_PATH,default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:Ie.BOOLEAN,default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:Ie.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:Ie.STRING,default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:Ie.ABSOLUTE_PATH,default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:Ie.ABSOLUTE_PATH,default:null}}}},caFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:Ie.ABSOLUTE_PATH,default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:Ie.ABSOLUTE_PATH,default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:Ie.ABSOLUTE_PATH,default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:Ie.BOOLEAN,default:!0},logFilters:{description:"Overrides for log levels",type:Ie.SHAPE,isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:Ie.STRING,default:void 0},text:{description:"Code of the texts covered by this override",type:Ie.STRING,default:void 0},pattern:{description:"Code of the patterns covered by this override",type:Ie.STRING,default:void 0},level:{description:"Log level override, set to null to remove override",type:Ie.STRING,values:Object.values(Co),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:Ie.BOOLEAN,default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:Ie.NUMBER,default:7},telemetryUserId:{description:"If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.",type:Ie.STRING,default:null},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:Ie.BOOLEAN,default:!0},enableStrictSettings:{description:"If true, unknown settings will cause Yarn to abort",type:Ie.BOOLEAN,default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:Ie.BOOLEAN,default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:Ie.STRING,default:"throw"},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:Ie.MAP,valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:Ie.SHAPE,properties:{dependencies:{description:"The set of dependencies that must be made available to the current package in order for it to work properly",type:Ie.MAP,valueDefinition:{description:"A range",type:Ie.STRING}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:Ie.MAP,valueDefinition:{description:"A semver range",type:Ie.STRING}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:Ie.MAP,valueDefinition:{description:"The peerDependency meta",type:Ie.SHAPE,properties:{optional:{description:"If true, the selected peer dependency will be marked as optional by the package manager and the consumer omitting it won't be reported as an error",type:Ie.BOOLEAN,default:!1}}}}}}}};function Cx(r,e,t,i,n){if(i.isArray||i.type===Ie.ANY&&Array.isArray(t))return Array.isArray(t)?t.map((s,o)=>dx(r,`${e}[${o}]`,s,i,n)):String(t).split(/,/).map(s=>dx(r,e,s,i,n));if(Array.isArray(t))throw new Error(`Non-array configuration settings "${e}" cannot be an array`);return dx(r,e,t,i,n)}function dx(r,e,t,i,n){var a;switch(i.type){case Ie.ANY:return t;case Ie.SHAPE:return hve(r,e,t,i,n);case Ie.MAP:return pve(r,e,t,i,n)}if(t===null&&!i.isNullable&&i.default!==null)throw new Error(`Non-nullable configuration settings "${e}" cannot be set to null`);if((a=i.values)==null?void 0:a.includes(t))return t;let o=(()=>{if(i.type===Ie.BOOLEAN&&typeof t!="string")return rd(t);if(typeof t!="string")throw new Error(`Expected value (${t}) to be a string`);let l=Nv(t,{env:process.env});switch(i.type){case Ie.ABSOLUTE_PATH:return x.resolve(n,H.toPortablePath(l));case Ie.LOCATOR_LOOSE:return qc(l,!1);case Ie.NUMBER:return parseInt(l);case Ie.LOCATOR:return qc(l);case Ie.BOOLEAN:return rd(l);default:return l}})();if(i.values&&!i.values.includes(o))throw new Error(`Invalid value, expected one of ${i.values.join(", ")}`);return o}function hve(r,e,t,i,n){if(typeof t!="object"||Array.isArray(t))throw new Pe(`Object configuration settings "${e}" must be an object`);let s=mx(r,i,{ignoreArrays:!0});if(t===null)return s;for(let[o,a]of Object.entries(t)){let l=`${e}.${o}`;if(!i.properties[o])throw new Pe(`Unrecognized configuration settings found: ${e}.${o} - run "yarn config -v" to see the list of settings supported in Yarn`);s.set(o,Cx(r,l,a,i.properties[o],n))}return s}function pve(r,e,t,i,n){let s=new Map;if(typeof t!="object"||Array.isArray(t))throw new Pe(`Map configuration settings "${e}" must be an object`);if(t===null)return s;for(let[o,a]of Object.entries(t)){let l=i.normalizeKeys?i.normalizeKeys(o):o,c=`${e}['${l}']`,u=i.valueDefinition;s.set(l,Cx(r,c,a,u,n))}return s}function mx(r,e,{ignoreArrays:t=!1}={}){switch(e.type){case Ie.SHAPE:{if(e.isArray&&!t)return[];let i=new Map;for(let[n,s]of Object.entries(e.properties))i.set(n,mx(r,s));return i}break;case Ie.MAP:return e.isArray&&!t?[]:new Map;case Ie.ABSOLUTE_PATH:return e.default===null?null:r.projectCwd===null?x.isAbsolute(e.default)?x.normalize(e.default):e.isNullable?null:void 0:Array.isArray(e.default)?e.default.map(i=>x.resolve(r.projectCwd,i)):x.resolve(r.projectCwd,e.default);default:return e.default}}function ww(r,e,t){if(e.type===Ie.SECRET&&typeof r=="string"&&t.hideSecrets)return fve;if(e.type===Ie.ABSOLUTE_PATH&&typeof r=="string"&&t.getNativePaths)return H.fromPortablePath(r);if(e.isArray&&Array.isArray(r)){let i=[];for(let n of r)i.push(ww(n,e,t));return i}if(e.type===Ie.MAP&&r instanceof Map){let i=new Map;for(let[n,s]of r.entries())i.set(n,ww(s,e.valueDefinition,t));return i}if(e.type===Ie.SHAPE&&r instanceof Map){let i=new Map;for(let[n,s]of r.entries()){let o=e.properties[n];i.set(n,ww(s,o,t))}return i}return r}function dve(){let r={};for(let[e,t]of Object.entries(process.env))e=e.toLowerCase(),!!e.startsWith(Iw)&&(e=(0,K4.default)(e.slice(Iw.length)),r[e]=t);return r}function yw(){let r=`${Iw}rc_filename`;for(let[e,t]of Object.entries(process.env))if(e.toLowerCase()===r&&typeof t=="string")return t;return fx}var gl;(function(i){i[i.LOCKFILE=0]="LOCKFILE",i[i.MANIFEST=1]="MANIFEST",i[i.NONE=2]="NONE"})(gl||(gl={}));var rA=class{constructor(e){this.projectCwd=null;this.plugins=new Map;this.settings=new Map;this.values=new Map;this.sources=new Map;this.invalid=new Map;this.packageExtensions=new Map;this.limits=new Map;this.startingCwd=e}static create(e,t,i){let n=new rA(e);typeof t!="undefined"&&!(t instanceof Map)&&(n.projectCwd=t),n.importSettings(px);let s=typeof i!="undefined"?i:t instanceof Map?t:new Map;for(let[o,a]of s)n.activatePlugin(o,a);return n}static async find(e,t,{lookup:i=0,strict:n=!0,usePath:s=!1,useRc:o=!0}={}){let a=dve();delete a.rcFilename;let l=await rA.findRcFiles(e),c=await rA.findHomeRcFile();if(c){let b=l.find(v=>v.path===c.path);b?b.strict=!1:l.push(te(N({},c),{strict:!1}))}let u=({ignoreCwd:b,yarnPath:v,ignorePath:k,lockfileFilename:T})=>({ignoreCwd:b,yarnPath:v,ignorePath:k,lockfileFilename:T}),g=q=>{var $=q,{ignoreCwd:b,yarnPath:v,ignorePath:k,lockfileFilename:T}=$,Y=Or($,["ignoreCwd","yarnPath","ignorePath","lockfileFilename"]);return Y},f=new rA(e);f.importSettings(u(px)),f.useWithSource("<environment>",u(a),e,{strict:!1});for(let{path:b,cwd:v,data:k}of l)f.useWithSource(b,u(k),v,{strict:!1});if(s){let b=f.get("yarnPath"),v=f.get("ignorePath");if(b!==null&&!v)return f}let h=f.get("lockfileFilename"),p;switch(i){case 0:p=await rA.findProjectCwd(e,h);break;case 1:p=await rA.findProjectCwd(e,null);break;case 2:U.existsSync(x.join(e,"package.json"))?p=x.resolve(e):p=null;break}f.startingCwd=e,f.projectCwd=p,f.importSettings(g(px));let m=new Map([["@@core",X3]]),y=b=>"default"in b?b.default:b;if(t!==null){for(let T of t.plugins.keys())m.set(T,y(t.modules.get(T)));let b=new Map;for(let T of cx())b.set(T,()=>Mg(T));for(let[T,Y]of t.modules)b.set(T,()=>Y);let v=new Set,k=async(T,Y)=>{let{factory:q,name:$}=Mg(T);if(v.has($))return;let z=new Map(b),ne=A=>{if(z.has(A))return z.get(A)();throw new Pe(`This plugin cannot access the package referenced via ${A} which is neither a builtin, nor an exposed entry`)},ee=await Tg(async()=>y(await q(ne)),A=>`${A} (when initializing ${$}, defined in ${Y})`);b.set($,()=>ee),v.add($),m.set($,ee)};if(a.plugins)for(let T of a.plugins.split(";")){let Y=x.resolve(e,H.toPortablePath(T));await k(Y,"<environment>")}for(let{path:T,cwd:Y,data:q}of l)if(!!o&&!!Array.isArray(q.plugins))for(let $ of q.plugins){let z=typeof $!="string"?$.path:$,ne=x.resolve(Y,H.toPortablePath(z));await k(ne,T)}}for(let[b,v]of m)f.activatePlugin(b,v);f.useWithSource("<environment>",g(a),e,{strict:n});for(let{path:b,cwd:v,data:k,strict:T}of l)f.useWithSource(b,g(k),v,{strict:T!=null?T:n});return f.get("enableGlobalCache")&&(f.values.set("cacheFolder",`${f.get("globalFolder")}/cache`),f.sources.set("cacheFolder","<internal>")),await f.refreshPackageExtensions(),f}static async findRcFiles(e){let t=yw(),i=[],n=e,s=null;for(;n!==s;){s=n;let o=x.join(s,t);if(U.existsSync(o)){let a=await U.readFilePromise(o,"utf8"),l;try{l=Si(a)}catch(c){let u="";throw a.match(/^\s+(?!-)[^:]+\s+\S+/m)&&(u=" (in particular, make sure you list the colons after each key name)"),new Pe(`Parse error when loading ${o}; please check it's proper Yaml${u}`)}i.push({path:o,cwd:s,data:l})}n=x.dirname(s)}return i}static async findHomeRcFile(){let e=yw(),t=Sd(),i=x.join(t,e);if(U.existsSync(i)){let n=await U.readFilePromise(i,"utf8"),s=Si(n);return{path:i,cwd:t,data:s}}return null}static async findProjectCwd(e,t){let i=null,n=e,s=null;for(;n!==s;){if(s=n,U.existsSync(x.join(s,"package.json"))&&(i=s),t!==null){if(U.existsSync(x.join(s,t))){i=s;break}}else if(i!==null)break;n=x.dirname(s)}return i}static async updateConfiguration(e,t){let i=yw(),n=x.join(e,i),s=U.existsSync(n)?Si(await U.readFilePromise(n,"utf8")):{},o=!1,a;if(typeof t=="function"){try{a=t(s)}catch{a=t({})}if(a===s)return}else{a=s;for(let l of Object.keys(t)){let c=s[l],u=t[l],g;if(typeof u=="function")try{g=u(c)}catch{g=u(void 0)}else g=u;c!==g&&(a[l]=g,o=!0)}if(!o)return}await U.changeFilePromise(n,Ua(a),{automaticNewlines:!0})}static async updateHomeConfiguration(e){let t=Sd();return await rA.updateConfiguration(t,e)}activatePlugin(e,t){this.plugins.set(e,t),typeof t.configuration!="undefined"&&this.importSettings(t.configuration)}importSettings(e){for(let[t,i]of Object.entries(e))if(i!=null){if(this.settings.has(t))throw new Error(`Cannot redefine settings "${t}"`);this.settings.set(t,i),this.values.set(t,mx(this,i))}}useWithSource(e,t,i,n){try{this.use(e,t,i,n)}catch(s){throw s.message+=` (in ${tt(this,e,Ye.PATH)})`,s}}use(e,t,i,{strict:n=!0,overwrite:s=!1}={}){n=n&&this.get("enableStrictSettings");for(let o of["enableStrictSettings",...Object.keys(t)]){if(typeof t[o]=="undefined"||o==="plugins"||e==="<environment>"&&gve.has(o))continue;if(o==="rcFilename")throw new Pe(`The rcFilename settings can only be set via ${`${Iw}RC_FILENAME`.toUpperCase()}, not via a rc file`);let l=this.settings.get(o);if(!l){if(n)throw new Pe(`Unrecognized or legacy configuration settings found: ${o} - run "yarn config -v" to see the list of settings supported in Yarn`);this.invalid.set(o,e);continue}if(this.sources.has(o)&&!(s||l.type===Ie.MAP||l.isArray&&l.concatenateValues))continue;let c;try{c=Cx(this,o,t[o],l,i)}catch(u){throw u.message+=` in ${tt(this,e,Ye.PATH)}`,u}if(o==="enableStrictSettings"&&e!=="<environment>"){n=c;continue}if(l.type===Ie.MAP){let u=this.values.get(o);this.values.set(o,new Map(s?[...u,...c]:[...c,...u])),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else if(l.isArray&&l.concatenateValues){let u=this.values.get(o);this.values.set(o,s?[...u,...c]:[...c,...u]),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else this.values.set(o,c),this.sources.set(o,e)}}get(e){if(!this.values.has(e))throw new Error(`Invalid configuration key "${e}"`);return this.values.get(e)}getSpecial(e,{hideSecrets:t=!1,getNativePaths:i=!1}){let n=this.get(e),s=this.settings.get(e);if(typeof s=="undefined")throw new Pe(`Couldn't find a configuration settings named "${e}"`);return ww(n,s,{hideSecrets:t,getNativePaths:i})}getSubprocessStreams(e,{header:t,prefix:i,report:n}){let s,o,a=U.createWriteStream(e);if(this.get("enableInlineBuilds")){let l=n.createStreamReporter(`${i} ${tt(this,"STDOUT","green")}`),c=n.createStreamReporter(`${i} ${tt(this,"STDERR","red")}`);s=new gx.PassThrough,s.pipe(l),s.pipe(a),o=new gx.PassThrough,o.pipe(c),o.pipe(a)}else s=a,o=a,typeof t!="undefined"&&s.write(`${t} -`);return{stdout:s,stderr:o}}makeResolver(){let e=[];for(let t of this.plugins.values())for(let i of t.resolvers||[])e.push(new i);return new Bd([new dw,new oi,new sx,...e])}makeFetcher(){let e=[];for(let t of this.plugins.values())for(let i of t.fetchers||[])e.push(new i);return new wd([new bd,new Qd,...e])}getLinkers(){let e=[];for(let t of this.plugins.values())for(let i of t.linkers||[])e.push(new i);return e}getSupportedArchitectures(){let e=vd(),t=this.get("supportedArchitectures"),i=t.get("os");i!==null&&(i=i.map(o=>o==="current"?e.os:o));let n=t.get("cpu");n!==null&&(n=n.map(o=>o==="current"?e.cpu:o));let s=t.get("libc");return s!==null&&(s=Vo(s,o=>{var a;return o==="current"?(a=e.libc)!=null?a:Vo.skip:o})),{os:i,cpu:n,libc:s}}async refreshPackageExtensions(){this.packageExtensions=new Map;let e=this.packageExtensions,t=(i,n,{userProvided:s=!1}={})=>{if(!mo(i.range))throw new Error("Only semver ranges are allowed as keys for the packageExtensions setting");let o=new At;o.load(n,{yamlCompatibilityMode:!0});let a=Ng(e,i.identHash),l=[];a.push([i.range,l]);let c={status:qi.Inactive,userProvided:s,parentDescriptor:i};for(let u of o.dependencies.values())l.push(te(N({},c),{type:wi.Dependency,descriptor:u}));for(let u of o.peerDependencies.values())l.push(te(N({},c),{type:wi.PeerDependency,descriptor:u}));for(let[u,g]of o.peerDependenciesMeta)for(let[f,h]of Object.entries(g))l.push(te(N({},c),{type:wi.PeerDependencyMeta,selector:u,key:f,value:h}))};await this.triggerHook(i=>i.registerPackageExtensions,this,t);for(let[i,n]of this.get("packageExtensions"))t(cl(i,!0),Py(n),{userProvided:!0})}normalizePackage(e){let t=ud(e);if(this.packageExtensions==null)throw new Error("refreshPackageExtensions has to be called before normalizing packages");let i=this.packageExtensions.get(e.identHash);if(typeof i!="undefined"){let s=e.version;if(s!==null){for(let[o,a]of i)if(!!Jc(s,o))for(let l of a)switch(l.status===qi.Inactive&&(l.status=qi.Redundant),l.type){case wi.Dependency:typeof t.dependencies.get(l.descriptor.identHash)=="undefined"&&(l.status=qi.Active,t.dependencies.set(l.descriptor.identHash,l.descriptor));break;case wi.PeerDependency:typeof t.peerDependencies.get(l.descriptor.identHash)=="undefined"&&(l.status=qi.Active,t.peerDependencies.set(l.descriptor.identHash,l.descriptor));break;case wi.PeerDependencyMeta:{let c=t.peerDependenciesMeta.get(l.selector);(typeof c=="undefined"||!Object.prototype.hasOwnProperty.call(c,l.key)||c[l.key]!==l.value)&&(l.status=qi.Active,Va(t.peerDependenciesMeta,l.selector,()=>({}))[l.key]=l.value)}break;default:Dv(l);break}}}let n=s=>s.scope?`${s.scope}__${s.name}`:`${s.name}`;for(let s of t.peerDependenciesMeta.keys()){let o=An(s);t.peerDependencies.has(o.identHash)||t.peerDependencies.set(o.identHash,rr(o,"*"))}for(let s of t.peerDependencies.values()){if(s.scope==="types")continue;let o=n(s),a=ea("types",o),l=Ot(a);t.peerDependencies.has(a.identHash)||t.peerDependenciesMeta.has(l)||(t.peerDependencies.set(a.identHash,rr(a,"*")),t.peerDependenciesMeta.set(l,{optional:!0}))}return t.dependencies=new Map(xn(t.dependencies,([,s])=>Pn(s))),t.peerDependencies=new Map(xn(t.peerDependencies,([,s])=>Pn(s))),t}getLimit(e){return Va(this.limits,e,()=>(0,H4.default)(this.get(e)))}async triggerHook(e,...t){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);!s||await s(...t)}}async triggerMultipleHooks(e,t){for(let i of t)await this.triggerHook(e,...i)}async reduceHook(e,t,...i){let n=t;for(let s of this.plugins.values()){let o=s.hooks;if(!o)continue;let a=e(o);!a||(n=await a(n,...i))}return n}async firstHook(e,...t){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);if(!s)continue;let o=await s(...t);if(typeof o!="undefined")return o}return null}},ye=rA;ye.telemetry=null;var ss;(function(i){i[i.Never=0]="Never",i[i.ErrorCode=1]="ErrorCode",i[i.Always=2]="Always"})(ss||(ss={}));var Bw=class extends ct{constructor({fileName:e,code:t,signal:i}){let n=ye.create(x.cwd()),s=tt(n,e,Ye.PATH);super(X.EXCEPTION,`Child ${s} reported an error`,o=>{Cve(t,i,{configuration:n,report:o})});this.code=Ix(t,i)}},yx=class extends Bw{constructor({fileName:e,code:t,signal:i,stdout:n,stderr:s}){super({fileName:e,code:t,signal:i});this.stdout=n,this.stderr=s}};function _c(r){return r!==null&&typeof r.fd=="number"}var Vc=new Set;function wx(){}function Bx(){for(let r of Vc)r.kill()}async function ia(r,e,{cwd:t,env:i=process.env,strict:n=!1,stdin:s=null,stdout:o,stderr:a,end:l=2}){let c=["pipe","pipe","pipe"];s===null?c[0]="ignore":_c(s)&&(c[0]=s),_c(o)&&(c[1]=o),_c(a)&&(c[2]=a);let u=(0,Ex.default)(r,e,{cwd:H.fromPortablePath(t),env:te(N({},i),{PWD:H.fromPortablePath(t)}),stdio:c});Vc.add(u),Vc.size===1&&(process.on("SIGINT",wx),process.on("SIGTERM",Bx)),!_c(s)&&s!==null&&s.pipe(u.stdin),_c(o)||u.stdout.pipe(o,{end:!1}),_c(a)||u.stderr.pipe(a,{end:!1});let g=()=>{for(let f of new Set([o,a]))_c(f)||f.end()};return new Promise((f,h)=>{u.on("error",p=>{Vc.delete(u),Vc.size===0&&(process.off("SIGINT",wx),process.off("SIGTERM",Bx)),(l===2||l===1)&&g(),h(p)}),u.on("close",(p,m)=>{Vc.delete(u),Vc.size===0&&(process.off("SIGINT",wx),process.off("SIGTERM",Bx)),(l===2||l===1&&p>0)&&g(),p===0||!n?f({code:Ix(p,m)}):h(new Bw({fileName:r,code:p,signal:m}))})})}async function mve(r,e,{cwd:t,env:i=process.env,encoding:n="utf8",strict:s=!1}){let o=["ignore","pipe","pipe"],a=[],l=[],c=H.fromPortablePath(t);typeof i.PWD!="undefined"&&(i=te(N({},i),{PWD:c}));let u=(0,Ex.default)(r,e,{cwd:c,env:i,stdio:o});return u.stdout.on("data",g=>{a.push(g)}),u.stderr.on("data",g=>{l.push(g)}),await new Promise((g,f)=>{u.on("error",h=>{let p=ye.create(t),m=tt(p,r,Ye.PATH);f(new ct(X.EXCEPTION,`Process ${m} failed to spawn`,y=>{y.reportError(X.EXCEPTION,` ${Xo(p,{label:"Thrown Error",value:po(Ye.NO_HINT,h.message)})}`)}))}),u.on("close",(h,p)=>{let m=n==="buffer"?Buffer.concat(a):Buffer.concat(a).toString(n),y=n==="buffer"?Buffer.concat(l):Buffer.concat(l).toString(n);h===0||!s?g({code:Ix(h,p),stdout:m,stderr:y}):f(new yx({fileName:r,code:h,signal:p,stdout:m,stderr:y}))})})}var Eve=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]]);function Ix(r,e){let t=Eve.get(e);return typeof t!="undefined"?128+t:r!=null?r:1}function Cve(r,e,{configuration:t,report:i}){i.reportError(X.EXCEPTION,` ${Xo(t,r!==null?{label:"Exit Code",value:po(Ye.NUMBER,r)}:{label:"Exit Signal",value:po(Ye.CODE,e)})}`)}var ir={};ft(ir,{Method:()=>ml,RequestError:()=>S5.RequestError,del:()=>DPe,get:()=>xPe,getNetworkSettings:()=>P5,post:()=>jP,put:()=>PPe,request:()=>Md});var B5=ge(Hw()),b5=ge(require("https")),Q5=ge(require("http")),UP=ge(ns()),KP=ge(w5()),jw=ge(require("url"));var S5=ge(Hw()),v5=new Map,k5=new Map,QPe=new Q5.Agent({keepAlive:!0}),SPe=new b5.Agent({keepAlive:!0});function x5(r){let e=new jw.URL(r),t={host:e.hostname,headers:{}};return e.port&&(t.port=Number(e.port)),{proxy:t}}async function HP(r){return Va(k5,r,()=>U.readFilePromise(r).then(e=>(k5.set(r,e),e)))}function vPe({statusCode:r,statusMessage:e},t){let i=tt(t,r,Ye.NUMBER),n=`https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${r}`;return Ug(t,`${i}${e?` (${e})`:""}`,n)}async function Gw(r,{configuration:e,customErrorMessage:t}){var i,n;try{return await r}catch(s){if(s.name!=="HTTPError")throw s;let o=(n=t==null?void 0:t(s))!=null?n:(i=s.response.body)==null?void 0:i.error;o==null&&(s.message.startsWith("Response code")?o="The remote server failed to provide the requested resource":o=s.message),s instanceof B5.TimeoutError&&s.event==="socket"&&(o+=`(can be increased via ${tt(e,"httpTimeout",Ye.SETTING)})`);let a=new ct(X.NETWORK_ERROR,o,l=>{s.response&&l.reportError(X.NETWORK_ERROR,` ${Xo(e,{label:"Response Code",value:po(Ye.NO_HINT,vPe(s.response,e))})}`),s.request&&(l.reportError(X.NETWORK_ERROR,` ${Xo(e,{label:"Request Method",value:po(Ye.NO_HINT,s.request.options.method)})}`),l.reportError(X.NETWORK_ERROR,` ${Xo(e,{label:"Request URL",value:po(Ye.URL,s.request.requestUrl)})}`)),s.request.redirects.length>0&&l.reportError(X.NETWORK_ERROR,` ${Xo(e,{label:"Request Redirects",value:po(Ye.NO_HINT,Hv(e,s.request.redirects,Ye.URL))})}`),s.request.retryCount===s.request.options.retry.limit&&l.reportError(X.NETWORK_ERROR,` ${Xo(e,{label:"Request Retry Count",value:po(Ye.NO_HINT,`${tt(e,s.request.retryCount,Ye.NUMBER)} (can be increased via ${tt(e,"httpRetry",Ye.SETTING)})`)})}`)});throw a.originalError=s,a}}function P5(r,e){let t=[...e.configuration.get("networkSettings")].sort(([o],[a])=>a.length-o.length),i={enableNetwork:void 0,caFilePath:void 0,httpProxy:void 0,httpsProxy:void 0,httpsKeyFilePath:void 0,httpsCertFilePath:void 0},n=Object.keys(i),s=typeof r=="string"?new jw.URL(r):r;for(let[o,a]of t)if(UP.default.isMatch(s.hostname,o))for(let l of n){let c=a.get(l);c!==null&&typeof i[l]=="undefined"&&(i[l]=c)}for(let o of n)typeof i[o]=="undefined"&&(i[o]=e.configuration.get(o));return i}var ml;(function(n){n.GET="GET",n.PUT="PUT",n.POST="POST",n.DELETE="DELETE"})(ml||(ml={}));async function Md(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o=ml.GET}){let a=async()=>await kPe(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o});return await(await t.reduceHook(c=>c.wrapNetworkRequest,a,{target:r,body:e,configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o}))()}async function xPe(r,n){var s=n,{configuration:e,jsonResponse:t}=s,i=Or(s,["configuration","jsonResponse"]);let o=Va(v5,r,()=>Gw(Md(r,null,N({configuration:e},i)),{configuration:e}).then(a=>(v5.set(r,a.body),a.body)));return Buffer.isBuffer(o)===!1&&(o=await o),t?JSON.parse(o.toString()):o}async function PPe(r,e,n){var s=n,{customErrorMessage:t}=s,i=Or(s,["customErrorMessage"]);return(await Gw(Md(r,e,te(N({},i),{method:ml.PUT})),i)).body}async function jP(r,e,n){var s=n,{customErrorMessage:t}=s,i=Or(s,["customErrorMessage"]);return(await Gw(Md(r,e,te(N({},i),{method:ml.POST})),i)).body}async function DPe(r,i){var n=i,{customErrorMessage:e}=n,t=Or(n,["customErrorMessage"]);return(await Gw(Md(r,null,te(N({},t),{method:ml.DELETE})),t)).body}async function kPe(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o=ml.GET}){let a=typeof r=="string"?new jw.URL(r):r,l=P5(a,{configuration:t});if(l.enableNetwork===!1)throw new Error(`Request to '${a.href}' has been blocked because of your configuration settings`);if(a.protocol==="http:"&&!UP.default.isMatch(a.hostname,t.get("unsafeHttpWhitelist")))throw new Error(`Unsafe http requests must be explicitly whitelisted in your configuration (${a.hostname})`);let u={agent:{http:l.httpProxy?KP.default.httpOverHttp(x5(l.httpProxy)):QPe,https:l.httpsProxy?KP.default.httpsOverHttp(x5(l.httpsProxy)):SPe},headers:i,method:o};u.responseType=s?"json":"buffer",e!==null&&(Buffer.isBuffer(e)||!n&&typeof e=="string"?u.body=e:u.json=e);let g=t.get("httpTimeout"),f=t.get("httpRetry"),h=t.get("enableStrictSsl"),p=l.caFilePath,m=l.httpsCertFilePath,y=l.httpsKeyFilePath,{default:b}=await Promise.resolve().then(()=>ge(Hw())),v=p?await HP(p):void 0,k=m?await HP(m):void 0,T=y?await HP(y):void 0,Y=b.extend(N({timeout:{socket:g},retry:f,https:{rejectUnauthorized:h,certificateAuthority:v,certificate:k,key:T}},u));return t.getLimit("networkConcurrency")(()=>Y(a))}var Zt={};ft(Zt,{PackageManager:()=>hn,detectPackageManager:()=>G9,executePackageAccessibleBinary:()=>z9,executePackageScript:()=>sB,executePackageShellcode:()=>iD,executeWorkspaceAccessibleBinary:()=>VDe,executeWorkspaceLifecycleScript:()=>W9,executeWorkspaceScript:()=>J9,getPackageAccessibleBinaries:()=>oB,getWorkspaceAccessibleBinaries:()=>q9,hasPackageScript:()=>WDe,hasWorkspaceScript:()=>rD,makeScriptEnv:()=>qd,maybeExecuteWorkspaceLifecycleScript:()=>_De,prepareExternalProject:()=>JDe});var Ud={};ft(Ud,{getLibzipPromise:()=>fn,getLibzipSync:()=>L5});var N5=ge(R5());var El=["number","number"],qP;(function(L){L[L.ZIP_ER_OK=0]="ZIP_ER_OK",L[L.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",L[L.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",L[L.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",L[L.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",L[L.ZIP_ER_READ=5]="ZIP_ER_READ",L[L.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",L[L.ZIP_ER_CRC=7]="ZIP_ER_CRC",L[L.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",L[L.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",L[L.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",L[L.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",L[L.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",L[L.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",L[L.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",L[L.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",L[L.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",L[L.ZIP_ER_EOF=17]="ZIP_ER_EOF",L[L.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",L[L.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",L[L.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",L[L.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",L[L.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",L[L.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",L[L.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",L[L.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",L[L.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",L[L.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",L[L.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",L[L.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",L[L.ZIP_ER_TELL=30]="ZIP_ER_TELL",L[L.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA"})(qP||(qP={}));var F5=r=>({get HEAP8(){return r.HEAP8},get HEAPU8(){return r.HEAPU8},errors:qP,SEEK_SET:0,SEEK_CUR:1,SEEK_END:2,ZIP_CHECKCONS:4,ZIP_CREATE:1,ZIP_EXCL:2,ZIP_TRUNCATE:8,ZIP_RDONLY:16,ZIP_FL_OVERWRITE:8192,ZIP_FL_COMPRESSED:4,ZIP_OPSYS_DOS:0,ZIP_OPSYS_AMIGA:1,ZIP_OPSYS_OPENVMS:2,ZIP_OPSYS_UNIX:3,ZIP_OPSYS_VM_CMS:4,ZIP_OPSYS_ATARI_ST:5,ZIP_OPSYS_OS_2:6,ZIP_OPSYS_MACINTOSH:7,ZIP_OPSYS_Z_SYSTEM:8,ZIP_OPSYS_CPM:9,ZIP_OPSYS_WINDOWS_NTFS:10,ZIP_OPSYS_MVS:11,ZIP_OPSYS_VSE:12,ZIP_OPSYS_ACORN_RISC:13,ZIP_OPSYS_VFAT:14,ZIP_OPSYS_ALTERNATE_MVS:15,ZIP_OPSYS_BEOS:16,ZIP_OPSYS_TANDEM:17,ZIP_OPSYS_OS_400:18,ZIP_OPSYS_OS_X:19,ZIP_CM_DEFAULT:-1,ZIP_CM_STORE:0,ZIP_CM_DEFLATE:8,uint08S:r._malloc(1),uint16S:r._malloc(2),uint32S:r._malloc(4),uint64S:r._malloc(8),malloc:r._malloc,free:r._free,getValue:r.getValue,open:r.cwrap("zip_open","number",["string","number","number"]),openFromSource:r.cwrap("zip_open_from_source","number",["number","number","number"]),close:r.cwrap("zip_close","number",["number"]),discard:r.cwrap("zip_discard",null,["number"]),getError:r.cwrap("zip_get_error","number",["number"]),getName:r.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:r.cwrap("zip_get_num_entries","number",["number","number"]),delete:r.cwrap("zip_delete","number",["number","number"]),stat:r.cwrap("zip_stat","number",["number","string","number","number"]),statIndex:r.cwrap("zip_stat_index","number",["number",...El,"number","number"]),fopen:r.cwrap("zip_fopen","number",["number","string","number"]),fopenIndex:r.cwrap("zip_fopen_index","number",["number",...El,"number"]),fread:r.cwrap("zip_fread","number",["number","number","number","number"]),fclose:r.cwrap("zip_fclose","number",["number"]),dir:{add:r.cwrap("zip_dir_add","number",["number","string"])},file:{add:r.cwrap("zip_file_add","number",["number","string","number","number"]),getError:r.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:r.cwrap("zip_file_get_external_attributes","number",["number",...El,"number","number","number"]),setExternalAttributes:r.cwrap("zip_file_set_external_attributes","number",["number",...El,"number","number","number"]),setMtime:r.cwrap("zip_file_set_mtime","number",["number",...El,"number","number"]),setCompression:r.cwrap("zip_set_file_compression","number",["number",...El,"number","number"])},ext:{countSymlinks:r.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:r.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:r.cwrap("zip_error_strerror","string",["number"])},name:{locate:r.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:r.cwrap("zip_source_buffer_create","number",["number","number","number","number"]),fromBuffer:r.cwrap("zip_source_buffer","number",["number","number",...El,"number"]),free:r.cwrap("zip_source_free",null,["number"]),keep:r.cwrap("zip_source_keep",null,["number"]),open:r.cwrap("zip_source_open","number",["number"]),close:r.cwrap("zip_source_close","number",["number"]),seek:r.cwrap("zip_source_seek","number",["number",...El,"number"]),tell:r.cwrap("zip_source_tell","number",["number"]),read:r.cwrap("zip_source_read","number",["number","number","number"]),error:r.cwrap("zip_source_error","number",["number"]),setMtime:r.cwrap("zip_source_set_mtime","number",["number","number"])},struct:{stat:r.cwrap("zipstruct_stat","number",[]),statS:r.cwrap("zipstruct_statS","number",[]),statName:r.cwrap("zipstruct_stat_name","string",["number"]),statIndex:r.cwrap("zipstruct_stat_index","number",["number"]),statSize:r.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:r.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:r.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:r.cwrap("zipstruct_stat_mtime","number",["number"]),statCrc:r.cwrap("zipstruct_stat_crc","number",["number"]),error:r.cwrap("zipstruct_error","number",[]),errorS:r.cwrap("zipstruct_errorS","number",[]),errorCodeZip:r.cwrap("zipstruct_error_code_zip","number",["number"])}});var JP=null;function L5(){return JP===null&&(JP=F5((0,N5.default)())),JP}async function fn(){return L5()}var Hd={};ft(Hd,{ShellError:()=>Ks,execute:()=>Zw,globUtils:()=>qw});var W5=ge(gv()),z5=ge(require("os")),os=ge(require("stream")),_5=ge(require("util"));var Ks=class extends Error{constructor(e){super(e);this.name="ShellError"}};var qw={};ft(qw,{fastGlobOptions:()=>M5,isBraceExpansion:()=>U5,isGlobPattern:()=>RPe,match:()=>FPe,micromatchOptions:()=>Ww});var T5=ge($y()),O5=ge(require("fs")),Jw=ge(ns()),Ww={strictBrackets:!0},M5={onlyDirectories:!1,onlyFiles:!1};function RPe(r){if(!Jw.default.scan(r,Ww).isGlob)return!1;try{Jw.default.parse(r,Ww)}catch{return!1}return!0}function FPe(r,{cwd:e,baseFs:t}){return(0,T5.default)(r,te(N({},M5),{cwd:H.fromPortablePath(e),fs:zE(O5.default,new Xh(t))}))}function U5(r){return Jw.default.scan(r,Ww).isBrace}var K5=ge(vQ()),sa=ge(require("stream")),H5=ge(require("string_decoder")),Nn;(function(i){i[i.STDIN=0]="STDIN",i[i.STDOUT=1]="STDOUT",i[i.STDERR=2]="STDERR"})(Nn||(Nn={}));var Zc=new Set;function WP(){}function zP(){for(let r of Zc)r.kill()}function j5(r,e,t,i){return n=>{let s=n[0]instanceof sa.Transform?"pipe":n[0],o=n[1]instanceof sa.Transform?"pipe":n[1],a=n[2]instanceof sa.Transform?"pipe":n[2],l=(0,K5.default)(r,e,te(N({},i),{stdio:[s,o,a]}));return Zc.add(l),Zc.size===1&&(process.on("SIGINT",WP),process.on("SIGTERM",zP)),n[0]instanceof sa.Transform&&n[0].pipe(l.stdin),n[1]instanceof sa.Transform&&l.stdout.pipe(n[1],{end:!1}),n[2]instanceof sa.Transform&&l.stderr.pipe(n[2],{end:!1}),{stdin:l.stdin,promise:new Promise(c=>{l.on("error",u=>{switch(Zc.delete(l),Zc.size===0&&(process.off("SIGINT",WP),process.off("SIGTERM",zP)),u.code){case"ENOENT":n[2].write(`command not found: ${r} -`),c(127);break;case"EACCES":n[2].write(`permission denied: ${r} -`),c(128);break;default:n[2].write(`uncaught error: ${u.message} -`),c(1);break}}),l.on("close",u=>{Zc.delete(l),Zc.size===0&&(process.off("SIGINT",WP),process.off("SIGTERM",zP)),c(u!==null?u:129)})})}}}function G5(r){return e=>{let t=e[0]==="pipe"?new sa.PassThrough:e[0];return{stdin:t,promise:Promise.resolve().then(()=>r({stdin:t,stdout:e[1],stderr:e[2]}))}}}var Io=class{constructor(e){this.stream=e}close(){}get(){return this.stream}},Y5=class{constructor(){this.stream=null}close(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");this.stream.end()}attach(e){this.stream=e}get(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");return this.stream}},Kd=class{constructor(e,t){this.stdin=null;this.stdout=null;this.stderr=null;this.pipe=null;this.ancestor=e,this.implementation=t}static start(e,{stdin:t,stdout:i,stderr:n}){let s=new Kd(null,e);return s.stdin=t,s.stdout=i,s.stderr=n,s}pipeTo(e,t=1){let i=new Kd(this,e),n=new Y5;return i.pipe=n,i.stdout=this.stdout,i.stderr=this.stderr,(t&1)==1?this.stdout=n:this.ancestor!==null&&(this.stderr=this.ancestor.stdout),(t&2)==2?this.stderr=n:this.ancestor!==null&&(this.stderr=this.ancestor.stderr),i}async exec(){let e=["ignore","ignore","ignore"];if(this.pipe)e[0]="pipe";else{if(this.stdin===null)throw new Error("Assertion failed: No input stream registered");e[0]=this.stdin.get()}let t;if(this.stdout===null)throw new Error("Assertion failed: No output stream registered");t=this.stdout,e[1]=t.get();let i;if(this.stderr===null)throw new Error("Assertion failed: No error stream registered");i=this.stderr,e[2]=i.get();let n=this.implementation(e);return this.pipe&&this.pipe.attach(n.stdin),await n.promise.then(s=>(t.close(),i.close(),s))}async run(){let e=[];for(let i=this;i;i=i.ancestor)e.push(i.exec());return(await Promise.all(e))[0]}};function zw(r,e){return Kd.start(r,e)}function q5(r,e=null){let t=new sa.PassThrough,i=new H5.StringDecoder,n="";return t.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` -`),a!==-1){let l=n+o.substring(0,a);o=o.substring(a+1),n="",r(e!==null?`${e} ${l}`:l)}while(a!==-1);n+=o}),t.on("end",()=>{let s=i.end();s!==""&&r(e!==null?`${e} ${s}`:s)}),t}function J5(r,{prefix:e}){return{stdout:q5(t=>r.stdout.write(`${t} -`),r.stdout.isTTY?e:null),stderr:q5(t=>r.stderr.write(`${t} -`),r.stderr.isTTY?e:null)}}var NPe=(0,_5.promisify)(setTimeout);var zi;(function(t){t[t.Readable=1]="Readable",t[t.Writable=2]="Writable"})(zi||(zi={}));function V5(r,e,t){let i=new os.PassThrough({autoDestroy:!0});switch(r){case Nn.STDIN:(e&1)==1&&t.stdin.pipe(i,{end:!1}),(e&2)==2&&t.stdin instanceof os.Writable&&i.pipe(t.stdin,{end:!1});break;case Nn.STDOUT:(e&1)==1&&t.stdout.pipe(i,{end:!1}),(e&2)==2&&i.pipe(t.stdout,{end:!1});break;case Nn.STDERR:(e&1)==1&&t.stderr.pipe(i,{end:!1}),(e&2)==2&&i.pipe(t.stderr,{end:!1});break;default:throw new Ks(`Bad file descriptor: "${r}"`)}return i}function _w(r,e={}){let t=N(N({},r),e);return t.environment=N(N({},r.environment),e.environment),t.variables=N(N({},r.variables),e.variables),t}var LPe=new Map([["cd",async([r=(0,z5.homedir)(),...e],t,i)=>{let n=x.resolve(i.cwd,H.toPortablePath(r));if(!(await t.baseFs.statPromise(n).catch(o=>{throw o.code==="ENOENT"?new Ks(`cd: no such file or directory: ${r}`):o})).isDirectory())throw new Ks(`cd: not a directory: ${r}`);return i.cwd=n,0}],["pwd",async(r,e,t)=>(t.stdout.write(`${H.fromPortablePath(t.cwd)} -`),0)],[":",async(r,e,t)=>0],["true",async(r,e,t)=>0],["false",async(r,e,t)=>1],["exit",async([r,...e],t,i)=>i.exitCode=parseInt(r!=null?r:i.variables["?"],10)],["echo",async(r,e,t)=>(t.stdout.write(`${r.join(" ")} -`),0)],["sleep",async([r],e,t)=>{if(typeof r=="undefined")throw new Ks("sleep: missing operand");let i=Number(r);if(Number.isNaN(i))throw new Ks(`sleep: invalid time interval '${r}'`);return await NPe(1e3*i,0)}],["__ysh_run_procedure",async(r,e,t)=>{let i=t.procedures[r[0]];return await zw(i,{stdin:new Io(t.stdin),stdout:new Io(t.stdout),stderr:new Io(t.stderr)}).run()}],["__ysh_set_redirects",async(r,e,t)=>{let i=t.stdin,n=t.stdout,s=t.stderr,o=[],a=[],l=[],c=0;for(;r[c]!=="--";){let g=r[c++],{type:f,fd:h}=JSON.parse(g),p=v=>{switch(h){case null:case 0:o.push(v);break;default:throw new Error(`Unsupported file descriptor: "${h}"`)}},m=v=>{switch(h){case null:case 1:a.push(v);break;case 2:l.push(v);break;default:throw new Error(`Unsupported file descriptor: "${h}"`)}},y=Number(r[c++]),b=c+y;for(let v=c;v<b;++c,++v)switch(f){case"<":p(()=>e.baseFs.createReadStream(x.resolve(t.cwd,H.toPortablePath(r[v]))));break;case"<<<":p(()=>{let k=new os.PassThrough;return process.nextTick(()=>{k.write(`${r[v]} -`),k.end()}),k});break;case"<&":p(()=>V5(Number(r[v]),1,t));break;case">":case">>":{let k=x.resolve(t.cwd,H.toPortablePath(r[v]));m(k==="/dev/null"?new os.Writable({autoDestroy:!0,emitClose:!0,write(T,Y,q){setImmediate(q)}}):e.baseFs.createWriteStream(k,f===">>"?{flags:"a"}:void 0))}break;case">&":m(V5(Number(r[v]),2,t));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${f}"`)}}if(o.length>0){let g=new os.PassThrough;i=g;let f=h=>{if(h===o.length)g.end();else{let p=o[h]();p.pipe(g,{end:!1}),p.on("end",()=>{f(h+1)})}};f(0)}if(a.length>0){let g=new os.PassThrough;n=g;for(let f of a)g.pipe(f)}if(l.length>0){let g=new os.PassThrough;s=g;for(let f of l)g.pipe(f)}let u=await zw(jd(r.slice(c+1),e,t),{stdin:new Io(i),stdout:new Io(n),stderr:new Io(s)}).run();return await Promise.all(a.map(g=>new Promise((f,h)=>{g.on("error",p=>{h(p)}),g.on("close",()=>{f()}),g.end()}))),await Promise.all(l.map(g=>new Promise((f,h)=>{g.on("error",p=>{h(p)}),g.on("close",()=>{f()}),g.end()}))),u}]]);async function TPe(r,e,t){let i=[],n=new os.PassThrough;return n.on("data",s=>i.push(s)),await Vw(r,e,_w(t,{stdout:n})),Buffer.concat(i).toString().replace(/[\r\n]+$/,"")}async function X5(r,e,t){let i=r.map(async s=>{let o=await AA(s.args,e,t);return{name:s.name,value:o.join(" ")}});return(await Promise.all(i)).reduce((s,o)=>(s[o.name]=o.value,s),{})}function Xw(r){return r.match(/[^ \r\n\t]+/g)||[]}async function Z5(r,e,t,i,n=i){switch(r.name){case"$":i(String(process.pid));break;case"#":i(String(e.args.length));break;case"@":if(r.quoted)for(let s of e.args)n(s);else for(let s of e.args){let o=Xw(s);for(let a=0;a<o.length-1;++a)n(o[a]);i(o[o.length-1])}break;case"*":{let s=e.args.join(" ");if(r.quoted)i(s);else for(let o of Xw(s))n(o)}break;case"PPID":i(String(process.ppid));break;case"RANDOM":i(String(Math.floor(Math.random()*32768)));break;default:{let s=parseInt(r.name,10),o;if(Number.isFinite(s))if(s>=0&&s<e.args.length)o=e.args[s];else if(r.defaultValue)o=(await AA(r.defaultValue,e,t)).join(" ");else if(r.alternativeValue)o=(await AA(r.alternativeValue,e,t)).join(" ");else throw new Ks(`Unbound argument #${s}`);else if(Object.prototype.hasOwnProperty.call(t.variables,r.name))o=t.variables[r.name];else if(Object.prototype.hasOwnProperty.call(t.environment,r.name))o=t.environment[r.name];else if(r.defaultValue)o=(await AA(r.defaultValue,e,t)).join(" ");else throw new Ks(`Unbound variable "${r.name}"`);if(typeof o!="undefined"&&r.alternativeValue&&(o=(await AA(r.alternativeValue,e,t)).join(" ")),r.quoted)i(o);else{let a=Xw(o);for(let c=0;c<a.length-1;++c)n(a[c]);let l=a[a.length-1];typeof l!="undefined"&&i(l)}}break}}var OPe={addition:(r,e)=>r+e,subtraction:(r,e)=>r-e,multiplication:(r,e)=>r*e,division:(r,e)=>Math.trunc(r/e)};async function Gd(r,e,t){if(r.type==="number"){if(Number.isInteger(r.value))return r.value;throw new Error(`Invalid number: "${r.value}", only integers are allowed`)}else if(r.type==="variable"){let i=[];await Z5(te(N({},r),{quoted:!0}),e,t,s=>i.push(s));let n=Number(i.join(" "));return Number.isNaN(n)?Gd({type:"variable",name:i.join(" ")},e,t):Gd({type:"number",value:n},e,t)}else return OPe[r.type](await Gd(r.left,e,t),await Gd(r.right,e,t))}async function AA(r,e,t){let i=new Map,n=[],s=[],o=u=>{s.push(u)},a=()=>{s.length>0&&n.push(s.join("")),s=[]},l=u=>{o(u),a()},c=(u,g,f)=>{let h=JSON.stringify({type:u,fd:g}),p=i.get(h);typeof p=="undefined"&&i.set(h,p=[]),p.push(f)};for(let u of r){let g=!1;switch(u.type){case"redirection":{let f=await AA(u.args,e,t);for(let h of f)c(u.subtype,u.fd,h)}break;case"argument":for(let f of u.segments)switch(f.type){case"text":o(f.text);break;case"glob":o(f.pattern),g=!0;break;case"shell":{let h=await TPe(f.shell,e,t);if(f.quoted)o(h);else{let p=Xw(h);for(let m=0;m<p.length-1;++m)l(p[m]);o(p[p.length-1])}}break;case"variable":await Z5(f,e,t,o,l);break;case"arithmetic":o(String(await Gd(f.arithmetic,e,t)));break}break}if(a(),g){let f=n.pop();if(typeof f=="undefined")throw new Error("Assertion failed: Expected a glob pattern to have been set");let h=await e.glob.match(f,{cwd:t.cwd,baseFs:e.baseFs});if(h.length===0){let p=U5(f)?". Note: Brace expansion of arbitrary strings isn't currently supported. For more details, please read this issue: https://github.com/yarnpkg/berry/issues/22":"";throw new Ks(`No matches found: "${f}"${p}`)}for(let p of h.sort())l(p)}}if(i.size>0){let u=[];for(let[g,f]of i.entries())u.splice(u.length,0,g,String(f.length),...f);n.splice(0,0,"__ysh_set_redirects",...u,"--")}return n}function jd(r,e,t){e.builtins.has(r[0])||(r=["command",...r]);let i=H.fromPortablePath(t.cwd),n=t.environment;typeof n.PWD!="undefined"&&(n=te(N({},n),{PWD:i}));let[s,...o]=r;if(s==="command")return j5(o[0],o.slice(1),e,{cwd:i,env:n});let a=e.builtins.get(s);if(typeof a=="undefined")throw new Error(`Assertion failed: A builtin should exist for "${s}"`);return G5(async({stdin:l,stdout:c,stderr:u})=>{let{stdin:g,stdout:f,stderr:h}=t;t.stdin=l,t.stdout=c,t.stderr=u;try{return await a(o,e,t)}finally{t.stdin=g,t.stdout=f,t.stderr=h}})}function MPe(r,e,t){return i=>{let n=new os.PassThrough,s=Vw(r,e,_w(t,{stdin:n}));return{stdin:n,promise:s}}}function UPe(r,e,t){return i=>{let n=new os.PassThrough,s=Vw(r,e,t);return{stdin:n,promise:s}}}function $5(r,e,t,i){if(e.length===0)return r;{let n;do n=String(Math.random());while(Object.prototype.hasOwnProperty.call(i.procedures,n));return i.procedures=N({},i.procedures),i.procedures[n]=r,jd([...e,"__ysh_run_procedure",n],t,i)}}async function e9(r,e,t){let i=r,n=null,s=null;for(;i;){let o=i.then?N({},t):t,a;switch(i.type){case"command":{let l=await AA(i.args,e,t),c=await X5(i.envs,e,t);a=i.envs.length?jd(l,e,_w(o,{environment:c})):jd(l,e,o)}break;case"subshell":{let l=await AA(i.args,e,t),c=MPe(i.subshell,e,o);a=$5(c,l,e,o)}break;case"group":{let l=await AA(i.args,e,t),c=UPe(i.group,e,o);a=$5(c,l,e,o)}break;case"envs":{let l=await X5(i.envs,e,t);o.environment=N(N({},o.environment),l),a=jd(["true"],e,o)}break}if(typeof a=="undefined")throw new Error("Assertion failed: An action should have been generated");if(n===null)s=zw(a,{stdin:new Io(o.stdin),stdout:new Io(o.stdout),stderr:new Io(o.stderr)});else{if(s===null)throw new Error("Assertion failed: The execution pipeline should have been setup");switch(n){case"|":s=s.pipeTo(a,Nn.STDOUT);break;case"|&":s=s.pipeTo(a,Nn.STDOUT|Nn.STDERR);break}}i.then?(n=i.then.type,i=i.then.chain):i=null}if(s===null)throw new Error("Assertion failed: The execution pipeline should have been setup");return await s.run()}async function KPe(r,e,t,{background:i=!1}={}){function n(s){let o=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],a=o[s%o.length];return W5.default.hex(a)}if(i){let s=t.nextBackgroundJobIndex++,o=n(s),a=`[${s}]`,l=o(a),{stdout:c,stderr:u}=J5(t,{prefix:l});return t.backgroundJobs.push(e9(r,e,_w(t,{stdout:c,stderr:u})).catch(g=>u.write(`${g.message} -`)).finally(()=>{t.stdout.isTTY&&t.stdout.write(`Job ${l}, '${o(tg(r))}' has ended -`)})),0}return await e9(r,e,t)}async function HPe(r,e,t,{background:i=!1}={}){let n,s=a=>{n=a,t.variables["?"]=String(a)},o=async a=>{try{return await KPe(a.chain,e,t,{background:i&&typeof a.then=="undefined"})}catch(l){if(!(l instanceof Ks))throw l;return t.stderr.write(`${l.message} -`),1}};for(s(await o(r));r.then;){if(t.exitCode!==null)return t.exitCode;switch(r.then.type){case"&&":n===0&&s(await o(r.then.line));break;case"||":n!==0&&s(await o(r.then.line));break;default:throw new Error(`Assertion failed: Unsupported command type: "${r.then.type}"`)}r=r.then.line}return n}async function Vw(r,e,t){let i=t.backgroundJobs;t.backgroundJobs=[];let n=0;for(let{command:s,type:o}of r){if(n=await HPe(s,e,t,{background:o==="&"}),t.exitCode!==null)return t.exitCode;t.variables["?"]=String(n)}return await Promise.all(t.backgroundJobs),t.backgroundJobs=i,n}function t9(r){switch(r.type){case"variable":return r.name==="@"||r.name==="#"||r.name==="*"||Number.isFinite(parseInt(r.name,10))||"defaultValue"in r&&!!r.defaultValue&&r.defaultValue.some(e=>Yd(e))||"alternativeValue"in r&&!!r.alternativeValue&&r.alternativeValue.some(e=>Yd(e));case"arithmetic":return _P(r.arithmetic);case"shell":return VP(r.shell);default:return!1}}function Yd(r){switch(r.type){case"redirection":return r.args.some(e=>Yd(e));case"argument":return r.segments.some(e=>t9(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${r.type}"`)}}function _P(r){switch(r.type){case"variable":return t9(r);case"number":return!1;default:return _P(r.left)||_P(r.right)}}function VP(r){return r.some(({command:e})=>{for(;e;){let t=e.chain;for(;t;){let i;switch(t.type){case"subshell":i=VP(t.subshell);break;case"command":i=t.envs.some(n=>n.args.some(s=>Yd(s)))||t.args.some(n=>Yd(n));break}if(i)return!0;if(!t.then)break;t=t.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function Zw(r,e=[],{baseFs:t=new ar,builtins:i={},cwd:n=H.toPortablePath(process.cwd()),env:s=process.env,stdin:o=process.stdin,stdout:a=process.stdout,stderr:l=process.stderr,variables:c={},glob:u=qw}={}){let g={};for(let[p,m]of Object.entries(s))typeof m!="undefined"&&(g[p]=m);let f=new Map(LPe);for(let[p,m]of Object.entries(i))f.set(p,m);o===null&&(o=new os.PassThrough,o.end());let h=VE(r,u);if(!VP(h)&&h.length>0&&e.length>0){let{command:p}=h[h.length-1];for(;p.then;)p=p.then.line;let m=p.chain;for(;m.then;)m=m.then.chain;m.type==="command"&&(m.args=m.args.concat(e.map(y=>({type:"argument",segments:[{type:"text",text:y}]}))))}return await Vw(h,{args:e,baseFs:t,builtins:f,initialStdin:o,initialStdout:a,initialStderr:l,glob:u},{cwd:n,environment:g,exitCode:null,procedures:{},stdin:o,stdout:a,stderr:l,variables:Object.assign({},c,{["?"]:0}),nextBackgroundJobIndex:1,backgroundJobs:[]})}var H9=ge($w()),j9=ge(fg()),Il=ge(require("stream"));var T9=ge(L9()),rB=ge(yc());var O9=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],M9=80,UDe=new Set([X.FETCH_NOT_CACHED,X.UNUSED_CACHE_ENTRY]),KDe=5,iB=rB.default.GITHUB_ACTIONS?{start:r=>`::group::${r} -`,end:r=>`::endgroup:: -`}:rB.default.TRAVIS?{start:r=>`travis_fold:start:${r} -`,end:r=>`travis_fold:end:${r} -`}:rB.default.GITLAB?{start:r=>`section_start:${Math.floor(Date.now()/1e3)}:${r.toLowerCase().replace(/\W+/g,"_")}[collapsed=true]\r${r} -`,end:r=>`section_end:${Math.floor(Date.now()/1e3)}:${r.toLowerCase().replace(/\W+/g,"_")}\r`}:null,U9=new Date,HDe=["iTerm.app","Apple_Terminal"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,jDe=r=>r,nB=jDe({patrick:{date:[17,3],chars:["\u{1F340}","\u{1F331}"],size:40},simba:{date:[19,7],chars:["\u{1F981}","\u{1F334}"],size:40},jack:{date:[31,10],chars:["\u{1F383}","\u{1F987}"],size:40},hogsfather:{date:[31,12],chars:["\u{1F389}","\u{1F384}"],size:40},default:{chars:["=","-"],size:80}}),GDe=HDe&&Object.keys(nB).find(r=>{let e=nB[r];return!(e.date&&(e.date[0]!==U9.getDate()||e.date[1]!==U9.getMonth()+1))})||"default";function K9(r,{configuration:e,json:t}){if(!e.get("enableMessageNames"))return"";let n=VA(r===null?0:r);return!t&&r===null?tt(e,n,"grey"):n}function tD(r,{configuration:e,json:t}){let i=K9(r,{configuration:e,json:t});if(!i||r===null||r===X.UNNAMED)return i;let n=X[r],s=`https://yarnpkg.com/advanced/error-codes#${i}---${n}`.toLowerCase();return Ug(e,i,s)}var Je=class extends Ji{constructor({configuration:e,stdout:t,json:i=!1,includeFooter:n=!0,includeLogs:s=!i,includeInfos:o=s,includeWarnings:a=s,forgettableBufferSize:l=KDe,forgettableNames:c=new Set}){super();this.uncommitted=new Set;this.cacheHitCount=0;this.cacheMissCount=0;this.lastCacheMiss=null;this.warningCount=0;this.errorCount=0;this.startTime=Date.now();this.indent=0;this.progress=new Map;this.progressTime=0;this.progressFrame=0;this.progressTimeout=null;this.progressStyle=null;this.progressMaxScaledSize=null;this.forgettableLines=[];if(sd(this,{configuration:e}),this.configuration=e,this.forgettableBufferSize=l,this.forgettableNames=new Set([...c,...UDe]),this.includeFooter=n,this.includeInfos=o,this.includeWarnings=a,this.json=i,this.stdout=t,e.get("enableProgressBars")&&!i&&t.isTTY&&t.columns>22){let u=e.get("progressBarStyle")||GDe;if(!Object.prototype.hasOwnProperty.call(nB,u))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=nB[u];let g="\u27A4 YN0000: \u250C ".length,f=Math.max(0,Math.min(t.columns-g,80));this.progressMaxScaledSize=Math.floor(this.progressStyle.size*f/80)}}static async start(e,t){let i=new this(e),n=process.emitWarning;process.emitWarning=(s,o)=>{if(typeof s!="string"){let l=s;s=l.message,o=o!=null?o:l.name}let a=typeof o!="undefined"?`${o}: ${s}`:s;i.reportWarning(X.UNNAMED,a)};try{await t(i)}catch(s){i.reportExceptionOnce(s)}finally{await i.finalize(),process.emitWarning=n}return i}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(e){this.cacheHitCount+=1}reportCacheMiss(e,t){this.lastCacheMiss=e,this.cacheMissCount+=1,typeof t!="undefined"&&!this.configuration.get("preferAggregateCacheInfo")&&this.reportInfo(X.FETCH_NOT_CACHED,t)}startSectionSync({reportHeader:e,reportFooter:t,skipIfEmpty:i},n){let s={committed:!1,action:()=>{e==null||e()}};i?this.uncommitted.add(s):(s.action(),s.committed=!0);let o=Date.now();try{return n()}catch(a){throw this.reportExceptionOnce(a),a}finally{let a=Date.now();this.uncommitted.delete(s),s.committed&&(t==null||t(a-o))}}async startSectionPromise({reportHeader:e,reportFooter:t,skipIfEmpty:i},n){let s={committed:!1,action:()=>{e==null||e()}};i?this.uncommitted.add(s):(s.action(),s.committed=!0);let o=Date.now();try{return await n()}catch(a){throw this.reportExceptionOnce(a),a}finally{let a=Date.now();this.uncommitted.delete(s),s.committed&&(t==null||t(a-o))}}startTimerImpl(e,t,i){let n=typeof t=="function"?{}:t;return{cb:typeof t=="function"?t:i,reportHeader:()=>{this.reportInfo(null,`\u250C ${e}`),this.indent+=1,iB!==null&&!this.json&&this.includeInfos&&this.stdout.write(iB.start(e))},reportFooter:o=>{this.indent-=1,iB!==null&&!this.json&&this.includeInfos&&this.stdout.write(iB.end(e)),this.configuration.get("enableTimers")&&o>200?this.reportInfo(null,`\u2514 Completed in ${tt(this.configuration,o,Ye.DURATION)}`):this.reportInfo(null,"\u2514 Completed")},skipIfEmpty:n.skipIfEmpty}}startTimerSync(e,t,i){let o=this.startTimerImpl(e,t,i),{cb:n}=o,s=Or(o,["cb"]);return this.startSectionSync(s,n)}async startTimerPromise(e,t,i){let o=this.startTimerImpl(e,t,i),{cb:n}=o,s=Or(o,["cb"]);return this.startSectionPromise(s,n)}async startCacheReport(e){let t=this.configuration.get("preferAggregateCacheInfo")?{cacheHitCount:this.cacheHitCount,cacheMissCount:this.cacheMissCount}:null;try{return await e()}catch(i){throw this.reportExceptionOnce(i),i}finally{t!==null&&this.reportCacheChanges(t)}}reportSeparator(){this.indent===0?this.writeLineWithForgettableReset(""):this.reportInfo(null,"")}reportInfo(e,t){if(!this.includeInfos)return;this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"",s=`${tt(this.configuration,"\u27A4","blueBright")} ${n}${this.formatIndent()}${t}`;if(this.json)this.reportJson({type:"info",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t});else if(this.forgettableNames.has(e))if(this.forgettableLines.push(s),this.forgettableLines.length>this.forgettableBufferSize){for(;this.forgettableLines.length>this.forgettableBufferSize;)this.forgettableLines.shift();this.writeLines(this.forgettableLines,{truncate:!0})}else this.writeLine(s,{truncate:!0});else this.writeLineWithForgettableReset(s)}reportWarning(e,t){if(this.warningCount+=1,!this.includeWarnings)return;this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"";this.json?this.reportJson({type:"warning",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t}):this.writeLineWithForgettableReset(`${tt(this.configuration,"\u27A4","yellowBright")} ${n}${this.formatIndent()}${t}`)}reportError(e,t){this.errorCount+=1,this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"";this.json?this.reportJson({type:"error",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t}):this.writeLineWithForgettableReset(`${tt(this.configuration,"\u27A4","redBright")} ${n}${this.formatIndent()}${t}`,{truncate:!1})}reportProgress(e){if(this.progressStyle===null)return te(N({},Promise.resolve()),{stop:()=>{}});if(e.hasProgress&&e.hasTitle)throw new Error("Unimplemented: Progress bars can't have both progress and titles.");let t=!1,i=Promise.resolve().then(async()=>{let s={progress:e.hasProgress?0:void 0,title:e.hasTitle?"":void 0};this.progress.set(e,{definition:s,lastScaledSize:e.hasProgress?-1:void 0,lastTitle:void 0}),this.refreshProgress({delta:-1});for await(let{progress:o,title:a}of e)t||s.progress===o&&s.title===a||(s.progress=o,s.title=a,this.refreshProgress());n()}),n=()=>{t||(t=!0,this.progress.delete(e),this.refreshProgress({delta:1}))};return te(N({},i),{stop:n})}reportJson(e){this.json&&this.writeLineWithForgettableReset(`${JSON.stringify(e)}`)}async finalize(){if(!this.includeFooter)return;let e="";this.errorCount>0?e="Failed with errors":this.warningCount>0?e="Done with warnings":e="Done";let t=tt(this.configuration,Date.now()-this.startTime,Ye.DURATION),i=this.configuration.get("enableTimers")?`${e} in ${t}`:e;this.errorCount>0?this.reportError(X.UNNAMED,i):this.warningCount>0?this.reportWarning(X.UNNAMED,i):this.reportInfo(X.UNNAMED,i)}writeLine(e,{truncate:t}={}){this.clearProgress({clear:!0}),this.stdout.write(`${this.truncate(e,{truncate:t})} -`),this.writeProgress()}writeLineWithForgettableReset(e,{truncate:t}={}){this.forgettableLines=[],this.writeLine(e,{truncate:t})}writeLines(e,{truncate:t}={}){this.clearProgress({delta:e.length});for(let i of e)this.stdout.write(`${this.truncate(i,{truncate:t})} -`);this.writeProgress()}reportCacheChanges({cacheHitCount:e,cacheMissCount:t}){let i=this.cacheHitCount-e,n=this.cacheMissCount-t;if(i===0&&n===0)return;let s="";this.cacheHitCount>1?s+=`${this.cacheHitCount} packages were already cached`:this.cacheHitCount===1?s+=" - one package was already cached":s+="No packages were cached",this.cacheHitCount>0?this.cacheMissCount>1?s+=`, ${this.cacheMissCount} had to be fetched`:this.cacheMissCount===1&&(s+=`, one had to be fetched (${It(this.configuration,this.lastCacheMiss)})`):this.cacheMissCount>1?s+=` - ${this.cacheMissCount} packages had to be fetched`:this.cacheMissCount===1&&(s+=` - one package had to be fetched (${It(this.configuration,this.lastCacheMiss)})`),this.reportInfo(X.FETCH_NOT_CACHED,s)}commit(){let e=this.uncommitted;this.uncommitted=new Set;for(let t of e)t.committed=!0,t.action()}clearProgress({delta:e=0,clear:t=!1}){this.progressStyle!==null&&this.progress.size+e>0&&(this.stdout.write(`[${this.progress.size+e}A`),(e>0||t)&&this.stdout.write(""))}writeProgress(){if(this.progressStyle===null||(this.progressTimeout!==null&&clearTimeout(this.progressTimeout),this.progressTimeout=null,this.progress.size===0))return;let e=Date.now();e-this.progressTime>M9&&(this.progressFrame=(this.progressFrame+1)%O9.length,this.progressTime=e);let t=O9[this.progressFrame];for(let i of this.progress.values()){let n="";if(typeof i.lastScaledSize!="undefined"){let l=this.progressStyle.chars[0].repeat(i.lastScaledSize),c=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-i.lastScaledSize);n=` ${l}${c}`}let s=this.formatName(null),o=s?`${s}: `:"",a=i.definition.title?` ${i.definition.title}`:"";this.stdout.write(`${tt(this.configuration,"\u27A4","blueBright")} ${o}${t}${n}${a} -`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress({force:!0})},M9)}refreshProgress({delta:e=0,force:t=!1}={}){let i=!1,n=!1;if(t||this.progress.size===0)i=!0;else for(let s of this.progress.values()){let o=typeof s.definition.progress!="undefined"?Math.trunc(this.progressMaxScaledSize*s.definition.progress):void 0,a=s.lastScaledSize;s.lastScaledSize=o;let l=s.lastTitle;if(s.lastTitle=s.definition.title,o!==a||(n=l!==s.definition.title)){i=!0;break}}i&&(this.clearProgress({delta:e,clear:n}),this.writeProgress())}truncate(e,{truncate:t}={}){return this.progressStyle===null&&(t=!1),typeof t=="undefined"&&(t=this.configuration.get("preferTruncatedLines")),t&&(e=(0,T9.default)(e,0,this.stdout.columns-1)),e}formatName(e){return K9(e,{configuration:this.configuration,json:this.json})}formatNameWithHyperlink(e){return tD(e,{configuration:this.configuration,json:this.json})}formatIndent(){return"\u2502 ".repeat(this.indent)}};var Kr="3.2.3";var hn;(function(n){n.Yarn1="Yarn Classic",n.Yarn2="Yarn",n.Npm="npm",n.Pnpm="pnpm"})(hn||(hn={}));async function lA(r,e,t,i=[]){if(process.platform==="win32"){let n=`@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"${t}" ${i.map(s=>`"${s.replace('"','""')}"`).join(" ")} %*`;await U.writeFilePromise(x.format({dir:r,name:e,ext:".cmd"}),n)}await U.writeFilePromise(x.join(r,e),`#!/bin/sh -exec "${t}" ${i.map(n=>`'${n.replace(/'/g,`'"'"'`)}'`).join(" ")} "$@" -`,{mode:493})}async function G9(r){let e=await At.tryFind(r);if(e==null?void 0:e.packageManager){let i=cw(e.packageManager);if(i==null?void 0:i.name){let n=`found ${JSON.stringify({packageManager:e.packageManager})} in manifest`,[s]=i.reference.split(".");switch(i.name){case"yarn":return{packageManager:Number(s)===1?hn.Yarn1:hn.Yarn2,reason:n};case"npm":return{packageManager:hn.Npm,reason:n};case"pnpm":return{packageManager:hn.Pnpm,reason:n}}}}let t;try{t=await U.readFilePromise(x.join(r,xt.lockfile),"utf8")}catch{}return t!==void 0?t.match(/^__metadata:$/m)?{packageManager:hn.Yarn2,reason:'"__metadata" key found in yarn.lock'}:{packageManager:hn.Yarn1,reason:'"__metadata" key not found in yarn.lock, must be a Yarn classic lockfile'}:U.existsSync(x.join(r,"package-lock.json"))?{packageManager:hn.Npm,reason:`found npm's "package-lock.json" lockfile`}:U.existsSync(x.join(r,"pnpm-lock.yaml"))?{packageManager:hn.Pnpm,reason:`found pnpm's "pnpm-lock.yaml" lockfile`}:null}async function qd({project:r,locator:e,binFolder:t,lifecycleScript:i}){var l,c;let n={};for(let[u,g]of Object.entries(process.env))typeof g!="undefined"&&(n[u.toLowerCase()!=="path"?u:"PATH"]=g);let s=H.fromPortablePath(t);n.BERRY_BIN_FOLDER=H.fromPortablePath(s);let o=process.env.COREPACK_ROOT?H.join(process.env.COREPACK_ROOT,"dist/yarn.js"):process.argv[1];if(await Promise.all([lA(t,"node",process.execPath),...Kr!==null?[lA(t,"run",process.execPath,[o,"run"]),lA(t,"yarn",process.execPath,[o]),lA(t,"yarnpkg",process.execPath,[o]),lA(t,"node-gyp",process.execPath,[o,"run","--top-level","node-gyp"])]:[]]),r&&(n.INIT_CWD=H.fromPortablePath(r.configuration.startingCwd),n.PROJECT_CWD=H.fromPortablePath(r.cwd)),n.PATH=n.PATH?`${s}${H.delimiter}${n.PATH}`:`${s}`,n.npm_execpath=`${s}${H.sep}yarn`,n.npm_node_execpath=`${s}${H.sep}node`,e){if(!r)throw new Error("Assertion failed: Missing project");let u=r.tryWorkspaceByLocator(e),g=u?(l=u.manifest.version)!=null?l:"":(c=r.storedPackages.get(e.locatorHash).version)!=null?c:"";n.npm_package_name=Ot(e),n.npm_package_version=g;let f;if(u)f=u.cwd;else{let h=r.storedPackages.get(e.locatorHash);if(!h)throw new Error(`Package for ${It(r.configuration,e)} not found in the project`);let p=r.configuration.getLinkers(),m={project:r,report:new Je({stdout:new Il.PassThrough,configuration:r.configuration})},y=p.find(b=>b.supportsPackage(h,m));if(!y)throw new Error(`The package ${It(r.configuration,h)} isn't supported by any of the available linkers`);f=await y.findPackageLocation(h,m)}n.npm_package_json=H.fromPortablePath(x.join(f,xt.manifest))}let a=Kr!==null?`yarn/${Kr}`:`yarn/${Mg("@yarnpkg/core").version}-core`;return n.npm_config_user_agent=`${a} npm/? node/${process.version} ${process.platform} ${process.arch}`,i&&(n.npm_lifecycle_event=i),r&&await r.configuration.triggerHook(u=>u.setupScriptEnvironment,r,n,async(u,g,f)=>await lA(t,Jr(u),g,f)),n}var YDe=2,qDe=(0,j9.default)(YDe);async function JDe(r,e,{configuration:t,report:i,workspace:n=null,locator:s=null}){await qDe(async()=>{await U.mktempPromise(async o=>{let a=x.join(o,"pack.log"),l=null,{stdout:c,stderr:u}=t.getSubprocessStreams(a,{prefix:H.fromPortablePath(r),report:i}),g=s&&ta(s)?fd(s):s,f=g?Fs(g):"an external project";c.write(`Packing ${f} from sources -`);let h=await G9(r),p;h!==null?(c.write(`Using ${h.packageManager} for bootstrap. Reason: ${h.reason} - -`),p=h.packageManager):(c.write(`No package manager configuration detected; defaulting to Yarn - -`),p=hn.Yarn2),await U.mktempPromise(async m=>{let y=await qd({binFolder:m}),v=new Map([[hn.Yarn1,async()=>{let T=n!==null?["workspace",n]:[],Y=x.join(r,xt.manifest),q=await U.readFilePromise(Y),$=await ia(process.execPath,[process.argv[1],"set","version","classic","--only-if-needed"],{cwd:r,env:y,stdin:l,stdout:c,stderr:u,end:ss.ErrorCode});if($.code!==0)return $.code;await U.writeFilePromise(Y,q),await U.appendFilePromise(x.join(r,".npmignore"),`/.yarn -`),c.write(` -`),delete y.NODE_ENV;let z=await ia("yarn",["install"],{cwd:r,env:y,stdin:l,stdout:c,stderr:u,end:ss.ErrorCode});if(z.code!==0)return z.code;c.write(` -`);let ne=await ia("yarn",[...T,"pack","--filename",H.fromPortablePath(e)],{cwd:r,env:y,stdin:l,stdout:c,stderr:u});return ne.code!==0?ne.code:0}],[hn.Yarn2,async()=>{let T=n!==null?["workspace",n]:[];y.YARN_ENABLE_INLINE_BUILDS="1";let Y=x.join(r,xt.lockfile);await U.existsPromise(Y)||await U.writeFilePromise(Y,"");let q=await ia("yarn",[...T,"pack","--install-if-needed","--filename",H.fromPortablePath(e)],{cwd:r,env:y,stdin:l,stdout:c,stderr:u});return q.code!==0?q.code:0}],[hn.Npm,async()=>{if(n!==null){let A=new Il.PassThrough,oe=Og(A);A.pipe(c,{end:!1});let ce=await ia("npm",["--version"],{cwd:r,env:y,stdin:l,stdout:A,stderr:u,end:ss.Never});if(A.end(),ce.code!==0)return c.end(),u.end(),ce.code;let Z=(await oe).toString().trim();if(!Jc(Z,">=7.x")){let O=ea(null,"npm"),L=rr(O,Z),de=rr(O,">=7.x");throw new Error(`Workspaces aren't supported by ${sr(t,L)}; please upgrade to ${sr(t,de)} (npm has been detected as the primary package manager for ${tt(t,r,Ye.PATH)})`)}}let T=n!==null?["--workspace",n]:[];delete y.npm_config_user_agent,delete y.npm_config_production,delete y.NPM_CONFIG_PRODUCTION,delete y.NODE_ENV;let Y=await ia("npm",["install"],{cwd:r,env:y,stdin:l,stdout:c,stderr:u,end:ss.ErrorCode});if(Y.code!==0)return Y.code;let q=new Il.PassThrough,$=Og(q);q.pipe(c);let z=await ia("npm",["pack","--silent",...T],{cwd:r,env:y,stdin:l,stdout:q,stderr:u});if(z.code!==0)return z.code;let ne=(await $).toString().trim().replace(/^.*\n/s,""),ee=x.resolve(r,H.toPortablePath(ne));return await U.renamePromise(ee,e),0}]]).get(p);if(typeof v=="undefined")throw new Error("Assertion failed: Unsupported workflow");let k=await v();if(!(k===0||typeof k=="undefined"))throw U.detachTemp(o),new ct(X.PACKAGE_PREPARATION_FAILED,`Packing the package failed (exit code ${k}, logs can be found here: ${tt(t,a,Ye.PATH)})`)})})})}async function WDe(r,e,{project:t}){let i=t.tryWorkspaceByLocator(r);if(i!==null)return rD(i,e);let n=t.storedPackages.get(r.locatorHash);if(!n)throw new Error(`Package for ${It(t.configuration,r)} not found in the project`);return await ys.openPromise(async s=>{let o=t.configuration,a=t.configuration.getLinkers(),l={project:t,report:new Je({stdout:new Il.PassThrough,configuration:o})},c=a.find(h=>h.supportsPackage(n,l));if(!c)throw new Error(`The package ${It(t.configuration,n)} isn't supported by any of the available linkers`);let u=await c.findPackageLocation(n,l),g=new _t(u,{baseFs:s});return(await At.find(Me.dot,{baseFs:g})).scripts.has(e)},{libzip:await fn()})}async function sB(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await U.mktempPromise(async l=>{let{manifest:c,env:u,cwd:g}=await Y9(r,{project:n,binFolder:l,cwd:i,lifecycleScript:e}),f=c.scripts.get(e);if(typeof f=="undefined")return 1;let h=async()=>await Zw(f,t,{cwd:g,env:u,stdin:s,stdout:o,stderr:a});return await(await n.configuration.reduceHook(m=>m.wrapScriptExecution,h,n,r,e,{script:f,args:t,cwd:g,env:u,stdin:s,stdout:o,stderr:a}))()})}async function iD(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await U.mktempPromise(async l=>{let{env:c,cwd:u}=await Y9(r,{project:n,binFolder:l,cwd:i});return await Zw(e,t,{cwd:u,env:c,stdin:s,stdout:o,stderr:a})})}async function zDe(r,{binFolder:e,cwd:t,lifecycleScript:i}){let n=await qd({project:r.project,locator:r.anchoredLocator,binFolder:e,lifecycleScript:i});return await Promise.all(Array.from(await q9(r),([s,[,o]])=>lA(e,Jr(s),process.execPath,[o]))),typeof t=="undefined"&&(t=x.dirname(await U.realpathPromise(x.join(r.cwd,"package.json")))),{manifest:r.manifest,binFolder:e,env:n,cwd:t}}async function Y9(r,{project:e,binFolder:t,cwd:i,lifecycleScript:n}){let s=e.tryWorkspaceByLocator(r);if(s!==null)return zDe(s,{binFolder:t,cwd:i,lifecycleScript:n});let o=e.storedPackages.get(r.locatorHash);if(!o)throw new Error(`Package for ${It(e.configuration,r)} not found in the project`);return await ys.openPromise(async a=>{let l=e.configuration,c=e.configuration.getLinkers(),u={project:e,report:new Je({stdout:new Il.PassThrough,configuration:l})},g=c.find(y=>y.supportsPackage(o,u));if(!g)throw new Error(`The package ${It(e.configuration,o)} isn't supported by any of the available linkers`);let f=await qd({project:e,locator:r,binFolder:t,lifecycleScript:n});await Promise.all(Array.from(await oB(r,{project:e}),([y,[,b]])=>lA(t,Jr(y),process.execPath,[b])));let h=await g.findPackageLocation(o,u),p=new _t(h,{baseFs:a}),m=await At.find(Me.dot,{baseFs:p});return typeof i=="undefined"&&(i=h),{manifest:m,binFolder:t,env:f,cwd:i}},{libzip:await fn()})}async function J9(r,e,t,{cwd:i,stdin:n,stdout:s,stderr:o}){return await sB(r.anchoredLocator,e,t,{cwd:i,project:r.project,stdin:n,stdout:s,stderr:o})}function rD(r,e){return r.manifest.scripts.has(e)}async function W9(r,e,{cwd:t,report:i}){let{configuration:n}=r.project,s=null;await U.mktempPromise(async o=>{let a=x.join(o,`${e}.log`),l=`# This file contains the result of Yarn calling the "${e}" lifecycle script inside a workspace ("${H.fromPortablePath(r.cwd)}") -`,{stdout:c,stderr:u}=n.getSubprocessStreams(a,{report:i,prefix:It(n,r.anchoredLocator),header:l});i.reportInfo(X.LIFECYCLE_SCRIPT,`Calling the "${e}" lifecycle script`);let g=await J9(r,e,[],{cwd:t,stdin:s,stdout:c,stderr:u});if(c.end(),u.end(),g!==0)throw U.detachTemp(o),new ct(X.LIFECYCLE_SCRIPT,`${(0,H9.default)(e)} script failed (exit code ${tt(n,g,Ye.NUMBER)}, logs can be found here: ${tt(n,a,Ye.PATH)}); run ${tt(n,`yarn ${e}`,Ye.CODE)} to investigate`)})}async function _De(r,e,t){rD(r,e)&&await W9(r,e,t)}async function oB(r,{project:e}){let t=e.configuration,i=new Map,n=e.storedPackages.get(r.locatorHash);if(!n)throw new Error(`Package for ${It(t,r)} not found in the project`);let s=new Il.Writable,o=t.getLinkers(),a={project:e,report:new Je({configuration:t,stdout:s})},l=new Set([r.locatorHash]);for(let u of n.dependencies.values()){let g=e.storedResolutions.get(u.descriptorHash);if(!g)throw new Error(`Assertion failed: The resolution (${sr(t,u)}) should have been registered`);l.add(g)}let c=await Promise.all(Array.from(l,async u=>{let g=e.storedPackages.get(u);if(!g)throw new Error(`Assertion failed: The package (${u}) should have been registered`);if(g.bin.size===0)return Vo.skip;let f=o.find(p=>p.supportsPackage(g,a));if(!f)return Vo.skip;let h=null;try{h=await f.findPackageLocation(g,a)}catch(p){if(p.code==="LOCATOR_NOT_INSTALLED")return Vo.skip;throw p}return{dependency:g,packageLocation:h}}));for(let u of c){if(u===Vo.skip)continue;let{dependency:g,packageLocation:f}=u;for(let[h,p]of g.bin)i.set(h,[g,H.fromPortablePath(x.resolve(f,p))])}return i}async function q9(r){return await oB(r.anchoredLocator,{project:r.project})}async function z9(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a,nodeArgs:l=[],packageAccessibleBinaries:c}){c!=null||(c=await oB(r,{project:n}));let u=c.get(e);if(!u)throw new Error(`Binary not found (${e}) for ${It(n.configuration,r)}`);return await U.mktempPromise(async g=>{let[,f]=u,h=await qd({project:n,locator:r,binFolder:g});await Promise.all(Array.from(c,([m,[,y]])=>lA(h.BERRY_BIN_FOLDER,Jr(m),process.execPath,[y])));let p;try{p=await ia(process.execPath,[...l,f,...t],{cwd:i,env:h,stdin:s,stdout:o,stderr:a})}finally{await U.removePromise(h.BERRY_BIN_FOLDER)}return p.code})}async function VDe(r,e,t,{cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a}){return await z9(r.anchoredLocator,e,t,{project:r.project,cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a})}var Bi={};ft(Bi,{convertToZip:()=>oNe,extractArchiveTo:()=>ANe,makeArchiveFromDirectory:()=>sNe});var K6=ge(require("stream")),H6=ge(N6());var L6=ge(require("os")),T6=ge(fg()),O6=ge(require("worker_threads")),Rl=Symbol("kTaskInfo"),dR=class{constructor(e){this.source=e;this.workers=[];this.limit=(0,T6.default)(Math.max(1,(0,L6.cpus)().length));this.cleanupInterval=setInterval(()=>{if(this.limit.pendingCount===0&&this.limit.activeCount===0){let t=this.workers.pop();t?t.terminate():clearInterval(this.cleanupInterval)}},5e3).unref()}createWorker(){this.cleanupInterval.refresh();let e=new O6.Worker(this.source,{eval:!0,execArgv:[...process.execArgv,"--unhandled-rejections=strict"]});return e.on("message",t=>{if(!e[Rl])throw new Error("Assertion failed: Worker sent a result without having a task assigned");e[Rl].resolve(t),e[Rl]=null,e.unref(),this.workers.push(e)}),e.on("error",t=>{var i;(i=e[Rl])==null||i.reject(t),e[Rl]=null}),e.on("exit",t=>{var i;t!==0&&((i=e[Rl])==null||i.reject(new Error(`Worker exited with code ${t}`))),e[Rl]=null}),e}run(e){return this.limit(()=>{var i;let t=(i=this.workers.pop())!=null?i:this.createWorker();return t.ref(),new Promise((n,s)=>{t[Rl]={resolve:n,reject:s},t.postMessage(e)})})}};var j6=ge(U6());async function sNe(r,{baseFs:e=new ar,prefixPath:t=Me.root,compressionLevel:i,inMemory:n=!1}={}){let s=await fn(),o;if(n)o=new li(null,{libzip:s,level:i});else{let l=await U.mktempPromise(),c=x.join(l,"archive.zip");o=new li(c,{create:!0,libzip:s,level:i})}let a=x.resolve(Me.root,t);return await o.copyPromise(a,r,{baseFs:e,stableTime:!0,stableSort:!0}),o}var G6;async function oNe(r,e){let t=await U.mktempPromise(),i=x.join(t,"archive.zip");return G6||(G6=new dR((0,j6.getContent)())),await G6.run({tmpFile:i,tgz:r,opts:e}),new li(i,{libzip:await fn(),level:e.compressionLevel})}async function*aNe(r){let e=new H6.default.Parse,t=new K6.PassThrough({objectMode:!0,autoDestroy:!0,emitClose:!0});e.on("entry",i=>{t.write(i)}),e.on("error",i=>{t.destroy(i)}),e.on("close",()=>{t.destroyed||t.end()}),e.end(r);for await(let i of t){let n=i;yield n,n.resume()}}async function ANe(r,e,{stripComponents:t=0,prefixPath:i=Me.dot}={}){var s,o;function n(a){if(a.path[0]==="/")return!0;let l=a.path.split(/\//g);return!!(l.some(c=>c==="..")||l.length<=t)}for await(let a of aNe(r)){if(n(a))continue;let l=x.normalize(H.toPortablePath(a.path)).replace(/\/$/,"").split(/\//g);if(l.length<=t)continue;let c=l.slice(t).join("/"),u=x.join(i,c),g=420;switch((a.type==="Directory"||(((s=a.mode)!=null?s:0)&73)!=0)&&(g|=73),a.type){case"Directory":e.mkdirpSync(x.dirname(u),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),e.mkdirSync(u,{mode:g}),e.utimesSync(u,Rr.SAFE_TIME,Rr.SAFE_TIME);break;case"OldFile":case"File":e.mkdirpSync(x.dirname(u),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),e.writeFileSync(u,await Og(a),{mode:g}),e.utimesSync(u,Rr.SAFE_TIME,Rr.SAFE_TIME);break;case"SymbolicLink":e.mkdirpSync(x.dirname(u),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),e.symlinkSync(a.linkpath,u),(o=e.lutimesSync)==null||o.call(e,u,Rr.SAFE_TIME,Rr.SAFE_TIME);break}}return e}var ls={};ft(ls,{emitList:()=>lNe,emitTree:()=>_6,treeNodeToJson:()=>z6,treeNodeToTreeify:()=>W6});var J6=ge(q6());function W6(r,{configuration:e}){let t={},i=(n,s)=>{let o=Array.isArray(n)?n.entries():Object.entries(n);for(let[a,{label:l,value:c,children:u}]of o){let g=[];typeof l!="undefined"&&g.push(Fy(e,l,Oc.BOLD)),typeof c!="undefined"&&g.push(tt(e,c[0],c[1])),g.length===0&&g.push(Fy(e,`${a}`,Oc.BOLD));let f=g.join(": "),h=s[f]={};typeof u!="undefined"&&i(u,h)}};if(typeof r.children=="undefined")throw new Error("The root node must only contain children");return i(r.children,t),t}function z6(r){let e=t=>{var s;if(typeof t.children=="undefined"){if(typeof t.value=="undefined")throw new Error("Assertion failed: Expected a value to be set if the children are missing");return Mc(t.value[0],t.value[1])}let i=Array.isArray(t.children)?t.children.entries():Object.entries((s=t.children)!=null?s:{}),n=Array.isArray(t.children)?[]:{};for(let[o,a]of i)n[o]=e(a);return typeof t.value=="undefined"?n:{value:Mc(t.value[0],t.value[1]),children:n}};return e(r)}function lNe(r,{configuration:e,stdout:t,json:i}){let n=r.map(s=>({value:s}));_6({children:n},{configuration:e,stdout:t,json:i})}function _6(r,{configuration:e,stdout:t,json:i,separators:n=0}){var o;if(i){let a=Array.isArray(r.children)?r.children.values():Object.values((o=r.children)!=null?o:{});for(let l of a)t.write(`${JSON.stringify(z6(l))} -`);return}let s=(0,J6.asTree)(W6(r,{configuration:e}),!1,!1);if(n>=1&&(s=s.replace(/^([├└]─)/gm,`\u2502 -$1`).replace(/^│\n/,"")),n>=2)for(let a=0;a<2;++a)s=s.replace(/^([│ ].{2}[├│ ].{2}[^\n]+\n)(([│ ]).{2}[├└].{2}[^\n]*\n[│ ].{2}[│ ].{2}[├└]─)/gm,`$1$3 \u2502 -$2`).replace(/^│\n/,"");if(n>=3)throw new Error("Only the first two levels are accepted by treeUtils.emitTree");t.write(s)}var V6=ge(require("crypto")),ER=ge(require("fs"));var cNe=8,Nt=class{constructor(e,{configuration:t,immutable:i=t.get("enableImmutableCache"),check:n=!1}){this.markedFiles=new Set;this.mutexes=new Map;this.cacheId=`-${(0,V6.randomBytes)(8).toString("hex")}.tmp`;this.configuration=t,this.cwd=e,this.immutable=i,this.check=n;let s=t.get("cacheKeyOverride");if(s!==null)this.cacheKey=`${s}`;else{let o=t.get("compressionLevel"),a=o!==cc?`c${o}`:"";this.cacheKey=[cNe,a].join("")}}static async find(e,{immutable:t,check:i}={}){let n=new Nt(e.get("cacheFolder"),{configuration:e,immutable:t,check:i});return await n.setup(),n}get mirrorCwd(){if(!this.configuration.get("enableMirror"))return null;let e=`${this.configuration.get("globalFolder")}/cache`;return e!==this.cwd?e:null}getVersionFilename(e){return`${Wg(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,t){let n=uNe(t).slice(0,10);return`${Wg(e)}-${n}.zip`}getLocatorPath(e,t,i={}){var s;return this.mirrorCwd===null||((s=i.unstablePackages)==null?void 0:s.has(e.locatorHash))?x.resolve(this.cwd,this.getVersionFilename(e)):t===null||IR(t)!==this.cacheKey?null:x.resolve(this.cwd,this.getChecksumFilename(e,t))}getLocatorMirrorPath(e){let t=this.mirrorCwd;return t!==null?x.resolve(t,this.getVersionFilename(e)):null}async setup(){if(!this.configuration.get("enableGlobalCache"))if(this.immutable){if(!await U.existsPromise(this.cwd))throw new ct(X.IMMUTABLE_CACHE,"Cache path does not exist.")}else{await U.mkdirPromise(this.cwd,{recursive:!0});let e=x.resolve(this.cwd,".gitignore");await U.changeFilePromise(e,`/.gitignore -*.flock -*.tmp -`)}(this.mirrorCwd||!this.immutable)&&await U.mkdirPromise(this.mirrorCwd||this.cwd,{recursive:!0})}async fetchPackageFromCache(e,t,a){var l=a,{onHit:i,onMiss:n,loader:s}=l,o=Or(l,["onHit","onMiss","loader"]);var A;let c=this.getLocatorMirrorPath(e),u=new ar,g=()=>{let oe=new li(null,{libzip:Y}),ce=x.join(Me.root,tx(e));return oe.mkdirSync(ce,{recursive:!0}),oe.writeJsonSync(x.join(ce,xt.manifest),{name:Ot(e),mocked:!0}),oe},f=async(oe,ce=null)=>{var O;if(ce===null&&((O=o.unstablePackages)==null?void 0:O.has(e.locatorHash)))return null;let Z=!o.skipIntegrityCheck||!t?`${this.cacheKey}/${await ow(oe)}`:t;if(ce!==null){let L=!o.skipIntegrityCheck||!t?`${this.cacheKey}/${await ow(ce)}`:t;if(Z!==L)throw new ct(X.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}if(t!==null&&Z!==t){let L;switch(this.check?L="throw":IR(t)!==IR(Z)?L="update":L=this.configuration.get("checksumBehavior"),L){case"ignore":return t;case"update":return Z;default:case"throw":throw new ct(X.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the expected checksum")}}return Z},h=async oe=>{if(!s)throw new Error(`Cache check required but no loader configured for ${It(this.configuration,e)}`);let ce=await s(),Z=ce.getRealPath();return ce.saveAndClose(),await U.chmodPromise(Z,420),await f(oe,Z)},p=async()=>{if(c===null||!await U.existsPromise(c)){let oe=await s(),ce=oe.getRealPath();return oe.saveAndClose(),{source:"loader",path:ce}}return{source:"mirror",path:c}},m=async()=>{if(!s)throw new Error(`Cache entry required but missing for ${It(this.configuration,e)}`);if(this.immutable)throw new ct(X.IMMUTABLE_CACHE,`Cache entry required but missing for ${It(this.configuration,e)}`);let{path:oe,source:ce}=await p(),Z=await f(oe),O=this.getLocatorPath(e,Z,o);if(!O)throw new Error("Assertion failed: Expected the cache path to be available");let L=[];ce!=="mirror"&&c!==null&&L.push(async()=>{let Be=`${c}${this.cacheId}`;await U.copyFilePromise(oe,Be,ER.default.constants.COPYFILE_FICLONE),await U.chmodPromise(Be,420),await U.renamePromise(Be,c)}),(!o.mirrorWriteOnly||c===null)&&L.push(async()=>{let Be=`${O}${this.cacheId}`;await U.copyFilePromise(oe,Be,ER.default.constants.COPYFILE_FICLONE),await U.chmodPromise(Be,420),await U.renamePromise(Be,O)});let de=o.mirrorWriteOnly&&c!=null?c:O;return await Promise.all(L.map(Be=>Be())),[!1,de,Z]},y=async()=>{let ce=(async()=>{var Ge;let Z=this.getLocatorPath(e,t,o),O=Z!==null?await u.existsPromise(Z):!1,L=!!((Ge=o.mockedPackages)==null?void 0:Ge.has(e.locatorHash))&&(!this.check||!O),de=L||O,Be=de?i:n;if(Be&&Be(),de){let re=null,se=Z;return L||(re=this.check?await h(se):await f(se)),[L,se,re]}else return m()})();this.mutexes.set(e.locatorHash,ce);try{return await ce}finally{this.mutexes.delete(e.locatorHash)}};for(let oe;oe=this.mutexes.get(e.locatorHash);)await oe;let[b,v,k]=await y();this.markedFiles.add(v);let T,Y=await fn(),q=b?()=>g():()=>new li(v,{baseFs:u,libzip:Y,readOnly:!0}),$=new Vh(()=>Fv(()=>T=q(),oe=>`Failed to open the cache entry for ${It(this.configuration,e)}: ${oe}`),x),z=new La(v,{baseFs:$,pathUtils:x}),ne=()=>{T==null||T.discardAndClose()},ee=((A=o.unstablePackages)==null?void 0:A.has(e.locatorHash))?null:k;return[z,ne,ee]}};function IR(r){let e=r.indexOf("/");return e!==-1?r.slice(0,e):null}function uNe(r){let e=r.indexOf("/");return e!==-1?r.slice(e+1):r}var cs;(function(t){t[t.SCRIPT=0]="SCRIPT",t[t.SHELLCODE=1]="SHELLCODE"})(cs||(cs={}));var dA=class extends Ji{constructor({configuration:e,stdout:t,suggestInstall:i=!0}){super();this.errorCount=0;sd(this,{configuration:e}),this.configuration=e,this.stdout=t,this.suggestInstall=i}static async start(e,t){let i=new this(e);try{await t(i)}catch(n){i.reportExceptionOnce(n)}finally{await i.finalize()}return i}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(e){}reportCacheMiss(e){}startSectionSync(e,t){return t()}async startSectionPromise(e,t){return await t()}startTimerSync(e,t,i){return(typeof t=="function"?t:i)()}async startTimerPromise(e,t,i){return await(typeof t=="function"?t:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){this.errorCount+=1,this.stdout.write(`${tt(this.configuration,"\u27A4","redBright")} ${this.formatNameWithHyperlink(e)}: ${t} -`)}reportProgress(e){let t=Promise.resolve().then(async()=>{for await(let{}of e);}),i=()=>{};return te(N({},t),{stop:i})}reportJson(e){}async finalize(){this.errorCount>0&&(this.stdout.write(` -`),this.stdout.write(`${tt(this.configuration,"\u27A4","redBright")} Errors happened when preparing the environment required to run this command. -`),this.suggestInstall&&this.stdout.write(`${tt(this.configuration,"\u27A4","redBright")} This might be caused by packages being missing from the lockfile, in which case running "yarn install" might help. -`))}formatNameWithHyperlink(e){return tD(e,{configuration:this.configuration,json:!1})}};var n0=ge(require("crypto"));function CA(){}CA.prototype={diff:function(e,t){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},n=i.callback;typeof i=="function"&&(n=i,i={}),this.options=i;var s=this;function o(m){return n?(setTimeout(function(){n(void 0,m)},0),!0):m}e=this.castInput(e),t=this.castInput(t),e=this.removeEmpty(this.tokenize(e)),t=this.removeEmpty(this.tokenize(t));var a=t.length,l=e.length,c=1,u=a+l;i.maxEditLength&&(u=Math.min(u,i.maxEditLength));var g=[{newPos:-1,components:[]}],f=this.extractCommon(g[0],t,e,0);if(g[0].newPos+1>=a&&f+1>=l)return o([{value:this.join(t),count:t.length}]);function h(){for(var m=-1*c;m<=c;m+=2){var y=void 0,b=g[m-1],v=g[m+1],k=(v?v.newPos:0)-m;b&&(g[m-1]=void 0);var T=b&&b.newPos+1<a,Y=v&&0<=k&&k<l;if(!T&&!Y){g[m]=void 0;continue}if(!T||Y&&b.newPos<v.newPos?(y=fNe(v),s.pushComponent(y.components,void 0,!0)):(y=b,y.newPos++,s.pushComponent(y.components,!0,void 0)),k=s.extractCommon(y,t,e,m),y.newPos+1>=a&&k+1>=l)return o(gNe(s,y.components,t,e,s.useLongestToken));g[m]=y}c++}if(n)(function m(){setTimeout(function(){if(c>u)return n();h()||m()},0)})();else for(;c<=u;){var p=h();if(p)return p}},pushComponent:function(e,t,i){var n=e[e.length-1];n&&n.added===t&&n.removed===i?e[e.length-1]={count:n.count+1,added:t,removed:i}:e.push({count:1,added:t,removed:i})},extractCommon:function(e,t,i,n){for(var s=t.length,o=i.length,a=e.newPos,l=a-n,c=0;a+1<s&&l+1<o&&this.equals(t[a+1],i[l+1]);)a++,l++,c++;return c&&e.components.push({count:c}),e.newPos=a,l},equals:function(e,t){return this.options.comparator?this.options.comparator(e,t):e===t||this.options.ignoreCase&&e.toLowerCase()===t.toLowerCase()},removeEmpty:function(e){for(var t=[],i=0;i<e.length;i++)e[i]&&t.push(e[i]);return t},castInput:function(e){return e},tokenize:function(e){return e.split("")},join:function(e){return e.join("")}};function gNe(r,e,t,i,n){for(var s=0,o=e.length,a=0,l=0;s<o;s++){var c=e[s];if(c.removed){if(c.value=r.join(i.slice(l,l+c.count)),l+=c.count,s&&e[s-1].added){var g=e[s-1];e[s-1]=e[s],e[s]=g}}else{if(!c.added&&n){var u=t.slice(a,a+c.count);u=u.map(function(h,p){var m=i[l+p];return m.length>h.length?m:h}),c.value=r.join(u)}else c.value=r.join(t.slice(a,a+c.count));a+=c.count,c.added||(l+=c.count)}}var f=e[o-1];return o>1&&typeof f.value=="string"&&(f.added||f.removed)&&r.equals("",f.value)&&(e[o-2].value+=f.value,e.pop()),e}function fNe(r){return{newPos:r.newPos,components:r.components.slice(0)}}var oAt=new CA;var X6=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,Z6=/\S/,$6=new CA;$6.equals=function(r,e){return this.options.ignoreCase&&(r=r.toLowerCase(),e=e.toLowerCase()),r===e||this.options.ignoreWhitespace&&!Z6.test(r)&&!Z6.test(e)};$6.tokenize=function(r){for(var e=r.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),t=0;t<e.length-1;t++)!e[t+1]&&e[t+2]&&X6.test(e[t])&&X6.test(e[t+2])&&(e[t]+=e[t+2],e.splice(t+1,2),t--);return e};var yR=new CA;yR.tokenize=function(r){var e=[],t=r.split(/(\n|\r\n)/);t[t.length-1]||t.pop();for(var i=0;i<t.length;i++){var n=t[i];i%2&&!this.options.newlineIsToken?e[e.length-1]+=n:(this.options.ignoreWhitespace&&(n=n.trim()),e.push(n))}return e};function hNe(r,e,t){return yR.diff(r,e,t)}var pNe=new CA;pNe.tokenize=function(r){return r.split(/(\S.+?[.!?])(?=\s+|$)/)};var dNe=new CA;dNe.tokenize=function(r){return r.split(/([{}:;,]|\s+)/)};function _B(r){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?_B=function(e){return typeof e}:_B=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_B(r)}function wR(r){return CNe(r)||mNe(r)||ENe(r)||INe()}function CNe(r){if(Array.isArray(r))return BR(r)}function mNe(r){if(typeof Symbol!="undefined"&&Symbol.iterator in Object(r))return Array.from(r)}function ENe(r,e){if(!!r){if(typeof r=="string")return BR(r,e);var t=Object.prototype.toString.call(r).slice(8,-1);if(t==="Object"&&r.constructor&&(t=r.constructor.name),t==="Map"||t==="Set")return Array.from(r);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return BR(r,e)}}function BR(r,e){(e==null||e>r.length)&&(e=r.length);for(var t=0,i=new Array(e);t<e;t++)i[t]=r[t];return i}function INe(){throw new TypeError(`Invalid attempt to spread non-iterable instance. -In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var yNe=Object.prototype.toString,cC=new CA;cC.useLongestToken=!0;cC.tokenize=yR.tokenize;cC.castInput=function(r){var e=this.options,t=e.undefinedReplacement,i=e.stringifyReplacer,n=i===void 0?function(s,o){return typeof o=="undefined"?t:o}:i;return typeof r=="string"?r:JSON.stringify(bR(r,null,null,n),n," ")};cC.equals=function(r,e){return CA.prototype.equals.call(cC,r.replace(/,([\r\n])/g,"$1"),e.replace(/,([\r\n])/g,"$1"))};function bR(r,e,t,i,n){e=e||[],t=t||[],i&&(r=i(n,r));var s;for(s=0;s<e.length;s+=1)if(e[s]===r)return t[s];var o;if(yNe.call(r)==="[object Array]"){for(e.push(r),o=new Array(r.length),t.push(o),s=0;s<r.length;s+=1)o[s]=bR(r[s],e,t,i,n);return e.pop(),t.pop(),o}if(r&&r.toJSON&&(r=r.toJSON()),_B(r)==="object"&&r!==null){e.push(r),o={},t.push(o);var a=[],l;for(l in r)r.hasOwnProperty(l)&&a.push(l);for(a.sort(),s=0;s<a.length;s+=1)l=a[s],o[l]=bR(r[l],e,t,i,l);e.pop(),t.pop()}else o=r;return o}var QR=new CA;QR.tokenize=function(r){return r.slice()};QR.join=QR.removeEmpty=function(r){return r};function e7(r,e,t,i,n,s,o){o||(o={}),typeof o.context=="undefined"&&(o.context=4);var a=hNe(t,i,o);if(!a)return;a.push({value:"",lines:[]});function l(b){return b.map(function(v){return" "+v})}for(var c=[],u=0,g=0,f=[],h=1,p=1,m=function(v){var k=a[v],T=k.lines||k.value.replace(/\n$/,"").split(` -`);if(k.lines=T,k.added||k.removed){var Y;if(!u){var q=a[v-1];u=h,g=p,q&&(f=o.context>0?l(q.lines.slice(-o.context)):[],u-=f.length,g-=f.length)}(Y=f).push.apply(Y,wR(T.map(function(Z){return(k.added?"+":"-")+Z}))),k.added?p+=T.length:h+=T.length}else{if(u)if(T.length<=o.context*2&&v<a.length-2){var $;($=f).push.apply($,wR(l(T)))}else{var z,ne=Math.min(T.length,o.context);(z=f).push.apply(z,wR(l(T.slice(0,ne))));var ee={oldStart:u,oldLines:h-u+ne,newStart:g,newLines:p-g+ne,lines:f};if(v>=a.length-2&&T.length<=o.context){var A=/\n$/.test(t),oe=/\n$/.test(i),ce=T.length==0&&f.length>ee.oldLines;!A&&ce&&t.length>0&&f.splice(ee.oldLines,0,"\\ No newline at end of file"),(!A&&!ce||!oe)&&f.push("\\ No newline at end of file")}c.push(ee),u=0,g=0,f=[]}h+=T.length,p+=T.length}},y=0;y<a.length;y++)m(y);return{oldFileName:r,newFileName:e,oldHeader:n,newHeader:s,hunks:c}}var s0=ge(oZ()),AZ=ge(fg()),lZ=ge(ri()),MR=ge(require("util")),UR=ge(require("v8")),KR=ge(require("zlib"));var _Oe=[[/^(git(?:\+(?:https|ssh))?:\/\/.*(?:\.git)?)#(.*)$/,(r,e,t,i)=>`${t}#commit=${i}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(r,e,t="",i,n)=>`https://${t}github.com/${i}.git#commit=${n}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(r,e,t="",i,n)=>`https://${t}github.com/${i}.git#commit=${n}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@.+(?:\/|(?:%2f)))?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,r=>`npm:${r}`],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)(?:#|$)/,r=>`npm:${r}`],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,r=>`npm:${r}`],[/^https?:\/\/[^/]+\/.*\/(@[^/]+)\/([^/]+)\/-\/\1\/\2-(?:[.\d\w-]+)\.tgz(?:#|$)/,(r,e)=>uw({protocol:"npm:",source:null,selector:r,params:{__archiveUrl:e}})],[/^[^/]+\.tgz#[0-9a-f]+$/,r=>`npm:${r}`]],LR=class{constructor(e){this.resolver=e;this.resolutions=null}async setup(e,{report:t}){let i=x.join(e.cwd,e.configuration.get("lockfileFilename"));if(!U.existsSync(i))return;let n=await U.readFilePromise(i,"utf8"),s=Si(n);if(Object.prototype.hasOwnProperty.call(s,"__metadata"))return;let o=this.resolutions=new Map;for(let a of Object.keys(s)){let l=dd(a);if(!l){t.reportWarning(X.YARN_IMPORT_FAILED,`Failed to parse the string "${a}" into a proper descriptor`);continue}mo(l.range)&&(l=rr(l,`npm:${l.range}`));let{version:c,resolved:u}=s[a];if(!u)continue;let g;for(let[h,p]of _Oe){let m=u.match(h);if(m){g=p(c,...m);break}}if(!g){t.reportWarning(X.YARN_IMPORT_FAILED,`${sr(e.configuration,l)}: Only some patterns can be imported from legacy lockfiles (not "${u}")`);continue}let f=l;try{let h=Jg(l.range),p=dd(h.selector,!0);p&&(f=p)}catch{}o.set(l.descriptorHash,cn(f,g))}}supportsDescriptor(e,t){return this.resolutions?this.resolutions.has(e.descriptorHash):!1}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){if(!this.resolutions)throw new Error("Assertion failed: The resolution store should have been setup");let n=this.resolutions.get(e.descriptorHash);if(!n)throw new Error("Assertion failed: The resolution should have been registered");return await this.resolver.getCandidates(Vk(n),t,i)}async getSatisfying(e,t,i){return null}async resolve(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}};var TR=class{constructor(e){this.resolver=e}supportsDescriptor(e,t){return!!(t.project.storedResolutions.get(e.descriptorHash)||t.project.originalPackages.has(lw(e).locatorHash))}supportsLocator(e,t){return!!(t.project.originalPackages.has(e.locatorHash)&&!t.project.lockfileNeedsRefresh)}shouldPersistResolution(e,t){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,i){let n=i.project.originalPackages.get(lw(e).locatorHash);if(n)return[n];let s=i.project.storedResolutions.get(e.descriptorHash);if(!s)throw new Error("Expected the resolution to have been successful - resolution not found");if(n=i.project.originalPackages.get(s),!n)throw new Error("Expected the resolution to have been successful - package not found");return[n]}async getSatisfying(e,t,i){return null}async resolve(e,t){let i=t.project.originalPackages.get(e.locatorHash);if(!i)throw new Error("The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache");return i}};var OR=class{constructor(e){this.resolver=e}supportsDescriptor(e,t){return this.resolver.supportsDescriptor(e,t)}supportsLocator(e,t){return this.resolver.supportsLocator(e,t)}shouldPersistResolution(e,t){return this.resolver.shouldPersistResolution(e,t)}bindDescriptor(e,t,i){return this.resolver.bindDescriptor(e,t,i)}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,i){throw new ct(X.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async getSatisfying(e,t,i){throw new ct(X.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async resolve(e,t){throw new ct(X.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}};var di=class extends Ji{reportCacheHit(e){}reportCacheMiss(e){}startSectionSync(e,t){return t()}async startSectionPromise(e,t){return await t()}startTimerSync(e,t,i){return(typeof t=="function"?t:i)()}async startTimerPromise(e,t,i){return await(typeof t=="function"?t:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){}reportProgress(e){let t=Promise.resolve().then(async()=>{for await(let{}of e);}),i=()=>{};return te(N({},t),{stop:i})}reportJson(e){}async finalize(){}};var aZ=ge(zk());var mC=class{constructor(e,{project:t}){this.workspacesCwds=new Set;this.dependencies=new Map;this.project=t,this.cwd=e}async setup(){var s;this.manifest=(s=await At.tryFind(this.cwd))!=null?s:new At,this.relativeCwd=x.relative(this.project.cwd,this.cwd)||Me.dot;let e=this.manifest.name?this.manifest.name:ea(null,`${this.computeCandidateName()}-${ln(this.relativeCwd).substring(0,6)}`),t=this.manifest.version?this.manifest.version:"0.0.0";this.locator=cn(e,t),this.anchoredDescriptor=rr(this.locator,`${oi.protocol}${this.relativeCwd}`),this.anchoredLocator=cn(this.locator,`${oi.protocol}${this.relativeCwd}`);let i=this.manifest.workspaceDefinitions.map(({pattern:o})=>o),n=await(0,aZ.default)(i,{cwd:H.fromPortablePath(this.cwd),expandDirectories:!1,onlyDirectories:!0,onlyFiles:!1,ignore:["**/node_modules","**/.git","**/.yarn"]});n.sort();for(let o of n){let a=x.resolve(this.cwd,H.toPortablePath(o));U.existsSync(x.join(a,"package.json"))&&this.workspacesCwds.add(a)}}accepts(e){var o;let t=e.indexOf(":"),i=t!==-1?e.slice(0,t+1):null,n=t!==-1?e.slice(t+1):e;if(i===oi.protocol&&x.normalize(n)===this.relativeCwd||i===oi.protocol&&(n==="*"||n==="^"||n==="~"))return!0;let s=mo(n);return s?i===oi.protocol?s.test((o=this.manifest.version)!=null?o:"0.0.0"):this.project.configuration.get("enableTransparentWorkspaces")&&this.manifest.version!==null?s.test(this.manifest.version):!1:!1}computeCandidateName(){return this.cwd===this.project.cwd?"root-workspace":`${x.basename(this.cwd)}`||"unnamed-workspace"}getRecursiveWorkspaceDependencies({dependencies:e=At.hardDependencies}={}){let t=new Set,i=n=>{for(let s of e)for(let o of n.manifest[s].values()){let a=this.project.tryWorkspaceByDescriptor(o);a===null||t.has(a)||(t.add(a),i(a))}};return i(this),t}getRecursiveWorkspaceDependents({dependencies:e=At.hardDependencies}={}){let t=new Set,i=n=>{for(let s of this.project.workspaces)e.some(a=>[...s.manifest[a].values()].some(l=>{let c=this.project.tryWorkspaceByDescriptor(l);return c!==null&&pd(c.anchoredLocator,n.anchoredLocator)}))&&!t.has(s)&&(t.add(s),i(s))};return i(this),t}getRecursiveWorkspaceChildren(){let e=[];for(let t of this.workspacesCwds){let i=this.project.workspacesByCwd.get(t);i&&e.push(i,...i.getRecursiveWorkspaceChildren())}return e}async persistManifest(){let e={};this.manifest.exportTo(e);let t=x.join(this.cwd,At.fileName),i=`${JSON.stringify(e,null,this.manifest.indent)} -`;await U.changeFilePromise(t,i,{automaticNewlines:!0}),this.manifest.raw=e}};var cZ=6,VOe=1,XOe=/ *, */g,uZ=/\/$/,ZOe=32,$Oe=(0,MR.promisify)(KR.default.gzip),eMe=(0,MR.promisify)(KR.default.gunzip),Ci;(function(t){t.UpdateLockfile="update-lockfile",t.SkipBuild="skip-build"})(Ci||(Ci={}));var HR={restoreInstallersCustomData:["installersCustomData"],restoreResolutions:["accessibleLocators","conditionalLocators","disabledLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"],restoreBuildState:["storedBuildState"]},gZ=r=>ln(`${VOe}`,r),ze=class{constructor(e,{configuration:t}){this.resolutionAliases=new Map;this.workspaces=[];this.workspacesByCwd=new Map;this.workspacesByIdent=new Map;this.storedResolutions=new Map;this.storedDescriptors=new Map;this.storedPackages=new Map;this.storedChecksums=new Map;this.storedBuildState=new Map;this.accessibleLocators=new Set;this.conditionalLocators=new Set;this.disabledLocators=new Set;this.originalPackages=new Map;this.optionalBuilds=new Set;this.lockfileNeedsRefresh=!1;this.peerRequirements=new Map;this.installersCustomData=new Map;this.lockFileChecksum=null;this.installStateChecksum=null;this.configuration=t,this.cwd=e}static async find(e,t){var p,m,y;if(!e.projectCwd)throw new Pe(`No project found in ${t}`);let i=e.projectCwd,n=t,s=null;for(;s!==e.projectCwd;){if(s=n,U.existsSync(x.join(s,xt.manifest))){i=s;break}n=x.dirname(s)}let o=new ze(e.projectCwd,{configuration:e});(p=ye.telemetry)==null||p.reportProject(o.cwd),await o.setupResolutions(),await o.setupWorkspaces(),(m=ye.telemetry)==null||m.reportWorkspaceCount(o.workspaces.length),(y=ye.telemetry)==null||y.reportDependencyCount(o.workspaces.reduce((b,v)=>b+v.manifest.dependencies.size+v.manifest.devDependencies.size,0));let a=o.tryWorkspaceByCwd(i);if(a)return{project:o,workspace:a,locator:a.anchoredLocator};let l=await o.findLocatorForLocation(`${i}/`,{strict:!0});if(l)return{project:o,locator:l,workspace:null};let c=tt(e,o.cwd,Ye.PATH),u=tt(e,x.relative(o.cwd,i),Ye.PATH),g=`- If ${c} isn't intended to be a project, remove any yarn.lock and/or package.json file there.`,f=`- If ${c} is intended to be a project, it might be that you forgot to list ${u} in its workspace configuration.`,h=`- Finally, if ${c} is fine and you intend ${u} to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.`;throw new Pe(`The nearest package directory (${tt(e,i,Ye.PATH)}) doesn't seem to be part of the project declared in ${tt(e,o.cwd,Ye.PATH)}. - -${[g,f,h].join(` -`)}`)}async setupResolutions(){var i;this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;let e=x.join(this.cwd,this.configuration.get("lockfileFilename")),t=this.configuration.get("defaultLanguageName");if(U.existsSync(e)){let n=await U.readFilePromise(e,"utf8");this.lockFileChecksum=gZ(n);let s=Si(n);if(s.__metadata){let o=s.__metadata.version,a=s.__metadata.cacheKey;this.lockfileNeedsRefresh=o<cZ;for(let l of Object.keys(s)){if(l==="__metadata")continue;let c=s[l];if(typeof c.resolution=="undefined")throw new Error(`Assertion failed: Expected the lockfile entry to have a resolution field (${l})`);let u=qc(c.resolution,!0),g=new At;g.load(c,{yamlCompatibilityMode:!0});let f=g.version,h=g.languageName||t,p=c.linkType.toUpperCase(),m=(i=c.conditions)!=null?i:null,y=g.dependencies,b=g.peerDependencies,v=g.dependenciesMeta,k=g.peerDependenciesMeta,T=g.bin;if(c.checksum!=null){let q=typeof a!="undefined"&&!c.checksum.includes("/")?`${a}/${c.checksum}`:c.checksum;this.storedChecksums.set(u.locatorHash,q)}let Y=te(N({},u),{version:f,languageName:h,linkType:p,conditions:m,dependencies:y,peerDependencies:b,dependenciesMeta:v,peerDependenciesMeta:k,bin:T});this.originalPackages.set(Y.locatorHash,Y);for(let q of l.split(XOe)){let $=cl(q);this.storedDescriptors.set($.descriptorHash,$),this.storedResolutions.set($.descriptorHash,u.locatorHash)}}}}}async setupWorkspaces(){this.workspaces=[],this.workspacesByCwd=new Map,this.workspacesByIdent=new Map;let e=[this.cwd];for(;e.length>0;){let t=e;e=[];for(let i of t){if(this.workspacesByCwd.has(i))continue;let n=await this.addWorkspace(i),s=this.storedPackages.get(n.anchoredLocator.locatorHash);s&&(n.dependencies=s.dependencies);for(let o of n.workspacesCwds)e.push(o)}}}async addWorkspace(e){let t=new mC(e,{project:this});await t.setup();let i=this.workspacesByIdent.get(t.locator.identHash);if(typeof i!="undefined")throw new Error(`Duplicate workspace name ${fi(this.configuration,t.locator)}: ${H.fromPortablePath(e)} conflicts with ${H.fromPortablePath(i.cwd)}`);return this.workspaces.push(t),this.workspacesByCwd.set(e,t),this.workspacesByIdent.set(t.locator.identHash,t),t}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){x.isAbsolute(e)||(e=x.resolve(this.cwd,e)),e=x.normalize(e).replace(/\/+$/,"");let t=this.workspacesByCwd.get(e);return t||null}getWorkspaceByCwd(e){let t=this.tryWorkspaceByCwd(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByFilePath(e){let t=null;for(let i of this.workspaces)x.relative(i.cwd,e).startsWith("../")||t&&t.cwd.length>=i.cwd.length||(t=i);return t||null}getWorkspaceByFilePath(e){let t=this.tryWorkspaceByFilePath(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByIdent(e){let t=this.workspacesByIdent.get(e.identHash);return typeof t=="undefined"?null:t}getWorkspaceByIdent(e){let t=this.tryWorkspaceByIdent(e);if(!t)throw new Error(`Workspace not found (${fi(this.configuration,e)})`);return t}tryWorkspaceByDescriptor(e){let t=this.tryWorkspaceByIdent(e);return t===null||(ll(e)&&(e=gd(e)),!t.accepts(e.range))?null:t}getWorkspaceByDescriptor(e){let t=this.tryWorkspaceByDescriptor(e);if(t===null)throw new Error(`Workspace not found (${sr(this.configuration,e)})`);return t}tryWorkspaceByLocator(e){let t=this.tryWorkspaceByIdent(e);return t===null||(ta(e)&&(e=fd(e)),t.locator.locatorHash!==e.locatorHash&&t.anchoredLocator.locatorHash!==e.locatorHash)?null:t}getWorkspaceByLocator(e){let t=this.tryWorkspaceByLocator(e);if(!t)throw new Error(`Workspace not found (${It(this.configuration,e)})`);return t}refreshWorkspaceDependencies(){for(let e of this.workspaces){let t=this.storedPackages.get(e.anchoredLocator.locatorHash);if(!t)throw new Error(`Assertion failed: Expected workspace ${md(this.configuration,e)} (${tt(this.configuration,x.join(e.cwd,xt.manifest),Ye.PATH)}) to have been resolved. Run "yarn install" to update the lockfile`);e.dependencies=new Map(t.dependencies)}}forgetResolution(e){let t=n=>{this.storedResolutions.delete(n),this.storedDescriptors.delete(n)},i=n=>{this.originalPackages.delete(n),this.storedPackages.delete(n),this.accessibleLocators.delete(n)};if("descriptorHash"in e){let n=this.storedResolutions.get(e.descriptorHash);t(e.descriptorHash);let s=new Set(this.storedResolutions.values());typeof n!="undefined"&&!s.has(n)&&i(n)}if("locatorHash"in e){i(e.locatorHash);for(let[n,s]of this.storedResolutions)s===e.locatorHash&&t(n)}}forgetTransientResolutions(){let e=this.configuration.makeResolver();for(let t of this.originalPackages.values()){let i;try{i=e.shouldPersistResolution(t,{project:this,resolver:e})}catch{i=!1}i||this.forgetResolution(t)}}forgetVirtualResolutions(){for(let e of this.storedPackages.values())for(let[t,i]of e.dependencies)ll(i)&&e.dependencies.set(t,gd(i))}getDependencyMeta(e,t){let i={},s=this.topLevelWorkspace.manifest.dependenciesMeta.get(Ot(e));if(!s)return i;let o=s.get(null);if(o&&Object.assign(i,o),t===null||!lZ.default.valid(t))return i;for(let[a,l]of s)a!==null&&a===t&&Object.assign(i,l);return i}async findLocatorForLocation(e,{strict:t=!1}={}){let i=new di,n=this.configuration.getLinkers(),s={project:this,report:i};for(let o of n){let a=await o.findPackageLocator(e,s);if(a){if(t&&(await o.findPackageLocation(a,s)).replace(uZ,"")!==e.replace(uZ,""))continue;return a}}return null}async resolveEverything(e){if(!this.workspacesByCwd||!this.workspacesByIdent)throw new Error("Workspaces must have been setup before calling this function");this.forgetVirtualResolutions(),e.lockfileOnly||this.forgetTransientResolutions();let t=e.resolver||this.configuration.makeResolver(),i=new LR(t);await i.setup(this,{report:e.report});let n=e.lockfileOnly?[new OR(t)]:[i,t],s=new Bd([new TR(t),...n]),o=this.configuration.makeFetcher(),a=e.lockfileOnly?{project:this,report:e.report,resolver:s}:{project:this,report:e.report,resolver:s,fetchOptions:{project:this,cache:e.cache,checksums:this.storedChecksums,report:e.report,fetcher:o,cacheOptions:{mirrorWriteOnly:!0}}},l=new Map,c=new Map,u=new Map,g=new Map,f=new Map,h=new Map,p=this.topLevelWorkspace.anchoredLocator,m=new Set,y=[],b=ux(),v=this.configuration.getSupportedArchitectures();await e.report.startProgressPromise(Ji.progressViaTitle(),async ne=>{let ee=async O=>{let L=await Tg(async()=>await s.resolve(O,a),Ge=>`${It(this.configuration,O)}: ${Ge}`);if(!pd(O,L))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${It(this.configuration,O)} to ${It(this.configuration,L)})`);g.set(L.locatorHash,L);let de=this.configuration.normalizePackage(L);for(let[Ge,re]of de.dependencies){let se=await this.configuration.reduceHook(he=>he.reduceDependency,re,this,de,re,{resolver:s,resolveOptions:a});if(!hd(re,se))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");let be=s.bindDescriptor(se,O,a);de.dependencies.set(Ge,be)}let Be=ho([...de.dependencies.values()].map(Ge=>Z(Ge)));return y.push(Be),Be.catch(()=>{}),c.set(de.locatorHash,de),de},A=async O=>{let L=f.get(O.locatorHash);if(typeof L!="undefined")return L;let de=Promise.resolve().then(()=>ee(O));return f.set(O.locatorHash,de),de},oe=async(O,L)=>{let de=await Z(L);return l.set(O.descriptorHash,O),u.set(O.descriptorHash,de.locatorHash),de},ce=async O=>{ne.setTitle(sr(this.configuration,O));let L=this.resolutionAliases.get(O.descriptorHash);if(typeof L!="undefined")return oe(O,this.storedDescriptors.get(L));let de=s.getResolutionDependencies(O,a),Be=new Map(await ho(de.map(async se=>{let be=s.bindDescriptor(se,p,a),he=await Z(be);return m.add(he.locatorHash),[se.descriptorHash,he]}))),re=(await Tg(async()=>await s.getCandidates(O,Be,a),se=>`${sr(this.configuration,O)}: ${se}`))[0];if(typeof re=="undefined")throw new Error(`${sr(this.configuration,O)}: No candidates found`);return l.set(O.descriptorHash,O),u.set(O.descriptorHash,re.locatorHash),A(re)},Z=O=>{let L=h.get(O.descriptorHash);if(typeof L!="undefined")return L;l.set(O.descriptorHash,O);let de=Promise.resolve().then(()=>ce(O));return h.set(O.descriptorHash,de),de};for(let O of this.workspaces){let L=O.anchoredDescriptor;y.push(Z(L))}for(;y.length>0;){let O=[...y];y.length=0,await ho(O)}});let k=new Set(this.resolutionAliases.values()),T=new Set(c.keys()),Y=new Set,q=new Map;tMe({project:this,report:e.report,accessibleLocators:Y,volatileDescriptors:k,optionalBuilds:T,peerRequirements:q,allDescriptors:l,allResolutions:u,allPackages:c});for(let ne of m)T.delete(ne);for(let ne of k)l.delete(ne),u.delete(ne);let $=new Set,z=new Set;for(let ne of c.values())ne.conditions!=null&&(!T.has(ne.locatorHash)||(fw(ne,v)||(fw(ne,b)&&e.report.reportWarningOnce(X.GHOST_ARCHITECTURE,`${It(this.configuration,ne)}: Your current architecture (${process.platform}-${process.arch}) is supported by this package, but is missing from the ${tt(this.configuration,"supportedArchitectures",Ri.SETTING)} setting`),z.add(ne.locatorHash)),$.add(ne.locatorHash)));this.storedResolutions=u,this.storedDescriptors=l,this.storedPackages=c,this.accessibleLocators=Y,this.conditionalLocators=$,this.disabledLocators=z,this.originalPackages=g,this.optionalBuilds=T,this.peerRequirements=q,this.refreshWorkspaceDependencies()}async fetchEverything({cache:e,report:t,fetcher:i,mode:n}){let s={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators},o=i||this.configuration.makeFetcher(),a={checksums:this.storedChecksums,project:this,cache:e,fetcher:o,report:t,cacheOptions:s},l=Array.from(new Set(xn(this.storedResolutions.values(),[f=>{let h=this.storedPackages.get(f);if(!h)throw new Error("Assertion failed: The locator should have been registered");return Fs(h)}])));n===Ci.UpdateLockfile&&(l=l.filter(f=>!this.storedChecksums.has(f)));let c=!1,u=Ji.progressViaCounter(l.length);t.reportProgress(u);let g=(0,AZ.default)(ZOe);if(await t.startCacheReport(async()=>{await ho(l.map(f=>g(async()=>{let h=this.storedPackages.get(f);if(!h)throw new Error("Assertion failed: The locator should have been registered");if(ta(h))return;let p;try{p=await o.fetch(h,a)}catch(m){m.message=`${It(this.configuration,h)}: ${m.message}`,t.reportExceptionOnce(m),c=m;return}p.checksum!=null?this.storedChecksums.set(h.locatorHash,p.checksum):this.storedChecksums.delete(h.locatorHash),p.releaseFs&&p.releaseFs()}).finally(()=>{u.tick()})))}),c)throw c}async linkEverything({cache:e,report:t,fetcher:i,mode:n}){var A,oe,ce;let s={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators,skipIntegrityCheck:!0},o=i||this.configuration.makeFetcher(),a={checksums:this.storedChecksums,project:this,cache:e,fetcher:o,report:t,skipIntegrityCheck:!0,cacheOptions:s},l=this.configuration.getLinkers(),c={project:this,report:t},u=new Map(l.map(Z=>{let O=Z.makeInstaller(c),L=O.getCustomDataKey(),de=this.installersCustomData.get(L);return typeof de!="undefined"&&O.attachCustomData(de),[Z,O]})),g=new Map,f=new Map,h=new Map,p=new Map(await ho([...this.accessibleLocators].map(async Z=>{let O=this.storedPackages.get(Z);if(!O)throw new Error("Assertion failed: The locator should have been registered");return[Z,await o.fetch(O,a)]}))),m=[];for(let Z of this.accessibleLocators){let O=this.storedPackages.get(Z);if(typeof O=="undefined")throw new Error("Assertion failed: The locator should have been registered");let L=p.get(O.locatorHash);if(typeof L=="undefined")throw new Error("Assertion failed: The fetch result should have been registered");let de=[],Be=re=>{de.push(re)},Ge=this.tryWorkspaceByLocator(O);if(Ge!==null){let re=[],{scripts:se}=Ge.manifest;for(let he of["preinstall","install","postinstall"])se.has(he)&&re.push([cs.SCRIPT,he]);try{for(let[he,Fe]of u)if(he.supportsPackage(O,c)&&(await Fe.installPackage(O,L,{holdFetchResult:Be})).buildDirective!==null)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}finally{de.length===0?(A=L.releaseFs)==null||A.call(L):m.push(ho(de).catch(()=>{}).then(()=>{var he;(he=L.releaseFs)==null||he.call(L)}))}let be=x.join(L.packageFs.getRealPath(),L.prefixPath);f.set(O.locatorHash,be),!ta(O)&&re.length>0&&h.set(O.locatorHash,{directives:re,buildLocations:[be]})}else{let re=l.find(he=>he.supportsPackage(O,c));if(!re)throw new ct(X.LINKER_NOT_FOUND,`${It(this.configuration,O)} isn't supported by any available linker`);let se=u.get(re);if(!se)throw new Error("Assertion failed: The installer should have been registered");let be;try{be=await se.installPackage(O,L,{holdFetchResult:Be})}finally{de.length===0?(oe=L.releaseFs)==null||oe.call(L):m.push(ho(de).then(()=>{}).then(()=>{var he;(he=L.releaseFs)==null||he.call(L)}))}g.set(O.locatorHash,re),f.set(O.locatorHash,be.packageLocation),be.buildDirective&&be.buildDirective.length>0&&be.packageLocation&&h.set(O.locatorHash,{directives:be.buildDirective,buildLocations:[be.packageLocation]})}}let y=new Map;for(let Z of this.accessibleLocators){let O=this.storedPackages.get(Z);if(!O)throw new Error("Assertion failed: The locator should have been registered");let L=this.tryWorkspaceByLocator(O)!==null,de=async(Be,Ge)=>{let re=f.get(O.locatorHash);if(typeof re=="undefined")throw new Error(`Assertion failed: The package (${It(this.configuration,O)}) should have been registered`);let se=[];for(let be of O.dependencies.values()){let he=this.storedResolutions.get(be.descriptorHash);if(typeof he=="undefined")throw new Error(`Assertion failed: The resolution (${sr(this.configuration,be)}, from ${It(this.configuration,O)})should have been registered`);let Fe=this.storedPackages.get(he);if(typeof Fe=="undefined")throw new Error(`Assertion failed: The package (${he}, resolved from ${sr(this.configuration,be)}) should have been registered`);let Ue=this.tryWorkspaceByLocator(Fe)===null?g.get(he):null;if(typeof Ue=="undefined")throw new Error(`Assertion failed: The package (${he}, resolved from ${sr(this.configuration,be)}) should have been registered`);Ue===Be||Ue===null?f.get(Fe.locatorHash)!==null&&se.push([be,Fe]):!L&&re!==null&&Ng(y,he).push(re)}re!==null&&await Ge.attachInternalDependencies(O,se)};if(L)for(let[Be,Ge]of u)Be.supportsPackage(O,c)&&await de(Be,Ge);else{let Be=g.get(O.locatorHash);if(!Be)throw new Error("Assertion failed: The linker should have been found");let Ge=u.get(Be);if(!Ge)throw new Error("Assertion failed: The installer should have been registered");await de(Be,Ge)}}for(let[Z,O]of y){let L=this.storedPackages.get(Z);if(!L)throw new Error("Assertion failed: The package should have been registered");let de=g.get(L.locatorHash);if(!de)throw new Error("Assertion failed: The linker should have been found");let Be=u.get(de);if(!Be)throw new Error("Assertion failed: The installer should have been registered");await Be.attachExternalDependents(L,O)}let b=new Map;for(let Z of u.values()){let O=await Z.finalizeInstall();for(let L of(ce=O==null?void 0:O.records)!=null?ce:[])h.set(L.locatorHash,{directives:L.buildDirective,buildLocations:L.buildLocations});typeof(O==null?void 0:O.customData)!="undefined"&&b.set(Z.getCustomDataKey(),O.customData)}if(this.installersCustomData=b,await ho(m),n===Ci.SkipBuild)return;let v=new Set(this.storedPackages.keys()),k=new Set(h.keys());for(let Z of k)v.delete(Z);let T=(0,n0.createHash)("sha512");T.update(process.versions.node),await this.configuration.triggerHook(Z=>Z.globalHashGeneration,this,Z=>{T.update("\0"),T.update(Z)});let Y=T.digest("hex"),q=new Map,$=Z=>{let O=q.get(Z.locatorHash);if(typeof O!="undefined")return O;let L=this.storedPackages.get(Z.locatorHash);if(typeof L=="undefined")throw new Error("Assertion failed: The package should have been registered");let de=(0,n0.createHash)("sha512");de.update(Z.locatorHash),q.set(Z.locatorHash,"<recursive>");for(let Be of L.dependencies.values()){let Ge=this.storedResolutions.get(Be.descriptorHash);if(typeof Ge=="undefined")throw new Error(`Assertion failed: The resolution (${sr(this.configuration,Be)}) should have been registered`);let re=this.storedPackages.get(Ge);if(typeof re=="undefined")throw new Error("Assertion failed: The package should have been registered");de.update($(re))}return O=de.digest("hex"),q.set(Z.locatorHash,O),O},z=(Z,O)=>{let L=(0,n0.createHash)("sha512");L.update(Y),L.update($(Z));for(let de of O)L.update(de);return L.digest("hex")},ne=new Map,ee=!1;for(;k.size>0;){let Z=k.size,O=[];for(let L of k){let de=this.storedPackages.get(L);if(!de)throw new Error("Assertion failed: The package should have been registered");let Be=!0;for(let se of de.dependencies.values()){let be=this.storedResolutions.get(se.descriptorHash);if(!be)throw new Error(`Assertion failed: The resolution (${sr(this.configuration,se)}) should have been registered`);if(k.has(be)){Be=!1;break}}if(!Be)continue;k.delete(L);let Ge=h.get(de.locatorHash);if(!Ge)throw new Error("Assertion failed: The build directive should have been registered");let re=z(de,Ge.buildLocations);if(this.storedBuildState.get(de.locatorHash)===re){ne.set(de.locatorHash,re);continue}ee||(await this.persistInstallStateFile(),ee=!0),this.storedBuildState.has(de.locatorHash)?t.reportInfo(X.MUST_REBUILD,`${It(this.configuration,de)} must be rebuilt because its dependency tree changed`):t.reportInfo(X.MUST_BUILD,`${It(this.configuration,de)} must be built because it never has been before or the last one failed`);for(let se of Ge.buildLocations){if(!x.isAbsolute(se))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${se})`);O.push((async()=>{for(let[be,he]of Ge.directives){let Fe=`# This file contains the result of Yarn building a package (${Fs(de)}) -`;switch(be){case cs.SCRIPT:Fe+=`# Script name: ${he} -`;break;case cs.SHELLCODE:Fe+=`# Script code: ${he} -`;break}let Ue=null;if(!await U.mktempPromise(async ve=>{let pe=x.join(ve,"build.log"),{stdout:V,stderr:Qe}=this.configuration.getSubprocessStreams(pe,{header:Fe,prefix:It(this.configuration,de),report:t}),le;try{switch(be){case cs.SCRIPT:le=await sB(de,he,[],{cwd:se,project:this,stdin:Ue,stdout:V,stderr:Qe});break;case cs.SHELLCODE:le=await iD(de,he,[],{cwd:se,project:this,stdin:Ue,stdout:V,stderr:Qe});break}}catch(gt){Qe.write(gt.stack),le=1}if(V.end(),Qe.end(),le===0)return ne.set(de.locatorHash,re),!0;U.detachTemp(ve);let fe=`${It(this.configuration,de)} couldn't be built successfully (exit code ${tt(this.configuration,le,Ye.NUMBER)}, logs can be found here: ${tt(this.configuration,pe,Ye.PATH)})`;return this.optionalBuilds.has(de.locatorHash)?(t.reportInfo(X.BUILD_FAILED,fe),ne.set(de.locatorHash,re),!0):(t.reportError(X.BUILD_FAILED,fe),!1)}))return}})())}}if(await ho(O),Z===k.size){let L=Array.from(k).map(de=>{let Be=this.storedPackages.get(de);if(!Be)throw new Error("Assertion failed: The package should have been registered");return It(this.configuration,Be)}).join(", ");t.reportError(X.CYCLIC_DEPENDENCIES,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${L})`);break}}this.storedBuildState=ne}async install(e){var a,l;let t=this.configuration.get("nodeLinker");(a=ye.telemetry)==null||a.reportInstall(t),await e.report.startTimerPromise("Project validation",{skipIfEmpty:!0},async()=>{await this.configuration.triggerHook(c=>c.validateProject,this,{reportWarning:e.report.reportWarning.bind(e.report),reportError:e.report.reportError.bind(e.report)})});for(let c of this.configuration.packageExtensions.values())for(let[,u]of c)for(let g of u)g.status=qi.Inactive;let i=x.join(this.cwd,this.configuration.get("lockfileFilename")),n=null;if(e.immutable)try{n=await U.readFilePromise(i,"utf8")}catch(c){throw c.code==="ENOENT"?new ct(X.FROZEN_LOCKFILE_EXCEPTION,"The lockfile would have been created by this install, which is explicitly forbidden."):c}await e.report.startTimerPromise("Resolution step",async()=>{await this.resolveEverything(e)}),await e.report.startTimerPromise("Post-resolution validation",{skipIfEmpty:!0},async()=>{for(let[,c]of this.configuration.packageExtensions)for(let[,u]of c)for(let g of u)if(g.userProvided){let f=tt(this.configuration,g,Ye.PACKAGE_EXTENSION);switch(g.status){case qi.Inactive:e.report.reportWarning(X.UNUSED_PACKAGE_EXTENSION,`${f}: No matching package in the dependency tree; you may not need this rule anymore.`);break;case qi.Redundant:e.report.reportWarning(X.REDUNDANT_PACKAGE_EXTENSION,`${f}: This rule seems redundant when applied on the original package; the extension may have been applied upstream.`);break}}if(n!==null){let c=oc(n,this.generateLockfile());if(c!==n){let u=e7(i,i,n,c,void 0,void 0,{maxEditLength:100});if(u){e.report.reportSeparator();for(let g of u.hunks){e.report.reportInfo(null,`@@ -${g.oldStart},${g.oldLines} +${g.newStart},${g.newLines} @@`);for(let f of g.lines)f.startsWith("+")?e.report.reportError(X.FROZEN_LOCKFILE_EXCEPTION,tt(this.configuration,f,Ye.ADDED)):f.startsWith("-")?e.report.reportError(X.FROZEN_LOCKFILE_EXCEPTION,tt(this.configuration,f,Ye.REMOVED)):e.report.reportInfo(null,tt(this.configuration,f,"grey"))}e.report.reportSeparator()}throw new ct(X.FROZEN_LOCKFILE_EXCEPTION,"The lockfile would have been modified by this install, which is explicitly forbidden.")}}});for(let c of this.configuration.packageExtensions.values())for(let[,u]of c)for(let g of u)g.userProvided&&g.status===qi.Active&&((l=ye.telemetry)==null||l.reportPackageExtension(Mc(g,Ye.PACKAGE_EXTENSION)));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e),(typeof e.persistProject=="undefined"||e.persistProject)&&e.mode!==Ci.UpdateLockfile&&await this.cacheCleanup(e)});let s=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],o=await Promise.all(s.map(async c=>aw(c,{cwd:this.cwd})));(typeof e.persistProject=="undefined"||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{if(e.mode===Ci.UpdateLockfile){e.report.reportWarning(X.UPDATE_LOCKFILE_ONLY_SKIP_LINK,`Skipped due to ${tt(this.configuration,"mode=update-lockfile",Ye.CODE)}`);return}await this.linkEverything(e);let c=await Promise.all(s.map(async u=>aw(u,{cwd:this.cwd})));for(let u=0;u<s.length;++u)o[u]!==c[u]&&e.report.reportError(X.FROZEN_ARTIFACT_EXCEPTION,`The checksum for ${s[u]} has been modified by this install, which is explicitly forbidden.`)}),await this.persistInstallStateFile(),await this.configuration.triggerHook(c=>c.afterAllInstalled,this,e)}generateLockfile(){let e=new Map;for(let[n,s]of this.storedResolutions.entries()){let o=e.get(s);o||e.set(s,o=new Set),o.add(n)}let t={};t.__metadata={version:cZ,cacheKey:void 0};for(let[n,s]of e.entries()){let o=this.originalPackages.get(n);if(!o)continue;let a=[];for(let f of s){let h=this.storedDescriptors.get(f);if(!h)throw new Error("Assertion failed: The descriptor should have been registered");a.push(h)}let l=a.map(f=>Pn(f)).sort().join(", "),c=new At;c.version=o.linkType===Qt.HARD?o.version:"0.0.0-use.local",c.languageName=o.languageName,c.dependencies=new Map(o.dependencies),c.peerDependencies=new Map(o.peerDependencies),c.dependenciesMeta=new Map(o.dependenciesMeta),c.peerDependenciesMeta=new Map(o.peerDependenciesMeta),c.bin=new Map(o.bin);let u,g=this.storedChecksums.get(o.locatorHash);if(typeof g!="undefined"){let f=g.indexOf("/");if(f===-1)throw new Error("Assertion failed: Expected the checksum to reference its cache key");let h=g.slice(0,f),p=g.slice(f+1);typeof t.__metadata.cacheKey=="undefined"&&(t.__metadata.cacheKey=h),h===t.__metadata.cacheKey?u=p:u=g}t[l]=te(N({},c.exportTo({},{compatibilityMode:!1})),{linkType:o.linkType.toLowerCase(),resolution:Fs(o),checksum:u,conditions:o.conditions||void 0})}return`${[`# This file is generated by running "yarn install" inside your project. -`,`# Manual changes might be lost - proceed with caution! -`].join("")} -`+Ua(t)}async persistLockfile(){let e=x.join(this.cwd,this.configuration.get("lockfileFilename")),t="";try{t=await U.readFilePromise(e,"utf8")}catch(s){}let i=this.generateLockfile(),n=oc(t,i);n!==t&&(await U.writeFilePromise(e,n),this.lockFileChecksum=gZ(n),this.lockfileNeedsRefresh=!1)}async persistInstallStateFile(){let e=[];for(let o of Object.values(HR))e.push(...o);let t=(0,s0.default)(this,e),i=UR.default.serialize(t),n=ln(i);if(this.installStateChecksum===n)return;let s=this.configuration.get("installStatePath");await U.mkdirPromise(x.dirname(s),{recursive:!0}),await U.writeFilePromise(s,await $Oe(i)),this.installStateChecksum=n}async restoreInstallState({restoreInstallersCustomData:e=!0,restoreResolutions:t=!0,restoreBuildState:i=!0}={}){let n=this.configuration.get("installStatePath"),s;try{let o=await eMe(await U.readFilePromise(n));s=UR.default.deserialize(o),this.installStateChecksum=ln(o)}catch{t&&await this.applyLightResolution();return}e&&typeof s.installersCustomData!="undefined"&&(this.installersCustomData=s.installersCustomData),i&&Object.assign(this,(0,s0.default)(s,HR.restoreBuildState)),t&&(s.lockFileChecksum===this.lockFileChecksum?(Object.assign(this,(0,s0.default)(s,HR.restoreResolutions)),this.refreshWorkspaceDependencies()):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new di}),await this.persistInstallStateFile()}async persist(){await this.persistLockfile();for(let e of this.workspacesByCwd.values())await e.persistManifest()}async cacheCleanup({cache:e,report:t}){if(this.configuration.get("enableGlobalCache"))return;let i=new Set([".gitignore"]);if(!lx(e.cwd,this.cwd)||!await U.existsPromise(e.cwd))return;let n=this.configuration.get("preferAggregateCacheInfo"),s=0,o=null;for(let a of await U.readdirPromise(e.cwd)){if(i.has(a))continue;let l=x.resolve(e.cwd,a);e.markedFiles.has(l)||(o=a,e.immutable?t.reportError(X.IMMUTABLE_CACHE,`${tt(this.configuration,x.basename(l),"magenta")} appears to be unused and would be marked for deletion, but the cache is immutable`):(n?s+=1:t.reportInfo(X.UNUSED_CACHE_ENTRY,`${tt(this.configuration,x.basename(l),"magenta")} appears to be unused - removing`),await U.removePromise(l)))}n&&s!==0&&t.reportInfo(X.UNUSED_CACHE_ENTRY,s>1?`${s} packages appeared to be unused and were removed`:`${o} appeared to be unused and was removed`),e.markedFiles.clear()}};function tMe({project:r,allDescriptors:e,allResolutions:t,allPackages:i,accessibleLocators:n=new Set,optionalBuilds:s=new Set,peerRequirements:o=new Map,volatileDescriptors:a=new Set,report:l,tolerateMissingPackages:c=!1}){var ne;let u=new Map,g=[],f=new Map,h=new Map,p=new Map,m=new Map,y=new Map,b=new Map(r.workspaces.map(ee=>{let A=ee.anchoredLocator.locatorHash,oe=i.get(A);if(typeof oe=="undefined"){if(c)return[A,null];throw new Error("Assertion failed: The workspace should have an associated package")}return[A,ud(oe)]})),v=()=>{let ee=U.mktempSync(),A=x.join(ee,"stacktrace.log"),oe=String(g.length+1).length,ce=g.map((Z,O)=>`${`${O+1}.`.padStart(oe," ")} ${Fs(Z)} -`).join("");throw U.writeFileSync(A,ce),U.detachTemp(ee),new ct(X.STACK_OVERFLOW_RESOLUTION,`Encountered a stack overflow when resolving peer dependencies; cf ${H.fromPortablePath(A)}`)},k=ee=>{let A=t.get(ee.descriptorHash);if(typeof A=="undefined")throw new Error("Assertion failed: The resolution should have been registered");let oe=i.get(A);if(!oe)throw new Error("Assertion failed: The package could not be found");return oe},T=(ee,A,oe,{top:ce,optional:Z})=>{g.length>1e3&&v(),g.push(A);let O=Y(ee,A,oe,{top:ce,optional:Z});return g.pop(),O},Y=(ee,A,oe,{top:ce,optional:Z})=>{if(n.has(A.locatorHash))return;n.add(A.locatorHash),Z||s.delete(A.locatorHash);let O=i.get(A.locatorHash);if(!O){if(c)return;throw new Error(`Assertion failed: The package (${It(r.configuration,A)}) should have been registered`)}let L=[],de=[],Be=[],Ge=[],re=[];for(let be of Array.from(O.dependencies.values())){if(O.peerDependencies.has(be.identHash)&&O.locatorHash!==ce)continue;if(ll(be))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");a.delete(be.descriptorHash);let he=Z;if(!he){let Qe=O.dependenciesMeta.get(Ot(be));if(typeof Qe!="undefined"){let le=Qe.get(null);typeof le!="undefined"&&le.optional&&(he=!0)}}let Fe=t.get(be.descriptorHash);if(!Fe){if(c)continue;throw new Error(`Assertion failed: The resolution (${sr(r.configuration,be)}) should have been registered`)}let Ue=b.get(Fe)||i.get(Fe);if(!Ue)throw new Error(`Assertion failed: The package (${Fe}, resolved from ${sr(r.configuration,be)}) should have been registered`);if(Ue.peerDependencies.size===0){T(be,Ue,new Map,{top:ce,optional:he});continue}let xe,ve,pe=new Set,V;de.push(()=>{xe=Xk(be,A.locatorHash),ve=Zk(Ue,A.locatorHash),O.dependencies.delete(be.identHash),O.dependencies.set(xe.identHash,xe),t.set(xe.descriptorHash,ve.locatorHash),e.set(xe.descriptorHash,xe),i.set(ve.locatorHash,ve),L.push([Ue,xe,ve])}),Be.push(()=>{var Qe;V=new Map;for(let le of ve.peerDependencies.values()){let fe=O.dependencies.get(le.identHash);if(!fe&&hd(A,le)&&(ee.identHash===A.identHash?fe=ee:(fe=rr(A,ee.range),e.set(fe.descriptorHash,fe),t.set(fe.descriptorHash,A.locatorHash),a.delete(fe.descriptorHash))),(!fe||fe.range==="missing:")&&ve.dependencies.has(le.identHash)){ve.peerDependencies.delete(le.identHash);continue}fe||(fe=rr(le,"missing:")),ve.dependencies.set(fe.identHash,fe),ll(fe)&&Lc(p,fe.descriptorHash).add(ve.locatorHash),f.set(fe.identHash,fe),fe.range==="missing:"&&pe.add(fe.identHash),V.set(le.identHash,(Qe=oe.get(le.identHash))!=null?Qe:ve.locatorHash)}ve.dependencies=new Map(xn(ve.dependencies,([le,fe])=>Ot(fe)))}),Ge.push(()=>{if(!i.has(ve.locatorHash))return;let Qe=u.get(Ue.locatorHash);typeof Qe=="number"&&Qe>=2&&v();let le=u.get(Ue.locatorHash),fe=typeof le!="undefined"?le+1:1;u.set(Ue.locatorHash,fe),T(xe,ve,V,{top:ce,optional:he}),u.set(Ue.locatorHash,fe-1)}),re.push(()=>{let Qe=O.dependencies.get(be.identHash);if(typeof Qe=="undefined")throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");let le=t.get(Qe.descriptorHash);if(typeof le=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");if(Lc(y,le).add(A.locatorHash),!!i.has(ve.locatorHash)){for(let fe of ve.peerDependencies.values()){let gt=V.get(fe.identHash);if(typeof gt=="undefined")throw new Error("Assertion failed: Expected the peer dependency ident to be registered");Ng(Lg(m,gt),Ot(fe)).push(ve.locatorHash)}for(let fe of pe)ve.dependencies.delete(fe)}})}for(let be of[...de,...Be])be();let se;do{se=!0;for(let[be,he,Fe]of L){let Ue=Lg(h,be.locatorHash),xe=ln(...[...Fe.dependencies.values()].map(Qe=>{let le=Qe.range!=="missing:"?t.get(Qe.descriptorHash):"missing:";if(typeof le=="undefined")throw new Error(`Assertion failed: Expected the resolution for ${sr(r.configuration,Qe)} to have been registered`);return le===ce?`${le} (top)`:le}),he.identHash),ve=Ue.get(xe);if(typeof ve=="undefined"){Ue.set(xe,he);continue}if(ve===he)continue;i.delete(Fe.locatorHash),e.delete(he.descriptorHash),t.delete(he.descriptorHash),n.delete(Fe.locatorHash);let pe=p.get(he.descriptorHash)||[],V=[O.locatorHash,...pe];p.delete(he.descriptorHash);for(let Qe of V){let le=i.get(Qe);typeof le!="undefined"&&(le.dependencies.get(he.identHash).descriptorHash!==ve.descriptorHash&&(se=!1),le.dependencies.set(he.identHash,ve))}}}while(!se);for(let be of[...Ge,...re])be()};for(let ee of r.workspaces){let A=ee.anchoredLocator;a.delete(ee.anchoredDescriptor.descriptorHash),T(ee.anchoredDescriptor,A,new Map,{top:A.locatorHash,optional:!1})}var q;(function(oe){oe[oe.NotProvided=0]="NotProvided",oe[oe.NotCompatible=1]="NotCompatible"})(q||(q={}));let $=[];for(let[ee,A]of y){let oe=i.get(ee);if(typeof oe=="undefined")throw new Error("Assertion failed: Expected the root to be registered");let ce=m.get(ee);if(typeof ce!="undefined")for(let Z of A){let O=i.get(Z);if(typeof O!="undefined")for(let[L,de]of ce){let Be=An(L);if(O.peerDependencies.has(Be.identHash))continue;let Ge=`p${ln(Z,L,ee).slice(0,5)}`;o.set(Ge,{subject:Z,requested:Be,rootRequester:ee,allRequesters:de});let re=oe.dependencies.get(Be.identHash);if(typeof re!="undefined"){let se=k(re),be=(ne=se.version)!=null?ne:"0.0.0",he=new Set;for(let Ue of de){let xe=i.get(Ue);if(typeof xe=="undefined")throw new Error("Assertion failed: Expected the link to be registered");let ve=xe.peerDependencies.get(Be.identHash);if(typeof ve=="undefined")throw new Error("Assertion failed: Expected the ident to be registered");he.add(ve.range)}[...he].every(Ue=>{if(Ue.startsWith(oi.protocol)){if(!r.tryWorkspaceByLocator(se))return!1;Ue=Ue.slice(oi.protocol.length),(Ue==="^"||Ue==="~")&&(Ue="*")}return Jc(be,Ue)})||$.push({type:1,subject:O,requested:Be,requester:oe,version:be,hash:Ge,requirementCount:de.length})}else{let se=oe.peerDependenciesMeta.get(L);(se==null?void 0:se.optional)||$.push({type:0,subject:O,requested:Be,requester:oe,hash:Ge})}}}}let z=[ee=>ex(ee.subject),ee=>Ot(ee.requested),ee=>`${ee.type}`];l==null||l.startSectionSync({reportFooter:()=>{l.reportWarning(X.UNNAMED,`Some peer dependencies are incorrectly met; run ${tt(r.configuration,"yarn explain peer-requirements <hash>",Ye.CODE)} for details, where ${tt(r.configuration,"<hash>",Ye.CODE)} is the six-letter p-prefixed code`)},skipIfEmpty:!0},()=>{for(let ee of xn($,z))switch(ee.type){case 0:l.reportWarning(X.MISSING_PEER_DEPENDENCY,`${It(r.configuration,ee.subject)} doesn't provide ${fi(r.configuration,ee.requested)} (${tt(r.configuration,ee.hash,Ye.CODE)}), requested by ${fi(r.configuration,ee.requester)}`);break;case 1:{let A=ee.requirementCount>1?"and some of its descendants request":"requests";l.reportWarning(X.INCOMPATIBLE_PEER_DEPENDENCY,`${It(r.configuration,ee.subject)} provides ${fi(r.configuration,ee.requested)} (${tt(r.configuration,ee.hash,Ye.CODE)}) with version ${Cd(r.configuration,ee.version)}, which doesn't satisfy what ${fi(r.configuration,ee.requester)} ${A}`)}break}})}var ua;(function(l){l.VERSION="version",l.COMMAND_NAME="commandName",l.PLUGIN_NAME="pluginName",l.INSTALL_COUNT="installCount",l.PROJECT_COUNT="projectCount",l.WORKSPACE_COUNT="workspaceCount",l.DEPENDENCY_COUNT="dependencyCount",l.EXTENSION="packageExtension"})(ua||(ua={}));var EC=class{constructor(e,t){this.values=new Map;this.hits=new Map;this.enumerators=new Map;this.configuration=e;let i=this.getRegistryPath();this.isNew=!U.existsSync(i),this.sendReport(t),this.startBuffer()}reportVersion(e){this.reportValue(ua.VERSION,e.replace(/-git\..*/,"-git"))}reportCommandName(e){this.reportValue(ua.COMMAND_NAME,e||"<none>")}reportPluginName(e){this.reportValue(ua.PLUGIN_NAME,e)}reportProject(e){this.reportEnumerator(ua.PROJECT_COUNT,e)}reportInstall(e){this.reportHit(ua.INSTALL_COUNT,e)}reportPackageExtension(e){this.reportValue(ua.EXTENSION,e)}reportWorkspaceCount(e){this.reportValue(ua.WORKSPACE_COUNT,String(e))}reportDependencyCount(e){this.reportValue(ua.DEPENDENCY_COUNT,String(e))}reportValue(e,t){Lc(this.values,e).add(t)}reportEnumerator(e,t){Lc(this.enumerators,e).add(ln(t))}reportHit(e,t="*"){let i=Lg(this.hits,e),n=Va(i,t,()=>0);i.set(t,n+1)}getRegistryPath(){let e=this.configuration.get("globalFolder");return x.join(e,"telemetry.json")}sendReport(e){var u,g,f;let t=this.getRegistryPath(),i;try{i=U.readJsonSync(t)}catch{i={}}let n=Date.now(),s=this.configuration.get("telemetryInterval")*24*60*60*1e3,a=((u=i.lastUpdate)!=null?u:n+s+Math.floor(s*Math.random()))+s;if(a>n&&i.lastUpdate!=null)return;try{U.mkdirSync(x.dirname(t),{recursive:!0}),U.writeJsonSync(t,{lastUpdate:n})}catch{return}if(a>n||!i.blocks)return;let l=`https://browser-http-intake.logs.datadoghq.eu/v1/input/${e}?ddsource=yarn`,c=h=>jP(l,h,{configuration:this.configuration}).catch(()=>{});for(let[h,p]of Object.entries((g=i.blocks)!=null?g:{})){if(Object.keys(p).length===0)continue;let m=p;m.userId=h,m.reportType="primary";for(let v of Object.keys((f=m.enumerators)!=null?f:{}))m.enumerators[v]=m.enumerators[v].length;c(m);let y=new Map,b=20;for(let[v,k]of Object.entries(m.values))k.length>0&&y.set(v,k.slice(0,b));for(;y.size>0;){let v={};v.userId=h,v.reportType="secondary",v.metrics={};for(let[k,T]of y)v.metrics[k]=T.shift(),T.length===0&&y.delete(k);c(v)}}}applyChanges(){var o,a,l,c,u,g,f,h,p;let e=this.getRegistryPath(),t;try{t=U.readJsonSync(e)}catch{t={}}let i=(o=this.configuration.get("telemetryUserId"))!=null?o:"*",n=t.blocks=(a=t.blocks)!=null?a:{},s=n[i]=(l=n[i])!=null?l:{};for(let m of this.hits.keys()){let y=s.hits=(c=s.hits)!=null?c:{},b=y[m]=(u=y[m])!=null?u:{};for(let[v,k]of this.hits.get(m))b[v]=((g=b[v])!=null?g:0)+k}for(let m of["values","enumerators"])for(let y of this[m].keys()){let b=s[m]=(f=s[m])!=null?f:{};b[y]=[...new Set([...(h=b[y])!=null?h:[],...(p=this[m].get(y))!=null?p:[]])]}U.mkdirSync(x.dirname(e),{recursive:!0}),U.writeJsonSync(e,t)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch{}})}};var jR=ge(require("child_process")),fZ=ge(yc());var GR=ge(require("fs"));var Tf=new Map([["constraints",[["constraints","query"],["constraints","source"],["constraints"]]],["exec",[]],["interactive-tools",[["search"],["upgrade-interactive"]]],["stage",[["stage"]]],["typescript",[]],["version",[["version","apply"],["version","check"],["version"]]],["workspace-tools",[["workspaces","focus"],["workspaces","foreach"]]]]);function rMe(r){let e=H.fromPortablePath(r);process.on("SIGINT",()=>{}),e?(0,jR.execFileSync)(process.execPath,[e,...process.argv.slice(2)],{stdio:"inherit",env:te(N({},process.env),{YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"})}):(0,jR.execFileSync)(e,process.argv.slice(2),{stdio:"inherit",env:te(N({},process.env),{YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"})})}async function o0({binaryVersion:r,pluginConfiguration:e}){async function t(){let n=new Bs({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:r});try{await i(n)}catch(s){process.stdout.write(n.error(s)),process.exitCode=1}}async function i(n){var m,y,b,v,k;let s=process.versions.node,o=">=12 <14 || 14.2 - 14.9 || >14.10.0";if(!Se.parseOptionalBoolean(process.env.YARN_IGNORE_NODE)&&!Wt.satisfiesWithPrereleases(s,o))throw new Pe(`This tool requires a Node version compatible with ${o} (got ${s}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);let l=await ye.find(H.toPortablePath(process.cwd()),e,{usePath:!0,strict:!1}),c=l.get("yarnPath"),u=l.get("ignorePath"),g=l.get("ignoreCwd"),f=H.toPortablePath(H.resolve(process.argv[1])),h=T=>U.readFilePromise(T).catch(()=>Buffer.of());if(!u&&!g&&await(async()=>c===f||Buffer.compare(...await Promise.all([h(c),h(f)]))===0)()){process.env.YARN_IGNORE_PATH="1",process.env.YARN_IGNORE_CWD="1",await i(n);return}else if(c!==null&&!u)if(!U.existsSync(c))process.stdout.write(n.error(new Error(`The "yarn-path" option has been set (in ${l.sources.get("yarnPath")}), but the specified location doesn't exist (${c}).`))),process.exitCode=1;else try{rMe(c)}catch(T){process.exitCode=T.code||1}else{u&&delete process.env.YARN_IGNORE_PATH,l.get("enableTelemetry")&&!fZ.isCI&&process.stdout.isTTY&&(ye.telemetry=new EC(l,"puba9cdc10ec5790a2cf4969dd413a47270")),(m=ye.telemetry)==null||m.reportVersion(r);for(let[$,z]of l.plugins.entries()){Tf.has((b=(y=$.match(/^@yarnpkg\/plugin-(.*)$/))==null?void 0:y[1])!=null?b:"")&&((v=ye.telemetry)==null||v.reportPluginName($));for(let ne of z.commands||[])n.register(ne)}let Y=n.process(process.argv.slice(2));Y.help||(k=ye.telemetry)==null||k.reportCommandName(Y.path.join(" "));let q=Y.cwd;if(typeof q!="undefined"&&!g){let $=(0,GR.realpathSync)(process.cwd()),z=(0,GR.realpathSync)(q);if($!==z){process.chdir(q),await t();return}}await n.runExit(Y,{cwd:H.toPortablePath(process.cwd()),plugins:e,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr})}}return t().catch(n=>{process.stdout.write(n.stack||n.message),process.exitCode=1}).finally(()=>U.rmtempPromise())}function hZ(r){r.Command.Path=(...e)=>t=>{t.paths=t.paths||[],t.paths.push(e)};for(let e of["Array","Boolean","String","Proxy","Rest","Counter"])r.Command[e]=(...t)=>(i,n)=>{let s=r.Option[e](...t);Object.defineProperty(i,`__${n}`,{configurable:!1,enumerable:!0,get(){return s},set(o){this[n]=o}})};return r}var YC={};ft(YC,{BaseCommand:()=>Le,WorkspaceRequiredError:()=>ht,getDynamicLibs:()=>kre,getPluginConfiguration:()=>T0,main:()=>o0,openWorkspace:()=>zf,pluginCommands:()=>Tf});var Le=class extends Re{constructor(){super(...arguments);this.cwd=J.String("--cwd",{hidden:!0})}};var ht=class extends Pe{constructor(e,t){let i=x.relative(e,t),n=x.join(e,At.fileName);super(`This command can only be run from within a workspace of your project (${i} isn't a workspace of ${n}).`)}};var AGe=ge(ri());ws();var lGe=ge(HF()),kre=()=>new Map([["@yarnpkg/cli",YC],["@yarnpkg/core",IC],["@yarnpkg/fslib",$h],["@yarnpkg/libzip",Ud],["@yarnpkg/parsers",ap],["@yarnpkg/shell",Hd],["clipanion",mp],["semver",AGe],["typanion",ug],["yup",lGe]]);async function zf(r,e){let{project:t,workspace:i}=await ze.find(r,e);if(!i)throw new ht(t.cwd,e);return i}var v_e=ge(ri());ws();var k_e=ge(HF());var YN={};ft(YN,{dedupeUtils:()=>BN,default:()=>y3e,suggestUtils:()=>cN});var Pae=ge(yc());var One=ge(zC());ws();var cN={};ft(cN,{Modifier:()=>da,Strategy:()=>Vr,Target:()=>Hr,WorkspaceModifier:()=>Zf,applyModifier:()=>Fne,extractDescriptorFromPath:()=>fN,extractRangeModifier:()=>Rne,fetchDescriptorFrom:()=>gN,findProjectDescriptors:()=>Tne,getModifier:()=>_C,getSuggestedDescriptors:()=>VC,makeWorkspaceDescriptor:()=>Lne,toWorkspaceModifier:()=>Nne});var uN=ge(ri()),vYe="workspace:",Hr;(function(i){i.REGULAR="dependencies",i.DEVELOPMENT="devDependencies",i.PEER="peerDependencies"})(Hr||(Hr={}));var da;(function(i){i.CARET="^",i.TILDE="~",i.EXACT=""})(da||(da={}));var Zf;(function(i){i.CARET="^",i.TILDE="~",i.EXACT="*"})(Zf||(Zf={}));var Vr;(function(s){s.KEEP="keep",s.REUSE="reuse",s.PROJECT="project",s.LATEST="latest",s.CACHE="cache"})(Vr||(Vr={}));function _C(r,e){return r.exact?da.EXACT:r.caret?da.CARET:r.tilde?da.TILDE:e.configuration.get("defaultSemverRangePrefix")}var kYe=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function Rne(r,{project:e}){let t=r.match(kYe);return t?t[1]:e.configuration.get("defaultSemverRangePrefix")}function Fne(r,e){let{protocol:t,source:i,params:n,selector:s}=P.parseRange(r.range);return uN.default.valid(s)&&(s=`${e}${r.range}`),P.makeDescriptor(r,P.makeRange({protocol:t,source:i,params:n,selector:s}))}function Nne(r){switch(r){case da.CARET:return Zf.CARET;case da.TILDE:return Zf.TILDE;case da.EXACT:return Zf.EXACT;default:throw new Error(`Assertion failed: Unknown modifier: "${r}"`)}}function Lne(r,e){return P.makeDescriptor(r.anchoredDescriptor,`${vYe}${Nne(e)}`)}async function Tne(r,{project:e,target:t}){let i=new Map,n=s=>{let o=i.get(s.descriptorHash);return o||i.set(s.descriptorHash,o={descriptor:s,locators:[]}),o};for(let s of e.workspaces)if(t===Hr.PEER){let o=s.manifest.peerDependencies.get(r.identHash);o!==void 0&&n(o).locators.push(s.locator)}else{let o=s.manifest.dependencies.get(r.identHash),a=s.manifest.devDependencies.get(r.identHash);t===Hr.DEVELOPMENT?a!==void 0?n(a).locators.push(s.locator):o!==void 0&&n(o).locators.push(s.locator):o!==void 0?n(o).locators.push(s.locator):a!==void 0&&n(a).locators.push(s.locator)}return i}async function fN(r,{cwd:e,workspace:t}){return await xYe(async i=>{x.isAbsolute(r)||(r=x.relative(t.cwd,x.resolve(e,r)),r.match(/^\.{0,2}\//)||(r=`./${r}`));let{project:n}=t,s=await gN(P.makeIdent(null,"archive"),r,{project:t.project,cache:i,workspace:t});if(!s)throw new Error("Assertion failed: The descriptor should have been found");let o=new di,a=n.configuration.makeResolver(),l=n.configuration.makeFetcher(),c={checksums:n.storedChecksums,project:n,cache:i,fetcher:l,report:o,resolver:a},u=a.bindDescriptor(s,t.anchoredLocator,c),g=P.convertDescriptorToLocator(u),f=await l.fetch(g,c),h=await At.find(f.prefixPath,{baseFs:f.packageFs});if(!h.name)throw new Error("Target path doesn't have a name");return P.makeDescriptor(h.name,r)})}async function VC(r,{project:e,workspace:t,cache:i,target:n,modifier:s,strategies:o,maxResults:a=Infinity}){if(!(a>=0))throw new Error(`Invalid maxResults (${a})`);if(r.range!=="unknown")return{suggestions:[{descriptor:r,name:`Use ${P.prettyDescriptor(e.configuration,r)}`,reason:"(unambiguous explicit request)"}],rejections:[]};let l=typeof t!="undefined"&&t!==null&&t.manifest[n].get(r.identHash)||null,c=[],u=[],g=async f=>{try{await f()}catch(h){u.push(h)}};for(let f of o){if(c.length>=a)break;switch(f){case Vr.KEEP:await g(async()=>{l&&c.push({descriptor:l,name:`Keep ${P.prettyDescriptor(e.configuration,l)}`,reason:"(no changes)"})});break;case Vr.REUSE:await g(async()=>{for(let{descriptor:h,locators:p}of(await Tne(r,{project:e,target:n})).values()){if(p.length===1&&p[0].locatorHash===t.anchoredLocator.locatorHash&&o.includes(Vr.KEEP))continue;let m=`(originally used by ${P.prettyLocator(e.configuration,p[0])}`;m+=p.length>1?` and ${p.length-1} other${p.length>2?"s":""})`:")",c.push({descriptor:h,name:`Reuse ${P.prettyDescriptor(e.configuration,h)}`,reason:m})}});break;case Vr.CACHE:await g(async()=>{for(let h of e.storedDescriptors.values())h.identHash===r.identHash&&c.push({descriptor:h,name:`Reuse ${P.prettyDescriptor(e.configuration,h)}`,reason:"(already used somewhere in the lockfile)"})});break;case Vr.PROJECT:await g(async()=>{if(t.manifest.name!==null&&r.identHash===t.manifest.name.identHash)return;let h=e.tryWorkspaceByIdent(r);if(h===null)return;let p=Lne(h,s);c.push({descriptor:p,name:`Attach ${P.prettyDescriptor(e.configuration,p)}`,reason:`(local workspace at ${ae.pretty(e.configuration,h.relativeCwd,ae.Type.PATH)})`})});break;case Vr.LATEST:await g(async()=>{if(r.range!=="unknown")c.push({descriptor:r,name:`Use ${P.prettyRange(e.configuration,r.range)}`,reason:"(explicit range requested)"});else if(n===Hr.PEER)c.push({descriptor:P.makeDescriptor(r,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(!e.configuration.get("enableNetwork"))c.push({descriptor:null,name:"Resolve from latest",reason:ae.pretty(e.configuration,"(unavailable because enableNetwork is toggled off)","grey")});else{let h=await gN(r,"latest",{project:e,cache:i,workspace:t,preserveModifier:!1});h&&(h=Fne(h,s),c.push({descriptor:h,name:`Use ${P.prettyDescriptor(e.configuration,h)}`,reason:"(resolved from latest)"}))}});break}}return{suggestions:c.slice(0,a),rejections:u.slice(0,a)}}async function gN(r,e,{project:t,cache:i,workspace:n,preserveModifier:s=!0}){let o=P.makeDescriptor(r,e),a=new di,l=t.configuration.makeFetcher(),c=t.configuration.makeResolver(),u={project:t,fetcher:l,cache:i,checksums:t.storedChecksums,report:a,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},g=te(N({},u),{resolver:c,fetchOptions:u}),f=c.bindDescriptor(o,n.anchoredLocator,g),h=await c.getCandidates(f,new Map,g);if(h.length===0)return null;let p=h[0],{protocol:m,source:y,params:b,selector:v}=P.parseRange(P.convertToManifestRange(p.reference));if(m===t.configuration.get("defaultProtocol")&&(m=null),uN.default.valid(v)&&s!==!1){let k=typeof s=="string"?s:o.range;v=Rne(k,{project:t})+v}return P.makeDescriptor(p,P.makeRange({protocol:m,source:y,params:b,selector:v}))}async function xYe(r){return await U.mktempPromise(async e=>{let t=ye.create(e);return t.useWithSource(e,{enableMirror:!1,compressionLevel:0},e,{overwrite:!0}),await r(new Nt(e,{configuration:t,check:!1,immutable:!1}))})}var XC=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.exact=J.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=J.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=J.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.dev=J.Boolean("-D,--dev",!1,{description:"Add a package as a dev dependency"});this.peer=J.Boolean("-P,--peer",!1,{description:"Add a package as a peer dependency"});this.optional=J.Boolean("-O,--optional",!1,{description:"Add / upgrade a package to an optional regular / peer dependency"});this.preferDev=J.Boolean("--prefer-dev",!1,{description:"Add / upgrade a package to a dev dependency"});this.interactive=J.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"});this.cached=J.Boolean("--cached",!1,{description:"Reuse the highest version already used somewhere within the project"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.silent=J.Boolean("--silent",{hidden:!0});this.packages=J.Rest()}async execute(){var m;let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=(m=this.interactive)!=null?m:e.get("preferInteractive"),o=_C(this,t),a=[...s?[Vr.REUSE]:[],Vr.PROJECT,...this.cached?[Vr.CACHE]:[],Vr.LATEST],l=s?Infinity:1,c=await Promise.all(this.packages.map(async y=>{let b=y.match(/^\.{0,2}\//)?await fN(y,{cwd:this.context.cwd,workspace:i}):P.tryParseDescriptor(y),v=y.match(/^(https?:|git@github)/);if(v)throw new Pe(`It seems you are trying to add a package using a ${ae.pretty(e,`${v[0]}...`,Ri.RANGE)} url; we now require package names to be explicitly specified. -Try running the command again with the package name prefixed: ${ae.pretty(e,"yarn add",Ri.CODE)} ${ae.pretty(e,P.makeDescriptor(P.makeIdent(null,"my-package"),`${v[0]}...`),Ri.DESCRIPTOR)}`);if(!b)throw new Pe(`The ${ae.pretty(e,y,Ri.CODE)} string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?`);let k=PYe(i,b,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional}),T=await VC(b,{project:t,workspace:i,cache:n,target:k,modifier:o,strategies:a,maxResults:l});return[b,T,k]})),u=await dA.start({configuration:e,stdout:this.context.stdout,suggestInstall:!1},async y=>{for(let[b,{suggestions:v,rejections:k}]of c)if(v.filter(Y=>Y.descriptor!==null).length===0){let[Y]=k;if(typeof Y=="undefined")throw new Error("Assertion failed: Expected an error to have been set");t.configuration.get("enableNetwork")?y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range`):y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range (note: network resolution has been disabled)`),y.reportSeparator(),y.reportExceptionOnce(Y)}});if(u.hasErrors())return u.exitCode();let g=!1,f=[],h=[];for(let[,{suggestions:y},b]of c){let v,k=y.filter($=>$.descriptor!==null),T=k[0].descriptor,Y=k.every($=>P.areDescriptorsEqual($.descriptor,T));k.length===1||Y?v=T:(g=!0,{answer:v}=await(0,One.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:y.map(({descriptor:$,name:z,reason:ne})=>$?{name:z,hint:ne,descriptor:$}:{name:z,hint:ne,disabled:!0}),onCancel:()=>process.exit(130),result($){return this.find($,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let q=i.manifest[b].get(v.identHash);(typeof q=="undefined"||q.descriptorHash!==v.descriptorHash)&&(i.manifest[b].set(v.identHash,v),this.optional&&(b==="dependencies"?i.manifest.ensureDependencyMeta(te(N({},v),{range:"unknown"})).optional=!0:b==="peerDependencies"&&(i.manifest.ensurePeerDependencyMeta(te(N({},v),{range:"unknown"})).optional=!0)),typeof q=="undefined"?f.push([i,b,v,a]):h.push([i,b,q,v]))}return await e.triggerMultipleHooks(y=>y.afterWorkspaceDependencyAddition,f),await e.triggerMultipleHooks(y=>y.afterWorkspaceDependencyReplacement,h),g&&this.context.stdout.write(` -`),(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeLogs:!this.context.quiet},async y=>{await t.install({cache:n,report:y,mode:this.mode})})).exitCode()}};XC.paths=[["add"]],XC.usage=Re.Usage({description:"add dependencies to the project",details:"\n This command adds a package to the package.json for the nearest workspace.\n\n - If it didn't exist before, the package will by default be added to the regular `dependencies` field, but this behavior can be overriden thanks to the `-D,--dev` flag (which will cause the dependency to be added to the `devDependencies` field instead) and the `-P,--peer` flag (which will do the same but for `peerDependencies`).\n\n - If the package was already listed in your dependencies, it will by default be upgraded whether it's part of your `dependencies` or `devDependencies` (it won't ever update `peerDependencies`, though).\n\n - If set, the `--prefer-dev` flag will operate as a more flexible `-D,--dev` in that it will add the package to your `devDependencies` if it isn't already listed in either `dependencies` or `devDependencies`, but it will also happily upgrade your `dependencies` if that's what you already use (whereas `-D,--dev` would throw an exception).\n\n - If set, the `-O,--optional` flag will add the package to the `optionalDependencies` field and, in combination with the `-P,--peer` flag, it will add the package as an optional peer dependency. If the package was already listed in your `dependencies`, it will be upgraded to `optionalDependencies`. If the package was already listed in your `peerDependencies`, in combination with the `-P,--peer` flag, it will be upgraded to an optional peer dependency: `\"peerDependenciesMeta\": { \"<package>\": { \"optional\": true } }`\n\n - If the added package doesn't specify a range at all its `latest` tag will be resolved and the returned version will be used to generate a new semver range (using the `^` modifier by default unless otherwise configured via the `defaultSemverRangePrefix` configuration, or the `~` modifier if `-T,--tilde` is specified, or no modifier at all if `-E,--exact` is specified). Two exceptions to this rule: the first one is that if the package is a workspace then its local version will be used, and the second one is that if you use `-P,--peer` the default range will be `*` and won't be resolved at all.\n\n - If the added package specifies a range (such as `^1.0.0`, `latest`, or `rc`), Yarn will add this range as-is in the resulting package.json entry (in particular, tags such as `rc` will be encoded as-is rather than being converted into a semver range).\n\n If the `--cached` option is used, Yarn will preferably reuse the highest version already used somewhere within the project, even if through a transitive dependency.\n\n If the `-i,--interactive` option is used (or if the `preferInteractive` settings is toggled on) the command will first try to check whether other workspaces in the project use the specified package and, if so, will offer to reuse them.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n For a compilation of all the supported protocols, please consult the dedicated page from our website: https://yarnpkg.com/features/protocols.\n ",examples:[["Add a regular package to the current workspace","$0 add lodash"],["Add a specific version for a package to the current workspace","$0 add lodash@1.2.3"],["Add a package from a GitHub repository (the master branch) to the current workspace using a URL","$0 add lodash@https://github.com/lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol","$0 add lodash@github:lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol (shorthand)","$0 add lodash@lodash/lodash"],["Add a package from a specific branch of a GitHub repository to the current workspace using the GitHub protocol (shorthand)","$0 add lodash-es@lodash/lodash#es"]]});var Mne=XC;function PYe(r,e,{dev:t,peer:i,preferDev:n,optional:s}){let o=r.manifest[Hr.REGULAR].has(e.identHash),a=r.manifest[Hr.DEVELOPMENT].has(e.identHash),l=r.manifest[Hr.PEER].has(e.identHash);if((t||i)&&o)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!t&&!i&&l)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a peer dependency - use either of -D or -P, or remove it from your peer dependencies first`);if(s&&a)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a dev dependency - remove the -O flag or remove it from your dev dependencies first`);if(s&&!i&&l)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a peer dependency - remove the -O flag or add the -P flag or remove it from your peer dependencies first`);if((t||n)&&s)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" cannot simultaneously be a dev dependency and an optional dependency`);return i?Hr.PEER:t||n?Hr.DEVELOPMENT:o?Hr.REGULAR:a?Hr.DEVELOPMENT:Hr.REGULAR}var ZC=class extends Le{constructor(){super(...arguments);this.verbose=J.Boolean("-v,--verbose",!1,{description:"Print both the binary name and the locator of the package that provides the binary"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.name=J.String({required:!1})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,locator:i}=await ze.find(e,this.context.cwd);if(await t.restoreInstallState(),this.name){let o=(await Zt.getPackageAccessibleBinaries(i,{project:t})).get(this.name);if(!o)throw new Pe(`Couldn't find a binary named "${this.name}" for package "${P.prettyLocator(e,i)}"`);let[,a]=o;return this.context.stdout.write(`${a} -`),0}return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async s=>{let o=await Zt.getPackageAccessibleBinaries(i,{project:t}),l=Array.from(o.keys()).reduce((c,u)=>Math.max(c,u.length),0);for(let[c,[u,g]]of o)s.reportJson({name:c,source:P.stringifyIdent(u),path:g});if(this.verbose)for(let[c,[u]]of o)s.reportInfo(null,`${c.padEnd(l," ")} ${P.prettyLocator(e,u)}`);else for(let c of o.keys())s.reportInfo(null,c)})).exitCode()}};ZC.paths=[["bin"]],ZC.usage=Re.Usage({description:"get the path to a binary script",details:` - When used without arguments, this command will print the list of all the binaries available in the current workspace. Adding the \`-v,--verbose\` flag will cause the output to contain both the binary name and the locator of the package that provides the binary. - - When an argument is specified, this command will just print the path to the binary on the standard output and exit. Note that the reported path may be stored within a zip archive. - `,examples:[["List all the available binaries","$0 bin"],["Print the path to a specific binary","$0 bin eslint"]]});var Une=ZC;var $C=class extends Le{constructor(){super(...arguments);this.mirror=J.Boolean("--mirror",!1,{description:"Remove the global cache files instead of the local cache files"});this.all=J.Boolean("--all",!1,{description:"Remove both the global cache files and the local cache files of the current project"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=await Nt.find(e);return(await Je.start({configuration:e,stdout:this.context.stdout},async()=>{let n=(this.all||this.mirror)&&t.mirrorCwd!==null,s=!this.mirror;n&&(await U.removePromise(t.mirrorCwd),await e.triggerHook(o=>o.cleanGlobalArtifacts,e)),s&&await U.removePromise(t.cwd)})).exitCode()}};$C.paths=[["cache","clean"],["cache","clear"]],$C.usage=Re.Usage({description:"remove the shared cache files",details:` - This command will remove all the files from the cache. - `,examples:[["Remove all the local archives","$0 cache clean"],["Remove all the archives stored in the ~/.yarn directory","$0 cache clean --mirror"]]});var Kne=$C;var Hne=ge(m0()),hN=ge(require("util")),em=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.unsafe=J.Boolean("--no-redacted",!1,{description:"Don't redact secrets (such as tokens) from the output"});this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=this.name.replace(/[.[].*$/,""),i=this.name.replace(/^[^.[]*/,"");if(typeof e.settings.get(t)=="undefined")throw new Pe(`Couldn't find a configuration settings named "${t}"`);let s=e.getSpecial(t,{hideSecrets:!this.unsafe,getNativePaths:!0}),o=Se.convertMapsToIndexableObjects(s),a=i?(0,Hne.default)(o,i):o,l=await Je.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async c=>{c.reportJson(a)});if(!this.json){if(typeof a=="string")return this.context.stdout.write(`${a} -`),l.exitCode();hN.inspect.styles.name="cyan",this.context.stdout.write(`${(0,hN.inspect)(a,{depth:Infinity,colors:e.get("enableColors"),compact:!1})} -`)}return l.exitCode()}};em.paths=[["config","get"]],em.usage=Re.Usage({description:"read a configuration settings",details:` - This command will print a configuration setting. - - Secrets (such as tokens) will be redacted from the output by default. If this behavior isn't desired, set the \`--no-redacted\` to get the untransformed value. - `,examples:[["Print a simple configuration setting","yarn config get yarnPath"],["Print a complex configuration setting","yarn config get packageExtensions"],["Print a nested field from the configuration",`yarn config get 'npmScopes["my-company"].npmRegistryServer'`],["Print a token from the configuration","yarn config get npmAuthToken --no-redacted"],["Print a configuration setting as JSON","yarn config get packageExtensions --json"]]});var jne=em;var eoe=ge(IN()),toe=ge(m0()),roe=ge($se()),yN=ge(require("util")),rm=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Set complex configuration settings to JSON values"});this.home=J.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=J.String();this.value=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=()=>{if(!e.projectCwd)throw new Pe("This command must be run from within a project folder");return e.projectCwd},i=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof e.settings.get(i)=="undefined")throw new Pe(`Couldn't find a configuration settings named "${i}"`);if(i==="enableStrictSettings")throw new Pe("This setting only affects the file it's in, and thus cannot be set from the CLI");let o=this.json?JSON.parse(this.value):this.value;await(this.home?h=>ye.updateHomeConfiguration(h):h=>ye.updateConfiguration(t(),h))(h=>{if(n){let p=(0,eoe.default)(h);return(0,roe.default)(p,this.name,o),p}else return te(N({},h),{[i]:o})});let c=(await ye.find(this.context.cwd,this.context.plugins)).getSpecial(i,{hideSecrets:!0,getNativePaths:!0}),u=Se.convertMapsToIndexableObjects(c),g=n?(0,toe.default)(u,n):u;return(await Je.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async h=>{yN.inspect.styles.name="cyan",h.reportInfo(X.UNNAMED,`Successfully set ${this.name} to ${(0,yN.inspect)(g,{depth:Infinity,colors:e.get("enableColors"),compact:!1})}`)})).exitCode()}};rm.paths=[["config","set"]],rm.usage=Re.Usage({description:"change a configuration settings",details:` - This command will set a configuration setting. - - When used without the \`--json\` flag, it can only set a simple configuration setting (a string, a number, or a boolean). - - When used with the \`--json\` flag, it can set both simple and complex configuration settings, including Arrays and Objects. - `,examples:[["Set a simple configuration setting (a string, a number, or a boolean)","yarn config set initScope myScope"],["Set a simple configuration setting (a string, a number, or a boolean) using the `--json` flag",'yarn config set initScope --json \\"myScope\\"'],["Set a complex configuration setting (an Array) using the `--json` flag",`yarn config set unsafeHttpWhitelist --json '["*.example.com", "example.com"]'`],["Set a complex configuration setting (an Object) using the `--json` flag",`yarn config set packageExtensions --json '{ "@babel/parser@*": { "dependencies": { "@babel/types": "*" } } }'`],["Set a nested configuration setting",'yarn config set npmScopes.company.npmRegistryServer "https://npm.example.com"'],["Set a nested configuration setting using indexed access for non-simple keys",`yarn config set 'npmRegistries["//npm.example.com"].npmAuthToken' "ffffffff-ffff-ffff-ffff-ffffffffffff"`]]});var ioe=rm;var goe=ge(IN()),foe=ge(wC()),hoe=ge(uoe()),im=class extends Le{constructor(){super(...arguments);this.home=J.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=()=>{if(!e.projectCwd)throw new Pe("This command must be run from within a project folder");return e.projectCwd},i=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*\.?/,"");if(typeof e.settings.get(i)=="undefined")throw new Pe(`Couldn't find a configuration settings named "${i}"`);let o=this.home?l=>ye.updateHomeConfiguration(l):l=>ye.updateConfiguration(t(),l);return(await Je.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async l=>{let c=!1;await o(u=>{if(!(0,foe.default)(u,this.name))return l.reportWarning(X.UNNAMED,`Configuration doesn't contain setting ${this.name}; there is nothing to unset`),c=!0,u;let g=n?(0,goe.default)(u):N({},u);return(0,hoe.default)(g,this.name),g}),c||l.reportInfo(X.UNNAMED,`Successfully unset ${this.name}`)})).exitCode()}};im.paths=[["config","unset"]],im.usage=Re.Usage({description:"unset a configuration setting",details:` - This command will unset a configuration setting. - `,examples:[["Unset a simple configuration setting","yarn config unset initScope"],["Unset a complex configuration setting","yarn config unset packageExtensions"],["Unset a nested configuration setting","yarn config unset npmScopes.company.npmRegistryServer"]]});var poe=im;var wN=ge(require("util")),nm=class extends Le{constructor(){super(...arguments);this.verbose=J.Boolean("-v,--verbose",!1,{description:"Print the setting description on top of the regular key/value information"});this.why=J.Boolean("--why",!1,{description:"Print the reason why a setting is set a particular way"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins,{strict:!1});return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{if(e.invalid.size>0&&!this.json){for(let[n,s]of e.invalid)i.reportError(X.INVALID_CONFIGURATION_KEY,`Invalid configuration key "${n}" in ${s}`);i.reportSeparator()}if(this.json){let n=Se.sortMap(e.settings.keys(),s=>s);for(let s of n){let o=e.settings.get(s),a=e.getSpecial(s,{hideSecrets:!0,getNativePaths:!0}),l=e.sources.get(s);this.verbose?i.reportJson({key:s,effective:a,source:l}):i.reportJson(N({key:s,effective:a,source:l},o))}}else{let n=Se.sortMap(e.settings.keys(),a=>a),s=n.reduce((a,l)=>Math.max(a,l.length),0),o={breakLength:Infinity,colors:e.get("enableColors"),maxArrayLength:2};if(this.why||this.verbose){let a=n.map(c=>{let u=e.settings.get(c);if(!u)throw new Error(`Assertion failed: This settings ("${c}") should have been registered`);let g=this.why?e.sources.get(c)||"<default>":u.description;return[c,g]}),l=a.reduce((c,[,u])=>Math.max(c,u.length),0);for(let[c,u]of a)i.reportInfo(null,`${c.padEnd(s," ")} ${u.padEnd(l," ")} ${(0,wN.inspect)(e.getSpecial(c,{hideSecrets:!0,getNativePaths:!0}),o)}`)}else for(let a of n)i.reportInfo(null,`${a.padEnd(s," ")} ${(0,wN.inspect)(e.getSpecial(a,{hideSecrets:!0,getNativePaths:!0}),o)}`)}})).exitCode()}};nm.paths=[["config"]],nm.usage=Re.Usage({description:"display the current configuration",details:` - This command prints the current active configuration settings. - `,examples:[["Print the active configuration settings","$0 config"]]});var doe=nm;ws();var BN={};ft(BN,{Strategy:()=>bu,acceptedStrategies:()=>FWe,dedupe:()=>bN});var Coe=ge(ns()),bu;(function(e){e.HIGHEST="highest"})(bu||(bu={}));var FWe=new Set(Object.values(bu)),NWe={highest:async(r,e,{resolver:t,fetcher:i,resolveOptions:n,fetchOptions:s})=>{let o=new Map;for(let[a,l]of r.storedResolutions){let c=r.storedDescriptors.get(a);if(typeof c=="undefined")throw new Error(`Assertion failed: The descriptor (${a}) should have been registered`);Se.getSetWithDefault(o,c.identHash).add(l)}return Array.from(r.storedDescriptors.values(),async a=>{if(e.length&&!Coe.default.isMatch(P.stringifyIdent(a),e))return null;let l=r.storedResolutions.get(a.descriptorHash);if(typeof l=="undefined")throw new Error(`Assertion failed: The resolution (${a.descriptorHash}) should have been registered`);let c=r.originalPackages.get(l);if(typeof c=="undefined"||!t.shouldPersistResolution(c,n))return null;let u=o.get(a.identHash);if(typeof u=="undefined")throw new Error(`Assertion failed: The resolutions (${a.identHash}) should have been registered`);if(u.size===1)return null;let g=[...u].map(y=>{let b=r.originalPackages.get(y);if(typeof b=="undefined")throw new Error(`Assertion failed: The package (${y}) should have been registered`);return b.reference}),f=await t.getSatisfying(a,g,n),h=f==null?void 0:f[0];if(typeof h=="undefined")return null;let p=h.locatorHash,m=r.originalPackages.get(p);if(typeof m=="undefined")throw new Error(`Assertion failed: The package (${p}) should have been registered`);return p===l?null:{descriptor:a,currentPackage:c,updatedPackage:m}})}};async function bN(r,{strategy:e,patterns:t,cache:i,report:n}){let{configuration:s}=r,o=new di,a=s.makeResolver(),l=s.makeFetcher(),c={cache:i,checksums:r.storedChecksums,fetcher:l,project:r,report:o,skipIntegrityCheck:!0,cacheOptions:{skipIntegrityCheck:!0}},u={project:r,resolver:a,report:o,fetchOptions:c};return await n.startTimerPromise("Deduplication step",async()=>{let f=await NWe[e](r,t,{resolver:a,resolveOptions:u,fetcher:l,fetchOptions:c}),h=Ji.progressViaCounter(f.length);n.reportProgress(h);let p=0;await Promise.all(f.map(b=>b.then(v=>{if(v===null)return;p++;let{descriptor:k,currentPackage:T,updatedPackage:Y}=v;n.reportInfo(X.UNNAMED,`${P.prettyDescriptor(s,k)} can be deduped from ${P.prettyLocator(s,T)} to ${P.prettyLocator(s,Y)}`),n.reportJson({descriptor:P.stringifyDescriptor(k),currentResolution:P.stringifyLocator(T),updatedResolution:P.stringifyLocator(Y)}),r.storedResolutions.set(k.descriptorHash,Y.locatorHash)}).finally(()=>h.tick())));let m;switch(p){case 0:m="No packages";break;case 1:m="One package";break;default:m=`${p} packages`}let y=ae.pretty(s,e,ae.Type.CODE);return n.reportInfo(X.UNNAMED,`${m} can be deduped using the ${y} strategy`),p})}var sm=class extends Le{constructor(){super(...arguments);this.strategy=J.String("-s,--strategy",bu.HIGHEST,{description:"The strategy to use when deduping dependencies",validator:nn(bu)});this.check=J.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd),i=await Nt.find(e);await t.restoreInstallState({restoreResolutions:!1});let n=0,s=await Je.start({configuration:e,includeFooter:!1,stdout:this.context.stdout,json:this.json},async o=>{n=await bN(t,{strategy:this.strategy,patterns:this.patterns,cache:i,report:o})});return s.hasErrors()?s.exitCode():this.check?n?1:0:(await Je.start({configuration:e,stdout:this.context.stdout,json:this.json},async a=>{await t.install({cache:i,report:a,mode:this.mode})})).exitCode()}};sm.paths=[["dedupe"]],sm.usage=Re.Usage({description:"deduplicate dependencies with overlapping ranges",details:"\n Duplicates are defined as descriptors with overlapping ranges being resolved and locked to different locators. They are a natural consequence of Yarn's deterministic installs, but they can sometimes pile up and unnecessarily increase the size of your project.\n\n This command dedupes dependencies in the current project using different strategies (only one is implemented at the moment):\n\n - `highest`: Reuses (where possible) the locators with the highest versions. This means that dependencies can only be upgraded, never downgraded. It's also guaranteed that it never takes more than a single pass to dedupe the entire dependency tree.\n\n **Note:** Even though it never produces a wrong dependency tree, this command should be used with caution, as it modifies the dependency tree, which can sometimes cause problems when packages don't strictly follow semver recommendations. Because of this, it is recommended to also review the changes manually.\n\n If set, the `-c,--check` flag will only report the found duplicates, without persisting the modified dependency tree. If changes are found, the command will exit with a non-zero exit code, making it suitable for CI purposes.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n ### In-depth explanation:\n\n Yarn doesn't deduplicate dependencies by default, otherwise installs wouldn't be deterministic and the lockfile would be useless. What it actually does is that it tries to not duplicate dependencies in the first place.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@*`will cause Yarn to reuse `foo@2.3.4`, even if the latest `foo` is actually `foo@2.10.14`, thus preventing unnecessary duplication.\n\n Duplication happens when Yarn can't unlock dependencies that have already been locked inside the lockfile.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@2.10.14` will cause Yarn to install `foo@2.10.14` because the existing resolution doesn't satisfy the range `2.10.14`. This behavior can lead to (sometimes) unwanted duplication, since now the lockfile contains 2 separate resolutions for the 2 `foo` descriptors, even though they have overlapping ranges, which means that the lockfile can be simplified so that both descriptors resolve to `foo@2.10.14`.\n ",examples:[["Dedupe all packages","$0 dedupe"],["Dedupe all packages using a specific strategy","$0 dedupe --strategy highest"],["Dedupe a specific package","$0 dedupe lodash"],["Dedupe all packages with the `@babel/*` scope","$0 dedupe '@babel/*'"],["Check for duplicates (can be used as a CI step)","$0 dedupe --check"]]});var moe=sm;var W0=class extends Le{async execute(){let{plugins:e}=await ye.find(this.context.cwd,this.context.plugins),t=[];for(let o of e){let{commands:a}=o[1];if(a){let c=Bs.from(a).definitions();t.push([o[0],c])}}let i=this.cli.definitions(),n=(o,a)=>o.split(" ").slice(1).join()===a.split(" ").slice(1).join(),s=Ioe()["@yarnpkg/builder"].bundles.standard;for(let o of t){let a=o[1];for(let l of a)i.find(c=>n(c.path,l.path)).plugin={name:o[0],isDefault:s.includes(o[0])}}this.context.stdout.write(`${JSON.stringify(i,null,2)} -`)}};W0.paths=[["--clipanion=definitions"]];var yoe=W0;var z0=class extends Le{async execute(){this.context.stdout.write(this.cli.usage(null))}};z0.paths=[["help"],["--help"],["-h"]];var woe=z0;var QN=class extends Le{constructor(){super(...arguments);this.leadingArgument=J.String();this.args=J.Proxy()}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!P.tryParseIdent(this.leadingArgument)){let e=x.resolve(this.context.cwd,H.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:e})}else return await this.cli.run(["run",this.leadingArgument,...this.args])}},Boe=QN;var _0=class extends Le{async execute(){this.context.stdout.write(`${Kr||"<unknown>"} -`)}};_0.paths=[["-v"],["--version"]];var boe=_0;var om=class extends Le{constructor(){super(...arguments);this.commandName=J.String();this.args=J.Proxy()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,locator:i}=await ze.find(e,this.context.cwd);return await t.restoreInstallState(),await Zt.executePackageShellcode(i,this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,project:t})}};om.paths=[["exec"]],om.usage=Re.Usage({description:"execute a shell script",details:` - This command simply executes a shell script within the context of the root directory of the active workspace using the portable shell. - - It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). - `,examples:[["Execute a single shell command","$0 exec echo Hello World"],["Execute a shell script",'$0 exec "tsc & babel src --out-dir lib"']]});var Qoe=om;ws();var am=class extends Le{constructor(){super(...arguments);this.hash=J.String({required:!1,validator:hp(fp(),[pp(/^p[0-9a-f]{5}$/)])})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd);return await t.restoreInstallState({restoreResolutions:!1}),await t.applyLightResolution(),typeof this.hash!="undefined"?await LWe(this.hash,t,{stdout:this.context.stdout}):(await Je.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async n=>{var o;let s=[([,a])=>P.stringifyLocator(t.storedPackages.get(a.subject)),([,a])=>P.stringifyIdent(a.requested)];for(let[a,l]of Se.sortMap(t.peerRequirements,s)){let c=t.storedPackages.get(l.subject);if(typeof c=="undefined")throw new Error("Assertion failed: Expected the subject package to have been registered");let u=t.storedPackages.get(l.rootRequester);if(typeof u=="undefined")throw new Error("Assertion failed: Expected the root package to have been registered");let g=(o=c.dependencies.get(l.requested.identHash))!=null?o:null,f=ae.pretty(e,a,ae.Type.CODE),h=P.prettyLocator(e,c),p=P.prettyIdent(e,l.requested),m=P.prettyIdent(e,u),y=l.allRequesters.length-1,b=`descendant${y===1?"":"s"}`,v=y>0?` and ${y} ${b}`:"",k=g!==null?"provides":"doesn't provide";n.reportInfo(null,`${f} \u2192 ${h} ${k} ${p} to ${m}${v}`)}})).exitCode()}};am.paths=[["explain","peer-requirements"]],am.usage=Re.Usage({description:"explain a set of peer requirements",details:` - A set of peer requirements represents all peer requirements that a dependent must satisfy when providing a given peer request to a requester and its descendants. - - When the hash argument is specified, this command prints a detailed explanation of all requirements of the set corresponding to the hash and whether they're satisfied or not. - - When used without arguments, this command lists all sets of peer requirements and the corresponding hash that can be used to get detailed information about a given set. - - **Note:** A hash is a six-letter p-prefixed code that can be obtained from peer dependency warnings or from the list of all peer requirements (\`yarn explain peer-requirements\`). - `,examples:[["Explain the corresponding set of peer requirements for a hash","$0 explain peer-requirements p1a4ed"],["List all sets of peer requirements","$0 explain peer-requirements"]]});var Soe=am;async function LWe(r,e,t){let{configuration:i}=e,n=e.peerRequirements.get(r);if(typeof n=="undefined")throw new Error(`No peerDependency requirements found for hash: "${r}"`);return(await Je.start({configuration:i,stdout:t.stdout,includeFooter:!1},async o=>{var b,v;let a=e.storedPackages.get(n.subject);if(typeof a=="undefined")throw new Error("Assertion failed: Expected the subject package to have been registered");let l=e.storedPackages.get(n.rootRequester);if(typeof l=="undefined")throw new Error("Assertion failed: Expected the root package to have been registered");let c=(b=a.dependencies.get(n.requested.identHash))!=null?b:null,u=c!==null?e.storedResolutions.get(c.descriptorHash):null;if(typeof u=="undefined")throw new Error("Assertion failed: Expected the resolution to have been registered");let g=u!==null?e.storedPackages.get(u):null;if(typeof g=="undefined")throw new Error("Assertion failed: Expected the provided package to have been registered");let f=[...n.allRequesters.values()].map(k=>{let T=e.storedPackages.get(k);if(typeof T=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let Y=P.devirtualizeLocator(T),q=e.storedPackages.get(Y.locatorHash);if(typeof q=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let $=q.peerDependencies.get(n.requested.identHash);if(typeof $=="undefined")throw new Error("Assertion failed: Expected the peer dependency to be registered");return{pkg:T,peerDependency:$}});if(g!==null){let k=f.every(({peerDependency:T})=>Wt.satisfiesWithPrereleases(g.version,T.range));o.reportInfo(X.UNNAMED,`${P.prettyLocator(i,a)} provides ${P.prettyLocator(i,g)} with version ${P.prettyReference(i,(v=g.version)!=null?v:"<missing>")}, which ${k?"satisfies":"doesn't satisfy"} the following requirements:`)}else o.reportInfo(X.UNNAMED,`${P.prettyLocator(i,a)} doesn't provide ${P.prettyIdent(i,n.requested)}, breaking the following requirements:`);o.reportSeparator();let h=ae.mark(i),p=[];for(let{pkg:k,peerDependency:T}of Se.sortMap(f,Y=>P.stringifyLocator(Y.pkg))){let q=(g!==null?Wt.satisfiesWithPrereleases(g.version,T.range):!1)?h.Check:h.Cross;p.push({stringifiedLocator:P.stringifyLocator(k),prettyLocator:P.prettyLocator(i,k),prettyRange:P.prettyRange(i,T.range),mark:q})}let m=Math.max(...p.map(({stringifiedLocator:k})=>k.length)),y=Math.max(...p.map(({prettyRange:k})=>k.length));for(let{stringifiedLocator:k,prettyLocator:T,prettyRange:Y,mark:q}of Se.sortMap(p,({stringifiedLocator:$})=>$))o.reportInfo(null,`${T.padEnd(m+(T.length-k.length)," ")} \u2192 ${Y.padEnd(y," ")} ${q}`);p.length>1&&(o.reportSeparator(),o.reportInfo(X.UNNAMED,`Note: these requirements start with ${P.prettyLocator(e.configuration,l)}`))})).exitCode()}ws();var voe=ge(ri()),Am=class extends Le{constructor(){super(...arguments);this.onlyIfNeeded=J.Boolean("--only-if-needed",!1,{description:"Only lock the Yarn version if it isn't already locked"});this.version=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);if(e.get("yarnPath")&&this.onlyIfNeeded)return 0;let t=()=>{if(typeof Kr=="undefined")throw new Pe("The --install flag can only be used without explicit version specifier from the Yarn CLI");return`file://${process.argv[1]}`},i;if(this.version==="self")i=t();else if(this.version==="latest"||this.version==="berry"||this.version==="stable")i=`https://repo.yarnpkg.com/${await lm(e,"stable")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="canary")i=`https://repo.yarnpkg.com/${await lm(e,"canary")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="classic")i="https://nightly.yarnpkg.com/latest.js";else if(this.version.match(/^https?:/))i=this.version;else if(this.version.match(/^\.{0,2}[\\/]/)||H.isAbsolute(this.version))i=`file://${H.resolve(this.version)}`;else if(Wt.satisfiesWithPrereleases(this.version,">=2.0.0"))i=`https://repo.yarnpkg.com/${this.version}/packages/yarnpkg-cli/bin/yarn.js`;else if(Wt.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))i=`https://github.com/yarnpkg/yarn/releases/download/v${this.version}/yarn-${this.version}.js`;else if(Wt.validRange(this.version))i=`https://repo.yarnpkg.com/${await TWe(e,this.version)}/packages/yarnpkg-cli/bin/yarn.js`;else throw new Pe(`Invalid version descriptor "${this.version}"`);return(await Je.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async s=>{let o="file://",a;i.startsWith(o)?(s.reportInfo(X.UNNAMED,`Downloading ${ae.pretty(e,i,Ri.URL)}`),a=await U.readFilePromise(H.toPortablePath(i.slice(o.length)))):(s.reportInfo(X.UNNAMED,`Retrieving ${ae.pretty(e,i,Ri.PATH)}`),a=await ir.get(i,{configuration:e})),await SN(e,null,a,{report:s})})).exitCode()}};Am.paths=[["set","version"]],Am.usage=Re.Usage({description:"lock the Yarn version used by the project",details:"\n This command will download a specific release of Yarn directly from the Yarn GitHub repository, will store it inside your project, and will change the `yarnPath` settings from your project `.yarnrc.yml` file to point to the new file.\n\n A very good use case for this command is to enforce the version of Yarn used by the any single member of your team inside a same project - by doing this you ensure that you have control on Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting a different behavior than you.\n\n The version specifier can be:\n\n - a tag:\n - `latest` / `berry` / `stable` -> the most recent stable berry (`>=2.0.0`) release\n - `canary` -> the most recent canary (release candidate) berry (`>=2.0.0`) release\n - `classic` -> the most recent classic (`^0.x || ^1.x`) release\n\n - a semver range (e.g. `2.x`) -> the most recent version satisfying the range (limited to berry releases)\n\n - a semver version (e.g. `2.4.1`, `1.22.1`)\n\n - a local file referenced through either a relative or absolute path\n\n - `self` -> the version used to invoke the command\n ",examples:[["Download the latest release from the Yarn repository","$0 set version latest"],["Download the latest canary release from the Yarn repository","$0 set version canary"],["Download the latest classic release from the Yarn repository","$0 set version classic"],["Download the most recent Yarn 3 build","$0 set version 3.x"],["Download a specific Yarn 2 build","$0 set version 2.0.0-rc.30"],["Switch back to a specific Yarn 1 release","$0 set version 1.22.1"],["Use a release from the local filesystem","$0 set version ./yarn.cjs"],["Use a release from a URL","$0 set version https://repo.yarnpkg.com/3.1.0/packages/yarnpkg-cli/bin/yarn.js"],["Download the version used to invoke the command","$0 set version self"]]});var koe=Am;async function TWe(r,e){let i=(await ir.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0})).tags.filter(n=>Wt.satisfiesWithPrereleases(n,e));if(i.length===0)throw new Pe(`No matching release found for range ${ae.pretty(r,e,ae.Type.RANGE)}.`);return i[0]}async function lm(r,e){let t=await ir.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0});if(!t.latest[e])throw new Pe(`Tag ${ae.pretty(r,e,ae.Type.RANGE)} not found`);return t.latest[e]}async function SN(r,e,t,{report:i}){var g;e===null&&await U.mktempPromise(async f=>{let h=x.join(f,"yarn.cjs");await U.writeFilePromise(h,t);let{stdout:p}=await Nr.execvp(process.execPath,[H.fromPortablePath(h),"--version"],{cwd:f,env:te(N({},process.env),{YARN_IGNORE_PATH:"1"})});if(e=p.trim(),!voe.default.valid(e))throw new Error(`Invalid semver version. ${ae.pretty(r,"yarn --version",ae.Type.CODE)} returned: -${e}`)});let n=(g=r.projectCwd)!=null?g:r.startingCwd,s=x.resolve(n,".yarn/releases"),o=x.resolve(s,`yarn-${e}.cjs`),a=x.relative(r.startingCwd,o),l=x.relative(n,o),c=r.get("yarnPath"),u=c===null||c.startsWith(`${s}/`);if(i.reportInfo(X.UNNAMED,`Saving the new release in ${ae.pretty(r,a,"magenta")}`),await U.removePromise(x.dirname(o)),await U.mkdirPromise(x.dirname(o),{recursive:!0}),await U.writeFilePromise(o,t,{mode:493}),u){await ye.updateConfiguration(n,{yarnPath:l});let f=await At.tryFind(n)||new At;f.packageManager=`yarn@${e&&Se.isTaggedYarnVersion(e)?e:await lm(r,"stable")}`;let h={};f.exportTo(h);let p=x.join(n,At.fileName),m=`${JSON.stringify(h,null,f.indent)} -`;await U.changeFilePromise(p,m,{automaticNewlines:!0})}}function xoe(r){return X[yI(r)]}var OWe=/## (?<code>YN[0-9]{4}) - `(?<name>[A-Z_]+)`\n\n(?<details>(?:.(?!##))+)/gs;async function MWe(r){let t=`https://repo.yarnpkg.com/${Se.isTaggedYarnVersion(Kr)?Kr:await lm(r,"canary")}/packages/gatsby/content/advanced/error-codes.md`,i=await ir.get(t,{configuration:r});return new Map(Array.from(i.toString().matchAll(OWe),({groups:n})=>{if(!n)throw new Error("Assertion failed: Expected the match to have been successful");let s=xoe(n.code);if(n.name!==s)throw new Error(`Assertion failed: Invalid error code data: Expected "${n.name}" to be named "${s}"`);return[n.code,n.details]}))}var cm=class extends Le{constructor(){super(...arguments);this.code=J.String({required:!1,validator:hp(fp(),[pp(/^YN[0-9]{4}$/)])});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);if(typeof this.code!="undefined"){let t=xoe(this.code),i=ae.pretty(e,t,ae.Type.CODE),n=this.cli.format().header(`${this.code} - ${i}`),o=(await MWe(e)).get(this.code),a=typeof o!="undefined"?ae.jsonOrPretty(this.json,e,ae.tuple(ae.Type.MARKDOWN,{text:o,format:this.cli.format(),paragraphs:!0})):`This error code does not have a description. - -You can help us by editing this page on GitHub \u{1F642}: -${ae.jsonOrPretty(this.json,e,ae.tuple(ae.Type.URL,"https://github.com/yarnpkg/berry/blob/master/packages/gatsby/content/advanced/error-codes.md"))} -`;this.json?this.context.stdout.write(`${JSON.stringify({code:this.code,name:t,details:a})} -`):this.context.stdout.write(`${n} - -${a} -`)}else{let t={children:Se.mapAndFilter(Object.entries(X),([i,n])=>Number.isNaN(Number(i))?Se.mapAndFilter.skip:{label:VA(Number(i)),value:ae.tuple(ae.Type.CODE,n)})};ls.emitTree(t,{configuration:e,stdout:this.context.stdout,json:this.json})}}};cm.paths=[["explain"]],cm.usage=Re.Usage({description:"explain an error code",details:` - When the code argument is specified, this command prints its name and its details. - - When used without arguments, this command lists all error codes and their names. - `,examples:[["Explain an error code","$0 explain YN0006"],["List all error codes","$0 explain"]]});var Poe=cm;var Doe=ge(ns()),um=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Print versions of a package from the whole project"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Print information for all packages, including transitive dependencies"});this.extra=J.Array("-X,--extra",[],{description:"An array of requests of extra data provided by plugins"});this.cache=J.Boolean("--cache",!1,{description:"Print information about the cache entry of a package (path, size, checksum)"});this.dependents=J.Boolean("--dependents",!1,{description:"Print all dependents for each matching package"});this.manifest=J.Boolean("--manifest",!1,{description:"Print data obtained by looking at the package archive (license, homepage, ...)"});this.nameOnly=J.Boolean("--name-only",!1,{description:"Only print the name for the matching packages"});this.virtuals=J.Boolean("--virtuals",!1,{description:"Print each instance of the virtual packages"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i&&!this.all)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let s=new Set(this.extra);this.cache&&s.add("cache"),this.dependents&&s.add("dependents"),this.manifest&&s.add("manifest");let o=(k,{recursive:T})=>{let Y=k.anchoredLocator.locatorHash,q=new Map,$=[Y];for(;$.length>0;){let z=$.shift();if(q.has(z))continue;let ne=t.storedPackages.get(z);if(typeof ne=="undefined")throw new Error("Assertion failed: Expected the package to be registered");if(q.set(z,ne),P.isVirtualLocator(ne)&&$.push(P.devirtualizeLocator(ne).locatorHash),!(!T&&z!==Y))for(let ee of ne.dependencies.values()){let A=t.storedResolutions.get(ee.descriptorHash);if(typeof A=="undefined")throw new Error("Assertion failed: Expected the resolution to be registered");$.push(A)}}return q.values()},a=({recursive:k})=>{let T=new Map;for(let Y of t.workspaces)for(let q of o(Y,{recursive:k}))T.set(q.locatorHash,q);return T.values()},l=({all:k,recursive:T})=>k&&T?t.storedPackages.values():k?a({recursive:T}):o(i,{recursive:T}),c=({all:k,recursive:T})=>{let Y=l({all:k,recursive:T}),q=this.patterns.map(ne=>{let ee=P.parseLocator(ne),A=Doe.default.makeRe(P.stringifyIdent(ee)),oe=P.isVirtualLocator(ee),ce=oe?P.devirtualizeLocator(ee):ee;return Z=>{let O=P.stringifyIdent(Z);if(!A.test(O))return!1;if(ee.reference==="unknown")return!0;let L=P.isVirtualLocator(Z),de=L?P.devirtualizeLocator(Z):Z;return!(oe&&L&&ee.reference!==Z.reference||ce.reference!==de.reference)}}),$=Se.sortMap([...Y],ne=>P.stringifyLocator(ne));return{selection:$.filter(ne=>q.length===0||q.some(ee=>ee(ne))),sortedLookup:$}},{selection:u,sortedLookup:g}=c({all:this.all,recursive:this.recursive});if(u.length===0)throw new Pe("No package matched your request");let f=new Map;if(this.dependents)for(let k of g)for(let T of k.dependencies.values()){let Y=t.storedResolutions.get(T.descriptorHash);if(typeof Y=="undefined")throw new Error("Assertion failed: Expected the resolution to be registered");Se.getArrayWithDefault(f,Y).push(k)}let h=new Map;for(let k of g){if(!P.isVirtualLocator(k))continue;let T=P.devirtualizeLocator(k);Se.getArrayWithDefault(h,T.locatorHash).push(k)}let p={},m={children:p},y=e.makeFetcher(),b={project:t,fetcher:y,cache:n,checksums:t.storedChecksums,report:new di,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},v=[async(k,T,Y)=>{var z,ne;if(!T.has("manifest"))return;let q=await y.fetch(k,b),$;try{$=await At.find(q.prefixPath,{baseFs:q.packageFs})}finally{(z=q.releaseFs)==null||z.call(q)}Y("Manifest",{License:ae.tuple(ae.Type.NO_HINT,$.license),Homepage:ae.tuple(ae.Type.URL,(ne=$.raw.homepage)!=null?ne:null)})},async(k,T,Y)=>{var A;if(!T.has("cache"))return;let q={mockedPackages:t.disabledLocators,unstablePackages:t.conditionalLocators},$=(A=t.storedChecksums.get(k.locatorHash))!=null?A:null,z=n.getLocatorPath(k,$,q),ne;if(z!==null)try{ne=U.statSync(z)}catch{}let ee=typeof ne!="undefined"?[ne.size,ae.Type.SIZE]:void 0;Y("Cache",{Checksum:ae.tuple(ae.Type.NO_HINT,$),Path:ae.tuple(ae.Type.PATH,z),Size:ee})}];for(let k of u){let T=P.isVirtualLocator(k);if(!this.virtuals&&T)continue;let Y={},q={value:[k,ae.Type.LOCATOR],children:Y};if(p[P.stringifyLocator(k)]=q,this.nameOnly){delete q.children;continue}let $=h.get(k.locatorHash);typeof $!="undefined"&&(Y.Instances={label:"Instances",value:ae.tuple(ae.Type.NUMBER,$.length)}),Y.Version={label:"Version",value:ae.tuple(ae.Type.NO_HINT,k.version)};let z=(ee,A)=>{let oe={};if(Y[ee]=oe,Array.isArray(A))oe.children=A.map(ce=>({value:ce}));else{let ce={};oe.children=ce;for(let[Z,O]of Object.entries(A))typeof O!="undefined"&&(ce[Z]={label:Z,value:O})}};if(!T){for(let ee of v)await ee(k,s,z);await e.triggerHook(ee=>ee.fetchPackageInfo,k,s,z)}k.bin.size>0&&!T&&z("Exported Binaries",[...k.bin.keys()].map(ee=>ae.tuple(ae.Type.PATH,ee)));let ne=f.get(k.locatorHash);typeof ne!="undefined"&&ne.length>0&&z("Dependents",ne.map(ee=>ae.tuple(ae.Type.LOCATOR,ee))),k.dependencies.size>0&&!T&&z("Dependencies",[...k.dependencies.values()].map(ee=>{var ce;let A=t.storedResolutions.get(ee.descriptorHash),oe=typeof A!="undefined"&&(ce=t.storedPackages.get(A))!=null?ce:null;return ae.tuple(ae.Type.RESOLUTION,{descriptor:ee,locator:oe})})),k.peerDependencies.size>0&&T&&z("Peer dependencies",[...k.peerDependencies.values()].map(ee=>{var Z,O;let A=k.dependencies.get(ee.identHash),oe=typeof A!="undefined"&&(Z=t.storedResolutions.get(A.descriptorHash))!=null?Z:null,ce=oe!==null&&(O=t.storedPackages.get(oe))!=null?O:null;return ae.tuple(ae.Type.RESOLUTION,{descriptor:ee,locator:ce})}))}ls.emitTree(m,{configuration:e,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}};um.paths=[["info"]],um.usage=Re.Usage({description:"see information related to packages",details:"\n This command prints various information related to the specified packages, accepting glob patterns.\n\n By default, if the locator reference is missing, Yarn will default to print the information about all the matching direct dependencies of the package for the active workspace. To instead print all versions of the package that are direct dependencies of any of your workspaces, use the `-A,--all` flag. Adding the `-R,--recursive` flag will also report transitive dependencies.\n\n Some fields will be hidden by default in order to keep the output readable, but can be selectively displayed by using additional options (`--dependents`, `--manifest`, `--virtuals`, ...) described in the option descriptions.\n\n Note that this command will only print the information directly related to the selected packages - if you wish to know why the package is there in the first place, use `yarn why` which will do just that (it also provides a `-R,--recursive` flag that may be of some help).\n ",examples:[["Show information about Lodash","$0 info lodash"]]});var Roe=um;var V0=ge(yc());ws();var gm=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.immutable=J.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"});this.immutableCache=J.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"});this.checkCache=J.Boolean("--check-cache",!1,{description:"Always refetch the packages and ensure that their checksums are consistent"});this.inlineBuilds=J.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.cacheFolder=J.String("--cache-folder",{hidden:!0});this.frozenLockfile=J.Boolean("--frozen-lockfile",{hidden:!0});this.ignoreEngines=J.Boolean("--ignore-engines",{hidden:!0});this.nonInteractive=J.Boolean("--non-interactive",{hidden:!0});this.preferOffline=J.Boolean("--prefer-offline",{hidden:!0});this.production=J.Boolean("--production",{hidden:!0});this.registry=J.String("--registry",{hidden:!0});this.silent=J.Boolean("--silent",{hidden:!0});this.networkTimeout=J.String("--network-timeout",{hidden:!0})}async execute(){var g;let e=await ye.find(this.context.cwd,this.context.plugins);typeof this.inlineBuilds!="undefined"&&e.useWithSource("<cli>",{enableInlineBuilds:this.inlineBuilds},e.startingCwd,{overwrite:!0});let t=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,i=async(f,{error:h})=>{let p=await Je.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async m=>{h?m.reportError(X.DEPRECATED_CLI_SETTINGS,f):m.reportWarning(X.DEPRECATED_CLI_SETTINGS,f)});return p.hasErrors()?p.exitCode():null};if(typeof this.ignoreEngines!="undefined"){let f=await i("The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",{error:!V0.default.VERCEL});if(f!==null)return f}if(typeof this.registry!="undefined"){let f=await i("The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file",{error:!1});if(f!==null)return f}if(typeof this.preferOffline!="undefined"){let f=await i("The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",{error:!V0.default.VERCEL});if(f!==null)return f}if(typeof this.production!="undefined"){let f=await i("The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",{error:!0});if(f!==null)return f}if(typeof this.nonInteractive!="undefined"){let f=await i("The --non-interactive option is deprecated",{error:!t});if(f!==null)return f}if(typeof this.frozenLockfile!="undefined"&&(await i("The --frozen-lockfile option is deprecated; use --immutable and/or --immutable-cache instead",{error:!1}),this.immutable=this.frozenLockfile),typeof this.cacheFolder!="undefined"){let f=await i("The cache-folder option has been deprecated; use rc settings instead",{error:!V0.default.NETLIFY});if(f!==null)return f}let n=this.mode===Ci.UpdateLockfile;if(n&&(this.immutable||this.immutableCache))throw new Pe(`${ae.pretty(e,"--immutable",ae.Type.CODE)} and ${ae.pretty(e,"--immutable-cache",ae.Type.CODE)} cannot be used with ${ae.pretty(e,"--mode=update-lockfile",ae.Type.CODE)}`);let s=((g=this.immutable)!=null?g:e.get("enableImmutableInstalls"))&&!n,o=this.immutableCache&&!n;if(e.projectCwd!==null){let f=await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async h=>{await UWe(e,s)&&(h.reportInfo(X.AUTOMERGE_SUCCESS,"Automatically fixed merge conflicts \u{1F44D}"),h.reportSeparator())});if(f.hasErrors())return f.exitCode()}if(e.projectCwd!==null&&typeof e.sources.get("nodeLinker")=="undefined"){let f=e.projectCwd,h;try{h=await U.readFilePromise(x.join(f,xt.lockfile),"utf8")}catch{}if(h==null?void 0:h.includes("yarn lockfile v1")){let p=await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async m=>{m.reportInfo(X.AUTO_NM_SUCCESS,"Migrating from Yarn 1; automatically enabling the compatibility node-modules linker \u{1F44D}"),m.reportSeparator(),e.use("<compat>",{nodeLinker:"node-modules"},f,{overwrite:!0}),await ye.updateConfiguration(f,{nodeLinker:"node-modules"})});if(p.hasErrors())return p.exitCode()}}if(e.projectCwd!==null){let f=await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async h=>{var p;((p=ye.telemetry)==null?void 0:p.isNew)&&(h.reportInfo(X.TELEMETRY_NOTICE,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),h.reportInfo(X.TELEMETRY_NOTICE,`Run ${ae.pretty(e,"yarn config set --home enableTelemetry 0",ae.Type.CODE)} to disable`),h.reportSeparator())});if(f.hasErrors())return f.exitCode()}let{project:a,workspace:l}=await ze.find(e,this.context.cwd),c=await Nt.find(e,{immutable:o,check:this.checkCache});if(!l)throw new ht(a.cwd,this.context.cwd);return await a.restoreInstallState({restoreResolutions:!1}),(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeLogs:!0},async f=>{await a.install({cache:c,report:f,immutable:s,mode:this.mode})})).exitCode()}};gm.paths=[["install"],Re.Default],gm.usage=Re.Usage({description:"install the project dependencies",details:` - This command sets up your project if needed. The installation is split into four different steps that each have their own characteristics: - - - **Resolution:** First the package manager will resolve your dependencies. The exact way a dependency version is privileged over another isn't standardized outside of the regular semver guarantees. If a package doesn't resolve to what you would expect, check that all dependencies are correctly declared (also check our website for more information: ). - - - **Fetch:** Then we download all the dependencies if needed, and make sure that they're all stored within our cache (check the value of \`cacheFolder\` in \`yarn config\` to see where the cache files are stored). - - - **Link:** Then we send the dependency tree information to internal plugins tasked with writing them on the disk in some form (for example by generating the .pnp.cjs file you might know). - - - **Build:** Once the dependency tree has been written on the disk, the package manager will now be free to run the build scripts for all packages that might need it, in a topological order compatible with the way they depend on one another. See https://yarnpkg.com/advanced/lifecycle-scripts for detail. - - Note that running this command is not part of the recommended workflow. Yarn supports zero-installs, which means that as long as you store your cache and your .pnp.cjs file inside your repository, everything will work without requiring any install right after cloning your repository or switching branches. - - If the \`--immutable\` option is set (defaults to true on CI), Yarn will abort with an error exit code if the lockfile was to be modified (other paths can be added using the \`immutablePatterns\` configuration setting). For backward compatibility we offer an alias under the name of \`--frozen-lockfile\`, but it will be removed in a later release. - - If the \`--immutable-cache\` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed). - - If the \`--check-cache\` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them. - - If the \`--inline-builds\` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments. - - If the \`--mode=<mode>\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: - - - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. - - - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. - `,examples:[["Install the project","$0 install"],["Validate a project when using Zero-Installs","$0 install --immutable --immutable-cache"],["Validate a project when using Zero-Installs (slightly safer if you accept external PRs)","$0 install --immutable --immutable-cache --check-cache"]]});var Foe=gm,KWe="|||||||",HWe=">>>>>>>",jWe="=======",Noe="<<<<<<<";async function UWe(r,e){if(!r.projectCwd)return!1;let t=x.join(r.projectCwd,r.get("lockfileFilename"));if(!await U.existsPromise(t))return!1;let i=await U.readFilePromise(t,"utf8");if(!i.includes(Noe))return!1;if(e)throw new ct(X.AUTOMERGE_IMMUTABLE,"Cannot autofix a lockfile when running an immutable install");let[n,s]=GWe(i),o,a;try{o=Si(n),a=Si(s)}catch(c){throw new ct(X.AUTOMERGE_FAILED_TO_PARSE,"The individual variants of the lockfile failed to parse")}let l=N(N({},o),a);for(let[c,u]of Object.entries(l))typeof u=="string"&&delete l[c];return await U.changeFilePromise(t,Ua(l),{automaticNewlines:!0}),!0}function GWe(r){let e=[[],[]],t=r.split(/\r?\n/g),i=!1;for(;t.length>0;){let n=t.shift();if(typeof n=="undefined")throw new Error("Assertion failed: Some lines should remain");if(n.startsWith(Noe)){for(;t.length>0;){let s=t.shift();if(typeof s=="undefined")throw new Error("Assertion failed: Some lines should remain");if(s===jWe){i=!1;break}else if(i||s.startsWith(KWe)){i=!0;continue}else e[0].push(s)}for(;t.length>0;){let s=t.shift();if(typeof s=="undefined")throw new Error("Assertion failed: Some lines should remain");if(s.startsWith(HWe))break;e[1].push(s)}}else e[0].push(n),e[1].push(n)}return[e[0].join(` -`),e[1].join(` -`)]}var fm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Link all workspaces belonging to the target project to the current one"});this.private=J.Boolean("-p,--private",!1,{description:"Also link private workspaces belonging to the target project to the current one"});this.relative=J.Boolean("-r,--relative",!1,{description:"Link workspaces using relative paths instead of absolute paths"});this.destination=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=x.resolve(this.context.cwd,H.toPortablePath(this.destination)),o=await ye.find(s,this.context.plugins,{useRc:!1,strict:!1}),{project:a,workspace:l}=await ze.find(o,s);if(t.cwd===a.cwd)throw new Pe("Invalid destination; Can't link the project to itself");if(!l)throw new ht(a.cwd,s);let c=t.topLevelWorkspace,u=[];if(this.all){for(let f of a.workspaces)f.manifest.name&&(!f.manifest.private||this.private)&&u.push(f);if(u.length===0)throw new Pe("No workspace found to be linked in the target project")}else{if(!l.manifest.name)throw new Pe("The target workspace doesn't have a name and thus cannot be linked");if(l.manifest.private&&!this.private)throw new Pe("The target workspace is marked private - use the --private flag to link it anyway");u.push(l)}for(let f of u){let h=P.stringifyIdent(f.locator),p=this.relative?x.relative(t.cwd,f.cwd):f.cwd;c.manifest.resolutions.push({pattern:{descriptor:{fullName:h}},reference:`portal:${p}`})}return(await Je.start({configuration:e,stdout:this.context.stdout},async f=>{await t.install({cache:n,report:f})})).exitCode()}};fm.paths=[["link"]],fm.usage=Re.Usage({description:"connect the local project to another one",details:"\n This command will set a new `resolutions` field in the project-level manifest and point it to the workspace at the specified location (even if part of another project).\n ",examples:[["Register a remote workspace for use in the current project","$0 link ~/ts-loader"],["Register all workspaces from a remote project for use in the current project","$0 link ~/jest --all"]]});var Loe=fm;var hm=class extends Le{constructor(){super(...arguments);this.args=J.Proxy()}async execute(){return this.cli.run(["exec","node",...this.args])}};hm.paths=[["node"]],hm.usage=Re.Usage({description:"run node with the hook already setup",details:` - This command simply runs Node. It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). - - The Node process will use the exact same version of Node as the one used to run Yarn itself, which might be a good way to ensure that your commands always use a consistent Node version. - `,examples:[["Run a Node script","$0 node ./my-script.js"]]});var Toe=hm;var qoe=ge(require("os"));var Moe=ge(require("os"));var YWe="https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml";async function Qu(r){let e=await ir.get(YWe,{configuration:r});return Si(e.toString())}var pm=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{let n=await Qu(e);for(let s of Object.entries(n)){let[l,o]=s,a=o,{experimental:c}=a,u=Or(a,["experimental"]);let g=l;c&&(g+=" [experimental]"),i.reportJson(N({name:l,experimental:c},u)),i.reportInfo(null,g)}})).exitCode()}};pm.paths=[["plugin","list"]],pm.usage=Re.Usage({category:"Plugin-related commands",description:"list the available official plugins",details:"\n This command prints the plugins available directly from the Yarn repository. Only those plugins can be referenced by name in `yarn plugin import`.\n ",examples:[["List the official plugins","$0 plugin list"]]});var Ooe=pm;var qWe=/^[0-9]+$/;function Uoe(r){return qWe.test(r)?`pull/${r}/head`:r}var JWe=({repository:r,branch:e},t)=>[["git","init",H.fromPortablePath(t)],["git","remote","add","origin",r],["git","fetch","origin","--depth=1",Uoe(e)],["git","reset","--hard","FETCH_HEAD"]],WWe=({branch:r})=>[["git","fetch","origin","--depth=1",Uoe(r),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx"]],zWe=({plugins:r,noMinify:e},t)=>[["yarn","build:cli",...new Array().concat(...r.map(i=>["--plugin",x.resolve(t,i)])),...e?["--no-minify"]:[],"|"]],dm=class extends Le{constructor(){super(...arguments);this.installPath=J.String("--path",{description:"The path where the repository should be cloned to"});this.repository=J.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=J.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.plugins=J.Array("--plugin",[],{description:"An array of additional plugins that should be included in the bundle"});this.noMinify=J.Boolean("--no-minify",!1,{description:"Build a bundle for development (debugging) - non-minified and non-mangled"});this.force=J.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.skipPlugins=J.Boolean("--skip-plugins",!1,{description:"Skip updating the contrib plugins"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd),i=typeof this.installPath!="undefined"?x.resolve(this.context.cwd,H.toPortablePath(this.installPath)):x.resolve(H.toPortablePath((0,Moe.tmpdir)()),"yarnpkg-sources",Rn.makeHash(this.repository).slice(0,6));return(await Je.start({configuration:e,stdout:this.context.stdout},async s=>{await kN(this,{configuration:e,report:s,target:i}),s.reportSeparator(),s.reportInfo(X.UNNAMED,"Building a fresh bundle"),s.reportSeparator(),await Cm(zWe(this,i),{configuration:e,context:this.context,target:i}),s.reportSeparator();let o=x.resolve(i,"packages/yarnpkg-cli/bundles/yarn.js"),a=await U.readFilePromise(o);await SN(e,"sources",a,{report:s}),this.skipPlugins||await _We(this,{project:t,report:s,target:i})})).exitCode()}};dm.paths=[["set","version","from","sources"]],dm.usage=Re.Usage({description:"build Yarn from master",details:` - This command will clone the Yarn repository into a temporary folder, then build it. The resulting bundle will then be copied into the local project. - - By default, it also updates all contrib plugins to the same commit the bundle is built from. This behavior can be disabled by using the \`--skip-plugins\` flag. - `,examples:[["Build Yarn from master","$0 set version from sources"]]});var Koe=dm;async function Cm(r,{configuration:e,context:t,target:i}){for(let[n,...s]of r){let o=s[s.length-1]==="|";if(o&&s.pop(),o)await Nr.pipevp(n,s,{cwd:i,stdin:t.stdin,stdout:t.stdout,stderr:t.stderr,strict:!0});else{t.stdout.write(`${ae.pretty(e,` $ ${[n,...s].join(" ")}`,"grey")} -`);try{await Nr.execvp(n,s,{cwd:i,strict:!0})}catch(a){throw t.stdout.write(a.stdout||a.stack),a}}}}async function kN(r,{configuration:e,report:t,target:i}){let n=!1;if(!r.force&&U.existsSync(x.join(i,".git"))){t.reportInfo(X.UNNAMED,"Fetching the latest commits"),t.reportSeparator();try{await Cm(WWe(r),{configuration:e,context:r.context,target:i}),n=!0}catch(s){t.reportSeparator(),t.reportWarning(X.UNNAMED,"Repository update failed; we'll try to regenerate it")}}n||(t.reportInfo(X.UNNAMED,"Cloning the remote repository"),t.reportSeparator(),await U.removePromise(i),await U.mkdirPromise(i,{recursive:!0}),await Cm(JWe(r,i),{configuration:e,context:r.context,target:i}))}async function _We(r,{project:e,report:t,target:i}){let n=await Qu(e.configuration),s=new Set(Object.keys(n));for(let o of e.configuration.plugins.keys())!s.has(o)||await vN(o,r,{project:e,report:t,target:i})}var Hoe=ge(ri()),joe=ge(require("url")),Goe=ge(require("vm"));var mm=class extends Le{constructor(){super(...arguments);this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);return(await Je.start({configuration:e,stdout:this.context.stdout},async i=>{let{project:n}=await ze.find(e,this.context.cwd),s,o;if(this.name.match(/^\.{0,2}[\\/]/)||H.isAbsolute(this.name)){let a=x.resolve(this.context.cwd,H.toPortablePath(this.name));i.reportInfo(X.UNNAMED,`Reading ${ae.pretty(e,a,ae.Type.PATH)}`),s=x.relative(n.cwd,a),o=await U.readFilePromise(a)}else{let a;if(this.name.match(/^https?:/)){try{new joe.URL(this.name)}catch{throw new ct(X.INVALID_PLUGIN_REFERENCE,`Plugin specifier "${this.name}" is neither a plugin name nor a valid url`)}s=this.name,a=this.name}else{let l=P.parseLocator(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-"));if(l.reference!=="unknown"&&!Hoe.default.valid(l.reference))throw new ct(X.UNNAMED,"Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.");let c=P.stringifyIdent(l),u=await Qu(e);if(!Object.prototype.hasOwnProperty.call(u,c))throw new ct(X.PLUGIN_NAME_NOT_FOUND,`Couldn't find a plugin named "${c}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be referenced by their name; any other plugin will have to be referenced through its public url (for example https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js).`);s=c,a=u[c].url,l.reference!=="unknown"?a=a.replace(/\/master\//,`/${c}/${l.reference}/`):Kr!==null&&(a=a.replace(/\/master\//,`/@yarnpkg/cli/${Kr}/`))}i.reportInfo(X.UNNAMED,`Downloading ${ae.pretty(e,a,"green")}`),o=await ir.get(a,{configuration:e})}await xN(s,o,{project:n,report:i})})).exitCode()}};mm.paths=[["plugin","import"]],mm.usage=Re.Usage({category:"Plugin-related commands",description:"download a plugin",details:` - This command downloads the specified plugin from its remote location and updates the configuration to reference it in further CLI invocations. - - Three types of plugin references are accepted: - - - If the plugin is stored within the Yarn repository, it can be referenced by name. - - Third-party plugins can be referenced directly through their public urls. - - Local plugins can be referenced by their path on the disk. - - Plugins cannot be downloaded from the npm registry, and aren't allowed to have dependencies (they need to be bundled into a single file, possibly thanks to the \`@yarnpkg/builder\` package). - `,examples:[['Download and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import @yarnpkg/plugin-exec"],['Download and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import exec"],["Download and activate a community plugin","$0 plugin import https://example.org/path/to/plugin.js"],["Activate a local plugin","$0 plugin import ./path/to/plugin.js"]]});var Yoe=mm;async function xN(r,e,{project:t,report:i}){let{configuration:n}=t,s={},o={exports:s};(0,Goe.runInNewContext)(e.toString(),{module:o,exports:s});let a=o.exports.name,l=`.yarn/plugins/${a}.cjs`,c=x.resolve(t.cwd,l);i.reportInfo(X.UNNAMED,`Saving the new plugin in ${ae.pretty(n,l,"magenta")}`),await U.mkdirPromise(x.dirname(c),{recursive:!0}),await U.writeFilePromise(c,e);let u={path:l,spec:r};await ye.updateConfiguration(t.cwd,g=>{let f=[],h=!1;for(let p of g.plugins||[]){let m=typeof p!="string"?p.path:p,y=x.resolve(t.cwd,H.toPortablePath(m)),{name:b}=Se.dynamicRequire(y);b!==a?f.push(p):(f.push(u),h=!0)}return h||f.push(u),te(N({},g),{plugins:f})})}var VWe=({pluginName:r,noMinify:e},t)=>[["yarn",`build:${r}`,...e?["--no-minify"]:[],"|"]],Em=class extends Le{constructor(){super(...arguments);this.installPath=J.String("--path",{description:"The path where the repository should be cloned to"});this.repository=J.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=J.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.noMinify=J.Boolean("--no-minify",!1,{description:"Build a plugin for development (debugging) - non-minified and non-mangled"});this.force=J.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=typeof this.installPath!="undefined"?x.resolve(this.context.cwd,H.toPortablePath(this.installPath)):x.resolve(H.toPortablePath((0,qoe.tmpdir)()),"yarnpkg-sources",Rn.makeHash(this.repository).slice(0,6));return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{let{project:s}=await ze.find(e,this.context.cwd),o=P.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),a=P.stringifyIdent(o),l=await Qu(e);if(!Object.prototype.hasOwnProperty.call(l,a))throw new ct(X.PLUGIN_NAME_NOT_FOUND,`Couldn't find a plugin named "${a}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);let c=a;await kN(this,{configuration:e,report:n,target:t}),await vN(c,this,{project:s,report:n,target:t})})).exitCode()}};Em.paths=[["plugin","import","from","sources"]],Em.usage=Re.Usage({category:"Plugin-related commands",description:"build a plugin from sources",details:` - This command clones the Yarn repository into a temporary folder, builds the specified contrib plugin and updates the configuration to reference it in further CLI invocations. - - The plugins can be referenced by their short name if sourced from the official Yarn repository. - `,examples:[['Build and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import from sources @yarnpkg/plugin-exec"],['Build and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import from sources exec"]]});var Joe=Em;async function vN(r,{context:e,noMinify:t},{project:i,report:n,target:s}){let o=r.replace(/@yarnpkg\//,""),{configuration:a}=i;n.reportSeparator(),n.reportInfo(X.UNNAMED,`Building a fresh ${o}`),n.reportSeparator(),await Cm(VWe({pluginName:o,noMinify:t},s),{configuration:a,context:e,target:s}),n.reportSeparator();let l=x.resolve(s,`packages/${o}/bundles/${r}.js`),c=await U.readFilePromise(l);await xN(r,c,{project:i,report:n})}var Im=class extends Le{constructor(){super(...arguments);this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd);return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{let s=this.name,o=P.parseIdent(s);if(!e.plugins.has(s))throw new Pe(`${P.prettyIdent(e,o)} isn't referenced by the current configuration`);let a=`.yarn/plugins/${s}.cjs`,l=x.resolve(t.cwd,a);U.existsSync(l)&&(n.reportInfo(X.UNNAMED,`Removing ${ae.pretty(e,a,ae.Type.PATH)}...`),await U.removePromise(l)),n.reportInfo(X.UNNAMED,"Updating the configuration..."),await ye.updateConfiguration(t.cwd,c=>{if(!Array.isArray(c.plugins))return c;let u=c.plugins.filter(g=>g.path!==a);return c.plugins.length===u.length?c:te(N({},c),{plugins:u})})})).exitCode()}};Im.paths=[["plugin","remove"]],Im.usage=Re.Usage({category:"Plugin-related commands",description:"remove a plugin",details:` - This command deletes the specified plugin from the .yarn/plugins folder and removes it from the configuration. - - **Note:** The plugins have to be referenced by their name property, which can be obtained using the \`yarn plugin runtime\` command. Shorthands are not allowed. - `,examples:[["Remove a plugin imported from the Yarn repository","$0 plugin remove @yarnpkg/plugin-typescript"],["Remove a plugin imported from a local file","$0 plugin remove my-local-plugin"]]});var Woe=Im;var ym=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{for(let n of e.plugins.keys()){let s=this.context.plugins.plugins.has(n),o=n;s&&(o+=" [builtin]"),i.reportJson({name:n,builtin:s}),i.reportInfo(null,`${o}`)}})).exitCode()}};ym.paths=[["plugin","runtime"]],ym.usage=Re.Usage({category:"Plugin-related commands",description:"list the active plugins",details:` - This command prints the currently active plugins. Will be displayed both builtin plugins and external plugins. - `,examples:[["List the currently active plugins","$0 plugin runtime"]]});var zoe=ym;var wm=class extends Le{constructor(){super(...arguments);this.idents=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);let s=new Set;for(let a of this.idents)s.add(P.parseIdent(a).identHash);if(await t.restoreInstallState({restoreResolutions:!1}),await t.resolveEverything({cache:n,report:new di}),s.size>0)for(let a of t.storedPackages.values())s.has(a.identHash)&&t.storedBuildState.delete(a.locatorHash);else t.storedBuildState.clear();return(await Je.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async a=>{await t.install({cache:n,report:a})})).exitCode()}};wm.paths=[["rebuild"]],wm.usage=Re.Usage({description:"rebuild the project's native packages",details:` - This command will automatically cause Yarn to forget about previous compilations of the given packages and to run them again. - - Note that while Yarn forgets the compilation, the previous artifacts aren't erased from the filesystem and may affect the next builds (in good or bad). To avoid this, you may remove the .yarn/unplugged folder, or any other relevant location where packages might have been stored (Yarn may offer a way to do that automatically in the future). - - By default all packages will be rebuilt, but you can filter the list by specifying the names of the packages you want to clear from memory. - `,examples:[["Rebuild all packages","$0 rebuild"],["Rebuild fsevents only","$0 rebuild fsevents"]]});var _oe=wm;var PN=ge(ns());ws();var Bm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Apply the operation to all workspaces from the current project"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=this.all?t.workspaces:[i],o=[Hr.REGULAR,Hr.DEVELOPMENT,Hr.PEER],a=[],l=!1,c=[];for(let h of this.patterns){let p=!1,m=P.parseIdent(h);for(let y of s){let b=[...y.manifest.peerDependenciesMeta.keys()];for(let v of(0,PN.default)(b,h))y.manifest.peerDependenciesMeta.delete(v),l=!0,p=!0;for(let v of o){let k=y.manifest.getForScope(v),T=[...k.values()].map(Y=>P.stringifyIdent(Y));for(let Y of(0,PN.default)(T,P.stringifyIdent(m))){let{identHash:q}=P.parseIdent(Y),$=k.get(q);if(typeof $=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");y.manifest[v].delete(q),c.push([y,v,$]),l=!0,p=!0}}}p||a.push(h)}let u=a.length>1?"Patterns":"Pattern",g=a.length>1?"don't":"doesn't",f=this.all?"any":"this";if(a.length>0)throw new Pe(`${u} ${ae.prettyList(e,a,Ri.CODE)} ${g} match any packages referenced by ${f} workspace`);return l?(await e.triggerMultipleHooks(p=>p.afterWorkspaceDependencyRemoval,c),(await Je.start({configuration:e,stdout:this.context.stdout},async p=>{await t.install({cache:n,report:p,mode:this.mode})})).exitCode()):0}};Bm.paths=[["remove"]],Bm.usage=Re.Usage({description:"remove dependencies from the project",details:` - This command will remove the packages matching the specified patterns from the current workspace. - - If the \`--mode=<mode>\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: - - - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. - - - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. - - This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them. - `,examples:[["Remove a dependency from the current project","$0 remove lodash"],["Remove a dependency from all workspaces at once","$0 remove lodash --all"],["Remove all dependencies starting with `eslint-`","$0 remove 'eslint-*'"],["Remove all dependencies with the `@babel` scope","$0 remove '@babel/*'"],["Remove all dependencies matching `react-dom` or `react-helmet`","$0 remove 'react-{dom,helmet}'"]]});var Voe=Bm;var Xoe=ge(require("util")),X0=class extends Le{async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);return(await Je.start({configuration:e,stdout:this.context.stdout},async s=>{let o=i.manifest.scripts,a=Se.sortMap(o.keys(),u=>u),l={breakLength:Infinity,colors:e.get("enableColors"),maxArrayLength:2},c=a.reduce((u,g)=>Math.max(u,g.length),0);for(let[u,g]of o.entries())s.reportInfo(null,`${u.padEnd(c," ")} ${(0,Xoe.inspect)(g,l)}`)})).exitCode()}};X0.paths=[["run"]];var Zoe=X0;var bm=class extends Le{constructor(){super(...arguments);this.inspect=J.String("--inspect",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.inspectBrk=J.String("--inspect-brk",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.topLevel=J.Boolean("-T,--top-level",!1,{description:"Check the root workspace for scripts and/or binaries instead of the current one"});this.binariesOnly=J.Boolean("-B,--binaries-only",!1,{description:"Ignore any user defined scripts and only check for binaries"});this.silent=J.Boolean("--silent",{hidden:!0});this.scriptName=J.String();this.args=J.Proxy()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i,locator:n}=await ze.find(e,this.context.cwd);await t.restoreInstallState();let s=this.topLevel?t.topLevelWorkspace.anchoredLocator:n;if(!this.binariesOnly&&await Zt.hasPackageScript(s,this.scriptName,{project:t}))return await Zt.executePackageScript(s,this.scriptName,this.args,{project:t,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});let o=await Zt.getPackageAccessibleBinaries(s,{project:t});if(o.get(this.scriptName)){let l=[];return this.inspect&&(typeof this.inspect=="string"?l.push(`--inspect=${this.inspect}`):l.push("--inspect")),this.inspectBrk&&(typeof this.inspectBrk=="string"?l.push(`--inspect-brk=${this.inspectBrk}`):l.push("--inspect-brk")),await Zt.executePackageAccessibleBinary(s,this.scriptName,this.args,{cwd:this.context.cwd,project:t,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,nodeArgs:l,packageAccessibleBinaries:o})}if(!this.topLevel&&!this.binariesOnly&&i&&this.scriptName.includes(":")){let c=(await Promise.all(t.workspaces.map(async u=>u.manifest.scripts.has(this.scriptName)?u:null))).filter(u=>u!==null);if(c.length===1)return await Zt.executeWorkspaceScript(c[0],this.scriptName,this.args,{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}if(this.topLevel)throw this.scriptName==="node-gyp"?new Pe(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${P.prettyLocator(e,n)}). This typically happens because some package depends on "node-gyp" to build itself, but didn't list it in their dependencies. To fix that, please run "yarn add node-gyp" into your top-level workspace. You also can open an issue on the repository of the specified package to suggest them to use an optional peer dependency.`):new Pe(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${P.prettyLocator(e,n)}).`);{if(this.scriptName==="global")throw new Pe("The 'yarn global' commands have been removed in 2.x - consider using 'yarn dlx' or a third-party plugin instead");let l=[this.scriptName].concat(this.args);for(let[c,u]of Tf)for(let g of u)if(l.length>=g.length&&JSON.stringify(l.slice(0,g.length))===JSON.stringify(g))throw new Pe(`Couldn't find a script named "${this.scriptName}", but a matching command can be found in the ${c} plugin. You can install it with "yarn plugin import ${c}".`);throw new Pe(`Couldn't find a script named "${this.scriptName}".`)}}};bm.paths=[["run"]],bm.usage=Re.Usage({description:"run a script defined in the package.json",details:` - This command will run a tool. The exact tool that will be executed will depend on the current state of your workspace: - - - If the \`scripts\` field from your local package.json contains a matching script name, its definition will get executed. - - - Otherwise, if one of the local workspace's dependencies exposes a binary with a matching name, this binary will get executed. - - - Otherwise, if the specified name contains a colon character and if one of the workspaces in the project contains exactly one script with a matching name, then this script will get executed. - - Whatever happens, the cwd of the spawned process will be the workspace that declares the script (which makes it possible to call commands cross-workspaces using the third syntax). - `,examples:[["Run the tests from the local workspace","$0 run test"],['Same thing, but without the "run" keyword',"$0 test"],["Inspect Webpack while running","$0 run --inspect-brk webpack"]]});var $oe=bm;var Qm=class extends Le{constructor(){super(...arguments);this.save=J.Boolean("-s,--save",!1,{description:"Persist the resolution inside the top-level manifest"});this.descriptor=J.String();this.resolution=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(await t.restoreInstallState({restoreResolutions:!1}),!i)throw new ht(t.cwd,this.context.cwd);let s=P.parseDescriptor(this.descriptor,!0),o=P.makeDescriptor(s,this.resolution);return t.storedDescriptors.set(s.descriptorHash,s),t.storedDescriptors.set(o.descriptorHash,o),t.resolutionAliases.set(s.descriptorHash,o.descriptorHash),(await Je.start({configuration:e,stdout:this.context.stdout},async l=>{await t.install({cache:n,report:l})})).exitCode()}};Qm.paths=[["set","resolution"]],Qm.usage=Re.Usage({description:"enforce a package resolution",details:'\n This command updates the resolution table so that `descriptor` is resolved by `resolution`.\n\n Note that by default this command only affect the current resolution table - meaning that this "manual override" will disappear if you remove the lockfile, or if the package disappear from the table. If you wish to make the enforced resolution persist whatever happens, add the `-s,--save` flag which will also edit the `resolutions` field from your top-level manifest.\n\n Note that no attempt is made at validating that `resolution` is a valid resolution entry for `descriptor`.\n ',examples:[["Force all instances of lodash@npm:^1.2.3 to resolve to 1.5.0","$0 set resolution lodash@npm:^1.2.3 1.5.0"]]});var eae=Qm;var tae=ge(ns()),Sm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Unlink all workspaces belonging to the target project from the current one"});this.leadingArguments=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);let s=t.topLevelWorkspace,o=new Set;if(this.leadingArguments.length===0&&this.all)for(let{pattern:l,reference:c}of s.manifest.resolutions)c.startsWith("portal:")&&o.add(l.descriptor.fullName);if(this.leadingArguments.length>0)for(let l of this.leadingArguments){let c=x.resolve(this.context.cwd,H.toPortablePath(l));if(Se.isPathLike(l)){let u=await ye.find(c,this.context.plugins,{useRc:!1,strict:!1}),{project:g,workspace:f}=await ze.find(u,c);if(!f)throw new ht(g.cwd,c);if(this.all){for(let h of g.workspaces)h.manifest.name&&o.add(P.stringifyIdent(h.locator));if(o.size===0)throw new Pe("No workspace found to be unlinked in the target project")}else{if(!f.manifest.name)throw new Pe("The target workspace doesn't have a name and thus cannot be unlinked");o.add(P.stringifyIdent(f.locator))}}else{let u=[...s.manifest.resolutions.map(({pattern:g})=>g.descriptor.fullName)];for(let g of(0,tae.default)(u,l))o.add(g)}}return s.manifest.resolutions=s.manifest.resolutions.filter(({pattern:l})=>!o.has(l.descriptor.fullName)),(await Je.start({configuration:e,stdout:this.context.stdout},async l=>{await t.install({cache:n,report:l})})).exitCode()}};Sm.paths=[["unlink"]],Sm.usage=Re.Usage({description:"disconnect the local project from another one",details:` - This command will remove any resolutions in the project-level manifest that would have been added via a yarn link with similar arguments. - `,examples:[["Unregister a remote workspace in the current project","$0 unlink ~/ts-loader"],["Unregister all workspaces from a remote project in the current project","$0 unlink ~/jest --all"],["Unregister all previously linked workspaces","$0 unlink --all"],["Unregister all workspaces matching a glob","$0 unlink '@babel/*' 'pkg-{a,b}'"]]});var rae=Sm;var iae=ge(zC()),DN=ge(ns());ws();var rh=class extends Le{constructor(){super(...arguments);this.interactive=J.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"});this.exact=J.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=J.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=J.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Resolve again ALL resolutions for those packages"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.patterns=J.Rest()}async execute(){return this.recursive?await this.executeUpRecursive():await this.executeUpClassic()}async executeUpRecursive(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=[...t.storedDescriptors.values()],o=s.map(u=>P.stringifyIdent(u)),a=new Set;for(let u of this.patterns){if(P.parseDescriptor(u).range!=="unknown")throw new Pe("Ranges aren't allowed when using --recursive");for(let g of(0,DN.default)(o,u)){let f=P.parseIdent(g);a.add(f.identHash)}}let l=s.filter(u=>a.has(u.identHash));for(let u of l)t.storedDescriptors.delete(u.descriptorHash),t.storedResolutions.delete(u.descriptorHash);return(await Je.start({configuration:e,stdout:this.context.stdout},async u=>{await t.install({cache:n,report:u})})).exitCode()}async executeUpClassic(){var m;let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=(m=this.interactive)!=null?m:e.get("preferInteractive"),o=_C(this,t),a=s?[Vr.KEEP,Vr.REUSE,Vr.PROJECT,Vr.LATEST]:[Vr.PROJECT,Vr.LATEST],l=[],c=[];for(let y of this.patterns){let b=!1,v=P.parseDescriptor(y);for(let k of t.workspaces)for(let T of[Hr.REGULAR,Hr.DEVELOPMENT]){let q=[...k.manifest.getForScope(T).values()].map($=>P.stringifyIdent($));for(let $ of(0,DN.default)(q,P.stringifyIdent(v))){let z=P.parseIdent($),ne=k.manifest[T].get(z.identHash);if(typeof ne=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");let ee=P.makeDescriptor(z,v.range);l.push(Promise.resolve().then(async()=>[k,T,ne,await VC(ee,{project:t,workspace:k,cache:n,target:T,modifier:o,strategies:a})])),b=!0}}b||c.push(y)}if(c.length>1)throw new Pe(`Patterns ${ae.prettyList(e,c,Ri.CODE)} don't match any packages referenced by any workspace`);if(c.length>0)throw new Pe(`Pattern ${ae.prettyList(e,c,Ri.CODE)} doesn't match any packages referenced by any workspace`);let u=await Promise.all(l),g=await dA.start({configuration:e,stdout:this.context.stdout,suggestInstall:!1},async y=>{for(let[,,b,{suggestions:v,rejections:k}]of u){let T=v.filter(Y=>Y.descriptor!==null);if(T.length===0){let[Y]=k;if(typeof Y=="undefined")throw new Error("Assertion failed: Expected an error to have been set");let q=this.cli.error(Y);t.configuration.get("enableNetwork")?y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range - -${q}`):y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range (note: network resolution has been disabled) - -${q}`)}else T.length>1&&!s&&y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} has multiple possible upgrade strategies; use -i to disambiguate manually`)}});if(g.hasErrors())return g.exitCode();let f=!1,h=[];for(let[y,b,,{suggestions:v}]of u){let k,T=v.filter(z=>z.descriptor!==null),Y=T[0].descriptor,q=T.every(z=>P.areDescriptorsEqual(z.descriptor,Y));T.length===1||q?k=Y:(f=!0,{answer:k}=await(0,iae.prompt)({type:"select",name:"answer",message:`Which range to you want to use in ${P.prettyWorkspace(e,y)} \u276F ${b}?`,choices:v.map(({descriptor:z,name:ne,reason:ee})=>z?{name:ne,hint:ee,descriptor:z}:{name:ne,hint:ee,disabled:!0}),onCancel:()=>process.exit(130),result(z){return this.find(z,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let $=y.manifest[b].get(k.identHash);if(typeof $=="undefined")throw new Error("Assertion failed: This descriptor should have a matching entry");if($.descriptorHash!==k.descriptorHash)y.manifest[b].set(k.identHash,k),h.push([y,b,$,k]);else{let z=e.makeResolver(),ne={project:t,resolver:z},ee=z.bindDescriptor($,y.anchoredLocator,ne);t.forgetResolution(ee)}}return await e.triggerMultipleHooks(y=>y.afterWorkspaceDependencyReplacement,h),f&&this.context.stdout.write(` -`),(await Je.start({configuration:e,stdout:this.context.stdout},async y=>{await t.install({cache:n,report:y,mode:this.mode})})).exitCode()}};rh.paths=[["up"]],rh.usage=Re.Usage({description:"upgrade dependencies across the project",details:"\n This command upgrades the packages matching the list of specified patterns to their latest available version across the whole project (regardless of whether they're part of `dependencies` or `devDependencies` - `peerDependencies` won't be affected). This is a project-wide command: all workspaces will be upgraded in the process.\n\n If `-R,--recursive` is set the command will change behavior and no other switch will be allowed. When operating under this mode `yarn up` will force all ranges matching the selected packages to be resolved again (often to the highest available versions) before being stored in the lockfile. It however won't touch your manifests anymore, so depending on your needs you might want to run both `yarn up` and `yarn up -R` to cover all bases.\n\n If `-i,--interactive` is set (or if the `preferInteractive` settings is toggled on) the command will offer various choices, depending on the detected upgrade paths. Some upgrades require this flag in order to resolve ambiguities.\n\n The, `-C,--caret`, `-E,--exact` and `-T,--tilde` options have the same meaning as in the `add` command (they change the modifier used when the range is missing or a tag, and are ignored when the range is explicitly set).\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the later will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n Generally you can see `yarn up` as a counterpart to what was `yarn upgrade --latest` in Yarn 1 (ie it ignores the ranges previously listed in your manifests), but unlike `yarn upgrade` which only upgraded dependencies in the current workspace, `yarn up` will upgrade all workspaces at the same time.\n\n This command accepts glob patterns as arguments (if valid Descriptors and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n **Note:** The ranges have to be static, only the package scopes and names can contain glob patterns.\n ",examples:[["Upgrade all instances of lodash to the latest release","$0 up lodash"],["Upgrade all instances of lodash to the latest release, but ask confirmation for each","$0 up lodash -i"],["Upgrade all instances of lodash to 1.2.3","$0 up lodash@1.2.3"],["Upgrade all instances of packages with the `@babel` scope to the latest release","$0 up '@babel/*'"],["Upgrade all instances of packages containing the word `jest` to the latest release","$0 up '*jest*'"],["Upgrade all instances of packages with the `@babel` scope to 7.0.0","$0 up '@babel/*@7.0.0'"]]}),rh.schema=[tS("recursive",bc.Forbids,["interactive","exact","tilde","caret"],{ignore:[void 0,!1]})];var nae=rh;var vm=class extends Le{constructor(){super(...arguments);this.recursive=J.Boolean("-R,--recursive",!1,{description:"List, for each workspace, what are all the paths that lead to the dependency"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.peers=J.Boolean("--peers",!1,{description:"Also print the peer dependencies that match the specified name"});this.package=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let n=P.parseIdent(this.package).identHash,s=this.recursive?ZWe(t,n,{configuration:e,peers:this.peers}):XWe(t,n,{configuration:e,peers:this.peers});ls.emitTree(s,{configuration:e,stdout:this.context.stdout,json:this.json,separators:1})}};vm.paths=[["why"]],vm.usage=Re.Usage({description:"display the reason why a package is needed",details:` - This command prints the exact reasons why a package appears in the dependency tree. - - If \`-R,--recursive\` is set, the listing will go in depth and will list, for each workspaces, what are all the paths that lead to the dependency. Note that the display is somewhat optimized in that it will not print the package listing twice for a single package, so if you see a leaf named "Foo" when looking for "Bar", it means that "Foo" already got printed higher in the tree. - `,examples:[["Explain why lodash is used in your project","$0 why lodash"]]});var sae=vm;function XWe(r,e,{configuration:t,peers:i}){let n=Se.sortMap(r.storedPackages.values(),a=>P.stringifyLocator(a)),s={},o={children:s};for(let a of n){let l={},c=null;for(let u of a.dependencies.values()){if(!i&&a.peerDependencies.has(u.identHash))continue;let g=r.storedResolutions.get(u.descriptorHash);if(!g)throw new Error("Assertion failed: The resolution should have been registered");let f=r.storedPackages.get(g);if(!f)throw new Error("Assertion failed: The package should have been registered");if(f.identHash!==e)continue;if(c===null){let p=P.stringifyLocator(a);s[p]={value:[a,ae.Type.LOCATOR],children:l}}let h=P.stringifyLocator(f);l[h]={value:[{descriptor:u,locator:f},ae.Type.DEPENDENT]}}}return o}function ZWe(r,e,{configuration:t,peers:i}){let n=Se.sortMap(r.workspaces,f=>P.stringifyLocator(f.anchoredLocator)),s=new Set,o=new Set,a=f=>{if(s.has(f.locatorHash))return o.has(f.locatorHash);if(s.add(f.locatorHash),f.identHash===e)return o.add(f.locatorHash),!0;let h=!1;f.identHash===e&&(h=!0);for(let p of f.dependencies.values()){if(!i&&f.peerDependencies.has(p.identHash))continue;let m=r.storedResolutions.get(p.descriptorHash);if(!m)throw new Error("Assertion failed: The resolution should have been registered");let y=r.storedPackages.get(m);if(!y)throw new Error("Assertion failed: The package should have been registered");a(y)&&(h=!0)}return h&&o.add(f.locatorHash),h};for(let f of n){let h=r.storedPackages.get(f.anchoredLocator.locatorHash);if(!h)throw new Error("Assertion failed: The package should have been registered");a(h)}let l=new Set,c={},u={children:c},g=(f,h,p)=>{if(!o.has(f.locatorHash))return;let m=p!==null?ae.tuple(ae.Type.DEPENDENT,{locator:f,descriptor:p}):ae.tuple(ae.Type.LOCATOR,f),y={},b={value:m,children:y},v=P.stringifyLocator(f);if(h[v]=b,!l.has(f.locatorHash)&&(l.add(f.locatorHash),!(p!==null&&r.tryWorkspaceByLocator(f))))for(let k of f.dependencies.values()){if(!i&&f.peerDependencies.has(k.identHash))continue;let T=r.storedResolutions.get(k.descriptorHash);if(!T)throw new Error("Assertion failed: The resolution should have been registered");let Y=r.storedPackages.get(T);if(!Y)throw new Error("Assertion failed: The package should have been registered");g(Y,y,k)}};for(let f of n){let h=r.storedPackages.get(f.anchoredLocator.locatorHash);if(!h)throw new Error("Assertion failed: The package should have been registered");g(h,c,null)}return u}var GN={};ft(GN,{default:()=>E3e,gitUtils:()=>Su});var Su={};ft(Su,{TreeishProtocols:()=>Mn,clone:()=>KN,fetchBase:()=>Sae,fetchChangedFiles:()=>vae,fetchChangedWorkspaces:()=>C3e,fetchRoot:()=>Qae,isGitUrl:()=>nh,lsRemote:()=>bae,normalizeLocator:()=>ON,normalizeRepoUrl:()=>km,resolveUrl:()=>UN,splitRepoUrl:()=>xm});var LN=ge(Iae()),yae=ge($w()),ih=ge(require("querystring")),TN=ge(ri()),wae=ge(require("url"));function Bae(){return te(N({},process.env),{GIT_SSH_COMMAND:process.env.GIT_SSH_COMMAND||`${process.env.GIT_SSH||"ssh"} -o BatchMode=yes`})}var d3e=[/^ssh:/,/^git(?:\+[^:]+)?:/,/^(?:git\+)?https?:[^#]+\/[^#]+(?:\.git)(?:#.*)?$/,/^git@[^#]+\/[^#]+\.git(?:#.*)?$/,/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z._0-9-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z._0-9-]+?)(?:\.git)?(?:#.*)?$/,/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/],Mn;(function(n){n.Commit="commit",n.Head="head",n.Tag="tag",n.Semver="semver"})(Mn||(Mn={}));function nh(r){return r?d3e.some(e=>!!r.match(e)):!1}function xm(r){r=km(r);let e=r.indexOf("#");if(e===-1)return{repo:r,treeish:{protocol:Mn.Head,request:"HEAD"},extra:{}};let t=r.slice(0,e),i=r.slice(e+1);if(i.match(/^[a-z]+=/)){let n=ih.default.parse(i);for(let[l,c]of Object.entries(n))if(typeof c!="string")throw new Error(`Assertion failed: The ${l} parameter must be a literal string`);let s=Object.values(Mn).find(l=>Object.prototype.hasOwnProperty.call(n,l)),o,a;typeof s!="undefined"?(o=s,a=n[s]):(o=Mn.Head,a="HEAD");for(let l of Object.values(Mn))delete n[l];return{repo:t,treeish:{protocol:o,request:a},extra:n}}else{let n=i.indexOf(":"),s,o;return n===-1?(s=null,o=i):(s=i.slice(0,n),o=i.slice(n+1)),{repo:t,treeish:{protocol:s,request:o},extra:{}}}}function km(r,{git:e=!1}={}){var t;if(r=r.replace(/^git\+https:/,"https:"),r=r.replace(/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)(?:\.git)?(#.*)?$/,"https://github.com/$1/$2.git$3"),r=r.replace(/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/,"https://github.com/$1/$2.git#$3"),e){r=r.replace(/^git\+([^:]+):/,"$1:");let i;try{i=wae.default.parse(r)}catch{i=null}i&&i.protocol==="ssh:"&&((t=i.path)==null?void 0:t.startsWith("/:"))&&(r=r.replace(/^ssh:\/\//,""))}return r}function ON(r){return P.makeLocator(r,km(r.reference))}async function bae(r,e){let t=km(r,{git:!0});if(!ir.getNetworkSettings(`https://${(0,LN.default)(t).resource}`,{configuration:e}).enableNetwork)throw new Error(`Request to '${t}' has been blocked because of your configuration settings`);let n=await MN("listing refs",["ls-remote",t],{cwd:e.startingCwd,env:Bae()},{configuration:e,normalizedRepoUrl:t}),s=new Map,o=/^([a-f0-9]{40})\t([^\n]+)/gm,a;for(;(a=o.exec(n.stdout))!==null;)s.set(a[2],a[1]);return s}async function UN(r,e){let{repo:t,treeish:{protocol:i,request:n},extra:s}=xm(r),o=await bae(t,e),a=(c,u)=>{switch(c){case Mn.Commit:{if(!u.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return ih.default.stringify(te(N({},s),{commit:u}))}case Mn.Head:{let g=o.get(u==="HEAD"?u:`refs/heads/${u}`);if(typeof g=="undefined")throw new Error(`Unknown head ("${u}")`);return ih.default.stringify(te(N({},s),{commit:g}))}case Mn.Tag:{let g=o.get(`refs/tags/${u}`);if(typeof g=="undefined")throw new Error(`Unknown tag ("${u}")`);return ih.default.stringify(te(N({},s),{commit:g}))}case Mn.Semver:{let g=Wt.validRange(u);if(!g)throw new Error(`Invalid range ("${u}")`);let f=new Map([...o.entries()].filter(([p])=>p.startsWith("refs/tags/")).map(([p,m])=>[TN.default.parse(p.slice(10)),m]).filter(p=>p[0]!==null)),h=TN.default.maxSatisfying([...f.keys()],g);if(h===null)throw new Error(`No matching range ("${u}")`);return ih.default.stringify(te(N({},s),{commit:f.get(h)}))}case null:{let g;if((g=l(Mn.Commit,u))!==null||(g=l(Mn.Tag,u))!==null||(g=l(Mn.Head,u))!==null)return g;throw u.match(/^[a-f0-9]+$/)?new Error(`Couldn't resolve "${u}" as either a commit, a tag, or a head - if a commit, use the 40-characters commit hash`):new Error(`Couldn't resolve "${u}" as either a commit, a tag, or a head`)}default:throw new Error(`Invalid Git resolution protocol ("${c}")`)}},l=(c,u)=>{try{return a(c,u)}catch(g){return null}};return`${t}#${a(i,n)}`}async function KN(r,e){return await e.getLimit("cloneConcurrency")(async()=>{let{repo:t,treeish:{protocol:i,request:n}}=xm(r);if(i!=="commit")throw new Error("Invalid treeish protocol when cloning");let s=km(t,{git:!0});if(ir.getNetworkSettings(`https://${(0,LN.default)(s).resource}`,{configuration:e}).enableNetwork===!1)throw new Error(`Request to '${s}' has been blocked because of your configuration settings`);let o=await U.mktempPromise(),a={cwd:o,env:Bae()};return await MN("cloning the repository",["clone","-c core.autocrlf=false",s,H.fromPortablePath(o)],a,{configuration:e,normalizedRepoUrl:s}),await MN("switching branch",["checkout",`${n}`],a,{configuration:e,normalizedRepoUrl:s}),o})}async function Qae(r){let e=null,t,i=r;do t=i,await U.existsPromise(x.join(t,".git"))&&(e=t),i=x.dirname(t);while(e===null&&i!==t);return e}async function Sae(r,{baseRefs:e}){if(e.length===0)throw new Pe("Can't run this command with zero base refs specified.");let t=[];for(let a of e){let{code:l}=await Nr.execvp("git",["merge-base",a,"HEAD"],{cwd:r});l===0&&t.push(a)}if(t.length===0)throw new Pe(`No ancestor could be found between any of HEAD and ${e.join(", ")}`);let{stdout:i}=await Nr.execvp("git",["merge-base","HEAD",...t],{cwd:r,strict:!0}),n=i.trim(),{stdout:s}=await Nr.execvp("git",["show","--quiet","--pretty=format:%s",n],{cwd:r,strict:!0}),o=s.trim();return{hash:n,title:o}}async function vae(r,{base:e,project:t}){let i=Se.buildIgnorePattern(t.configuration.get("changesetIgnorePatterns")),{stdout:n}=await Nr.execvp("git",["diff","--name-only",`${e}`],{cwd:r,strict:!0}),s=n.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>x.resolve(r,H.toPortablePath(c))),{stdout:o}=await Nr.execvp("git",["ls-files","--others","--exclude-standard"],{cwd:r,strict:!0}),a=o.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>x.resolve(r,H.toPortablePath(c))),l=[...new Set([...s,...a].sort())];return i?l.filter(c=>!x.relative(t.cwd,c).match(i)):l}async function C3e({ref:r,project:e}){if(e.configuration.projectCwd===null)throw new Pe("This command can only be run from within a Yarn project");let t=[x.resolve(e.cwd,e.configuration.get("cacheFolder")),x.resolve(e.cwd,e.configuration.get("installStatePath")),x.resolve(e.cwd,e.configuration.get("lockfileFilename")),x.resolve(e.cwd,e.configuration.get("virtualFolder"))];await e.configuration.triggerHook(o=>o.populateYarnPaths,e,o=>{o!=null&&t.push(o)});let i=await Qae(e.configuration.projectCwd);if(i==null)throw new Pe("This command can only be run on Git repositories");let n=await Sae(i,{baseRefs:typeof r=="string"?[r]:e.configuration.get("changesetBaseRefs")}),s=await vae(i,{base:n.hash,project:e});return new Set(Se.mapAndFilter(s,o=>{let a=e.tryWorkspaceByFilePath(o);return a===null?Se.mapAndFilter.skip:t.some(l=>o.startsWith(l))?Se.mapAndFilter.skip:a}))}async function MN(r,e,t,{configuration:i,normalizedRepoUrl:n}){try{return await Nr.execvp("git",e,te(N({},t),{strict:!0}))}catch(s){if(!(s instanceof Nr.ExecError))throw s;let o=s.reportExtra,a=s.stderr.toString();throw new ct(X.EXCEPTION,`Failed ${r}`,l=>{l.reportError(X.EXCEPTION,` ${ae.prettyField(i,{label:"Repository URL",value:ae.tuple(ae.Type.URL,n)})}`);for(let c of a.matchAll(/^(.+?): (.*)$/gm)){let[,u,g]=c;u=u.toLowerCase();let f=u==="error"?"Error":`${(0,yae.default)(u)} Error`;l.reportError(X.EXCEPTION,` ${ae.prettyField(i,{label:f,value:ae.tuple(ae.Type.NO_HINT,g)})}`)}o==null||o(l)})}}var HN=class{supports(e,t){return nh(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,n=ON(e),s=new Map(t.checksums);s.set(n.locatorHash,i);let o=te(N({},t),{checksums:s}),a=await this.downloadHosted(n,o);if(a!==null)return a;let[l,c,u]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote repository`),loader:()=>this.cloneFromRemote(n,o),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:l,releaseFs:c,prefixPath:P.getIdentVendorPath(e),checksum:u}}async downloadHosted(e,t){return t.project.configuration.reduceHook(i=>i.fetchHostedRepository,null,e,t)}async cloneFromRemote(e,t){let i=await KN(e.reference,t.project.configuration),n=xm(e.reference),s=x.join(i,"package.tgz");await Zt.prepareExternalProject(i,s,{configuration:t.project.configuration,report:t.report,workspace:n.extra.workspace,locator:e});let o=await U.readFilePromise(s);return await Se.releaseAfterUseAsync(async()=>await Bi.convertToZip(o,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1}))}};var jN=class{supportsDescriptor(e,t){return nh(e.range)}supportsLocator(e,t){return nh(e.reference)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=await UN(e.range,i.project.configuration);return[P.makeLocator(e,n)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var m3e={configuration:{changesetBaseRefs:{description:"The base git refs that the current HEAD is compared against when detecting changes. Supports git branches, tags, and commits.",type:Ie.STRING,isArray:!0,isNullable:!1,default:["master","origin/master","upstream/master","main","origin/main","upstream/main"]},changesetIgnorePatterns:{description:"Array of glob patterns; files matching them will be ignored when fetching the changed files",type:Ie.STRING,default:[],isArray:!0},cloneConcurrency:{description:"Maximal number of concurrent clones",type:Ie.NUMBER,default:2}},fetchers:[HN],resolvers:[jN]};var E3e=m3e;var Pm=class extends Le{constructor(){super(...arguments);this.since=J.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.verbose=J.Boolean("-v,--verbose",!1,{description:"Also return the cross-dependencies between workspaces"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd);return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async n=>{let s=this.since?await Su.fetchChangedWorkspaces({ref:this.since,project:t}):t.workspaces,o=new Set(s);if(this.recursive)for(let a of[...s].map(l=>l.getRecursiveWorkspaceDependents()))for(let l of a)o.add(l);for(let a of o){let{manifest:l}=a,c;if(this.verbose){let u=new Set,g=new Set;for(let f of At.hardDependencies)for(let[h,p]of l.getForScope(f)){let m=t.tryWorkspaceByDescriptor(p);m===null?t.workspacesByIdent.has(h)&&g.add(p):u.add(m)}c={workspaceDependencies:Array.from(u).map(f=>f.relativeCwd),mismatchedWorkspaceDependencies:Array.from(g).map(f=>P.stringifyDescriptor(f))}}n.reportInfo(null,`${a.relativeCwd}`),n.reportJson(N({location:a.relativeCwd,name:l.name?P.stringifyIdent(l.name):null},c))}})).exitCode()}};Pm.paths=[["workspaces","list"]],Pm.usage=Re.Usage({category:"Workspace-related commands",description:"list all available workspaces",details:"\n This command will print the list of all workspaces in the project.\n\n - If `--since` is set, Yarn will only list workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If both the `-v,--verbose` and `--json` options are set, Yarn will also return the cross-dependencies between each workspaces (useful when you wish to automatically generate Buck / Bazel rules).\n "});var kae=Pm;var Dm=class extends Le{constructor(){super(...arguments);this.workspaceName=J.String();this.commandName=J.String();this.args=J.Proxy()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);let n=t.workspaces,s=new Map(n.map(a=>{let l=P.convertToIdent(a.locator);return[P.stringifyIdent(l),a]})),o=s.get(this.workspaceName);if(o===void 0){let a=Array.from(s.keys()).sort();throw new Pe(`Workspace '${this.workspaceName}' not found. Did you mean any of the following: - - ${a.join(` - - `)}?`)}return this.cli.run([this.commandName,...this.args],{cwd:o.cwd})}};Dm.paths=[["workspace"]],Dm.usage=Re.Usage({category:"Workspace-related commands",description:"run a command within the specified workspace",details:` - This command will run a given sub-command on a single workspace. - `,examples:[["Add a package to a single workspace","yarn workspace components add -D react"],["Run build script on a single workspace","yarn workspace components run build"]]});var xae=Dm;var I3e={configuration:{enableImmutableInstalls:{description:"If true (the default on CI), prevents the install command from modifying the lockfile",type:Ie.BOOLEAN,default:Pae.isCI},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:Ie.STRING,values:["^","~",""],default:da.CARET}},commands:[Kne,jne,ioe,poe,eae,Koe,koe,kae,yoe,woe,Boe,boe,Mne,Une,doe,moe,Qoe,Soe,Poe,Roe,Foe,Loe,rae,Toe,Joe,Yoe,Woe,Ooe,zoe,_oe,Voe,Zoe,$oe,nae,sae,xae]},y3e=I3e;var _N={};ft(_N,{default:()=>B3e});var He={optional:!0},qN=[["@tailwindcss/aspect-ratio@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@tailwindcss/line-clamp@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@fullhuman/postcss-purgecss@3.1.3 || 3.1.3-alpha.0",{peerDependencies:{postcss:"^8.0.0"}}],["@samverschueren/stream-to-observable@<0.3.1",{peerDependenciesMeta:{rxjs:He,zenObservable:He}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:He,zenObservable:He}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{["supports-color"]:He}}],["got@<11",{dependencies:{["@types/responselike"]:"^1.0.0",["@types/keyv"]:"^3.1.1"}}],["cacheable-lookup@<4.1.2",{dependencies:{["@types/keyv"]:"^3.1.1"}}],["http-link-dataloader@*",{peerDependencies:{graphql:"^0.13.1 || ^14.0.0"}}],["typescript-language-server@*",{dependencies:{["vscode-jsonrpc"]:"^5.0.1",["vscode-languageserver-protocol"]:"^3.15.0"}}],["postcss-syntax@*",{peerDependenciesMeta:{["postcss-html"]:He,["postcss-jsx"]:He,["postcss-less"]:He,["postcss-markdown"]:He,["postcss-scss"]:He}}],["jss-plugin-rule-value-function@<=10.1.1",{dependencies:{["tiny-warning"]:"^1.0.2"}}],["ink-select-input@<4.1.0",{peerDependencies:{react:"^16.8.2"}}],["license-webpack-plugin@<2.3.18",{peerDependenciesMeta:{webpack:He}}],["snowpack@>=3.3.0",{dependencies:{["node-gyp"]:"^7.1.0"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:He}}],["reactcss@*",{peerDependencies:{react:"*"}}],["react-color@<=2.19.0",{peerDependencies:{react:"*"}}],["gatsby-plugin-i18n@*",{dependencies:{ramda:"^0.24.1"}}],["useragent@^2.0.0",{dependencies:{request:"^2.88.0",yamlparser:"0.0.x",semver:"5.5.x"}}],["@apollographql/apollo-tools@<=0.5.2",{peerDependencies:{graphql:"^14.2.1 || ^15.0.0"}}],["material-table@^2.0.0",{dependencies:{"@babel/runtime":"^7.11.2"}}],["@babel/parser@*",{dependencies:{"@babel/types":"^7.8.3"}}],["fork-ts-checker-webpack-plugin@<=6.3.4",{peerDependencies:{eslint:">= 6",typescript:">= 2.7",webpack:">= 4","vue-template-compiler":"*"},peerDependenciesMeta:{eslint:He,"vue-template-compiler":He}}],["rc-animate@<=3.1.1",{peerDependencies:{react:">=16.9.0","react-dom":">=16.9.0"}}],["react-bootstrap-table2-paginator@*",{dependencies:{classnames:"^2.2.6"}}],["react-draggable@<=4.4.3",{peerDependencies:{react:">= 16.3.0","react-dom":">= 16.3.0"}}],["apollo-upload-client@<14",{peerDependencies:{graphql:"14 - 15"}}],["react-instantsearch-core@<=6.7.0",{peerDependencies:{algoliasearch:">= 3.1 < 5"}}],["react-instantsearch-dom@<=6.7.0",{dependencies:{"react-fast-compare":"^3.0.0"}}],["ws@<7.2.1",{peerDependencies:{bufferutil:"^4.0.1","utf-8-validate":"^5.0.2"},peerDependenciesMeta:{bufferutil:He,"utf-8-validate":He}}],["react-portal@*",{peerDependencies:{"react-dom":"^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"}}],["react-scripts@<=4.0.1",{peerDependencies:{react:"*"}}],["testcafe@<=1.10.1",{dependencies:{"@babel/plugin-transform-for-of":"^7.12.1","@babel/runtime":"^7.12.5"}}],["testcafe-legacy-api@<=4.2.0",{dependencies:{"testcafe-hammerhead":"^17.0.1","read-file-relative":"^1.2.0"}}],["@google-cloud/firestore@<=4.9.3",{dependencies:{protobufjs:"^6.8.6"}}],["gatsby-source-apiserver@*",{dependencies:{["babel-polyfill"]:"^6.26.0"}}],["@webpack-cli/package-utils@<=1.0.1-alpha.4",{dependencies:{["cross-spawn"]:"^7.0.3"}}],["gatsby-remark-prismjs@<3.3.28",{dependencies:{lodash:"^4"}}],["gatsby-plugin-favicon@*",{peerDependencies:{webpack:"*"}}],["gatsby-plugin-sharp@<=4.6.0-next.3",{dependencies:{debug:"^4.3.1"}}],["gatsby-react-router-scroll@<=5.6.0-next.0",{dependencies:{["prop-types"]:"^15.7.2"}}],["@rebass/forms@*",{dependencies:{["@styled-system/should-forward-prop"]:"^5.0.0"},peerDependencies:{react:"^16.8.6"}}],["rebass@*",{peerDependencies:{react:"^16.8.6"}}],["@ant-design/react-slick@<=0.28.3",{peerDependencies:{react:">=16.0.0"}}],["mqtt@<4.2.7",{dependencies:{duplexify:"^4.1.1"}}],["vue-cli-plugin-vuetify@<=2.0.3",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":He,"vuetify-loader":He}}],["vue-cli-plugin-vuetify@<=2.0.4",{dependencies:{"null-loader":"^3.0.0"}}],["vue-cli-plugin-vuetify@>=2.4.3",{peerDependencies:{vue:"*"}}],["@vuetify/cli-plugin-utils@<=0.0.4",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":He}}],["@vue/cli-plugin-typescript@<=5.0.0-alpha.0",{dependencies:{"babel-loader":"^8.1.0"}}],["@vue/cli-plugin-typescript@<=5.0.0-beta.0",{dependencies:{"@babel/core":"^7.12.16"},peerDependencies:{"vue-template-compiler":"^2.0.0"},peerDependenciesMeta:{"vue-template-compiler":He}}],["cordova-ios@<=6.3.0",{dependencies:{underscore:"^1.9.2"}}],["cordova-lib@<=10.0.1",{dependencies:{underscore:"^1.9.2"}}],["git-node-fs@*",{peerDependencies:{"js-git":"^0.7.8"},peerDependenciesMeta:{"js-git":He}}],["consolidate@<0.16.0",{peerDependencies:{mustache:"^3.0.0"},peerDependenciesMeta:{mustache:He}}],["consolidate@*",{peerDependencies:{velocityjs:"^2.0.1",tinyliquid:"^0.2.34","liquid-node":"^3.0.1",jade:"^1.11.0","then-jade":"*",dust:"^0.3.0","dustjs-helpers":"^1.7.4","dustjs-linkedin":"^2.7.5",swig:"^1.4.2","swig-templates":"^2.0.3","razor-tmpl":"^1.3.1",atpl:">=0.7.6",liquor:"^0.0.5",twig:"^1.15.2",ejs:"^3.1.5",eco:"^1.1.0-rc-3",jazz:"^0.0.18",jqtpl:"~1.1.0",hamljs:"^0.6.2",hamlet:"^0.3.3",whiskers:"^0.4.0","haml-coffee":"^1.14.1","hogan.js":"^3.0.2",templayed:">=0.2.3",handlebars:"^4.7.6",underscore:"^1.11.0",lodash:"^4.17.20",pug:"^3.0.0","then-pug":"*",qejs:"^3.0.5",walrus:"^0.10.1",mustache:"^4.0.1",just:"^0.1.8",ect:"^0.5.9",mote:"^0.2.0",toffee:"^0.3.6",dot:"^1.1.3","bracket-template":"^1.1.5",ractive:"^1.3.12",nunjucks:"^3.2.2",htmling:"^0.0.8","babel-core":"^6.26.3",plates:"~0.4.11","react-dom":"^16.13.1",react:"^16.13.1","arc-templates":"^0.5.3",vash:"^0.13.0",slm:"^2.0.0",marko:"^3.14.4",teacup:"^2.0.0","coffee-script":"^1.12.7",squirrelly:"^5.1.0",twing:"^5.0.2"},peerDependenciesMeta:{velocityjs:He,tinyliquid:He,"liquid-node":He,jade:He,"then-jade":He,dust:He,"dustjs-helpers":He,"dustjs-linkedin":He,swig:He,"swig-templates":He,"razor-tmpl":He,atpl:He,liquor:He,twig:He,ejs:He,eco:He,jazz:He,jqtpl:He,hamljs:He,hamlet:He,whiskers:He,"haml-coffee":He,"hogan.js":He,templayed:He,handlebars:He,underscore:He,lodash:He,pug:He,"then-pug":He,qejs:He,walrus:He,mustache:He,just:He,ect:He,mote:He,toffee:He,dot:He,"bracket-template":He,ractive:He,nunjucks:He,htmling:He,"babel-core":He,plates:He,"react-dom":He,react:He,"arc-templates":He,vash:He,slm:He,marko:He,teacup:He,"coffee-script":He,squirrelly:He,twing:He}}],["vue-loader@<=16.3.3",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",webpack:"^4.1.0 || ^5.0.0-0"},peerDependenciesMeta:{"@vue/compiler-sfc":He}}],["vue-loader@^16.7.0",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",vue:"^3.2.13"},peerDependenciesMeta:{"@vue/compiler-sfc":He,vue:He}}],["scss-parser@*",{dependencies:{lodash:"^4.17.21"}}],["query-ast@*",{dependencies:{lodash:"^4.17.21"}}],["redux-thunk@<=2.3.0",{peerDependencies:{redux:"^4.0.0"}}],["skypack@<=0.3.2",{dependencies:{tar:"^6.1.0"}}],["@npmcli/metavuln-calculator@<2.0.0",{dependencies:{"json-parse-even-better-errors":"^2.3.1"}}],["bin-links@<2.3.0",{dependencies:{"mkdirp-infer-owner":"^1.0.2"}}],["rollup-plugin-polyfill-node@<=0.8.0",{peerDependencies:{rollup:"^1.20.0 || ^2.0.0"}}],["snowpack@<3.8.6",{dependencies:{"magic-string":"^0.25.7"}}],["elm-webpack-loader@*",{dependencies:{temp:"^0.9.4"}}],["winston-transport@<=4.4.0",{dependencies:{logform:"^2.2.0"}}],["jest-vue-preprocessor@*",{dependencies:{"@babel/core":"7.8.7","@babel/template":"7.8.6"},peerDependencies:{pug:"^2.0.4"},peerDependenciesMeta:{pug:He}}],["redux-persist@*",{peerDependencies:{react:">=16"},peerDependenciesMeta:{react:He}}],["sodium@>=3",{dependencies:{"node-gyp":"^3.8.0"}}],["babel-plugin-graphql-tag@<=3.1.0",{peerDependencies:{graphql:"^14.0.0 || ^15.0.0"}}],["@playwright/test@<=1.14.1",{dependencies:{"jest-matcher-utils":"^26.4.2"}}],...["babel-plugin-remove-graphql-queries@<3.14.0-next.1","babel-preset-gatsby-package@<1.14.0-next.1","create-gatsby@<1.14.0-next.1","gatsby-admin@<0.24.0-next.1","gatsby-cli@<3.14.0-next.1","gatsby-core-utils@<2.14.0-next.1","gatsby-design-tokens@<3.14.0-next.1","gatsby-legacy-polyfills@<1.14.0-next.1","gatsby-plugin-benchmark-reporting@<1.14.0-next.1","gatsby-plugin-graphql-config@<0.23.0-next.1","gatsby-plugin-image@<1.14.0-next.1","gatsby-plugin-mdx@<2.14.0-next.1","gatsby-plugin-netlify-cms@<5.14.0-next.1","gatsby-plugin-no-sourcemaps@<3.14.0-next.1","gatsby-plugin-page-creator@<3.14.0-next.1","gatsby-plugin-preact@<5.14.0-next.1","gatsby-plugin-preload-fonts@<2.14.0-next.1","gatsby-plugin-schema-snapshot@<2.14.0-next.1","gatsby-plugin-styletron@<6.14.0-next.1","gatsby-plugin-subfont@<3.14.0-next.1","gatsby-plugin-utils@<1.14.0-next.1","gatsby-recipes@<0.25.0-next.1","gatsby-source-shopify@<5.6.0-next.1","gatsby-source-wikipedia@<3.14.0-next.1","gatsby-transformer-screenshot@<3.14.0-next.1","gatsby-worker@<0.5.0-next.1"].map(r=>[r,{dependencies:{"@babel/runtime":"^7.14.8"}}]),["gatsby-core-utils@<2.14.0-next.1",{dependencies:{got:"8.3.2"}}],["gatsby-plugin-gatsby-cloud@<=3.1.0-next.0",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["gatsby-plugin-gatsby-cloud@<=3.2.0-next.1",{peerDependencies:{webpack:"*"}}],["babel-plugin-remove-graphql-queries@<=3.14.0-next.1",{dependencies:{"gatsby-core-utils":"^2.8.0-next.1"}}],["gatsby-plugin-netlify@3.13.0-next.1",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["clipanion-v3-codemod@<=0.2.0",{peerDependencies:{jscodeshift:"^0.11.0"}}],["react-live@*",{peerDependencies:{"react-dom":"*",react:"*"}}],["webpack@<4.44.1",{peerDependenciesMeta:{"webpack-cli":He,"webpack-command":He}}],["webpack@<5.0.0-beta.23",{peerDependenciesMeta:{"webpack-cli":He}}],["webpack-dev-server@<3.10.2",{peerDependenciesMeta:{"webpack-cli":He}}],["@docusaurus/responsive-loader@<1.5.0",{peerDependenciesMeta:{sharp:He,jimp:He}}],["eslint-module-utils@*",{peerDependenciesMeta:{"eslint-import-resolver-node":He,"eslint-import-resolver-typescript":He,"eslint-import-resolver-webpack":He,"@typescript-eslint/parser":He}}],["eslint-plugin-import@*",{peerDependenciesMeta:{"@typescript-eslint/parser":He}}],["critters-webpack-plugin@<3.0.2",{peerDependenciesMeta:{"html-webpack-plugin":He}}],["terser@<=5.10.0",{dependencies:{acorn:"^8.5.0"}}],["babel-preset-react-app@10.0.x",{dependencies:{"@babel/plugin-proposal-private-property-in-object":"^7.16.0"}}],["eslint-config-react-app@*",{peerDependenciesMeta:{typescript:He}}],["@vue/eslint-config-typescript@<11.0.0",{peerDependenciesMeta:{typescript:He}}],["unplugin-vue2-script-setup@<0.9.1",{peerDependencies:{"@vue/composition-api":"^1.4.3","@vue/runtime-dom":"^3.2.26"}}],["@cypress/snapshot@*",{dependencies:{debug:"^3.2.7"}}],["auto-relay@*",{peerDependencies:{"reflect-metadata":"^0.1.13"}}],["vue-template-babel-compiler@<1.2.0",{peerDependencies:{["vue-template-compiler"]:"^2.6.0"}}],["@parcel/transformer-image@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["@parcel/transformer-js@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["parcel@*",{peerDependenciesMeta:{["@parcel/core"]:He}}],["react-scripts@*",{peerDependencies:{eslint:"*"}}],["focus-trap-react@^8.0.0",{dependencies:{tabbable:"^5.3.2"}}],["react-rnd@<10.3.7",{peerDependencies:{react:">=16.3.0","react-dom":">=16.3.0"}}],["connect-mongo@*",{peerDependencies:{"express-session":"^1.17.1"}}],["vue-i18n@<9",{peerDependencies:{vue:"^2"}}],["vue-router@<4",{peerDependencies:{vue:"^2"}}],["unified@<10",{dependencies:{"@types/unist":"^2.0.0"}}],["react-github-btn@<=1.3.0",{peerDependencies:{react:">=16.3.0"}}],["react-dev-utils@*",{peerDependencies:{typescript:">=2.7",webpack:">=4"},peerDependenciesMeta:{typescript:He}}],["@asyncapi/react-component@<=1.0.0-next.39",{peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}}],["xo@*",{peerDependencies:{webpack:">=1.11.0"},peerDependenciesMeta:{webpack:He}}],["babel-plugin-remove-graphql-queries@<=4.20.0-next.0",{dependencies:{"@babel/types":"^7.15.4"}}],["gatsby-plugin-page-creator@<=4.20.0-next.1",{dependencies:{"fs-extra":"^10.1.0"}}],["gatsby-plugin-utils@<=3.14.0-next.1",{dependencies:{fastq:"^1.13.0"},peerDependencies:{graphql:"^15.0.0"}}],["gatsby-plugin-mdx@<3.1.0-next.1",{dependencies:{mkdirp:"^1.0.4"}}],["gatsby-plugin-mdx@^2",{peerDependencies:{gatsby:"^3.0.0-next"}}]];var JN;function Dae(){return typeof JN=="undefined"&&(JN=require("zlib").brotliDecompressSync(Buffer.from("G7weAByFTVk3Vs7UfHhq4yykgEM7pbW7TI43SG2S5tvGrwHBAzdz+s/npQ6tgEvobvxisrPIadkXeUAJotBn5bDZ5kAhcRqsIHe3F75Walet5hNalwgFDtxb0BiDUjiUQkjG0yW2hto9HPgiCkm316d6bC0kST72YN7D7rfkhCE9x4J0XwB0yavalxpUu2t9xszHrmtwalOxT7VslsxWcB1qpqZwERUra4psWhTV8BgwWeizurec82Caf1ABL11YMfbf8FJ9JBceZOkgmvrQPbC9DUldX/yMbmX06UQluCEjSwUoyO+EZPIjofr+/oAZUck2enraRD+oWLlnlYnj8xB+gwSo9lmmks4fXv574qSqcWA6z21uYkzMu3EWj+K23RxeQlLqiE35/rC8GcS4CGkKHKKq+zAIQwD9iRDNfiAqueLLpicFFrNsAI4zeTD/eO9MHcnRa5m8UT+M2+V+AkFST4BlKneiAQRSdST8KEAIyFlULt6wa9EBd0Ds28VmpaxquJdVt+nwdEs5xUskI13OVtFyY0UrQIRAlCuvvWivvlSKQfTO+2Q8OyUR1W5RvetaPz4jD27hdtwHFFA1Ptx6Ee/t2cY2rg2G46M1pNDRf2pWhvpy8pqMnuI3++4OF3+7OFIWXGjh+o7Nr2jNvbiYcQdQS1h903/jVFgOpA0yJ78z+x759bFA0rq+6aY5qPB4FzS3oYoLupDUhD9nDz6F6H7hpnlMf18KNKDu4IKjTWwrAnY6MFQw1W6ymOALHlFyCZmQhldg1MQHaMVVQTVgDC60TfaBqG++Y8PEoFhN/PBTZT175KNP/BlHDYGOOBmnBdzqJKplZ/ljiVG0ZBzfqeBRrrUkn6rA54462SgiliKoYVnbeptMdXNfAuaupIEi0bApF10TlgHfmEJAPUVidRVFyDupSem5po5vErPqWKhKbUIp0LozpYsIKK57dM/HKr+nguF+7924IIWMICkQ8JUigs9D+W+c4LnNoRtPPKNRUiCYmP+Jfo2lfKCKw8qpraEeWU3uiNRO6zcyKQoXPR5htmzzLznke7b4YbXW3I1lIRzmgG02Udb58U+7TpwyN7XymCgH+wuPDthZVQvRZuEP+SnLtMicz9m5zASWOBiAcLmkuFlTKuHspSIhCBD0yUPKcxu81A+4YD78rA2vtwsUEday9WNyrShyrl60rWmA+SmbYZkQOwFJWArxRYYc5jGhA5ikxYw1rx3ei4NmeX/lKiwpZ9Ln1tV2Ae7sArvxuVLbJjqJRjW1vFXAyHpvLG+8MJ6T2Ubx5M2KDa2SN6vuIGxJ9WQM9Mk3Q7aCNiZONXllhqq24DmoLbQfW2rYWsOgHWjtOmIQMyMKdiHZDjoyIq5+U700nZ6odJAoYXPQBvFNiQ78d5jaXliBqLTJEqUCwi+LiH2mx92EmNKDsJL74Z613+3lf20pxkV1+erOrjj8pW00vsPaahKUM+05ssd5uwM7K482KWEf3TCwlg/o3e5ngto7qSMz7YteIgCsF1UOcsLk7F7MxWbvrPMY473ew0G+noVL8EPbkmEMftMSeL6HFub/zy+2JQ==","base64")).toString()),JN}var WN;function Rae(){return typeof WN=="undefined"&&(WN=require("zlib").brotliDecompressSync(Buffer.from("G8MSIIzURnVBnObTcvb3XE6v2S9Qgc2K801Oa5otNKEtK8BINZNcaQHy+9/vf/WXBimwutXC33P2DPc64pps5rz7NGGWaOKNSPL4Y2KRE8twut2lFOIN+OXPtRmPMRhMTILib2bEQx43az2I5d3YS8Roa5UZpF/ujHb3Djd3GDvYUfvFYSUQ39vb2cmifp/rgB4J/65JK3wRBTvMBoNBmn3mbXC63/gbBkW/2IRPri0O8bcsRBsmarF328pAln04nyJFkwUAvNu934supAqLtyerZZpJ8I8suJHhf/ocMV+scKwa8NOiDKIPXw6Ex/EEZD6TEGaW8N5zvNHYF10l6Lfooj7D5W2k3dgvQSbp2Wv8TGOayS978gxlOLVjTGXs66ozewbrjwElLtyrYNnWTfzzdEutgROUFPVMhnMoy8EjJLLlWwIEoySxliim9kYW30JUHiPVyjt0iAw/ZpPmCbUCltYPnq6ZNblIKhTNhqS/oqC9iya5sGKZTOVsTEg34n92uZTf2iPpcZih8rPW8CzA+adIGmyCPcKdLMsBLShd+zuEbTrqpwuh+DLmracZcjPC5Sdf5odDAhKpFuOsQS67RT+1VgWWygSv3YwxDnylc04/PYuaMeIzhBkLrvs7e/OUzRTF56MmfY6rI63QtEjEQzq637zQqJ39nNhu3NmoRRhW/086bHGBUtx0PE0j3aEGvkdh9WJC8y8j8mqqke9/dQ5la+Q3ba4RlhvTbnfQhPDDab3tUifkjKuOsp13mXEmO00Mu88F/M67R7LXfoFDFLNtgCSWjWX+3Jn1371pJTK9xPBiMJafvDjtFyAzu8rxeQ0TKMQXNPs5xxiBOd+BRJP8KP88XPtJIbZKh/cdW8KvBUkpqKpGoiIaA32c3/JnQr4efXt85mXvidOvn/eU3Pase1typLYBalJ14mCso9h79nuMOuCa/kZAOkJHmTjP5RM2WNoPasZUAnT1TAE/NH25hUxcQv6hQWR/m1PKk4ooXMcM4SR1iYU3fUohvqk4RY2hbmTVVIXv6TvqO+0doOjgeVFAcom+RlwJQmOVH7pr1Q9LoJT6n1DeQEB+NHygsATbIwTcOKZlJsY8G4+suX1uQLjUWwLjjs0mvSvZcLTpIGAekeR7GCgl8eo3ndAqEe2XCav4huliHjdbIPBsGJuPX7lrO9HX1UbXRH5opOe1x6JsOSgHZR+EaxuXVhpLLxm6jk1LJtZfHSc6BKPun3CpYYVMJGwEUyk8MTGG0XL5MfEwaXpnc9TKnBmlGn6nHiGREc3ysn47XIBDzA+YvFdjZzVIEDcKGpS6PbUJehFRjEne8D0lVU1XuRtlgszq6pTNlQ/3MzNOEgCWPyTct22V2mEi2krizn5VDo9B19/X2DB3hCGRMM7ONbtnAcIx/OWB1u5uPbW1gsH8irXxT/IzG0PoXWYjhbMsH3KTuoOl5o17PulcgvsfTSnKFM354GWI8luqZnrswWjiXy3G+Vbyo1KMopFmmvBwNELgaS8z8dNZchx/Cl/xjddxhMcyqtzFyONb2Zdu90NkI8pAeufe7YlXrp53v8Dj/l8vWeVspRKBGXScBBPI/HinSTGmLDOGGOCIyH0JFdOZx0gWsacNlQLJMIrBhqRxXxHF/5pseWwejlAAvZ3klZSDSYY8mkToaWejXhgNomeGtx1DTLEUFMRkgF5yFB22WYdJnaWN14r1YJj81hGi45+jrADS5nYRhCiSlCJJ1nL8pYX+HDSMhdTEWyRcgHVp/IsUIZYMfT+YYncUQPgcxNGCHfZ88vDdrcUuaGIl6zhAsiaq7R5dfqrqXH/JcBhfjT8D0azayIyEz75Nxp6YkcyDxlJq3EXnJUpqDohJJOysL1t1uNiHESlvsxPb5cpbW0+ICZqJmUZus1BMW0F5IVBODLIo2zHHjA0=","base64")).toString()),WN}var zN;function Fae(){return typeof zN=="undefined"&&(zN=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),zN}var Nae=new Map([[P.makeIdent(null,"fsevents").identHash,Dae],[P.makeIdent(null,"resolve").identHash,Rae],[P.makeIdent(null,"typescript").identHash,Fae]]),w3e={hooks:{registerPackageExtensions:async(r,e)=>{for(let[t,i]of qN)e(P.parseDescriptor(t,!0),i)},getBuiltinPatch:async(r,e)=>{var s;let t="compat/";if(!e.startsWith(t))return;let i=P.parseIdent(e.slice(t.length)),n=(s=Nae.get(i.identHash))==null?void 0:s();return typeof n!="undefined"?n:null},reduceDependency:async(r,e,t,i)=>typeof Nae.get(r.identHash)=="undefined"?r:P.makeDescriptor(r,P.makeRange({protocol:"patch:",source:P.stringifyDescriptor(r),selector:`~builtin<compat/${P.stringifyIdent(r)}>`,params:null}))}},B3e=w3e;var VN={};ft(VN,{default:()=>Q3e});var Z0=class extends Le{constructor(){super(...arguments);this.pkg=J.String("-p,--package",{description:"The package to run the provided command from"});this.quiet=J.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=J.String();this.args=J.Proxy()}async execute(){let e=[];this.pkg&&e.push("--package",this.pkg),this.quiet&&e.push("--quiet");let t=P.parseDescriptor(this.command),i;t.scope?i=P.makeIdent(t.scope,`create-${t.name}`):t.name.startsWith("@")?i=P.makeIdent(t.name.substring(1),"create"):i=P.makeIdent(null,`create-${t.name}`);let n=P.stringifyIdent(i);return t.range!=="unknown"&&(n+=`@${t.range}`),this.cli.run(["dlx",...e,n,...this.args])}};Z0.paths=[["create"]];var Lae=Z0;var Rm=class extends Le{constructor(){super(...arguments);this.packages=J.Array("-p,--package",{description:"The package(s) to install before running the command"});this.quiet=J.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=J.String();this.args=J.Proxy()}async execute(){return ye.telemetry=null,await U.mktempPromise(async e=>{var p;let t=x.join(e,`dlx-${process.pid}`);await U.mkdirPromise(t),await U.writeFilePromise(x.join(t,"package.json"),`{} -`),await U.writeFilePromise(x.join(t,"yarn.lock"),"");let i=x.join(t,".yarnrc.yml"),n=await ye.findProjectCwd(this.context.cwd,xt.lockfile),s=!(await ye.find(this.context.cwd,null,{strict:!1})).get("enableGlobalCache"),o=n!==null?x.join(n,".yarnrc.yml"):null;o!==null&&U.existsSync(o)?(await U.copyFilePromise(o,i),await ye.updateConfiguration(t,m=>{let y=te(N({},m),{enableGlobalCache:s,enableTelemetry:!1});return Array.isArray(m.plugins)&&(y.plugins=m.plugins.map(b=>{let v=typeof b=="string"?b:b.path,k=H.isAbsolute(v)?v:H.resolve(H.fromPortablePath(n),v);return typeof b=="string"?k:{path:k,spec:b.spec}})),y})):await U.writeFilePromise(i,`enableGlobalCache: ${s} -enableTelemetry: false -`);let a=(p=this.packages)!=null?p:[this.command],l=P.parseDescriptor(this.command).name,c=await this.cli.run(["add","--",...a],{cwd:t,quiet:this.quiet});if(c!==0)return c;this.quiet||this.context.stdout.write(` -`);let u=await ye.find(t,this.context.plugins),{project:g,workspace:f}=await ze.find(u,t);if(f===null)throw new ht(g.cwd,t);await g.restoreInstallState();let h=await Zt.getWorkspaceAccessibleBinaries(f);return h.has(l)===!1&&h.size===1&&typeof this.packages=="undefined"&&(l=Array.from(h)[0][0]),await Zt.executeWorkspaceAccessibleBinary(f,l,this.args,{packageAccessibleBinaries:h,cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}};Rm.paths=[["dlx"]],Rm.usage=Re.Usage({description:"run a package in a temporary environment",details:"\n This command will install a package within a temporary environment, and run its binary script if it contains any. The binary will run within the current cwd.\n\n By default Yarn will download the package named `command`, but this can be changed through the use of the `-p,--package` flag which will instruct Yarn to still run the same command but from a different package.\n\n Using `yarn dlx` as a replacement of `yarn add` isn't recommended, as it makes your project non-deterministic (Yarn doesn't keep track of the packages installed through `dlx` - neither their name, nor their version).\n ",examples:[["Use create-react-app to create a new React app","yarn dlx create-react-app ./my-app"],["Install multiple packages for a single command",`yarn dlx -p typescript -p ts-node ts-node --transpile-only -e "console.log('hello!')"`]]});var Tae=Rm;var b3e={commands:[Lae,Tae]},Q3e=b3e;var sL={};ft(sL,{default:()=>k3e,fileUtils:()=>XN});var sh=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,Fm=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/,Xr="file:";var XN={};ft(XN,{makeArchiveFromLocator:()=>$0,makeBufferFromLocator:()=>eL,makeLocator:()=>$N,makeSpec:()=>Oae,parseSpec:()=>ZN});function ZN(r){let{params:e,selector:t}=P.parseRange(r),i=H.toPortablePath(t);return{parentLocator:e&&typeof e.locator=="string"?P.parseLocator(e.locator):null,path:i}}function Oae({parentLocator:r,path:e,folderHash:t,protocol:i}){let n=r!==null?{locator:P.stringifyLocator(r)}:{},s=typeof t!="undefined"?{hash:t}:{};return P.makeRange({protocol:i,source:e,selector:e,params:N(N({},s),n)})}function $N(r,{parentLocator:e,path:t,folderHash:i,protocol:n}){return P.makeLocator(r,Oae({parentLocator:e,path:t,folderHash:i,protocol:n}))}async function $0(r,{protocol:e,fetchOptions:t,inMemory:i=!1}){let{parentLocator:n,path:s}=P.parseFileStyleRange(r.reference,{protocol:e}),o=x.isAbsolute(s)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(n,t),a=o.localPath?{packageFs:new _t(Me.root),prefixPath:x.relative(Me.root,o.localPath)}:o;o!==a&&o.releaseFs&&o.releaseFs();let l=a.packageFs,c=x.join(a.prefixPath,s);return await Se.releaseAfterUseAsync(async()=>await Bi.makeArchiveFromDirectory(c,{baseFs:l,prefixPath:P.getIdentVendorPath(r),compressionLevel:t.project.configuration.get("compressionLevel"),inMemory:i}),a.releaseFs)}async function eL(r,{protocol:e,fetchOptions:t}){return(await $0(r,{protocol:e,fetchOptions:t,inMemory:!0})).getBufferAndClose()}var tL=class{supports(e,t){return!!e.reference.startsWith(Xr)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:Xr});if(x.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:x.resolve(s,n)}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async fetchFromDisk(e,t){return $0(e,{protocol:Xr,fetchOptions:t})}};var S3e=2,rL=class{supportsDescriptor(e,t){return e.range.match(sh)?!0:!!e.range.startsWith(Xr)}supportsLocator(e,t){return!!e.reference.startsWith(Xr)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return sh.test(e.range)&&(e=P.makeDescriptor(e,`${Xr}${e.range}`)),P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:n,parentLocator:s}=ZN(e.range);if(s===null)throw new Error("Assertion failed: The descriptor should have been bound");let o=await eL(P.makeLocator(e,P.makeRange({protocol:Xr,source:n,selector:n,params:{locator:P.stringifyLocator(s)}})),{protocol:Xr,fetchOptions:i.fetchOptions}),a=Rn.makeHash(`${S3e}`,o).slice(0,6);return[$N(e,{parentLocator:s,path:n,folderHash:a,protocol:Xr})]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var iL=class{supports(e,t){return Fm.test(e.reference)?!!e.reference.startsWith(Xr):!1}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromDisk(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:Xr}),s=x.isAbsolute(n)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new _t(Me.root),prefixPath:x.relative(Me.root,s.localPath)}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=x.join(o.prefixPath,n),c=await a.readFilePromise(l);return await Se.releaseAfterUseAsync(async()=>await Bi.convertToZip(c,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1}),o.releaseFs)}};var nL=class{supportsDescriptor(e,t){return Fm.test(e.range)?!!(e.range.startsWith(Xr)||sh.test(e.range)):!1}supportsLocator(e,t){return Fm.test(e.reference)?!!e.reference.startsWith(Xr):!1}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return sh.test(e.range)&&(e=P.makeDescriptor(e,`${Xr}${e.range}`)),P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range;return n.startsWith(Xr)&&(n=n.slice(Xr.length)),[P.makeLocator(e,`${Xr}${H.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var v3e={fetchers:[iL,tL],resolvers:[nL,rL]},k3e=v3e;var aL={};ft(aL,{default:()=>D3e});var Mae=ge(require("querystring")),Uae=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];function Kae(r){return r?Uae.some(e=>!!r.match(e)):!1}function Hae(r){let e;for(let a of Uae)if(e=r.match(a),e)break;if(!e)throw new Error(x3e(r));let[,t,i,n,s="master"]=e,{commit:o}=Mae.default.parse(s);return s=o||s.replace(/[^:]*:/,""),{auth:t,username:i,reponame:n,treeish:s}}function x3e(r){return`Input cannot be parsed as a valid GitHub URL ('${r}').`}var oL=class{supports(e,t){return!!Kae(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from GitHub`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i=await ir.get(this.getLocatorUrl(e,t),{configuration:t.project.configuration});return await U.mktempPromise(async n=>{let s=new _t(n);await Bi.extractArchiveTo(i,s,{stripComponents:1});let o=Su.splitRepoUrl(e.reference),a=x.join(n,"package.tgz");await Zt.prepareExternalProject(n,a,{configuration:t.project.configuration,report:t.report,workspace:o.extra.workspace,locator:e});let l=await U.readFilePromise(a);return await Bi.convertToZip(l,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,t){let{auth:i,username:n,reponame:s,treeish:o}=Hae(e.reference);return`https://${i?`${i}@`:""}github.com/${n}/${s}/archive/${o}.tar.gz`}};var P3e={hooks:{async fetchHostedRepository(r,e,t){if(r!==null)return r;let i=new oL;if(!i.supports(e,t))return null;try{return await i.fetch(e,t)}catch(n){return null}}}},D3e=P3e;var cL={};ft(cL,{default:()=>F3e});var Nm=/^[^?]*\.(?:tar\.gz|tgz)(?:\?.*)?$/,Lm=/^https?:/;var AL=class{supports(e,t){return Nm.test(e.reference)?!!Lm.test(e.reference):!1}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i=await ir.get(e.reference,{configuration:t.project.configuration});return await Bi.convertToZip(i,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}};var lL=class{supportsDescriptor(e,t){return Nm.test(e.range)?!!Lm.test(e.range):!1}supportsLocator(e,t){return Nm.test(e.reference)?!!Lm.test(e.reference):!1}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){return[P.convertDescriptorToLocator(e)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var R3e={fetchers:[AL],resolvers:[lL]},F3e=R3e;var hL={};ft(hL,{default:()=>N4e});var hAe=ge(fAe()),fL=ge(require("util")),Tm=class extends Le{constructor(){super(...arguments);this.private=J.Boolean("-p,--private",!1,{description:"Initialize a private package"});this.workspace=J.Boolean("-w,--workspace",!1,{description:"Initialize a workspace root with a `packages/` directory"});this.install=J.String("-i,--install",!1,{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"});this.usev2=J.Boolean("-2",!1,{hidden:!0});this.yes=J.Boolean("-y,--yes",{hidden:!0});this.assumeFreshProject=J.Boolean("--assume-fresh-project",!1,{hidden:!0})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=typeof this.install=="string"?this.install:this.usev2||this.install===!0?"latest":null;return t!==null?await this.executeProxy(e,t):await this.executeRegular(e)}async executeProxy(e,t){if(e.projectCwd!==null&&e.projectCwd!==this.context.cwd)throw new Pe("Cannot use the --install flag from within a project subdirectory");U.existsSync(this.context.cwd)||await U.mkdirPromise(this.context.cwd,{recursive:!0});let i=x.join(this.context.cwd,e.get("lockfileFilename"));U.existsSync(i)||await U.writeFilePromise(i,"");let n=await this.cli.run(["set","version",t],{quiet:!0});if(n!==0)return n;let s=[];return this.private&&s.push("-p"),this.workspace&&s.push("-w"),this.yes&&s.push("-y"),await U.mktempPromise(async o=>{let{code:a}=await Nr.pipevp("yarn",["init",...s],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await Zt.makeScriptEnv({binFolder:o})});return a})}async executeRegular(e){var l;let t=null;try{t=(await ze.find(e,this.context.cwd)).project}catch{t=null}U.existsSync(this.context.cwd)||await U.mkdirPromise(this.context.cwd,{recursive:!0});let i=await At.tryFind(this.context.cwd)||new At,n=Object.fromEntries(e.get("initFields").entries());i.load(n),i.name=(l=i.name)!=null?l:P.makeIdent(e.get("initScope"),x.basename(this.context.cwd)),i.packageManager=Kr&&Se.isTaggedYarnVersion(Kr)?`yarn@${Kr}`:null,typeof i.raw.private=="undefined"&&(this.private||this.workspace&&i.workspaceDefinitions.length===0)&&(i.private=!0),this.workspace&&i.workspaceDefinitions.length===0&&(await U.mkdirPromise(x.join(this.context.cwd,"packages"),{recursive:!0}),i.workspaceDefinitions=[{pattern:"packages/*"}]);let s={};i.exportTo(s),fL.inspect.styles.name="cyan",this.context.stdout.write(`${(0,fL.inspect)(s,{depth:Infinity,colors:!0,compact:!1})} -`);let o=x.join(this.context.cwd,At.fileName);await U.changeFilePromise(o,`${JSON.stringify(s,null,2)} -`,{automaticNewlines:!0});let a=x.join(this.context.cwd,"README.md");if(U.existsSync(a)||await U.writeFilePromise(a,`# ${P.stringifyIdent(i.name)} -`),!t||t.cwd===this.context.cwd){let c=x.join(this.context.cwd,xt.lockfile);U.existsSync(c)||await U.writeFilePromise(c,"");let g=[".yarn/*","!.yarn/patches","!.yarn/plugins","!.yarn/releases","!.yarn/sdks","!.yarn/versions","","# Swap the comments on the following lines if you don't wish to use zero-installs","# Documentation here: https://yarnpkg.com/features/zero-installs","!.yarn/cache","#.pnp.*"].map(y=>`${y} -`).join(""),f=x.join(this.context.cwd,".gitignore");U.existsSync(f)||await U.writeFilePromise(f,g);let h={["*"]:{endOfLine:"lf",insertFinalNewline:!0},["*.{js,json,yml}"]:{charset:"utf-8",indentStyle:"space",indentSize:2}};(0,hAe.default)(h,e.get("initEditorConfig"));let p=`root = true -`;for(let[y,b]of Object.entries(h)){p+=` -[${y}] -`;for(let[v,k]of Object.entries(b))p+=`${v.replace(/[A-Z]/g,Y=>`_${Y.toLowerCase()}`)} = ${k} -`}let m=x.join(this.context.cwd,".editorconfig");U.existsSync(m)||await U.writeFilePromise(m,p),U.existsSync(x.join(this.context.cwd,".git"))||await Nr.execvp("git",["init"],{cwd:this.context.cwd})}}};Tm.paths=[["init"]],Tm.usage=Re.Usage({description:"create a new package",details:"\n This command will setup a new package in your local directory.\n\n If the `-p,--private` or `-w,--workspace` options are set, the package will be private by default.\n\n If the `-w,--workspace` option is set, the package will be configured to accept a set of workspaces in the `packages/` directory.\n\n If the `-i,--install` option is given a value, Yarn will first download it using `yarn set version` and only then forward the init call to the newly downloaded bundle. Without arguments, the downloaded bundle will be `latest`.\n\n The initial settings of the manifest can be changed by using the `initScope` and `initFields` configuration values. Additionally, Yarn will generate an EditorConfig file whose rules can be altered via `initEditorConfig`, and will initialize a Git repository in the current directory.\n ",examples:[["Create a new package in the local directory","yarn init"],["Create a new private package in the local directory","yarn init -p"],["Create a new package and store the Yarn release inside","yarn init -i=latest"],["Create a new private package and defines it as a workspace root","yarn init -w"]]});var pAe=Tm;var F4e={configuration:{initScope:{description:"Scope used when creating packages via the init command",type:Ie.STRING,default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:Ie.MAP,valueDefinition:{description:"",type:Ie.ANY}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:Ie.MAP,valueDefinition:{description:"",type:Ie.ANY}}},commands:[pAe]},N4e=F4e;var EL={};ft(EL,{default:()=>T4e});var BA="portal:",bA="link:";var pL=class{supports(e,t){return!!e.reference.startsWith(BA)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:BA});if(x.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:x.resolve(s,n)}async fetch(e,t){var c;let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:BA}),s=x.isAbsolute(n)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new _t(Me.root),prefixPath:x.relative(Me.root,s.localPath),localPath:Me.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=x.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new _t(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot,localPath:l}:{packageFs:new Ta(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot}}};var dL=class{supportsDescriptor(e,t){return!!e.range.startsWith(BA)}supportsLocator(e,t){return!!e.reference.startsWith(BA)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(BA.length);return[P.makeLocator(e,`${BA}${H.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.SOFT,conditions:n.getConditions(),dependencies:new Map([...n.dependencies]),peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var CL=class{supports(e,t){return!!e.reference.startsWith(bA)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:bA});if(x.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:x.resolve(s,n)}async fetch(e,t){var c;let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:bA}),s=x.isAbsolute(n)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new _t(Me.root),prefixPath:x.relative(Me.root,s.localPath),localPath:Me.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=x.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new _t(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot,discardFromLookup:!0,localPath:l}:{packageFs:new Ta(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot,discardFromLookup:!0}}};var mL=class{supportsDescriptor(e,t){return!!e.range.startsWith(bA)}supportsLocator(e,t){return!!e.reference.startsWith(bA)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(bA.length);return[P.makeLocator(e,`${bA}${H.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){return te(N({},e),{version:"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:Qt.SOFT,conditions:null,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map})}};var L4e={fetchers:[CL,pL],resolvers:[mL,dL]},T4e=L4e;var WL={};ft(WL,{default:()=>qze});var Un;(function(i){i[i.REGULAR=0]="REGULAR",i[i.WORKSPACE=1]="WORKSPACE",i[i.EXTERNAL_SOFT_LINK=2]="EXTERNAL_SOFT_LINK"})(Un||(Un={}));var QA;(function(i){i[i.YES=0]="YES",i[i.NO=1]="NO",i[i.DEPENDS=2]="DEPENDS"})(QA||(QA={}));var IL=(r,e)=>`${r}@${e}`,dAe=(r,e)=>{let t=e.indexOf("#"),i=t>=0?e.substring(t+1):e;return IL(r,i)},Bo;(function(s){s[s.NONE=-1]="NONE",s[s.PERF=0]="PERF",s[s.CHECK=1]="CHECK",s[s.REASONS=2]="REASONS",s[s.INTENSIVE_CHECK=9]="INTENSIVE_CHECK"})(Bo||(Bo={}));var mAe=(r,e={})=>{let t=e.debugLevel||Number(process.env.NM_DEBUG_LEVEL||-1),i=e.check||t>=9,n=e.hoistingLimits||new Map,s={check:i,debugLevel:t,hoistingLimits:n,fastLookupPossible:!0},o;s.debugLevel>=0&&(o=Date.now());let a=O4e(r,s),l=!1,c=0;do l=yL(a,[a],new Set([a.locator]),new Map,s).anotherRoundNeeded,s.fastLookupPossible=!1,c++;while(l);if(s.debugLevel>=0&&console.log(`hoist time: ${Date.now()-o}ms, rounds: ${c}`),s.debugLevel>=1){let u=Om(a);if(yL(a,[a],new Set([a.locator]),new Map,s).isGraphChanged)throw new Error(`The hoisting result is not terminal, prev tree: -${u}, next tree: -${Om(a)}`);let f=CAe(a);if(f)throw new Error(`${f}, after hoisting finished: -${Om(a)}`)}return s.debugLevel>=2&&console.log(Om(a)),M4e(a)},U4e=r=>{let e=r[r.length-1],t=new Map,i=new Set,n=s=>{if(!i.has(s)){i.add(s);for(let o of s.hoistedDependencies.values())t.set(o.name,o);for(let o of s.dependencies.values())s.peerNames.has(o.name)||n(o)}};return n(e),t},K4e=r=>{let e=r[r.length-1],t=new Map,i=new Set,n=new Set,s=(o,a)=>{if(i.has(o))return;i.add(o);for(let c of o.hoistedDependencies.values())if(!a.has(c.name)){let u;for(let g of r)u=g.dependencies.get(c.name),u&&t.set(u.name,u)}let l=new Set;for(let c of o.dependencies.values())l.add(c.name);for(let c of o.dependencies.values())o.peerNames.has(c.name)||s(c,l)};return s(e,n),t},EAe=(r,e)=>{if(e.decoupled)return e;let{name:t,references:i,ident:n,locator:s,dependencies:o,originalDependencies:a,hoistedDependencies:l,peerNames:c,reasons:u,isHoistBorder:g,hoistPriority:f,dependencyKind:h,hoistedFrom:p,hoistedTo:m}=e,y={name:t,references:new Set(i),ident:n,locator:s,dependencies:new Map(o),originalDependencies:new Map(a),hoistedDependencies:new Map(l),peerNames:new Set(c),reasons:new Map(u),decoupled:!0,isHoistBorder:g,hoistPriority:f,dependencyKind:h,hoistedFrom:new Map(p),hoistedTo:new Map(m)},b=y.dependencies.get(t);return b&&b.ident==y.ident&&y.dependencies.set(t,y),r.dependencies.set(y.name,y),y},H4e=(r,e)=>{let t=new Map([[r.name,[r.ident]]]);for(let n of r.dependencies.values())r.peerNames.has(n.name)||t.set(n.name,[n.ident]);let i=Array.from(e.keys());i.sort((n,s)=>{let o=e.get(n),a=e.get(s);return a.hoistPriority!==o.hoistPriority?a.hoistPriority-o.hoistPriority:a.peerDependents.size!==o.peerDependents.size?a.peerDependents.size-o.peerDependents.size:a.dependents.size-o.dependents.size});for(let n of i){let s=n.substring(0,n.indexOf("@",1)),o=n.substring(s.length+1);if(!r.peerNames.has(s)){let a=t.get(s);a||(a=[],t.set(s,a)),a.indexOf(o)<0&&a.push(o)}}return t},wL=r=>{let e=new Set,t=(i,n=new Set)=>{if(!n.has(i)){n.add(i);for(let s of i.peerNames)if(!r.peerNames.has(s)){let o=r.dependencies.get(s);o&&!e.has(o)&&t(o,n)}e.add(i)}};for(let i of r.dependencies.values())r.peerNames.has(i.name)||t(i);return e},yL=(r,e,t,i,n,s=new Set)=>{let o=e[e.length-1];if(s.has(o))return{anotherRoundNeeded:!1,isGraphChanged:!1};s.add(o);let a=G4e(o),l=H4e(o,a),c=r==o?new Map:n.fastLookupPossible?U4e(e):K4e(e),u,g=!1,f=!1,h=new Map(Array.from(l.entries()).map(([m,y])=>[m,y[0]])),p=new Map;do{let m=j4e(r,e,t,c,h,l,i,p,n);m.isGraphChanged&&(f=!0),m.anotherRoundNeeded&&(g=!0),u=!1;for(let[y,b]of l)b.length>1&&!o.dependencies.has(y)&&(h.delete(y),b.shift(),h.set(y,b[0]),u=!0)}while(u);for(let m of o.dependencies.values())if(!o.peerNames.has(m.name)&&!t.has(m.locator)){t.add(m.locator);let y=yL(r,[...e,m],t,p,n);y.isGraphChanged&&(f=!0),y.anotherRoundNeeded&&(g=!0),t.delete(m.locator)}return{anotherRoundNeeded:g,isGraphChanged:f}},Y4e=r=>{for(let[e,t]of r.dependencies)if(!r.peerNames.has(e)&&t.ident!==r.ident)return!0;return!1},q4e=(r,e,t,i,n,s,o,a,{outputReason:l,fastLookupPossible:c})=>{let u,g=null,f=new Set;l&&(u=`${Array.from(e).map(y=>Li(y)).join("\u2192")}`);let h=t[t.length-1],m=!(i.ident===h.ident);if(l&&!m&&(g="- self-reference"),m&&(m=i.dependencyKind!==1,l&&!m&&(g="- workspace")),m&&i.dependencyKind===2&&(m=!Y4e(i),l&&!m&&(g="- external soft link with unhoisted dependencies")),m&&(m=h.dependencyKind!==1||h.hoistedFrom.has(i.name)||e.size===1,l&&!m&&(g=h.reasons.get(i.name))),m&&(m=!r.peerNames.has(i.name),l&&!m&&(g=`- cannot shadow peer: ${Li(r.originalDependencies.get(i.name).locator)} at ${u}`)),m){let y=!1,b=n.get(i.name);if(y=!b||b.ident===i.ident,l&&!y&&(g=`- filled by: ${Li(b.locator)} at ${u}`),y)for(let v=t.length-1;v>=1;v--){let T=t[v].dependencies.get(i.name);if(T&&T.ident!==i.ident){y=!1;let Y=a.get(h);Y||(Y=new Set,a.set(h,Y)),Y.add(i.name),l&&(g=`- filled by ${Li(T.locator)} at ${t.slice(0,v).map(q=>Li(q.locator)).join("\u2192")}`);break}}m=y}if(m&&(m=s.get(i.name)===i.ident,l&&!m&&(g=`- filled by: ${Li(o.get(i.name)[0])} at ${u}`)),m){let y=!0,b=new Set(i.peerNames);for(let v=t.length-1;v>=1;v--){let k=t[v];for(let T of b){if(k.peerNames.has(T)&&k.originalDependencies.has(T))continue;let Y=k.dependencies.get(T);Y&&r.dependencies.get(T)!==Y&&(v===t.length-1?f.add(Y):(f=null,y=!1,l&&(g=`- peer dependency ${Li(Y.locator)} from parent ${Li(k.locator)} was not hoisted to ${u}`))),b.delete(T)}if(!y)break}m=y}if(m&&!c)for(let y of i.hoistedDependencies.values()){let b=n.get(y.name)||r.dependencies.get(y.name);if(!b||y.ident!==b.ident){m=!1,l&&(g=`- previously hoisted dependency mismatch, needed: ${Li(y.locator)}, available: ${Li(b==null?void 0:b.locator)}`);break}}return f!==null&&f.size>0?{isHoistable:2,dependsOn:f,reason:g}:{isHoistable:m?0:1,reason:g}},eb=r=>`${r.name}@${r.locator}`,j4e=(r,e,t,i,n,s,o,a,l)=>{let c=e[e.length-1],u=new Set,g=!1,f=!1,h=(b,v,k,T,Y)=>{if(u.has(T))return;let q=[...v,eb(T)],$=[...k,eb(T)],z=new Map,ne=new Map;for(let Z of wL(T)){let O=q4e(c,t,[c,...b,T],Z,i,n,s,a,{outputReason:l.debugLevel>=2,fastLookupPossible:l.fastLookupPossible});if(ne.set(Z,O),O.isHoistable===2)for(let L of O.dependsOn){let de=z.get(L.name)||new Set;de.add(Z.name),z.set(L.name,de)}}let ee=new Set,A=(Z,O,L)=>{if(!ee.has(Z)){ee.add(Z),ne.set(Z,{isHoistable:1,reason:L});for(let de of z.get(Z.name)||[])A(T.dependencies.get(de),O,l.debugLevel>=2?`- peer dependency ${Li(Z.locator)} from parent ${Li(T.locator)} was not hoisted`:"")}};for(let[Z,O]of ne)O.isHoistable===1&&A(Z,O,O.reason);let oe=!1;for(let Z of ne.keys())if(!ee.has(Z)){f=!0;let O=o.get(T);O&&O.has(Z.name)&&(g=!0),oe=!0,T.dependencies.delete(Z.name),T.hoistedDependencies.set(Z.name,Z),T.reasons.delete(Z.name);let L=c.dependencies.get(Z.name);if(l.debugLevel>=2){let de=Array.from(v).concat([T.locator]).map(Ge=>Li(Ge)).join("\u2192"),Be=c.hoistedFrom.get(Z.name);Be||(Be=[],c.hoistedFrom.set(Z.name,Be)),Be.push(de),T.hoistedTo.set(Z.name,Array.from(e).map(Ge=>Li(Ge.locator)).join("\u2192"))}if(!L)c.ident!==Z.ident&&(c.dependencies.set(Z.name,Z),Y.add(Z));else for(let de of Z.references)L.references.add(de)}if(T.dependencyKind===2&&oe&&(g=!0),l.check){let Z=CAe(r);if(Z)throw new Error(`${Z}, after hoisting dependencies of ${[c,...b,T].map(O=>Li(O.locator)).join("\u2192")}: -${Om(r)}`)}let ce=wL(T);for(let Z of ce)if(ee.has(Z)){let O=ne.get(Z);if((n.get(Z.name)===Z.ident||!T.reasons.has(Z.name))&&O.isHoistable!==0&&T.reasons.set(Z.name,O.reason),!Z.isHoistBorder&&$.indexOf(eb(Z))<0){u.add(T);let de=EAe(T,Z);h([...b,T],q,$,de,m),u.delete(T)}}},p,m=new Set(wL(c)),y=Array.from(e).map(b=>eb(b));do{p=m,m=new Set;for(let b of p){if(b.locator===c.locator||b.isHoistBorder)continue;let v=EAe(c,b);h([],Array.from(t),y,v,m)}}while(m.size>0);return{anotherRoundNeeded:g,isGraphChanged:f}},CAe=r=>{let e=[],t=new Set,i=new Set,n=(s,o,a)=>{if(t.has(s)||(t.add(s),i.has(s)))return;let l=new Map(o);for(let c of s.dependencies.values())s.peerNames.has(c.name)||l.set(c.name,c);for(let c of s.originalDependencies.values()){let u=l.get(c.name),g=()=>`${Array.from(i).concat([s]).map(f=>Li(f.locator)).join("\u2192")}`;if(s.peerNames.has(c.name)){let f=o.get(c.name);(f!==u||!f||f.ident!==c.ident)&&e.push(`${g()} - broken peer promise: expected ${c.ident} but found ${f&&f.ident}`)}else{let f=a.hoistedFrom.get(s.name),h=s.hoistedTo.get(c.name),p=`${f?` hoisted from ${f.join(", ")}`:""}`,m=`${h?` hoisted to ${h}`:""}`,y=`${g()}${p}`;u?u.ident!==c.ident&&e.push(`${y} - broken require promise for ${c.name}${m}: expected ${c.ident}, but found: ${u.ident}`):e.push(`${y} - broken require promise: no required dependency ${c.name}${m} found`)}}i.add(s);for(let c of s.dependencies.values())s.peerNames.has(c.name)||n(c,l,s);i.delete(s)};return n(r,r.dependencies,r),e.join(` -`)},O4e=(r,e)=>{let{identName:t,name:i,reference:n,peerNames:s}=r,o={name:i,references:new Set([n]),locator:IL(t,n),ident:dAe(t,n),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(s),reasons:new Map,decoupled:!0,isHoistBorder:!0,hoistPriority:0,dependencyKind:1,hoistedFrom:new Map,hoistedTo:new Map},a=new Map([[r,o]]),l=(c,u)=>{let g=a.get(c),f=!!g;if(!g){let{name:h,identName:p,reference:m,peerNames:y,hoistPriority:b,dependencyKind:v}=c,k=e.hoistingLimits.get(u.locator);g={name:h,references:new Set([m]),locator:IL(p,m),ident:dAe(p,m),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(y),reasons:new Map,decoupled:!0,isHoistBorder:k?k.has(h):!1,hoistPriority:b||0,dependencyKind:v||0,hoistedFrom:new Map,hoistedTo:new Map},a.set(c,g)}if(u.dependencies.set(c.name,g),u.originalDependencies.set(c.name,g),f){let h=new Set,p=m=>{if(!h.has(m)){h.add(m),m.decoupled=!1;for(let y of m.dependencies.values())m.peerNames.has(y.name)||p(y)}};p(g)}else for(let h of c.dependencies)l(h,g)};for(let c of r.dependencies)l(c,o);return o},BL=r=>r.substring(0,r.indexOf("@",1)),M4e=r=>{let e={name:r.name,identName:BL(r.locator),references:new Set(r.references),dependencies:new Set},t=new Set([r]),i=(n,s,o)=>{let a=t.has(n),l;if(s===n)l=o;else{let{name:c,references:u,locator:g}=n;l={name:c,identName:BL(g),references:u,dependencies:new Set}}if(o.dependencies.add(l),!a){t.add(n);for(let c of n.dependencies.values())n.peerNames.has(c.name)||i(c,n,l);t.delete(n)}};for(let n of r.dependencies.values())i(n,r,e);return e},G4e=r=>{let e=new Map,t=new Set([r]),i=o=>`${o.name}@${o.ident}`,n=o=>{let a=i(o),l=e.get(a);return l||(l={dependents:new Set,peerDependents:new Set,hoistPriority:0},e.set(a,l)),l},s=(o,a)=>{let l=!!t.has(a);if(n(a).dependents.add(o.ident),!l){t.add(a);for(let u of a.dependencies.values()){let g=n(u);g.hoistPriority=Math.max(g.hoistPriority,u.hoistPriority),a.peerNames.has(u.name)?g.peerDependents.add(a.ident):s(a,u)}}};for(let o of r.dependencies.values())r.peerNames.has(o.name)||s(r,o);return e},Li=r=>{if(!r)return"none";let e=r.indexOf("@",1),t=r.substring(0,e);t.endsWith("$wsroot$")&&(t=`wh:${t.replace("$wsroot$","")}`);let i=r.substring(e+1);if(i==="workspace:.")return".";if(i){let n=(i.indexOf("#")>0?i.split("#")[1]:i).replace("npm:","");return i.startsWith("virtual")&&(t=`v:${t}`),n.startsWith("workspace")&&(t=`w:${t}`,n=""),`${t}${n?`@${n}`:""}`}else return`${t}`},IAe=5e4,Om=r=>{let e=0,t=(n,s,o="")=>{if(e>IAe||s.has(n))return"";e++;let a=Array.from(n.dependencies.values()).sort((c,u)=>c.name===u.name?0:c.name>u.name?1:-1),l="";s.add(n);for(let c=0;c<a.length;c++){let u=a[c];if(!n.peerNames.has(u.name)&&u!==n){let g=n.reasons.get(u.name),f=BL(u.locator);l+=`${o}${c<a.length-1?"\u251C\u2500":"\u2514\u2500"}${(s.has(u)?">":"")+(f!==u.name?`a:${u.name}:`:"")+Li(u.locator)+(g?` ${g}`:"")} -`,l+=t(u,s,`${o}${c<a.length-1?"\u2502 ":" "}`)}}return s.delete(n),l};return t(r,new Set)+(e>IAe?` -Tree is too large, part of the tree has been dunped -`:"")};var bo;(function(t){t.HARD="HARD",t.SOFT="SOFT"})(bo||(bo={}));var Kn;(function(i){i.WORKSPACES="workspaces",i.DEPENDENCIES="dependencies",i.NONE="none"})(Kn||(Kn={}));var yAe="node_modules",vu="$wsroot$";var Mm=(r,e)=>{let{packageTree:t,hoistingLimits:i,errors:n,preserveSymlinksRequired:s}=J4e(r,e),o=null;if(n.length===0){let a=mAe(t,{hoistingLimits:i});o=W4e(r,a,e)}return{tree:o,errors:n,preserveSymlinksRequired:s}},Ca=r=>`${r.name}@${r.reference}`,bL=r=>{let e=new Map;for(let[t,i]of r.entries())if(!i.dirList){let n=e.get(i.locator);n||(n={target:i.target,linkType:i.linkType,locations:[],aliases:i.aliases},e.set(i.locator,n)),n.locations.push(t)}for(let t of e.values())t.locations=t.locations.sort((i,n)=>{let s=i.split(x.delimiter).length,o=n.split(x.delimiter).length;return n===i?0:s!==o?o-s:n>i?1:-1});return e},wAe=(r,e)=>{let t=P.isVirtualLocator(r)?P.devirtualizeLocator(r):r,i=P.isVirtualLocator(e)?P.devirtualizeLocator(e):e;return P.areLocatorsEqual(t,i)},QL=(r,e,t,i)=>{if(r.linkType!==bo.SOFT)return!1;let n=H.toPortablePath(t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(r.packageLocation):r.packageLocation);return x.contains(i,n)===null},z4e=r=>{let e=r.getPackageInformation(r.topLevel);if(e===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");if(r.findPackageLocator(e.packageLocation)===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let i=H.toPortablePath(e.packageLocation.slice(0,-1)),n=new Map,s={children:new Map},o=r.getDependencyTreeRoots(),a=new Map,l=new Set,c=(f,h)=>{let p=Ca(f);if(l.has(p))return;l.add(p);let m=r.getPackageInformation(f);if(m){let y=h?Ca(h):"";if(Ca(f)!==y&&m.linkType===bo.SOFT&&!QL(m,f,r,i)){let b=BAe(m,f,r);(!a.get(b)||f.reference.startsWith("workspace:"))&&a.set(b,f)}for(let[b,v]of m.packageDependencies)v!==null&&(m.packagePeers.has(b)||c(r.getLocator(b,v),f))}};for(let f of o)c(f,null);let u=i.split(x.sep);for(let f of a.values()){let h=r.getPackageInformation(f),m=H.toPortablePath(h.packageLocation.slice(0,-1)).split(x.sep).slice(u.length),y=s;for(let b of m){let v=y.children.get(b);v||(v={children:new Map},y.children.set(b,v)),y=v}y.workspaceLocator=f}let g=(f,h)=>{if(f.workspaceLocator){let p=Ca(h),m=n.get(p);m||(m=new Set,n.set(p,m)),m.add(f.workspaceLocator)}for(let p of f.children.values())g(p,f.workspaceLocator||h)};for(let f of s.children.values())g(f,s.workspaceLocator);return n},J4e=(r,e)=>{let t=[],i=!1,n=new Map,s=z4e(r),o=r.getPackageInformation(r.topLevel);if(o===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");let a=r.findPackageLocator(o.packageLocation);if(a===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let l=H.toPortablePath(o.packageLocation.slice(0,-1)),c={name:a.name,identName:a.name,reference:a.reference,peerNames:o.packagePeers,dependencies:new Set,dependencyKind:Un.WORKSPACE},u=new Map,g=(h,p)=>`${Ca(p)}:${h}`,f=(h,p,m,y,b,v,k,T)=>{var Z,O;let Y=g(h,m),q=u.get(Y),$=!!q;!$&&m.name===a.name&&m.reference===a.reference&&(q=c,u.set(Y,c));let z=QL(p,m,r,l);if(!q){let L=Un.REGULAR;z?L=Un.EXTERNAL_SOFT_LINK:p.linkType===bo.SOFT&&m.name.endsWith(vu)&&(L=Un.WORKSPACE),q={name:h,identName:m.name,reference:m.reference,dependencies:new Set,peerNames:L===Un.WORKSPACE?new Set:p.packagePeers,dependencyKind:L},u.set(Y,q)}let ne;if(z?ne=2:b.linkType===bo.SOFT?ne=1:ne=0,q.hoistPriority=Math.max(q.hoistPriority||0,ne),T&&!z){let L=Ca({name:y.identName,reference:y.reference}),de=n.get(L)||new Set;n.set(L,de),de.add(q.name)}let ee=new Map(p.packageDependencies);if(e.project){let L=e.project.workspacesByCwd.get(H.toPortablePath(p.packageLocation.slice(0,-1)));if(L){let de=new Set([...Array.from(L.manifest.peerDependencies.values(),Be=>P.stringifyIdent(Be)),...Array.from(L.manifest.peerDependenciesMeta.keys())]);for(let Be of de)ee.has(Be)||(ee.set(Be,v.get(Be)||null),q.peerNames.add(Be))}}let A=Ca({name:m.name.replace(vu,""),reference:m.reference}),oe=s.get(A);if(oe)for(let L of oe)ee.set(`${L.name}${vu}`,L.reference);(p!==b||p.linkType!==bo.SOFT||!z&&(!e.selfReferencesByCwd||e.selfReferencesByCwd.get(k)))&&y.dependencies.add(q);let ce=m!==a&&p.linkType===bo.SOFT&&!m.name.endsWith(vu)&&!z;if(!$&&!ce){let L=new Map;for(let[de,Be]of ee)if(Be!==null){let Ge=r.getLocator(de,Be),re=r.getLocator(de.replace(vu,""),Be),se=r.getPackageInformation(re);if(se===null)throw new Error("Assertion failed: Expected the package to have been registered");let be=QL(se,Ge,r,l);if(e.validateExternalSoftLinks&&e.project&&be){se.packageDependencies.size>0&&(i=!0);for(let[ve,pe]of se.packageDependencies)if(pe!==null){let V=P.parseLocator(Array.isArray(pe)?`${pe[0]}@${pe[1]}`:`${ve}@${pe}`);if(Ca(V)!==Ca(Ge)){let Qe=ee.get(ve);if(Qe){let le=P.parseLocator(Array.isArray(Qe)?`${Qe[0]}@${Qe[1]}`:`${ve}@${Qe}`);wAe(le,V)||t.push({messageName:X.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK,text:`Cannot link ${P.prettyIdent(e.project.configuration,P.parseIdent(Ge.name))} into ${P.prettyLocator(e.project.configuration,P.parseLocator(`${m.name}@${m.reference}`))} dependency ${P.prettyLocator(e.project.configuration,V)} conflicts with parent dependency ${P.prettyLocator(e.project.configuration,le)}`})}else{let le=L.get(ve);if(le){let fe=le.target,gt=P.parseLocator(Array.isArray(fe)?`${fe[0]}@${fe[1]}`:`${ve}@${fe}`);wAe(gt,V)||t.push({messageName:X.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK,text:`Cannot link ${P.prettyIdent(e.project.configuration,P.parseIdent(Ge.name))} into ${P.prettyLocator(e.project.configuration,P.parseLocator(`${m.name}@${m.reference}`))} dependency ${P.prettyLocator(e.project.configuration,V)} conflicts with dependency ${P.prettyLocator(e.project.configuration,gt)} from sibling portal ${P.prettyIdent(e.project.configuration,P.parseIdent(le.portal.name))}`})}else L.set(ve,{target:V.reference,portal:Ge})}}}}let he=(Z=e.hoistingLimitsByCwd)==null?void 0:Z.get(k),Fe=be?k:x.relative(l,H.toPortablePath(se.packageLocation))||Me.dot,Ue=(O=e.hoistingLimitsByCwd)==null?void 0:O.get(Fe),xe=he===Kn.DEPENDENCIES||Ue===Kn.DEPENDENCIES||Ue===Kn.WORKSPACES;f(de,se,Ge,q,p,ee,Fe,xe)}}};return f(a.name,o,a,c,o,o.packageDependencies,Me.dot,!1),{packageTree:c,hoistingLimits:n,errors:t,preserveSymlinksRequired:i}};function BAe(r,e,t){let i=t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(r.packageLocation):r.packageLocation;return H.toPortablePath(i||r.packageLocation)}function _4e(r,e,t){let i=e.getLocator(r.name.replace(vu,""),r.reference),n=e.getPackageInformation(i);if(n===null)throw new Error("Assertion failed: Expected the package to be registered");let s,o;return t.pnpifyFs?(o=H.toPortablePath(n.packageLocation),s=bo.SOFT):(o=BAe(n,r,e),s=n.linkType),{linkType:s,target:o}}var W4e=(r,e,t)=>{let i=new Map,n=(u,g,f)=>{let{linkType:h,target:p}=_4e(u,r,t);return{locator:Ca(u),nodePath:g,target:p,linkType:h,aliases:f}},s=u=>{let[g,f]=u.split("/");return f?{scope:Jr(g),name:Jr(f)}:{scope:null,name:Jr(g)}},o=new Set,a=(u,g,f)=>{if(!o.has(u)){o.add(u);for(let h of u.dependencies){if(h===u)continue;let p=Array.from(h.references).sort(),m={name:h.identName,reference:p[0]},{name:y,scope:b}=s(h.name),v=b?[b,y]:[y],k=x.join(g,yAe),T=x.join(k,...v),Y=`${f}/${m.name}`,q=n(m,f,p.slice(1)),$=!1;if(q.linkType===bo.SOFT&&t.project){let z=t.project.workspacesByCwd.get(q.target.slice(0,-1));$=!!(z&&!z.manifest.name)}if(!h.name.endsWith(vu)&&!$){let z=i.get(T);if(z){if(z.dirList)throw new Error(`Assertion failed: ${T} cannot merge dir node with leaf node`);{let oe=P.parseLocator(z.locator),ce=P.parseLocator(q.locator);if(z.linkType!==q.linkType)throw new Error(`Assertion failed: ${T} cannot merge nodes with different link types ${z.nodePath}/${P.stringifyLocator(oe)} and ${f}/${P.stringifyLocator(ce)}`);if(oe.identHash!==ce.identHash)throw new Error(`Assertion failed: ${T} cannot merge nodes with different idents ${z.nodePath}/${P.stringifyLocator(oe)} and ${f}/s${P.stringifyLocator(ce)}`);q.aliases=[...q.aliases,...z.aliases,P.parseLocator(z.locator).reference]}}i.set(T,q);let ne=T.split("/"),ee=ne.indexOf(yAe),A=ne.length-1;for(;ee>=0&&A>ee;){let oe=H.toPortablePath(ne.slice(0,A).join(x.sep)),ce=Jr(ne[A]),Z=i.get(oe);if(!Z)i.set(oe,{dirList:new Set([ce])});else if(Z.dirList){if(Z.dirList.has(ce))break;Z.dirList.add(ce)}A--}}a(h,q.linkType===bo.SOFT?q.target:T,Y)}}},l=n({name:e.name,reference:Array.from(e.references)[0]},"",[]),c=l.target;return i.set(c,l),a(e,c,""),i};var TL={};ft(TL,{PnpInstaller:()=>ah,PnpLinker:()=>xu,default:()=>Eze,getPnpPath:()=>Ol,jsInstallUtils:()=>ma,pnpUtils:()=>NL,quotePathIfNeeded:()=>WAe});var qAe=ge(ri()),JAe=ge(require("url"));var bAe;(function(t){t.HARD="HARD",t.SOFT="SOFT"})(bAe||(bAe={}));var er;(function(f){f.DEFAULT="DEFAULT",f.TOP_LEVEL="TOP_LEVEL",f.FALLBACK_EXCLUSION_LIST="FALLBACK_EXCLUSION_LIST",f.FALLBACK_EXCLUSION_ENTRIES="FALLBACK_EXCLUSION_ENTRIES",f.FALLBACK_EXCLUSION_DATA="FALLBACK_EXCLUSION_DATA",f.PACKAGE_REGISTRY_DATA="PACKAGE_REGISTRY_DATA",f.PACKAGE_REGISTRY_ENTRIES="PACKAGE_REGISTRY_ENTRIES",f.PACKAGE_STORE_DATA="PACKAGE_STORE_DATA",f.PACKAGE_STORE_ENTRIES="PACKAGE_STORE_ENTRIES",f.PACKAGE_INFORMATION_DATA="PACKAGE_INFORMATION_DATA",f.PACKAGE_DEPENDENCIES="PACKAGE_DEPENDENCIES",f.PACKAGE_DEPENDENCY="PACKAGE_DEPENDENCY"})(er||(er={}));var QAe={[er.DEFAULT]:{collapsed:!1,next:{["*"]:er.DEFAULT}},[er.TOP_LEVEL]:{collapsed:!1,next:{fallbackExclusionList:er.FALLBACK_EXCLUSION_LIST,packageRegistryData:er.PACKAGE_REGISTRY_DATA,["*"]:er.DEFAULT}},[er.FALLBACK_EXCLUSION_LIST]:{collapsed:!1,next:{["*"]:er.FALLBACK_EXCLUSION_ENTRIES}},[er.FALLBACK_EXCLUSION_ENTRIES]:{collapsed:!0,next:{["*"]:er.FALLBACK_EXCLUSION_DATA}},[er.FALLBACK_EXCLUSION_DATA]:{collapsed:!0,next:{["*"]:er.DEFAULT}},[er.PACKAGE_REGISTRY_DATA]:{collapsed:!1,next:{["*"]:er.PACKAGE_REGISTRY_ENTRIES}},[er.PACKAGE_REGISTRY_ENTRIES]:{collapsed:!0,next:{["*"]:er.PACKAGE_STORE_DATA}},[er.PACKAGE_STORE_DATA]:{collapsed:!1,next:{["*"]:er.PACKAGE_STORE_ENTRIES}},[er.PACKAGE_STORE_ENTRIES]:{collapsed:!0,next:{["*"]:er.PACKAGE_INFORMATION_DATA}},[er.PACKAGE_INFORMATION_DATA]:{collapsed:!1,next:{packageDependencies:er.PACKAGE_DEPENDENCIES,["*"]:er.DEFAULT}},[er.PACKAGE_DEPENDENCIES]:{collapsed:!1,next:{["*"]:er.PACKAGE_DEPENDENCY}},[er.PACKAGE_DEPENDENCY]:{collapsed:!0,next:{["*"]:er.DEFAULT}}};function V4e(r,e,t){let i="";i+="[";for(let n=0,s=r.length;n<s;++n)i+=tb(String(n),r[n],e,t).replace(/^ +/g,""),n+1<s&&(i+=", ");return i+="]",i}function X4e(r,e,t){let i=`${t} `,n="";n+=t,n+=`[ -`;for(let s=0,o=r.length;s<o;++s)n+=i+tb(String(s),r[s],e,i).replace(/^ +/,""),s+1<o&&(n+=","),n+=` -`;return n+=t,n+="]",n}function Z4e(r,e,t){let i=Object.keys(r),n="";n+="{";for(let s=0,o=i.length,a=0;s<o;++s){let l=i[s],c=r[l];typeof c!="undefined"&&(a!==0&&(n+=", "),n+=JSON.stringify(l),n+=": ",n+=tb(l,c,e,t).replace(/^ +/g,""),a+=1)}return n+="}",n}function $4e(r,e,t){let i=Object.keys(r),n=`${t} `,s="";s+=t,s+=`{ -`;let o=0;for(let a=0,l=i.length;a<l;++a){let c=i[a],u=r[c];typeof u!="undefined"&&(o!==0&&(s+=",",s+=` -`),s+=n,s+=JSON.stringify(c),s+=": ",s+=tb(c,u,e,n).replace(/^ +/g,""),o+=1)}return o!==0&&(s+=` -`),s+=t,s+="}",s}function tb(r,e,t,i){let{next:n}=QAe[t],s=n[r]||n["*"];return SAe(e,s,i)}function SAe(r,e,t){let{collapsed:i}=QAe[e];return Array.isArray(r)?i?V4e(r,e,t):X4e(r,e,t):typeof r=="object"&&r!==null?i?Z4e(r,e,t):$4e(r,e,t):JSON.stringify(r)}function vAe(r){return SAe(r,er.TOP_LEVEL,"")}function Um(r,e){let t=Array.from(r);Array.isArray(e)||(e=[e]);let i=[];for(let s of e)i.push(t.map(o=>s(o)));let n=t.map((s,o)=>o);return n.sort((s,o)=>{for(let a of i){let l=a[s]<a[o]?-1:a[s]>a[o]?1:0;if(l!==0)return l}return 0}),n.map(s=>t[s])}function eze(r){let e=new Map,t=Um(r.fallbackExclusionList||[],[({name:i,reference:n})=>i,({name:i,reference:n})=>n]);for(let{name:i,reference:n}of t){let s=e.get(i);typeof s=="undefined"&&e.set(i,s=new Set),s.add(n)}return Array.from(e).map(([i,n])=>[i,Array.from(n)])}function tze(r){return Um(r.fallbackPool||[],([e])=>e)}function rze(r){let e=[];for(let[t,i]of Um(r.packageRegistry,([n])=>n===null?"0":`1${n}`)){let n=[];e.push([t,n]);for(let[s,{packageLocation:o,packageDependencies:a,packagePeers:l,linkType:c,discardFromLookup:u}]of Um(i,([g])=>g===null?"0":`1${g}`)){let g=[];t!==null&&s!==null&&!a.has(t)&&g.push([t,s]);for(let[p,m]of Um(a.entries(),([y])=>y))g.push([p,m]);let f=l&&l.size>0?Array.from(l):void 0,h=u||void 0;n.push([s,{packageLocation:o,packageDependencies:g,packagePeers:f,linkType:c,discardFromLookup:h}])}}return e}function Km(r){return{__info:["This file is automatically generated. Do not touch it, or risk","your modifications being lost. We also recommend you not to read","it either without using the @yarnpkg/pnp package, as the data layout","is entirely unspecified and WILL change from a version to another."],dependencyTreeRoots:r.dependencyTreeRoots,enableTopLevelFallback:r.enableTopLevelFallback||!1,ignorePatternData:r.ignorePattern||null,fallbackExclusionList:eze(r),fallbackPool:tze(r),packageRegistryData:rze(r)}}var PAe=ge(xAe());function DAe(r,e){return[r?`${r} -`:"",`/* eslint-disable */ - -`,`try { -`,` Object.freeze({}).detectStrictMode = true; -`,`} catch (error) { -`," throw new Error(`The whole PnP file got strict-mode-ified, which is known to break (Emscripten libraries aren't strict mode). This usually happens when the file goes through Babel.`);\n",`} -`,` -`,`function $$SETUP_STATE(hydrateRuntimeState, basePath) { -`,e.replace(/^/gm," "),`} -`,` -`,(0,PAe.default)()].join("")}function ize(r){return JSON.stringify(r,null,2)}function nze(r){return`'${r.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,`\\ -`)}'`}function sze(r){return[`return hydrateRuntimeState(JSON.parse(${nze(vAe(r))}), {basePath: basePath || __dirname}); -`].join("")}function oze(r){return[`var path = require('path'); -`,`var dataLocation = path.resolve(__dirname, ${JSON.stringify(r)}); -`,`return hydrateRuntimeState(require(dataLocation), {basePath: basePath || path.dirname(dataLocation)}); -`].join("")}function RAe(r){let e=Km(r),t=sze(e);return DAe(r.shebang,t)}function FAe(r){let e=Km(r),t=oze(r.dataLocation),i=DAe(r.shebang,t);return{dataFile:ize(e),loaderFile:i}}var TAe=ge(require("fs")),gze=ge(require("path")),OAe=ge(require("util"));function vL(r,{basePath:e}){let t=H.toPortablePath(e),i=x.resolve(t),n=r.ignorePatternData!==null?new RegExp(r.ignorePatternData):null,s=new Map,o=new Map(r.packageRegistryData.map(([g,f])=>[g,new Map(f.map(([h,p])=>{var k;if(g===null!=(h===null))throw new Error("Assertion failed: The name and reference should be null, or neither should");let m=(k=p.discardFromLookup)!=null?k:!1,y={name:g,reference:h},b=s.get(p.packageLocation);b?(b.discardFromLookup=b.discardFromLookup&&m,m||(b.locator=y)):s.set(p.packageLocation,{locator:y,discardFromLookup:m});let v=null;return[h,{packageDependencies:new Map(p.packageDependencies),packagePeers:new Set(p.packagePeers),linkType:p.linkType,discardFromLookup:m,get packageLocation(){return v||(v=x.join(i,p.packageLocation))}}]}))])),a=new Map(r.fallbackExclusionList.map(([g,f])=>[g,new Set(f)])),l=new Map(r.fallbackPool),c=r.dependencyTreeRoots,u=r.enableTopLevelFallback;return{basePath:t,dependencyTreeRoots:c,enableTopLevelFallback:u,fallbackExclusionList:a,fallbackPool:l,ignorePattern:n,packageLocatorsByLocations:s,packageRegistry:o}}var Hm=ge(require("module"));function oh(r,e){if(typeof r=="string")return r;if(r){let t,i;if(Array.isArray(r)){for(t=0;t<r.length;t++)if(i=oh(r[t],e))return i}else for(t in r)if(e.has(t))return oh(r[t],e)}}function ku(r,e,t){throw new Error(t?`No known conditions for "${e}" entry in "${r}" package`:`Missing "${e}" export in "${r}" package`)}function aze(r,e){return e===r?".":e[0]==="."?e:e.replace(new RegExp("^"+r+"/"),"./")}function NAe(r,e=".",t={}){let{name:i,exports:n}=r;if(n){let{browser:s,require:o,unsafe:a,conditions:l=[]}=t,c=aze(i,e);if(c[0]!=="."&&(c="./"+c),typeof n=="string")return c==="."?n:ku(i,c);let u=new Set(["default",...l]);a||u.add(o?"require":"import"),a||u.add(s?"browser":"node");let g,f,h=!1;for(g in n){h=g[0]!==".";break}if(h)return c==="."?oh(n,u)||ku(i,c,1):ku(i,c);if(f=n[c])return oh(f,u)||ku(i,c,1);for(g in n){if(f=g[g.length-1],f==="/"&&c.startsWith(g))return(f=oh(n[g],u))?f+c.substring(g.length):ku(i,c,1);if(f==="*"&&c.startsWith(g.slice(0,-1))&&c.substring(g.length-1).length>0)return(f=oh(n[g],u))?f.replace("*",c.substring(g.length-1)):ku(i,c,1)}return ku(i,c)}}var kL=ge(require("util"));var ur;(function(c){c.API_ERROR="API_ERROR",c.BUILTIN_NODE_RESOLUTION_FAILED="BUILTIN_NODE_RESOLUTION_FAILED",c.EXPORTS_RESOLUTION_FAILED="EXPORTS_RESOLUTION_FAILED",c.MISSING_DEPENDENCY="MISSING_DEPENDENCY",c.MISSING_PEER_DEPENDENCY="MISSING_PEER_DEPENDENCY",c.QUALIFIED_PATH_RESOLUTION_FAILED="QUALIFIED_PATH_RESOLUTION_FAILED",c.INTERNAL="INTERNAL",c.UNDECLARED_DEPENDENCY="UNDECLARED_DEPENDENCY",c.UNSUPPORTED="UNSUPPORTED"})(ur||(ur={}));var Aze=new Set([ur.BUILTIN_NODE_RESOLUTION_FAILED,ur.MISSING_DEPENDENCY,ur.MISSING_PEER_DEPENDENCY,ur.QUALIFIED_PATH_RESOLUTION_FAILED,ur.UNDECLARED_DEPENDENCY]);function ai(r,e,t={},i){i!=null||(i=Aze.has(r)?"MODULE_NOT_FOUND":r);let n={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(e),{code:te(N({},n),{value:i}),pnpCode:te(N({},n),{value:r}),data:te(N({},n),{value:t})})}function Qo(r){return H.normalize(H.fromPortablePath(r))}var lze=ge(require("fs")),LAe=ge(require("module")),cze=ge(require("path")),uze=new Set(LAe.Module.builtinModules||Object.keys(process.binding("natives"))),rb=r=>r.startsWith("node:")||uze.has(r);function xL(r,e){let t=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,i=Number(process.env.PNP_DEBUG_LEVEL),n=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/,s=/^(\/|\.{1,2}(\/|$))/,o=/\/$/,a=/^\.{0,2}\//,l={name:null,reference:null},c=[],u=new Set;if(r.enableTopLevelFallback===!0&&c.push(l),e.compatibilityMode!==!1)for(let re of["react-scripts","gatsby"]){let se=r.packageRegistry.get(re);if(se)for(let be of se.keys()){if(be===null)throw new Error("Assertion failed: This reference shouldn't be null");c.push({name:re,reference:be})}}let{ignorePattern:g,packageRegistry:f,packageLocatorsByLocations:h}=r;function p(re,se){return{fn:re,args:se,error:null,result:null}}function m(re){var Ue,xe,ve,pe,V,Qe;let se=(ve=(xe=(Ue=process.stderr)==null?void 0:Ue.hasColors)==null?void 0:xe.call(Ue))!=null?ve:process.stdout.isTTY,be=(le,fe)=>`[${le}m${fe}`,he=re.error;console.error(he?be("31;1",`\u2716 ${(pe=re.error)==null?void 0:pe.message.replace(/\n.*/s,"")}`):be("33;1","\u203C Resolution")),re.args.length>0&&console.error();for(let le of re.args)console.error(` ${be("37;1","In \u2190")} ${(0,kL.inspect)(le,{colors:se,compact:!0})}`);re.result&&(console.error(),console.error(` ${be("37;1","Out \u2192")} ${(0,kL.inspect)(re.result,{colors:se,compact:!0})}`));let Fe=(Qe=(V=new Error().stack.match(/(?<=^ +)at.*/gm))==null?void 0:V.slice(2))!=null?Qe:[];if(Fe.length>0){console.error();for(let le of Fe)console.error(` ${be("38;5;244",le)}`)}console.error()}function y(re,se){if(e.allowDebug===!1)return se;if(Number.isFinite(i)){if(i>=2)return(...be)=>{let he=p(re,be);try{return he.result=se(...be)}catch(Fe){throw he.error=Fe}finally{m(he)}};if(i>=1)return(...be)=>{try{return se(...be)}catch(he){let Fe=p(re,be);throw Fe.error=he,m(Fe),he}}}return se}function b(re){let se=A(re);if(!se)throw ai(ur.INTERNAL,"Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)");return se}function v(re){if(re.name===null)return!0;for(let se of r.dependencyTreeRoots)if(se.name===re.name&&se.reference===re.reference)return!0;return!1}let k=new Set(["default","node","require"]);function T(re,se=k){let be=Z(x.join(re,"internal.js"),{resolveIgnored:!0,includeDiscardFromLookup:!0});if(be===null)throw ai(ur.INTERNAL,`The locator that owns the "${re}" path can't be found inside the dependency tree (this is probably an internal error)`);let{packageLocation:he}=b(be),Fe=x.join(he,xt.manifest);if(!e.fakeFs.existsSync(Fe))return null;let Ue=JSON.parse(e.fakeFs.readFileSync(Fe,"utf8")),xe=x.contains(he,re);if(xe===null)throw ai(ur.INTERNAL,"unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)");a.test(xe)||(xe=`./${xe}`);let ve;try{ve=NAe(Ue,x.normalize(xe),{conditions:se,unsafe:!0})}catch(pe){throw ai(ur.EXPORTS_RESOLUTION_FAILED,pe.message,{unqualifiedPath:Qo(re),locator:be,pkgJson:Ue,subpath:Qo(xe),conditions:se},"ERR_PACKAGE_PATH_NOT_EXPORTED")}return typeof ve=="string"?x.join(he,ve):null}function Y(re,se,{extensions:be}){let he;try{se.push(re),he=e.fakeFs.statSync(re)}catch(Fe){}if(he&&!he.isDirectory())return e.fakeFs.realpathSync(re);if(he&&he.isDirectory()){let Fe;try{Fe=JSON.parse(e.fakeFs.readFileSync(x.join(re,xt.manifest),"utf8"))}catch(xe){}let Ue;if(Fe&&Fe.main&&(Ue=x.resolve(re,Fe.main)),Ue&&Ue!==re){let xe=Y(Ue,se,{extensions:be});if(xe!==null)return xe}}for(let Fe=0,Ue=be.length;Fe<Ue;Fe++){let xe=`${re}${be[Fe]}`;if(se.push(xe),e.fakeFs.existsSync(xe))return xe}if(he&&he.isDirectory())for(let Fe=0,Ue=be.length;Fe<Ue;Fe++){let xe=x.format({dir:re,name:"index",ext:be[Fe]});if(se.push(xe),e.fakeFs.existsSync(xe))return xe}return null}function q(re){let se=new Hm.Module(re,null);return se.filename=re,se.paths=Hm.Module._nodeModulePaths(re),se}function $(re,se){return se.endsWith("/")&&(se=x.join(se,"internal.js")),Hm.Module._resolveFilename(H.fromPortablePath(re),q(H.fromPortablePath(se)),!1,{plugnplay:!1})}function z(re){if(g===null)return!1;let se=x.contains(r.basePath,re);return se===null?!1:!!g.test(se.replace(/\/$/,""))}let ne={std:3,resolveVirtual:1,getAllLocators:1},ee=l;function A({name:re,reference:se}){let be=f.get(re);if(!be)return null;let he=be.get(se);return he||null}function oe({name:re,reference:se}){let be=[];for(let[he,Fe]of f)if(he!==null)for(let[Ue,xe]of Fe)Ue===null||xe.packageDependencies.get(re)!==se||he===re&&Ue===se||be.push({name:he,reference:Ue});return be}function ce(re,se){let be=new Map,he=new Set,Fe=xe=>{let ve=JSON.stringify(xe.name);if(he.has(ve))return;he.add(ve);let pe=oe(xe);for(let V of pe)if(b(V).packagePeers.has(re))Fe(V);else{let le=be.get(V.name);typeof le=="undefined"&&be.set(V.name,le=new Set),le.add(V.reference)}};Fe(se);let Ue=[];for(let xe of[...be.keys()].sort())for(let ve of[...be.get(xe)].sort())Ue.push({name:xe,reference:ve});return Ue}function Z(re,{resolveIgnored:se=!1,includeDiscardFromLookup:be=!1}={}){if(z(re)&&!se)return null;let he=x.relative(r.basePath,re);he.match(s)||(he=`./${he}`),he.endsWith("/")||(he=`${he}/`);do{let Fe=h.get(he);if(typeof Fe=="undefined"||Fe.discardFromLookup&&!be){he=he.substring(0,he.lastIndexOf("/",he.length-2)+1);continue}return Fe.locator}while(he!=="");return null}function O(re,se,{considerBuiltins:be=!0}={}){if(re==="pnpapi")return H.toPortablePath(e.pnpapiResolution);if(be&&rb(re))return null;let he=Qo(re),Fe=se&&Qo(se);if(se&&z(se)&&(!x.isAbsolute(re)||Z(re)===null)){let ve=$(re,se);if(ve===!1)throw ai(ur.BUILTIN_NODE_RESOLUTION_FAILED,`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) - -Require request: "${he}" -Required by: ${Fe} -`,{request:he,issuer:Fe});return H.toPortablePath(ve)}let Ue,xe=re.match(n);if(xe){if(!se)throw ai(ur.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:he,issuer:Fe});let[,ve,pe]=xe,V=Z(se);if(!V){let jt=$(re,se);if(jt===!1)throw ai(ur.BUILTIN_NODE_RESOLUTION_FAILED,`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). - -Require path: "${he}" -Required by: ${Fe} -`,{request:he,issuer:Fe});return H.toPortablePath(jt)}let le=b(V).packageDependencies.get(ve),fe=null;if(le==null&&V.name!==null){let jt=r.fallbackExclusionList.get(V.name);if(!jt||!jt.has(V.reference)){for(let Oi=0,$s=c.length;Oi<$s;++Oi){let jn=b(c[Oi]).packageDependencies.get(ve);if(jn!=null){t?fe=jn:le=jn;break}}if(r.enableTopLevelFallback&&le==null&&fe===null){let Oi=r.fallbackPool.get(ve);Oi!=null&&(fe=Oi)}}}let gt=null;if(le===null)if(v(V))gt=ai(ur.MISSING_PEER_DEPENDENCY,`Your application tried to access ${ve} (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,dependencyName:ve});else{let jt=ce(ve,V);jt.every(Qr=>v(Qr))?gt=ai(ur.MISSING_PEER_DEPENDENCY,`${V.name} tried to access ${ve} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) -${jt.map(Qr=>`Ancestor breaking the chain: ${Qr.name}@${Qr.reference} -`).join("")} -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve,brokenAncestors:jt}):gt=ai(ur.MISSING_PEER_DEPENDENCY,`${V.name} tried to access ${ve} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) - -${jt.map(Qr=>`Ancestor breaking the chain: ${Qr.name}@${Qr.reference} -`).join("")} -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve,brokenAncestors:jt})}else le===void 0&&(!be&&rb(re)?v(V)?gt=ai(ur.UNDECLARED_DEPENDENCY,`Your application tried to access ${ve}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${ve} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,dependencyName:ve}):gt=ai(ur.UNDECLARED_DEPENDENCY,`${V.name} tried to access ${ve}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${ve} isn't otherwise declared in ${V.name}'s dependencies, this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve}):v(V)?gt=ai(ur.UNDECLARED_DEPENDENCY,`Your application tried to access ${ve}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,dependencyName:ve}):gt=ai(ur.UNDECLARED_DEPENDENCY,`${V.name} tried to access ${ve}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve}));if(le==null){if(fe===null||gt===null)throw gt||new Error("Assertion failed: Expected an error to have been set");le=fe;let jt=gt.message.replace(/\n.*/g,"");gt.message=jt,!u.has(jt)&&i!==0&&(u.add(jt),process.emitWarning(gt))}let Ht=Array.isArray(le)?{name:le[0],reference:le[1]}:{name:ve,reference:le},Mt=b(Ht);if(!Mt.packageLocation)throw ai(ur.MISSING_DEPENDENCY,`A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. - -Required package: ${Ht.name}@${Ht.reference}${Ht.name!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) -`,{request:he,issuer:Fe,dependencyLocator:Object.assign({},Ht)});let Ei=Mt.packageLocation;pe?Ue=x.join(Ei,pe):Ue=Ei}else if(x.isAbsolute(re))Ue=x.normalize(re);else{if(!se)throw ai(ur.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:he,issuer:Fe});let ve=x.resolve(se);se.match(o)?Ue=x.normalize(x.join(ve,re)):Ue=x.normalize(x.join(x.dirname(ve),re))}return x.normalize(Ue)}function L(re,se,be=k){if(s.test(re))return se;let he=T(se,be);return he?x.normalize(he):se}function de(re,{extensions:se=Object.keys(Hm.Module._extensions)}={}){var Fe,Ue;let be=[],he=Y(re,be,{extensions:se});if(he)return x.normalize(he);{let xe=Qo(re),ve=Z(re);if(ve){let{packageLocation:pe}=b(ve),V=!0;try{e.fakeFs.accessSync(pe)}catch(Qe){if((Qe==null?void 0:Qe.code)==="ENOENT")V=!1;else{let le=((Ue=(Fe=Qe==null?void 0:Qe.message)!=null?Fe:Qe)!=null?Ue:"empty exception thrown").replace(/^[A-Z]/,fe=>fe.toLowerCase());throw ai(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`Required package exists but could not be accessed (${le}). - -Missing package: ${ve.name}@${ve.reference} -Expected package location: ${Qo(pe)} -`,{unqualifiedPath:xe,extensions:se})}}if(!V){let Qe=pe.includes("/unplugged/")?"Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).":"Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.";throw ai(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`${Qe} - -Missing package: ${ve.name}@${ve.reference} -Expected package location: ${Qo(pe)} -`,{unqualifiedPath:xe,extensions:se})}}throw ai(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`Qualified path resolution failed: we looked for the following paths, but none could be accessed. - -Source path: ${xe} -${be.map(pe=>`Not found: ${Qo(pe)} -`).join("")}`,{unqualifiedPath:xe,extensions:se})}}function Be(re,se,{considerBuiltins:be,extensions:he,conditions:Fe}={}){try{let Ue=O(re,se,{considerBuiltins:be});if(re==="pnpapi")return Ue;if(Ue===null)return null;let xe=()=>se!==null?z(se):!1,ve=(!be||!rb(re))&&!xe()?L(re,Ue,Fe):Ue;return de(ve,{extensions:he})}catch(Ue){throw Object.prototype.hasOwnProperty.call(Ue,"pnpCode")&&Object.assign(Ue.data,{request:Qo(re),issuer:se&&Qo(se)}),Ue}}function Ge(re){let se=x.normalize(re),be=Wr.resolveVirtual(se);return be!==se?be:null}return{VERSIONS:ne,topLevel:ee,getLocator:(re,se)=>Array.isArray(se)?{name:se[0],reference:se[1]}:{name:re,reference:se},getDependencyTreeRoots:()=>[...r.dependencyTreeRoots],getAllLocators(){let re=[];for(let[se,be]of f)for(let he of be.keys())se!==null&&he!==null&&re.push({name:se,reference:he});return re},getPackageInformation:re=>{let se=A(re);if(se===null)return null;let be=H.fromPortablePath(se.packageLocation);return te(N({},se),{packageLocation:be})},findPackageLocator:re=>Z(H.toPortablePath(re)),resolveToUnqualified:y("resolveToUnqualified",(re,se,be)=>{let he=se!==null?H.toPortablePath(se):null,Fe=O(H.toPortablePath(re),he,be);return Fe===null?null:H.fromPortablePath(Fe)}),resolveUnqualified:y("resolveUnqualified",(re,se)=>H.fromPortablePath(de(H.toPortablePath(re),se))),resolveRequest:y("resolveRequest",(re,se,be)=>{let he=se!==null?H.toPortablePath(se):null,Fe=Be(H.toPortablePath(re),he,be);return Fe===null?null:H.fromPortablePath(Fe)}),resolveVirtual:y("resolveVirtual",re=>{let se=Ge(H.toPortablePath(re));return se!==null?H.fromPortablePath(se):null})}}var U0t=(0,OAe.promisify)(TAe.readFile);var MAe=(r,e,t)=>{let i=Km(r),n=vL(i,{basePath:e}),s=H.join(e,xt.pnpCjs);return xL(n,{fakeFs:t,pnpapiResolution:s})};var DL=ge(KAe());var ma={};ft(ma,{checkAndReportManifestCompatibility:()=>jAe,checkManifestCompatibility:()=>HAe,extractBuildScripts:()=>ib,getExtractHint:()=>RL,hasBindingGyp:()=>FL});function HAe(r){return P.isPackageCompatible(r,Xg.getArchitectureSet())}function jAe(r,e,{configuration:t,report:i}){return HAe(r)?!0:(i==null||i.reportWarningOnce(X.INCOMPATIBLE_ARCHITECTURE,`${P.prettyLocator(t,r)} The ${Xg.getArchitectureName()} architecture is incompatible with this package, ${e} skipped.`),!1)}function ib(r,e,t,{configuration:i,report:n}){let s=[];for(let a of["preinstall","install","postinstall"])e.manifest.scripts.has(a)&&s.push([cs.SCRIPT,a]);return!e.manifest.scripts.has("install")&&e.misc.hasBindingGyp&&s.push([cs.SHELLCODE,"node-gyp rebuild"]),s.length===0?[]:r.linkType!==Qt.HARD?(n==null||n.reportWarningOnce(X.SOFT_LINK_BUILD,`${P.prettyLocator(i,r)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`),[]):t&&t.built===!1?(n==null||n.reportInfoOnce(X.BUILD_DISABLED,`${P.prettyLocator(i,r)} lists build scripts, but its build has been explicitly disabled through configuration.`),[]):!i.get("enableScripts")&&!t.built?(n==null||n.reportWarningOnce(X.DISABLED_BUILD_SCRIPTS,`${P.prettyLocator(i,r)} lists build scripts, but all build scripts have been disabled.`),[]):jAe(r,"build",{configuration:i,report:n})?s:[]}var fze=new Set([".exe",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function RL(r){return r.packageFs.getExtractHint({relevantExtensions:fze})}function FL(r){let e=x.join(r.prefixPath,"binding.gyp");return r.packageFs.existsSync(e)}var NL={};ft(NL,{getUnpluggedPath:()=>jm});function jm(r,{configuration:e}){return x.resolve(e.get("pnpUnpluggedFolder"),P.slugifyLocator(r))}var hze=new Set([P.makeIdent(null,"nan").identHash,P.makeIdent(null,"node-gyp").identHash,P.makeIdent(null,"node-pre-gyp").identHash,P.makeIdent(null,"node-addon-api").identHash,P.makeIdent(null,"fsevents").identHash,P.makeIdent(null,"open").identHash,P.makeIdent(null,"opn").identHash]),xu=class{constructor(){this.mode="strict";this.pnpCache=new Map}supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the PnP linker to be enabled");let i=Ol(t.project).cjs;if(!U.existsSync(i))throw new Pe(`The project in ${ae.pretty(t.project.configuration,`${t.project.cwd}/package.json`,ae.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=Se.getFactoryWithDefault(this.pnpCache,i,()=>Se.dynamicRequire(i,{cachingStrategy:Se.CachingStrategy.FsTime})),s={name:P.stringifyIdent(e),reference:e.reference},o=n.getPackageInformation(s);if(!o)throw new Pe(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed PnP map - running an install might help`);return H.toPortablePath(o.packageLocation)}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=Ol(t.project).cjs;if(!U.existsSync(i))return null;let s=Se.getFactoryWithDefault(this.pnpCache,i,()=>Se.dynamicRequire(i,{cachingStrategy:Se.CachingStrategy.FsTime})).findPackageLocator(H.fromPortablePath(e));return s?P.makeLocator(P.parseIdent(s.name),s.reference):null}makeInstaller(e){return new ah(e)}isEnabled(e){return!(e.project.configuration.get("nodeLinker")!=="pnp"||e.project.configuration.get("pnpMode")!==this.mode)}},ah=class{constructor(e){this.opts=e;this.mode="strict";this.asyncActions=new Se.AsyncActions(10);this.packageRegistry=new Map;this.virtualTemplates=new Map;this.isESMLoaderRequired=!1;this.customData={store:new Map};this.unpluggedPaths=new Set;this.opts=e}getCustomDataKey(){return JSON.stringify({name:"PnpInstaller",version:2})}attachCustomData(e){this.customData=e}async installPackage(e,t,i){let n=P.stringifyIdent(e),s=e.reference,o=!!this.opts.project.tryWorkspaceByLocator(e),a=P.isVirtualLocator(e),l=e.peerDependencies.size>0&&!a,c=!l&&!o,u=!l&&e.linkType!==Qt.SOFT,g,f;if(c||u){let k=a?P.devirtualizeLocator(e):e;g=this.customData.store.get(k.locatorHash),typeof g=="undefined"&&(g=await pze(t),e.linkType===Qt.HARD&&this.customData.store.set(k.locatorHash,g)),g.manifest.type==="module"&&(this.isESMLoaderRequired=!0),f=this.opts.project.getDependencyMeta(k,e.version)}let h=c?ib(e,g,f,{configuration:this.opts.project.configuration,report:this.opts.report}):[],p=u?await this.unplugPackageIfNeeded(e,g,t,f,i):t.packageFs;if(x.isAbsolute(t.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${t.prefixPath}) to be relative to the parent`);let m=x.resolve(p.getRealPath(),t.prefixPath),y=LL(this.opts.project.cwd,m),b=new Map,v=new Set;if(a){for(let k of e.peerDependencies.values())b.set(P.stringifyIdent(k),null),v.add(P.stringifyIdent(k));if(!o){let k=P.devirtualizeLocator(e);this.virtualTemplates.set(k.locatorHash,{location:LL(this.opts.project.cwd,Wr.resolveVirtual(m)),locator:k})}}return Se.getMapWithDefault(this.packageRegistry,n).set(s,{packageLocation:y,packageDependencies:b,packagePeers:v,linkType:e.linkType,discardFromLookup:t.discardFromLookup||!1}),{packageLocation:m,buildDirective:h.length>0?h:null}}async attachInternalDependencies(e,t){let i=this.getPackageInformation(e);for(let[n,s]of t){let o=P.areIdentsEqual(n,s)?s.reference:[P.stringifyIdent(s),s.reference];i.packageDependencies.set(P.stringifyIdent(n),o)}}async attachExternalDependents(e,t){for(let i of t)this.getDiskInformation(i).packageDependencies.set(P.stringifyIdent(e),e.reference)}async finalizeInstall(){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;let e=Ol(this.opts.project);if(U.existsSync(e.cjsLegacy)&&(this.opts.report.reportWarning(X.UNNAMED,`Removing the old ${ae.pretty(this.opts.project.configuration,xt.pnpJs,ae.Type.PATH)} file. You might need to manually update existing references to reference the new ${ae.pretty(this.opts.project.configuration,xt.pnpCjs,ae.Type.PATH)} file. If you use Editor SDKs, you'll have to rerun ${ae.pretty(this.opts.project.configuration,"yarn sdks",ae.Type.CODE)}.`),await U.removePromise(e.cjsLegacy)),this.isEsmEnabled()||await U.removePromise(e.esmLoader),this.opts.project.configuration.get("nodeLinker")!=="pnp"){await U.removePromise(e.cjs),await U.removePromise(this.opts.project.configuration.get("pnpDataPath")),await U.removePromise(e.esmLoader);return}for(let{locator:u,location:g}of this.virtualTemplates.values())Se.getMapWithDefault(this.packageRegistry,P.stringifyIdent(u)).set(u.reference,{packageLocation:g,packageDependencies:new Map,packagePeers:new Set,linkType:Qt.SOFT,discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));let t=this.opts.project.configuration.get("pnpFallbackMode"),i=this.opts.project.workspaces.map(({anchoredLocator:u})=>({name:P.stringifyIdent(u),reference:u.reference})),n=t!=="none",s=[],o=new Map,a=Se.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),l=this.packageRegistry,c=this.opts.project.configuration.get("pnpShebang");if(t==="dependencies-only")for(let u of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(u)&&s.push({name:P.stringifyIdent(u),reference:u.reference});return await this.asyncActions.wait(),await this.finalizeInstallWithPnp({dependencyTreeRoots:i,enableTopLevelFallback:n,fallbackExclusionList:s,fallbackPool:o,ignorePattern:a,packageRegistry:l,shebang:c}),{customData:this.customData}}async transformPnpSettings(e){}isEsmEnabled(){if(this.opts.project.configuration.sources.has("pnpEnableEsmLoader"))return this.opts.project.configuration.get("pnpEnableEsmLoader");if(this.isESMLoaderRequired)return!0;for(let e of this.opts.project.workspaces)if(e.manifest.type==="module")return!0;return!1}async finalizeInstallWithPnp(e){let t=Ol(this.opts.project),i=this.opts.project.configuration.get("pnpDataPath"),n=await this.locateNodeModules(e.ignorePattern);if(n.length>0){this.opts.report.reportWarning(X.DANGEROUS_NODE_MODULES,"One or more node_modules have been detected and will be removed. This operation may take some time.");for(let o of n)await U.removePromise(o)}if(await this.transformPnpSettings(e),this.opts.project.configuration.get("pnpEnableInlining")){let o=RAe(e);await U.changeFilePromise(t.cjs,o,{automaticNewlines:!0,mode:493}),await U.removePromise(i)}else{let o=x.relative(x.dirname(t.cjs),i),{dataFile:a,loaderFile:l}=FAe(te(N({},e),{dataLocation:o}));await U.changeFilePromise(t.cjs,l,{automaticNewlines:!0,mode:493}),await U.changeFilePromise(i,a,{automaticNewlines:!0,mode:420})}this.isEsmEnabled()&&(this.opts.report.reportWarning(X.UNNAMED,"ESM support for PnP uses the experimental loader API and is therefore experimental"),await U.changeFilePromise(t.esmLoader,(0,DL.default)(),{automaticNewlines:!0,mode:420}));let s=this.opts.project.configuration.get("pnpUnpluggedFolder");if(this.unpluggedPaths.size===0)await U.removePromise(s);else for(let o of await U.readdirPromise(s)){let a=x.resolve(s,o);this.unpluggedPaths.has(a)||await U.removePromise(a)}}async locateNodeModules(e){let t=[],i=e?new RegExp(e):null;for(let n of this.opts.project.workspaces){let s=x.join(n.cwd,"node_modules");if(i&&i.test(x.relative(this.opts.project.cwd,n.cwd))||!U.existsSync(s))continue;let o=await U.readdirPromise(s,{withFileTypes:!0}),a=o.filter(l=>!l.isDirectory()||l.name===".bin"||!l.name.startsWith("."));if(a.length===o.length)t.push(s);else for(let l of a)t.push(x.join(s,l.name))}return t}async unplugPackageIfNeeded(e,t,i,n,s){return this.shouldBeUnplugged(e,t,n)?this.unplugPackage(e,i,s):i.packageFs}shouldBeUnplugged(e,t,i){return typeof i.unplugged!="undefined"?i.unplugged:hze.has(e.identHash)||e.conditions!=null?!0:t.manifest.preferUnplugged!==null?t.manifest.preferUnplugged:!!(ib(e,t,i,{configuration:this.opts.project.configuration}).length>0||t.misc.extractHint)}async unplugPackage(e,t,i){let n=jm(e,{configuration:this.opts.project.configuration});return this.opts.project.disabledLocators.has(e.locatorHash)?new La(n,{baseFs:t.packageFs,pathUtils:x}):(this.unpluggedPaths.add(n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{let s=x.join(n,t.prefixPath,".ready");await U.existsPromise(s)||(this.opts.project.storedBuildState.delete(e.locatorHash),await U.mkdirPromise(n,{recursive:!0}),await U.copyPromise(n,Me.dot,{baseFs:t.packageFs,overwrite:!1}),await U.writeFilePromise(s,""))})),new _t(n))}getPackageInformation(e){let t=P.stringifyIdent(e),i=e.reference,n=this.packageRegistry.get(t);if(!n)throw new Error(`Assertion failed: The package information store should have been available (for ${P.prettyIdent(this.opts.project.configuration,e)})`);let s=n.get(i);if(!s)throw new Error(`Assertion failed: The package information should have been available (for ${P.prettyLocator(this.opts.project.configuration,e)})`);return s}getDiskInformation(e){let t=Se.getMapWithDefault(this.packageRegistry,"@@disk"),i=LL(this.opts.project.cwd,e);return Se.getFactoryWithDefault(t,i,()=>({packageLocation:i,packageDependencies:new Map,packagePeers:new Set,linkType:Qt.SOFT,discardFromLookup:!1}))}};function LL(r,e){let t=x.relative(r,e);return t.match(/^\.{0,2}\//)||(t=`./${t}`),t.replace(/\/?$/,"/")}async function pze(r){var i;let e=(i=await At.tryFind(r.prefixPath,{baseFs:r.packageFs}))!=null?i:new At,t=new Set(["preinstall","install","postinstall"]);for(let n of e.scripts.keys())t.has(n)||e.scripts.delete(n);return{manifest:{scripts:e.scripts,preferUnplugged:e.preferUnplugged,type:e.type},misc:{extractHint:RL(r),hasBindingGyp:FL(r)}}}var GAe=ge(ns());var Gm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Unplug direct dependencies from the entire project"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Unplug both direct and transitive dependencies"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);if(e.get("nodeLinker")!=="pnp")throw new Pe("This command can only be used if the `nodeLinker` option is set to `pnp`");await t.restoreInstallState();let s=new Set(this.patterns),o=this.patterns.map(f=>{let h=P.parseDescriptor(f),p=h.range!=="unknown"?h:P.makeDescriptor(h,"*");if(!Wt.validRange(p.range))throw new Pe(`The range of the descriptor patterns must be a valid semver range (${P.prettyDescriptor(e,p)})`);return m=>{let y=P.stringifyIdent(m);return!GAe.default.isMatch(y,P.stringifyIdent(p))||m.version&&!Wt.satisfiesWithPrereleases(m.version,p.range)?!1:(s.delete(f),!0)}}),a=()=>{let f=[];for(let h of t.storedPackages.values())!t.tryWorkspaceByLocator(h)&&!P.isVirtualLocator(h)&&o.some(p=>p(h))&&f.push(h);return f},l=f=>{let h=new Set,p=[],m=(y,b)=>{if(!h.has(y.locatorHash)&&(h.add(y.locatorHash),!t.tryWorkspaceByLocator(y)&&o.some(v=>v(y))&&p.push(y),!(b>0&&!this.recursive)))for(let v of y.dependencies.values()){let k=t.storedResolutions.get(v.descriptorHash);if(!k)throw new Error("Assertion failed: The resolution should have been registered");let T=t.storedPackages.get(k);if(!T)throw new Error("Assertion failed: The package should have been registered");m(T,b+1)}};for(let y of f){let b=t.storedPackages.get(y.anchoredLocator.locatorHash);if(!b)throw new Error("Assertion failed: The package should have been registered");m(b,0)}return p},c,u;if(this.all&&this.recursive?(c=a(),u="the project"):this.all?(c=l(t.workspaces),u="any workspace"):(c=l([i]),u="this workspace"),s.size>1)throw new Pe(`Patterns ${ae.prettyList(e,s,ae.Type.CODE)} don't match any packages referenced by ${u}`);if(s.size>0)throw new Pe(`Pattern ${ae.prettyList(e,s,ae.Type.CODE)} doesn't match any packages referenced by ${u}`);return c=Se.sortMap(c,f=>P.stringifyLocator(f)),(await Je.start({configuration:e,stdout:this.context.stdout,json:this.json},async f=>{var h;for(let p of c){let m=(h=p.version)!=null?h:"unknown",y=t.topLevelWorkspace.manifest.ensureDependencyMeta(P.makeDescriptor(p,m));y.unplugged=!0,f.reportInfo(X.UNNAMED,`Will unpack ${P.prettyLocator(e,p)} to ${ae.pretty(e,jm(p,{configuration:e}),ae.Type.PATH)}`),f.reportJson({locator:P.stringifyLocator(p),version:m})}await t.topLevelWorkspace.persistManifest(),f.reportSeparator(),await t.install({cache:n,report:f})})).exitCode()}};Gm.paths=[["unplug"]],Gm.usage=Re.Usage({description:"force the unpacking of a list of packages",details:"\n This command will add the selectors matching the specified patterns to the list of packages that must be unplugged when installed.\n\n A package being unplugged means that instead of being referenced directly through its archive, it will be unpacked at install time in the directory configured via `pnpUnpluggedFolder`. Note that unpacking packages this way is generally not recommended because it'll make it harder to store your packages within the repository. However, it's a good approach to quickly and safely debug some packages, and can even sometimes be required depending on the context (for example when the package contains shellscripts).\n\n Running the command will set a persistent flag inside your top-level `package.json`, in the `dependenciesMeta` field. As such, to undo its effects, you'll need to revert the changes made to the manifest and run `yarn install` to apply the modification.\n\n By default, only direct dependencies from the current workspace are affected. If `-A,--all` is set, direct dependencies from the entire project are affected. Using the `-R,--recursive` flag will affect transitive dependencies as well as direct ones.\n\n This command accepts glob patterns inside the scope and name components (not the range). Make sure to escape the patterns to prevent your own shell from trying to expand them.\n ",examples:[["Unplug the lodash dependency from the active workspace","yarn unplug lodash"],["Unplug all instances of lodash referenced by any workspace","yarn unplug lodash -A"],["Unplug all instances of lodash referenced by the active workspace and its dependencies","yarn unplug lodash -R"],["Unplug all instances of lodash, anywhere","yarn unplug lodash -AR"],["Unplug one specific version of lodash","yarn unplug lodash@1.2.3"],["Unplug all packages with the `@babel` scope","yarn unplug '@babel/*'"],["Unplug all packages (only for testing, not recommended)","yarn unplug -R '*'"]]});var YAe=Gm;var Ol=r=>({cjs:x.join(r.cwd,xt.pnpCjs),cjsLegacy:x.join(r.cwd,xt.pnpJs),esmLoader:x.join(r.cwd,".pnp.loader.mjs")}),WAe=r=>/\s/.test(r)?JSON.stringify(r):r;async function dze(r,e,t){let i=Ol(r),n=`--require ${WAe(H.fromPortablePath(i.cjs))}`;if(U.existsSync(i.esmLoader)&&(n=`${n} --experimental-loader ${(0,JAe.pathToFileURL)(H.fromPortablePath(i.esmLoader)).href}`),i.cjs.includes(" ")&&qAe.default.lt(process.versions.node,"12.0.0"))throw new Error(`Expected the build location to not include spaces when using Node < 12.0.0 (${process.versions.node})`);if(U.existsSync(i.cjs)){let s=e.NODE_OPTIONS||"",o=/\s*--require\s+\S*\.pnp\.c?js\s*/g,a=/\s*--experimental-loader\s+\S*\.pnp\.loader\.mjs\s*/;s=s.replace(o," ").replace(a," ").trim(),s=s?`${n} ${s}`:n,e.NODE_OPTIONS=s}}async function Cze(r,e){let t=Ol(r);e(t.cjs),e(t.esmLoader),e(r.configuration.get("pnpDataPath")),e(r.configuration.get("pnpUnpluggedFolder"))}var mze={hooks:{populateYarnPaths:Cze,setupScriptEnvironment:dze},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "node-modules"',type:Ie.STRING,default:"pnp"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:Ie.STRING,default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:Ie.STRING,default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:Ie.STRING,default:[],isArray:!0},pnpEnableEsmLoader:{description:"If true, Yarn will generate an ESM loader (`.pnp.loader.mjs`). If this is not explicitly set Yarn tries to automatically detect whether ESM support is required.",type:Ie.BOOLEAN,default:!1},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:Ie.BOOLEAN,default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:Ie.STRING,default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:Ie.ABSOLUTE_PATH,default:"./.yarn/unplugged"},pnpDataPath:{description:"Path of the file where the PnP data (used by the loader) must be written",type:Ie.ABSOLUTE_PATH,default:"./.pnp.data.json"}},linkers:[xu],commands:[YAe]},Eze=mze;var $Ae=ge(ZAe());var HL=ge(require("crypto")),ele=ge(require("fs")),tle=1,jr="node_modules",nb=".bin",rle=".yarn-state.yml",Ti;(function(i){i.CLASSIC="classic",i.HARDLINKS_LOCAL="hardlinks-local",i.HARDLINKS_GLOBAL="hardlinks-global"})(Ti||(Ti={}));var jL=class{constructor(){this.installStateCache=new Map}supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the node-modules linker to be enabled");let i=t.project.tryWorkspaceByLocator(e);if(i)return i.cwd;let n=await Se.getFactoryWithDefault(this.installStateCache,t.project.cwd,async()=>await GL(t.project,{unrollAliases:!0}));if(n===null)throw new Pe("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");let s=n.locatorMap.get(P.stringifyLocator(e));if(!s){let a=new Pe(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw a.code="LOCATOR_NOT_INSTALLED",a}let o=t.project.configuration.startingCwd;return s.locations.find(a=>x.contains(o,a))||s.locations[0]}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=await Se.getFactoryWithDefault(this.installStateCache,t.project.cwd,async()=>await GL(t.project,{unrollAliases:!0}));if(i===null)return null;let{locationRoot:n,segments:s}=sb(x.resolve(e),{skipPrefix:t.project.cwd}),o=i.locationTree.get(n);if(!o)return null;let a=o.locator;for(let l of s){if(o=o.children.get(l),!o)break;a=o.locator||a}return P.parseLocator(a)}makeInstaller(e){return new ile(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="node-modules"}},ile=class{constructor(e){this.opts=e;this.localStore=new Map;this.realLocatorChecksums=new Map;this.customData={store:new Map}}getCustomDataKey(){return JSON.stringify({name:"NodeModulesInstaller",version:2})}attachCustomData(e){this.customData=e}async installPackage(e,t){var u;let i=x.resolve(t.packageFs.getRealPath(),t.prefixPath),n=this.customData.store.get(e.locatorHash);if(typeof n=="undefined"&&(n=await Tze(e,t),e.linkType===Qt.HARD&&this.customData.store.set(e.locatorHash,n)),!P.isPackageCompatible(e,this.opts.project.configuration.getSupportedArchitectures()))return{packageLocation:null,buildDirective:null};let s=new Map,o=new Set;s.has(P.stringifyIdent(e))||s.set(P.stringifyIdent(e),e.reference);let a=e;if(P.isVirtualLocator(e)){a=P.devirtualizeLocator(e);for(let g of e.peerDependencies.values())s.set(P.stringifyIdent(g),null),o.add(P.stringifyIdent(g))}let l={packageLocation:`${H.fromPortablePath(i)}/`,packageDependencies:s,packagePeers:o,linkType:e.linkType,discardFromLookup:(u=t.discardFromLookup)!=null?u:!1};this.localStore.set(e.locatorHash,{pkg:e,customPackageData:n,dependencyMeta:this.opts.project.getDependencyMeta(e,e.version),pnpNode:l});let c=t.checksum?t.checksum.substring(t.checksum.indexOf("/")+1):null;return this.realLocatorChecksums.set(a.locatorHash,c),{packageLocation:i,buildDirective:null}}async attachInternalDependencies(e,t){let i=this.localStore.get(e.locatorHash);if(typeof i=="undefined")throw new Error("Assertion failed: Expected information object to have been registered");for(let[n,s]of t){let o=P.areIdentsEqual(n,s)?s.reference:[P.stringifyIdent(s),s.reference];i.pnpNode.packageDependencies.set(P.stringifyIdent(n),o)}}async attachExternalDependents(e,t){throw new Error("External dependencies haven't been implemented for the node-modules linker")}async finalizeInstall(){if(this.opts.project.configuration.get("nodeLinker")!=="node-modules")return;let e=new Wr({baseFs:new ys({libzip:await fn(),maxOpenFiles:80,readOnlyArchives:!0})}),t=await GL(this.opts.project),i=this.opts.project.configuration.get("nmMode");(t===null||i!==t.nmMode)&&(this.opts.project.storedBuildState.clear(),t={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map,nmMode:i,mtimeMs:0});let n=new Map(this.opts.project.workspaces.map(f=>{var p,m;let h=this.opts.project.configuration.get("nmHoistingLimits");try{h=Se.validateEnum(Kn,(m=(p=f.manifest.installConfig)==null?void 0:p.hoistingLimits)!=null?m:h)}catch(y){let b=P.prettyWorkspace(this.opts.project.configuration,f);this.opts.report.reportWarning(X.INVALID_MANIFEST,`${b}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(Kn).join(", ")}, using default: "${h}"`)}return[f.relativeCwd,h]})),s=new Map(this.opts.project.workspaces.map(f=>{var p,m;let h=this.opts.project.configuration.get("nmSelfReferences");return h=(m=(p=f.manifest.installConfig)==null?void 0:p.selfReferences)!=null?m:h,[f.relativeCwd,h]})),o={VERSIONS:{std:1},topLevel:{name:null,reference:null},getLocator:(f,h)=>Array.isArray(h)?{name:h[0],reference:h[1]}:{name:f,reference:h},getDependencyTreeRoots:()=>this.opts.project.workspaces.map(f=>{let h=f.anchoredLocator;return{name:P.stringifyIdent(f.locator),reference:h.reference}}),getPackageInformation:f=>{let h=f.reference===null?this.opts.project.topLevelWorkspace.anchoredLocator:P.makeLocator(P.parseIdent(f.name),f.reference),p=this.localStore.get(h.locatorHash);if(typeof p=="undefined")throw new Error("Assertion failed: Expected the package reference to have been registered");return p.pnpNode},findPackageLocator:f=>{let h=this.opts.project.tryWorkspaceByCwd(H.toPortablePath(f));if(h!==null){let p=h.anchoredLocator;return{name:P.stringifyIdent(p),reference:p.reference}}throw new Error("Assertion failed: Unimplemented")},resolveToUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveRequest:()=>{throw new Error("Assertion failed: Unimplemented")},resolveVirtual:f=>H.fromPortablePath(Wr.resolveVirtual(H.toPortablePath(f)))},{tree:a,errors:l,preserveSymlinksRequired:c}=Mm(o,{pnpifyFs:!1,validateExternalSoftLinks:!0,hoistingLimitsByCwd:n,project:this.opts.project,selfReferencesByCwd:s});if(!a){for(let{messageName:f,text:h}of l)this.opts.report.reportError(f,h);return}let u=bL(a);await Oze(t,u,{baseFs:e,project:this.opts.project,report:this.opts.report,realLocatorChecksums:this.realLocatorChecksums,loadManifest:async f=>{let h=P.parseLocator(f),p=this.localStore.get(h.locatorHash);if(typeof p=="undefined")throw new Error("Assertion failed: Expected the slot to exist");return p.customPackageData.manifest}});let g=[];for(let[f,h]of u.entries()){if(nle(f))continue;let p=P.parseLocator(f),m=this.localStore.get(p.locatorHash);if(typeof m=="undefined")throw new Error("Assertion failed: Expected the slot to exist");if(this.opts.project.tryWorkspaceByLocator(m.pkg))continue;let y=ma.extractBuildScripts(m.pkg,m.customPackageData,m.dependencyMeta,{configuration:this.opts.project.configuration,report:this.opts.report});y.length!==0&&g.push({buildLocations:h.locations,locatorHash:p.locatorHash,buildDirective:y})}return c&&this.opts.report.reportWarning(X.NM_PRESERVE_SYMLINKS_REQUIRED,`The application uses portals and that's why ${ae.pretty(this.opts.project.configuration,"--preserve-symlinks",ae.Type.CODE)} Node option is required for launching it`),{customData:this.customData,records:g}}};async function Tze(r,e){var n;let t=(n=await At.tryFind(e.prefixPath,{baseFs:e.packageFs}))!=null?n:new At,i=new Set(["preinstall","install","postinstall"]);for(let s of t.scripts.keys())i.has(s)||t.scripts.delete(s);return{manifest:{bin:t.bin,scripts:t.scripts},misc:{extractHint:ma.getExtractHint(e),hasBindingGyp:ma.hasBindingGyp(e)}}}async function Mze(r,e,t,i,{installChangedByUser:n}){let s="";s+=`# Warning: This file is automatically generated. Removing it is fine, but will -`,s+=`# cause your node_modules installation to become invalidated. -`,s+=` -`,s+=`__metadata: -`,s+=` version: ${tle} -`,s+=` nmMode: ${i.value} -`;let o=Array.from(e.keys()).sort(),a=P.stringifyLocator(r.topLevelWorkspace.anchoredLocator);for(let u of o){let g=e.get(u);s+=` -`,s+=`${JSON.stringify(u)}: -`,s+=` locations: -`;for(let f of g.locations){let h=x.contains(r.cwd,f);if(h===null)throw new Error(`Assertion failed: Expected the path to be within the project (${f})`);s+=` - ${JSON.stringify(h)} -`}if(g.aliases.length>0){s+=` aliases: -`;for(let f of g.aliases)s+=` - ${JSON.stringify(f)} -`}if(u===a&&t.size>0){s+=` bin: -`;for(let[f,h]of t){let p=x.contains(r.cwd,f);if(p===null)throw new Error(`Assertion failed: Expected the path to be within the project (${f})`);s+=` ${JSON.stringify(p)}: -`;for(let[m,y]of h){let b=x.relative(x.join(f,jr),y);s+=` ${JSON.stringify(m)}: ${JSON.stringify(b)} -`}}}}let l=r.cwd,c=x.join(l,jr,rle);n&&await U.removePromise(c),await U.changeFilePromise(c,s,{automaticNewlines:!0})}async function GL(r,{unrollAliases:e=!1}={}){let t=r.cwd,i=x.join(t,jr,rle),n;try{n=await U.statPromise(i)}catch(c){}if(!n)return null;let s=Si(await U.readFilePromise(i,"utf8"));if(s.__metadata.version>tle)return null;let o=s.__metadata.nmMode||Ti.CLASSIC,a=new Map,l=new Map;delete s.__metadata;for(let[c,u]of Object.entries(s)){let g=u.locations.map(h=>x.join(t,h)),f=u.bin;if(f)for(let[h,p]of Object.entries(f)){let m=x.join(t,H.toPortablePath(h)),y=Se.getMapWithDefault(l,m);for(let[b,v]of Object.entries(p))y.set(Jr(b),H.toPortablePath([m,jr,v].join(x.sep)))}if(a.set(c,{target:Me.dot,linkType:Qt.HARD,locations:g,aliases:u.aliases||[]}),e&&u.aliases)for(let h of u.aliases){let{scope:p,name:m}=P.parseLocator(c),y=P.makeLocator(P.makeIdent(p,m),h),b=P.stringifyLocator(y);a.set(b,{target:Me.dot,linkType:Qt.HARD,locations:g,aliases:[]})}}return{locatorMap:a,binSymlinks:l,locationTree:sle(a,{skipPrefix:r.cwd}),nmMode:o,mtimeMs:n.mtimeMs}}var lh=async(r,e)=>{if(r.split(x.sep).indexOf(jr)<0)throw new Error(`Assertion failed: trying to remove dir that doesn't contain node_modules: ${r}`);try{if(!e.innerLoop){let i=e.allowSymlink?await U.statPromise(r):await U.lstatPromise(r);if(e.allowSymlink&&!i.isDirectory()||!e.allowSymlink&&i.isSymbolicLink()){await U.unlinkPromise(r);return}}let t=await U.readdirPromise(r,{withFileTypes:!0});for(let i of t){let n=x.join(r,Jr(i.name));i.isDirectory()?(i.name!==jr||e&&e.innerLoop)&&await lh(n,{innerLoop:!0,contentsOnly:!1}):await U.unlinkPromise(n)}e.contentsOnly||await U.rmdirPromise(r)}catch(t){if(t.code!=="ENOENT"&&t.code!=="ENOTEMPTY")throw t}},ole=4,sb=(r,{skipPrefix:e})=>{let t=x.contains(e,r);if(t===null)throw new Error(`Assertion failed: Writing attempt prevented to ${r} which is outside project root: ${e}`);let i=t.split(x.sep).filter(l=>l!==""),n=i.indexOf(jr),s=i.slice(0,n).join(x.sep),o=x.join(e,s),a=i.slice(n);return{locationRoot:o,segments:a}},sle=(r,{skipPrefix:e})=>{let t=new Map;if(r===null)return t;let i=()=>({children:new Map,linkType:Qt.HARD});for(let[n,s]of r.entries()){if(s.linkType===Qt.SOFT&&x.contains(e,s.target)!==null){let a=Se.getFactoryWithDefault(t,s.target,i);a.locator=n,a.linkType=s.linkType}for(let o of s.locations){let{locationRoot:a,segments:l}=sb(o,{skipPrefix:e}),c=Se.getFactoryWithDefault(t,a,i);for(let u=0;u<l.length;++u){let g=l[u];if(g!=="."){let f=Se.getFactoryWithDefault(c.children,g,i);c.children.set(g,f),c=f}u===l.length-1&&(c.locator=n,c.linkType=s.linkType)}}}return t},YL=async(r,e)=>{let t;try{process.platform==="win32"&&(t=await U.lstatPromise(r))}catch(i){}process.platform=="win32"&&(!t||t.isDirectory())?await U.symlinkPromise(r,e,"junction"):await U.symlinkPromise(x.relative(x.dirname(e),r),e)};async function ale(r,e,t){let i=x.join(r,Jr(`${HL.default.randomBytes(16).toString("hex")}.tmp`));try{await U.writeFilePromise(i,t);try{await U.linkPromise(i,e)}catch(n){}}finally{await U.unlinkPromise(i)}}async function Uze({srcPath:r,dstPath:e,srcMode:t,globalHardlinksStore:i,baseFs:n,nmMode:s,digest:o}){if(s.value===Ti.HARDLINKS_GLOBAL&&i&&o){let l=x.join(i,o.substring(0,2),`${o.substring(2)}.dat`),c;try{if(await Rn.checksumFile(l,{baseFs:U,algorithm:"sha1"})!==o){let g=x.join(i,Jr(`${HL.default.randomBytes(16).toString("hex")}.tmp`));await U.renamePromise(l,g);let f=await n.readFilePromise(r);await U.writeFilePromise(g,f);try{await U.linkPromise(g,l),await U.unlinkPromise(g)}catch(h){}}await U.linkPromise(l,e),c=!0}catch(u){c=!1}if(!c){let u=await n.readFilePromise(r);await ale(i,l,u);try{await U.linkPromise(l,e)}catch(g){g&&g.code&&g.code=="EXDEV"&&(s.value=Ti.HARDLINKS_LOCAL,await n.copyFilePromise(r,e))}}}else await n.copyFilePromise(r,e);let a=t&511;a!==420&&await U.chmodPromise(e,a)}var Ml;(function(i){i.FILE="file",i.DIRECTORY="directory",i.SYMLINK="symlink"})(Ml||(Ml={}));var Kze=async(r,e,{baseFs:t,globalHardlinksStore:i,nmMode:n,packageChecksum:s})=>{await U.mkdirPromise(r,{recursive:!0});let o=async(l=Me.dot)=>{let c=x.join(e,l),u=await t.readdirPromise(c,{withFileTypes:!0}),g=new Map;for(let f of u){let h=x.join(l,f.name),p,m=x.join(c,f.name);if(f.isFile()){if(p={kind:Ml.FILE,mode:(await t.lstatPromise(m)).mode},n.value===Ti.HARDLINKS_GLOBAL){let y=await Rn.checksumFile(m,{baseFs:t,algorithm:"sha1"});p.digest=y}}else if(f.isDirectory())p={kind:Ml.DIRECTORY};else if(f.isSymbolicLink())p={kind:Ml.SYMLINK,symlinkTo:await t.readlinkPromise(m)};else throw new Error(`Unsupported file type (file: ${m}, mode: 0o${await t.statSync(m).mode.toString(8).padStart(6,"0")})`);if(g.set(h,p),f.isDirectory()&&h!==jr){let y=await o(h);for(let[b,v]of y)g.set(b,v)}}return g},a;if(n.value===Ti.HARDLINKS_GLOBAL&&i&&s){let l=x.join(i,s.substring(0,2),`${s.substring(2)}.json`);try{a=new Map(Object.entries(JSON.parse(await U.readFilePromise(l,"utf8"))))}catch(c){a=await o(),await ale(i,l,Buffer.from(JSON.stringify(Object.fromEntries(a))))}}else a=await o();for(let[l,c]of a){let u=x.join(e,l),g=x.join(r,l);c.kind===Ml.DIRECTORY?await U.mkdirPromise(g,{recursive:!0}):c.kind===Ml.FILE?await Uze({srcPath:u,dstPath:g,srcMode:c.mode,digest:c.digest,nmMode:n,baseFs:t,globalHardlinksStore:i}):c.kind===Ml.SYMLINK&&await YL(x.resolve(x.dirname(g),c.symlinkTo),g)}};function Hze(r,e,t,i){let n=new Map,s=new Map,o=new Map,a=!1,l=(c,u,g,f,h)=>{let p=!0,m=x.join(c,u),y=new Set;if(u===jr||u.startsWith("@")){let v;try{v=U.statSync(m)}catch(T){}p=!!v,v?v.mtimeMs>t?(a=!0,y=new Set(U.readdirSync(m))):y=new Set(g.children.get(u).children.keys()):a=!0;let k=e.get(c);if(k){let T=x.join(c,jr,nb),Y;try{Y=U.statSync(T)}catch(q){}if(!Y)a=!0;else if(Y.mtimeMs>t){a=!0;let q=new Set(U.readdirSync(T)),$=new Map;s.set(c,$);for(let[z,ne]of k)q.has(z)&&$.set(z,ne)}else s.set(c,k)}}else p=h.has(u);let b=g.children.get(u);if(p){let{linkType:v,locator:k}=b,T={children:new Map,linkType:v,locator:k};if(f.children.set(u,T),k){let Y=Se.getSetWithDefault(o,k);Y.add(m),o.set(k,Y)}for(let Y of b.children.keys())l(m,Y,b,T,y)}else b.locator&&i.storedBuildState.delete(P.parseLocator(b.locator).locatorHash)};for(let[c,u]of r){let{linkType:g,locator:f}=u,h={children:new Map,linkType:g,locator:f};if(n.set(c,h),f){let p=Se.getSetWithDefault(o,u.locator);p.add(c),o.set(u.locator,p)}u.children.has(jr)&&l(c,jr,u,h,new Set)}return{locationTree:n,binSymlinks:s,locatorLocations:o,installChangedByUser:a}}function nle(r){let e=P.parseDescriptor(r);return P.isVirtualDescriptor(e)&&(e=P.devirtualizeDescriptor(e)),e.range.startsWith("link:")}async function jze(r,e,t,{loadManifest:i}){let n=new Map;for(let[a,{locations:l}]of r){let c=nle(a)?null:await i(a,l[0]),u=new Map;if(c)for(let[g,f]of c.bin){let h=x.join(l[0],f);f!==""&&U.existsSync(h)&&u.set(g,f)}n.set(a,u)}let s=new Map,o=(a,l,c)=>{let u=new Map,g=x.contains(t,a);if(c.locator&&g!==null){let f=n.get(c.locator);for(let[h,p]of f){let m=x.join(a,H.toPortablePath(p));u.set(Jr(h),m)}for(let[h,p]of c.children){let m=x.join(a,h),y=o(m,m,p);y.size>0&&s.set(a,new Map([...s.get(a)||new Map,...y]))}}else for(let[f,h]of c.children){let p=o(x.join(a,f),l,h);for(let[m,y]of p)u.set(m,y)}return u};for(let[a,l]of e){let c=o(a,a,l);c.size>0&&s.set(a,new Map([...s.get(a)||new Map,...c]))}return s}var Ale=(r,e)=>{if(!r||!e)return r===e;let t=P.parseLocator(r);P.isVirtualLocator(t)&&(t=P.devirtualizeLocator(t));let i=P.parseLocator(e);return P.isVirtualLocator(i)&&(i=P.devirtualizeLocator(i)),P.areLocatorsEqual(t,i)};function qL(r){return x.join(r.get("globalFolder"),"store")}async function Oze(r,e,{baseFs:t,project:i,report:n,loadManifest:s,realLocatorChecksums:o}){let a=x.join(i.cwd,jr),{locationTree:l,binSymlinks:c,locatorLocations:u,installChangedByUser:g}=Hze(r.locationTree,r.binSymlinks,r.mtimeMs,i),f=sle(e,{skipPrefix:i.cwd}),h=[],p=async({srcDir:z,dstDir:ne,linkType:ee,globalHardlinksStore:A,nmMode:oe,packageChecksum:ce})=>{let Z=(async()=>{try{ee===Qt.SOFT?(await U.mkdirPromise(x.dirname(ne),{recursive:!0}),await YL(x.resolve(z),ne)):await Kze(ne,z,{baseFs:t,globalHardlinksStore:A,nmMode:oe,packageChecksum:ce})}catch(O){throw O.message=`While persisting ${z} -> ${ne} ${O.message}`,O}finally{T.tick()}})().then(()=>h.splice(h.indexOf(Z),1));h.push(Z),h.length>ole&&await Promise.race(h)},m=async(z,ne,ee)=>{let A=(async()=>{let oe=async(ce,Z,O)=>{try{O.innerLoop||await U.mkdirPromise(Z,{recursive:!0});let L=await U.readdirPromise(ce,{withFileTypes:!0});for(let de of L){if(!O.innerLoop&&de.name===nb)continue;let Be=x.join(ce,de.name),Ge=x.join(Z,de.name);de.isDirectory()?(de.name!==jr||O&&O.innerLoop)&&(await U.mkdirPromise(Ge,{recursive:!0}),await oe(Be,Ge,te(N({},O),{innerLoop:!0}))):$.value===Ti.HARDLINKS_LOCAL||$.value===Ti.HARDLINKS_GLOBAL?await U.linkPromise(Be,Ge):await U.copyFilePromise(Be,Ge,ele.default.constants.COPYFILE_FICLONE)}}catch(L){throw O.innerLoop||(L.message=`While cloning ${ce} -> ${Z} ${L.message}`),L}finally{O.innerLoop||T.tick()}};await oe(z,ne,ee)})().then(()=>h.splice(h.indexOf(A),1));h.push(A),h.length>ole&&await Promise.race(h)},y=async(z,ne,ee)=>{if(ee)for(let[A,oe]of ne.children){let ce=ee.children.get(A);await y(x.join(z,A),oe,ce)}else{ne.children.has(jr)&&await lh(x.join(z,jr),{contentsOnly:!1});let A=x.basename(z)===jr&&f.has(x.join(x.dirname(z),x.sep));await lh(z,{contentsOnly:z===a,allowSymlink:A})}};for(let[z,ne]of l){let ee=f.get(z);for(let[A,oe]of ne.children){if(A===".")continue;let ce=ee&&ee.children.get(A),Z=x.join(z,A);await y(Z,oe,ce)}}let b=async(z,ne,ee)=>{if(ee){Ale(ne.locator,ee.locator)||await lh(z,{contentsOnly:ne.linkType===Qt.HARD});for(let[A,oe]of ne.children){let ce=ee.children.get(A);await b(x.join(z,A),oe,ce)}}else{ne.children.has(jr)&&await lh(x.join(z,jr),{contentsOnly:!0});let A=x.basename(z)===jr&&f.has(x.join(x.dirname(z),x.sep));await lh(z,{contentsOnly:ne.linkType===Qt.HARD,allowSymlink:A})}};for(let[z,ne]of f){let ee=l.get(z);for(let[A,oe]of ne.children){if(A===".")continue;let ce=ee&&ee.children.get(A);await b(x.join(z,A),oe,ce)}}let v=new Map,k=[];for(let[z,ne]of u)for(let ee of ne){let{locationRoot:A,segments:oe}=sb(ee,{skipPrefix:i.cwd}),ce=f.get(A),Z=A;if(ce){for(let O of oe)if(Z=x.join(Z,O),ce=ce.children.get(O),!ce)break;if(ce){let O=Ale(ce.locator,z),L=e.get(ce.locator),de=L.target,Be=Z,Ge=L.linkType;if(O)v.has(de)||v.set(de,Be);else if(de!==Be){let re=P.parseLocator(ce.locator);P.isVirtualLocator(re)&&(re=P.devirtualizeLocator(re)),k.push({srcDir:de,dstDir:Be,linkType:Ge,realLocatorHash:re.locatorHash})}}}}for(let[z,{locations:ne}]of e.entries())for(let ee of ne){let{locationRoot:A,segments:oe}=sb(ee,{skipPrefix:i.cwd}),ce=l.get(A),Z=f.get(A),O=A,L=e.get(z),de=P.parseLocator(z);P.isVirtualLocator(de)&&(de=P.devirtualizeLocator(de));let Be=de.locatorHash,Ge=L.target,re=ee;if(Ge===re)continue;let se=L.linkType;for(let be of oe)Z=Z.children.get(be);if(!ce)k.push({srcDir:Ge,dstDir:re,linkType:se,realLocatorHash:Be});else for(let be of oe)if(O=x.join(O,be),ce=ce.children.get(be),!ce){k.push({srcDir:Ge,dstDir:re,linkType:se,realLocatorHash:Be});break}}let T=Ji.progressViaCounter(k.length),Y=n.reportProgress(T),q=i.configuration.get("nmMode"),$={value:q};try{let z=$.value===Ti.HARDLINKS_GLOBAL?`${qL(i.configuration)}/v1`:null;if(z&&!await U.existsPromise(z)){await U.mkdirpPromise(z);for(let ee=0;ee<256;ee++)await U.mkdirPromise(x.join(z,ee.toString(16).padStart(2,"0")))}for(let ee of k)(ee.linkType===Qt.SOFT||!v.has(ee.srcDir))&&(v.set(ee.srcDir,ee.dstDir),await p(te(N({},ee),{globalHardlinksStore:z,nmMode:$,packageChecksum:o.get(ee.realLocatorHash)||null})));await Promise.all(h),h.length=0;for(let ee of k){let A=v.get(ee.srcDir);ee.linkType!==Qt.SOFT&&ee.dstDir!==A&&await m(A,ee.dstDir,{nmMode:$})}await Promise.all(h),await U.mkdirPromise(a,{recursive:!0});let ne=await jze(e,f,i.cwd,{loadManifest:s});await Gze(c,ne,i.cwd),await Mze(i,e,ne,$,{installChangedByUser:g}),q==Ti.HARDLINKS_GLOBAL&&$.value==Ti.HARDLINKS_LOCAL&&n.reportWarningOnce(X.NM_HARDLINKS_MODE_DOWNGRADED,"'nmMode' has been downgraded to 'hardlinks-local' due to global cache and install folder being on different devices")}finally{Y.stop()}}async function Gze(r,e,t){for(let i of r.keys()){if(x.contains(t,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);if(!e.has(i)){let n=x.join(i,jr,nb);await U.removePromise(n)}}for(let[i,n]of e){if(x.contains(t,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);let s=x.join(i,jr,nb),o=r.get(i)||new Map;await U.mkdirPromise(s,{recursive:!0});for(let a of o.keys())n.has(a)||(await U.removePromise(x.join(s,a)),process.platform==="win32"&&await U.removePromise(x.join(s,Jr(`${a}.cmd`))));for(let[a,l]of n){let c=o.get(a),u=x.join(s,a);c!==l&&(process.platform==="win32"?await(0,$Ae.default)(H.fromPortablePath(l),H.fromPortablePath(u),{createPwshFile:!1}):(await U.removePromise(u),await YL(l,u),x.contains(t,await U.realpathPromise(l))!==null&&await U.chmodPromise(l,493)))}}}var JL=class extends xu{constructor(){super(...arguments);this.mode="loose"}makeInstaller(e){return new lle(e)}},lle=class extends ah{constructor(){super(...arguments);this.mode="loose"}async transformPnpSettings(e){let t=new Wr({baseFs:new ys({libzip:await fn(),maxOpenFiles:80,readOnlyArchives:!0})}),i=MAe(e,this.opts.project.cwd,t),{tree:n,errors:s}=Mm(i,{pnpifyFs:!1,project:this.opts.project});if(!n){for(let{messageName:u,text:g}of s)this.opts.report.reportError(u,g);return}let o=new Map;e.fallbackPool=o;let a=(u,g)=>{let f=P.parseLocator(g.locator),h=P.stringifyIdent(f);h===u?o.set(u,f.reference):o.set(u,[h,f.reference])},l=x.join(this.opts.project.cwd,xt.nodeModules),c=n.get(l);if(typeof c!="undefined"){if("target"in c)throw new Error("Assertion failed: Expected the root junction point to be a directory");for(let u of c.dirList){let g=x.join(l,u),f=n.get(g);if(typeof f=="undefined")throw new Error("Assertion failed: Expected the child to have been registered");if("target"in f)a(u,f);else for(let h of f.dirList){let p=x.join(g,h),m=n.get(p);if(typeof m=="undefined")throw new Error("Assertion failed: Expected the subchild to have been registered");if("target"in m)a(`${u}/${h}`,m);else throw new Error("Assertion failed: Expected the leaf junction to be a package")}}}}};var Yze={hooks:{cleanGlobalArtifacts:async r=>{let e=qL(r);await U.removePromise(e)}},configuration:{nmHoistingLimits:{description:"Prevent packages to be hoisted past specific levels",type:Ie.STRING,values:[Kn.WORKSPACES,Kn.DEPENDENCIES,Kn.NONE],default:Kn.NONE},nmMode:{description:'If set to "hardlinks-local" Yarn will utilize hardlinks to reduce disk space consumption inside "node_modules" directories. With "hardlinks-global" Yarn will use global content addressable storage to reduce "node_modules" size across all the projects using this option.',type:Ie.STRING,values:[Ti.CLASSIC,Ti.HARDLINKS_LOCAL,Ti.HARDLINKS_GLOBAL],default:Ti.CLASSIC},nmSelfReferences:{description:"If set to 'false' the workspace will not be allowed to require itself and corresponding self-referencing symlink will not be created",type:Ie.BOOLEAN,default:!0}},linkers:[jL,JL]},qze=Yze;var JT={};ft(JT,{default:()=>$9e,npmConfigUtils:()=>br,npmHttpUtils:()=>zt,npmPublishUtils:()=>Bh});var hle=ge(ri());var Cr="npm:";var zt={};ft(zt,{AuthType:()=>us,customPackageError:()=>zze,del:()=>Xze,get:()=>So,getIdentUrl:()=>Kl,handleInvalidAuthenticationError:()=>Ul,post:()=>_ze,put:()=>Vze});var gle=ge(zC()),fle=ge(require("url"));var br={};ft(br,{RegistryType:()=>SA,getAuditRegistry:()=>Jze,getAuthConfiguration:()=>_L,getDefaultRegistry:()=>ob,getPublishRegistry:()=>cle,getRegistryConfiguration:()=>ule,getScopeConfiguration:()=>zL,getScopeRegistry:()=>vA,normalizeRegistry:()=>Ea});var SA;(function(i){i.AUDIT_REGISTRY="npmAuditRegistry",i.FETCH_REGISTRY="npmRegistryServer",i.PUBLISH_REGISTRY="npmPublishRegistry"})(SA||(SA={}));function Ea(r){return r.replace(/\/$/,"")}function Jze(r,{configuration:e}){let t=e.get(SA.AUDIT_REGISTRY);return t!==null?Ea(t):cle(r,{configuration:e})}function cle(r,{configuration:e}){var t;return((t=r.publishConfig)==null?void 0:t.registry)?Ea(r.publishConfig.registry):r.name?vA(r.name.scope,{configuration:e,type:SA.PUBLISH_REGISTRY}):ob({configuration:e,type:SA.PUBLISH_REGISTRY})}function vA(r,{configuration:e,type:t=SA.FETCH_REGISTRY}){let i=zL(r,{configuration:e});if(i===null)return ob({configuration:e,type:t});let n=i.get(t);return n===null?ob({configuration:e,type:t}):Ea(n)}function ob({configuration:r,type:e=SA.FETCH_REGISTRY}){let t=r.get(e);return Ea(t!==null?t:r.get(SA.FETCH_REGISTRY))}function ule(r,{configuration:e}){let t=e.get("npmRegistries"),i=Ea(r),n=t.get(i);if(typeof n!="undefined")return n;let s=t.get(i.replace(/^[a-z]+:/,""));return typeof s!="undefined"?s:null}function zL(r,{configuration:e}){if(r===null)return null;let i=e.get("npmScopes").get(r);return i||null}function _L(r,{configuration:e,ident:t}){let i=t&&zL(t.scope,{configuration:e});return(i==null?void 0:i.get("npmAuthIdent"))||(i==null?void 0:i.get("npmAuthToken"))?i:ule(r,{configuration:e})||e}var us;(function(n){n[n.NO_AUTH=0]="NO_AUTH",n[n.BEST_EFFORT=1]="BEST_EFFORT",n[n.CONFIGURATION=2]="CONFIGURATION",n[n.ALWAYS_AUTH=3]="ALWAYS_AUTH"})(us||(us={}));async function Ul(r,{attemptedAs:e,registry:t,headers:i,configuration:n}){var s,o;if(ab(r))throw new ct(X.AUTHENTICATION_INVALID,"Invalid OTP token");if(((s=r.originalError)==null?void 0:s.name)==="HTTPError"&&((o=r.originalError)==null?void 0:o.response.statusCode)===401)throw new ct(X.AUTHENTICATION_INVALID,`Invalid authentication (${typeof e!="string"?`as ${await Wze(t,i,{configuration:n})}`:`attempted as ${e}`})`)}function zze(r){var e;return((e=r.response)==null?void 0:e.statusCode)===404?"Package not found":null}function Kl(r){return r.scope?`/@${r.scope}%2f${r.name}`:`/${r.name}`}async function So(r,a){var l=a,{configuration:e,headers:t,ident:i,authType:n,registry:s}=l,o=Or(l,["configuration","headers","ident","authType","registry"]);if(i&&typeof s=="undefined"&&(s=vA(i.scope,{configuration:e})),i&&i.scope&&typeof n=="undefined"&&(n=1),typeof s!="string")throw new Error("Assertion failed: The registry should be a string");let c=await Ab(s,{authType:n,configuration:e,ident:i});c&&(t=te(N({},t),{authorization:c}));try{return await ir.get(r.charAt(0)==="/"?`${s}${r}`:r,N({configuration:e,headers:t},o))}catch(u){throw await Ul(u,{registry:s,configuration:e,headers:t}),u}}async function _ze(r,e,u){var g=u,{attemptedAs:t,configuration:i,headers:n,ident:s,authType:o=3,registry:a,otp:l}=g,c=Or(g,["attemptedAs","configuration","headers","ident","authType","registry","otp"]);if(s&&typeof a=="undefined"&&(a=vA(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let f=await Ab(a,{authType:o,configuration:i,ident:s});f&&(n=te(N({},n),{authorization:f})),l&&(n=N(N({},n),ch(l)));try{return await ir.post(a+r,e,N({configuration:i,headers:n},c))}catch(h){if(!ab(h)||l)throw await Ul(h,{attemptedAs:t,registry:a,configuration:i,headers:n}),h;l=await VL();let p=N(N({},n),ch(l));try{return await ir.post(`${a}${r}`,e,N({configuration:i,headers:p},c))}catch(m){throw await Ul(m,{attemptedAs:t,registry:a,configuration:i,headers:n}),m}}}async function Vze(r,e,u){var g=u,{attemptedAs:t,configuration:i,headers:n,ident:s,authType:o=3,registry:a,otp:l}=g,c=Or(g,["attemptedAs","configuration","headers","ident","authType","registry","otp"]);if(s&&typeof a=="undefined"&&(a=vA(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let f=await Ab(a,{authType:o,configuration:i,ident:s});f&&(n=te(N({},n),{authorization:f})),l&&(n=N(N({},n),ch(l)));try{return await ir.put(a+r,e,N({configuration:i,headers:n},c))}catch(h){if(!ab(h))throw await Ul(h,{attemptedAs:t,registry:a,configuration:i,headers:n}),h;l=await VL();let p=N(N({},n),ch(l));try{return await ir.put(`${a}${r}`,e,N({configuration:i,headers:p},c))}catch(m){throw await Ul(m,{attemptedAs:t,registry:a,configuration:i,headers:n}),m}}}async function Xze(r,c){var u=c,{attemptedAs:e,configuration:t,headers:i,ident:n,authType:s=3,registry:o,otp:a}=u,l=Or(u,["attemptedAs","configuration","headers","ident","authType","registry","otp"]);if(n&&typeof o=="undefined"&&(o=vA(n.scope,{configuration:t})),typeof o!="string")throw new Error("Assertion failed: The registry should be a string");let g=await Ab(o,{authType:s,configuration:t,ident:n});g&&(i=te(N({},i),{authorization:g})),a&&(i=N(N({},i),ch(a)));try{return await ir.del(o+r,N({configuration:t,headers:i},l))}catch(f){if(!ab(f)||a)throw await Ul(f,{attemptedAs:e,registry:o,configuration:t,headers:i}),f;a=await VL();let h=N(N({},i),ch(a));try{return await ir.del(`${o}${r}`,N({configuration:t,headers:h},l))}catch(p){throw await Ul(p,{attemptedAs:e,registry:o,configuration:t,headers:i}),p}}}async function Ab(r,{authType:e=2,configuration:t,ident:i}){let n=_L(r,{configuration:t,ident:i}),s=Zze(n,e);if(!s)return null;let o=await t.reduceHook(a=>a.getNpmAuthenticationHeader,void 0,r,{configuration:t,ident:i});if(o)return o;if(n.get("npmAuthToken"))return`Bearer ${n.get("npmAuthToken")}`;if(n.get("npmAuthIdent")){let a=n.get("npmAuthIdent");return a.includes(":")?`Basic ${Buffer.from(a).toString("base64")}`:`Basic ${a}`}if(s&&e!==1)throw new ct(X.AUTHENTICATION_NOT_FOUND,"No authentication configured for request");return null}function Zze(r,e){switch(e){case 2:return r.get("npmAlwaysAuth");case 1:case 3:return!0;case 0:return!1;default:throw new Error("Unreachable")}}async function Wze(r,e,{configuration:t}){var i;if(typeof e=="undefined"||typeof e.authorization=="undefined")return"an anonymous user";try{return(i=(await ir.get(new fle.URL(`${r}/-/whoami`).href,{configuration:t,headers:e,jsonResponse:!0})).username)!=null?i:"an unknown user"}catch{return"an unknown user"}}async function VL(){if(process.env.TEST_ENV)return process.env.TEST_NPM_2FA_TOKEN||"";let{otp:r}=await(0,gle.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return r}function ab(r){var e,t;if(((e=r.originalError)==null?void 0:e.name)!=="HTTPError")return!1;try{return((t=r.originalError)==null?void 0:t.response.headers["www-authenticate"].split(/,\s*/).map(n=>n.toLowerCase())).includes("otp")}catch(i){return!1}}function ch(r){return{["npm-otp"]:r}}var XL=class{supports(e,t){if(!e.reference.startsWith(Cr))return!1;let{selector:i,params:n}=P.parseRange(e.reference);return!(!hle.default.valid(i)||n===null||typeof n.__archiveUrl!="string")}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let{params:i}=P.parseRange(e.reference);if(i===null||typeof i.__archiveUrl!="string")throw new Error("Assertion failed: The archiveUrl querystring parameter should have been available");let n=await So(i.__archiveUrl,{configuration:t.project.configuration,ident:e});return await Bi.convertToZip(n,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}};var ZL=class{supportsDescriptor(e,t){return!(!e.range.startsWith(Cr)||!P.tryParseDescriptor(e.range.slice(Cr.length),!0))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){let i=P.parseDescriptor(e.range.slice(Cr.length),!0);return t.resolver.getResolutionDependencies(i,t)}async getCandidates(e,t,i){let n=P.parseDescriptor(e.range.slice(Cr.length),!0);return await i.resolver.getCandidates(n,t,i)}async getSatisfying(e,t,i){let n=P.parseDescriptor(e.range.slice(Cr.length),!0);return i.resolver.getSatisfying(n,t,i)}resolve(e,t){throw new Error("Unreachable")}};var ple=ge(ri()),dle=ge(require("url"));var vo=class{supports(e,t){if(!e.reference.startsWith(Cr))return!1;let i=new dle.URL(e.reference);return!(!ple.default.valid(i.pathname)||i.searchParams.has("__archiveUrl"))}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote registry`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i;try{i=await So(vo.getLocatorUrl(e),{configuration:t.project.configuration,ident:e})}catch(n){i=await So(vo.getLocatorUrl(e).replace(/%2f/g,"/"),{configuration:t.project.configuration,ident:e})}return await Bi.convertToZip(i,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,t,{configuration:i}){let n=vA(e.scope,{configuration:i}),s=vo.getLocatorUrl(e);return t=t.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),n=n.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),t=t.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),t===n+s||t===n+s.replace(/%2f/g,"/")}static getLocatorUrl(e){let t=Wt.clean(e.reference.slice(Cr.length));if(t===null)throw new ct(X.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");return`${Kl(e)}/-/${e.name}-${t}.tgz`}};var Cle=ge(ri());var lb=P.makeIdent(null,"node-gyp"),$ze=/\b(node-gyp|prebuild-install)\b/,$L=class{supportsDescriptor(e,t){return e.range.startsWith(Cr)?!!Wt.validRange(e.range.slice(Cr.length)):!1}supportsLocator(e,t){if(!e.reference.startsWith(Cr))return!1;let{selector:i}=P.parseRange(e.reference);return!!Cle.default.valid(i)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=Wt.validRange(e.range.slice(Cr.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(Cr.length)}`);let s=await So(Kl(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0}),o=Se.mapAndFilter(Object.keys(s.versions),c=>{try{let u=new Wt.SemVer(c);if(n.test(u))return u}catch{}return Se.mapAndFilter.skip}),a=o.filter(c=>!s.versions[c.raw].deprecated),l=a.length>0?a:o;return l.sort((c,u)=>-c.compare(u)),l.map(c=>{let u=P.makeLocator(e,`${Cr}${c.raw}`),g=s.versions[c.raw].dist.tarball;return vo.isConventionalTarballUrl(u,g,{configuration:i.project.configuration})?u:P.bindLocator(u,{__archiveUrl:g})})}async getSatisfying(e,t,i){let n=Wt.validRange(e.range.slice(Cr.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(Cr.length)}`);return Se.mapAndFilter(t,s=>{try{let{selector:o}=P.parseRange(s,{requireProtocol:Cr}),a=new Wt.SemVer(o);if(n.test(a))return{reference:s,version:a}}catch{}return Se.mapAndFilter.skip}).sort((s,o)=>-s.version.compare(o.version)).map(({reference:s})=>P.makeLocator(e,s))}async resolve(e,t){let{selector:i}=P.parseRange(e.reference),n=Wt.clean(i);if(n===null)throw new ct(X.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");let s=await So(Kl(e),{configuration:t.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"versions"))throw new ct(X.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(!Object.prototype.hasOwnProperty.call(s.versions,n))throw new ct(X.REMOTE_NOT_FOUND,`Registry failed to return reference "${n}"`);let o=new At;if(o.load(s.versions[n]),!o.dependencies.has(lb.identHash)&&!o.peerDependencies.has(lb.identHash)){for(let a of o.scripts.values())if(a.match($ze)){o.dependencies.set(lb.identHash,P.makeDescriptor(lb,"latest")),t.report.reportWarningOnce(X.NODE_GYP_INJECTED,`${P.prettyLocator(t.project.configuration,e)}: Implicit dependencies on node-gyp are discouraged`);break}}if(typeof o.raw.deprecated=="string"&&o.raw.deprecated!==""){let a=P.prettyLocator(t.project.configuration,e),l=o.raw.deprecated.match(/\S/)?`${a} is deprecated: ${o.raw.deprecated}`:`${a} is deprecated`;t.report.reportWarningOnce(X.DEPRECATED_PACKAGE,l)}return te(N({},e),{version:n,languageName:"node",linkType:Qt.HARD,conditions:o.getConditions(),dependencies:o.dependencies,peerDependencies:o.peerDependencies,dependenciesMeta:o.dependenciesMeta,peerDependenciesMeta:o.peerDependenciesMeta,bin:o.bin})}};var eT=class{supportsDescriptor(e,t){return!(!e.range.startsWith(Cr)||!_g.test(e.range.slice(Cr.length)))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(Cr.length),s=await So(Kl(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"dist-tags"))throw new ct(X.REMOTE_INVALID,'Registry returned invalid data - missing "dist-tags" field');let o=s["dist-tags"];if(!Object.prototype.hasOwnProperty.call(o,n))throw new ct(X.REMOTE_NOT_FOUND,`Registry failed to return tag "${n}"`);let a=o[n],l=P.makeLocator(e,`${Cr}${a}`),c=s.versions[a].dist.tarball;return vo.isConventionalTarballUrl(l,c,{configuration:i.project.configuration})?[l]:[P.bindLocator(l,{__archiveUrl:c})]}async getSatisfying(e,t,i){return null}async resolve(e,t){throw new Error("Unreachable")}};var Bh={};ft(Bh,{getGitHead:()=>X9e,makePublishBody:()=>V9e});var jT={};ft(jT,{default:()=>R9e,packUtils:()=>DA});var DA={};ft(DA,{genPackList:()=>Db,genPackStream:()=>HT,genPackageManifest:()=>qce,hasPackScripts:()=>UT,prepareForPack:()=>KT});var MT=ge(ns()),Gce=ge(jce()),Yce=ge(require("zlib")),y9e=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],w9e=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function UT(r){return!!(Zt.hasWorkspaceScript(r,"prepack")||Zt.hasWorkspaceScript(r,"postpack"))}async function KT(r,{report:e},t){await Zt.maybeExecuteWorkspaceLifecycleScript(r,"prepack",{report:e});try{let i=x.join(r.cwd,At.fileName);await U.existsPromise(i)&&await r.manifest.loadFile(i,{baseFs:U}),await t()}finally{await Zt.maybeExecuteWorkspaceLifecycleScript(r,"postpack",{report:e})}}async function HT(r,e){var s,o;typeof e=="undefined"&&(e=await Db(r));let t=new Set;for(let a of(o=(s=r.manifest.publishConfig)==null?void 0:s.executableFiles)!=null?o:new Set)t.add(x.normalize(a));for(let a of r.manifest.bin.values())t.add(x.normalize(a));let i=Gce.default.pack();process.nextTick(async()=>{for(let a of e){let l=x.normalize(a),c=x.resolve(r.cwd,l),u=x.join("package",l),g=await U.lstatPromise(c),f={name:u,mtime:new Date(Rr.SAFE_TIME*1e3)},h=t.has(l)?493:420,p,m,y=new Promise((v,k)=>{p=v,m=k}),b=v=>{v?m(v):p()};if(g.isFile()){let v;l==="package.json"?v=Buffer.from(JSON.stringify(await qce(r),null,2)):v=await U.readFilePromise(c),i.entry(te(N({},f),{mode:h,type:"file"}),v,b)}else g.isSymbolicLink()?i.entry(te(N({},f),{mode:h,type:"symlink",linkname:await U.readlinkPromise(c)}),b):b(new Error(`Unsupported file type ${g.mode} for ${H.fromPortablePath(l)}`));await y}i.finalize()});let n=(0,Yce.createGzip)();return i.pipe(n),n}async function qce(r){let e=JSON.parse(JSON.stringify(r.manifest.raw));return await r.project.configuration.triggerHook(t=>t.beforeWorkspacePacking,r,e),e}async function Db(r){var g,f,h,p,m,y,b,v;let e=r.project,t=e.configuration,i={accept:[],reject:[]};for(let k of w9e)i.reject.push(k);for(let k of y9e)i.accept.push(k);i.reject.push(t.get("rcFilename"));let n=k=>{if(k===null||!k.startsWith(`${r.cwd}/`))return;let T=x.relative(r.cwd,k),Y=x.resolve(Me.root,T);i.reject.push(Y)};n(x.resolve(e.cwd,t.get("lockfileFilename"))),n(t.get("cacheFolder")),n(t.get("globalFolder")),n(t.get("installStatePath")),n(t.get("virtualFolder")),n(t.get("yarnPath")),await t.triggerHook(k=>k.populateYarnPaths,e,k=>{n(k)});for(let k of e.workspaces){let T=x.relative(r.cwd,k.cwd);T!==""&&!T.match(/^(\.\.)?\//)&&i.reject.push(`/${T}`)}let s={accept:[],reject:[]},o=(f=(g=r.manifest.publishConfig)==null?void 0:g.main)!=null?f:r.manifest.main,a=(p=(h=r.manifest.publishConfig)==null?void 0:h.module)!=null?p:r.manifest.module,l=(y=(m=r.manifest.publishConfig)==null?void 0:m.browser)!=null?y:r.manifest.browser,c=(v=(b=r.manifest.publishConfig)==null?void 0:b.bin)!=null?v:r.manifest.bin;o!=null&&s.accept.push(x.resolve(Me.root,o)),a!=null&&s.accept.push(x.resolve(Me.root,a)),typeof l=="string"&&s.accept.push(x.resolve(Me.root,l));for(let k of c.values())s.accept.push(x.resolve(Me.root,k));if(l instanceof Map)for(let[k,T]of l.entries())s.accept.push(x.resolve(Me.root,k)),typeof T=="string"&&s.accept.push(x.resolve(Me.root,T));let u=r.manifest.files!==null;if(u){s.reject.push("/*");for(let k of r.manifest.files)Jce(s.accept,k,{cwd:Me.root})}return await B9e(r.cwd,{hasExplicitFileList:u,globalList:i,ignoreList:s})}async function B9e(r,{hasExplicitFileList:e,globalList:t,ignoreList:i}){let n=[],s=new Ta(r),o=[[Me.root,[i]]];for(;o.length>0;){let[a,l]=o.pop(),c=await s.lstatPromise(a);if(!zce(a,{globalList:t,ignoreLists:c.isDirectory()?null:l}))if(c.isDirectory()){let u=await s.readdirPromise(a),g=!1,f=!1;if(!e||a!==Me.root)for(let m of u)g=g||m===".gitignore",f=f||m===".npmignore";let h=f?await Wce(s,a,".npmignore"):g?await Wce(s,a,".gitignore"):null,p=h!==null?[h].concat(l):l;zce(a,{globalList:t,ignoreLists:l})&&(p=[...l,{accept:[],reject:["**/*"]}]);for(let m of u)o.push([x.resolve(a,m),p])}else(c.isFile()||c.isSymbolicLink())&&n.push(x.relative(Me.root,a))}return n.sort()}async function Wce(r,e,t){let i={accept:[],reject:[]},n=await r.readFilePromise(x.join(e,t),"utf8");for(let s of n.split(/\n/g))Jce(i.reject,s,{cwd:e});return i}function b9e(r,{cwd:e}){let t=r[0]==="!";return t&&(r=r.slice(1)),r.match(/\.{0,1}\//)&&(r=x.resolve(e,r)),t&&(r=`!${r}`),r}function Jce(r,e,{cwd:t}){let i=e.trim();i===""||i[0]==="#"||r.push(b9e(i,{cwd:t}))}var gs;(function(i){i[i.None=0]="None",i[i.Match=1]="Match",i[i.NegatedMatch=2]="NegatedMatch"})(gs||(gs={}));function zce(r,{globalList:e,ignoreLists:t}){let i=Rb(r,e.accept);if(i!==0)return i===2;let n=Rb(r,e.reject);if(n!==0)return n===1;if(t!==null)for(let s of t){let o=Rb(r,s.accept);if(o!==0)return o===2;let a=Rb(r,s.reject);if(a!==0)return a===1}return!1}function Rb(r,e){let t=e,i=[];for(let n=0;n<e.length;++n)e[n][0]!=="!"?t!==e&&t.push(e[n]):(t===e&&(t=e.slice(0,n)),i.push(e[n].slice(1)));return _ce(r,i)?2:_ce(r,t)?1:0}function _ce(r,e){let t=e,i=[];for(let n=0;n<e.length;++n)e[n].includes("/")?t!==e&&t.push(e[n]):(t===e&&(t=e.slice(0,n)),i.push(e[n]));return!!(MT.default.isMatch(r,t,{dot:!0,nocase:!0})||MT.default.isMatch(r,i,{dot:!0,basename:!0,nocase:!0}))}var iE=class extends Le{constructor(){super(...arguments);this.installIfNeeded=J.Boolean("--install-if-needed",!1,{description:"Run a preliminary `yarn install` if the package contains build scripts"});this.dryRun=J.Boolean("-n,--dry-run",!1,{description:"Print the file paths without actually generating the package archive"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.out=J.String("-o,--out",{description:"Create the archive at the specified path"});this.filename=J.String("--filename",{hidden:!0})}async execute(){var a;let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await UT(i)&&(this.installIfNeeded?await t.install({cache:await Nt.find(e),report:new di}):await t.restoreInstallState());let n=(a=this.out)!=null?a:this.filename,s=typeof n!="undefined"?x.resolve(this.context.cwd,Q9e(n,{workspace:i})):x.resolve(i.cwd,"package.tgz");return(await Je.start({configuration:e,stdout:this.context.stdout,json:this.json},async l=>{await KT(i,{report:l},async()=>{l.reportJson({base:H.fromPortablePath(i.cwd)});let c=await Db(i);for(let u of c)l.reportInfo(null,H.fromPortablePath(u)),l.reportJson({location:H.fromPortablePath(u)});if(!this.dryRun){let u=await HT(i,c),g=U.createWriteStream(s);u.pipe(g),await new Promise(f=>{g.on("finish",f)})}}),this.dryRun||(l.reportInfo(X.UNNAMED,`Package archive generated in ${ae.pretty(e,s,ae.Type.PATH)}`),l.reportJson({output:H.fromPortablePath(s)}))})).exitCode()}};iE.paths=[["pack"]],iE.usage=Re.Usage({description:"generate a tarball from the active workspace",details:"\n This command will turn the active workspace into a compressed archive suitable for publishing. The archive will by default be stored at the root of the workspace (`package.tgz`).\n\n If the `-o,---out` is set the archive will be created at the specified path. The `%s` and `%v` variables can be used within the path and will be respectively replaced by the package name and version.\n ",examples:[["Create an archive from the active workspace","yarn pack"],["List the files that would be made part of the workspace's archive","yarn pack --dry-run"],["Name and output the archive in a dedicated folder","yarn pack --out /artifacts/%s-%v.tgz"]]});var Vce=iE;function Q9e(r,{workspace:e}){let t=r.replace("%s",S9e(e)).replace("%v",v9e(e));return H.toPortablePath(t)}function S9e(r){return r.manifest.name!==null?P.slugifyIdent(r.manifest.name):"package"}function v9e(r){return r.manifest.version!==null?r.manifest.version:"unknown"}var k9e=["dependencies","devDependencies","peerDependencies"],x9e="workspace:",P9e=(r,e)=>{var i,n;e.publishConfig&&(e.publishConfig.main&&(e.main=e.publishConfig.main),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.module&&(e.module=e.publishConfig.module),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.exports&&(e.exports=e.publishConfig.exports),e.publishConfig.bin&&(e.bin=e.publishConfig.bin));let t=r.project;for(let s of k9e)for(let o of r.manifest.getForScope(s).values()){let a=t.tryWorkspaceByDescriptor(o),l=P.parseRange(o.range);if(l.protocol===x9e)if(a===null){if(t.tryWorkspaceByIdent(o)===null)throw new ct(X.WORKSPACE_NOT_FOUND,`${P.prettyDescriptor(t.configuration,o)}: No local workspace found for this range`)}else{let c;P.areDescriptorsEqual(o,a.anchoredDescriptor)||l.selector==="*"?c=(i=a.manifest.version)!=null?i:"0.0.0":l.selector==="~"||l.selector==="^"?c=`${l.selector}${(n=a.manifest.version)!=null?n:"0.0.0"}`:c=l.selector;let u=s==="dependencies"?P.makeDescriptor(o,"unknown"):null,g=u!==null&&r.manifest.ensureDependencyMeta(u).optional?"optionalDependencies":s;e[g][P.stringifyIdent(o)]=c}}},D9e={hooks:{beforeWorkspacePacking:P9e},commands:[Vce]},R9e=D9e;var sue=ge(require("crypto")),oue=ge(nue()),aue=ge(require("url"));async function V9e(r,e,{access:t,tag:i,registry:n,gitHead:s}){let o=r.project.configuration,a=r.manifest.name,l=r.manifest.version,c=P.stringifyIdent(a),u=(0,sue.createHash)("sha1").update(e).digest("hex"),g=oue.default.fromData(e).toString();typeof t=="undefined"&&(r.manifest.publishConfig&&typeof r.manifest.publishConfig.access=="string"?t=r.manifest.publishConfig.access:o.get("npmPublishAccess")!==null?t=o.get("npmPublishAccess"):a.scope?t="restricted":t="public");let f=await DA.genPackageManifest(r),h=`${c}-${l}.tgz`,p=new aue.URL(`${Ea(n)}/${c}/-/${h}`);return{_id:c,_attachments:{[h]:{content_type:"application/octet-stream",data:e.toString("base64"),length:e.length}},name:c,access:t,["dist-tags"]:{[i]:l},versions:{[l]:te(N({},f),{_id:`${c}@${l}`,name:c,version:l,gitHead:s,dist:{shasum:u,integrity:g,tarball:p.toString()}})}}}async function X9e(r){try{let{stdout:e}=await Nr.execvp("git",["rev-parse","--revs-only","HEAD"],{cwd:r});return e.trim()===""?void 0:e.trim()}catch{return}}var WT={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:Ie.BOOLEAN,default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:Ie.SECRET,default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:Ie.SECRET,default:null}},Aue={npmAuditRegistry:{description:"Registry to query for audit reports",type:Ie.STRING,default:null},npmPublishRegistry:{description:"Registry to push packages to",type:Ie.STRING,default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:Ie.STRING,default:"https://registry.yarnpkg.com"}},Z9e={configuration:te(N(N({},WT),Aue),{npmScopes:{description:"Settings per package scope",type:Ie.MAP,valueDefinition:{description:"",type:Ie.SHAPE,properties:N(N({},WT),Aue)}},npmRegistries:{description:"Settings per registry",type:Ie.MAP,normalizeKeys:Ea,valueDefinition:{description:"",type:Ie.SHAPE,properties:N({},WT)}}}),fetchers:[XL,vo],resolvers:[ZL,$L,eT]},$9e=Z9e;var XT={};ft(XT,{default:()=>A_e});ws();var ba;(function(i){i.All="all",i.Production="production",i.Development="development"})(ba||(ba={}));var xo;(function(s){s.Info="info",s.Low="low",s.Moderate="moderate",s.High="high",s.Critical="critical"})(xo||(xo={}));var Fb=[xo.Info,xo.Low,xo.Moderate,xo.High,xo.Critical];function lue(r,e){let t=[],i=new Set,n=o=>{i.has(o)||(i.add(o),t.push(o))};for(let o of e)n(o);let s=new Set;for(;t.length>0;){let o=t.shift(),a=r.storedResolutions.get(o);if(typeof a=="undefined")throw new Error("Assertion failed: Expected the resolution to have been registered");let l=r.storedPackages.get(a);if(!!l){s.add(o);for(let c of l.dependencies.values())n(c.descriptorHash)}}return s}function e_e(r,e){return new Set([...r].filter(t=>!e.has(t)))}function t_e(r,e,{all:t}){let i=t?r.workspaces:[e],n=i.map(f=>f.manifest),s=new Set(n.map(f=>[...f.dependencies].map(([h,p])=>h)).flat()),o=new Set(n.map(f=>[...f.devDependencies].map(([h,p])=>h)).flat()),a=i.map(f=>[...f.dependencies.values()]).flat(),l=a.filter(f=>s.has(f.identHash)).map(f=>f.descriptorHash),c=a.filter(f=>o.has(f.identHash)).map(f=>f.descriptorHash),u=lue(r,l),g=lue(r,c);return e_e(g,u)}function cue(r){let e={};for(let t of r)e[P.stringifyIdent(t)]=P.parseRange(t.range).selector;return e}function uue(r){if(typeof r=="undefined")return new Set;let e=Fb.indexOf(r),t=Fb.slice(e);return new Set(t)}function r_e(r,e){let t=uue(e),i={};for(let n of t)i[n]=r[n];return i}function gue(r,e){var i;let t=r_e(r,e);for(let n of Object.keys(t))if((i=t[n])!=null?i:0>0)return!0;return!1}function fue(r,e){var s;let t={},i={children:t},n=Object.values(r.advisories);if(e!=null){let o=uue(e);n=n.filter(a=>o.has(a.severity))}for(let o of Se.sortMap(n,a=>a.module_name))t[o.module_name]={label:o.module_name,value:ae.tuple(ae.Type.RANGE,o.findings.map(a=>a.version).join(", ")),children:{Issue:{label:"Issue",value:ae.tuple(ae.Type.NO_HINT,o.title)},URL:{label:"URL",value:ae.tuple(ae.Type.URL,o.url)},Severity:{label:"Severity",value:ae.tuple(ae.Type.NO_HINT,o.severity)},["Vulnerable Versions"]:{label:"Vulnerable Versions",value:ae.tuple(ae.Type.RANGE,o.vulnerable_versions)},["Patched Versions"]:{label:"Patched Versions",value:ae.tuple(ae.Type.RANGE,o.patched_versions)},Via:{label:"Via",value:ae.tuple(ae.Type.NO_HINT,Array.from(new Set(o.findings.map(a=>a.paths).flat().map(a=>a.split(">")[0]))).join(", "))},Recommendation:{label:"Recommendation",value:ae.tuple(ae.Type.NO_HINT,(s=o.recommendation)==null?void 0:s.replace(/\n/g," "))}}};return i}function hue(r,e,{all:t,environment:i}){let n=t?r.workspaces:[e],s=[ba.All,ba.Production].includes(i),o=[];if(s)for(let c of n)for(let u of c.manifest.dependencies.values())o.push(u);let a=[ba.All,ba.Development].includes(i),l=[];if(a)for(let c of n)for(let u of c.manifest.devDependencies.values())l.push(u);return cue([...o,...l].filter(c=>P.parseRange(c.range).protocol===null))}function pue(r,e,{all:t}){var s;let i=t_e(r,e,{all:t}),n={};for(let o of r.storedPackages.values())n[P.stringifyIdent(o)]={version:(s=o.version)!=null?s:"0.0.0",integrity:o.identHash,requires:cue(o.dependencies.values()),dev:i.has(P.convertLocatorToDescriptor(o).descriptorHash)};return n}var oE=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Audit dependencies from all workspaces"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Audit transitive dependencies as well"});this.environment=J.String("--environment",ba.All,{description:"Which environments to cover",validator:nn(ba)});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.severity=J.String("--severity",xo.Info,{description:"Minimal severity requested for packages to be displayed",validator:nn(xo)})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let n=hue(t,i,{all:this.all,environment:this.environment}),s=pue(t,i,{all:this.all});if(!this.recursive)for(let f of Object.keys(s))Object.prototype.hasOwnProperty.call(n,f)?s[f].requires={}:delete s[f];let o={requires:n,dependencies:s},a=br.getAuditRegistry(i.manifest,{configuration:e}),l,c=await dA.start({configuration:e,stdout:this.context.stdout},async()=>{l=await zt.post("/-/npm/v1/security/audits/quick",o,{authType:zt.AuthType.BEST_EFFORT,configuration:e,jsonResponse:!0,registry:a})});if(c.hasErrors())return c.exitCode();let u=gue(l.metadata.vulnerabilities,this.severity);return!this.json&&u?(ls.emitTree(fue(l,this.severity),{configuration:e,json:this.json,stdout:this.context.stdout,separators:2}),1):(await Je.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async f=>{f.reportJson(l),u||f.reportInfo(X.EXCEPTION,"No audit suggestions")})).exitCode()}};oE.paths=[["npm","audit"]],oE.usage=Re.Usage({description:"perform a vulnerability audit against the installed packages",details:` - This command checks for known security reports on the packages you use. The reports are by default extracted from the npm registry, and may or may not be relevant to your actual program (not all vulnerabilities affect all code paths). - - For consistency with our other commands the default is to only check the direct dependencies for the active workspace. To extend this search to all workspaces, use \`-A,--all\`. To extend this search to both direct and transitive dependencies, use \`-R,--recursive\`. - - Applying the \`--severity\` flag will limit the audit table to vulnerabilities of the corresponding severity and above. Valid values are ${Fb.map(e=>`\`${e}\``).join(", ")}. - - If the \`--json\` flag is set, Yarn will print the output exactly as received from the registry. Regardless of this flag, the process will exit with a non-zero exit code if a report is found for the selected packages. - - To understand the dependency tree requiring vulnerable packages, check the raw report with the \`--json\` flag or use \`yarn why <package>\` to get more information as to who depends on them. - `,examples:[["Checks for known security issues with the installed packages. The output is a list of known issues.","yarn npm audit"],["Audit dependencies in all workspaces","yarn npm audit --all"],["Limit auditing to `dependencies` (excludes `devDependencies`)","yarn npm audit --environment production"],["Show audit report as valid JSON","yarn npm audit --json"],["Audit all direct and transitive dependencies","yarn npm audit --recursive"],["Output moderate (or more severe) vulnerabilities","yarn npm audit --severity moderate"]]});var due=oE;var zT=ge(ri()),_T=ge(require("util")),aE=class extends Le{constructor(){super(...arguments);this.fields=J.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.packages=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd),i=typeof this.fields!="undefined"?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,n=[],s=!1,o=await Je.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async a=>{for(let l of this.packages){let c;if(l==="."){let k=t.topLevelWorkspace;if(!k.manifest.name)throw new Pe(`Missing ${ae.pretty(e,"name",ae.Type.CODE)} field in ${H.fromPortablePath(x.join(k.cwd,xt.manifest))}`);c=P.makeDescriptor(k.manifest.name,"unknown")}else c=P.parseDescriptor(l);let u=zt.getIdentUrl(c),g=VT(await zt.get(u,{configuration:e,ident:c,jsonResponse:!0,customErrorMessage:zt.customPackageError})),f=Object.keys(g.versions).sort(zT.default.compareLoose),p=g["dist-tags"].latest||f[f.length-1],m=Wt.validRange(c.range);if(m){let k=zT.default.maxSatisfying(f,m);k!==null?p=k:(a.reportWarning(X.UNNAMED,`Unmet range ${P.prettyRange(e,c.range)}; falling back to the latest version`),s=!0)}else Object.prototype.hasOwnProperty.call(g["dist-tags"],c.range)?p=g["dist-tags"][c.range]:c.range!=="unknown"&&(a.reportWarning(X.UNNAMED,`Unknown tag ${P.prettyRange(e,c.range)}; falling back to the latest version`),s=!0);let y=g.versions[p],b=te(N(N({},g),y),{version:p,versions:f}),v;if(i!==null){v={};for(let k of i){let T=b[k];if(typeof T!="undefined")v[k]=T;else{a.reportWarning(X.EXCEPTION,`The ${ae.pretty(e,k,ae.Type.CODE)} field doesn't exist inside ${P.prettyIdent(e,c)}'s information`),s=!0;continue}}}else this.json||(delete b.dist,delete b.readme,delete b.users),v=b;a.reportJson(v),this.json||n.push(v)}});_T.inspect.styles.name="cyan";for(let a of n)(a!==n[0]||s)&&this.context.stdout.write(` -`),this.context.stdout.write(`${(0,_T.inspect)(a,{depth:Infinity,colors:!0,compact:!1})} -`);return o.exitCode()}};aE.paths=[["npm","info"]],aE.usage=Re.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command fetches information about a package from the npm registry and prints it in a tree format.\n\n The package does not have to be installed locally, but needs to have been published (in particular, local changes will be ignored even for workspaces).\n\n Append `@<range>` to the package argument to provide information specific to the latest version that satisfies the range or to the corresponding tagged version. If the range is invalid or if there is no version satisfying the range, the command will print a warning and fall back to the latest version.\n\n If the `-f,--fields` option is set, it's a comma-separated list of fields which will be used to only display part of the package information.\n\n By default, this command won't return the `dist`, `readme`, and `users` fields, since they are often very long. To explicitly request those fields, explicitly list them with the `--fields` flag or request the output in JSON mode.\n ",examples:[["Show all available information about react (except the `dist`, `readme`, and `users` fields)","yarn npm info react"],["Show all available information about react as valid JSON (including the `dist`, `readme`, and `users` fields)","yarn npm info react --json"],["Show all available information about react@16.12.0","yarn npm info react@16.12.0"],["Show all available information about react@next","yarn npm info react@next"],["Show the description of react","yarn npm info react --fields description"],["Show all available versions of react","yarn npm info react --fields versions"],["Show the readme of react","yarn npm info react --fields readme"],["Show a few fields of react","yarn npm info react --fields homepage,repository"]]});var Cue=aE;function VT(r){if(Array.isArray(r)){let e=[];for(let t of r)t=VT(t),t&&e.push(t);return e}else if(typeof r=="object"&&r!==null){let e={};for(let t of Object.keys(r)){if(t.startsWith("_"))continue;let i=VT(r[t]);i&&(e[t]=i)}return e}else return r||null}var mue=ge(zC()),AE=class extends Le{constructor(){super(...arguments);this.scope=J.String("-s,--scope",{description:"Login to the registry configured for a given scope"});this.publish=J.Boolean("--publish",!1,{description:"Login to the publish registry"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=await Nb({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{let s=await n_e({registry:t,report:n,stdin:this.context.stdin,stdout:this.context.stdout}),o=`/-/user/org.couchdb.user:${encodeURIComponent(s.name)}`,a=await zt.put(o,s,{attemptedAs:s.name,configuration:e,registry:t,jsonResponse:!0,authType:zt.AuthType.NO_AUTH});return await i_e(t,a.token,{configuration:e,scope:this.scope}),n.reportInfo(X.UNNAMED,"Successfully logged in")})).exitCode()}};AE.paths=[["npm","login"]],AE.usage=Re.Usage({category:"Npm-related commands",description:"store new login info to access the npm registry",details:"\n This command will ask you for your username, password, and 2FA One-Time-Password (when it applies). It will then modify your local configuration (in your home folder, never in the project itself) to reference the new tokens thus generated.\n\n Adding the `-s,--scope` flag will cause the authentication to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the authentication to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n ",examples:[["Login to the default registry","yarn npm login"],["Login to the registry linked to the @my-scope registry","yarn npm login --scope my-scope"],["Login to the publish registry for the current package","yarn npm login --publish"]]});var Eue=AE;async function Nb({scope:r,publish:e,configuration:t,cwd:i}){return r&&e?br.getScopeRegistry(r,{configuration:t,type:br.RegistryType.PUBLISH_REGISTRY}):r?br.getScopeRegistry(r,{configuration:t}):e?br.getPublishRegistry((await zf(t,i)).manifest,{configuration:t}):br.getDefaultRegistry({configuration:t})}async function i_e(r,e,{configuration:t,scope:i}){let n=o=>a=>{let l=Se.isIndexableObject(a)?a:{},c=l[o],u=Se.isIndexableObject(c)?c:{};return te(N({},l),{[o]:te(N({},u),{npmAuthToken:e})})},s=i?{npmScopes:n(i)}:{npmRegistries:n(r)};return await ye.updateHomeConfiguration(s)}async function n_e({registry:r,report:e,stdin:t,stdout:i}){if(process.env.TEST_ENV)return{name:process.env.TEST_NPM_USER||"",password:process.env.TEST_NPM_PASSWORD||""};e.reportInfo(X.UNNAMED,`Logging in to ${r}`);let n=!1;r.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(e.reportInfo(X.UNNAMED,"You seem to be using the GitHub Package Registry. Tokens must be generated with the 'repo', 'write:packages', and 'read:packages' permissions."),n=!0),e.reportSeparator();let{username:s,password:o}=await(0,mue.prompt)([{type:"input",name:"username",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:t,stdout:i},{type:"password",name:"password",message:n?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:t,stdout:i}]);return e.reportSeparator(),{name:s,password:o}}var bh=new Set(["npmAuthIdent","npmAuthToken"]),lE=class extends Le{constructor(){super(...arguments);this.scope=J.String("-s,--scope",{description:"Logout of the registry configured for a given scope"});this.publish=J.Boolean("--publish",!1,{description:"Logout of the publish registry"});this.all=J.Boolean("-A,--all",!1,{description:"Logout of all registries"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=async()=>{var l;let n=await Nb({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),s=await ye.find(this.context.cwd,this.context.plugins),o=P.makeIdent((l=this.scope)!=null?l:null,"pkg");return!br.getAuthConfiguration(n,{configuration:s,ident:o}).get("npmAuthToken")};return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{if(this.all&&(await s_e(),n.reportInfo(X.UNNAMED,"Successfully logged out from everything")),this.scope){await Iue("npmScopes",this.scope),await t()?n.reportInfo(X.UNNAMED,`Successfully logged out from ${this.scope}`):n.reportWarning(X.UNNAMED,"Scope authentication settings removed, but some other ones settings still apply to it");return}let s=await Nb({configuration:e,cwd:this.context.cwd,publish:this.publish});await Iue("npmRegistries",s),await t()?n.reportInfo(X.UNNAMED,`Successfully logged out from ${s}`):n.reportWarning(X.UNNAMED,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}};lE.paths=[["npm","logout"]],lE.usage=Re.Usage({category:"Npm-related commands",description:"logout of the npm registry",details:"\n This command will log you out by modifying your local configuration (in your home folder, never in the project itself) to delete all credentials linked to a registry.\n\n Adding the `-s,--scope` flag will cause the deletion to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the deletion to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n\n Adding the `-A,--all` flag will cause the deletion to be done against all registries and scopes.\n ",examples:[["Logout of the default registry","yarn npm logout"],["Logout of the @my-scope scope","yarn npm logout --scope my-scope"],["Logout of the publish registry for the current package","yarn npm logout --publish"],["Logout of all registries","yarn npm logout --all"]]});var yue=lE;function o_e(r,e){let t=r[e];if(!Se.isIndexableObject(t))return!1;let i=new Set(Object.keys(t));if([...bh].every(s=>!i.has(s)))return!1;for(let s of bh)i.delete(s);if(i.size===0)return r[e]=void 0,!0;let n=N({},t);for(let s of bh)delete n[s];return r[e]=n,!0}async function s_e(){let r=e=>{let t=!1,i=Se.isIndexableObject(e)?N({},e):{};i.npmAuthToken&&(delete i.npmAuthToken,t=!0);for(let n of Object.keys(i))o_e(i,n)&&(t=!0);if(Object.keys(i).length!==0)return t?i:e};return await ye.updateHomeConfiguration({npmRegistries:r,npmScopes:r})}async function Iue(r,e){return await ye.updateHomeConfiguration({[r]:t=>{let i=Se.isIndexableObject(t)?t:{};if(!Object.prototype.hasOwnProperty.call(i,e))return t;let n=i[e],s=Se.isIndexableObject(n)?n:{},o=new Set(Object.keys(s));if([...bh].every(l=>!o.has(l)))return t;for(let l of bh)o.delete(l);if(o.size===0)return Object.keys(i).length===1?void 0:te(N({},i),{[e]:void 0});let a={};for(let l of bh)a[l]=void 0;return te(N({},i),{[e]:N(N({},s),a)})}})}var cE=class extends Le{constructor(){super(...arguments);this.access=J.String("--access",{description:"The access for the published package (public or restricted)"});this.tag=J.String("--tag","latest",{description:"The tag on the registry that the package should be attached to"});this.tolerateRepublish=J.Boolean("--tolerate-republish",!1,{description:"Warn and exit when republishing an already existing version of a package"});this.otp=J.String("--otp",{description:"The OTP token to use with the command"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);if(i.manifest.private)throw new Pe("Private workspaces cannot be published");if(i.manifest.name===null||i.manifest.version===null)throw new Pe("Workspaces must have valid names and versions to be published on an external registry");await t.restoreInstallState();let n=i.manifest.name,s=i.manifest.version,o=br.getPublishRegistry(i.manifest,{configuration:e});return(await Je.start({configuration:e,stdout:this.context.stdout},async l=>{var c,u;if(this.tolerateRepublish)try{let g=await zt.get(zt.getIdentUrl(n),{configuration:e,registry:o,ident:n,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(g,"versions"))throw new ct(X.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(Object.prototype.hasOwnProperty.call(g.versions,s)){l.reportWarning(X.UNNAMED,`Registry already knows about version ${s}; skipping.`);return}}catch(g){if(((u=(c=g.originalError)==null?void 0:c.response)==null?void 0:u.statusCode)!==404)throw g}await Zt.maybeExecuteWorkspaceLifecycleScript(i,"prepublish",{report:l}),await DA.prepareForPack(i,{report:l},async()=>{let g=await DA.genPackList(i);for(let y of g)l.reportInfo(null,y);let f=await DA.genPackStream(i,g),h=await Se.bufferStream(f),p=await Bh.getGitHead(i.cwd),m=await Bh.makePublishBody(i,h,{access:this.access,tag:this.tag,registry:o,gitHead:p});await zt.put(zt.getIdentUrl(n),m,{configuration:e,registry:o,ident:n,otp:this.otp,jsonResponse:!0})}),l.reportInfo(X.UNNAMED,"Package archive published")})).exitCode()}};cE.paths=[["npm","publish"]],cE.usage=Re.Usage({category:"Npm-related commands",description:"publish the active workspace to the npm registry",details:'\n This command will pack the active workspace into a fresh archive and upload it to the npm registry.\n\n The package will by default be attached to the `latest` tag on the registry, but this behavior can be overriden by using the `--tag` option.\n\n Note that for legacy reasons scoped packages are by default published with an access set to `restricted` (aka "private packages"). This requires you to register for a paid npm plan. In case you simply wish to publish a public scoped package to the registry (for free), just add the `--access public` flag. This behavior can be enabled by default through the `npmPublishAccess` settings.\n ',examples:[["Publish the active workspace","yarn npm publish"]]});var wue=cE;var bue=ge(ri());var uE=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=J.String({required:!1})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n;if(typeof this.package!="undefined")n=P.parseIdent(this.package);else{if(!i)throw new ht(t.cwd,this.context.cwd);if(!i.manifest.name)throw new Pe(`Missing 'name' field in ${H.fromPortablePath(x.join(i.cwd,xt.manifest))}`);n=i.manifest.name}let s=await gE(n,e),a={children:Se.sortMap(Object.entries(s),([l])=>l).map(([l,c])=>({value:ae.tuple(ae.Type.RESOLUTION,{descriptor:P.makeDescriptor(n,l),locator:P.makeLocator(n,c)})}))};return ls.emitTree(a,{configuration:e,json:this.json,stdout:this.context.stdout})}};uE.paths=[["npm","tag","list"]],uE.usage=Re.Usage({category:"Npm-related commands",description:"list all dist-tags of a package",details:` - This command will list all tags of a package from the npm registry. - - If the package is not specified, Yarn will default to the current workspace. - `,examples:[["List all tags of package `my-pkg`","yarn npm tag list my-pkg"]]});var Bue=uE;async function gE(r,e){let t=`/-/package${zt.getIdentUrl(r)}/dist-tags`;return zt.get(t,{configuration:e,ident:r,jsonResponse:!0,customErrorMessage:zt.customPackageError})}var fE=class extends Le{constructor(){super(...arguments);this.package=J.String();this.tag=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);let n=P.parseDescriptor(this.package,!0),s=n.range;if(!bue.default.valid(s))throw new Pe(`The range ${ae.pretty(e,n.range,ae.Type.RANGE)} must be a valid semver version`);let o=br.getPublishRegistry(i.manifest,{configuration:e}),a=ae.pretty(e,n,ae.Type.IDENT),l=ae.pretty(e,s,ae.Type.RANGE),c=ae.pretty(e,this.tag,ae.Type.CODE);return(await Je.start({configuration:e,stdout:this.context.stdout},async g=>{let f=await gE(n,e);Object.prototype.hasOwnProperty.call(f,this.tag)&&f[this.tag]===s&&g.reportWarning(X.UNNAMED,`Tag ${c} is already set to version ${l}`);let h=`/-/package${zt.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await zt.put(h,s,{configuration:e,registry:o,ident:n,jsonRequest:!0,jsonResponse:!0}),g.reportInfo(X.UNNAMED,`Tag ${c} added to version ${l} of package ${a}`)})).exitCode()}};fE.paths=[["npm","tag","add"]],fE.usage=Re.Usage({category:"Npm-related commands",description:"add a tag for a specific version of a package",details:` - This command will add a tag to the npm registry for a specific version of a package. If the tag already exists, it will be overwritten. - `,examples:[["Add a `beta` tag for version `2.3.4-beta.4` of package `my-pkg`","yarn npm tag add my-pkg@2.3.4-beta.4 beta"]]});var Que=fE;var hE=class extends Le{constructor(){super(...arguments);this.package=J.String();this.tag=J.String()}async execute(){if(this.tag==="latest")throw new Pe("The 'latest' tag cannot be removed.");let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);let n=P.parseIdent(this.package),s=br.getPublishRegistry(i.manifest,{configuration:e}),o=ae.pretty(e,this.tag,ae.Type.CODE),a=ae.pretty(e,n,ae.Type.IDENT),l=await gE(n,e);if(!Object.prototype.hasOwnProperty.call(l,this.tag))throw new Pe(`${o} is not a tag of package ${a}`);return(await Je.start({configuration:e,stdout:this.context.stdout},async u=>{let g=`/-/package${zt.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await zt.del(g,{configuration:e,registry:s,ident:n,jsonResponse:!0}),u.reportInfo(X.UNNAMED,`Tag ${o} removed from package ${a}`)})).exitCode()}};hE.paths=[["npm","tag","remove"]],hE.usage=Re.Usage({category:"Npm-related commands",description:"remove a tag from a package",details:` - This command will remove a tag from a package from the npm registry. - `,examples:[["Remove the `beta` tag from package `my-pkg`","yarn npm tag remove my-pkg beta"]]});var Sue=hE;var pE=class extends Le{constructor(){super(...arguments);this.scope=J.String("-s,--scope",{description:"Print username for the registry configured for a given scope"});this.publish=J.Boolean("--publish",!1,{description:"Print username for the publish registry"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t;return this.scope&&this.publish?t=br.getScopeRegistry(this.scope,{configuration:e,type:br.RegistryType.PUBLISH_REGISTRY}):this.scope?t=br.getScopeRegistry(this.scope,{configuration:e}):this.publish?t=br.getPublishRegistry((await zf(e,this.context.cwd)).manifest,{configuration:e}):t=br.getDefaultRegistry({configuration:e}),(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{var o,a;let s;try{s=await zt.get("/-/whoami",{configuration:e,registry:t,authType:zt.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?P.makeIdent(this.scope,""):void 0})}catch(l){if(((o=l.response)==null?void 0:o.statusCode)===401||((a=l.response)==null?void 0:a.statusCode)===403){n.reportError(X.AUTHENTICATION_INVALID,"Authentication failed - your credentials may have expired");return}else throw l}n.reportInfo(X.UNNAMED,s.username)})).exitCode()}};pE.paths=[["npm","whoami"]],pE.usage=Re.Usage({category:"Npm-related commands",description:"display the name of the authenticated user",details:"\n Print the username associated with the current authentication settings to the standard output.\n\n When using `-s,--scope`, the username printed will be the one that matches the authentication settings of the registry associated with the given scope (those settings can be overriden using the `npmRegistries` map, and the registry associated with the scope is configured via the `npmScopes` map).\n\n When using `--publish`, the registry we'll select will by default be the one used when publishing packages (`publishConfig.registry` or `npmPublishRegistry` if available, otherwise we'll fallback to the regular `npmRegistryServer`).\n ",examples:[["Print username for the default registry","yarn npm whoami"],["Print username for the registry on a given scope","yarn npm whoami --scope company"]]});var vue=pE;var a_e={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:Ie.STRING,default:null}},commands:[due,Cue,Eue,yue,wue,Que,Bue,Sue,vue]},A_e=a_e;var AO={};ft(AO,{default:()=>B_e,patchUtils:()=>ZT});var ZT={};ft(ZT,{applyPatchFile:()=>Ob,diffFolders:()=>sO,ensureUnpatchedDescriptor:()=>eO,extractPackageToDisk:()=>nO,extractPatchFlags:()=>Nue,isParentRequired:()=>iO,loadPatchFiles:()=>EE,makeDescriptor:()=>tO,makeLocator:()=>rO,parseDescriptor:()=>CE,parseLocator:()=>mE,parsePatchFile:()=>Tb});var dE=class extends Error{constructor(e,t){super(`Cannot apply hunk #${e+1}`);this.hunk=t}};var l_e=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function Qh(r){return x.relative(Me.root,x.resolve(Me.root,H.toPortablePath(r)))}function c_e(r){let e=r.trim().match(l_e);if(!e)throw new Error(`Bad header line: '${r}'`);return{original:{start:Math.max(Number(e[1]),1),length:Number(e[3]||1)},patched:{start:Math.max(Number(e[4]),1),length:Number(e[6]||1)}}}var u_e=420,g_e=493,Zr;(function(i){i.Context="context",i.Insertion="insertion",i.Deletion="deletion"})(Zr||(Zr={}));var kue=()=>({semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null}),f_e=r=>({header:c_e(r),parts:[]}),h_e={["@"]:"header",["-"]:Zr.Deletion,["+"]:Zr.Insertion,[" "]:Zr.Context,["\\"]:"pragma",undefined:Zr.Context};function d_e(r){let e=[],t=kue(),i="parsing header",n=null,s=null;function o(){n&&(s&&(n.parts.push(s),s=null),t.hunks.push(n),n=null)}function a(){o(),e.push(t),t=kue()}for(let l=0;l<r.length;l++){let c=r[l];if(i==="parsing header")if(c.startsWith("@@"))i="parsing hunks",t.hunks=[],l-=1;else if(c.startsWith("diff --git ")){t&&t.diffLineFromPath&&a();let u=c.match(/^diff --git a\/(.*?) b\/(.*?)\s*$/);if(!u)throw new Error(`Bad diff line: ${c}`);t.diffLineFromPath=u[1],t.diffLineToPath=u[2]}else if(c.startsWith("old mode "))t.oldMode=c.slice("old mode ".length).trim();else if(c.startsWith("new mode "))t.newMode=c.slice("new mode ".length).trim();else if(c.startsWith("deleted file mode "))t.deletedFileMode=c.slice("deleted file mode ".length).trim();else if(c.startsWith("new file mode "))t.newFileMode=c.slice("new file mode ".length).trim();else if(c.startsWith("rename from "))t.renameFrom=c.slice("rename from ".length).trim();else if(c.startsWith("rename to "))t.renameTo=c.slice("rename to ".length).trim();else if(c.startsWith("index ")){let u=c.match(/(\w+)\.\.(\w+)/);if(!u)continue;t.beforeHash=u[1],t.afterHash=u[2]}else c.startsWith("semver exclusivity ")?t.semverExclusivity=c.slice("semver exclusivity ".length).trim():c.startsWith("--- ")?t.fromPath=c.slice("--- a/".length).trim():c.startsWith("+++ ")&&(t.toPath=c.slice("+++ b/".length).trim());else{let u=h_e[c[0]]||null;switch(u){case"header":o(),n=f_e(c);break;case null:i="parsing header",a(),l-=1;break;case"pragma":{if(!c.startsWith("\\ No newline at end of file"))throw new Error(`Unrecognized pragma in patch file: ${c}`);if(!s)throw new Error("Bad parser state: No newline at EOF pragma encountered without context");s.noNewlineAtEndOfFile=!0}break;case Zr.Context:case Zr.Deletion:case Zr.Insertion:{if(!n)throw new Error("Bad parser state: Hunk lines encountered before hunk header");s&&s.type!==u&&(n.parts.push(s),s=null),s||(s={type:u,lines:[],noNewlineAtEndOfFile:!1}),s.lines.push(c.slice(1))}break;default:Se.assertNever(u);break}}}a();for(let{hunks:l}of e)if(l)for(let c of l)p_e(c);return e}function C_e(r){let e=[];for(let t of r){let{semverExclusivity:i,diffLineFromPath:n,diffLineToPath:s,oldMode:o,newMode:a,deletedFileMode:l,newFileMode:c,renameFrom:u,renameTo:g,beforeHash:f,afterHash:h,fromPath:p,toPath:m,hunks:y}=t,b=u?"rename":l?"file deletion":c?"file creation":y&&y.length>0?"patch":"mode change",v=null;switch(b){case"rename":{if(!u||!g)throw new Error("Bad parser state: rename from & to not given");e.push({type:"rename",semverExclusivity:i,fromPath:Qh(u),toPath:Qh(g)}),v=g}break;case"file deletion":{let k=n||p;if(!k)throw new Error("Bad parse state: no path given for file deletion");e.push({type:"file deletion",semverExclusivity:i,hunk:y&&y[0]||null,path:Qh(k),mode:Lb(l),hash:f})}break;case"file creation":{let k=s||m;if(!k)throw new Error("Bad parse state: no path given for file creation");e.push({type:"file creation",semverExclusivity:i,hunk:y&&y[0]||null,path:Qh(k),mode:Lb(c),hash:h})}break;case"patch":case"mode change":v=m||s;break;default:Se.assertNever(b);break}v&&o&&a&&o!==a&&e.push({type:"mode change",semverExclusivity:i,path:Qh(v),oldMode:Lb(o),newMode:Lb(a)}),v&&y&&y.length&&e.push({type:"patch",semverExclusivity:i,path:Qh(v),hunks:y,beforeHash:f,afterHash:h})}if(e.length===0)throw new Error("Unable to parse patch file: No changes found. Make sure the patch is a valid UTF8 encoded string");return e}function Lb(r){let e=parseInt(r,8)&511;if(e!==u_e&&e!==g_e)throw new Error(`Unexpected file mode string: ${r}`);return e}function Tb(r){let e=r.split(/\n/g);return e[e.length-1]===""&&e.pop(),C_e(d_e(e))}function p_e(r){let e=0,t=0;for(let{type:i,lines:n}of r.parts)switch(i){case Zr.Context:t+=n.length,e+=n.length;break;case Zr.Deletion:e+=n.length;break;case Zr.Insertion:t+=n.length;break;default:Se.assertNever(i);break}if(e!==r.header.original.length||t!==r.header.patched.length){let i=n=>n<0?n:`+${n}`;throw new Error(`hunk header integrity check failed (expected @@ ${i(r.header.original.length)} ${i(r.header.patched.length)} @@, got @@ ${i(e)} ${i(t)} @@)`)}}async function Sh(r,e,t){let i=await r.lstatPromise(e),n=await t();if(typeof n!="undefined"&&(e=n),r.lutimesPromise)await r.lutimesPromise(e,i.atime,i.mtime);else if(!i.isSymbolicLink())await r.utimesPromise(e,i.atime,i.mtime);else throw new Error("Cannot preserve the time values of a symlink")}async function Ob(r,{baseFs:e=new ar,dryRun:t=!1,version:i=null}={}){for(let n of r)if(!(n.semverExclusivity!==null&&i!==null&&!Wt.satisfiesWithPrereleases(i,n.semverExclusivity)))switch(n.type){case"file deletion":if(t){if(!e.existsSync(n.path))throw new Error(`Trying to delete a file that doesn't exist: ${n.path}`)}else await Sh(e,x.dirname(n.path),async()=>{await e.unlinkPromise(n.path)});break;case"rename":if(t){if(!e.existsSync(n.fromPath))throw new Error(`Trying to move a file that doesn't exist: ${n.fromPath}`)}else await Sh(e,x.dirname(n.fromPath),async()=>{await Sh(e,x.dirname(n.toPath),async()=>{await Sh(e,n.fromPath,async()=>(await e.movePromise(n.fromPath,n.toPath),n.toPath))})});break;case"file creation":if(t){if(e.existsSync(n.path))throw new Error(`Trying to create a file that already exists: ${n.path}`)}else{let s=n.hunk?n.hunk.parts[0].lines.join(` -`)+(n.hunk.parts[0].noNewlineAtEndOfFile?"":` -`):"";await e.mkdirpPromise(x.dirname(n.path),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),await e.writeFilePromise(n.path,s,{mode:n.mode}),await e.utimesPromise(n.path,Rr.SAFE_TIME,Rr.SAFE_TIME)}break;case"patch":await Sh(e,n.path,async()=>{await m_e(n,{baseFs:e,dryRun:t})});break;case"mode change":{let o=(await e.statPromise(n.path)).mode;if(xue(n.newMode)!==xue(o))continue;await Sh(e,n.path,async()=>{await e.chmodPromise(n.path,n.newMode)})}break;default:Se.assertNever(n);break}}function xue(r){return(r&64)>0}function Pue(r){return r.replace(/\s+$/,"")}function E_e(r,e){return Pue(r)===Pue(e)}async function m_e({hunks:r,path:e},{baseFs:t,dryRun:i=!1}){let n=await t.statSync(e).mode,o=(await t.readFileSync(e,"utf8")).split(/\n/),a=[],l=0,c=0;for(let g of r){let f=Math.max(c,g.header.patched.start+l),h=Math.max(0,f-c),p=Math.max(0,o.length-f-g.header.original.length),m=Math.max(h,p),y=0,b=0,v=null;for(;y<=m;){if(y<=h&&(b=f-y,v=Due(g,o,b),v!==null)){y=-y;break}if(y<=p&&(b=f+y,v=Due(g,o,b),v!==null))break;y+=1}if(v===null)throw new dE(r.indexOf(g),g);a.push(v),l+=y,c=b+g.header.original.length}if(i)return;let u=0;for(let g of a)for(let f of g)switch(f.type){case"splice":{let h=f.index+u;o.splice(h,f.numToDelete,...f.linesToInsert),u+=f.linesToInsert.length-f.numToDelete}break;case"pop":o.pop();break;case"push":o.push(f.line);break;default:Se.assertNever(f);break}await t.writeFilePromise(e,o.join(` -`),{mode:n})}function Due(r,e,t){let i=[];for(let n of r.parts)switch(n.type){case Zr.Context:case Zr.Deletion:{for(let s of n.lines){let o=e[t];if(o==null||!E_e(o,s))return null;t+=1}n.type===Zr.Deletion&&(i.push({type:"splice",index:t-n.lines.length,numToDelete:n.lines.length,linesToInsert:[]}),n.noNewlineAtEndOfFile&&i.push({type:"push",line:""}))}break;case Zr.Insertion:i.push({type:"splice",index:t,numToDelete:0,linesToInsert:n.lines}),n.noNewlineAtEndOfFile&&i.push({type:"pop"});break;default:Se.assertNever(n.type);break}return i}var I_e=/^builtin<([^>]+)>$/;function $T(r,e){let{source:t,selector:i,params:n}=P.parseRange(r);if(t===null)throw new Error("Patch locators must explicitly define their source");let s=i?i.split(/&/).map(c=>H.toPortablePath(c)):[],o=n&&typeof n.locator=="string"?P.parseLocator(n.locator):null,a=n&&typeof n.version=="string"?n.version:null,l=e(t);return{parentLocator:o,sourceItem:l,patchPaths:s,sourceVersion:a}}function CE(r){let i=$T(r.range,P.parseDescriptor),{sourceItem:e}=i,t=Or(i,["sourceItem"]);return te(N({},t),{sourceDescriptor:e})}function mE(r){let i=$T(r.reference,P.parseLocator),{sourceItem:e}=i,t=Or(i,["sourceItem"]);return te(N({},t),{sourceLocator:e})}function eO(r){if(!r.range.startsWith("patch:"))return r;let{sourceItem:e}=$T(r.range,P.parseDescriptor);return e}function Rue({parentLocator:r,sourceItem:e,patchPaths:t,sourceVersion:i,patchHash:n},s){let o=r!==null?{locator:P.stringifyLocator(r)}:{},a=typeof i!="undefined"?{version:i}:{},l=typeof n!="undefined"?{hash:n}:{};return P.makeRange({protocol:"patch:",source:s(e),selector:t.join("&"),params:N(N(N({},a),l),o)})}function tO(r,{parentLocator:e,sourceDescriptor:t,patchPaths:i}){return P.makeDescriptor(r,Rue({parentLocator:e,sourceItem:t,patchPaths:i},P.stringifyDescriptor))}function rO(r,{parentLocator:e,sourcePackage:t,patchPaths:i,patchHash:n}){return P.makeLocator(r,Rue({parentLocator:e,sourceItem:t,sourceVersion:t.version,patchPaths:i,patchHash:n},P.stringifyLocator))}function Fue({onAbsolute:r,onRelative:e,onBuiltin:t},i){i.startsWith("~")&&(i=i.slice(1));let s=i.match(I_e);return s!==null?t(s[1]):x.isAbsolute(i)?r(i):e(i)}function Nue(r){let e=r.startsWith("~");return e&&(r=r.slice(1)),{optional:e}}function iO(r){return Fue({onAbsolute:()=>!1,onRelative:()=>!0,onBuiltin:()=>!1},r)}async function EE(r,e,t){let i=r!==null?await t.fetcher.fetch(r,t):null,n=i&&i.localPath?{packageFs:new _t(Me.root),prefixPath:x.relative(Me.root,i.localPath)}:i;i&&i!==n&&i.releaseFs&&i.releaseFs();let s=await Se.releaseAfterUseAsync(async()=>await Promise.all(e.map(async o=>{let a=Nue(o),l=await Fue({onAbsolute:async()=>await U.readFilePromise(o,"utf8"),onRelative:async()=>{if(n===null)throw new Error("Assertion failed: The parent locator should have been fetched");return await n.packageFs.readFilePromise(x.join(n.prefixPath,o),"utf8")},onBuiltin:async c=>await t.project.configuration.firstHook(u=>u.getBuiltinPatch,t.project,c)},o);return te(N({},a),{source:l})})));for(let o of s)typeof o.source=="string"&&(o.source=o.source.replace(/\r\n?/g,` -`));return s}async function nO(r,{cache:e,project:t}){let i=t.storedPackages.get(r.locatorHash);if(typeof i=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let n=t.storedChecksums,s=new di,o=t.configuration.makeFetcher(),a=await o.fetch(r,{cache:e,project:t,fetcher:o,checksums:n,report:s}),l=await U.mktempPromise(),c=x.join(l,"source"),u=x.join(l,"user"),g=x.join(l,".yarn-patch.json");return await Promise.all([U.copyPromise(c,a.prefixPath,{baseFs:a.packageFs}),U.copyPromise(u,a.prefixPath,{baseFs:a.packageFs}),U.writeJsonPromise(g,{locator:P.stringifyLocator(r),version:i.version})]),U.detachTemp(l),u}async function sO(r,e){let t=H.fromPortablePath(r).replace(/\\/g,"/"),i=H.fromPortablePath(e).replace(/\\/g,"/"),{stdout:n,stderr:s}=await Nr.execvp("git",["-c","core.safecrlf=false","diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index","--no-renames","--text",t,i],{cwd:H.toPortablePath(process.cwd()),env:te(N({},process.env),{GIT_CONFIG_NOSYSTEM:"1",HOME:"",XDG_CONFIG_HOME:"",USERPROFILE:""})});if(s.length>0)throw new Error(`Unable to diff directories. Make sure you have a recent version of 'git' available in PATH. -The following error was reported by 'git': -${s}`);let o=t.startsWith("/")?a=>a.slice(1):a=>a;return n.replace(new RegExp(`(a|b)(${Se.escapeRegExp(`/${o(t)}/`)})`,"g"),"$1/").replace(new RegExp(`(a|b)${Se.escapeRegExp(`/${o(i)}/`)}`,"g"),"$1/").replace(new RegExp(Se.escapeRegExp(`${t}/`),"g"),"").replace(new RegExp(Se.escapeRegExp(`${i}/`),"g"),"")}function Lue(r,{configuration:e,report:t}){for(let i of r.parts)for(let n of i.lines)switch(i.type){case Zr.Context:t.reportInfo(null,` ${ae.pretty(e,n,"grey")}`);break;case Zr.Deletion:t.reportError(X.FROZEN_LOCKFILE_EXCEPTION,`- ${ae.pretty(e,n,ae.Type.REMOVED)}`);break;case Zr.Insertion:t.reportError(X.FROZEN_LOCKFILE_EXCEPTION,`+ ${ae.pretty(e,n,ae.Type.ADDED)}`);break;default:Se.assertNever(i.type)}}var oO=class{supports(e,t){return!!e.reference.startsWith("patch:")}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.patchPackage(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async patchPackage(e,t){let{parentLocator:i,sourceLocator:n,sourceVersion:s,patchPaths:o}=mE(e),a=await EE(i,o,t),l=await U.mktempPromise(),c=x.join(l,"current.zip"),u=await t.fetcher.fetch(n,t),g=P.getIdentVendorPath(e),f=await fn(),h=new li(c,{libzip:f,create:!0,level:t.project.configuration.get("compressionLevel")});await Se.releaseAfterUseAsync(async()=>{await h.copyPromise(g,u.prefixPath,{baseFs:u.packageFs,stableSort:!0})},u.releaseFs),h.saveAndClose();for(let{source:p,optional:m}of a){if(p===null)continue;let y=new li(c,{libzip:f,level:t.project.configuration.get("compressionLevel")}),b=new _t(x.resolve(Me.root,g),{baseFs:y});try{await Ob(Tb(p),{baseFs:b,version:s})}catch(v){if(!(v instanceof dE))throw v;let k=t.project.configuration.get("enableInlineHunks"),T=!k&&!m?" (set enableInlineHunks for details)":"",Y=`${P.prettyLocator(t.project.configuration,e)}: ${v.message}${T}`,q=$=>{!k||Lue(v.hunk,{configuration:t.project.configuration,report:$})};if(y.discardAndClose(),m){t.report.reportWarningOnce(X.PATCH_HUNK_FAILED,Y,{reportExtra:q});continue}else throw new ct(X.PATCH_HUNK_FAILED,Y,q)}y.saveAndClose()}return new li(c,{libzip:f,level:t.project.configuration.get("compressionLevel")})}};var y_e=3,aO=class{supportsDescriptor(e,t){return!!e.range.startsWith("patch:")}supportsLocator(e,t){return!!e.reference.startsWith("patch:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){let{patchPaths:n}=CE(e);return n.every(s=>!iO(s))?e:P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){let{sourceDescriptor:i}=CE(e);return[i]}async getCandidates(e,t,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{parentLocator:n,sourceDescriptor:s,patchPaths:o}=CE(e),a=await EE(n,o,i.fetchOptions),l=t.get(s.descriptorHash);if(typeof l=="undefined")throw new Error("Assertion failed: The dependency should have been resolved");let c=Rn.makeHash(`${y_e}`,...a.map(u=>JSON.stringify(u))).slice(0,6);return[rO(e,{parentLocator:n,sourcePackage:l,patchPaths:o,patchHash:c})]}async getSatisfying(e,t,i){return null}async resolve(e,t){let{sourceLocator:i}=mE(e),n=await t.resolver.resolve(i,t);return N(N({},n),e)}};var IE=class extends Le{constructor(){super(...arguments);this.save=J.Boolean("-s,--save",!1,{description:"Add the patch to your resolution entries"});this.patchFolder=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let n=x.resolve(this.context.cwd,H.toPortablePath(this.patchFolder)),s=x.join(n,"../source"),o=x.join(n,"../.yarn-patch.json");if(!U.existsSync(s))throw new Pe("The argument folder didn't get created by 'yarn patch'");let a=await sO(s,n),l=await U.readJsonPromise(o),c=P.parseLocator(l.locator,!0);if(!t.storedPackages.has(c.locatorHash))throw new Pe("No package found in the project for the given locator");if(!this.save){this.context.stdout.write(a);return}let u=e.get("patchFolder"),g=x.join(u,`${P.slugifyLocator(c)}.patch`);await U.mkdirPromise(u,{recursive:!0}),await U.writeFilePromise(g,a);let f=new Map;for(let h of t.storedPackages.values()){if(P.isVirtualLocator(h))continue;let p=h.dependencies.get(c.identHash);if(!p)continue;let m=P.isVirtualDescriptor(p)?P.devirtualizeDescriptor(p):p,y=eO(m),b=t.storedResolutions.get(y.descriptorHash);if(!b)throw new Error("Assertion failed: Expected the resolution to have been registered");if(!t.storedPackages.get(b))throw new Error("Assertion failed: Expected the package to have been registered");let k=t.originalPackages.get(h.locatorHash);if(!k)throw new Error("Assertion failed: Expected the original package to have been registered");let T=k.dependencies.get(p.identHash);if(!T)throw new Error("Assertion failed: Expected the original dependency to have been registered");f.set(T.descriptorHash,T)}for(let h of f.values()){let p=tO(h,{parentLocator:null,sourceDescriptor:P.convertLocatorToDescriptor(c),sourceVersion:null,patchPaths:[`./${x.relative(t.cwd,g)}`]});t.topLevelWorkspace.manifest.resolutions.push({pattern:{descriptor:{fullName:P.stringifyIdent(p),description:h.range}},reference:p.range})}await t.persist()}};IE.paths=[["patch-commit"]],IE.usage=Re.Usage({description:"generate a patch out of a directory",details:"\n By default, this will print a patchfile on stdout based on the diff between the folder passed in and the original version of the package. Such file is suitable for consumption with the `patch:` protocol.\n\n With the `-s,--save` option set, the patchfile won't be printed on stdout anymore and will instead be stored within a local file (by default kept within `.yarn/patches`, but configurable via the `patchFolder` setting). A `resolutions` entry will also be added to your top-level manifest, referencing the patched package via the `patch:` protocol.\n\n Note that only folders generated by `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "});var Tue=IE;var yE=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let s=P.parseLocator(this.package);if(s.reference==="unknown"){let o=Se.mapAndFilter([...t.storedPackages.values()],a=>a.identHash!==s.identHash?Se.mapAndFilter.skip:P.isVirtualLocator(a)?Se.mapAndFilter.skip:a);if(o.length===0)throw new Pe("No package found in the project for the given locator");if(o.length>1)throw new Pe(`Multiple candidate packages found; explicitly choose one of them (use \`yarn why <package>\` to get more information as to who depends on them): -${o.map(a=>` -- ${P.prettyLocator(e,a)}`).join("")}`);s=o[0]}if(!t.storedPackages.has(s.locatorHash))throw new Pe("No package found in the project for the given locator");await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async o=>{let a=await nO(s,{cache:n,project:t});o.reportJson({locator:P.stringifyLocator(s),path:H.fromPortablePath(a)}),o.reportInfo(X.UNNAMED,`Package ${P.prettyLocator(e,s)} got extracted with success!`),o.reportInfo(X.UNNAMED,`You can now edit the following folder: ${ae.pretty(e,H.fromPortablePath(a),"magenta")}`),o.reportInfo(X.UNNAMED,`Once you are done run ${ae.pretty(e,`yarn patch-commit -s ${process.platform==="win32"?'"':""}${H.fromPortablePath(a)}${process.platform==="win32"?'"':""}`,"cyan")} and Yarn will store a patchfile based on your changes.`)})}};yE.paths=[["patch"]],yE.usage=Re.Usage({description:"prepare a package for patching",details:"\n This command will cause a package to be extracted in a temporary directory intended to be editable at will.\n \n Once you're done with your changes, run `yarn patch-commit -s <path>` (with `<path>` being the temporary directory you received) to generate a patchfile and register it into your top-level manifest via the `patch:` protocol. Run `yarn patch-commit -h` for more details.\n "});var Oue=yE;var w_e={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:Ie.BOOLEAN,default:!1},patchFolder:{description:"Folder where the patch files must be written",type:Ie.ABSOLUTE_PATH,default:"./.yarn/patches"}},commands:[Tue,Oue],fetchers:[oO],resolvers:[aO]},B_e=w_e;var gO={};ft(gO,{default:()=>S_e});var lO=class{supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the pnpm linker to be enabled");let i=cO(),n=t.project.installersCustomData.get(i);if(!n)throw new Pe(`The project in ${ae.pretty(t.project.configuration,`${t.project.cwd}/package.json`,ae.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let s=n.pathByLocator.get(e.locatorHash);if(typeof s=="undefined")throw new Pe(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed pnpm map - running an install might help`);return s}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=cO(),n=t.project.installersCustomData.get(i);if(!n)throw new Pe(`The project in ${ae.pretty(t.project.configuration,`${t.project.cwd}/package.json`,ae.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let s=e.match(/(^.*\/node_modules\/(@[^/]*\/)?[^/]+)(\/.*$)/);if(s){let l=n.locatorByPath.get(s[1]);if(l)return l}let o=e,a=e;do{a=o,o=x.dirname(a);let l=n.locatorByPath.get(a);if(l)return l}while(o!==a);return null}makeInstaller(e){return new Mue(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="pnpm"}},Mue=class{constructor(e){this.opts=e;this.asyncActions=new Se.AsyncActions(10);this.customData={pathByLocator:new Map,locatorByPath:new Map}}getCustomDataKey(){return cO()}attachCustomData(e){}async installPackage(e,t,i){switch(e.linkType){case Qt.SOFT:return this.installPackageSoft(e,t,i);case Qt.HARD:return this.installPackageHard(e,t,i)}throw new Error("Assertion failed: Unsupported package link type")}async installPackageSoft(e,t,i){let n=x.resolve(t.packageFs.getRealPath(),t.prefixPath);return this.customData.pathByLocator.set(e.locatorHash,n),{packageLocation:n,buildDirective:null}}async installPackageHard(e,t,i){var u;let n=b_e(e,{project:this.opts.project});this.customData.locatorByPath.set(n,P.stringifyLocator(e)),this.customData.pathByLocator.set(e.locatorHash,n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{await U.mkdirPromise(n,{recursive:!0}),await U.copyPromise(n,t.prefixPath,{baseFs:t.packageFs,overwrite:!1})}));let o=P.isVirtualLocator(e)?P.devirtualizeLocator(e):e,a={manifest:(u=await At.tryFind(t.prefixPath,{baseFs:t.packageFs}))!=null?u:new At,misc:{hasBindingGyp:ma.hasBindingGyp(t)}},l=this.opts.project.getDependencyMeta(o,e.version),c=ma.extractBuildScripts(e,a,l,{configuration:this.opts.project.configuration,report:this.opts.report});return{packageLocation:n,buildDirective:c}}async attachInternalDependencies(e,t){this.opts.project.configuration.get("nodeLinker")==="pnpm"&&(!Hue(e,{project:this.opts.project})||this.asyncActions.reduce(e.locatorHash,async i=>{await i;let n=this.customData.pathByLocator.get(e.locatorHash);if(typeof n=="undefined")throw new Error(`Assertion failed: Expected the package to have been registered (${P.stringifyLocator(e)})`);let s=x.join(n,xt.nodeModules),o=[],a=await jue(s);for(let[l,c]of t){let u=c;Hue(c,{project:this.opts.project})||(this.opts.report.reportWarning(X.UNNAMED,"The pnpm linker doesn't support providing different versions to workspaces' peer dependencies"),u=P.devirtualizeLocator(c));let g=this.customData.pathByLocator.get(u.locatorHash);if(typeof g=="undefined")throw new Error(`Assertion failed: Expected the package to have been registered (${P.stringifyLocator(c)})`);let f=P.stringifyIdent(l),h=x.join(s,f),p=x.relative(x.dirname(h),g),m=a.get(f);a.delete(f),o.push(Promise.resolve().then(async()=>{if(m){if(m.isSymbolicLink()&&await U.readlinkPromise(h)===p)return;await U.removePromise(h)}await U.mkdirpPromise(x.dirname(h)),process.platform=="win32"?await U.symlinkPromise(g,h,"junction"):await U.symlinkPromise(p,h)}))}o.push(Gue(s,a)),await Promise.all(o)}))}async attachExternalDependents(e,t){throw new Error("External dependencies haven't been implemented for the pnpm linker")}async finalizeInstall(){let e=Kue(this.opts.project);if(this.opts.project.configuration.get("nodeLinker")!=="pnpm")await U.removePromise(e);else{let t=[],i=new Set;for(let s of this.customData.pathByLocator.values()){let o=x.contains(e,s);if(o!==null){let[a,,...l]=o.split(x.sep);i.add(a);let c=x.join(e,a);t.push(U.readdirPromise(c).then(u=>Promise.all(u.map(async g=>{let f=x.join(c,g);if(g===xt.nodeModules){let h=await jue(f);return h.delete(l.join(x.sep)),Gue(f,h)}else return U.removePromise(f)}))).catch(u=>{if(u.code!=="ENOENT")throw u}))}}let n;try{n=await U.readdirPromise(e)}catch{n=[]}for(let s of n)i.has(s)||t.push(U.removePromise(x.join(e,s)));await Promise.all(t)}return await this.asyncActions.wait(),await uO(e),this.opts.project.configuration.get("nodeLinker")!=="node-modules"&&await uO(Uue(this.opts.project)),{customData:this.customData}}};function cO(){return JSON.stringify({name:"PnpmInstaller",version:2})}function Uue(r){return x.join(r.cwd,xt.nodeModules)}function Kue(r){return x.join(Uue(r),".store")}function b_e(r,{project:e}){let t=P.slugifyLocator(r),i=P.getIdentVendorPath(r);return x.join(Kue(e),t,i)}function Hue(r,{project:e}){return!P.isVirtualLocator(r)||!e.tryWorkspaceByLocator(r)}async function jue(r){let e=new Map,t=[];try{t=await U.readdirPromise(r,{withFileTypes:!0})}catch(i){if(i.code!=="ENOENT")throw i}try{for(let i of t)if(!i.name.startsWith("."))if(i.name.startsWith("@")){let n=await U.readdirPromise(x.join(r,i.name),{withFileTypes:!0});if(n.length===0)e.set(i.name,i);else for(let s of n)e.set(`${i.name}/${s.name}`,s)}else e.set(i.name,i)}catch(i){if(i.code!=="ENOENT")throw i}return e}async function Gue(r,e){var n;let t=[],i=new Set;for(let s of e.keys()){t.push(U.removePromise(x.join(r,s)));let o=(n=P.tryParseIdent(s))==null?void 0:n.scope;o&&i.add(`@${o}`)}return Promise.all(t).then(()=>Promise.all([...i].map(s=>uO(x.join(r,s)))))}async function uO(r){try{await U.rmdirPromise(r)}catch(e){if(e.code!=="ENOENT"&&e.code!=="ENOTEMPTY")throw e}}var Q_e={linkers:[lO]},S_e=Q_e;var T0=()=>({modules:new Map([["@yarnpkg/cli",YC],["@yarnpkg/core",IC],["@yarnpkg/fslib",$h],["@yarnpkg/libzip",Ud],["@yarnpkg/parsers",ap],["@yarnpkg/shell",Hd],["clipanion",hZ(mp)],["semver",v_e],["typanion",ug],["yup",k_e],["@yarnpkg/plugin-essentials",YN],["@yarnpkg/plugin-compat",_N],["@yarnpkg/plugin-dlx",VN],["@yarnpkg/plugin-file",sL],["@yarnpkg/plugin-git",GN],["@yarnpkg/plugin-github",aL],["@yarnpkg/plugin-http",cL],["@yarnpkg/plugin-init",hL],["@yarnpkg/plugin-link",EL],["@yarnpkg/plugin-nm",WL],["@yarnpkg/plugin-npm",JT],["@yarnpkg/plugin-npm-cli",XT],["@yarnpkg/plugin-pack",jT],["@yarnpkg/plugin-patch",AO],["@yarnpkg/plugin-pnp",TL],["@yarnpkg/plugin-pnpm",gO]]),plugins:new Set(["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm"])});o0({binaryVersion:Kr||"<unknown>",pluginConfiguration:T0()});})(); -/*! - * buildToken - * Builds OAuth token prefix (helper function) - * - * @name buildToken - * @function - * @param {GitUrl} obj The parsed Git url object. - * @return {String} token prefix - */ -/*! - * fill-range <https://github.com/jonschlinkert/fill-range> - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Licensed under the MIT License. - */ -/*! - * is-extglob <https://github.com/jonschlinkert/is-extglob> - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ -/*! - * is-glob <https://github.com/jonschlinkert/is-glob> - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ -/*! - * is-number <https://github.com/jonschlinkert/is-number> - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */ -/*! - * is-windows <https://github.com/jonschlinkert/is-windows> - * - * Copyright © 2015-2018, Jon Schlinkert. - * Released under the MIT License. - */ -/*! - * to-regex-range <https://github.com/micromatch/to-regex-range> - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */ diff --git a/.yarn/releases/yarn-3.8.1.cjs b/.yarn/releases/yarn-3.8.1.cjs new file mode 100755 index 0000000000..85d80bac86 --- /dev/null +++ b/.yarn/releases/yarn-3.8.1.cjs @@ -0,0 +1,875 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var Lge=Object.create;var lS=Object.defineProperty;var Oge=Object.getOwnPropertyDescriptor;var Mge=Object.getOwnPropertyNames;var Kge=Object.getPrototypeOf,Uge=Object.prototype.hasOwnProperty;var J=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var Hge=(r,e)=>()=>(r&&(e=r(r=0)),e);var I=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ct=(r,e)=>{for(var t in e)lS(r,t,{get:e[t],enumerable:!0})},jge=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Mge(e))!Uge.call(r,n)&&n!==t&&lS(r,n,{get:()=>e[n],enumerable:!(i=Oge(e,n))||i.enumerable});return r};var ve=(r,e,t)=>(t=r!=null?Lge(Kge(r)):{},jge(e||!r||!r.__esModule?lS(t,"default",{value:r,enumerable:!0}):t,r));var kK=I((nZe,xK)=>{xK.exports=PK;PK.sync=lfe;var SK=J("fs");function Afe(r,e){var t=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!t||(t=t.split(";"),t.indexOf("")!==-1))return!0;for(var i=0;i<t.length;i++){var n=t[i].toLowerCase();if(n&&r.substr(-n.length).toLowerCase()===n)return!0}return!1}function vK(r,e,t){return!r.isSymbolicLink()&&!r.isFile()?!1:Afe(e,t)}function PK(r,e,t){SK.stat(r,function(i,n){t(i,i?!1:vK(n,r,e))})}function lfe(r,e){return vK(SK.statSync(r),r,e)}});var TK=I((sZe,NK)=>{NK.exports=RK;RK.sync=cfe;var DK=J("fs");function RK(r,e,t){DK.stat(r,function(i,n){t(i,i?!1:FK(n,e))})}function cfe(r,e){return FK(DK.statSync(r),e)}function FK(r,e){return r.isFile()&&ufe(r,e)}function ufe(r,e){var t=r.mode,i=r.uid,n=r.gid,s=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),o=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),u=a|l,g=t&c||t&l&&n===o||t&a&&i===s||t&u&&s===0;return g}});var OK=I((aZe,LK)=>{var oZe=J("fs"),AI;process.platform==="win32"||global.TESTING_WINDOWS?AI=kK():AI=TK();LK.exports=SS;SS.sync=gfe;function SS(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){SS(r,e||{},function(s,o){s?n(s):i(o)})})}AI(r,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),t(i,n)})}function gfe(r,e){try{return AI.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}});var YK=I((AZe,GK)=>{var kg=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",MK=J("path"),ffe=kg?";":":",KK=OK(),UK=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),HK=(r,e)=>{let t=e.colon||ffe,i=r.match(/\//)||kg&&r.match(/\\/)?[""]:[...kg?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],n=kg?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=kg?n.split(t):[""];return kg&&r.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},jK=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=HK(r,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(UK(r));let h=i[c],p=/^".*"$/.test(h)?h.slice(1,-1):h,d=MK.join(p,r),m=!p&&/^\.[\\\/]/.test(r)?r.slice(0,2)+d:d;u(l(m,c,0))}),l=(c,u,g)=>new Promise((h,p)=>{if(g===n.length)return h(a(u+1));let d=n[g];KK(c+d,{pathExt:s},(m,y)=>{if(!m&&y)if(e.all)o.push(c+d);else return h(c+d);return h(l(c,u,g+1))})});return t?a(0).then(c=>t(null,c),t):a(0)},hfe=(r,e)=>{e=e||{};let{pathEnv:t,pathExt:i,pathExtExe:n}=HK(r,e),s=[];for(let o=0;o<t.length;o++){let a=t[o],l=/^".*"$/.test(a)?a.slice(1,-1):a,c=MK.join(l,r),u=!l&&/^\.[\\\/]/.test(r)?r.slice(0,2)+c:c;for(let g=0;g<i.length;g++){let h=u+i[g];try{if(KK.sync(h,{pathExt:n}))if(e.all)s.push(h);else return h}catch{}}}if(e.all&&s.length)return s;if(e.nothrow)return null;throw UK(r)};GK.exports=jK;jK.sync=hfe});var JK=I((lZe,vS)=>{"use strict";var qK=(r={})=>{let e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};vS.exports=qK;vS.exports.default=qK});var XK=I((cZe,VK)=>{"use strict";var WK=J("path"),pfe=YK(),dfe=JK();function zK(r,e){let t=r.options.env||process.env,i=process.cwd(),n=r.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(r.options.cwd)}catch{}let o;try{o=pfe.sync(r.command,{path:t[dfe({env:t})],pathExt:e?WK.delimiter:void 0})}catch{}finally{s&&process.chdir(i)}return o&&(o=WK.resolve(n?r.options.cwd:"",o)),o}function Cfe(r){return zK(r)||zK(r,!0)}VK.exports=Cfe});var ZK=I((uZe,xS)=>{"use strict";var PS=/([()\][%!^"`<>&|;, *?])/g;function mfe(r){return r=r.replace(PS,"^$1"),r}function Efe(r,e){return r=`${r}`,r=r.replace(/(\\*)"/g,'$1$1\\"'),r=r.replace(/(\\*)$/,"$1$1"),r=`"${r}"`,r=r.replace(PS,"^$1"),e&&(r=r.replace(PS,"^$1")),r}xS.exports.command=mfe;xS.exports.argument=Efe});var $K=I((gZe,_K)=>{"use strict";_K.exports=/^#!(.*)/});var tU=I((fZe,eU)=>{"use strict";var Ife=$K();eU.exports=(r="")=>{let e=r.match(Ife);if(!e)return null;let[t,i]=e[0].replace(/#! ?/,"").split(" "),n=t.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var iU=I((hZe,rU)=>{"use strict";var kS=J("fs"),yfe=tU();function wfe(r){let t=Buffer.alloc(150),i;try{i=kS.openSync(r,"r"),kS.readSync(i,t,0,150,0),kS.closeSync(i)}catch{}return yfe(t.toString())}rU.exports=wfe});var aU=I((pZe,oU)=>{"use strict";var Bfe=J("path"),nU=XK(),sU=ZK(),bfe=iU(),Qfe=process.platform==="win32",Sfe=/\.(?:com|exe)$/i,vfe=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Pfe(r){r.file=nU(r);let e=r.file&&bfe(r.file);return e?(r.args.unshift(r.file),r.command=e,nU(r)):r.file}function xfe(r){if(!Qfe)return r;let e=Pfe(r),t=!Sfe.test(e);if(r.options.forceShell||t){let i=vfe.test(e);r.command=Bfe.normalize(r.command),r.command=sU.command(r.command),r.args=r.args.map(s=>sU.argument(s,i));let n=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${n}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function kfe(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);let i={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?i:xfe(i)}oU.exports=kfe});var cU=I((dZe,lU)=>{"use strict";var DS=process.platform==="win32";function RS(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function Dfe(r,e){if(!DS)return;let t=r.emit;r.emit=function(i,n){if(i==="exit"){let s=AU(n,e,"spawn");if(s)return t.call(r,"error",s)}return t.apply(r,arguments)}}function AU(r,e){return DS&&r===1&&!e.file?RS(e.original,"spawn"):null}function Rfe(r,e){return DS&&r===1&&!e.file?RS(e.original,"spawnSync"):null}lU.exports={hookChildProcess:Dfe,verifyENOENT:AU,verifyENOENTSync:Rfe,notFoundError:RS}});var TS=I((CZe,Dg)=>{"use strict";var uU=J("child_process"),FS=aU(),NS=cU();function gU(r,e,t){let i=FS(r,e,t),n=uU.spawn(i.command,i.args,i.options);return NS.hookChildProcess(n,i),n}function Ffe(r,e,t){let i=FS(r,e,t),n=uU.spawnSync(i.command,i.args,i.options);return n.error=n.error||NS.verifyENOENTSync(n.status,i),n}Dg.exports=gU;Dg.exports.spawn=gU;Dg.exports.sync=Ffe;Dg.exports._parse=FS;Dg.exports._enoent=NS});var hU=I((mZe,fU)=>{"use strict";function Nfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function $l(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,$l)}Nfe($l,Error);$l.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g<c.parts.length;g++)u+=c.parts[g]instanceof Array?s(c.parts[g][0])+"-"+s(c.parts[g][1]):s(c.parts[g]);return"["+(c.inverted?"^":"")+u+"]"},any:function(c){return"any character"},end:function(c){return"end of input"},other:function(c){return c.description}};function i(c){return c.charCodeAt(0).toString(16).toUpperCase()}function n(c){return c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function s(c){return c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function o(c){return t[c.type](c)}function a(c){var u=new Array(c.length),g,h;for(g=0;g<c.length;g++)u[g]=o(c[g]);if(u.sort(),u.length>0){for(g=1,h=1;g<u.length;g++)u[g-1]!==u[g]&&(u[h]=u[g],h++);u.length=h}switch(u.length){case 1:return u[0];case 2:return u[0]+" or "+u[1];default:return u.slice(0,-1).join(", ")+", or "+u[u.length-1]}}function l(c){return c?'"'+n(c)+'"':"end of input"}return"Expected "+a(r)+" but "+l(e)+" found."};function Tfe(r,e){e=e!==void 0?e:{};var t={},i={Start:Ia},n=Ia,s=function(C){return C||[]},o=function(C,b,R){return[{command:C,type:b}].concat(R||[])},a=function(C,b){return[{command:C,type:b||";"}]},l=function(C){return C},c=";",u=Ue(";",!1),g="&",h=Ue("&",!1),p=function(C,b){return b?{chain:C,then:b}:{chain:C}},d=function(C,b){return{type:C,line:b}},m="&&",y=Ue("&&",!1),B="||",S=Ue("||",!1),x=function(C,b){return b?{...C,then:b}:C},F=function(C,b){return{type:C,chain:b}},H="|&",q=Ue("|&",!1),_="|",X=Ue("|",!1),W="=",Z=Ue("=",!1),A=function(C,b){return{name:C,args:[b]}},ne=function(C){return{name:C,args:[]}},ue="(",te=Ue("(",!1),O=")",N=Ue(")",!1),ce=function(C,b){return{type:"subshell",subshell:C,args:b}},he="{",xe=Ue("{",!1),De="}",Re=Ue("}",!1),se=function(C,b){return{type:"group",group:C,args:b}},Ae=function(C,b){return{type:"command",args:b,envs:C}},ye=function(C){return{type:"envs",envs:C}},ge=function(C){return C},oe=function(C){return C},Ye=/^[0-9]/,ie=Ve([["0","9"]],!1,!1),G=function(C,b,R){return{type:"redirection",subtype:b,fd:C!==null?parseInt(C):null,args:[R]}},fe=">>",re=Ue(">>",!1),de=">&",Ze=Ue(">&",!1),vt=">",mt=Ue(">",!1),Tr="<<<",ti=Ue("<<<",!1),ui="<&",gr=Ue("<&",!1),gi="<",ri=Ue("<",!1),Ms=function(C){return{type:"argument",segments:[].concat(...C)}},fr=function(C){return C},Ei="$'",rs=Ue("$'",!1),ua="'",CA=Ue("'",!1),gg=function(C){return[{type:"text",text:C}]},is='""',mA=Ue('""',!1),ga=function(){return{type:"text",text:""}},wp='"',EA=Ue('"',!1),IA=function(C){return C},Ir=function(C){return{type:"arithmetic",arithmetic:C,quoted:!0}},Nl=function(C){return{type:"shell",shell:C,quoted:!0}},fg=function(C){return{type:"variable",...C,quoted:!0}},Io=function(C){return{type:"text",text:C}},hg=function(C){return{type:"arithmetic",arithmetic:C,quoted:!1}},Bp=function(C){return{type:"shell",shell:C,quoted:!1}},bp=function(C){return{type:"variable",...C,quoted:!1}},Qr=function(C){return{type:"glob",pattern:C}},Ri=/^[^']/,yo=Ve(["'"],!0,!1),Nn=function(C){return C.join("")},ae=/^[^$"]/,yt=Ve(["$",'"'],!0,!1),Tl=`\\ +`,Tn=Ue(`\\ +`,!1),ns=function(){return""},ss="\\",ut=Ue("\\",!1),wo=/^[\\$"`]/,At=Ve(["\\","$",'"',"`"],!1,!1),An=function(C){return C},Q="\\a",Nt=Ue("\\a",!1),pg=function(){return"a"},Ll="\\b",Qp=Ue("\\b",!1),Sp=function(){return"\b"},vp=/^[Ee]/,Pp=Ve(["E","e"],!1,!1),xp=function(){return"\x1B"},j="\\f",Et=Ue("\\f",!1),yA=function(){return"\f"},Wi="\\n",Ol=Ue("\\n",!1),ze=function(){return` +`},fa="\\r",dg=Ue("\\r",!1),OE=function(){return"\r"},kp="\\t",ME=Ue("\\t",!1),sr=function(){return" "},Ln="\\v",Ml=Ue("\\v",!1),Dp=function(){return"\v"},Ks=/^[\\'"?]/,ha=Ve(["\\","'",'"',"?"],!1,!1),ln=function(C){return String.fromCharCode(parseInt(C,16))},Ne="\\x",Cg=Ue("\\x",!1),Kl="\\u",Us=Ue("\\u",!1),Ul="\\U",wA=Ue("\\U",!1),mg=function(C){return String.fromCodePoint(parseInt(C,16))},Eg=/^[0-7]/,pa=Ve([["0","7"]],!1,!1),da=/^[0-9a-fA-f]/,tt=Ve([["0","9"],["a","f"],["A","f"]],!1,!1),Bo=nt(),BA="{}",Rp=Ue("{}",!1),Ca=function(){return"{}"},Hl="-",jl=Ue("-",!1),bA="+",ma=Ue("+",!1),Fp=".",KE=Ue(".",!1),Gl=function(C,b,R){return{type:"number",value:(C==="-"?-1:1)*parseFloat(b.join("")+"."+R.join(""))}},UE=function(C,b){return{type:"number",value:(C==="-"?-1:1)*parseInt(b.join(""))}},Np=function(C){return{type:"variable",...C}},Yl=function(C){return{type:"variable",name:C}},Lr=function(C){return C},HE="*",Hs=Ue("*",!1),js="/",Ig=Ue("/",!1),QA=function(C,b,R){return{type:b==="*"?"multiplication":"division",right:R}},D=function(C,b){return b.reduce((R,U)=>({left:R,...U}),C)},Y=function(C,b,R){return{type:b==="+"?"addition":"subtraction",right:R}},pe="$((",Le=Ue("$((",!1),ke="))",Je=Ue("))",!1),pt=function(C){return C},Xt="$(",Ea=Ue("$(",!1),D1=function(C){return C},Gs="${",yg=Ue("${",!1),JQ=":-",R1=Ue(":-",!1),F1=function(C,b){return{name:C,defaultValue:b}},WQ=":-}",N1=Ue(":-}",!1),T1=function(C){return{name:C,defaultValue:[]}},zQ=":+",L1=Ue(":+",!1),O1=function(C,b){return{name:C,alternativeValue:b}},VQ=":+}",M1=Ue(":+}",!1),K1=function(C){return{name:C,alternativeValue:[]}},XQ=function(C){return{name:C}},U1="$",H1=Ue("$",!1),j1=function(C){return e.isGlobPattern(C)},G1=function(C){return C},ZQ=/^[a-zA-Z0-9_]/,_Q=Ve([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),$Q=function(){return Ie()},ql=/^[$@*?#a-zA-Z0-9_\-]/,jE=Ve(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),eS=/^[()}<>$|&; \t"']/,tS=Ve(["(",")","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),rS=/^[<>&; \t"']/,GE=Ve(["<",">","&",";"," "," ",'"',"'"],!1,!1),Jl=/^[ \t]/,wg=Ve([" "," "],!1,!1),f=0,E=0,w=[{line:1,column:1}],k=0,L=[],T=0,ee;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function Ie(){return r.substring(E,f)}function Oe(){return ii(E,f)}function it(C,b){throw b=b!==void 0?b:ii(E,f),On([Ii(C)],r.substring(E,f),b)}function at(C,b){throw b=b!==void 0?b:ii(E,f),yi(C,b)}function Ue(C,b){return{type:"literal",text:C,ignoreCase:b}}function Ve(C,b,R){return{type:"class",parts:C,inverted:b,ignoreCase:R}}function nt(){return{type:"any"}}function wt(){return{type:"end"}}function Ii(C){return{type:"other",description:C}}function cn(C){var b=w[C],R;if(b)return b;for(R=C-1;!w[R];)R--;for(b=w[R],b={line:b.line,column:b.column};R<C;)r.charCodeAt(R)===10?(b.line++,b.column=1):b.column++,R++;return w[C]=b,b}function ii(C,b){var R=cn(C),U=cn(b);return{start:{offset:C,line:R.line,column:R.column},end:{offset:b,line:U.line,column:U.column}}}function Be(C){f<k||(f>k&&(k=f,L=[]),L.push(C))}function yi(C,b){return new $l(C,null,null,b)}function On(C,b,R){return new $l($l.buildMessage(C,b),C,b,R)}function Ia(){var C,b,R;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();return b!==t?(R=Sr(),R===t&&(R=null),R!==t?(E=C,b=s(R),C=b):(f=C,C=t)):(f=C,C=t),C}function Sr(){var C,b,R,U,le;if(C=f,b=iS(),b!==t){for(R=[],U=Me();U!==t;)R.push(U),U=Me();R!==t?(U=Y1(),U!==t?(le=mge(),le===t&&(le=null),le!==t?(E=C,b=o(b,U,le),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t)}else f=C,C=t;if(C===t)if(C=f,b=iS(),b!==t){for(R=[],U=Me();U!==t;)R.push(U),U=Me();R!==t?(U=Y1(),U===t&&(U=null),U!==t?(E=C,b=a(b,U),C=b):(f=C,C=t)):(f=C,C=t)}else f=C,C=t;return C}function mge(){var C,b,R,U,le;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t)if(R=Sr(),R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();U!==t?(E=C,b=l(R),C=b):(f=C,C=t)}else f=C,C=t;else f=C,C=t;return C}function Y1(){var C;return r.charCodeAt(f)===59?(C=c,f++):(C=t,T===0&&Be(u)),C===t&&(r.charCodeAt(f)===38?(C=g,f++):(C=t,T===0&&Be(h))),C}function iS(){var C,b,R;return C=f,b=q1(),b!==t?(R=Ege(),R===t&&(R=null),R!==t?(E=C,b=p(b,R),C=b):(f=C,C=t)):(f=C,C=t),C}function Ege(){var C,b,R,U,le,be,ft;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t)if(R=Ige(),R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();if(U!==t)if(le=iS(),le!==t){for(be=[],ft=Me();ft!==t;)be.push(ft),ft=Me();be!==t?(E=C,b=d(R,le),C=b):(f=C,C=t)}else f=C,C=t;else f=C,C=t}else f=C,C=t;else f=C,C=t;return C}function Ige(){var C;return r.substr(f,2)===m?(C=m,f+=2):(C=t,T===0&&Be(y)),C===t&&(r.substr(f,2)===B?(C=B,f+=2):(C=t,T===0&&Be(S))),C}function q1(){var C,b,R;return C=f,b=Bge(),b!==t?(R=yge(),R===t&&(R=null),R!==t?(E=C,b=x(b,R),C=b):(f=C,C=t)):(f=C,C=t),C}function yge(){var C,b,R,U,le,be,ft;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t)if(R=wge(),R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();if(U!==t)if(le=q1(),le!==t){for(be=[],ft=Me();ft!==t;)be.push(ft),ft=Me();be!==t?(E=C,b=F(R,le),C=b):(f=C,C=t)}else f=C,C=t;else f=C,C=t}else f=C,C=t;else f=C,C=t;return C}function wge(){var C;return r.substr(f,2)===H?(C=H,f+=2):(C=t,T===0&&Be(q)),C===t&&(r.charCodeAt(f)===124?(C=_,f++):(C=t,T===0&&Be(X))),C}function YE(){var C,b,R,U,le,be;if(C=f,b=iK(),b!==t)if(r.charCodeAt(f)===61?(R=W,f++):(R=t,T===0&&Be(Z)),R!==t)if(U=z1(),U!==t){for(le=[],be=Me();be!==t;)le.push(be),be=Me();le!==t?(E=C,b=A(b,U),C=b):(f=C,C=t)}else f=C,C=t;else f=C,C=t;else f=C,C=t;if(C===t)if(C=f,b=iK(),b!==t)if(r.charCodeAt(f)===61?(R=W,f++):(R=t,T===0&&Be(Z)),R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();U!==t?(E=C,b=ne(b),C=b):(f=C,C=t)}else f=C,C=t;else f=C,C=t;return C}function Bge(){var C,b,R,U,le,be,ft,It,Gr,fi,os;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t)if(r.charCodeAt(f)===40?(R=ue,f++):(R=t,T===0&&Be(te)),R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();if(U!==t)if(le=Sr(),le!==t){for(be=[],ft=Me();ft!==t;)be.push(ft),ft=Me();if(be!==t)if(r.charCodeAt(f)===41?(ft=O,f++):(ft=t,T===0&&Be(N)),ft!==t){for(It=[],Gr=Me();Gr!==t;)It.push(Gr),Gr=Me();if(It!==t){for(Gr=[],fi=Tp();fi!==t;)Gr.push(fi),fi=Tp();if(Gr!==t){for(fi=[],os=Me();os!==t;)fi.push(os),os=Me();fi!==t?(E=C,b=ce(le,Gr),C=b):(f=C,C=t)}else f=C,C=t}else f=C,C=t}else f=C,C=t;else f=C,C=t}else f=C,C=t;else f=C,C=t}else f=C,C=t;else f=C,C=t;if(C===t){for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t)if(r.charCodeAt(f)===123?(R=he,f++):(R=t,T===0&&Be(xe)),R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();if(U!==t)if(le=Sr(),le!==t){for(be=[],ft=Me();ft!==t;)be.push(ft),ft=Me();if(be!==t)if(r.charCodeAt(f)===125?(ft=De,f++):(ft=t,T===0&&Be(Re)),ft!==t){for(It=[],Gr=Me();Gr!==t;)It.push(Gr),Gr=Me();if(It!==t){for(Gr=[],fi=Tp();fi!==t;)Gr.push(fi),fi=Tp();if(Gr!==t){for(fi=[],os=Me();os!==t;)fi.push(os),os=Me();fi!==t?(E=C,b=se(le,Gr),C=b):(f=C,C=t)}else f=C,C=t}else f=C,C=t}else f=C,C=t;else f=C,C=t}else f=C,C=t;else f=C,C=t}else f=C,C=t;else f=C,C=t;if(C===t){for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t){for(R=[],U=YE();U!==t;)R.push(U),U=YE();if(R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();if(U!==t){if(le=[],be=W1(),be!==t)for(;be!==t;)le.push(be),be=W1();else le=t;if(le!==t){for(be=[],ft=Me();ft!==t;)be.push(ft),ft=Me();be!==t?(E=C,b=Ae(R,le),C=b):(f=C,C=t)}else f=C,C=t}else f=C,C=t}else f=C,C=t}else f=C,C=t;if(C===t){for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t){if(R=[],U=YE(),U!==t)for(;U!==t;)R.push(U),U=YE();else R=t;if(R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();U!==t?(E=C,b=ye(R),C=b):(f=C,C=t)}else f=C,C=t}else f=C,C=t}}}return C}function J1(){var C,b,R,U,le;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t){if(R=[],U=qE(),U!==t)for(;U!==t;)R.push(U),U=qE();else R=t;if(R!==t){for(U=[],le=Me();le!==t;)U.push(le),le=Me();U!==t?(E=C,b=ge(R),C=b):(f=C,C=t)}else f=C,C=t}else f=C,C=t;return C}function W1(){var C,b,R;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();if(b!==t?(R=Tp(),R!==t?(E=C,b=oe(R),C=b):(f=C,C=t)):(f=C,C=t),C===t){for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();b!==t?(R=qE(),R!==t?(E=C,b=oe(R),C=b):(f=C,C=t)):(f=C,C=t)}return C}function Tp(){var C,b,R,U,le;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();return b!==t?(Ye.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(ie)),R===t&&(R=null),R!==t?(U=bge(),U!==t?(le=qE(),le!==t?(E=C,b=G(R,U,le),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C}function bge(){var C;return r.substr(f,2)===fe?(C=fe,f+=2):(C=t,T===0&&Be(re)),C===t&&(r.substr(f,2)===de?(C=de,f+=2):(C=t,T===0&&Be(Ze)),C===t&&(r.charCodeAt(f)===62?(C=vt,f++):(C=t,T===0&&Be(mt)),C===t&&(r.substr(f,3)===Tr?(C=Tr,f+=3):(C=t,T===0&&Be(ti)),C===t&&(r.substr(f,2)===ui?(C=ui,f+=2):(C=t,T===0&&Be(gr)),C===t&&(r.charCodeAt(f)===60?(C=gi,f++):(C=t,T===0&&Be(ri))))))),C}function qE(){var C,b,R;for(C=f,b=[],R=Me();R!==t;)b.push(R),R=Me();return b!==t?(R=z1(),R!==t?(E=C,b=oe(R),C=b):(f=C,C=t)):(f=C,C=t),C}function z1(){var C,b,R;if(C=f,b=[],R=V1(),R!==t)for(;R!==t;)b.push(R),R=V1();else b=t;return b!==t&&(E=C,b=Ms(b)),C=b,C}function V1(){var C,b;return C=f,b=Qge(),b!==t&&(E=C,b=fr(b)),C=b,C===t&&(C=f,b=Sge(),b!==t&&(E=C,b=fr(b)),C=b,C===t&&(C=f,b=vge(),b!==t&&(E=C,b=fr(b)),C=b,C===t&&(C=f,b=Pge(),b!==t&&(E=C,b=fr(b)),C=b))),C}function Qge(){var C,b,R,U;return C=f,r.substr(f,2)===Ei?(b=Ei,f+=2):(b=t,T===0&&Be(rs)),b!==t?(R=Dge(),R!==t?(r.charCodeAt(f)===39?(U=ua,f++):(U=t,T===0&&Be(CA)),U!==t?(E=C,b=gg(R),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C}function Sge(){var C,b,R,U;return C=f,r.charCodeAt(f)===39?(b=ua,f++):(b=t,T===0&&Be(CA)),b!==t?(R=xge(),R!==t?(r.charCodeAt(f)===39?(U=ua,f++):(U=t,T===0&&Be(CA)),U!==t?(E=C,b=gg(R),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C}function vge(){var C,b,R,U;if(C=f,r.substr(f,2)===is?(b=is,f+=2):(b=t,T===0&&Be(mA)),b!==t&&(E=C,b=ga()),C=b,C===t)if(C=f,r.charCodeAt(f)===34?(b=wp,f++):(b=t,T===0&&Be(EA)),b!==t){for(R=[],U=X1();U!==t;)R.push(U),U=X1();R!==t?(r.charCodeAt(f)===34?(U=wp,f++):(U=t,T===0&&Be(EA)),U!==t?(E=C,b=IA(R),C=b):(f=C,C=t)):(f=C,C=t)}else f=C,C=t;return C}function Pge(){var C,b,R;if(C=f,b=[],R=Z1(),R!==t)for(;R!==t;)b.push(R),R=Z1();else b=t;return b!==t&&(E=C,b=IA(b)),C=b,C}function X1(){var C,b;return C=f,b=tK(),b!==t&&(E=C,b=Ir(b)),C=b,C===t&&(C=f,b=rK(),b!==t&&(E=C,b=Nl(b)),C=b,C===t&&(C=f,b=aS(),b!==t&&(E=C,b=fg(b)),C=b,C===t&&(C=f,b=kge(),b!==t&&(E=C,b=Io(b)),C=b))),C}function Z1(){var C,b;return C=f,b=tK(),b!==t&&(E=C,b=hg(b)),C=b,C===t&&(C=f,b=rK(),b!==t&&(E=C,b=Bp(b)),C=b,C===t&&(C=f,b=aS(),b!==t&&(E=C,b=bp(b)),C=b,C===t&&(C=f,b=Nge(),b!==t&&(E=C,b=Qr(b)),C=b,C===t&&(C=f,b=Fge(),b!==t&&(E=C,b=Io(b)),C=b)))),C}function xge(){var C,b,R;for(C=f,b=[],Ri.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(yo));R!==t;)b.push(R),Ri.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(yo));return b!==t&&(E=C,b=Nn(b)),C=b,C}function kge(){var C,b,R;if(C=f,b=[],R=_1(),R===t&&(ae.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(yt))),R!==t)for(;R!==t;)b.push(R),R=_1(),R===t&&(ae.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(yt)));else b=t;return b!==t&&(E=C,b=Nn(b)),C=b,C}function _1(){var C,b,R;return C=f,r.substr(f,2)===Tl?(b=Tl,f+=2):(b=t,T===0&&Be(Tn)),b!==t&&(E=C,b=ns()),C=b,C===t&&(C=f,r.charCodeAt(f)===92?(b=ss,f++):(b=t,T===0&&Be(ut)),b!==t?(wo.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(At)),R!==t?(E=C,b=An(R),C=b):(f=C,C=t)):(f=C,C=t)),C}function Dge(){var C,b,R;for(C=f,b=[],R=$1(),R===t&&(Ri.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(yo)));R!==t;)b.push(R),R=$1(),R===t&&(Ri.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(yo)));return b!==t&&(E=C,b=Nn(b)),C=b,C}function $1(){var C,b,R;return C=f,r.substr(f,2)===Q?(b=Q,f+=2):(b=t,T===0&&Be(Nt)),b!==t&&(E=C,b=pg()),C=b,C===t&&(C=f,r.substr(f,2)===Ll?(b=Ll,f+=2):(b=t,T===0&&Be(Qp)),b!==t&&(E=C,b=Sp()),C=b,C===t&&(C=f,r.charCodeAt(f)===92?(b=ss,f++):(b=t,T===0&&Be(ut)),b!==t?(vp.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(Pp)),R!==t?(E=C,b=xp(),C=b):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===j?(b=j,f+=2):(b=t,T===0&&Be(Et)),b!==t&&(E=C,b=yA()),C=b,C===t&&(C=f,r.substr(f,2)===Wi?(b=Wi,f+=2):(b=t,T===0&&Be(Ol)),b!==t&&(E=C,b=ze()),C=b,C===t&&(C=f,r.substr(f,2)===fa?(b=fa,f+=2):(b=t,T===0&&Be(dg)),b!==t&&(E=C,b=OE()),C=b,C===t&&(C=f,r.substr(f,2)===kp?(b=kp,f+=2):(b=t,T===0&&Be(ME)),b!==t&&(E=C,b=sr()),C=b,C===t&&(C=f,r.substr(f,2)===Ln?(b=Ln,f+=2):(b=t,T===0&&Be(Ml)),b!==t&&(E=C,b=Dp()),C=b,C===t&&(C=f,r.charCodeAt(f)===92?(b=ss,f++):(b=t,T===0&&Be(ut)),b!==t?(Ks.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(ha)),R!==t?(E=C,b=An(R),C=b):(f=C,C=t)):(f=C,C=t),C===t&&(C=Rge()))))))))),C}function Rge(){var C,b,R,U,le,be,ft,It,Gr,fi,os,AS;return C=f,r.charCodeAt(f)===92?(b=ss,f++):(b=t,T===0&&Be(ut)),b!==t?(R=nS(),R!==t?(E=C,b=ln(R),C=b):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Ne?(b=Ne,f+=2):(b=t,T===0&&Be(Cg)),b!==t?(R=f,U=f,le=nS(),le!==t?(be=Mn(),be!==t?(le=[le,be],U=le):(f=U,U=t)):(f=U,U=t),U===t&&(U=nS()),U!==t?R=r.substring(R,f):R=U,R!==t?(E=C,b=ln(R),C=b):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Kl?(b=Kl,f+=2):(b=t,T===0&&Be(Us)),b!==t?(R=f,U=f,le=Mn(),le!==t?(be=Mn(),be!==t?(ft=Mn(),ft!==t?(It=Mn(),It!==t?(le=[le,be,ft,It],U=le):(f=U,U=t)):(f=U,U=t)):(f=U,U=t)):(f=U,U=t),U!==t?R=r.substring(R,f):R=U,R!==t?(E=C,b=ln(R),C=b):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Ul?(b=Ul,f+=2):(b=t,T===0&&Be(wA)),b!==t?(R=f,U=f,le=Mn(),le!==t?(be=Mn(),be!==t?(ft=Mn(),ft!==t?(It=Mn(),It!==t?(Gr=Mn(),Gr!==t?(fi=Mn(),fi!==t?(os=Mn(),os!==t?(AS=Mn(),AS!==t?(le=[le,be,ft,It,Gr,fi,os,AS],U=le):(f=U,U=t)):(f=U,U=t)):(f=U,U=t)):(f=U,U=t)):(f=U,U=t)):(f=U,U=t)):(f=U,U=t)):(f=U,U=t),U!==t?R=r.substring(R,f):R=U,R!==t?(E=C,b=mg(R),C=b):(f=C,C=t)):(f=C,C=t)))),C}function nS(){var C;return Eg.test(r.charAt(f))?(C=r.charAt(f),f++):(C=t,T===0&&Be(pa)),C}function Mn(){var C;return da.test(r.charAt(f))?(C=r.charAt(f),f++):(C=t,T===0&&Be(tt)),C}function Fge(){var C,b,R,U,le;if(C=f,b=[],R=f,r.charCodeAt(f)===92?(U=ss,f++):(U=t,T===0&&Be(ut)),U!==t?(r.length>f?(le=r.charAt(f),f++):(le=t,T===0&&Be(Bo)),le!==t?(E=R,U=An(le),R=U):(f=R,R=t)):(f=R,R=t),R===t&&(R=f,r.substr(f,2)===BA?(U=BA,f+=2):(U=t,T===0&&Be(Rp)),U!==t&&(E=R,U=Ca()),R=U,R===t&&(R=f,U=f,T++,le=nK(),T--,le===t?U=void 0:(f=U,U=t),U!==t?(r.length>f?(le=r.charAt(f),f++):(le=t,T===0&&Be(Bo)),le!==t?(E=R,U=An(le),R=U):(f=R,R=t)):(f=R,R=t))),R!==t)for(;R!==t;)b.push(R),R=f,r.charCodeAt(f)===92?(U=ss,f++):(U=t,T===0&&Be(ut)),U!==t?(r.length>f?(le=r.charAt(f),f++):(le=t,T===0&&Be(Bo)),le!==t?(E=R,U=An(le),R=U):(f=R,R=t)):(f=R,R=t),R===t&&(R=f,r.substr(f,2)===BA?(U=BA,f+=2):(U=t,T===0&&Be(Rp)),U!==t&&(E=R,U=Ca()),R=U,R===t&&(R=f,U=f,T++,le=nK(),T--,le===t?U=void 0:(f=U,U=t),U!==t?(r.length>f?(le=r.charAt(f),f++):(le=t,T===0&&Be(Bo)),le!==t?(E=R,U=An(le),R=U):(f=R,R=t)):(f=R,R=t)));else b=t;return b!==t&&(E=C,b=Nn(b)),C=b,C}function sS(){var C,b,R,U,le,be;if(C=f,r.charCodeAt(f)===45?(b=Hl,f++):(b=t,T===0&&Be(jl)),b===t&&(r.charCodeAt(f)===43?(b=bA,f++):(b=t,T===0&&Be(ma))),b===t&&(b=null),b!==t){if(R=[],Ye.test(r.charAt(f))?(U=r.charAt(f),f++):(U=t,T===0&&Be(ie)),U!==t)for(;U!==t;)R.push(U),Ye.test(r.charAt(f))?(U=r.charAt(f),f++):(U=t,T===0&&Be(ie));else R=t;if(R!==t)if(r.charCodeAt(f)===46?(U=Fp,f++):(U=t,T===0&&Be(KE)),U!==t){if(le=[],Ye.test(r.charAt(f))?(be=r.charAt(f),f++):(be=t,T===0&&Be(ie)),be!==t)for(;be!==t;)le.push(be),Ye.test(r.charAt(f))?(be=r.charAt(f),f++):(be=t,T===0&&Be(ie));else le=t;le!==t?(E=C,b=Gl(b,R,le),C=b):(f=C,C=t)}else f=C,C=t;else f=C,C=t}else f=C,C=t;if(C===t){if(C=f,r.charCodeAt(f)===45?(b=Hl,f++):(b=t,T===0&&Be(jl)),b===t&&(r.charCodeAt(f)===43?(b=bA,f++):(b=t,T===0&&Be(ma))),b===t&&(b=null),b!==t){if(R=[],Ye.test(r.charAt(f))?(U=r.charAt(f),f++):(U=t,T===0&&Be(ie)),U!==t)for(;U!==t;)R.push(U),Ye.test(r.charAt(f))?(U=r.charAt(f),f++):(U=t,T===0&&Be(ie));else R=t;R!==t?(E=C,b=UE(b,R),C=b):(f=C,C=t)}else f=C,C=t;if(C===t&&(C=f,b=aS(),b!==t&&(E=C,b=Np(b)),C=b,C===t&&(C=f,b=Wl(),b!==t&&(E=C,b=Yl(b)),C=b,C===t)))if(C=f,r.charCodeAt(f)===40?(b=ue,f++):(b=t,T===0&&Be(te)),b!==t){for(R=[],U=Me();U!==t;)R.push(U),U=Me();if(R!==t)if(U=eK(),U!==t){for(le=[],be=Me();be!==t;)le.push(be),be=Me();le!==t?(r.charCodeAt(f)===41?(be=O,f++):(be=t,T===0&&Be(N)),be!==t?(E=C,b=Lr(U),C=b):(f=C,C=t)):(f=C,C=t)}else f=C,C=t;else f=C,C=t}else f=C,C=t}return C}function oS(){var C,b,R,U,le,be,ft,It;if(C=f,b=sS(),b!==t){for(R=[],U=f,le=[],be=Me();be!==t;)le.push(be),be=Me();if(le!==t)if(r.charCodeAt(f)===42?(be=HE,f++):(be=t,T===0&&Be(Hs)),be===t&&(r.charCodeAt(f)===47?(be=js,f++):(be=t,T===0&&Be(Ig))),be!==t){for(ft=[],It=Me();It!==t;)ft.push(It),It=Me();ft!==t?(It=sS(),It!==t?(E=U,le=QA(b,be,It),U=le):(f=U,U=t)):(f=U,U=t)}else f=U,U=t;else f=U,U=t;for(;U!==t;){for(R.push(U),U=f,le=[],be=Me();be!==t;)le.push(be),be=Me();if(le!==t)if(r.charCodeAt(f)===42?(be=HE,f++):(be=t,T===0&&Be(Hs)),be===t&&(r.charCodeAt(f)===47?(be=js,f++):(be=t,T===0&&Be(Ig))),be!==t){for(ft=[],It=Me();It!==t;)ft.push(It),It=Me();ft!==t?(It=sS(),It!==t?(E=U,le=QA(b,be,It),U=le):(f=U,U=t)):(f=U,U=t)}else f=U,U=t;else f=U,U=t}R!==t?(E=C,b=D(b,R),C=b):(f=C,C=t)}else f=C,C=t;return C}function eK(){var C,b,R,U,le,be,ft,It;if(C=f,b=oS(),b!==t){for(R=[],U=f,le=[],be=Me();be!==t;)le.push(be),be=Me();if(le!==t)if(r.charCodeAt(f)===43?(be=bA,f++):(be=t,T===0&&Be(ma)),be===t&&(r.charCodeAt(f)===45?(be=Hl,f++):(be=t,T===0&&Be(jl))),be!==t){for(ft=[],It=Me();It!==t;)ft.push(It),It=Me();ft!==t?(It=oS(),It!==t?(E=U,le=Y(b,be,It),U=le):(f=U,U=t)):(f=U,U=t)}else f=U,U=t;else f=U,U=t;for(;U!==t;){for(R.push(U),U=f,le=[],be=Me();be!==t;)le.push(be),be=Me();if(le!==t)if(r.charCodeAt(f)===43?(be=bA,f++):(be=t,T===0&&Be(ma)),be===t&&(r.charCodeAt(f)===45?(be=Hl,f++):(be=t,T===0&&Be(jl))),be!==t){for(ft=[],It=Me();It!==t;)ft.push(It),It=Me();ft!==t?(It=oS(),It!==t?(E=U,le=Y(b,be,It),U=le):(f=U,U=t)):(f=U,U=t)}else f=U,U=t;else f=U,U=t}R!==t?(E=C,b=D(b,R),C=b):(f=C,C=t)}else f=C,C=t;return C}function tK(){var C,b,R,U,le,be;if(C=f,r.substr(f,3)===pe?(b=pe,f+=3):(b=t,T===0&&Be(Le)),b!==t){for(R=[],U=Me();U!==t;)R.push(U),U=Me();if(R!==t)if(U=eK(),U!==t){for(le=[],be=Me();be!==t;)le.push(be),be=Me();le!==t?(r.substr(f,2)===ke?(be=ke,f+=2):(be=t,T===0&&Be(Je)),be!==t?(E=C,b=pt(U),C=b):(f=C,C=t)):(f=C,C=t)}else f=C,C=t;else f=C,C=t}else f=C,C=t;return C}function rK(){var C,b,R,U;return C=f,r.substr(f,2)===Xt?(b=Xt,f+=2):(b=t,T===0&&Be(Ea)),b!==t?(R=Sr(),R!==t?(r.charCodeAt(f)===41?(U=O,f++):(U=t,T===0&&Be(N)),U!==t?(E=C,b=D1(R),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C}function aS(){var C,b,R,U,le,be;return C=f,r.substr(f,2)===Gs?(b=Gs,f+=2):(b=t,T===0&&Be(yg)),b!==t?(R=Wl(),R!==t?(r.substr(f,2)===JQ?(U=JQ,f+=2):(U=t,T===0&&Be(R1)),U!==t?(le=J1(),le!==t?(r.charCodeAt(f)===125?(be=De,f++):(be=t,T===0&&Be(Re)),be!==t?(E=C,b=F1(R,le),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Gs?(b=Gs,f+=2):(b=t,T===0&&Be(yg)),b!==t?(R=Wl(),R!==t?(r.substr(f,3)===WQ?(U=WQ,f+=3):(U=t,T===0&&Be(N1)),U!==t?(E=C,b=T1(R),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Gs?(b=Gs,f+=2):(b=t,T===0&&Be(yg)),b!==t?(R=Wl(),R!==t?(r.substr(f,2)===zQ?(U=zQ,f+=2):(U=t,T===0&&Be(L1)),U!==t?(le=J1(),le!==t?(r.charCodeAt(f)===125?(be=De,f++):(be=t,T===0&&Be(Re)),be!==t?(E=C,b=O1(R,le),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Gs?(b=Gs,f+=2):(b=t,T===0&&Be(yg)),b!==t?(R=Wl(),R!==t?(r.substr(f,3)===VQ?(U=VQ,f+=3):(U=t,T===0&&Be(M1)),U!==t?(E=C,b=K1(R),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.substr(f,2)===Gs?(b=Gs,f+=2):(b=t,T===0&&Be(yg)),b!==t?(R=Wl(),R!==t?(r.charCodeAt(f)===125?(U=De,f++):(U=t,T===0&&Be(Re)),U!==t?(E=C,b=XQ(R),C=b):(f=C,C=t)):(f=C,C=t)):(f=C,C=t),C===t&&(C=f,r.charCodeAt(f)===36?(b=U1,f++):(b=t,T===0&&Be(H1)),b!==t?(R=Wl(),R!==t?(E=C,b=XQ(R),C=b):(f=C,C=t)):(f=C,C=t)))))),C}function Nge(){var C,b,R;return C=f,b=Tge(),b!==t?(E=f,R=j1(b),R?R=void 0:R=t,R!==t?(E=C,b=G1(b),C=b):(f=C,C=t)):(f=C,C=t),C}function Tge(){var C,b,R,U,le;if(C=f,b=[],R=f,U=f,T++,le=sK(),T--,le===t?U=void 0:(f=U,U=t),U!==t?(r.length>f?(le=r.charAt(f),f++):(le=t,T===0&&Be(Bo)),le!==t?(E=R,U=An(le),R=U):(f=R,R=t)):(f=R,R=t),R!==t)for(;R!==t;)b.push(R),R=f,U=f,T++,le=sK(),T--,le===t?U=void 0:(f=U,U=t),U!==t?(r.length>f?(le=r.charAt(f),f++):(le=t,T===0&&Be(Bo)),le!==t?(E=R,U=An(le),R=U):(f=R,R=t)):(f=R,R=t);else b=t;return b!==t&&(E=C,b=Nn(b)),C=b,C}function iK(){var C,b,R;if(C=f,b=[],ZQ.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(_Q)),R!==t)for(;R!==t;)b.push(R),ZQ.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(_Q));else b=t;return b!==t&&(E=C,b=$Q()),C=b,C}function Wl(){var C,b,R;if(C=f,b=[],ql.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(jE)),R!==t)for(;R!==t;)b.push(R),ql.test(r.charAt(f))?(R=r.charAt(f),f++):(R=t,T===0&&Be(jE));else b=t;return b!==t&&(E=C,b=$Q()),C=b,C}function nK(){var C;return eS.test(r.charAt(f))?(C=r.charAt(f),f++):(C=t,T===0&&Be(tS)),C}function sK(){var C;return rS.test(r.charAt(f))?(C=r.charAt(f),f++):(C=t,T===0&&Be(GE)),C}function Me(){var C,b;if(C=[],Jl.test(r.charAt(f))?(b=r.charAt(f),f++):(b=t,T===0&&Be(wg)),b!==t)for(;b!==t;)C.push(b),Jl.test(r.charAt(f))?(b=r.charAt(f),f++):(b=t,T===0&&Be(wg));else C=t;return C}if(ee=n(),ee!==t&&f===r.length)return ee;throw ee!==t&&f<r.length&&Be(wt()),On(L,k<r.length?r.charAt(k):null,k<r.length?ii(k,k+1):ii(k,k))}fU.exports={SyntaxError:$l,parse:Tfe}});var EU=I((RZe,mU)=>{"use strict";function Mfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function tc(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,tc)}Mfe(tc,Error);tc.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g<c.parts.length;g++)u+=c.parts[g]instanceof Array?s(c.parts[g][0])+"-"+s(c.parts[g][1]):s(c.parts[g]);return"["+(c.inverted?"^":"")+u+"]"},any:function(c){return"any character"},end:function(c){return"end of input"},other:function(c){return c.description}};function i(c){return c.charCodeAt(0).toString(16).toUpperCase()}function n(c){return c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function s(c){return c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function o(c){return t[c.type](c)}function a(c){var u=new Array(c.length),g,h;for(g=0;g<c.length;g++)u[g]=o(c[g]);if(u.sort(),u.length>0){for(g=1,h=1;g<u.length;g++)u[g-1]!==u[g]&&(u[h]=u[g],h++);u.length=h}switch(u.length){case 1:return u[0];case 2:return u[0]+" or "+u[1];default:return u.slice(0,-1).join(", ")+", or "+u[u.length-1]}}function l(c){return c?'"'+n(c)+'"':"end of input"}return"Expected "+a(r)+" but "+l(e)+" found."};function Kfe(r,e){e=e!==void 0?e:{};var t={},i={resolution:Ae},n=Ae,s="/",o=ue("/",!1),a=function(ie,G){return{from:ie,descriptor:G}},l=function(ie){return{descriptor:ie}},c="@",u=ue("@",!1),g=function(ie,G){return{fullName:ie,description:G}},h=function(ie){return{fullName:ie}},p=function(){return W()},d=/^[^\/@]/,m=te(["/","@"],!0,!1),y=/^[^\/]/,B=te(["/"],!0,!1),S=0,x=0,F=[{line:1,column:1}],H=0,q=[],_=0,X;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function W(){return r.substring(x,S)}function Z(){return xe(x,S)}function A(ie,G){throw G=G!==void 0?G:xe(x,S),se([ce(ie)],r.substring(x,S),G)}function ne(ie,G){throw G=G!==void 0?G:xe(x,S),Re(ie,G)}function ue(ie,G){return{type:"literal",text:ie,ignoreCase:G}}function te(ie,G,fe){return{type:"class",parts:ie,inverted:G,ignoreCase:fe}}function O(){return{type:"any"}}function N(){return{type:"end"}}function ce(ie){return{type:"other",description:ie}}function he(ie){var G=F[ie],fe;if(G)return G;for(fe=ie-1;!F[fe];)fe--;for(G=F[fe],G={line:G.line,column:G.column};fe<ie;)r.charCodeAt(fe)===10?(G.line++,G.column=1):G.column++,fe++;return F[ie]=G,G}function xe(ie,G){var fe=he(ie),re=he(G);return{start:{offset:ie,line:fe.line,column:fe.column},end:{offset:G,line:re.line,column:re.column}}}function De(ie){S<H||(S>H&&(H=S,q=[]),q.push(ie))}function Re(ie,G){return new tc(ie,null,null,G)}function se(ie,G,fe){return new tc(tc.buildMessage(ie,G),ie,G,fe)}function Ae(){var ie,G,fe,re;return ie=S,G=ye(),G!==t?(r.charCodeAt(S)===47?(fe=s,S++):(fe=t,_===0&&De(o)),fe!==t?(re=ye(),re!==t?(x=ie,G=a(G,re),ie=G):(S=ie,ie=t)):(S=ie,ie=t)):(S=ie,ie=t),ie===t&&(ie=S,G=ye(),G!==t&&(x=ie,G=l(G)),ie=G),ie}function ye(){var ie,G,fe,re;return ie=S,G=ge(),G!==t?(r.charCodeAt(S)===64?(fe=c,S++):(fe=t,_===0&&De(u)),fe!==t?(re=Ye(),re!==t?(x=ie,G=g(G,re),ie=G):(S=ie,ie=t)):(S=ie,ie=t)):(S=ie,ie=t),ie===t&&(ie=S,G=ge(),G!==t&&(x=ie,G=h(G)),ie=G),ie}function ge(){var ie,G,fe,re,de;return ie=S,r.charCodeAt(S)===64?(G=c,S++):(G=t,_===0&&De(u)),G!==t?(fe=oe(),fe!==t?(r.charCodeAt(S)===47?(re=s,S++):(re=t,_===0&&De(o)),re!==t?(de=oe(),de!==t?(x=ie,G=p(),ie=G):(S=ie,ie=t)):(S=ie,ie=t)):(S=ie,ie=t)):(S=ie,ie=t),ie===t&&(ie=S,G=oe(),G!==t&&(x=ie,G=p()),ie=G),ie}function oe(){var ie,G,fe;if(ie=S,G=[],d.test(r.charAt(S))?(fe=r.charAt(S),S++):(fe=t,_===0&&De(m)),fe!==t)for(;fe!==t;)G.push(fe),d.test(r.charAt(S))?(fe=r.charAt(S),S++):(fe=t,_===0&&De(m));else G=t;return G!==t&&(x=ie,G=p()),ie=G,ie}function Ye(){var ie,G,fe;if(ie=S,G=[],y.test(r.charAt(S))?(fe=r.charAt(S),S++):(fe=t,_===0&&De(B)),fe!==t)for(;fe!==t;)G.push(fe),y.test(r.charAt(S))?(fe=r.charAt(S),S++):(fe=t,_===0&&De(B));else G=t;return G!==t&&(x=ie,G=p()),ie=G,ie}if(X=n(),X!==t&&S===r.length)return X;throw X!==t&&S<r.length&&De(N()),se(q,H<r.length?r.charAt(H):null,H<r.length?xe(H,H+1):xe(H,H))}mU.exports={SyntaxError:tc,parse:Kfe}});var ic=I((NZe,rc)=>{"use strict";function yU(r){return typeof r>"u"||r===null}function Ufe(r){return typeof r=="object"&&r!==null}function Hfe(r){return Array.isArray(r)?r:yU(r)?[]:[r]}function jfe(r,e){var t,i,n,s;if(e)for(s=Object.keys(e),t=0,i=s.length;t<i;t+=1)n=s[t],r[n]=e[n];return r}function Gfe(r,e){var t="",i;for(i=0;i<e;i+=1)t+=r;return t}function Yfe(r){return r===0&&Number.NEGATIVE_INFINITY===1/r}rc.exports.isNothing=yU;rc.exports.isObject=Ufe;rc.exports.toArray=Hfe;rc.exports.repeat=Gfe;rc.exports.isNegativeZero=Yfe;rc.exports.extend=jfe});var Ng=I((TZe,wU)=>{"use strict";function Xp(r,e){Error.call(this),this.name="YAMLException",this.reason=r,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Xp.prototype=Object.create(Error.prototype);Xp.prototype.constructor=Xp;Xp.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t};wU.exports=Xp});var QU=I((LZe,bU)=>{"use strict";var BU=ic();function HS(r,e,t,i,n){this.name=r,this.buffer=e,this.position=t,this.line=i,this.column=n}HS.prototype.getSnippet=function(e,t){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,t=t||75,i="",n=this.position;n>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(n-1))===-1;)if(n-=1,this.position-n>t/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;o<this.buffer.length&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(o))===-1;)if(o+=1,o-this.position>t/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),BU.repeat(" ",e)+i+a+s+` +`+BU.repeat(" ",e+this.position-n+i.length)+"^"};HS.prototype.toString=function(e){var t,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(i+=`: +`+t)),i};bU.exports=HS});var ni=I((OZe,vU)=>{"use strict";var SU=Ng(),qfe=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],Jfe=["scalar","sequence","mapping"];function Wfe(r){var e={};return r!==null&&Object.keys(r).forEach(function(t){r[t].forEach(function(i){e[String(i)]=t})}),e}function zfe(r,e){if(e=e||{},Object.keys(e).forEach(function(t){if(qfe.indexOf(t)===-1)throw new SU('Unknown option "'+t+'" is met in definition of "'+r+'" YAML type.')}),this.tag=r,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=Wfe(e.styleAliases||null),Jfe.indexOf(this.kind)===-1)throw new SU('Unknown kind "'+this.kind+'" is specified for "'+r+'" YAML type.')}vU.exports=zfe});var nc=I((MZe,xU)=>{"use strict";var PU=ic(),pI=Ng(),Vfe=ni();function jS(r,e,t){var i=[];return r.include.forEach(function(n){t=jS(n,e,t)}),r[e].forEach(function(n){t.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),t.push(n)}),t.filter(function(n,s){return i.indexOf(s)===-1})}function Xfe(){var r={scalar:{},sequence:{},mapping:{},fallback:{}},e,t;function i(n){r[n.kind][n.tag]=r.fallback[n.tag]=n}for(e=0,t=arguments.length;e<t;e+=1)arguments[e].forEach(i);return r}function Tg(r){this.include=r.include||[],this.implicit=r.implicit||[],this.explicit=r.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&e.loadKind!=="scalar")throw new pI("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=jS(this,"implicit",[]),this.compiledExplicit=jS(this,"explicit",[]),this.compiledTypeMap=Xfe(this.compiledImplicit,this.compiledExplicit)}Tg.DEFAULT=null;Tg.create=function(){var e,t;switch(arguments.length){case 1:e=Tg.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new pI("Wrong number of arguments for Schema.create function")}if(e=PU.toArray(e),t=PU.toArray(t),!e.every(function(i){return i instanceof Tg}))throw new pI("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(i){return i instanceof Vfe}))throw new pI("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new Tg({include:e,explicit:t})};xU.exports=Tg});var DU=I((KZe,kU)=>{"use strict";var Zfe=ni();kU.exports=new Zfe("tag:yaml.org,2002:str",{kind:"scalar",construct:function(r){return r!==null?r:""}})});var FU=I((UZe,RU)=>{"use strict";var _fe=ni();RU.exports=new _fe("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(r){return r!==null?r:[]}})});var TU=I((HZe,NU)=>{"use strict";var $fe=ni();NU.exports=new $fe("tag:yaml.org,2002:map",{kind:"mapping",construct:function(r){return r!==null?r:{}}})});var dI=I((jZe,LU)=>{"use strict";var ehe=nc();LU.exports=new ehe({explicit:[DU(),FU(),TU()]})});var MU=I((GZe,OU)=>{"use strict";var the=ni();function rhe(r){if(r===null)return!0;var e=r.length;return e===1&&r==="~"||e===4&&(r==="null"||r==="Null"||r==="NULL")}function ihe(){return null}function nhe(r){return r===null}OU.exports=new the("tag:yaml.org,2002:null",{kind:"scalar",resolve:rhe,construct:ihe,predicate:nhe,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var UU=I((YZe,KU)=>{"use strict";var she=ni();function ohe(r){if(r===null)return!1;var e=r.length;return e===4&&(r==="true"||r==="True"||r==="TRUE")||e===5&&(r==="false"||r==="False"||r==="FALSE")}function ahe(r){return r==="true"||r==="True"||r==="TRUE"}function Ahe(r){return Object.prototype.toString.call(r)==="[object Boolean]"}KU.exports=new she("tag:yaml.org,2002:bool",{kind:"scalar",resolve:ohe,construct:ahe,predicate:Ahe,represent:{lowercase:function(r){return r?"true":"false"},uppercase:function(r){return r?"TRUE":"FALSE"},camelcase:function(r){return r?"True":"False"}},defaultStyle:"lowercase"})});var jU=I((qZe,HU)=>{"use strict";var lhe=ic(),che=ni();function uhe(r){return 48<=r&&r<=57||65<=r&&r<=70||97<=r&&r<=102}function ghe(r){return 48<=r&&r<=55}function fhe(r){return 48<=r&&r<=57}function hhe(r){if(r===null)return!1;var e=r.length,t=0,i=!1,n;if(!e)return!1;if(n=r[t],(n==="-"||n==="+")&&(n=r[++t]),n==="0"){if(t+1===e)return!0;if(n=r[++t],n==="b"){for(t++;t<e;t++)if(n=r[t],n!=="_"){if(n!=="0"&&n!=="1")return!1;i=!0}return i&&n!=="_"}if(n==="x"){for(t++;t<e;t++)if(n=r[t],n!=="_"){if(!uhe(r.charCodeAt(t)))return!1;i=!0}return i&&n!=="_"}for(;t<e;t++)if(n=r[t],n!=="_"){if(!ghe(r.charCodeAt(t)))return!1;i=!0}return i&&n!=="_"}if(n==="_")return!1;for(;t<e;t++)if(n=r[t],n!=="_"){if(n===":")break;if(!fhe(r.charCodeAt(t)))return!1;i=!0}return!i||n==="_"?!1:n!==":"?!0:/^(:[0-5]?[0-9])+$/.test(r.slice(t))}function phe(r){var e=r,t=1,i,n,s=[];return e.indexOf("_")!==-1&&(e=e.replace(/_/g,"")),i=e[0],(i==="-"||i==="+")&&(i==="-"&&(t=-1),e=e.slice(1),i=e[0]),e==="0"?0:i==="0"?e[1]==="b"?t*parseInt(e.slice(2),2):e[1]==="x"?t*parseInt(e,16):t*parseInt(e,8):e.indexOf(":")!==-1?(e.split(":").forEach(function(o){s.unshift(parseInt(o,10))}),e=0,n=1,s.forEach(function(o){e+=o*n,n*=60}),t*e):t*parseInt(e,10)}function dhe(r){return Object.prototype.toString.call(r)==="[object Number]"&&r%1===0&&!lhe.isNegativeZero(r)}HU.exports=new che("tag:yaml.org,2002:int",{kind:"scalar",resolve:hhe,construct:phe,predicate:dhe,represent:{binary:function(r){return r>=0?"0b"+r.toString(2):"-0b"+r.toString(2).slice(1)},octal:function(r){return r>=0?"0"+r.toString(8):"-0"+r.toString(8).slice(1)},decimal:function(r){return r.toString(10)},hexadecimal:function(r){return r>=0?"0x"+r.toString(16).toUpperCase():"-0x"+r.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var qU=I((JZe,YU)=>{"use strict";var GU=ic(),Che=ni(),mhe=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function Ehe(r){return!(r===null||!mhe.test(r)||r[r.length-1]==="_")}function Ihe(r){var e,t,i,n;return e=r.replace(/_/g,"").toLowerCase(),t=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(s){n.unshift(parseFloat(s,10))}),e=0,i=1,n.forEach(function(s){e+=s*i,i*=60}),t*e):t*parseFloat(e,10)}var yhe=/^[-+]?[0-9]+e/;function whe(r,e){var t;if(isNaN(r))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===r)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===r)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(GU.isNegativeZero(r))return"-0.0";return t=r.toString(10),yhe.test(t)?t.replace("e",".e"):t}function Bhe(r){return Object.prototype.toString.call(r)==="[object Number]"&&(r%1!==0||GU.isNegativeZero(r))}YU.exports=new Che("tag:yaml.org,2002:float",{kind:"scalar",resolve:Ehe,construct:Ihe,predicate:Bhe,represent:whe,defaultStyle:"lowercase"})});var GS=I((WZe,JU)=>{"use strict";var bhe=nc();JU.exports=new bhe({include:[dI()],implicit:[MU(),UU(),jU(),qU()]})});var YS=I((zZe,WU)=>{"use strict";var Qhe=nc();WU.exports=new Qhe({include:[GS()]})});var ZU=I((VZe,XU)=>{"use strict";var She=ni(),zU=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),VU=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function vhe(r){return r===null?!1:zU.exec(r)!==null||VU.exec(r)!==null}function Phe(r){var e,t,i,n,s,o,a,l=0,c=null,u,g,h;if(e=zU.exec(r),e===null&&(e=VU.exec(r)),e===null)throw new Error("Date resolve error");if(t=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(t,i,n));if(s=+e[4],o=+e[5],a=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(u=+e[10],g=+(e[11]||0),c=(u*60+g)*6e4,e[9]==="-"&&(c=-c)),h=new Date(Date.UTC(t,i,n,s,o,a,l)),c&&h.setTime(h.getTime()-c),h}function xhe(r){return r.toISOString()}XU.exports=new She("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:vhe,construct:Phe,instanceOf:Date,represent:xhe})});var $U=I((XZe,_U)=>{"use strict";var khe=ni();function Dhe(r){return r==="<<"||r===null}_U.exports=new khe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:Dhe})});var r2=I((ZZe,t2)=>{"use strict";var sc;try{e2=J,sc=e2("buffer").Buffer}catch{}var e2,Rhe=ni(),qS=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function Fhe(r){if(r===null)return!1;var e,t,i=0,n=r.length,s=qS;for(t=0;t<n;t++)if(e=s.indexOf(r.charAt(t)),!(e>64)){if(e<0)return!1;i+=6}return i%8===0}function Nhe(r){var e,t,i=r.replace(/[\r\n=]/g,""),n=i.length,s=qS,o=0,a=[];for(e=0;e<n;e++)e%4===0&&e&&(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)),o=o<<6|s.indexOf(i.charAt(e));return t=n%4*6,t===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):t===18?(a.push(o>>10&255),a.push(o>>2&255)):t===12&&a.push(o>>4&255),sc?sc.from?sc.from(a):new sc(a):a}function The(r){var e="",t=0,i,n,s=r.length,o=qS;for(i=0;i<s;i++)i%3===0&&i&&(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]),t=(t<<8)+r[i];return n=s%3,n===0?(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]):n===2?(e+=o[t>>10&63],e+=o[t>>4&63],e+=o[t<<2&63],e+=o[64]):n===1&&(e+=o[t>>2&63],e+=o[t<<4&63],e+=o[64],e+=o[64]),e}function Lhe(r){return sc&&sc.isBuffer(r)}t2.exports=new Rhe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:Fhe,construct:Nhe,predicate:Lhe,represent:The})});var n2=I(($Ze,i2)=>{"use strict";var Ohe=ni(),Mhe=Object.prototype.hasOwnProperty,Khe=Object.prototype.toString;function Uhe(r){if(r===null)return!0;var e=[],t,i,n,s,o,a=r;for(t=0,i=a.length;t<i;t+=1){if(n=a[t],o=!1,Khe.call(n)!=="[object Object]")return!1;for(s in n)if(Mhe.call(n,s))if(!o)o=!0;else return!1;if(!o)return!1;if(e.indexOf(s)===-1)e.push(s);else return!1}return!0}function Hhe(r){return r!==null?r:[]}i2.exports=new Ohe("tag:yaml.org,2002:omap",{kind:"sequence",resolve:Uhe,construct:Hhe})});var o2=I((e_e,s2)=>{"use strict";var jhe=ni(),Ghe=Object.prototype.toString;function Yhe(r){if(r===null)return!0;var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e<t;e+=1){if(i=o[e],Ghe.call(i)!=="[object Object]"||(n=Object.keys(i),n.length!==1))return!1;s[e]=[n[0],i[n[0]]]}return!0}function qhe(r){if(r===null)return[];var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e<t;e+=1)i=o[e],n=Object.keys(i),s[e]=[n[0],i[n[0]]];return s}s2.exports=new jhe("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:Yhe,construct:qhe})});var A2=I((t_e,a2)=>{"use strict";var Jhe=ni(),Whe=Object.prototype.hasOwnProperty;function zhe(r){if(r===null)return!0;var e,t=r;for(e in t)if(Whe.call(t,e)&&t[e]!==null)return!1;return!0}function Vhe(r){return r!==null?r:{}}a2.exports=new Jhe("tag:yaml.org,2002:set",{kind:"mapping",resolve:zhe,construct:Vhe})});var Lg=I((r_e,l2)=>{"use strict";var Xhe=nc();l2.exports=new Xhe({include:[YS()],implicit:[ZU(),$U()],explicit:[r2(),n2(),o2(),A2()]})});var u2=I((i_e,c2)=>{"use strict";var Zhe=ni();function _he(){return!0}function $he(){}function epe(){return""}function tpe(r){return typeof r>"u"}c2.exports=new Zhe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:_he,construct:$he,predicate:tpe,represent:epe})});var f2=I((n_e,g2)=>{"use strict";var rpe=ni();function ipe(r){if(r===null||r.length===0)return!1;var e=r,t=/\/([gim]*)$/.exec(r),i="";return!(e[0]==="/"&&(t&&(i=t[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function npe(r){var e=r,t=/\/([gim]*)$/.exec(r),i="";return e[0]==="/"&&(t&&(i=t[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function spe(r){var e="/"+r.source+"/";return r.global&&(e+="g"),r.multiline&&(e+="m"),r.ignoreCase&&(e+="i"),e}function ope(r){return Object.prototype.toString.call(r)==="[object RegExp]"}g2.exports=new rpe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:ipe,construct:npe,predicate:ope,represent:spe})});var d2=I((s_e,p2)=>{"use strict";var CI;try{h2=J,CI=h2("esprima")}catch{typeof window<"u"&&(CI=window.esprima)}var h2,ape=ni();function Ape(r){if(r===null)return!1;try{var e="("+r+")",t=CI.parse(e,{range:!0});return!(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")}catch{return!1}}function lpe(r){var e="("+r+")",t=CI.parse(e,{range:!0}),i=[],n;if(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return t.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=t.body[0].expression.body.range,t.body[0].expression.body.type==="BlockStatement"?new Function(i,e.slice(n[0]+1,n[1]-1)):new Function(i,"return "+e.slice(n[0],n[1]))}function cpe(r){return r.toString()}function upe(r){return Object.prototype.toString.call(r)==="[object Function]"}p2.exports=new ape("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:Ape,construct:lpe,predicate:upe,represent:cpe})});var Zp=I((a_e,m2)=>{"use strict";var C2=nc();m2.exports=C2.DEFAULT=new C2({include:[Lg()],explicit:[u2(),f2(),d2()]})});var O2=I((A_e,_p)=>{"use strict";var ba=ic(),Q2=Ng(),gpe=QU(),S2=Lg(),fpe=Zp(),kA=Object.prototype.hasOwnProperty,mI=1,v2=2,P2=3,EI=4,JS=1,hpe=2,E2=3,ppe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,dpe=/[\x85\u2028\u2029]/,Cpe=/[,\[\]\{\}]/,x2=/^(?:!|!!|![a-z\-]+!)$/i,k2=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function I2(r){return Object.prototype.toString.call(r)}function vo(r){return r===10||r===13}function ac(r){return r===9||r===32}function fn(r){return r===9||r===32||r===10||r===13}function Og(r){return r===44||r===91||r===93||r===123||r===125}function mpe(r){var e;return 48<=r&&r<=57?r-48:(e=r|32,97<=e&&e<=102?e-97+10:-1)}function Epe(r){return r===120?2:r===117?4:r===85?8:0}function Ipe(r){return 48<=r&&r<=57?r-48:-1}function y2(r){return r===48?"\0":r===97?"\x07":r===98?"\b":r===116||r===9?" ":r===110?` +`:r===118?"\v":r===102?"\f":r===114?"\r":r===101?"\x1B":r===32?" ":r===34?'"':r===47?"/":r===92?"\\":r===78?"\x85":r===95?"\xA0":r===76?"\u2028":r===80?"\u2029":""}function ype(r){return r<=65535?String.fromCharCode(r):String.fromCharCode((r-65536>>10)+55296,(r-65536&1023)+56320)}var D2=new Array(256),R2=new Array(256);for(oc=0;oc<256;oc++)D2[oc]=y2(oc)?1:0,R2[oc]=y2(oc);var oc;function wpe(r,e){this.input=r,this.filename=e.filename||null,this.schema=e.schema||fpe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=r.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function F2(r,e){return new Q2(e,new gpe(r.filename,r.input,r.position,r.line,r.position-r.lineStart))}function gt(r,e){throw F2(r,e)}function II(r,e){r.onWarning&&r.onWarning.call(null,F2(r,e))}var w2={YAML:function(e,t,i){var n,s,o;e.version!==null&>(e,"duplication of %YAML directive"),i.length!==1&>(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&>(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&>(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&II(e,"unsupported YAML version of the document")},TAG:function(e,t,i){var n,s;i.length!==2&>(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],x2.test(n)||gt(e,"ill-formed tag handle (first argument) of the TAG directive"),kA.call(e.tagMap,n)&>(e,'there is a previously declared suffix for "'+n+'" tag handle'),k2.test(s)||gt(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function xA(r,e,t,i){var n,s,o,a;if(e<t){if(a=r.input.slice(e,t),i)for(n=0,s=a.length;n<s;n+=1)o=a.charCodeAt(n),o===9||32<=o&&o<=1114111||gt(r,"expected valid JSON character");else ppe.test(a)&>(r,"the stream contains non-printable characters");r.result+=a}}function B2(r,e,t,i){var n,s,o,a;for(ba.isObject(t)||gt(r,"cannot merge mappings; the provided source object is unacceptable"),n=Object.keys(t),o=0,a=n.length;o<a;o+=1)s=n[o],kA.call(e,s)||(e[s]=t[s],i[s]=!0)}function Mg(r,e,t,i,n,s,o,a){var l,c;if(Array.isArray(n))for(n=Array.prototype.slice.call(n),l=0,c=n.length;l<c;l+=1)Array.isArray(n[l])&>(r,"nested arrays are not supported inside keys"),typeof n=="object"&&I2(n[l])==="[object Object]"&&(n[l]="[object Object]");if(typeof n=="object"&&I2(n)==="[object Object]"&&(n="[object Object]"),n=String(n),e===null&&(e={}),i==="tag:yaml.org,2002:merge")if(Array.isArray(s))for(l=0,c=s.length;l<c;l+=1)B2(r,e,s[l],t);else B2(r,e,s,t);else!r.json&&!kA.call(t,n)&&kA.call(e,n)&&(r.line=o||r.line,r.position=a||r.position,gt(r,"duplicated mapping key")),e[n]=s,delete t[n];return e}function WS(r){var e;e=r.input.charCodeAt(r.position),e===10?r.position++:e===13?(r.position++,r.input.charCodeAt(r.position)===10&&r.position++):gt(r,"a line break is expected"),r.line+=1,r.lineStart=r.position}function Jr(r,e,t){for(var i=0,n=r.input.charCodeAt(r.position);n!==0;){for(;ac(n);)n=r.input.charCodeAt(++r.position);if(e&&n===35)do n=r.input.charCodeAt(++r.position);while(n!==10&&n!==13&&n!==0);if(vo(n))for(WS(r),n=r.input.charCodeAt(r.position),i++,r.lineIndent=0;n===32;)r.lineIndent++,n=r.input.charCodeAt(++r.position);else break}return t!==-1&&i!==0&&r.lineIndent<t&&II(r,"deficient indentation"),i}function yI(r){var e=r.position,t;return t=r.input.charCodeAt(e),!!((t===45||t===46)&&t===r.input.charCodeAt(e+1)&&t===r.input.charCodeAt(e+2)&&(e+=3,t=r.input.charCodeAt(e),t===0||fn(t)))}function zS(r,e){e===1?r.result+=" ":e>1&&(r.result+=ba.repeat(` +`,e-1))}function Bpe(r,e,t){var i,n,s,o,a,l,c,u,g=r.kind,h=r.result,p;if(p=r.input.charCodeAt(r.position),fn(p)||Og(p)||p===35||p===38||p===42||p===33||p===124||p===62||p===39||p===34||p===37||p===64||p===96||(p===63||p===45)&&(n=r.input.charCodeAt(r.position+1),fn(n)||t&&Og(n)))return!1;for(r.kind="scalar",r.result="",s=o=r.position,a=!1;p!==0;){if(p===58){if(n=r.input.charCodeAt(r.position+1),fn(n)||t&&Og(n))break}else if(p===35){if(i=r.input.charCodeAt(r.position-1),fn(i))break}else{if(r.position===r.lineStart&&yI(r)||t&&Og(p))break;if(vo(p))if(l=r.line,c=r.lineStart,u=r.lineIndent,Jr(r,!1,-1),r.lineIndent>=e){a=!0,p=r.input.charCodeAt(r.position);continue}else{r.position=o,r.line=l,r.lineStart=c,r.lineIndent=u;break}}a&&(xA(r,s,o,!1),zS(r,r.line-l),s=o=r.position,a=!1),ac(p)||(o=r.position+1),p=r.input.charCodeAt(++r.position)}return xA(r,s,o,!1),r.result?!0:(r.kind=g,r.result=h,!1)}function bpe(r,e){var t,i,n;if(t=r.input.charCodeAt(r.position),t!==39)return!1;for(r.kind="scalar",r.result="",r.position++,i=n=r.position;(t=r.input.charCodeAt(r.position))!==0;)if(t===39)if(xA(r,i,r.position,!0),t=r.input.charCodeAt(++r.position),t===39)i=r.position,r.position++,n=r.position;else return!0;else vo(t)?(xA(r,i,n,!0),zS(r,Jr(r,!1,e)),i=n=r.position):r.position===r.lineStart&&yI(r)?gt(r,"unexpected end of the document within a single quoted scalar"):(r.position++,n=r.position);gt(r,"unexpected end of the stream within a single quoted scalar")}function Qpe(r,e){var t,i,n,s,o,a;if(a=r.input.charCodeAt(r.position),a!==34)return!1;for(r.kind="scalar",r.result="",r.position++,t=i=r.position;(a=r.input.charCodeAt(r.position))!==0;){if(a===34)return xA(r,t,r.position,!0),r.position++,!0;if(a===92){if(xA(r,t,r.position,!0),a=r.input.charCodeAt(++r.position),vo(a))Jr(r,!1,e);else if(a<256&&D2[a])r.result+=R2[a],r.position++;else if((o=Epe(a))>0){for(n=o,s=0;n>0;n--)a=r.input.charCodeAt(++r.position),(o=mpe(a))>=0?s=(s<<4)+o:gt(r,"expected hexadecimal character");r.result+=ype(s),r.position++}else gt(r,"unknown escape sequence");t=i=r.position}else vo(a)?(xA(r,t,i,!0),zS(r,Jr(r,!1,e)),t=i=r.position):r.position===r.lineStart&&yI(r)?gt(r,"unexpected end of the document within a double quoted scalar"):(r.position++,i=r.position)}gt(r,"unexpected end of the stream within a double quoted scalar")}function Spe(r,e){var t=!0,i,n=r.tag,s,o=r.anchor,a,l,c,u,g,h={},p,d,m,y;if(y=r.input.charCodeAt(r.position),y===91)l=93,g=!1,s=[];else if(y===123)l=125,g=!0,s={};else return!1;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),y=r.input.charCodeAt(++r.position);y!==0;){if(Jr(r,!0,e),y=r.input.charCodeAt(r.position),y===l)return r.position++,r.tag=n,r.anchor=o,r.kind=g?"mapping":"sequence",r.result=s,!0;t||gt(r,"missed comma between flow collection entries"),d=p=m=null,c=u=!1,y===63&&(a=r.input.charCodeAt(r.position+1),fn(a)&&(c=u=!0,r.position++,Jr(r,!0,e))),i=r.line,Kg(r,e,mI,!1,!0),d=r.tag,p=r.result,Jr(r,!0,e),y=r.input.charCodeAt(r.position),(u||r.line===i)&&y===58&&(c=!0,y=r.input.charCodeAt(++r.position),Jr(r,!0,e),Kg(r,e,mI,!1,!0),m=r.result),g?Mg(r,s,h,d,p,m):c?s.push(Mg(r,null,h,d,p,m)):s.push(p),Jr(r,!0,e),y=r.input.charCodeAt(r.position),y===44?(t=!0,y=r.input.charCodeAt(++r.position)):t=!1}gt(r,"unexpected end of the stream within a flow collection")}function vpe(r,e){var t,i,n=JS,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=r.input.charCodeAt(r.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(r.kind="scalar",r.result="";g!==0;)if(g=r.input.charCodeAt(++r.position),g===43||g===45)JS===n?n=g===43?E2:hpe:gt(r,"repeat of a chomping mode identifier");else if((u=Ipe(g))>=0)u===0?gt(r,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?gt(r,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(ac(g)){do g=r.input.charCodeAt(++r.position);while(ac(g));if(g===35)do g=r.input.charCodeAt(++r.position);while(!vo(g)&&g!==0)}for(;g!==0;){for(WS(r),r.lineIndent=0,g=r.input.charCodeAt(r.position);(!o||r.lineIndent<a)&&g===32;)r.lineIndent++,g=r.input.charCodeAt(++r.position);if(!o&&r.lineIndent>a&&(a=r.lineIndent),vo(g)){l++;continue}if(r.lineIndent<a){n===E2?r.result+=ba.repeat(` +`,s?1+l:l):n===JS&&s&&(r.result+=` +`);break}for(i?ac(g)?(c=!0,r.result+=ba.repeat(` +`,s?1+l:l)):c?(c=!1,r.result+=ba.repeat(` +`,l+1)):l===0?s&&(r.result+=" "):r.result+=ba.repeat(` +`,l):r.result+=ba.repeat(` +`,s?1+l:l),s=!0,o=!0,l=0,t=r.position;!vo(g)&&g!==0;)g=r.input.charCodeAt(++r.position);xA(r,t,r.position,!1)}return!0}function b2(r,e){var t,i=r.tag,n=r.anchor,s=[],o,a=!1,l;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),l=r.input.charCodeAt(r.position);l!==0&&!(l!==45||(o=r.input.charCodeAt(r.position+1),!fn(o)));){if(a=!0,r.position++,Jr(r,!0,-1)&&r.lineIndent<=e){s.push(null),l=r.input.charCodeAt(r.position);continue}if(t=r.line,Kg(r,e,P2,!1,!0),s.push(r.result),Jr(r,!0,-1),l=r.input.charCodeAt(r.position),(r.line===t||r.lineIndent>e)&&l!==0)gt(r,"bad indentation of a sequence entry");else if(r.lineIndent<e)break}return a?(r.tag=i,r.anchor=n,r.kind="sequence",r.result=s,!0):!1}function Ppe(r,e,t){var i,n,s,o,a=r.tag,l=r.anchor,c={},u={},g=null,h=null,p=null,d=!1,m=!1,y;for(r.anchor!==null&&(r.anchorMap[r.anchor]=c),y=r.input.charCodeAt(r.position);y!==0;){if(i=r.input.charCodeAt(r.position+1),s=r.line,o=r.position,(y===63||y===58)&&fn(i))y===63?(d&&(Mg(r,c,u,g,h,null),g=h=p=null),m=!0,d=!0,n=!0):d?(d=!1,n=!0):gt(r,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),r.position+=1,y=i;else if(Kg(r,t,v2,!1,!0))if(r.line===s){for(y=r.input.charCodeAt(r.position);ac(y);)y=r.input.charCodeAt(++r.position);if(y===58)y=r.input.charCodeAt(++r.position),fn(y)||gt(r,"a whitespace character is expected after the key-value separator within a block mapping"),d&&(Mg(r,c,u,g,h,null),g=h=p=null),m=!0,d=!1,n=!1,g=r.tag,h=r.result;else if(m)gt(r,"can not read an implicit mapping pair; a colon is missed");else return r.tag=a,r.anchor=l,!0}else if(m)gt(r,"can not read a block mapping entry; a multiline key may not be an implicit key");else return r.tag=a,r.anchor=l,!0;else break;if((r.line===s||r.lineIndent>e)&&(Kg(r,e,EI,!0,n)&&(d?h=r.result:p=r.result),d||(Mg(r,c,u,g,h,p,s,o),g=h=p=null),Jr(r,!0,-1),y=r.input.charCodeAt(r.position)),r.lineIndent>e&&y!==0)gt(r,"bad indentation of a mapping entry");else if(r.lineIndent<e)break}return d&&Mg(r,c,u,g,h,null),m&&(r.tag=a,r.anchor=l,r.kind="mapping",r.result=c),m}function xpe(r){var e,t=!1,i=!1,n,s,o;if(o=r.input.charCodeAt(r.position),o!==33)return!1;if(r.tag!==null&>(r,"duplication of a tag property"),o=r.input.charCodeAt(++r.position),o===60?(t=!0,o=r.input.charCodeAt(++r.position)):o===33?(i=!0,n="!!",o=r.input.charCodeAt(++r.position)):n="!",e=r.position,t){do o=r.input.charCodeAt(++r.position);while(o!==0&&o!==62);r.position<r.length?(s=r.input.slice(e,r.position),o=r.input.charCodeAt(++r.position)):gt(r,"unexpected end of the stream within a verbatim tag")}else{for(;o!==0&&!fn(o);)o===33&&(i?gt(r,"tag suffix cannot contain exclamation marks"):(n=r.input.slice(e-1,r.position+1),x2.test(n)||gt(r,"named tag handle cannot contain such characters"),i=!0,e=r.position+1)),o=r.input.charCodeAt(++r.position);s=r.input.slice(e,r.position),Cpe.test(s)&>(r,"tag suffix cannot contain flow indicator characters")}return s&&!k2.test(s)&>(r,"tag name cannot contain such characters: "+s),t?r.tag=s:kA.call(r.tagMap,n)?r.tag=r.tagMap[n]+s:n==="!"?r.tag="!"+s:n==="!!"?r.tag="tag:yaml.org,2002:"+s:gt(r,'undeclared tag handle "'+n+'"'),!0}function kpe(r){var e,t;if(t=r.input.charCodeAt(r.position),t!==38)return!1;for(r.anchor!==null&>(r,"duplication of an anchor property"),t=r.input.charCodeAt(++r.position),e=r.position;t!==0&&!fn(t)&&!Og(t);)t=r.input.charCodeAt(++r.position);return r.position===e&>(r,"name of an anchor node must contain at least one character"),r.anchor=r.input.slice(e,r.position),!0}function Dpe(r){var e,t,i;if(i=r.input.charCodeAt(r.position),i!==42)return!1;for(i=r.input.charCodeAt(++r.position),e=r.position;i!==0&&!fn(i)&&!Og(i);)i=r.input.charCodeAt(++r.position);return r.position===e&>(r,"name of an alias node must contain at least one character"),t=r.input.slice(e,r.position),kA.call(r.anchorMap,t)||gt(r,'unidentified alias "'+t+'"'),r.result=r.anchorMap[t],Jr(r,!0,-1),!0}function Kg(r,e,t,i,n){var s,o,a,l=1,c=!1,u=!1,g,h,p,d,m;if(r.listener!==null&&r.listener("open",r),r.tag=null,r.anchor=null,r.kind=null,r.result=null,s=o=a=EI===t||P2===t,i&&Jr(r,!0,-1)&&(c=!0,r.lineIndent>e?l=1:r.lineIndent===e?l=0:r.lineIndent<e&&(l=-1)),l===1)for(;xpe(r)||kpe(r);)Jr(r,!0,-1)?(c=!0,a=s,r.lineIndent>e?l=1:r.lineIndent===e?l=0:r.lineIndent<e&&(l=-1)):a=!1;if(a&&(a=c||n),(l===1||EI===t)&&(mI===t||v2===t?d=e:d=e+1,m=r.position-r.lineStart,l===1?a&&(b2(r,m)||Ppe(r,m,d))||Spe(r,d)?u=!0:(o&&vpe(r,d)||bpe(r,d)||Qpe(r,d)?u=!0:Dpe(r)?(u=!0,(r.tag!==null||r.anchor!==null)&>(r,"alias node should not have any properties")):Bpe(r,d,mI===t)&&(u=!0,r.tag===null&&(r.tag="?")),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):l===0&&(u=a&&b2(r,m))),r.tag!==null&&r.tag!=="!")if(r.tag==="?"){for(r.result!==null&&r.kind!=="scalar"&>(r,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+r.kind+'"'),g=0,h=r.implicitTypes.length;g<h;g+=1)if(p=r.implicitTypes[g],p.resolve(r.result)){r.result=p.construct(r.result),r.tag=p.tag,r.anchor!==null&&(r.anchorMap[r.anchor]=r.result);break}}else kA.call(r.typeMap[r.kind||"fallback"],r.tag)?(p=r.typeMap[r.kind||"fallback"][r.tag],r.result!==null&&p.kind!==r.kind&>(r,"unacceptable node kind for !<"+r.tag+'> tag; it should be "'+p.kind+'", not "'+r.kind+'"'),p.resolve(r.result)?(r.result=p.construct(r.result),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):gt(r,"cannot resolve a node with !<"+r.tag+"> explicit tag")):gt(r,"unknown tag !<"+r.tag+">");return r.listener!==null&&r.listener("close",r),r.tag!==null||r.anchor!==null||u}function Rpe(r){var e=r.position,t,i,n,s=!1,o;for(r.version=null,r.checkLineBreaks=r.legacy,r.tagMap={},r.anchorMap={};(o=r.input.charCodeAt(r.position))!==0&&(Jr(r,!0,-1),o=r.input.charCodeAt(r.position),!(r.lineIndent>0||o!==37));){for(s=!0,o=r.input.charCodeAt(++r.position),t=r.position;o!==0&&!fn(o);)o=r.input.charCodeAt(++r.position);for(i=r.input.slice(t,r.position),n=[],i.length<1&>(r,"directive name must not be less than one character in length");o!==0;){for(;ac(o);)o=r.input.charCodeAt(++r.position);if(o===35){do o=r.input.charCodeAt(++r.position);while(o!==0&&!vo(o));break}if(vo(o))break;for(t=r.position;o!==0&&!fn(o);)o=r.input.charCodeAt(++r.position);n.push(r.input.slice(t,r.position))}o!==0&&WS(r),kA.call(w2,i)?w2[i](r,i,n):II(r,'unknown document directive "'+i+'"')}if(Jr(r,!0,-1),r.lineIndent===0&&r.input.charCodeAt(r.position)===45&&r.input.charCodeAt(r.position+1)===45&&r.input.charCodeAt(r.position+2)===45?(r.position+=3,Jr(r,!0,-1)):s&>(r,"directives end mark is expected"),Kg(r,r.lineIndent-1,EI,!1,!0),Jr(r,!0,-1),r.checkLineBreaks&&dpe.test(r.input.slice(e,r.position))&&II(r,"non-ASCII line breaks are interpreted as content"),r.documents.push(r.result),r.position===r.lineStart&&yI(r)){r.input.charCodeAt(r.position)===46&&(r.position+=3,Jr(r,!0,-1));return}if(r.position<r.length-1)gt(r,"end of the stream or a document separator is expected");else return}function N2(r,e){r=String(r),e=e||{},r.length!==0&&(r.charCodeAt(r.length-1)!==10&&r.charCodeAt(r.length-1)!==13&&(r+=` +`),r.charCodeAt(0)===65279&&(r=r.slice(1)));var t=new wpe(r,e),i=r.indexOf("\0");for(i!==-1&&(t.position=i,gt(t,"null byte is not allowed in input")),t.input+="\0";t.input.charCodeAt(t.position)===32;)t.lineIndent+=1,t.position+=1;for(;t.position<t.length-1;)Rpe(t);return t.documents}function T2(r,e,t){e!==null&&typeof e=="object"&&typeof t>"u"&&(t=e,e=null);var i=N2(r,t);if(typeof e!="function")return i;for(var n=0,s=i.length;n<s;n+=1)e(i[n])}function L2(r,e){var t=N2(r,e);if(t.length!==0){if(t.length===1)return t[0];throw new Q2("expected a single document in the stream, but found more")}}function Fpe(r,e,t){return typeof e=="object"&&e!==null&&typeof t>"u"&&(t=e,e=null),T2(r,e,ba.extend({schema:S2},t))}function Npe(r,e){return L2(r,ba.extend({schema:S2},e))}_p.exports.loadAll=T2;_p.exports.load=L2;_p.exports.safeLoadAll=Fpe;_p.exports.safeLoad=Npe});var oH=I((l_e,_S)=>{"use strict";var ed=ic(),td=Ng(),Tpe=Zp(),Lpe=Lg(),q2=Object.prototype.toString,J2=Object.prototype.hasOwnProperty,Ope=9,$p=10,Mpe=13,Kpe=32,Upe=33,Hpe=34,W2=35,jpe=37,Gpe=38,Ype=39,qpe=42,z2=44,Jpe=45,V2=58,Wpe=61,zpe=62,Vpe=63,Xpe=64,X2=91,Z2=93,Zpe=96,_2=123,_pe=124,$2=125,Ni={};Ni[0]="\\0";Ni[7]="\\a";Ni[8]="\\b";Ni[9]="\\t";Ni[10]="\\n";Ni[11]="\\v";Ni[12]="\\f";Ni[13]="\\r";Ni[27]="\\e";Ni[34]='\\"';Ni[92]="\\\\";Ni[133]="\\N";Ni[160]="\\_";Ni[8232]="\\L";Ni[8233]="\\P";var $pe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function ede(r,e){var t,i,n,s,o,a,l;if(e===null)return{};for(t={},i=Object.keys(e),n=0,s=i.length;n<s;n+=1)o=i[n],a=String(e[o]),o.slice(0,2)==="!!"&&(o="tag:yaml.org,2002:"+o.slice(2)),l=r.compiledTypeMap.fallback[o],l&&J2.call(l.styleAliases,a)&&(a=l.styleAliases[a]),t[o]=a;return t}function M2(r){var e,t,i;if(e=r.toString(16).toUpperCase(),r<=255)t="x",i=2;else if(r<=65535)t="u",i=4;else if(r<=4294967295)t="U",i=8;else throw new td("code point within a string may not be greater than 0xFFFFFFFF");return"\\"+t+ed.repeat("0",i-e.length)+e}function tde(r){this.schema=r.schema||Tpe,this.indent=Math.max(1,r.indent||2),this.noArrayIndent=r.noArrayIndent||!1,this.skipInvalid=r.skipInvalid||!1,this.flowLevel=ed.isNothing(r.flowLevel)?-1:r.flowLevel,this.styleMap=ede(this.schema,r.styles||null),this.sortKeys=r.sortKeys||!1,this.lineWidth=r.lineWidth||80,this.noRefs=r.noRefs||!1,this.noCompatMode=r.noCompatMode||!1,this.condenseFlow=r.condenseFlow||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function K2(r,e){for(var t=ed.repeat(" ",e),i=0,n=-1,s="",o,a=r.length;i<a;)n=r.indexOf(` +`,i),n===-1?(o=r.slice(i),i=a):(o=r.slice(i,n+1),i=n+1),o.length&&o!==` +`&&(s+=t),s+=o;return s}function VS(r,e){return` +`+ed.repeat(" ",r.indent*e)}function rde(r,e){var t,i,n;for(t=0,i=r.implicitTypes.length;t<i;t+=1)if(n=r.implicitTypes[t],n.resolve(e))return!0;return!1}function ZS(r){return r===Kpe||r===Ope}function Ug(r){return 32<=r&&r<=126||161<=r&&r<=55295&&r!==8232&&r!==8233||57344<=r&&r<=65533&&r!==65279||65536<=r&&r<=1114111}function ide(r){return Ug(r)&&!ZS(r)&&r!==65279&&r!==Mpe&&r!==$p}function U2(r,e){return Ug(r)&&r!==65279&&r!==z2&&r!==X2&&r!==Z2&&r!==_2&&r!==$2&&r!==V2&&(r!==W2||e&&ide(e))}function nde(r){return Ug(r)&&r!==65279&&!ZS(r)&&r!==Jpe&&r!==Vpe&&r!==V2&&r!==z2&&r!==X2&&r!==Z2&&r!==_2&&r!==$2&&r!==W2&&r!==Gpe&&r!==qpe&&r!==Upe&&r!==_pe&&r!==Wpe&&r!==zpe&&r!==Ype&&r!==Hpe&&r!==jpe&&r!==Xpe&&r!==Zpe}function eH(r){var e=/^\n* /;return e.test(r)}var tH=1,rH=2,iH=3,nH=4,wI=5;function sde(r,e,t,i,n){var s,o,a,l=!1,c=!1,u=i!==-1,g=-1,h=nde(r.charCodeAt(0))&&!ZS(r.charCodeAt(r.length-1));if(e)for(s=0;s<r.length;s++){if(o=r.charCodeAt(s),!Ug(o))return wI;a=s>0?r.charCodeAt(s-1):null,h=h&&U2(o,a)}else{for(s=0;s<r.length;s++){if(o=r.charCodeAt(s),o===$p)l=!0,u&&(c=c||s-g-1>i&&r[g+1]!==" ",g=s);else if(!Ug(o))return wI;a=s>0?r.charCodeAt(s-1):null,h=h&&U2(o,a)}c=c||u&&s-g-1>i&&r[g+1]!==" "}return!l&&!c?h&&!n(r)?tH:rH:t>9&&eH(r)?wI:c?nH:iH}function ode(r,e,t,i){r.dump=function(){if(e.length===0)return"''";if(!r.noCompatMode&&$pe.indexOf(e)!==-1)return"'"+e+"'";var n=r.indent*Math.max(1,t),s=r.lineWidth===-1?-1:Math.max(Math.min(r.lineWidth,40),r.lineWidth-n),o=i||r.flowLevel>-1&&t>=r.flowLevel;function a(l){return rde(r,l)}switch(sde(e,o,r.indent,s,a)){case tH:return e;case rH:return"'"+e.replace(/'/g,"''")+"'";case iH:return"|"+H2(e,r.indent)+j2(K2(e,n));case nH:return">"+H2(e,r.indent)+j2(K2(ade(e,s),n));case wI:return'"'+Ade(e,s)+'"';default:throw new td("impossible error: invalid scalar style")}}()}function H2(r,e){var t=eH(r)?String(e):"",i=r[r.length-1]===` +`,n=i&&(r[r.length-2]===` +`||r===` +`),s=n?"+":i?"":"-";return t+s+` +`}function j2(r){return r[r.length-1]===` +`?r.slice(0,-1):r}function ade(r,e){for(var t=/(\n+)([^\n]*)/g,i=function(){var c=r.indexOf(` +`);return c=c!==-1?c:r.length,t.lastIndex=c,G2(r.slice(0,c),e)}(),n=r[0]===` +`||r[0]===" ",s,o;o=t.exec(r);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` +`:"")+G2(l,e),n=s}return i}function G2(r,e){if(r===""||r[0]===" ")return r;for(var t=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=t.exec(r);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` +`+r.slice(n,s),n=s+1),o=a;return l+=` +`,r.length-n>e&&o>n?l+=r.slice(n,o)+` +`+r.slice(o+1):l+=r.slice(n),l.slice(1)}function Ade(r){for(var e="",t,i,n,s=0;s<r.length;s++){if(t=r.charCodeAt(s),t>=55296&&t<=56319&&(i=r.charCodeAt(s+1),i>=56320&&i<=57343)){e+=M2((t-55296)*1024+i-56320+65536),s++;continue}n=Ni[t],e+=!n&&Ug(t)?r[s]:n||M2(t)}return e}function lde(r,e,t){var i="",n=r.tag,s,o;for(s=0,o=t.length;s<o;s+=1)Ac(r,e,t[s],!1,!1)&&(s!==0&&(i+=","+(r.condenseFlow?"":" ")),i+=r.dump);r.tag=n,r.dump="["+i+"]"}function cde(r,e,t,i){var n="",s=r.tag,o,a;for(o=0,a=t.length;o<a;o+=1)Ac(r,e+1,t[o],!0,!0)&&((!i||o!==0)&&(n+=VS(r,e)),r.dump&&$p===r.dump.charCodeAt(0)?n+="-":n+="- ",n+=r.dump);r.tag=s,r.dump=n||"[]"}function ude(r,e,t){var i="",n=r.tag,s=Object.keys(t),o,a,l,c,u;for(o=0,a=s.length;o<a;o+=1)u="",o!==0&&(u+=", "),r.condenseFlow&&(u+='"'),l=s[o],c=t[l],Ac(r,e,l,!1,!1)&&(r.dump.length>1024&&(u+="? "),u+=r.dump+(r.condenseFlow?'"':"")+":"+(r.condenseFlow?"":" "),Ac(r,e,c,!1,!1)&&(u+=r.dump,i+=u));r.tag=n,r.dump="{"+i+"}"}function gde(r,e,t,i){var n="",s=r.tag,o=Object.keys(t),a,l,c,u,g,h;if(r.sortKeys===!0)o.sort();else if(typeof r.sortKeys=="function")o.sort(r.sortKeys);else if(r.sortKeys)throw new td("sortKeys must be a boolean or a function");for(a=0,l=o.length;a<l;a+=1)h="",(!i||a!==0)&&(h+=VS(r,e)),c=o[a],u=t[c],Ac(r,e+1,c,!0,!0,!0)&&(g=r.tag!==null&&r.tag!=="?"||r.dump&&r.dump.length>1024,g&&(r.dump&&$p===r.dump.charCodeAt(0)?h+="?":h+="? "),h+=r.dump,g&&(h+=VS(r,e)),Ac(r,e+1,u,!0,g)&&(r.dump&&$p===r.dump.charCodeAt(0)?h+=":":h+=": ",h+=r.dump,n+=h));r.tag=s,r.dump=n||"{}"}function Y2(r,e,t){var i,n,s,o,a,l;for(n=t?r.explicitTypes:r.implicitTypes,s=0,o=n.length;s<o;s+=1)if(a=n[s],(a.instanceOf||a.predicate)&&(!a.instanceOf||typeof e=="object"&&e instanceof a.instanceOf)&&(!a.predicate||a.predicate(e))){if(r.tag=t?a.tag:"?",a.represent){if(l=r.styleMap[a.tag]||a.defaultStyle,q2.call(a.represent)==="[object Function]")i=a.represent(e,l);else if(J2.call(a.represent,l))i=a.represent[l](e,l);else throw new td("!<"+a.tag+'> tag resolver accepts not "'+l+'" style');r.dump=i}return!0}return!1}function Ac(r,e,t,i,n,s){r.tag=null,r.dump=t,Y2(r,t,!1)||Y2(r,t,!0);var o=q2.call(r.dump);i&&(i=r.flowLevel<0||r.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=r.duplicates.indexOf(t),c=l!==-1),(r.tag!==null&&r.tag!=="?"||c||r.indent!==2&&e>0)&&(n=!1),c&&r.usedDuplicates[l])r.dump="*ref_"+l;else{if(a&&c&&!r.usedDuplicates[l]&&(r.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(r.dump).length!==0?(gde(r,e,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(ude(r,e,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump));else if(o==="[object Array]"){var u=r.noArrayIndent&&e>0?e-1:e;i&&r.dump.length!==0?(cde(r,u,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(lde(r,u,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump))}else if(o==="[object String]")r.tag!=="?"&&ode(r,r.dump,e,s);else{if(r.skipInvalid)return!1;throw new td("unacceptable kind of an object to dump "+o)}r.tag!==null&&r.tag!=="?"&&(r.dump="!<"+r.tag+"> "+r.dump)}return!0}function fde(r,e){var t=[],i=[],n,s;for(XS(r,t,i),n=0,s=i.length;n<s;n+=1)e.duplicates.push(t[i[n]]);e.usedDuplicates=new Array(s)}function XS(r,e,t){var i,n,s;if(r!==null&&typeof r=="object")if(n=e.indexOf(r),n!==-1)t.indexOf(n)===-1&&t.push(n);else if(e.push(r),Array.isArray(r))for(n=0,s=r.length;n<s;n+=1)XS(r[n],e,t);else for(i=Object.keys(r),n=0,s=i.length;n<s;n+=1)XS(r[i[n]],e,t)}function sH(r,e){e=e||{};var t=new tde(e);return t.noRefs||fde(r,t),Ac(t,0,r,!0,!0)?t.dump+` +`:""}function hde(r,e){return sH(r,ed.extend({schema:Lpe},e))}_S.exports.dump=sH;_S.exports.safeDump=hde});var AH=I((c_e,Dr)=>{"use strict";var BI=O2(),aH=oH();function bI(r){return function(){throw new Error("Function "+r+" is deprecated and cannot be used.")}}Dr.exports.Type=ni();Dr.exports.Schema=nc();Dr.exports.FAILSAFE_SCHEMA=dI();Dr.exports.JSON_SCHEMA=GS();Dr.exports.CORE_SCHEMA=YS();Dr.exports.DEFAULT_SAFE_SCHEMA=Lg();Dr.exports.DEFAULT_FULL_SCHEMA=Zp();Dr.exports.load=BI.load;Dr.exports.loadAll=BI.loadAll;Dr.exports.safeLoad=BI.safeLoad;Dr.exports.safeLoadAll=BI.safeLoadAll;Dr.exports.dump=aH.dump;Dr.exports.safeDump=aH.safeDump;Dr.exports.YAMLException=Ng();Dr.exports.MINIMAL_SCHEMA=dI();Dr.exports.SAFE_SCHEMA=Lg();Dr.exports.DEFAULT_SCHEMA=Zp();Dr.exports.scan=bI("scan");Dr.exports.parse=bI("parse");Dr.exports.compose=bI("compose");Dr.exports.addConstructor=bI("addConstructor")});var cH=I((u_e,lH)=>{"use strict";var pde=AH();lH.exports=pde});var gH=I((g_e,uH)=>{"use strict";function dde(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function lc(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,lc)}dde(lc,Error);lc.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g<c.parts.length;g++)u+=c.parts[g]instanceof Array?s(c.parts[g][0])+"-"+s(c.parts[g][1]):s(c.parts[g]);return"["+(c.inverted?"^":"")+u+"]"},any:function(c){return"any character"},end:function(c){return"end of input"},other:function(c){return c.description}};function i(c){return c.charCodeAt(0).toString(16).toUpperCase()}function n(c){return c.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function s(c){return c.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,function(u){return"\\x0"+i(u)}).replace(/[\x10-\x1F\x7F-\x9F]/g,function(u){return"\\x"+i(u)})}function o(c){return t[c.type](c)}function a(c){var u=new Array(c.length),g,h;for(g=0;g<c.length;g++)u[g]=o(c[g]);if(u.sort(),u.length>0){for(g=1,h=1;g<u.length;g++)u[g-1]!==u[g]&&(u[h]=u[g],h++);u.length=h}switch(u.length){case 1:return u[0];case 2:return u[0]+" or "+u[1];default:return u.slice(0,-1).join(", ")+", or "+u[u.length-1]}}function l(c){return c?'"'+n(c)+'"':"end of input"}return"Expected "+a(r)+" but "+l(e)+" found."};function Cde(r,e){e=e!==void 0?e:{};var t={},i={Start:Us},n=Us,s=function(D){return[].concat(...D)},o="-",a=sr("-",!1),l=function(D){return D},c=function(D){return Object.assign({},...D)},u="#",g=sr("#",!1),h=Ml(),p=function(){return{}},d=":",m=sr(":",!1),y=function(D,Y){return{[D]:Y}},B=",",S=sr(",",!1),x=function(D,Y){return Y},F=function(D,Y,pe){return Object.assign({},...[D].concat(Y).map(Le=>({[Le]:pe})))},H=function(D){return D},q=function(D){return D},_=Ks("correct indentation"),X=" ",W=sr(" ",!1),Z=function(D){return D.length===QA*Ig},A=function(D){return D.length===(QA+1)*Ig},ne=function(){return QA++,!0},ue=function(){return QA--,!0},te=function(){return dg()},O=Ks("pseudostring"),N=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,ce=Ln(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),he=/^[^\r\n\t ,\][{}:#"']/,xe=Ln(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),De=function(){return dg().replace(/^ *| *$/g,"")},Re="--",se=sr("--",!1),Ae=/^[a-zA-Z\/0-9]/,ye=Ln([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),ge=/^[^\r\n\t :,]/,oe=Ln(["\r",` +`," "," ",":",","],!0,!1),Ye="null",ie=sr("null",!1),G=function(){return null},fe="true",re=sr("true",!1),de=function(){return!0},Ze="false",vt=sr("false",!1),mt=function(){return!1},Tr=Ks("string"),ti='"',ui=sr('"',!1),gr=function(){return""},gi=function(D){return D},ri=function(D){return D.join("")},Ms=/^[^"\\\0-\x1F\x7F]/,fr=Ln(['"',"\\",["\0",""],"\x7F"],!0,!1),Ei='\\"',rs=sr('\\"',!1),ua=function(){return'"'},CA="\\\\",gg=sr("\\\\",!1),is=function(){return"\\"},mA="\\/",ga=sr("\\/",!1),wp=function(){return"/"},EA="\\b",IA=sr("\\b",!1),Ir=function(){return"\b"},Nl="\\f",fg=sr("\\f",!1),Io=function(){return"\f"},hg="\\n",Bp=sr("\\n",!1),bp=function(){return` +`},Qr="\\r",Ri=sr("\\r",!1),yo=function(){return"\r"},Nn="\\t",ae=sr("\\t",!1),yt=function(){return" "},Tl="\\u",Tn=sr("\\u",!1),ns=function(D,Y,pe,Le){return String.fromCharCode(parseInt(`0x${D}${Y}${pe}${Le}`))},ss=/^[0-9a-fA-F]/,ut=Ln([["0","9"],["a","f"],["A","F"]],!1,!1),wo=Ks("blank space"),At=/^[ \t]/,An=Ln([" "," "],!1,!1),Q=Ks("white space"),Nt=/^[ \t\n\r]/,pg=Ln([" "," ",` +`,"\r"],!1,!1),Ll=`\r +`,Qp=sr(`\r +`,!1),Sp=` +`,vp=sr(` +`,!1),Pp="\r",xp=sr("\r",!1),j=0,Et=0,yA=[{line:1,column:1}],Wi=0,Ol=[],ze=0,fa;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function dg(){return r.substring(Et,j)}function OE(){return ln(Et,j)}function kp(D,Y){throw Y=Y!==void 0?Y:ln(Et,j),Kl([Ks(D)],r.substring(Et,j),Y)}function ME(D,Y){throw Y=Y!==void 0?Y:ln(Et,j),Cg(D,Y)}function sr(D,Y){return{type:"literal",text:D,ignoreCase:Y}}function Ln(D,Y,pe){return{type:"class",parts:D,inverted:Y,ignoreCase:pe}}function Ml(){return{type:"any"}}function Dp(){return{type:"end"}}function Ks(D){return{type:"other",description:D}}function ha(D){var Y=yA[D],pe;if(Y)return Y;for(pe=D-1;!yA[pe];)pe--;for(Y=yA[pe],Y={line:Y.line,column:Y.column};pe<D;)r.charCodeAt(pe)===10?(Y.line++,Y.column=1):Y.column++,pe++;return yA[D]=Y,Y}function ln(D,Y){var pe=ha(D),Le=ha(Y);return{start:{offset:D,line:pe.line,column:pe.column},end:{offset:Y,line:Le.line,column:Le.column}}}function Ne(D){j<Wi||(j>Wi&&(Wi=j,Ol=[]),Ol.push(D))}function Cg(D,Y){return new lc(D,null,null,Y)}function Kl(D,Y,pe){return new lc(lc.buildMessage(D,Y),D,Y,pe)}function Us(){var D;return D=mg(),D}function Ul(){var D,Y,pe;for(D=j,Y=[],pe=wA();pe!==t;)Y.push(pe),pe=wA();return Y!==t&&(Et=D,Y=s(Y)),D=Y,D}function wA(){var D,Y,pe,Le,ke;return D=j,Y=da(),Y!==t?(r.charCodeAt(j)===45?(pe=o,j++):(pe=t,ze===0&&Ne(a)),pe!==t?(Le=Lr(),Le!==t?(ke=pa(),ke!==t?(Et=D,Y=l(ke),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t),D}function mg(){var D,Y,pe;for(D=j,Y=[],pe=Eg();pe!==t;)Y.push(pe),pe=Eg();return Y!==t&&(Et=D,Y=c(Y)),D=Y,D}function Eg(){var D,Y,pe,Le,ke,Je,pt,Xt,Ea;if(D=j,Y=Lr(),Y===t&&(Y=null),Y!==t){if(pe=j,r.charCodeAt(j)===35?(Le=u,j++):(Le=t,ze===0&&Ne(g)),Le!==t){if(ke=[],Je=j,pt=j,ze++,Xt=js(),ze--,Xt===t?pt=void 0:(j=pt,pt=t),pt!==t?(r.length>j?(Xt=r.charAt(j),j++):(Xt=t,ze===0&&Ne(h)),Xt!==t?(pt=[pt,Xt],Je=pt):(j=Je,Je=t)):(j=Je,Je=t),Je!==t)for(;Je!==t;)ke.push(Je),Je=j,pt=j,ze++,Xt=js(),ze--,Xt===t?pt=void 0:(j=pt,pt=t),pt!==t?(r.length>j?(Xt=r.charAt(j),j++):(Xt=t,ze===0&&Ne(h)),Xt!==t?(pt=[pt,Xt],Je=pt):(j=Je,Je=t)):(j=Je,Je=t);else ke=t;ke!==t?(Le=[Le,ke],pe=Le):(j=pe,pe=t)}else j=pe,pe=t;if(pe===t&&(pe=null),pe!==t){if(Le=[],ke=Hs(),ke!==t)for(;ke!==t;)Le.push(ke),ke=Hs();else Le=t;Le!==t?(Et=D,Y=p(),D=Y):(j=D,D=t)}else j=D,D=t}else j=D,D=t;if(D===t&&(D=j,Y=da(),Y!==t?(pe=Rp(),pe!==t?(Le=Lr(),Le===t&&(Le=null),Le!==t?(r.charCodeAt(j)===58?(ke=d,j++):(ke=t,ze===0&&Ne(m)),ke!==t?(Je=Lr(),Je===t&&(Je=null),Je!==t?(pt=pa(),pt!==t?(Et=D,Y=y(pe,pt),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t),D===t&&(D=j,Y=da(),Y!==t?(pe=Ca(),pe!==t?(Le=Lr(),Le===t&&(Le=null),Le!==t?(r.charCodeAt(j)===58?(ke=d,j++):(ke=t,ze===0&&Ne(m)),ke!==t?(Je=Lr(),Je===t&&(Je=null),Je!==t?(pt=pa(),pt!==t?(Et=D,Y=y(pe,pt),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t),D===t))){if(D=j,Y=da(),Y!==t)if(pe=Ca(),pe!==t)if(Le=Lr(),Le!==t)if(ke=jl(),ke!==t){if(Je=[],pt=Hs(),pt!==t)for(;pt!==t;)Je.push(pt),pt=Hs();else Je=t;Je!==t?(Et=D,Y=y(pe,ke),D=Y):(j=D,D=t)}else j=D,D=t;else j=D,D=t;else j=D,D=t;else j=D,D=t;if(D===t)if(D=j,Y=da(),Y!==t)if(pe=Ca(),pe!==t){if(Le=[],ke=j,Je=Lr(),Je===t&&(Je=null),Je!==t?(r.charCodeAt(j)===44?(pt=B,j++):(pt=t,ze===0&&Ne(S)),pt!==t?(Xt=Lr(),Xt===t&&(Xt=null),Xt!==t?(Ea=Ca(),Ea!==t?(Et=ke,Je=x(pe,Ea),ke=Je):(j=ke,ke=t)):(j=ke,ke=t)):(j=ke,ke=t)):(j=ke,ke=t),ke!==t)for(;ke!==t;)Le.push(ke),ke=j,Je=Lr(),Je===t&&(Je=null),Je!==t?(r.charCodeAt(j)===44?(pt=B,j++):(pt=t,ze===0&&Ne(S)),pt!==t?(Xt=Lr(),Xt===t&&(Xt=null),Xt!==t?(Ea=Ca(),Ea!==t?(Et=ke,Je=x(pe,Ea),ke=Je):(j=ke,ke=t)):(j=ke,ke=t)):(j=ke,ke=t)):(j=ke,ke=t);else Le=t;Le!==t?(ke=Lr(),ke===t&&(ke=null),ke!==t?(r.charCodeAt(j)===58?(Je=d,j++):(Je=t,ze===0&&Ne(m)),Je!==t?(pt=Lr(),pt===t&&(pt=null),pt!==t?(Xt=pa(),Xt!==t?(Et=D,Y=F(pe,Le,Xt),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)}else j=D,D=t;else j=D,D=t}return D}function pa(){var D,Y,pe,Le,ke,Je,pt;if(D=j,Y=j,ze++,pe=j,Le=js(),Le!==t?(ke=tt(),ke!==t?(r.charCodeAt(j)===45?(Je=o,j++):(Je=t,ze===0&&Ne(a)),Je!==t?(pt=Lr(),pt!==t?(Le=[Le,ke,Je,pt],pe=Le):(j=pe,pe=t)):(j=pe,pe=t)):(j=pe,pe=t)):(j=pe,pe=t),ze--,pe!==t?(j=Y,Y=void 0):Y=t,Y!==t?(pe=Hs(),pe!==t?(Le=Bo(),Le!==t?(ke=Ul(),ke!==t?(Je=BA(),Je!==t?(Et=D,Y=H(ke),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t),D===t&&(D=j,Y=js(),Y!==t?(pe=Bo(),pe!==t?(Le=mg(),Le!==t?(ke=BA(),ke!==t?(Et=D,Y=H(Le),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t),D===t))if(D=j,Y=Hl(),Y!==t){if(pe=[],Le=Hs(),Le!==t)for(;Le!==t;)pe.push(Le),Le=Hs();else pe=t;pe!==t?(Et=D,Y=q(Y),D=Y):(j=D,D=t)}else j=D,D=t;return D}function da(){var D,Y,pe;for(ze++,D=j,Y=[],r.charCodeAt(j)===32?(pe=X,j++):(pe=t,ze===0&&Ne(W));pe!==t;)Y.push(pe),r.charCodeAt(j)===32?(pe=X,j++):(pe=t,ze===0&&Ne(W));return Y!==t?(Et=j,pe=Z(Y),pe?pe=void 0:pe=t,pe!==t?(Y=[Y,pe],D=Y):(j=D,D=t)):(j=D,D=t),ze--,D===t&&(Y=t,ze===0&&Ne(_)),D}function tt(){var D,Y,pe;for(D=j,Y=[],r.charCodeAt(j)===32?(pe=X,j++):(pe=t,ze===0&&Ne(W));pe!==t;)Y.push(pe),r.charCodeAt(j)===32?(pe=X,j++):(pe=t,ze===0&&Ne(W));return Y!==t?(Et=j,pe=A(Y),pe?pe=void 0:pe=t,pe!==t?(Y=[Y,pe],D=Y):(j=D,D=t)):(j=D,D=t),D}function Bo(){var D;return Et=j,D=ne(),D?D=void 0:D=t,D}function BA(){var D;return Et=j,D=ue(),D?D=void 0:D=t,D}function Rp(){var D;return D=Gl(),D===t&&(D=bA()),D}function Ca(){var D,Y,pe;if(D=Gl(),D===t){if(D=j,Y=[],pe=ma(),pe!==t)for(;pe!==t;)Y.push(pe),pe=ma();else Y=t;Y!==t&&(Et=D,Y=te()),D=Y}return D}function Hl(){var D;return D=Fp(),D===t&&(D=KE(),D===t&&(D=Gl(),D===t&&(D=bA()))),D}function jl(){var D;return D=Fp(),D===t&&(D=Gl(),D===t&&(D=ma())),D}function bA(){var D,Y,pe,Le,ke,Je;if(ze++,D=j,N.test(r.charAt(j))?(Y=r.charAt(j),j++):(Y=t,ze===0&&Ne(ce)),Y!==t){for(pe=[],Le=j,ke=Lr(),ke===t&&(ke=null),ke!==t?(he.test(r.charAt(j))?(Je=r.charAt(j),j++):(Je=t,ze===0&&Ne(xe)),Je!==t?(ke=[ke,Je],Le=ke):(j=Le,Le=t)):(j=Le,Le=t);Le!==t;)pe.push(Le),Le=j,ke=Lr(),ke===t&&(ke=null),ke!==t?(he.test(r.charAt(j))?(Je=r.charAt(j),j++):(Je=t,ze===0&&Ne(xe)),Je!==t?(ke=[ke,Je],Le=ke):(j=Le,Le=t)):(j=Le,Le=t);pe!==t?(Et=D,Y=De(),D=Y):(j=D,D=t)}else j=D,D=t;return ze--,D===t&&(Y=t,ze===0&&Ne(O)),D}function ma(){var D,Y,pe,Le,ke;if(D=j,r.substr(j,2)===Re?(Y=Re,j+=2):(Y=t,ze===0&&Ne(se)),Y===t&&(Y=null),Y!==t)if(Ae.test(r.charAt(j))?(pe=r.charAt(j),j++):(pe=t,ze===0&&Ne(ye)),pe!==t){for(Le=[],ge.test(r.charAt(j))?(ke=r.charAt(j),j++):(ke=t,ze===0&&Ne(oe));ke!==t;)Le.push(ke),ge.test(r.charAt(j))?(ke=r.charAt(j),j++):(ke=t,ze===0&&Ne(oe));Le!==t?(Et=D,Y=De(),D=Y):(j=D,D=t)}else j=D,D=t;else j=D,D=t;return D}function Fp(){var D,Y;return D=j,r.substr(j,4)===Ye?(Y=Ye,j+=4):(Y=t,ze===0&&Ne(ie)),Y!==t&&(Et=D,Y=G()),D=Y,D}function KE(){var D,Y;return D=j,r.substr(j,4)===fe?(Y=fe,j+=4):(Y=t,ze===0&&Ne(re)),Y!==t&&(Et=D,Y=de()),D=Y,D===t&&(D=j,r.substr(j,5)===Ze?(Y=Ze,j+=5):(Y=t,ze===0&&Ne(vt)),Y!==t&&(Et=D,Y=mt()),D=Y),D}function Gl(){var D,Y,pe,Le;return ze++,D=j,r.charCodeAt(j)===34?(Y=ti,j++):(Y=t,ze===0&&Ne(ui)),Y!==t?(r.charCodeAt(j)===34?(pe=ti,j++):(pe=t,ze===0&&Ne(ui)),pe!==t?(Et=D,Y=gr(),D=Y):(j=D,D=t)):(j=D,D=t),D===t&&(D=j,r.charCodeAt(j)===34?(Y=ti,j++):(Y=t,ze===0&&Ne(ui)),Y!==t?(pe=UE(),pe!==t?(r.charCodeAt(j)===34?(Le=ti,j++):(Le=t,ze===0&&Ne(ui)),Le!==t?(Et=D,Y=gi(pe),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)),ze--,D===t&&(Y=t,ze===0&&Ne(Tr)),D}function UE(){var D,Y,pe;if(D=j,Y=[],pe=Np(),pe!==t)for(;pe!==t;)Y.push(pe),pe=Np();else Y=t;return Y!==t&&(Et=D,Y=ri(Y)),D=Y,D}function Np(){var D,Y,pe,Le,ke,Je;return Ms.test(r.charAt(j))?(D=r.charAt(j),j++):(D=t,ze===0&&Ne(fr)),D===t&&(D=j,r.substr(j,2)===Ei?(Y=Ei,j+=2):(Y=t,ze===0&&Ne(rs)),Y!==t&&(Et=D,Y=ua()),D=Y,D===t&&(D=j,r.substr(j,2)===CA?(Y=CA,j+=2):(Y=t,ze===0&&Ne(gg)),Y!==t&&(Et=D,Y=is()),D=Y,D===t&&(D=j,r.substr(j,2)===mA?(Y=mA,j+=2):(Y=t,ze===0&&Ne(ga)),Y!==t&&(Et=D,Y=wp()),D=Y,D===t&&(D=j,r.substr(j,2)===EA?(Y=EA,j+=2):(Y=t,ze===0&&Ne(IA)),Y!==t&&(Et=D,Y=Ir()),D=Y,D===t&&(D=j,r.substr(j,2)===Nl?(Y=Nl,j+=2):(Y=t,ze===0&&Ne(fg)),Y!==t&&(Et=D,Y=Io()),D=Y,D===t&&(D=j,r.substr(j,2)===hg?(Y=hg,j+=2):(Y=t,ze===0&&Ne(Bp)),Y!==t&&(Et=D,Y=bp()),D=Y,D===t&&(D=j,r.substr(j,2)===Qr?(Y=Qr,j+=2):(Y=t,ze===0&&Ne(Ri)),Y!==t&&(Et=D,Y=yo()),D=Y,D===t&&(D=j,r.substr(j,2)===Nn?(Y=Nn,j+=2):(Y=t,ze===0&&Ne(ae)),Y!==t&&(Et=D,Y=yt()),D=Y,D===t&&(D=j,r.substr(j,2)===Tl?(Y=Tl,j+=2):(Y=t,ze===0&&Ne(Tn)),Y!==t?(pe=Yl(),pe!==t?(Le=Yl(),Le!==t?(ke=Yl(),ke!==t?(Je=Yl(),Je!==t?(Et=D,Y=ns(pe,Le,ke,Je),D=Y):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)):(j=D,D=t)))))))))),D}function Yl(){var D;return ss.test(r.charAt(j))?(D=r.charAt(j),j++):(D=t,ze===0&&Ne(ut)),D}function Lr(){var D,Y;if(ze++,D=[],At.test(r.charAt(j))?(Y=r.charAt(j),j++):(Y=t,ze===0&&Ne(An)),Y!==t)for(;Y!==t;)D.push(Y),At.test(r.charAt(j))?(Y=r.charAt(j),j++):(Y=t,ze===0&&Ne(An));else D=t;return ze--,D===t&&(Y=t,ze===0&&Ne(wo)),D}function HE(){var D,Y;if(ze++,D=[],Nt.test(r.charAt(j))?(Y=r.charAt(j),j++):(Y=t,ze===0&&Ne(pg)),Y!==t)for(;Y!==t;)D.push(Y),Nt.test(r.charAt(j))?(Y=r.charAt(j),j++):(Y=t,ze===0&&Ne(pg));else D=t;return ze--,D===t&&(Y=t,ze===0&&Ne(Q)),D}function Hs(){var D,Y,pe,Le,ke,Je;if(D=j,Y=js(),Y!==t){for(pe=[],Le=j,ke=Lr(),ke===t&&(ke=null),ke!==t?(Je=js(),Je!==t?(ke=[ke,Je],Le=ke):(j=Le,Le=t)):(j=Le,Le=t);Le!==t;)pe.push(Le),Le=j,ke=Lr(),ke===t&&(ke=null),ke!==t?(Je=js(),Je!==t?(ke=[ke,Je],Le=ke):(j=Le,Le=t)):(j=Le,Le=t);pe!==t?(Y=[Y,pe],D=Y):(j=D,D=t)}else j=D,D=t;return D}function js(){var D;return r.substr(j,2)===Ll?(D=Ll,j+=2):(D=t,ze===0&&Ne(Qp)),D===t&&(r.charCodeAt(j)===10?(D=Sp,j++):(D=t,ze===0&&Ne(vp)),D===t&&(r.charCodeAt(j)===13?(D=Pp,j++):(D=t,ze===0&&Ne(xp)))),D}let Ig=2,QA=0;if(fa=n(),fa!==t&&j===r.length)return fa;throw fa!==t&&j<r.length&&Ne(Dp()),Kl(Ol,Wi<r.length?r.charAt(Wi):null,Wi<r.length?ln(Wi,Wi+1):ln(Wi,Wi))}uH.exports={SyntaxError:lc,parse:Cde}});var mH=I((C_e,ev)=>{"use strict";var wde=r=>{let e=!1,t=!1,i=!1;for(let n=0;n<r.length;n++){let s=r[n];e&&/[a-zA-Z]/.test(s)&&s.toUpperCase()===s?(r=r.slice(0,n)+"-"+r.slice(n),e=!1,i=t,t=!0,n++):t&&i&&/[a-zA-Z]/.test(s)&&s.toLowerCase()===s?(r=r.slice(0,n-1)+"-"+r.slice(n-1),i=t,t=!1,e=!0):(e=s.toLowerCase()===s&&s.toUpperCase()!==s,i=t,t=s.toUpperCase()===s&&s.toLowerCase()!==s)}return r},CH=(r,e)=>{if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let t=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(r)?r=r.map(n=>n.trim()).filter(n=>n.length).join("-"):r=r.trim(),r.length===0?"":r.length===1?e.pascalCase?r.toUpperCase():r.toLowerCase():(r!==r.toLowerCase()&&(r=wde(r)),r=r.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),t(r))};ev.exports=CH;ev.exports.default=CH});var EH=I((m_e,Bde)=>{Bde.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var cc=I(Un=>{"use strict";var yH=EH(),Po=process.env;Object.defineProperty(Un,"_vendors",{value:yH.map(function(r){return r.constant})});Un.name=null;Un.isPR=null;yH.forEach(function(r){let t=(Array.isArray(r.env)?r.env:[r.env]).every(function(i){return IH(i)});if(Un[r.constant]=t,t)switch(Un.name=r.name,typeof r.pr){case"string":Un.isPR=!!Po[r.pr];break;case"object":"env"in r.pr?Un.isPR=r.pr.env in Po&&Po[r.pr.env]!==r.pr.ne:"any"in r.pr?Un.isPR=r.pr.any.some(function(i){return!!Po[i]}):Un.isPR=IH(r.pr);break;default:Un.isPR=null}});Un.isCI=!!(Po.CI||Po.CONTINUOUS_INTEGRATION||Po.BUILD_NUMBER||Po.RUN_ID||Un.name);function IH(r){return typeof r=="string"?!!Po[r]:Object.keys(r).every(function(e){return Po[e]===r[e]})}});var hn={};ct(hn,{KeyRelationship:()=>uc,applyCascade:()=>ad,base64RegExp:()=>SH,colorStringAlphaRegExp:()=>QH,colorStringRegExp:()=>bH,computeKey:()=>DA,getPrintable:()=>Wr,hasExactLength:()=>DH,hasForbiddenKeys:()=>tCe,hasKeyRelationship:()=>av,hasMaxLength:()=>Mde,hasMinLength:()=>Ode,hasMutuallyExclusiveKeys:()=>rCe,hasRequiredKeys:()=>eCe,hasUniqueItems:()=>Kde,isArray:()=>xde,isAtLeast:()=>jde,isAtMost:()=>Gde,isBase64:()=>_de,isBoolean:()=>Sde,isDate:()=>Pde,isDict:()=>Dde,isEnum:()=>Xi,isHexColor:()=>Zde,isISO8601:()=>Xde,isInExclusiveRange:()=>qde,isInInclusiveRange:()=>Yde,isInstanceOf:()=>Fde,isInteger:()=>Jde,isJSON:()=>$de,isLiteral:()=>bde,isLowerCase:()=>Wde,isNegative:()=>Ude,isNullable:()=>Lde,isNumber:()=>vde,isObject:()=>Rde,isOneOf:()=>Nde,isOptional:()=>Tde,isPositive:()=>Hde,isString:()=>od,isTuple:()=>kde,isUUID4:()=>Vde,isUnknown:()=>kH,isUpperCase:()=>zde,iso8601RegExp:()=>ov,makeCoercionFn:()=>gc,makeSetter:()=>xH,makeTrait:()=>PH,makeValidator:()=>Bt,matchesRegExp:()=>Ad,plural:()=>kI,pushError:()=>ht,simpleKeyRegExp:()=>BH,uuid4RegExp:()=>vH});function Bt({test:r}){return PH(r)()}function Wr(r){return r===null?"null":r===void 0?"undefined":r===""?"an empty string":JSON.stringify(r)}function DA(r,e){var t,i,n;return typeof e=="number"?`${(t=r==null?void 0:r.p)!==null&&t!==void 0?t:"."}[${e}]`:BH.test(e)?`${(i=r==null?void 0:r.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=r==null?void 0:r.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function gc(r,e){return t=>{let i=r[e];return r[e]=t,gc(r,e).bind(null,i)}}function xH(r,e){return t=>{r[e]=t}}function kI(r,e,t){return r===1?e:t}function ht({errors:r,p:e}={},t){return r==null||r.push(`${e!=null?e:"."}: ${t}`),!1}function bde(r){return Bt({test:(e,t)=>e!==r?ht(t,`Expected a literal (got ${Wr(r)})`):!0})}function Xi(r){let e=Array.isArray(r)?r:Object.values(r),t=new Set(e);return Bt({test:(i,n)=>t.has(i)?!0:ht(n,`Expected a valid enumeration value (got ${Wr(i)})`)})}var BH,bH,QH,SH,vH,ov,PH,kH,od,Qde,Sde,vde,Pde,xde,kde,Dde,Rde,Fde,Nde,ad,Tde,Lde,Ode,Mde,DH,Kde,Ude,Hde,jde,Gde,Yde,qde,Jde,Ad,Wde,zde,Vde,Xde,Zde,_de,$de,eCe,tCe,rCe,uc,iCe,av,As=Hge(()=>{BH=/^[a-zA-Z_][a-zA-Z0-9_]*$/,bH=/^#[0-9a-f]{6}$/i,QH=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,SH=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,vH=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,ov=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/,PH=r=>()=>r;kH=()=>Bt({test:(r,e)=>!0});od=()=>Bt({test:(r,e)=>typeof r!="string"?ht(e,`Expected a string (got ${Wr(r)})`):!0});Qde=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),Sde=()=>Bt({test:(r,e)=>{var t;if(typeof r!="boolean"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return ht(e,"Unbound coercion result");let i=Qde.get(r);if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return ht(e,`Expected a boolean (got ${Wr(r)})`)}return!0}}),vde=()=>Bt({test:(r,e)=>{var t;if(typeof r!="number"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return ht(e,"Unbound coercion result");let i;if(typeof r=="string"){let n;try{n=JSON.parse(r)}catch{}if(typeof n=="number")if(JSON.stringify(n)===r)i=n;else return ht(e,`Received a number that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return ht(e,`Expected a number (got ${Wr(r)})`)}return!0}}),Pde=()=>Bt({test:(r,e)=>{var t;if(!(r instanceof Date)){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return ht(e,"Unbound coercion result");let i;if(typeof r=="string"&&ov.test(r))i=new Date(r);else{let n;if(typeof r=="string"){let s;try{s=JSON.parse(r)}catch{}typeof s=="number"&&(n=s)}else typeof r=="number"&&(n=r);if(typeof n<"u")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return ht(e,`Received a timestamp that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return ht(e,`Expected a date (got ${Wr(r)})`)}return!0}}),xde=(r,{delimiter:e}={})=>Bt({test:(t,i)=>{var n;if(typeof t=="string"&&typeof e<"u"&&typeof(i==null?void 0:i.coercions)<"u"){if(typeof(i==null?void 0:i.coercion)>"u")return ht(i,"Unbound coercion result");t=t.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,t)])}if(!Array.isArray(t))return ht(i,`Expected an array (got ${Wr(t)})`);let s=!0;for(let o=0,a=t.length;o<a&&(s=r(t[o],Object.assign(Object.assign({},i),{p:DA(i,o),coercion:gc(t,o)}))&&s,!(!s&&(i==null?void 0:i.errors)==null));++o);return s}}),kde=(r,{delimiter:e}={})=>{let t=DH(r.length);return Bt({test:(i,n)=>{var s;if(typeof i=="string"&&typeof e<"u"&&typeof(n==null?void 0:n.coercions)<"u"){if(typeof(n==null?void 0:n.coercion)>"u")return ht(n,"Unbound coercion result");i=i.split(e),n.coercions.push([(s=n.p)!==null&&s!==void 0?s:".",n.coercion.bind(null,i)])}if(!Array.isArray(i))return ht(n,`Expected a tuple (got ${Wr(i)})`);let o=t(i,Object.assign({},n));for(let a=0,l=i.length;a<l&&a<r.length&&(o=r[a](i[a],Object.assign(Object.assign({},n),{p:DA(n,a),coercion:gc(i,a)}))&&o,!(!o&&(n==null?void 0:n.errors)==null));++a);return o}})},Dde=(r,{keys:e=null}={})=>Bt({test:(t,i)=>{if(typeof t!="object"||t===null)return ht(i,`Expected an object (got ${Wr(t)})`);let n=Object.keys(t),s=!0;for(let o=0,a=n.length;o<a&&(s||(i==null?void 0:i.errors)!=null);++o){let l=n[o],c=t[l];if(l==="__proto__"||l==="constructor"){s=ht(Object.assign(Object.assign({},i),{p:DA(i,l)}),"Unsafe property name");continue}if(e!==null&&!e(l,i)){s=!1;continue}if(!r(c,Object.assign(Object.assign({},i),{p:DA(i,l),coercion:gc(t,l)}))){s=!1;continue}}return s}}),Rde=(r,{extra:e=null}={})=>{let t=Object.keys(r);return Bt({test:(i,n)=>{if(typeof i!="object"||i===null)return ht(n,`Expected an object (got ${Wr(i)})`);let s=new Set([...t,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=ht(Object.assign(Object.assign({},n),{p:DA(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(r,l)?r[l]:void 0,u=Object.prototype.hasOwnProperty.call(i,l)?i[l]:void 0;typeof c<"u"?a=c(u,Object.assign(Object.assign({},n),{p:DA(n,l),coercion:gc(i,l)}))&&a:e===null?a=ht(Object.assign(Object.assign({},n),{p:DA(n,l)}),`Extraneous property (got ${Wr(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:xH(i,l)})}if(!a&&(n==null?void 0:n.errors)==null)break}return e!==null&&(a||(n==null?void 0:n.errors)!=null)&&(a=e(o,n)&&a),a}})},Fde=r=>Bt({test:(e,t)=>e instanceof r?!0:ht(t,`Expected an instance of ${r.name} (got ${Wr(e)})`)}),Nde=(r,{exclusive:e=!1}={})=>Bt({test:(t,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)<"u"?[]:void 0;for(let c=0,u=r.length;c<u;++c){let g=typeof(i==null?void 0:i.errors)<"u"?[]:void 0,h=typeof(i==null?void 0:i.coercions)<"u"?[]:void 0;if(r[c](t,Object.assign(Object.assign({},i),{errors:g,coercions:h,p:`${(n=i==null?void 0:i.p)!==null&&n!==void 0?n:"."}#${c+1}`}))){if(a.push([`#${c+1}`,h]),!e)break}else l==null||l.push(g[0])}if(a.length===1){let[,c]=a[0];return typeof c<"u"&&((s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...c)),!0}return a.length>1?ht(i,`Expected to match exactly a single predicate (matched ${a.join(", ")})`):(o=i==null?void 0:i.errors)===null||o===void 0||o.push(...l),!1}}),ad=(r,e)=>Bt({test:(t,i)=>{var n,s;let o={value:t},a=typeof(i==null?void 0:i.coercions)<"u"?gc(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)<"u"?[]:void 0;if(!r(t,Object.assign(Object.assign({},i),{coercion:a,coercions:l})))return!1;let c=[];if(typeof l<"u")for(let[,u]of l)c.push(u());try{if(typeof(i==null?void 0:i.coercions)<"u"){if(o.value!==t){if(typeof(i==null?void 0:i.coercion)>"u")return ht(i,"Unbound coercion result");i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,o.value)])}(s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...l)}return e.every(u=>u(o.value,i))}finally{for(let u of c)u()}}}),Tde=r=>Bt({test:(e,t)=>typeof e>"u"?!0:r(e,t)}),Lde=r=>Bt({test:(e,t)=>e===null?!0:r(e,t)}),Ode=r=>Bt({test:(e,t)=>e.length>=r?!0:ht(t,`Expected to have a length of at least ${r} elements (got ${e.length})`)}),Mde=r=>Bt({test:(e,t)=>e.length<=r?!0:ht(t,`Expected to have a length of at most ${r} elements (got ${e.length})`)}),DH=r=>Bt({test:(e,t)=>e.length!==r?ht(t,`Expected to have a length of exactly ${r} elements (got ${e.length})`):!0}),Kde=({map:r}={})=>Bt({test:(e,t)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;s<o;++s){let a=e[s],l=typeof r<"u"?r(a):a;if(i.has(l)){if(n.has(l))continue;ht(t,`Expected to contain unique elements; got a duplicate with ${Wr(e)}`),n.add(l)}else i.add(l)}return n.size===0}}),Ude=()=>Bt({test:(r,e)=>r<=0?!0:ht(e,`Expected to be negative (got ${r})`)}),Hde=()=>Bt({test:(r,e)=>r>=0?!0:ht(e,`Expected to be positive (got ${r})`)}),jde=r=>Bt({test:(e,t)=>e>=r?!0:ht(t,`Expected to be at least ${r} (got ${e})`)}),Gde=r=>Bt({test:(e,t)=>e<=r?!0:ht(t,`Expected to be at most ${r} (got ${e})`)}),Yde=(r,e)=>Bt({test:(t,i)=>t>=r&&t<=e?!0:ht(i,`Expected to be in the [${r}; ${e}] range (got ${t})`)}),qde=(r,e)=>Bt({test:(t,i)=>t>=r&&t<e?!0:ht(i,`Expected to be in the [${r}; ${e}[ range (got ${t})`)}),Jde=({unsafe:r=!1}={})=>Bt({test:(e,t)=>e!==Math.round(e)?ht(t,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:ht(t,`Expected to be a safe integer (got ${e})`)}),Ad=r=>Bt({test:(e,t)=>r.test(e)?!0:ht(t,`Expected to match the pattern ${r.toString()} (got ${Wr(e)})`)}),Wde=()=>Bt({test:(r,e)=>r!==r.toLowerCase()?ht(e,`Expected to be all-lowercase (got ${r})`):!0}),zde=()=>Bt({test:(r,e)=>r!==r.toUpperCase()?ht(e,`Expected to be all-uppercase (got ${r})`):!0}),Vde=()=>Bt({test:(r,e)=>vH.test(r)?!0:ht(e,`Expected to be a valid UUID v4 (got ${Wr(r)})`)}),Xde=()=>Bt({test:(r,e)=>ov.test(r)?!1:ht(e,`Expected to be a valid ISO 8601 date string (got ${Wr(r)})`)}),Zde=({alpha:r=!1})=>Bt({test:(e,t)=>(r?bH.test(e):QH.test(e))?!0:ht(t,`Expected to be a valid hexadecimal color string (got ${Wr(e)})`)}),_de=()=>Bt({test:(r,e)=>SH.test(r)?!0:ht(e,`Expected to be a valid base 64 string (got ${Wr(r)})`)}),$de=(r=kH())=>Bt({test:(e,t)=>{let i;try{i=JSON.parse(e)}catch{return ht(t,`Expected to be a valid JSON string (got ${Wr(e)})`)}return r(i,t)}}),eCe=r=>{let e=new Set(r);return Bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?ht(i,`Missing required ${kI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},tCe=r=>{let e=new Set(r);return Bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?ht(i,`Forbidden ${kI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},rCe=r=>{let e=new Set(r);return Bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?ht(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(r){r.Forbids="Forbids",r.Requires="Requires"})(uc||(uc={}));iCe={[uc.Forbids]:{expect:!1,message:"forbids using"},[uc.Requires]:{expect:!0,message:"requires using"}},av=(r,e,t,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(t),o=iCe[e];return Bt({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(r)||n.has(a[r]))return!0;let u=[];for(let g of s)(c.has(g)&&!n.has(a[g]))!==o.expect&&u.push(g);return u.length>=1?ht(l,`Property "${r}" ${o.message} ${kI(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var zH=I((m$e,WH)=>{"use strict";WH.exports=(r,...e)=>new Promise(t=>{t(r(...e))})});var Jg=I((E$e,pv)=>{"use strict";var ICe=zH(),VH=r=>{if(r<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],t=0,i=()=>{t--,e.length>0&&e.shift()()},n=(a,l,...c)=>{t++;let u=ICe(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{t<r?n(a,l,...c):e.push(n.bind(null,a,l,...c))},o=(a,...l)=>new Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>t},pendingCount:{get:()=>e.length}}),o};pv.exports=VH;pv.exports.default=VH});var fd=I((y$e,XH)=>{var yCe="2.0.0",wCe=Number.MAX_SAFE_INTEGER||9007199254740991,BCe=16;XH.exports={SEMVER_SPEC_VERSION:yCe,MAX_LENGTH:256,MAX_SAFE_INTEGER:wCe,MAX_SAFE_COMPONENT_LENGTH:BCe}});var hd=I((w$e,ZH)=>{var bCe=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...r)=>console.error("SEMVER",...r):()=>{};ZH.exports=bCe});var fc=I((FA,_H)=>{var{MAX_SAFE_COMPONENT_LENGTH:dv}=fd(),QCe=hd();FA=_H.exports={};var SCe=FA.re=[],$e=FA.src=[],et=FA.t={},vCe=0,bt=(r,e,t)=>{let i=vCe++;QCe(i,e),et[r]=i,$e[i]=e,SCe[i]=new RegExp(e,t?"g":void 0)};bt("NUMERICIDENTIFIER","0|[1-9]\\d*");bt("NUMERICIDENTIFIERLOOSE","[0-9]+");bt("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");bt("MAINVERSION",`(${$e[et.NUMERICIDENTIFIER]})\\.(${$e[et.NUMERICIDENTIFIER]})\\.(${$e[et.NUMERICIDENTIFIER]})`);bt("MAINVERSIONLOOSE",`(${$e[et.NUMERICIDENTIFIERLOOSE]})\\.(${$e[et.NUMERICIDENTIFIERLOOSE]})\\.(${$e[et.NUMERICIDENTIFIERLOOSE]})`);bt("PRERELEASEIDENTIFIER",`(?:${$e[et.NUMERICIDENTIFIER]}|${$e[et.NONNUMERICIDENTIFIER]})`);bt("PRERELEASEIDENTIFIERLOOSE",`(?:${$e[et.NUMERICIDENTIFIERLOOSE]}|${$e[et.NONNUMERICIDENTIFIER]})`);bt("PRERELEASE",`(?:-(${$e[et.PRERELEASEIDENTIFIER]}(?:\\.${$e[et.PRERELEASEIDENTIFIER]})*))`);bt("PRERELEASELOOSE",`(?:-?(${$e[et.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${$e[et.PRERELEASEIDENTIFIERLOOSE]})*))`);bt("BUILDIDENTIFIER","[0-9A-Za-z-]+");bt("BUILD",`(?:\\+(${$e[et.BUILDIDENTIFIER]}(?:\\.${$e[et.BUILDIDENTIFIER]})*))`);bt("FULLPLAIN",`v?${$e[et.MAINVERSION]}${$e[et.PRERELEASE]}?${$e[et.BUILD]}?`);bt("FULL",`^${$e[et.FULLPLAIN]}$`);bt("LOOSEPLAIN",`[v=\\s]*${$e[et.MAINVERSIONLOOSE]}${$e[et.PRERELEASELOOSE]}?${$e[et.BUILD]}?`);bt("LOOSE",`^${$e[et.LOOSEPLAIN]}$`);bt("GTLT","((?:<|>)?=?)");bt("XRANGEIDENTIFIERLOOSE",`${$e[et.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);bt("XRANGEIDENTIFIER",`${$e[et.NUMERICIDENTIFIER]}|x|X|\\*`);bt("XRANGEPLAIN",`[v=\\s]*(${$e[et.XRANGEIDENTIFIER]})(?:\\.(${$e[et.XRANGEIDENTIFIER]})(?:\\.(${$e[et.XRANGEIDENTIFIER]})(?:${$e[et.PRERELEASE]})?${$e[et.BUILD]}?)?)?`);bt("XRANGEPLAINLOOSE",`[v=\\s]*(${$e[et.XRANGEIDENTIFIERLOOSE]})(?:\\.(${$e[et.XRANGEIDENTIFIERLOOSE]})(?:\\.(${$e[et.XRANGEIDENTIFIERLOOSE]})(?:${$e[et.PRERELEASELOOSE]})?${$e[et.BUILD]}?)?)?`);bt("XRANGE",`^${$e[et.GTLT]}\\s*${$e[et.XRANGEPLAIN]}$`);bt("XRANGELOOSE",`^${$e[et.GTLT]}\\s*${$e[et.XRANGEPLAINLOOSE]}$`);bt("COERCE",`(^|[^\\d])(\\d{1,${dv}})(?:\\.(\\d{1,${dv}}))?(?:\\.(\\d{1,${dv}}))?(?:$|[^\\d])`);bt("COERCERTL",$e[et.COERCE],!0);bt("LONETILDE","(?:~>?)");bt("TILDETRIM",`(\\s*)${$e[et.LONETILDE]}\\s+`,!0);FA.tildeTrimReplace="$1~";bt("TILDE",`^${$e[et.LONETILDE]}${$e[et.XRANGEPLAIN]}$`);bt("TILDELOOSE",`^${$e[et.LONETILDE]}${$e[et.XRANGEPLAINLOOSE]}$`);bt("LONECARET","(?:\\^)");bt("CARETTRIM",`(\\s*)${$e[et.LONECARET]}\\s+`,!0);FA.caretTrimReplace="$1^";bt("CARET",`^${$e[et.LONECARET]}${$e[et.XRANGEPLAIN]}$`);bt("CARETLOOSE",`^${$e[et.LONECARET]}${$e[et.XRANGEPLAINLOOSE]}$`);bt("COMPARATORLOOSE",`^${$e[et.GTLT]}\\s*(${$e[et.LOOSEPLAIN]})$|^$`);bt("COMPARATOR",`^${$e[et.GTLT]}\\s*(${$e[et.FULLPLAIN]})$|^$`);bt("COMPARATORTRIM",`(\\s*)${$e[et.GTLT]}\\s*(${$e[et.LOOSEPLAIN]}|${$e[et.XRANGEPLAIN]})`,!0);FA.comparatorTrimReplace="$1$2$3";bt("HYPHENRANGE",`^\\s*(${$e[et.XRANGEPLAIN]})\\s+-\\s+(${$e[et.XRANGEPLAIN]})\\s*$`);bt("HYPHENRANGELOOSE",`^\\s*(${$e[et.XRANGEPLAINLOOSE]})\\s+-\\s+(${$e[et.XRANGEPLAINLOOSE]})\\s*$`);bt("STAR","(<|>)?=?\\s*\\*");bt("GTE0","^\\s*>=\\s*0.0.0\\s*$");bt("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var pd=I((B$e,$H)=>{var PCe=["includePrerelease","loose","rtl"],xCe=r=>r?typeof r!="object"?{loose:!0}:PCe.filter(e=>r[e]).reduce((e,t)=>(e[t]=!0,e),{}):{};$H.exports=xCe});var LI=I((b$e,rj)=>{var ej=/^[0-9]+$/,tj=(r,e)=>{let t=ej.test(r),i=ej.test(e);return t&&i&&(r=+r,e=+e),r===e?0:t&&!i?-1:i&&!t?1:r<e?-1:1},kCe=(r,e)=>tj(e,r);rj.exports={compareIdentifiers:tj,rcompareIdentifiers:kCe}});var Li=I((Q$e,oj)=>{var OI=hd(),{MAX_LENGTH:ij,MAX_SAFE_INTEGER:MI}=fd(),{re:nj,t:sj}=fc(),DCe=pd(),{compareIdentifiers:dd}=LI(),Gn=class{constructor(e,t){if(t=DCe(t),e instanceof Gn){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>ij)throw new TypeError(`version is longer than ${ij} characters`);OI("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;let i=e.trim().match(t.loose?nj[sj.LOOSE]:nj[sj.FULL]);if(!i)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>MI||this.major<0)throw new TypeError("Invalid major version");if(this.minor>MI||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>MI||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let s=+n;if(s>=0&&s<MI)return s}return n}):this.prerelease=[],this.build=i[5]?i[5].split("."):[],this.format()}format(){return this.version=`${this.major}.${this.minor}.${this.patch}`,this.prerelease.length&&(this.version+=`-${this.prerelease.join(".")}`),this.version}toString(){return this.version}compare(e){if(OI("SemVer.compare",this.version,this.options,e),!(e instanceof Gn)){if(typeof e=="string"&&e===this.version)return 0;e=new Gn(e,this.options)}return e.version===this.version?0:this.compareMain(e)||this.comparePre(e)}compareMain(e){return e instanceof Gn||(e=new Gn(e,this.options)),dd(this.major,e.major)||dd(this.minor,e.minor)||dd(this.patch,e.patch)}comparePre(e){if(e instanceof Gn||(e=new Gn(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;let t=0;do{let i=this.prerelease[t],n=e.prerelease[t];if(OI("prerelease compare",t,i,n),i===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;if(i===n)continue;return dd(i,n)}while(++t)}compareBuild(e){e instanceof Gn||(e=new Gn(e,this.options));let t=0;do{let i=this.build[t],n=e.build[t];if(OI("prerelease compare",t,i,n),i===void 0&&n===void 0)return 0;if(n===void 0)return 1;if(i===void 0)return-1;if(i===n)continue;return dd(i,n)}while(++t)}inc(e,t){switch(e){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",t);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",t);break;case"prepatch":this.prerelease.length=0,this.inc("patch",t),this.inc("pre",t);break;case"prerelease":this.prerelease.length===0&&this.inc("patch",t),this.inc("pre",t);break;case"major":(this.minor!==0||this.patch!==0||this.prerelease.length===0)&&this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":(this.patch!==0||this.prerelease.length===0)&&this.minor++,this.patch=0,this.prerelease=[];break;case"patch":this.prerelease.length===0&&this.patch++,this.prerelease=[];break;case"pre":if(this.prerelease.length===0)this.prerelease=[0];else{let i=this.prerelease.length;for(;--i>=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};oj.exports=Gn});var hc=I((S$e,cj)=>{var{MAX_LENGTH:RCe}=fd(),{re:aj,t:Aj}=fc(),lj=Li(),FCe=pd(),NCe=(r,e)=>{if(e=FCe(e),r instanceof lj)return r;if(typeof r!="string"||r.length>RCe||!(e.loose?aj[Aj.LOOSE]:aj[Aj.FULL]).test(r))return null;try{return new lj(r,e)}catch{return null}};cj.exports=NCe});var gj=I((v$e,uj)=>{var TCe=hc(),LCe=(r,e)=>{let t=TCe(r,e);return t?t.version:null};uj.exports=LCe});var hj=I((P$e,fj)=>{var OCe=hc(),MCe=(r,e)=>{let t=OCe(r.trim().replace(/^[=v]+/,""),e);return t?t.version:null};fj.exports=MCe});var dj=I((x$e,pj)=>{var KCe=Li(),UCe=(r,e,t,i)=>{typeof t=="string"&&(i=t,t=void 0);try{return new KCe(r,t).inc(e,i).version}catch{return null}};pj.exports=UCe});var ls=I((k$e,mj)=>{var Cj=Li(),HCe=(r,e,t)=>new Cj(r,t).compare(new Cj(e,t));mj.exports=HCe});var KI=I((D$e,Ej)=>{var jCe=ls(),GCe=(r,e,t)=>jCe(r,e,t)===0;Ej.exports=GCe});var wj=I((R$e,yj)=>{var Ij=hc(),YCe=KI(),qCe=(r,e)=>{if(YCe(r,e))return null;{let t=Ij(r),i=Ij(e),n=t.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in t)if((a==="major"||a==="minor"||a==="patch")&&t[a]!==i[a])return s+a;return o}};yj.exports=qCe});var bj=I((F$e,Bj)=>{var JCe=Li(),WCe=(r,e)=>new JCe(r,e).major;Bj.exports=WCe});var Sj=I((N$e,Qj)=>{var zCe=Li(),VCe=(r,e)=>new zCe(r,e).minor;Qj.exports=VCe});var Pj=I((T$e,vj)=>{var XCe=Li(),ZCe=(r,e)=>new XCe(r,e).patch;vj.exports=ZCe});var kj=I((L$e,xj)=>{var _Ce=hc(),$Ce=(r,e)=>{let t=_Ce(r,e);return t&&t.prerelease.length?t.prerelease:null};xj.exports=$Ce});var Rj=I((O$e,Dj)=>{var eme=ls(),tme=(r,e,t)=>eme(e,r,t);Dj.exports=tme});var Nj=I((M$e,Fj)=>{var rme=ls(),ime=(r,e)=>rme(r,e,!0);Fj.exports=ime});var UI=I((K$e,Lj)=>{var Tj=Li(),nme=(r,e,t)=>{let i=new Tj(r,t),n=new Tj(e,t);return i.compare(n)||i.compareBuild(n)};Lj.exports=nme});var Mj=I((U$e,Oj)=>{var sme=UI(),ome=(r,e)=>r.sort((t,i)=>sme(t,i,e));Oj.exports=ome});var Uj=I((H$e,Kj)=>{var ame=UI(),Ame=(r,e)=>r.sort((t,i)=>ame(i,t,e));Kj.exports=Ame});var Cd=I((j$e,Hj)=>{var lme=ls(),cme=(r,e,t)=>lme(r,e,t)>0;Hj.exports=cme});var HI=I((G$e,jj)=>{var ume=ls(),gme=(r,e,t)=>ume(r,e,t)<0;jj.exports=gme});var Cv=I((Y$e,Gj)=>{var fme=ls(),hme=(r,e,t)=>fme(r,e,t)!==0;Gj.exports=hme});var jI=I((q$e,Yj)=>{var pme=ls(),dme=(r,e,t)=>pme(r,e,t)>=0;Yj.exports=dme});var GI=I((J$e,qj)=>{var Cme=ls(),mme=(r,e,t)=>Cme(r,e,t)<=0;qj.exports=mme});var mv=I((W$e,Jj)=>{var Eme=KI(),Ime=Cv(),yme=Cd(),wme=jI(),Bme=HI(),bme=GI(),Qme=(r,e,t,i)=>{switch(e){case"===":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r===t;case"!==":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r!==t;case"":case"=":case"==":return Eme(r,t,i);case"!=":return Ime(r,t,i);case">":return yme(r,t,i);case">=":return wme(r,t,i);case"<":return Bme(r,t,i);case"<=":return bme(r,t,i);default:throw new TypeError(`Invalid operator: ${e}`)}};Jj.exports=Qme});var zj=I((z$e,Wj)=>{var Sme=Li(),vme=hc(),{re:YI,t:qI}=fc(),Pme=(r,e)=>{if(r instanceof Sme)return r;if(typeof r=="number"&&(r=String(r)),typeof r!="string")return null;e=e||{};let t=null;if(!e.rtl)t=r.match(YI[qI.COERCE]);else{let i;for(;(i=YI[qI.COERCERTL].exec(r))&&(!t||t.index+t[0].length!==r.length);)(!t||i.index+i[0].length!==t.index+t[0].length)&&(t=i),YI[qI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;YI[qI.COERCERTL].lastIndex=-1}return t===null?null:vme(`${t[2]}.${t[3]||"0"}.${t[4]||"0"}`,e)};Wj.exports=Pme});var Xj=I((V$e,Vj)=>{"use strict";Vj.exports=function(r){r.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var JI=I((X$e,Zj)=>{"use strict";Zj.exports=Mt;Mt.Node=pc;Mt.create=Mt;function Mt(r){var e=this;if(e instanceof Mt||(e=new Mt),e.tail=null,e.head=null,e.length=0,r&&typeof r.forEach=="function")r.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var t=0,i=arguments.length;t<i;t++)e.push(arguments[t]);return e}Mt.prototype.removeNode=function(r){if(r.list!==this)throw new Error("removing node which does not belong to this list");var e=r.next,t=r.prev;return e&&(e.prev=t),t&&(t.next=e),r===this.head&&(this.head=e),r===this.tail&&(this.tail=t),r.list.length--,r.next=null,r.prev=null,r.list=null,e};Mt.prototype.unshiftNode=function(r){if(r!==this.head){r.list&&r.list.removeNode(r);var e=this.head;r.list=this,r.next=e,e&&(e.prev=r),this.head=r,this.tail||(this.tail=r),this.length++}};Mt.prototype.pushNode=function(r){if(r!==this.tail){r.list&&r.list.removeNode(r);var e=this.tail;r.list=this,r.prev=e,e&&(e.next=r),this.tail=r,this.head||(this.head=r),this.length++}};Mt.prototype.push=function(){for(var r=0,e=arguments.length;r<e;r++)kme(this,arguments[r]);return this.length};Mt.prototype.unshift=function(){for(var r=0,e=arguments.length;r<e;r++)Dme(this,arguments[r]);return this.length};Mt.prototype.pop=function(){if(!!this.tail){var r=this.tail.value;return this.tail=this.tail.prev,this.tail?this.tail.next=null:this.head=null,this.length--,r}};Mt.prototype.shift=function(){if(!!this.head){var r=this.head.value;return this.head=this.head.next,this.head?this.head.prev=null:this.tail=null,this.length--,r}};Mt.prototype.forEach=function(r,e){e=e||this;for(var t=this.head,i=0;t!==null;i++)r.call(e,t.value,i,this),t=t.next};Mt.prototype.forEachReverse=function(r,e){e=e||this;for(var t=this.tail,i=this.length-1;t!==null;i--)r.call(e,t.value,i,this),t=t.prev};Mt.prototype.get=function(r){for(var e=0,t=this.head;t!==null&&e<r;e++)t=t.next;if(e===r&&t!==null)return t.value};Mt.prototype.getReverse=function(r){for(var e=0,t=this.tail;t!==null&&e<r;e++)t=t.prev;if(e===r&&t!==null)return t.value};Mt.prototype.map=function(r,e){e=e||this;for(var t=new Mt,i=this.head;i!==null;)t.push(r.call(e,i.value,this)),i=i.next;return t};Mt.prototype.mapReverse=function(r,e){e=e||this;for(var t=new Mt,i=this.tail;i!==null;)t.push(r.call(e,i.value,this)),i=i.prev;return t};Mt.prototype.reduce=function(r,e){var t,i=this.head;if(arguments.length>1)t=e;else if(this.head)i=this.head.next,t=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)t=r(t,i.value,n),i=i.next;return t};Mt.prototype.reduceReverse=function(r,e){var t,i=this.tail;if(arguments.length>1)t=e;else if(this.tail)i=this.tail.prev,t=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)t=r(t,i.value,n),i=i.prev;return t};Mt.prototype.toArray=function(){for(var r=new Array(this.length),e=0,t=this.head;t!==null;e++)r[e]=t.value,t=t.next;return r};Mt.prototype.toArrayReverse=function(){for(var r=new Array(this.length),e=0,t=this.tail;t!==null;e++)r[e]=t.value,t=t.prev;return r};Mt.prototype.slice=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Mt;if(e<r||e<0)return t;r<0&&(r=0),e>this.length&&(e=this.length);for(var i=0,n=this.head;n!==null&&i<r;i++)n=n.next;for(;n!==null&&i<e;i++,n=n.next)t.push(n.value);return t};Mt.prototype.sliceReverse=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Mt;if(e<r||e<0)return t;r<0&&(r=0),e>this.length&&(e=this.length);for(var i=this.length,n=this.tail;n!==null&&i>e;i--)n=n.prev;for(;n!==null&&i>r;i--,n=n.prev)t.push(n.value);return t};Mt.prototype.splice=function(r,e,...t){r>this.length&&(r=this.length-1),r<0&&(r=this.length+r);for(var i=0,n=this.head;n!==null&&i<r;i++)n=n.next;for(var s=[],i=0;n&&i<e;i++)s.push(n.value),n=this.removeNode(n);n===null&&(n=this.tail),n!==this.head&&n!==this.tail&&(n=n.prev);for(var i=0;i<t.length;i++)n=xme(this,n,t[i]);return s};Mt.prototype.reverse=function(){for(var r=this.head,e=this.tail,t=r;t!==null;t=t.prev){var i=t.prev;t.prev=t.next,t.next=i}return this.head=e,this.tail=r,this};function xme(r,e,t){var i=e===r.head?new pc(t,null,e,r):new pc(t,e,e.next,r);return i.next===null&&(r.tail=i),i.prev===null&&(r.head=i),r.length++,i}function kme(r,e){r.tail=new pc(e,r.tail,null,r),r.head||(r.head=r.tail),r.length++}function Dme(r,e){r.head=new pc(e,null,r.head,r),r.tail||(r.tail=r.head),r.length++}function pc(r,e,t,i){if(!(this instanceof pc))return new pc(r,e,t,i);this.list=i,this.value=r,e?(e.next=this,this.prev=e):this.prev=null,t?(t.prev=this,this.next=t):this.next=null}try{Xj()(Mt)}catch{}});var rG=I((Z$e,tG)=>{"use strict";var Rme=JI(),dc=Symbol("max"),Pa=Symbol("length"),Wg=Symbol("lengthCalculator"),Ed=Symbol("allowStale"),Cc=Symbol("maxAge"),va=Symbol("dispose"),_j=Symbol("noDisposeOnSet"),pi=Symbol("lruList"),Xs=Symbol("cache"),eG=Symbol("updateAgeOnGet"),Ev=()=>1,yv=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let t=this[dc]=e.max||1/0,i=e.length||Ev;if(this[Wg]=typeof i!="function"?Ev:i,this[Ed]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[Cc]=e.maxAge||0,this[va]=e.dispose,this[_j]=e.noDisposeOnSet||!1,this[eG]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[dc]=e||1/0,md(this)}get max(){return this[dc]}set allowStale(e){this[Ed]=!!e}get allowStale(){return this[Ed]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[Cc]=e,md(this)}get maxAge(){return this[Cc]}set lengthCalculator(e){typeof e!="function"&&(e=Ev),e!==this[Wg]&&(this[Wg]=e,this[Pa]=0,this[pi].forEach(t=>{t.length=this[Wg](t.value,t.key),this[Pa]+=t.length})),md(this)}get lengthCalculator(){return this[Wg]}get length(){return this[Pa]}get itemCount(){return this[pi].length}rforEach(e,t){t=t||this;for(let i=this[pi].tail;i!==null;){let n=i.prev;$j(this,e,i,t),i=n}}forEach(e,t){t=t||this;for(let i=this[pi].head;i!==null;){let n=i.next;$j(this,e,i,t),i=n}}keys(){return this[pi].toArray().map(e=>e.key)}values(){return this[pi].toArray().map(e=>e.value)}reset(){this[va]&&this[pi]&&this[pi].length&&this[pi].forEach(e=>this[va](e.key,e.value)),this[Xs]=new Map,this[pi]=new Rme,this[Pa]=0}dump(){return this[pi].map(e=>WI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[pi]}set(e,t,i){if(i=i||this[Cc],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[Wg](t,e);if(this[Xs].has(e)){if(s>this[dc])return zg(this,this[Xs].get(e)),!1;let l=this[Xs].get(e).value;return this[va]&&(this[_j]||this[va](e,l.value)),l.now=n,l.maxAge=i,l.value=t,this[Pa]+=s-l.length,l.length=s,this.get(e),md(this),!0}let o=new wv(e,t,s,n,i);return o.length>this[dc]?(this[va]&&this[va](e,t),!1):(this[Pa]+=o.length,this[pi].unshift(o),this[Xs].set(e,this[pi].head),md(this),!0)}has(e){if(!this[Xs].has(e))return!1;let t=this[Xs].get(e).value;return!WI(this,t)}get(e){return Iv(this,e,!0)}peek(e){return Iv(this,e,!1)}pop(){let e=this[pi].tail;return e?(zg(this,e),e.value):null}del(e){zg(this,this[Xs].get(e))}load(e){this.reset();let t=Date.now();for(let i=e.length-1;i>=0;i--){let n=e[i],s=n.e||0;if(s===0)this.set(n.k,n.v);else{let o=s-t;o>0&&this.set(n.k,n.v,o)}}}prune(){this[Xs].forEach((e,t)=>Iv(this,t,!1))}},Iv=(r,e,t)=>{let i=r[Xs].get(e);if(i){let n=i.value;if(WI(r,n)){if(zg(r,i),!r[Ed])return}else t&&(r[eG]&&(i.value.now=Date.now()),r[pi].unshiftNode(i));return n.value}},WI=(r,e)=>{if(!e||!e.maxAge&&!r[Cc])return!1;let t=Date.now()-e.now;return e.maxAge?t>e.maxAge:r[Cc]&&t>r[Cc]},md=r=>{if(r[Pa]>r[dc])for(let e=r[pi].tail;r[Pa]>r[dc]&&e!==null;){let t=e.prev;zg(r,e),e=t}},zg=(r,e)=>{if(e){let t=e.value;r[va]&&r[va](t.key,t.value),r[Pa]-=t.length,r[Xs].delete(t.key),r[pi].removeNode(e)}},wv=class{constructor(e,t,i,n,s){this.key=e,this.value=t,this.length=i,this.now=n,this.maxAge=s||0}},$j=(r,e,t,i)=>{let n=t.value;WI(r,n)&&(zg(r,t),r[Ed]||(n=void 0)),n&&e.call(i,n.value,n.key,r)};tG.exports=yv});var cs=I((_$e,oG)=>{var mc=class{constructor(e,t){if(t=Nme(t),e instanceof mc)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new mc(e.raw,t);if(e instanceof Bv)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(i=>this.parseRange(i.trim())).filter(i=>i.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let i=this.set[0];if(this.set=this.set.filter(n=>!nG(n[0])),this.set.length===0)this.set=[i];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&Kme(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let i=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=iG.get(i);if(n)return n;let s=this.options.loose,o=s?Oi[Qi.HYPHENRANGELOOSE]:Oi[Qi.HYPHENRANGE];e=e.replace(o,Vme(this.options.includePrerelease)),Mr("hyphen replace",e),e=e.replace(Oi[Qi.COMPARATORTRIM],Lme),Mr("comparator trim",e,Oi[Qi.COMPARATORTRIM]),e=e.replace(Oi[Qi.TILDETRIM],Ome),e=e.replace(Oi[Qi.CARETTRIM],Mme),e=e.split(/\s+/).join(" ");let a=s?Oi[Qi.COMPARATORLOOSE]:Oi[Qi.COMPARATOR],l=e.split(" ").map(h=>Ume(h,this.options)).join(" ").split(/\s+/).map(h=>zme(h,this.options)).filter(this.options.loose?h=>!!h.match(a):()=>!0).map(h=>new Bv(h,this.options)),c=l.length,u=new Map;for(let h of l){if(nG(h))return[h];u.set(h.value,h)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return iG.set(i,g),g}intersects(e,t){if(!(e instanceof mc))throw new TypeError("a Range is required");return this.set.some(i=>sG(i,t)&&e.set.some(n=>sG(n,t)&&i.every(s=>n.every(o=>s.intersects(o,t)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new Tme(e,this.options)}catch{return!1}for(let t=0;t<this.set.length;t++)if(Xme(this.set[t],e,this.options))return!0;return!1}};oG.exports=mc;var Fme=rG(),iG=new Fme({max:1e3}),Nme=pd(),Bv=Id(),Mr=hd(),Tme=Li(),{re:Oi,t:Qi,comparatorTrimReplace:Lme,tildeTrimReplace:Ome,caretTrimReplace:Mme}=fc(),nG=r=>r.value==="<0.0.0-0",Kme=r=>r.value==="",sG=(r,e)=>{let t=!0,i=r.slice(),n=i.pop();for(;t&&i.length;)t=i.every(s=>n.intersects(s,e)),n=i.pop();return t},Ume=(r,e)=>(Mr("comp",r,e),r=Gme(r,e),Mr("caret",r),r=Hme(r,e),Mr("tildes",r),r=qme(r,e),Mr("xrange",r),r=Wme(r,e),Mr("stars",r),r),_i=r=>!r||r.toLowerCase()==="x"||r==="*",Hme=(r,e)=>r.trim().split(/\s+/).map(t=>jme(t,e)).join(" "),jme=(r,e)=>{let t=e.loose?Oi[Qi.TILDELOOSE]:Oi[Qi.TILDE];return r.replace(t,(i,n,s,o,a)=>{Mr("tilde",r,i,n,s,o,a);let l;return _i(n)?l="":_i(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:_i(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(Mr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,Mr("tilde return",l),l})},Gme=(r,e)=>r.trim().split(/\s+/).map(t=>Yme(t,e)).join(" "),Yme=(r,e)=>{Mr("caret",r,e);let t=e.loose?Oi[Qi.CARETLOOSE]:Oi[Qi.CARET],i=e.includePrerelease?"-0":"";return r.replace(t,(n,s,o,a,l)=>{Mr("caret",r,n,s,o,a,l);let c;return _i(s)?c="":_i(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:_i(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(Mr("replaceCaret pr",l),s==="0"?o==="0"?c=`>=${s}.${o}.${a}-${l} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}-${l} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a}-${l} <${+s+1}.0.0-0`):(Mr("no pr"),s==="0"?o==="0"?c=`>=${s}.${o}.${a}${i} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a} <${+s+1}.0.0-0`),Mr("caret return",c),c})},qme=(r,e)=>(Mr("replaceXRanges",r,e),r.split(/\s+/).map(t=>Jme(t,e)).join(" ")),Jme=(r,e)=>{r=r.trim();let t=e.loose?Oi[Qi.XRANGELOOSE]:Oi[Qi.XRANGE];return r.replace(t,(i,n,s,o,a,l)=>{Mr("xRange",r,i,n,s,o,a,l);let c=_i(s),u=c||_i(o),g=u||_i(a),h=g;return n==="="&&h&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?i="<0.0.0-0":i="*":n&&h?(u&&(o=0),a=0,n===">"?(n=">=",u?(s=+s+1,o=0,a=0):(o=+o+1,a=0)):n==="<="&&(n="<",u?s=+s+1:o=+o+1),n==="<"&&(l="-0"),i=`${n+s}.${o}.${a}${l}`):u?i=`>=${s}.0.0${l} <${+s+1}.0.0-0`:g&&(i=`>=${s}.${o}.0${l} <${s}.${+o+1}.0-0`),Mr("xRange return",i),i})},Wme=(r,e)=>(Mr("replaceStars",r,e),r.trim().replace(Oi[Qi.STAR],"")),zme=(r,e)=>(Mr("replaceGTE0",r,e),r.trim().replace(Oi[e.includePrerelease?Qi.GTE0PRE:Qi.GTE0],"")),Vme=r=>(e,t,i,n,s,o,a,l,c,u,g,h,p)=>(_i(i)?t="":_i(n)?t=`>=${i}.0.0${r?"-0":""}`:_i(s)?t=`>=${i}.${n}.0${r?"-0":""}`:o?t=`>=${t}`:t=`>=${t}${r?"-0":""}`,_i(c)?l="":_i(u)?l=`<${+c+1}.0.0-0`:_i(g)?l=`<${c}.${+u+1}.0-0`:h?l=`<=${c}.${u}.${g}-${h}`:r?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${t} ${l}`.trim()),Xme=(r,e,t)=>{for(let i=0;i<r.length;i++)if(!r[i].test(e))return!1;if(e.prerelease.length&&!t.includePrerelease){for(let i=0;i<r.length;i++)if(Mr(r[i].semver),r[i].semver!==Bv.ANY&&r[i].semver.prerelease.length>0){let n=r[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Id=I(($$e,uG)=>{var yd=Symbol("SemVer ANY"),Vg=class{static get ANY(){return yd}constructor(e,t){if(t=Zme(t),e instanceof Vg){if(e.loose===!!t.loose)return e;e=e.value}Qv("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===yd?this.value="":this.value=this.operator+this.semver.version,Qv("comp",this)}parse(e){let t=this.options.loose?aG[AG.COMPARATORLOOSE]:aG[AG.COMPARATOR],i=e.match(t);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=i[1]!==void 0?i[1]:"",this.operator==="="&&(this.operator=""),i[2]?this.semver=new lG(i[2],this.options.loose):this.semver=yd}toString(){return this.value}test(e){if(Qv("Comparator.test",e,this.options.loose),this.semver===yd||e===yd)return!0;if(typeof e=="string")try{e=new lG(e,this.options)}catch{return!1}return bv(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof Vg))throw new TypeError("a Comparator is required");if((!t||typeof t!="object")&&(t={loose:!!t,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new cG(e.value,t).test(this.value);if(e.operator==="")return e.value===""?!0:new cG(this.value,t).test(e.semver);let i=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),s=this.semver.version===e.semver.version,o=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=bv(this.semver,"<",e.semver,t)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=bv(this.semver,">",e.semver,t)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};uG.exports=Vg;var Zme=pd(),{re:aG,t:AG}=fc(),bv=mv(),Qv=hd(),lG=Li(),cG=cs()});var wd=I((eet,gG)=>{var _me=cs(),$me=(r,e,t)=>{try{e=new _me(e,t)}catch{return!1}return e.test(r)};gG.exports=$me});var hG=I((tet,fG)=>{var eEe=cs(),tEe=(r,e)=>new eEe(r,e).set.map(t=>t.map(i=>i.value).join(" ").trim().split(" "));fG.exports=tEe});var dG=I((ret,pG)=>{var rEe=Li(),iEe=cs(),nEe=(r,e,t)=>{let i=null,n=null,s=null;try{s=new iEe(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new rEe(i,t))}),i};pG.exports=nEe});var mG=I((iet,CG)=>{var sEe=Li(),oEe=cs(),aEe=(r,e,t)=>{let i=null,n=null,s=null;try{s=new oEe(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new sEe(i,t))}),i};CG.exports=aEe});var yG=I((net,IG)=>{var Sv=Li(),AEe=cs(),EG=Cd(),lEe=(r,e)=>{r=new AEe(r,e);let t=new Sv("0.0.0");if(r.test(t)||(t=new Sv("0.0.0-0"),r.test(t)))return t;t=null;for(let i=0;i<r.set.length;++i){let n=r.set[i],s=null;n.forEach(o=>{let a=new Sv(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||EG(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!t||EG(t,s))&&(t=s)}return t&&r.test(t)?t:null};IG.exports=lEe});var BG=I((set,wG)=>{var cEe=cs(),uEe=(r,e)=>{try{return new cEe(r,e).range||"*"}catch{return null}};wG.exports=uEe});var zI=I((oet,vG)=>{var gEe=Li(),SG=Id(),{ANY:fEe}=SG,hEe=cs(),pEe=wd(),bG=Cd(),QG=HI(),dEe=GI(),CEe=jI(),mEe=(r,e,t,i)=>{r=new gEe(r,i),e=new hEe(e,i);let n,s,o,a,l;switch(t){case">":n=bG,s=dEe,o=QG,a=">",l=">=";break;case"<":n=QG,s=CEe,o=bG,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(pEe(r,e,i))return!1;for(let c=0;c<e.set.length;++c){let u=e.set[c],g=null,h=null;if(u.forEach(p=>{p.semver===fEe&&(p=new SG(">=0.0.0")),g=g||p,h=h||p,n(p.semver,g.semver,i)?g=p:o(p.semver,h.semver,i)&&(h=p)}),g.operator===a||g.operator===l||(!h.operator||h.operator===a)&&s(r,h.semver))return!1;if(h.operator===l&&o(r,h.semver))return!1}return!0};vG.exports=mEe});var xG=I((aet,PG)=>{var EEe=zI(),IEe=(r,e,t)=>EEe(r,e,">",t);PG.exports=IEe});var DG=I((Aet,kG)=>{var yEe=zI(),wEe=(r,e,t)=>yEe(r,e,"<",t);kG.exports=wEe});var NG=I((cet,FG)=>{var RG=cs(),BEe=(r,e,t)=>(r=new RG(r,t),e=new RG(e,t),r.intersects(e));FG.exports=BEe});var LG=I((uet,TG)=>{var bEe=wd(),QEe=ls();TG.exports=(r,e,t)=>{let i=[],n=null,s=null,o=r.sort((u,g)=>QEe(u,g,t));for(let u of o)bEe(u,e,t)?(s=u,n||(n=u)):(s&&i.push([n,s]),s=null,n=null);n&&i.push([n,null]);let a=[];for(let[u,g]of i)u===g?a.push(u):!g&&u===o[0]?a.push("*"):g?u===o[0]?a.push(`<=${g}`):a.push(`${u} - ${g}`):a.push(`>=${u}`);let l=a.join(" || "),c=typeof e.raw=="string"?e.raw:String(e);return l.length<c.length?l:e}});var HG=I((get,UG)=>{var OG=cs(),VI=Id(),{ANY:vv}=VI,Bd=wd(),Pv=ls(),SEe=(r,e,t={})=>{if(r===e)return!0;r=new OG(r,t),e=new OG(e,t);let i=!1;e:for(let n of r.set){for(let s of e.set){let o=vEe(n,s,t);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},vEe=(r,e,t)=>{if(r===e)return!0;if(r.length===1&&r[0].semver===vv){if(e.length===1&&e[0].semver===vv)return!0;t.includePrerelease?r=[new VI(">=0.0.0-0")]:r=[new VI(">=0.0.0")]}if(e.length===1&&e[0].semver===vv){if(t.includePrerelease)return!0;e=[new VI(">=0.0.0")]}let i=new Set,n,s;for(let p of r)p.operator===">"||p.operator===">="?n=MG(n,p,t):p.operator==="<"||p.operator==="<="?s=KG(s,p,t):i.add(p.semver);if(i.size>1)return null;let o;if(n&&s){if(o=Pv(n.semver,s.semver,t),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let p of i){if(n&&!Bd(p,String(n),t)||s&&!Bd(p,String(s),t))return null;for(let d of e)if(!Bd(p,String(d),t))return!1;return!0}let a,l,c,u,g=s&&!t.includePrerelease&&s.semver.prerelease.length?s.semver:!1,h=n&&!t.includePrerelease&&n.semver.prerelease.length?n.semver:!1;g&&g.prerelease.length===1&&s.operator==="<"&&g.prerelease[0]===0&&(g=!1);for(let p of e){if(u=u||p.operator===">"||p.operator===">=",c=c||p.operator==="<"||p.operator==="<=",n){if(h&&p.semver.prerelease&&p.semver.prerelease.length&&p.semver.major===h.major&&p.semver.minor===h.minor&&p.semver.patch===h.patch&&(h=!1),p.operator===">"||p.operator===">="){if(a=MG(n,p,t),a===p&&a!==n)return!1}else if(n.operator===">="&&!Bd(n.semver,String(p),t))return!1}if(s){if(g&&p.semver.prerelease&&p.semver.prerelease.length&&p.semver.major===g.major&&p.semver.minor===g.minor&&p.semver.patch===g.patch&&(g=!1),p.operator==="<"||p.operator==="<="){if(l=KG(s,p,t),l===p&&l!==s)return!1}else if(s.operator==="<="&&!Bd(s.semver,String(p),t))return!1}if(!p.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||h||g)},MG=(r,e,t)=>{if(!r)return e;let i=Pv(r.semver,e.semver,t);return i>0?r:i<0||e.operator===">"&&r.operator===">="?e:r},KG=(r,e,t)=>{if(!r)return e;let i=Pv(r.semver,e.semver,t);return i<0?r:i>0||e.operator==="<"&&r.operator==="<="?e:r};UG.exports=SEe});var zr=I((fet,jG)=>{var xv=fc();jG.exports={re:xv.re,src:xv.src,tokens:xv.t,SEMVER_SPEC_VERSION:fd().SEMVER_SPEC_VERSION,SemVer:Li(),compareIdentifiers:LI().compareIdentifiers,rcompareIdentifiers:LI().rcompareIdentifiers,parse:hc(),valid:gj(),clean:hj(),inc:dj(),diff:wj(),major:bj(),minor:Sj(),patch:Pj(),prerelease:kj(),compare:ls(),rcompare:Rj(),compareLoose:Nj(),compareBuild:UI(),sort:Mj(),rsort:Uj(),gt:Cd(),lt:HI(),eq:KI(),neq:Cv(),gte:jI(),lte:GI(),cmp:mv(),coerce:zj(),Comparator:Id(),Range:cs(),satisfies:wd(),toComparators:hG(),maxSatisfying:dG(),minSatisfying:mG(),minVersion:yG(),validRange:BG(),outside:zI(),gtr:xG(),ltr:DG(),intersects:NG(),simplifyRange:LG(),subset:HG()}});var kv=I(XI=>{"use strict";Object.defineProperty(XI,"__esModule",{value:!0});XI.VERSION=void 0;XI.VERSION="9.1.0"});var Kt=I((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(r,e,t){if(t||arguments.length===2)for(var i=0,n=e.length,s;i<n;i++)(s||!(i in e))&&(s||(s=Array.prototype.slice.call(e,0,i)),s[i]=e[i]);return r.concat(s||Array.prototype.slice.call(e))};Object.defineProperty(exports,"__esModule",{value:!0});exports.toFastProperties=exports.timer=exports.peek=exports.isES2015MapSupported=exports.PRINT_WARNING=exports.PRINT_ERROR=exports.packArray=exports.IDENTITY=exports.NOOP=exports.merge=exports.groupBy=exports.defaults=exports.assignNoOverwrite=exports.assign=exports.zipObject=exports.sortBy=exports.indexOf=exports.some=exports.difference=exports.every=exports.isObject=exports.isRegExp=exports.isArray=exports.partial=exports.uniq=exports.compact=exports.reduce=exports.findAll=exports.find=exports.cloneObj=exports.cloneArr=exports.contains=exports.has=exports.pick=exports.reject=exports.filter=exports.dropRight=exports.drop=exports.isFunction=exports.isUndefined=exports.isString=exports.forEach=exports.last=exports.first=exports.flatten=exports.map=exports.mapValues=exports.values=exports.keys=exports.isEmpty=void 0;exports.upperFirst=void 0;function isEmpty(r){return r&&r.length===0}exports.isEmpty=isEmpty;function keys(r){return r==null?[]:Object.keys(r)}exports.keys=keys;function values(r){for(var e=[],t=Object.keys(r),i=0;i<t.length;i++)e.push(r[t[i]]);return e}exports.values=values;function mapValues(r,e){for(var t=[],i=keys(r),n=0;n<i.length;n++){var s=i[n];t.push(e.call(null,r[s],s))}return t}exports.mapValues=mapValues;function map(r,e){for(var t=[],i=0;i<r.length;i++)t.push(e.call(null,r[i],i));return t}exports.map=map;function flatten(r){for(var e=[],t=0;t<r.length;t++){var i=r[t];Array.isArray(i)?e=e.concat(flatten(i)):e.push(i)}return e}exports.flatten=flatten;function first(r){return isEmpty(r)?void 0:r[0]}exports.first=first;function last(r){var e=r&&r.length;return e?r[e-1]:void 0}exports.last=last;function forEach(r,e){if(Array.isArray(r))for(var t=0;t<r.length;t++)e.call(null,r[t],t);else if(isObject(r))for(var i=keys(r),t=0;t<i.length;t++){var n=i[t],s=r[n];e.call(null,s,n)}else throw Error("non exhaustive match")}exports.forEach=forEach;function isString(r){return typeof r=="string"}exports.isString=isString;function isUndefined(r){return r===void 0}exports.isUndefined=isUndefined;function isFunction(r){return r instanceof Function}exports.isFunction=isFunction;function drop(r,e){return e===void 0&&(e=1),r.slice(e,r.length)}exports.drop=drop;function dropRight(r,e){return e===void 0&&(e=1),r.slice(0,r.length-e)}exports.dropRight=dropRight;function filter(r,e){var t=[];if(Array.isArray(r))for(var i=0;i<r.length;i++){var n=r[i];e.call(null,n)&&t.push(n)}return t}exports.filter=filter;function reject(r,e){return filter(r,function(t){return!e(t)})}exports.reject=reject;function pick(r,e){for(var t=Object.keys(r),i={},n=0;n<t.length;n++){var s=t[n],o=r[s];e(o)&&(i[s]=o)}return i}exports.pick=pick;function has(r,e){return isObject(r)?r.hasOwnProperty(e):!1}exports.has=has;function contains(r,e){return find(r,function(t){return t===e})!==void 0}exports.contains=contains;function cloneArr(r){for(var e=[],t=0;t<r.length;t++)e.push(r[t]);return e}exports.cloneArr=cloneArr;function cloneObj(r){var e={};for(var t in r)Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=r[t]);return e}exports.cloneObj=cloneObj;function find(r,e){for(var t=0;t<r.length;t++){var i=r[t];if(e.call(null,i))return i}}exports.find=find;function findAll(r,e){for(var t=[],i=0;i<r.length;i++){var n=r[i];e.call(null,n)&&t.push(n)}return t}exports.findAll=findAll;function reduce(r,e,t){for(var i=Array.isArray(r),n=i?r:values(r),s=i?[]:keys(r),o=t,a=0;a<n.length;a++)o=e.call(null,o,n[a],i?a:s[a]);return o}exports.reduce=reduce;function compact(r){return reject(r,function(e){return e==null})}exports.compact=compact;function uniq(r,e){e===void 0&&(e=function(i){return i});var t=[];return reduce(r,function(i,n){var s=e(n);return contains(t,s)?i:(t.push(s),i.concat(n))},[])}exports.uniq=uniq;function partial(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];var i=[null],n=i.concat(e);return Function.bind.apply(r,n)}exports.partial=partial;function isArray(r){return Array.isArray(r)}exports.isArray=isArray;function isRegExp(r){return r instanceof RegExp}exports.isRegExp=isRegExp;function isObject(r){return r instanceof Object}exports.isObject=isObject;function every(r,e){for(var t=0;t<r.length;t++)if(!e(r[t],t))return!1;return!0}exports.every=every;function difference(r,e){return reject(r,function(t){return contains(e,t)})}exports.difference=difference;function some(r,e){for(var t=0;t<r.length;t++)if(e(r[t]))return!0;return!1}exports.some=some;function indexOf(r,e){for(var t=0;t<r.length;t++)if(r[t]===e)return t;return-1}exports.indexOf=indexOf;function sortBy(r,e){var t=cloneArr(r);return t.sort(function(i,n){return e(i)-e(n)}),t}exports.sortBy=sortBy;function zipObject(r,e){if(r.length!==e.length)throw Error("can't zipObject with different number of keys and values!");for(var t={},i=0;i<r.length;i++)t[r[i]]=e[i];return t}exports.zipObject=zipObject;function assign(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];for(var i=0;i<e.length;i++)for(var n=e[i],s=keys(n),o=0;o<s.length;o++){var a=s[o];r[a]=n[a]}return r}exports.assign=assign;function assignNoOverwrite(r){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];for(var i=0;i<e.length;i++)for(var n=e[i],s=keys(n),o=0;o<s.length;o++){var a=s[o];has(r,a)||(r[a]=n[a])}return r}exports.assignNoOverwrite=assignNoOverwrite;function defaults(){for(var r=[],e=0;e<arguments.length;e++)r[e]=arguments[e];return assignNoOverwrite.apply(void 0,__spreadArray([{}],r,!1))}exports.defaults=defaults;function groupBy(r,e){var t={};return forEach(r,function(i){var n=e(i),s=t[n];s?s.push(i):t[n]=[i]}),t}exports.groupBy=groupBy;function merge(r,e){for(var t=cloneObj(r),i=keys(e),n=0;n<i.length;n++){var s=i[n],o=e[s];t[s]=o}return t}exports.merge=merge;function NOOP(){}exports.NOOP=NOOP;function IDENTITY(r){return r}exports.IDENTITY=IDENTITY;function packArray(r){for(var e=[],t=0;t<r.length;t++){var i=r[t];e.push(i!==void 0?i:void 0)}return e}exports.packArray=packArray;function PRINT_ERROR(r){console&&console.error&&console.error("Error: "+r)}exports.PRINT_ERROR=PRINT_ERROR;function PRINT_WARNING(r){console&&console.warn&&console.warn("Warning: "+r)}exports.PRINT_WARNING=PRINT_WARNING;function isES2015MapSupported(){return typeof Map=="function"}exports.isES2015MapSupported=isES2015MapSupported;function peek(r){return r[r.length-1]}exports.peek=peek;function timer(r){var e=new Date().getTime(),t=r(),i=new Date().getTime(),n=i-e;return{time:n,value:t}}exports.timer=timer;function toFastProperties(toBecomeFast){function FakeConstructor(){}FakeConstructor.prototype=toBecomeFast;var fakeInstance=new FakeConstructor;function fakeAccess(){return typeof fakeInstance.bar}return fakeAccess(),fakeAccess(),toBecomeFast;eval(toBecomeFast)}exports.toFastProperties=toFastProperties;function upperFirst(r){if(!r)return r;var e=getCharacterFromCodePointAt(r,0);return e.toUpperCase()+r.substring(e.length)}exports.upperFirst=upperFirst;var surrogatePairPattern=/[\uD800-\uDBFF][\uDC00-\uDFFF]/;function getCharacterFromCodePointAt(r,e){var t=r.substring(e,e+1);return surrogatePairPattern.test(t)?t:r[e]}});var _I=I((GG,ZI)=>{(function(r,e){typeof define=="function"&&define.amd?define([],e):typeof ZI=="object"&&ZI.exports?ZI.exports=e():r.regexpToAst=e()})(typeof self<"u"?self:GG,function(){function r(){}r.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},r.prototype.restoreState=function(d){this.idx=d.idx,this.input=d.input,this.groupIdx=d.groupIdx},r.prototype.pattern=function(d){this.idx=0,this.input=d,this.groupIdx=0,this.consumeChar("/");var m=this.disjunction();this.consumeChar("/");for(var y={type:"Flags",loc:{begin:this.idx,end:d.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":o(y,"global");break;case"i":o(y,"ignoreCase");break;case"m":o(y,"multiLine");break;case"u":o(y,"unicode");break;case"y":o(y,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:y,value:m,loc:this.loc(0)}},r.prototype.disjunction=function(){var d=[],m=this.idx;for(d.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),d.push(this.alternative());return{type:"Disjunction",value:d,loc:this.loc(m)}},r.prototype.alternative=function(){for(var d=[],m=this.idx;this.isTerm();)d.push(this.term());return{type:"Alternative",value:d,loc:this.loc(m)}},r.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},r.prototype.assertion=function(){var d=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(d)};case"$":return{type:"EndAnchor",loc:this.loc(d)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(d)};case"B":return{type:"NonWordBoundary",loc:this.loc(d)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");var m;switch(this.popChar()){case"=":m="Lookahead";break;case"!":m="NegativeLookahead";break}a(m);var y=this.disjunction();return this.consumeChar(")"),{type:m,value:y,loc:this.loc(d)}}l()},r.prototype.quantifier=function(d){var m,y=this.idx;switch(this.popChar()){case"*":m={atLeast:0,atMost:1/0};break;case"+":m={atLeast:1,atMost:1/0};break;case"?":m={atLeast:0,atMost:1};break;case"{":var B=this.integerIncludingZero();switch(this.popChar()){case"}":m={atLeast:B,atMost:B};break;case",":var S;this.isDigit()?(S=this.integerIncludingZero(),m={atLeast:B,atMost:S}):m={atLeast:B,atMost:1/0},this.consumeChar("}");break}if(d===!0&&m===void 0)return;a(m);break}if(!(d===!0&&m===void 0))return a(m),this.peekChar(0)==="?"?(this.consumeChar("?"),m.greedy=!1):m.greedy=!0,m.type="Quantifier",m.loc=this.loc(y),m},r.prototype.atom=function(){var d,m=this.idx;switch(this.peekChar()){case".":d=this.dotAll();break;case"\\":d=this.atomEscape();break;case"[":d=this.characterClass();break;case"(":d=this.group();break}return d===void 0&&this.isPatternCharacter()&&(d=this.patternCharacter()),a(d),d.loc=this.loc(m),this.isQuantifier()&&(d.quantifier=this.quantifier()),d},r.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` +`),n("\r"),n("\u2028"),n("\u2029")]}},r.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.decimalEscapeAtom=function(){var d=this.positiveInteger();return{type:"GroupBackReference",value:d}},r.prototype.characterClassEscape=function(){var d,m=!1;switch(this.popChar()){case"d":d=u;break;case"D":d=u,m=!0;break;case"s":d=h;break;case"S":d=h,m=!0;break;case"w":d=g;break;case"W":d=g,m=!0;break}return a(d),{type:"Set",value:d,complement:m}},r.prototype.controlEscapeAtom=function(){var d;switch(this.popChar()){case"f":d=n("\f");break;case"n":d=n(` +`);break;case"r":d=n("\r");break;case"t":d=n(" ");break;case"v":d=n("\v");break}return a(d),{type:"Character",value:d}},r.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var d=this.popChar();if(/[a-zA-Z]/.test(d)===!1)throw Error("Invalid ");var m=d.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:m}},r.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},r.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},r.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},r.prototype.identityEscapeAtom=function(){var d=this.popChar();return{type:"Character",value:n(d)}},r.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case` +`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var d=this.popChar();return{type:"Character",value:n(d)}}},r.prototype.characterClass=function(){var d=[],m=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),m=!0);this.isClassAtom();){var y=this.classAtom(),B=y.type==="Character";if(B&&this.isRangeDash()){this.consumeChar("-");var S=this.classAtom(),x=S.type==="Character";if(x){if(S.value<y.value)throw Error("Range out of order in character class");d.push({from:y.value,to:S.value})}else s(y.value,d),d.push(n("-")),s(S.value,d)}else s(y.value,d)}return this.consumeChar("]"),{type:"Set",complement:m,value:d}},r.prototype.classAtom=function(){switch(this.peekChar()){case"]":case` +`:case"\r":case"\u2028":case"\u2029":throw Error("TBD");case"\\":return this.classEscape();default:return this.classPatternCharacterAtom()}},r.prototype.classEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"b":return this.consumeChar("b"),{type:"Character",value:n("\b")};case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.group=function(){var d=!0;switch(this.consumeChar("("),this.peekChar(0)){case"?":this.consumeChar("?"),this.consumeChar(":"),d=!1;break;default:this.groupIdx++;break}var m=this.disjunction();this.consumeChar(")");var y={type:"Group",capturing:d,value:m};return d&&(y.idx=this.groupIdx),y},r.prototype.positiveInteger=function(){var d=this.popChar();if(i.test(d)===!1)throw Error("Expecting a positive integer");for(;t.test(this.peekChar(0));)d+=this.popChar();return parseInt(d,10)},r.prototype.integerIncludingZero=function(){var d=this.popChar();if(t.test(d)===!1)throw Error("Expecting an integer");for(;t.test(this.peekChar(0));)d+=this.popChar();return parseInt(d,10)},r.prototype.patternCharacter=function(){var d=this.popChar();switch(d){case` +`:case"\r":case"\u2028":case"\u2029":case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":throw Error("TBD");default:return{type:"Character",value:n(d)}}},r.prototype.isRegExpFlag=function(){switch(this.peekChar(0)){case"g":case"i":case"m":case"u":case"y":return!0;default:return!1}},r.prototype.isRangeDash=function(){return this.peekChar()==="-"&&this.isClassAtom(1)},r.prototype.isDigit=function(){return t.test(this.peekChar(0))},r.prototype.isClassAtom=function(d){switch(d===void 0&&(d=0),this.peekChar(d)){case"]":case` +`:case"\r":case"\u2028":case"\u2029":return!1;default:return!0}},r.prototype.isTerm=function(){return this.isAtom()||this.isAssertion()},r.prototype.isAtom=function(){if(this.isPatternCharacter())return!0;switch(this.peekChar(0)){case".":case"\\":case"[":case"(":return!0;default:return!1}},r.prototype.isAssertion=function(){switch(this.peekChar(0)){case"^":case"$":return!0;case"\\":switch(this.peekChar(1)){case"b":case"B":return!0;default:return!1}case"(":return this.peekChar(1)==="?"&&(this.peekChar(2)==="="||this.peekChar(2)==="!");default:return!1}},r.prototype.isQuantifier=function(){var d=this.saveState();try{return this.quantifier(!0)!==void 0}catch{return!1}finally{this.restoreState(d)}},r.prototype.isPatternCharacter=function(){switch(this.peekChar()){case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":case"/":case` +`:case"\r":case"\u2028":case"\u2029":return!1;default:return!0}},r.prototype.parseHexDigits=function(d){for(var m="",y=0;y<d;y++){var B=this.popChar();if(e.test(B)===!1)throw Error("Expecting a HexDecimal digits");m+=B}var S=parseInt(m,16);return{type:"Character",value:S}},r.prototype.peekChar=function(d){return d===void 0&&(d=0),this.input[this.idx+d]},r.prototype.popChar=function(){var d=this.peekChar(0);return this.consumeChar(),d},r.prototype.consumeChar=function(d){if(d!==void 0&&this.input[this.idx]!==d)throw Error("Expected: '"+d+"' but found: '"+this.input[this.idx]+"' at offset: "+this.idx);if(this.idx>=this.input.length)throw Error("Unexpected end of input");this.idx++},r.prototype.loc=function(d){return{begin:d,end:this.idx}};var e=/[0-9a-fA-F]/,t=/[0-9]/,i=/[1-9]/;function n(d){return d.charCodeAt(0)}function s(d,m){d.length!==void 0?d.forEach(function(y){m.push(y)}):m.push(d)}function o(d,m){if(d[m]===!0)throw"duplicate flag "+m;d[m]=!0}function a(d){if(d===void 0)throw Error("Internal Error - Should never get here!")}function l(){throw Error("Internal Error - Should never get here!")}var c,u=[];for(c=n("0");c<=n("9");c++)u.push(c);var g=[n("_")].concat(u);for(c=n("a");c<=n("z");c++)g.push(c);for(c=n("A");c<=n("Z");c++)g.push(c);var h=[n(" "),n("\f"),n(` +`),n("\r"),n(" "),n("\v"),n(" "),n("\xA0"),n("\u1680"),n("\u2000"),n("\u2001"),n("\u2002"),n("\u2003"),n("\u2004"),n("\u2005"),n("\u2006"),n("\u2007"),n("\u2008"),n("\u2009"),n("\u200A"),n("\u2028"),n("\u2029"),n("\u202F"),n("\u205F"),n("\u3000"),n("\uFEFF")];function p(){}return p.prototype.visitChildren=function(d){for(var m in d){var y=d[m];d.hasOwnProperty(m)&&(y.type!==void 0?this.visit(y):Array.isArray(y)&&y.forEach(function(B){this.visit(B)},this))}},p.prototype.visit=function(d){switch(d.type){case"Pattern":this.visitPattern(d);break;case"Flags":this.visitFlags(d);break;case"Disjunction":this.visitDisjunction(d);break;case"Alternative":this.visitAlternative(d);break;case"StartAnchor":this.visitStartAnchor(d);break;case"EndAnchor":this.visitEndAnchor(d);break;case"WordBoundary":this.visitWordBoundary(d);break;case"NonWordBoundary":this.visitNonWordBoundary(d);break;case"Lookahead":this.visitLookahead(d);break;case"NegativeLookahead":this.visitNegativeLookahead(d);break;case"Character":this.visitCharacter(d);break;case"Set":this.visitSet(d);break;case"Group":this.visitGroup(d);break;case"GroupBackReference":this.visitGroupBackReference(d);break;case"Quantifier":this.visitQuantifier(d);break}this.visitChildren(d)},p.prototype.visitPattern=function(d){},p.prototype.visitFlags=function(d){},p.prototype.visitDisjunction=function(d){},p.prototype.visitAlternative=function(d){},p.prototype.visitStartAnchor=function(d){},p.prototype.visitEndAnchor=function(d){},p.prototype.visitWordBoundary=function(d){},p.prototype.visitNonWordBoundary=function(d){},p.prototype.visitLookahead=function(d){},p.prototype.visitNegativeLookahead=function(d){},p.prototype.visitCharacter=function(d){},p.prototype.visitSet=function(d){},p.prototype.visitGroup=function(d){},p.prototype.visitGroupBackReference=function(d){},p.prototype.visitQuantifier=function(d){},{RegExpParser:r,BaseRegExpVisitor:p,VERSION:"0.5.0"}})});var ey=I(Xg=>{"use strict";Object.defineProperty(Xg,"__esModule",{value:!0});Xg.clearRegExpParserCache=Xg.getRegExpAst=void 0;var PEe=_I(),$I={},xEe=new PEe.RegExpParser;function kEe(r){var e=r.toString();if($I.hasOwnProperty(e))return $I[e];var t=xEe.pattern(e);return $I[e]=t,t}Xg.getRegExpAst=kEe;function DEe(){$I={}}Xg.clearRegExpParserCache=DEe});var zG=I(Cn=>{"use strict";var REe=Cn&&Cn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Cn,"__esModule",{value:!0});Cn.canMatchCharCode=Cn.firstCharOptimizedIndices=Cn.getOptimizedStartCodesIndices=Cn.failedOptimizationPrefixMsg=void 0;var qG=_I(),us=Kt(),JG=ey(),xa=Rv(),WG="Complement Sets are not supported for first char optimization";Cn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: +`;function FEe(r,e){e===void 0&&(e=!1);try{var t=(0,JG.getRegExpAst)(r),i=ry(t.value,{},t.flags.ignoreCase);return i}catch(s){if(s.message===WG)e&&(0,us.PRINT_WARNING)(""+Cn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+r.toString()+` > +`)+` Complement Sets cannot be automatically optimized. + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{var n="";e&&(n=` + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),(0,us.PRINT_ERROR)(Cn.failedOptimizationPrefixMsg+` +`+(" Failed parsing: < "+r.toString()+` > +`)+(" Using the regexp-to-ast library version: "+qG.VERSION+` +`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}Cn.getOptimizedStartCodesIndices=FEe;function ry(r,e,t){switch(r.type){case"Disjunction":for(var i=0;i<r.value.length;i++)ry(r.value[i],e,t);break;case"Alternative":for(var n=r.value,i=0;i<n.length;i++){var s=n[i];switch(s.type){case"EndAnchor":case"GroupBackReference":case"Lookahead":case"NegativeLookahead":case"StartAnchor":case"WordBoundary":case"NonWordBoundary":continue}var o=s;switch(o.type){case"Character":ty(o.value,e,t);break;case"Set":if(o.complement===!0)throw Error(WG);(0,us.forEach)(o.value,function(c){if(typeof c=="number")ty(c,e,t);else{var u=c;if(t===!0)for(var g=u.from;g<=u.to;g++)ty(g,e,t);else{for(var g=u.from;g<=u.to&&g<xa.minOptimizationVal;g++)ty(g,e,t);if(u.to>=xa.minOptimizationVal)for(var h=u.from>=xa.minOptimizationVal?u.from:xa.minOptimizationVal,p=u.to,d=(0,xa.charCodeToOptimizedIndex)(h),m=(0,xa.charCodeToOptimizedIndex)(p),y=d;y<=m;y++)e[y]=y}}});break;case"Group":ry(o.value,e,t);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&Dv(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,us.values)(e)}Cn.firstCharOptimizedIndices=ry;function ty(r,e,t){var i=(0,xa.charCodeToOptimizedIndex)(r);e[i]=i,t===!0&&NEe(r,e)}function NEe(r,e){var t=String.fromCharCode(r),i=t.toUpperCase();if(i!==t){var n=(0,xa.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=t.toLowerCase();if(s!==t){var n=(0,xa.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function YG(r,e){return(0,us.find)(r.value,function(t){if(typeof t=="number")return(0,us.contains)(e,t);var i=t;return(0,us.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function Dv(r){return r.quantifier&&r.quantifier.atLeast===0?!0:r.value?(0,us.isArray)(r.value)?(0,us.every)(r.value,Dv):Dv(r.value):!1}var TEe=function(r){REe(e,r);function e(t){var i=r.call(this)||this;return i.targetCharCodes=t,i.found=!1,i}return e.prototype.visitChildren=function(t){if(this.found!==!0){switch(t.type){case"Lookahead":this.visitLookahead(t);return;case"NegativeLookahead":this.visitNegativeLookahead(t);return}r.prototype.visitChildren.call(this,t)}},e.prototype.visitCharacter=function(t){(0,us.contains)(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?YG(t,this.targetCharCodes)===void 0&&(this.found=!0):YG(t,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(qG.BaseRegExpVisitor);function LEe(r,e){if(e instanceof RegExp){var t=(0,JG.getRegExpAst)(e),i=new TEe(r);return i.visit(t),i.found}else return(0,us.find)(e,function(n){return(0,us.contains)(r,n.charCodeAt(0))})!==void 0}Cn.canMatchCharCode=LEe});var Rv=I(We=>{"use strict";var VG=We&&We.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(We,"__esModule",{value:!0});We.charCodeToOptimizedIndex=We.minOptimizationVal=We.buildLineBreakIssueMessage=We.LineTerminatorOptimizedTester=We.isShortPattern=We.isCustomPattern=We.cloneEmptyGroups=We.performWarningRuntimeChecks=We.performRuntimeChecks=We.addStickyFlag=We.addStartOfInput=We.findUnreachablePatterns=We.findModesThatDoNotExist=We.findInvalidGroupType=We.findDuplicatePatterns=We.findUnsupportedFlags=We.findStartOfInputAnchor=We.findEmptyMatchRegExps=We.findEndOfInputAnchor=We.findInvalidPatterns=We.findMissingPatterns=We.validatePatterns=We.analyzeTokenTypes=We.enableSticky=We.disableSticky=We.SUPPORT_STICKY=We.MODES=We.DEFAULT_MODE=void 0;var XG=_I(),tr=bd(),Se=Kt(),Zg=zG(),ZG=ey(),ko="PATTERN";We.DEFAULT_MODE="defaultMode";We.MODES="modes";We.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function OEe(){We.SUPPORT_STICKY=!1}We.disableSticky=OEe;function MEe(){We.SUPPORT_STICKY=!0}We.enableSticky=MEe;function KEe(r,e){e=(0,Se.defaults)(e,{useSticky:We.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` +`],tracer:function(S,x){return x()}});var t=e.tracer;t("initCharCodeToOptimizedIndexMap",function(){VEe()});var i;t("Reject Lexer.NA",function(){i=(0,Se.reject)(r,function(S){return S[ko]===tr.Lexer.NA})});var n=!1,s;t("Transform Patterns",function(){n=!1,s=(0,Se.map)(i,function(S){var x=S[ko];if((0,Se.isRegExp)(x)){var F=x.source;return F.length===1&&F!=="^"&&F!=="$"&&F!=="."&&!x.ignoreCase?F:F.length===2&&F[0]==="\\"&&!(0,Se.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],F[1])?F[1]:e.useSticky?Tv(x):Nv(x)}else{if((0,Se.isFunction)(x))return n=!0,{exec:x};if((0,Se.has)(x,"exec"))return n=!0,x;if(typeof x=="string"){if(x.length===1)return x;var H=x.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),q=new RegExp(H);return e.useSticky?Tv(q):Nv(q)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;t("misc mapping",function(){o=(0,Se.map)(i,function(S){return S.tokenTypeIdx}),a=(0,Se.map)(i,function(S){var x=S.GROUP;if(x!==tr.Lexer.SKIPPED){if((0,Se.isString)(x))return x;if((0,Se.isUndefined)(x))return!1;throw Error("non exhaustive match")}}),l=(0,Se.map)(i,function(S){var x=S.LONGER_ALT;if(x){var F=(0,Se.isArray)(x)?(0,Se.map)(x,function(H){return(0,Se.indexOf)(i,H)}):[(0,Se.indexOf)(i,x)];return F}}),c=(0,Se.map)(i,function(S){return S.PUSH_MODE}),u=(0,Se.map)(i,function(S){return(0,Se.has)(S,"POP_MODE")})});var g;t("Line Terminator Handling",function(){var S=uY(e.lineTerminatorCharacters);g=(0,Se.map)(i,function(x){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,Se.map)(i,function(x){if((0,Se.has)(x,"LINE_BREAKS"))return x.LINE_BREAKS;if(lY(x,S)===!1)return(0,Zg.canMatchCharCode)(S,x.PATTERN)}))});var h,p,d,m;t("Misc Mapping #2",function(){h=(0,Se.map)(i,Ov),p=(0,Se.map)(s,AY),d=(0,Se.reduce)(i,function(S,x){var F=x.GROUP;return(0,Se.isString)(F)&&F!==tr.Lexer.SKIPPED&&(S[F]=[]),S},{}),m=(0,Se.map)(s,function(S,x){return{pattern:s[x],longerAlt:l[x],canLineTerminator:g[x],isCustom:h[x],short:p[x],group:a[x],push:c[x],pop:u[x],tokenTypeIdx:o[x],tokenType:i[x]}})});var y=!0,B=[];return e.safeMode||t("First Char Optimization",function(){B=(0,Se.reduce)(i,function(S,x,F){if(typeof x.PATTERN=="string"){var H=x.PATTERN.charCodeAt(0),q=Lv(H);Fv(S,q,m[F])}else if((0,Se.isArray)(x.START_CHARS_HINT)){var _;(0,Se.forEach)(x.START_CHARS_HINT,function(W){var Z=typeof W=="string"?W.charCodeAt(0):W,A=Lv(Z);_!==A&&(_=A,Fv(S,A,m[F]))})}else if((0,Se.isRegExp)(x.PATTERN))if(x.PATTERN.unicode)y=!1,e.ensureOptimizations&&(0,Se.PRINT_ERROR)(""+Zg.failedOptimizationPrefixMsg+(" Unable to analyze < "+x.PATTERN.toString()+` > pattern. +`)+` The regexp unicode flag is not currently supported by the regexp-to-ast library. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{var X=(0,Zg.getOptimizedStartCodesIndices)(x.PATTERN,e.ensureOptimizations);(0,Se.isEmpty)(X)&&(y=!1),(0,Se.forEach)(X,function(W){Fv(S,W,m[F])})}else e.ensureOptimizations&&(0,Se.PRINT_ERROR)(""+Zg.failedOptimizationPrefixMsg+(" TokenType: <"+x.name+`> is using a custom token pattern without providing <start_chars_hint> parameter. +`)+` This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),y=!1;return S},[])}),t("ArrayPacking",function(){B=(0,Se.packArray)(B)}),{emptyGroups:d,patternIdxToConfig:m,charCodeToPatternIdxToConfig:B,hasCustom:n,canBeOptimized:y}}We.analyzeTokenTypes=KEe;function UEe(r,e){var t=[],i=_G(r);t=t.concat(i.errors);var n=$G(i.valid),s=n.valid;return t=t.concat(n.errors),t=t.concat(HEe(s)),t=t.concat(sY(s)),t=t.concat(oY(s,e)),t=t.concat(aY(s)),t}We.validatePatterns=UEe;function HEe(r){var e=[],t=(0,Se.filter)(r,function(i){return(0,Se.isRegExp)(i[ko])});return e=e.concat(eY(t)),e=e.concat(rY(t)),e=e.concat(iY(t)),e=e.concat(nY(t)),e=e.concat(tY(t)),e}function _G(r){var e=(0,Se.filter)(r,function(n){return!(0,Se.has)(n,ko)}),t=(0,Se.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:tr.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,Se.difference)(r,e);return{errors:t,valid:i}}We.findMissingPatterns=_G;function $G(r){var e=(0,Se.filter)(r,function(n){var s=n[ko];return!(0,Se.isRegExp)(s)&&!(0,Se.isFunction)(s)&&!(0,Se.has)(s,"exec")&&!(0,Se.isString)(s)}),t=(0,Se.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:tr.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,Se.difference)(r,e);return{errors:t,valid:i}}We.findInvalidPatterns=$G;var jEe=/[^\\][\$]/;function eY(r){var e=function(n){VG(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitEndAnchor=function(o){this.found=!0},s}(XG.BaseRegExpVisitor),t=(0,Se.filter)(r,function(n){var s=n[ko];try{var o=(0,ZG.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return jEe.test(s.source)}}),i=(0,Se.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain end of input anchor '$' + See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:tr.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}We.findEndOfInputAnchor=eY;function tY(r){var e=(0,Se.filter)(r,function(i){var n=i[ko];return n.test("")}),t=(0,Se.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:tr.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return t}We.findEmptyMatchRegExps=tY;var GEe=/[^\\[][\^]|^\^/;function rY(r){var e=function(n){VG(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitStartAnchor=function(o){this.found=!0},s}(XG.BaseRegExpVisitor),t=(0,Se.filter)(r,function(n){var s=n[ko];try{var o=(0,ZG.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return GEe.test(s.source)}}),i=(0,Se.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain start of input anchor '^' + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:tr.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}We.findStartOfInputAnchor=rY;function iY(r){var e=(0,Se.filter)(r,function(i){var n=i[ko];return n instanceof RegExp&&(n.multiline||n.global)}),t=(0,Se.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:tr.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return t}We.findUnsupportedFlags=iY;function nY(r){var e=[],t=(0,Se.map)(r,function(s){return(0,Se.reduce)(r,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,Se.contains)(e,a)&&a.PATTERN!==tr.Lexer.NA&&(e.push(a),o.push(a)),o},[])});t=(0,Se.compact)(t);var i=(0,Se.filter)(t,function(s){return s.length>1}),n=(0,Se.map)(i,function(s){var o=(0,Se.map)(s,function(l){return l.name}),a=(0,Se.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:tr.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}We.findDuplicatePatterns=nY;function sY(r){var e=(0,Se.filter)(r,function(i){if(!(0,Se.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==tr.Lexer.SKIPPED&&n!==tr.Lexer.NA&&!(0,Se.isString)(n)}),t=(0,Se.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:tr.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return t}We.findInvalidGroupType=sY;function oY(r,e){var t=(0,Se.filter)(r,function(n){return n.PUSH_MODE!==void 0&&!(0,Se.contains)(e,n.PUSH_MODE)}),i=(0,Se.map)(t,function(n){var s="Token Type: ->"+n.name+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+n.PUSH_MODE+"<-which does not exist";return{message:s,type:tr.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}We.findModesThatDoNotExist=oY;function aY(r){var e=[],t=(0,Se.reduce)(r,function(i,n,s){var o=n.PATTERN;return o===tr.Lexer.NA||((0,Se.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,Se.isRegExp)(o)&&qEe(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,Se.forEach)(r,function(i,n){(0,Se.forEach)(t,function(s){var o=s.str,a=s.idx,l=s.tokenType;if(n<a&&YEe(o,i.PATTERN)){var c="Token: ->"+l.name+`<- can never be matched. +`+("Because it appears AFTER the Token Type ->"+i.name+"<-")+`in the lexer's definition. +See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:c,type:tr.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}We.findUnreachablePatterns=aY;function YEe(r,e){if((0,Se.isRegExp)(e)){var t=e.exec(r);return t!==null&&t.index===0}else{if((0,Se.isFunction)(e))return e(r,0,[],{});if((0,Se.has)(e,"exec"))return e.exec(r,0,[],{});if(typeof e=="string")return e===r;throw Error("non exhaustive match")}}function qEe(r){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,Se.find)(e,function(t){return r.source.indexOf(t)!==-1})===void 0}function Nv(r){var e=r.ignoreCase?"i":"";return new RegExp("^(?:"+r.source+")",e)}We.addStartOfInput=Nv;function Tv(r){var e=r.ignoreCase?"iy":"y";return new RegExp(""+r.source,e)}We.addStickyFlag=Tv;function JEe(r,e,t){var i=[];return(0,Se.has)(r,We.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+We.DEFAULT_MODE+`> property in its definition +`,type:tr.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,Se.has)(r,We.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+We.MODES+`> property in its definition +`,type:tr.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,Se.has)(r,We.MODES)&&(0,Se.has)(r,We.DEFAULT_MODE)&&!(0,Se.has)(r.modes,r.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+We.DEFAULT_MODE+": <"+r.defaultMode+`>which does not exist +`,type:tr.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,Se.has)(r,We.MODES)&&(0,Se.forEach)(r.modes,function(n,s){(0,Se.forEach)(n,function(o,a){(0,Se.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> +`),type:tr.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}We.performRuntimeChecks=JEe;function WEe(r,e,t){var i=[],n=!1,s=(0,Se.compact)((0,Se.flatten)((0,Se.mapValues)(r.modes,function(l){return l}))),o=(0,Se.reject)(s,function(l){return l[ko]===tr.Lexer.NA}),a=uY(t);return e&&(0,Se.forEach)(o,function(l){var c=lY(l,a);if(c!==!1){var u=cY(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,Se.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,Zg.canMatchCharCode)(a,l.PATTERN)&&(n=!0)}),e&&!n&&i.push({message:`Warning: No LINE_BREAKS Found. + This Lexer has been defined to track line and column information, + But none of the Token Types can be identified as matching a line terminator. + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS + for details.`,type:tr.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}We.performWarningRuntimeChecks=WEe;function zEe(r){var e={},t=(0,Se.keys)(r);return(0,Se.forEach)(t,function(i){var n=r[i];if((0,Se.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}We.cloneEmptyGroups=zEe;function Ov(r){var e=r.PATTERN;if((0,Se.isRegExp)(e))return!1;if((0,Se.isFunction)(e))return!0;if((0,Se.has)(e,"exec"))return!0;if((0,Se.isString)(e))return!1;throw Error("non exhaustive match")}We.isCustomPattern=Ov;function AY(r){return(0,Se.isString)(r)&&r.length===1?r.charCodeAt(0):!1}We.isShortPattern=AY;We.LineTerminatorOptimizedTester={test:function(r){for(var e=r.length,t=this.lastIndex;t<e;t++){var i=r.charCodeAt(t);if(i===10)return this.lastIndex=t+1,!0;if(i===13)return r.charCodeAt(t+1)===10?this.lastIndex=t+2:this.lastIndex=t+1,!0}return!1},lastIndex:0};function lY(r,e){if((0,Se.has)(r,"LINE_BREAKS"))return!1;if((0,Se.isRegExp)(r.PATTERN)){try{(0,Zg.canMatchCharCode)(e,r.PATTERN)}catch(t){return{issue:tr.LexerDefinitionErrorType.IDENTIFY_TERMINATOR,errMsg:t.message}}return!1}else{if((0,Se.isString)(r.PATTERN))return!1;if(Ov(r))return{issue:tr.LexerDefinitionErrorType.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}}function cY(r,e){if(e.issue===tr.LexerDefinitionErrorType.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern. +`+(" The problem is in the <"+r.name+`> Token Type +`)+(" Root cause: "+e.errMsg+`. +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===tr.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the <line_breaks> option. +`+(" The problem is in the <"+r.name+`> Token Type +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}We.buildLineBreakIssueMessage=cY;function uY(r){var e=(0,Se.map)(r,function(t){return(0,Se.isString)(t)&&t.length>0?t.charCodeAt(0):t});return e}function Fv(r,e,t){r[e]===void 0?r[e]=[t]:r[e].push(t)}We.minOptimizationVal=256;var iy=[];function Lv(r){return r<We.minOptimizationVal?r:iy[r]}We.charCodeToOptimizedIndex=Lv;function VEe(){if((0,Se.isEmpty)(iy)){iy=new Array(65536);for(var r=0;r<65536;r++)iy[r]=r>255?255+~~(r/255):r}}});var _g=I(Rt=>{"use strict";Object.defineProperty(Rt,"__esModule",{value:!0});Rt.isTokenType=Rt.hasExtendingTokensTypesMapProperty=Rt.hasExtendingTokensTypesProperty=Rt.hasCategoriesProperty=Rt.hasShortKeyProperty=Rt.singleAssignCategoriesToksMap=Rt.assignCategoriesMapProp=Rt.assignCategoriesTokensProp=Rt.assignTokenDefaultProps=Rt.expandCategories=Rt.augmentTokenTypes=Rt.tokenIdxToClass=Rt.tokenShortNameIdx=Rt.tokenStructuredMatcherNoCategories=Rt.tokenStructuredMatcher=void 0;var Vr=Kt();function XEe(r,e){var t=r.tokenTypeIdx;return t===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[t]===!0}Rt.tokenStructuredMatcher=XEe;function ZEe(r,e){return r.tokenTypeIdx===e.tokenTypeIdx}Rt.tokenStructuredMatcherNoCategories=ZEe;Rt.tokenShortNameIdx=1;Rt.tokenIdxToClass={};function _Ee(r){var e=gY(r);fY(e),pY(e),hY(e),(0,Vr.forEach)(e,function(t){t.isParent=t.categoryMatches.length>0})}Rt.augmentTokenTypes=_Ee;function gY(r){for(var e=(0,Vr.cloneArr)(r),t=r,i=!0;i;){t=(0,Vr.compact)((0,Vr.flatten)((0,Vr.map)(t,function(s){return s.CATEGORIES})));var n=(0,Vr.difference)(t,e);e=e.concat(n),(0,Vr.isEmpty)(n)?i=!1:t=n}return e}Rt.expandCategories=gY;function fY(r){(0,Vr.forEach)(r,function(e){dY(e)||(Rt.tokenIdxToClass[Rt.tokenShortNameIdx]=e,e.tokenTypeIdx=Rt.tokenShortNameIdx++),Mv(e)&&!(0,Vr.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Mv(e)||(e.CATEGORIES=[]),CY(e)||(e.categoryMatches=[]),mY(e)||(e.categoryMatchesMap={})})}Rt.assignTokenDefaultProps=fY;function hY(r){(0,Vr.forEach)(r,function(e){e.categoryMatches=[],(0,Vr.forEach)(e.categoryMatchesMap,function(t,i){e.categoryMatches.push(Rt.tokenIdxToClass[i].tokenTypeIdx)})})}Rt.assignCategoriesTokensProp=hY;function pY(r){(0,Vr.forEach)(r,function(e){Kv([],e)})}Rt.assignCategoriesMapProp=pY;function Kv(r,e){(0,Vr.forEach)(r,function(t){e.categoryMatchesMap[t.tokenTypeIdx]=!0}),(0,Vr.forEach)(e.CATEGORIES,function(t){var i=r.concat(e);(0,Vr.contains)(i,t)||Kv(i,t)})}Rt.singleAssignCategoriesToksMap=Kv;function dY(r){return(0,Vr.has)(r,"tokenTypeIdx")}Rt.hasShortKeyProperty=dY;function Mv(r){return(0,Vr.has)(r,"CATEGORIES")}Rt.hasCategoriesProperty=Mv;function CY(r){return(0,Vr.has)(r,"categoryMatches")}Rt.hasExtendingTokensTypesProperty=CY;function mY(r){return(0,Vr.has)(r,"categoryMatchesMap")}Rt.hasExtendingTokensTypesMapProperty=mY;function $Ee(r){return(0,Vr.has)(r,"tokenTypeIdx")}Rt.isTokenType=$Ee});var Uv=I(ny=>{"use strict";Object.defineProperty(ny,"__esModule",{value:!0});ny.defaultLexerErrorProvider=void 0;ny.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(r){return"Unable to pop Lexer Mode after encountering Token ->"+r.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(r,e,t,i,n){return"unexpected character: ->"+r.charAt(e)+"<- at offset: "+e+","+(" skipped "+t+" characters.")}}});var bd=I(Ec=>{"use strict";Object.defineProperty(Ec,"__esModule",{value:!0});Ec.Lexer=Ec.LexerDefinitionErrorType=void 0;var Zs=Rv(),rr=Kt(),eIe=_g(),tIe=Uv(),rIe=ey(),iIe;(function(r){r[r.MISSING_PATTERN=0]="MISSING_PATTERN",r[r.INVALID_PATTERN=1]="INVALID_PATTERN",r[r.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",r[r.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",r[r.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",r[r.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",r[r.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",r[r.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",r[r.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",r[r.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",r[r.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",r[r.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",r[r.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",r[r.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",r[r.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",r[r.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",r[r.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(iIe=Ec.LexerDefinitionErrorType||(Ec.LexerDefinitionErrorType={}));var Qd={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` +`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:tIe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(Qd);var nIe=function(){function r(e,t){var i=this;if(t===void 0&&(t=Qd),this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},typeof t=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. +a boolean 2nd argument is no longer supported`);this.config=(0,rr.merge)(Qd,t);var n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",function(){var s,o=!0;i.TRACE_INIT("Lexer Config handling",function(){if(i.config.lineTerminatorsPattern===Qd.lineTerminatorsPattern)i.config.lineTerminatorsPattern=Zs.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===Qd.lineTerminatorCharacters)throw Error(`Error: Missing <lineTerminatorCharacters> property on the Lexer config. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');i.trackStartLines=/full|onlyStart/i.test(i.config.positionTracking),i.trackEndLines=/full/i.test(i.config.positionTracking),(0,rr.isArray)(e)?(s={modes:{}},s.modes[Zs.DEFAULT_MODE]=(0,rr.cloneArr)(e),s[Zs.DEFAULT_MODE]=Zs.DEFAULT_MODE):(o=!1,s=(0,rr.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,Zs.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,Zs.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,rr.forEach)(s.modes,function(u,g){s.modes[g]=(0,rr.reject)(u,function(h){return(0,rr.isUndefined)(h)})});var a=(0,rr.keys)(s.modes);if((0,rr.forEach)(s.modes,function(u,g){i.TRACE_INIT("Mode: <"+g+"> processing",function(){if(i.modes.push(g),i.config.skipValidations===!1&&i.TRACE_INIT("validatePatterns",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,Zs.validatePatterns)(u,a))}),(0,rr.isEmpty)(i.lexerDefinitionErrors)){(0,eIe.augmentTokenTypes)(u);var h;i.TRACE_INIT("analyzeTokenTypes",function(){h=(0,Zs.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=h.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=h.charCodeToPatternIdxToConfig,i.emptyGroups=(0,rr.merge)(i.emptyGroups,h.emptyGroups),i.hasCustom=h.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=h.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,rr.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,rr.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- +`);throw new Error(`Errors detected in definition of Lexer: +`+c)}(0,rr.forEach)(i.lexerDefinitionWarning,function(u){(0,rr.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(Zs.SUPPORT_STICKY?(i.chopInput=rr.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=rr.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=rr.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=rr.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=rr.NOOP),/full/i.test(i.config.positionTracking))i.createTokenInstance=i.createFullToken;else if(/onlyStart/i.test(i.config.positionTracking))i.createTokenInstance=i.createStartOnlyToken;else if(/onlyOffset/i.test(i.config.positionTracking))i.createTokenInstance=i.createOffsetOnlyToken;else throw Error('Invalid <positionTracking> config option: "'+i.config.positionTracking+'"');i.hasCustom?(i.addToken=i.addTokenUsingPush,i.handlePayload=i.handlePayloadWithCustom):(i.addToken=i.addTokenUsingMemberAccess,i.handlePayload=i.handlePayloadNoCustom)}),i.TRACE_INIT("Failed Optimization Warnings",function(){var u=(0,rr.reduce)(i.canModeBeOptimized,function(g,h,p){return h===!1&&g.push(p),g},[]);if(t.ensureOptimizations&&!(0,rr.isEmpty)(u))throw Error("Lexer Modes: < "+u.join(", ")+` > cannot be optimized. + Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. + Or inspect the console log for details on how to resolve these issues.`)}),i.TRACE_INIT("clearRegExpParserCache",function(){(0,rIe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,rr.toFastProperties)(i)})})}return r.prototype.tokenize=function(e,t){if(t===void 0&&(t=this.defaultMode),!(0,rr.isEmpty)(this.lexerDefinitionErrors)){var i=(0,rr.map)(this.lexerDefinitionErrors,function(o){return o.message}),n=i.join(`----------------------- +`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: +`+n)}var s=this.tokenizeInternal(e,t);return s},r.prototype.tokenizeInternal=function(e,t){var i=this,n,s,o,a,l,c,u,g,h,p,d,m,y,B,S,x,F=e,H=F.length,q=0,_=0,X=this.hasCustom?0:Math.floor(e.length/10),W=new Array(X),Z=[],A=this.trackStartLines?1:void 0,ne=this.trackStartLines?1:void 0,ue=(0,Zs.cloneEmptyGroups)(this.emptyGroups),te=this.trackStartLines,O=this.config.lineTerminatorsPattern,N=0,ce=[],he=[],xe=[],De=[];Object.freeze(De);var Re=void 0;function se(){return ce}function Ae(fr){var Ei=(0,Zs.charCodeToOptimizedIndex)(fr),rs=he[Ei];return rs===void 0?De:rs}var ye=function(fr){if(xe.length===1&&fr.tokenType.PUSH_MODE===void 0){var Ei=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(fr);Z.push({offset:fr.startOffset,line:fr.startLine!==void 0?fr.startLine:void 0,column:fr.startColumn!==void 0?fr.startColumn:void 0,length:fr.image.length,message:Ei})}else{xe.pop();var rs=(0,rr.last)(xe);ce=i.patternIdxToConfig[rs],he=i.charCodeToPatternIdxToConfig[rs],N=ce.length;var ua=i.canModeBeOptimized[rs]&&i.config.safeMode===!1;he&&ua?Re=Ae:Re=se}};function ge(fr){xe.push(fr),he=this.charCodeToPatternIdxToConfig[fr],ce=this.patternIdxToConfig[fr],N=ce.length,N=ce.length;var Ei=this.canModeBeOptimized[fr]&&this.config.safeMode===!1;he&&Ei?Re=Ae:Re=se}ge.call(this,t);for(var oe;q<H;){c=null;var Ye=F.charCodeAt(q),ie=Re(Ye),G=ie.length;for(n=0;n<G;n++){oe=ie[n];var fe=oe.pattern;u=null;var re=oe.short;if(re!==!1?Ye===re&&(c=fe):oe.isCustom===!0?(x=fe.exec(F,q,W,ue),x!==null?(c=x[0],x.payload!==void 0&&(u=x.payload)):c=null):(this.updateLastIndex(fe,q),c=this.match(fe,e,q)),c!==null){if(l=oe.longerAlt,l!==void 0){var de=l.length;for(o=0;o<de;o++){var Ze=ce[l[o]],vt=Ze.pattern;if(g=null,Ze.isCustom===!0?(x=vt.exec(F,q,W,ue),x!==null?(a=x[0],x.payload!==void 0&&(g=x.payload)):a=null):(this.updateLastIndex(vt,q),a=this.match(vt,e,q)),a&&a.length>c.length){c=a,u=g,oe=Ze;break}}}break}}if(c!==null){if(h=c.length,p=oe.group,p!==void 0&&(d=oe.tokenTypeIdx,m=this.createTokenInstance(c,q,d,oe.tokenType,A,ne,h),this.handlePayload(m,u),p===!1?_=this.addToken(W,_,m):ue[p].push(m)),e=this.chopInput(e,h),q=q+h,ne=this.computeNewColumn(ne,h),te===!0&&oe.canLineTerminator===!0){var mt=0,Tr=void 0,ti=void 0;O.lastIndex=0;do Tr=O.test(c),Tr===!0&&(ti=O.lastIndex-1,mt++);while(Tr===!0);mt!==0&&(A=A+mt,ne=h-ti,this.updateTokenEndLineColumnLocation(m,p,ti,mt,A,ne,h))}this.handleModes(oe,ye,ge,m)}else{for(var ui=q,gr=A,gi=ne,ri=!1;!ri&&q<H;)for(B=F.charCodeAt(q),e=this.chopInput(e,1),q++,s=0;s<N;s++){var Ms=ce[s],fe=Ms.pattern,re=Ms.short;if(re!==!1?F.charCodeAt(q)===re&&(ri=!0):Ms.isCustom===!0?ri=fe.exec(F,q,W,ue)!==null:(this.updateLastIndex(fe,q),ri=fe.exec(e)!==null),ri===!0)break}y=q-ui,S=this.config.errorMessageProvider.buildUnexpectedCharactersMessage(F,ui,y,gr,gi),Z.push({offset:ui,line:gr,column:gi,length:y,message:S})}}return this.hasCustom||(W.length=_),{tokens:W,groups:ue,errors:Z}},r.prototype.handleModes=function(e,t,i,n){if(e.pop===!0){var s=e.push;t(n),s!==void 0&&i.call(this,s)}else e.push!==void 0&&i.call(this,e.push)},r.prototype.chopInput=function(e,t){return e.substring(t)},r.prototype.updateLastIndex=function(e,t){e.lastIndex=t},r.prototype.updateTokenEndLineColumnLocation=function(e,t,i,n,s,o,a){var l,c;t!==void 0&&(l=i===a-1,c=l?-1:0,n===1&&l===!0||(e.endLine=s+c,e.endColumn=o-1+-c))},r.prototype.computeNewColumn=function(e,t){return e+t},r.prototype.createTokenInstance=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return null},r.prototype.createOffsetOnlyToken=function(e,t,i,n){return{image:e,startOffset:t,tokenTypeIdx:i,tokenType:n}},r.prototype.createStartOnlyToken=function(e,t,i,n,s,o){return{image:e,startOffset:t,startLine:s,startColumn:o,tokenTypeIdx:i,tokenType:n}},r.prototype.createFullToken=function(e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:t+a-1,startLine:s,endLine:s,startColumn:o,endColumn:o+a-1,tokenTypeIdx:i,tokenType:n}},r.prototype.addToken=function(e,t,i){return 666},r.prototype.addTokenUsingPush=function(e,t,i){return e.push(i),t},r.prototype.addTokenUsingMemberAccess=function(e,t,i){return e[t]=i,t++,t},r.prototype.handlePayload=function(e,t){},r.prototype.handlePayloadNoCustom=function(e,t){},r.prototype.handlePayloadWithCustom=function(e,t){t!==null&&(e.payload=t)},r.prototype.match=function(e,t,i){return null},r.prototype.matchWithTest=function(e,t,i){var n=e.test(t);return n===!0?t.substring(i,e.lastIndex):null},r.prototype.matchWithExec=function(e,t){var i=e.exec(t);return i!==null?i[0]:i},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent<this.traceInitMaxIdent&&console.log(i+"--> <"+e+">");var n=(0,rr.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&a(i+"<-- <"+e+"> time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",r.NA=/NOT_APPLICABLE/,r}();Ec.Lexer=nIe});var NA=I(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.tokenMatcher=Si.createTokenInstance=Si.EOF=Si.createToken=Si.hasTokenLabel=Si.tokenName=Si.tokenLabel=void 0;var _s=Kt(),sIe=bd(),Hv=_g();function oIe(r){return vY(r)?r.LABEL:r.name}Si.tokenLabel=oIe;function aIe(r){return r.name}Si.tokenName=aIe;function vY(r){return(0,_s.isString)(r.LABEL)&&r.LABEL!==""}Si.hasTokenLabel=vY;var AIe="parent",EY="categories",IY="label",yY="group",wY="push_mode",BY="pop_mode",bY="longer_alt",QY="line_breaks",SY="start_chars_hint";function PY(r){return lIe(r)}Si.createToken=PY;function lIe(r){var e=r.pattern,t={};if(t.name=r.name,(0,_s.isUndefined)(e)||(t.PATTERN=e),(0,_s.has)(r,AIe))throw`The parent property is no longer supported. +See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,_s.has)(r,EY)&&(t.CATEGORIES=r[EY]),(0,Hv.augmentTokenTypes)([t]),(0,_s.has)(r,IY)&&(t.LABEL=r[IY]),(0,_s.has)(r,yY)&&(t.GROUP=r[yY]),(0,_s.has)(r,BY)&&(t.POP_MODE=r[BY]),(0,_s.has)(r,wY)&&(t.PUSH_MODE=r[wY]),(0,_s.has)(r,bY)&&(t.LONGER_ALT=r[bY]),(0,_s.has)(r,QY)&&(t.LINE_BREAKS=r[QY]),(0,_s.has)(r,SY)&&(t.START_CHARS_HINT=r[SY]),t}Si.EOF=PY({name:"EOF",pattern:sIe.Lexer.NA});(0,Hv.augmentTokenTypes)([Si.EOF]);function cIe(r,e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:r.tokenTypeIdx,tokenType:r}}Si.createTokenInstance=cIe;function uIe(r,e){return(0,Hv.tokenStructuredMatcher)(r,e)}Si.tokenMatcher=uIe});var mn=I(qt=>{"use strict";var ka=qt&&qt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(qt,"__esModule",{value:!0});qt.serializeProduction=qt.serializeGrammar=qt.Terminal=qt.Alternation=qt.RepetitionWithSeparator=qt.Repetition=qt.RepetitionMandatoryWithSeparator=qt.RepetitionMandatory=qt.Option=qt.Alternative=qt.Rule=qt.NonTerminal=qt.AbstractProduction=void 0;var or=Kt(),gIe=NA(),Do=function(){function r(e){this._definition=e}return Object.defineProperty(r.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),r.prototype.accept=function(e){e.visit(this),(0,or.forEach)(this.definition,function(t){t.accept(e)})},r}();qt.AbstractProduction=Do;var xY=function(r){ka(e,r);function e(t){var i=r.call(this,[])||this;return i.idx=1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this.referencedRule!==void 0?this.referencedRule.definition:[]},set:function(t){},enumerable:!1,configurable:!0}),e.prototype.accept=function(t){t.visit(this)},e}(Do);qt.NonTerminal=xY;var kY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.orgText="",(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.Rule=kY;var DY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.ignoreAmbiguities=!1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.Alternative=DY;var RY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.Option=RY;var FY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.RepetitionMandatory=FY;var NY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.RepetitionMandatoryWithSeparator=NY;var TY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.Repetition=TY;var LY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return e}(Do);qt.RepetitionWithSeparator=LY;var OY=function(r){ka(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,or.assign)(i,(0,or.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(t){this._definition=t},enumerable:!1,configurable:!0}),e}(Do);qt.Alternation=OY;var sy=function(){function r(e){this.idx=1,(0,or.assign)(this,(0,or.pick)(e,function(t){return t!==void 0}))}return r.prototype.accept=function(e){e.visit(this)},r}();qt.Terminal=sy;function fIe(r){return(0,or.map)(r,Sd)}qt.serializeGrammar=fIe;function Sd(r){function e(s){return(0,or.map)(s,Sd)}if(r instanceof xY){var t={type:"NonTerminal",name:r.nonTerminalName,idx:r.idx};return(0,or.isString)(r.label)&&(t.label=r.label),t}else{if(r instanceof DY)return{type:"Alternative",definition:e(r.definition)};if(r instanceof RY)return{type:"Option",idx:r.idx,definition:e(r.definition)};if(r instanceof FY)return{type:"RepetitionMandatory",idx:r.idx,definition:e(r.definition)};if(r instanceof NY)return{type:"RepetitionMandatoryWithSeparator",idx:r.idx,separator:Sd(new sy({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof LY)return{type:"RepetitionWithSeparator",idx:r.idx,separator:Sd(new sy({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof TY)return{type:"Repetition",idx:r.idx,definition:e(r.definition)};if(r instanceof OY)return{type:"Alternation",idx:r.idx,definition:e(r.definition)};if(r instanceof sy){var i={type:"Terminal",name:r.terminalType.name,label:(0,gIe.tokenLabel)(r.terminalType),idx:r.idx};(0,or.isString)(r.label)&&(i.terminalLabel=r.label);var n=r.terminalType.PATTERN;return r.terminalType.PATTERN&&(i.pattern=(0,or.isRegExp)(n)?n.source:n),i}else{if(r instanceof kY)return{type:"Rule",name:r.name,orgText:r.orgText,definition:e(r.definition)};throw Error("non exhaustive match")}}}qt.serializeProduction=Sd});var ay=I(oy=>{"use strict";Object.defineProperty(oy,"__esModule",{value:!0});oy.RestWalker=void 0;var jv=Kt(),En=mn(),hIe=function(){function r(){}return r.prototype.walk=function(e,t){var i=this;t===void 0&&(t=[]),(0,jv.forEach)(e.definition,function(n,s){var o=(0,jv.drop)(e.definition,s+1);if(n instanceof En.NonTerminal)i.walkProdRef(n,o,t);else if(n instanceof En.Terminal)i.walkTerminal(n,o,t);else if(n instanceof En.Alternative)i.walkFlat(n,o,t);else if(n instanceof En.Option)i.walkOption(n,o,t);else if(n instanceof En.RepetitionMandatory)i.walkAtLeastOne(n,o,t);else if(n instanceof En.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,t);else if(n instanceof En.RepetitionWithSeparator)i.walkManySep(n,o,t);else if(n instanceof En.Repetition)i.walkMany(n,o,t);else if(n instanceof En.Alternation)i.walkOr(n,o,t);else throw Error("non exhaustive match")})},r.prototype.walkTerminal=function(e,t,i){},r.prototype.walkProdRef=function(e,t,i){},r.prototype.walkFlat=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkOption=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkAtLeastOne=function(e,t,i){var n=[new En.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkAtLeastOneSep=function(e,t,i){var n=MY(e,t,i);this.walk(e,n)},r.prototype.walkMany=function(e,t,i){var n=[new En.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkManySep=function(e,t,i){var n=MY(e,t,i);this.walk(e,n)},r.prototype.walkOr=function(e,t,i){var n=this,s=t.concat(i);(0,jv.forEach)(e.definition,function(o){var a=new En.Alternative({definition:[o]});n.walk(a,s)})},r}();oy.RestWalker=hIe;function MY(r,e,t){var i=[new En.Option({definition:[new En.Terminal({terminalType:r.separator})].concat(r.definition)})],n=i.concat(e,t);return n}});var $g=I(Ay=>{"use strict";Object.defineProperty(Ay,"__esModule",{value:!0});Ay.GAstVisitor=void 0;var Ro=mn(),pIe=function(){function r(){}return r.prototype.visit=function(e){var t=e;switch(t.constructor){case Ro.NonTerminal:return this.visitNonTerminal(t);case Ro.Alternative:return this.visitAlternative(t);case Ro.Option:return this.visitOption(t);case Ro.RepetitionMandatory:return this.visitRepetitionMandatory(t);case Ro.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(t);case Ro.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(t);case Ro.Repetition:return this.visitRepetition(t);case Ro.Alternation:return this.visitAlternation(t);case Ro.Terminal:return this.visitTerminal(t);case Ro.Rule:return this.visitRule(t);default:throw Error("non exhaustive match")}},r.prototype.visitNonTerminal=function(e){},r.prototype.visitAlternative=function(e){},r.prototype.visitOption=function(e){},r.prototype.visitRepetition=function(e){},r.prototype.visitRepetitionMandatory=function(e){},r.prototype.visitRepetitionMandatoryWithSeparator=function(e){},r.prototype.visitRepetitionWithSeparator=function(e){},r.prototype.visitAlternation=function(e){},r.prototype.visitTerminal=function(e){},r.prototype.visitRule=function(e){},r}();Ay.GAstVisitor=pIe});var Pd=I(Mi=>{"use strict";var dIe=Mi&&Mi.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Mi,"__esModule",{value:!0});Mi.collectMethods=Mi.DslMethodsCollectorVisitor=Mi.getProductionDslName=Mi.isBranchingProd=Mi.isOptionalProd=Mi.isSequenceProd=void 0;var vd=Kt(),wr=mn(),CIe=$g();function mIe(r){return r instanceof wr.Alternative||r instanceof wr.Option||r instanceof wr.Repetition||r instanceof wr.RepetitionMandatory||r instanceof wr.RepetitionMandatoryWithSeparator||r instanceof wr.RepetitionWithSeparator||r instanceof wr.Terminal||r instanceof wr.Rule}Mi.isSequenceProd=mIe;function Gv(r,e){e===void 0&&(e=[]);var t=r instanceof wr.Option||r instanceof wr.Repetition||r instanceof wr.RepetitionWithSeparator;return t?!0:r instanceof wr.Alternation?(0,vd.some)(r.definition,function(i){return Gv(i,e)}):r instanceof wr.NonTerminal&&(0,vd.contains)(e,r)?!1:r instanceof wr.AbstractProduction?(r instanceof wr.NonTerminal&&e.push(r),(0,vd.every)(r.definition,function(i){return Gv(i,e)})):!1}Mi.isOptionalProd=Gv;function EIe(r){return r instanceof wr.Alternation}Mi.isBranchingProd=EIe;function IIe(r){if(r instanceof wr.NonTerminal)return"SUBRULE";if(r instanceof wr.Option)return"OPTION";if(r instanceof wr.Alternation)return"OR";if(r instanceof wr.RepetitionMandatory)return"AT_LEAST_ONE";if(r instanceof wr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(r instanceof wr.RepetitionWithSeparator)return"MANY_SEP";if(r instanceof wr.Repetition)return"MANY";if(r instanceof wr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Mi.getProductionDslName=IIe;var KY=function(r){dIe(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.separator="-",t.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},t}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(t){var i=t.terminalType.name+this.separator+"Terminal";(0,vd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitNonTerminal=function(t){var i=t.nonTerminalName+this.separator+"Terminal";(0,vd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(CIe.GAstVisitor);Mi.DslMethodsCollectorVisitor=KY;var ly=new KY;function yIe(r){ly.reset(),r.accept(ly);var e=ly.dslMethods;return ly.reset(),e}Mi.collectMethods=yIe});var qv=I(Fo=>{"use strict";Object.defineProperty(Fo,"__esModule",{value:!0});Fo.firstForTerminal=Fo.firstForBranching=Fo.firstForSequence=Fo.first=void 0;var cy=Kt(),UY=mn(),Yv=Pd();function uy(r){if(r instanceof UY.NonTerminal)return uy(r.referencedRule);if(r instanceof UY.Terminal)return GY(r);if((0,Yv.isSequenceProd)(r))return HY(r);if((0,Yv.isBranchingProd)(r))return jY(r);throw Error("non exhaustive match")}Fo.first=uy;function HY(r){for(var e=[],t=r.definition,i=0,n=t.length>i,s,o=!0;n&&o;)s=t[i],o=(0,Yv.isOptionalProd)(s),e=e.concat(uy(s)),i=i+1,n=t.length>i;return(0,cy.uniq)(e)}Fo.firstForSequence=HY;function jY(r){var e=(0,cy.map)(r.definition,function(t){return uy(t)});return(0,cy.uniq)((0,cy.flatten)(e))}Fo.firstForBranching=jY;function GY(r){return[r.terminalType]}Fo.firstForTerminal=GY});var Jv=I(gy=>{"use strict";Object.defineProperty(gy,"__esModule",{value:!0});gy.IN=void 0;gy.IN="_~IN~_"});var zY=I(gs=>{"use strict";var wIe=gs&&gs.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(gs,"__esModule",{value:!0});gs.buildInProdFollowPrefix=gs.buildBetweenProdsFollowPrefix=gs.computeAllProdsFollows=gs.ResyncFollowsWalker=void 0;var BIe=ay(),bIe=qv(),YY=Kt(),qY=Jv(),QIe=mn(),JY=function(r){wIe(e,r);function e(t){var i=r.call(this)||this;return i.topProd=t,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(t,i,n){},e.prototype.walkProdRef=function(t,i,n){var s=WY(t.referencedRule,t.idx)+this.topProd.name,o=i.concat(n),a=new QIe.Alternative({definition:o}),l=(0,bIe.first)(a);this.follows[s]=l},e}(BIe.RestWalker);gs.ResyncFollowsWalker=JY;function SIe(r){var e={};return(0,YY.forEach)(r,function(t){var i=new JY(t).startWalking();(0,YY.assign)(e,i)}),e}gs.computeAllProdsFollows=SIe;function WY(r,e){return r.name+e+qY.IN}gs.buildBetweenProdsFollowPrefix=WY;function vIe(r){var e=r.terminalType.name;return e+r.idx+qY.IN}gs.buildInProdFollowPrefix=vIe});var xd=I(Da=>{"use strict";Object.defineProperty(Da,"__esModule",{value:!0});Da.defaultGrammarValidatorErrorProvider=Da.defaultGrammarResolverErrorProvider=Da.defaultParserErrorProvider=void 0;var ef=NA(),PIe=Kt(),$s=Kt(),Wv=mn(),VY=Pd();Da.defaultParserErrorProvider={buildMismatchTokenMessage:function(r){var e=r.expected,t=r.actual,i=r.previous,n=r.ruleName,s=(0,ef.hasTokenLabel)(e),o=s?"--> "+(0,ef.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+t.image+"' <--";return a},buildNotAllInputParsedMessage:function(r){var e=r.firstRedundant,t=r.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(r){var e=r.expectedPathsPerAlt,t=r.actual,i=r.previous,n=r.customUserDescription,s=r.ruleName,o="Expecting: ",a=(0,$s.first)(t).image,l=` +but found: '`+a+"'";if(n)return o+n+l;var c=(0,$s.reduce)(e,function(p,d){return p.concat(d)},[]),u=(0,$s.map)(c,function(p){return"["+(0,$s.map)(p,function(d){return(0,ef.tokenLabel)(d)}).join(", ")+"]"}),g=(0,$s.map)(u,function(p,d){return" "+(d+1)+". "+p}),h=`one of these possible Token sequences: +`+g.join(` +`);return o+h+l},buildEarlyExitMessage:function(r){var e=r.expectedIterationPaths,t=r.actual,i=r.customUserDescription,n=r.ruleName,s="Expecting: ",o=(0,$s.first)(t).image,a=` +but found: '`+o+"'";if(i)return s+i+a;var l=(0,$s.map)(e,function(u){return"["+(0,$s.map)(u,function(g){return(0,ef.tokenLabel)(g)}).join(",")+"]"}),c=`expecting at least one iteration which starts with one of these possible Token sequences:: + `+("<"+l.join(" ,")+">");return s+c+a}};Object.freeze(Da.defaultParserErrorProvider);Da.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(r,e){var t="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- +inside top level rule: ->`+r.name+"<-";return t}};Da.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(r,e){function t(u){return u instanceof Wv.Terminal?u.terminalType.name:u instanceof Wv.NonTerminal?u.nonTerminalName:""}var i=r.name,n=(0,$s.first)(e),s=n.idx,o=(0,VY.getProductionDslName)(n),a=t(n),l=s>0,c="->"+o+(l?s:"")+"<- "+(a?"with argument: ->"+a+"<-":"")+` + appears more than once (`+e.length+" times) in the top level rule: ->"+i+`<-. + For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES + `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,` +`),c},buildNamespaceConflictError:function(r){var e=`Namespace conflict found in grammar. +`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+r.name+`>. +`)+`To resolve this make sure each Terminal and Non-Terminal names are unique +This is easy to accomplish by using the convention that Terminal names start with an uppercase letter +and Non-Terminal names start with a lower case letter.`;return e},buildAlternationPrefixAmbiguityError:function(r){var e=(0,$s.map)(r.prefixPath,function(n){return(0,ef.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous alternatives: <"+r.ambiguityIndices.join(" ,")+`> due to common lookahead prefix +`+("in <OR"+t+"> inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`)+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX +For Further details.`;return i},buildAlternationAmbiguityError:function(r){var e=(0,$s.map)(r.prefixPath,function(n){return(0,ef.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous Alternatives Detected: <"+r.ambiguityIndices.join(" ,")+"> in <OR"+t+">"+(" inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`);return i=i+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,i},buildEmptyRepetitionError:function(r){var e=(0,VY.getProductionDslName)(r.repetition);r.repetition.idx!==0&&(e+=r.repetition.idx);var t="The repetition <"+e+"> within Rule <"+r.topLevelRule.name+`> can never consume any tokens. +This could lead to an infinite loop.`;return t},buildTokenNameError:function(r){return"deprecated"},buildEmptyAlternationError:function(r){var e="Ambiguous empty alternative: <"+(r.emptyChoiceIdx+1)+">"+(" in <OR"+r.alternation.idx+"> inside <"+r.topLevelRule.name+`> Rule. +`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(r){var e=`An Alternation cannot have more than 256 alternatives: +`+("<OR"+r.alternation.idx+"> inside <"+r.topLevelRule.name+`> Rule. + has `+(r.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(r){var e=r.topLevelRule.name,t=PIe.map(r.leftRecursionPath,function(s){return s.name}),i=e+" --> "+t.concat([e]).join(" --> "),n=`Left Recursion found in grammar. +`+("rule: <"+e+`> can be invoked from itself (directly or indirectly) +`)+(`without consuming any Tokens. The grammar path that causes this is: + `+i+` +`)+` To fix this refactor your grammar to remove the left recursion. +see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.`;return n},buildInvalidRuleNameError:function(r){return"deprecated"},buildDuplicateRuleNameError:function(r){var e;r.topLevelRule instanceof Wv.Rule?e=r.topLevelRule.name:e=r.topLevelRule;var t="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+r.grammarName+"<-";return t}}});var _Y=I(TA=>{"use strict";var xIe=TA&&TA.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(TA,"__esModule",{value:!0});TA.GastRefResolverVisitor=TA.resolveGrammar=void 0;var kIe=Yn(),XY=Kt(),DIe=$g();function RIe(r,e){var t=new ZY(r,e);return t.resolveRefs(),t.errors}TA.resolveGrammar=RIe;var ZY=function(r){xIe(e,r);function e(t,i){var n=r.call(this)||this;return n.nameToTopRule=t,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var t=this;(0,XY.forEach)((0,XY.values)(this.nameToTopRule),function(i){t.currTopLevel=i,i.accept(t)})},e.prototype.visitNonTerminal=function(t){var i=this.nameToTopRule[t.nonTerminalName];if(i)t.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,t);this.errors.push({message:n,type:kIe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:t.nonTerminalName})}},e}(DIe.GAstVisitor);TA.GastRefResolverVisitor=ZY});var Dd=I(Rr=>{"use strict";var Ic=Rr&&Rr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Rr,"__esModule",{value:!0});Rr.nextPossibleTokensAfter=Rr.possiblePathsFrom=Rr.NextTerminalAfterAtLeastOneSepWalker=Rr.NextTerminalAfterAtLeastOneWalker=Rr.NextTerminalAfterManySepWalker=Rr.NextTerminalAfterManyWalker=Rr.AbstractNextTerminalAfterProductionWalker=Rr.NextAfterTokenWalker=Rr.AbstractNextPossibleTokensWalker=void 0;var $Y=ay(),Lt=Kt(),FIe=qv(),kt=mn(),eq=function(r){Ic(e,r);function e(t,i){var n=r.call(this)||this;return n.topProd=t,n.path=i,n.possibleTokTypes=[],n.nextProductionName="",n.nextProductionOccurrence=0,n.found=!1,n.isAtEndOfPath=!1,n}return e.prototype.startWalking=function(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,Lt.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,Lt.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(t,i){i===void 0&&(i=[]),this.found||r.prototype.walk.call(this,t,i)},e.prototype.walkProdRef=function(t,i,n){if(t.referencedRule.name===this.nextProductionName&&t.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(t.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,Lt.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}($Y.RestWalker);Rr.AbstractNextPossibleTokensWalker=eq;var NIe=function(r){Ic(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.path=i,n.nextTerminalName="",n.nextTerminalOccurrence=0,n.nextTerminalName=n.path.lastTok.name,n.nextTerminalOccurrence=n.path.lastTokOccurrence,n}return e.prototype.walkTerminal=function(t,i,n){if(this.isAtEndOfPath&&t.terminalType.name===this.nextTerminalName&&t.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new kt.Alternative({definition:s});this.possibleTokTypes=(0,FIe.first)(o),this.found=!0}},e}(eq);Rr.NextAfterTokenWalker=NIe;var kd=function(r){Ic(e,r);function e(t,i){var n=r.call(this)||this;return n.topRule=t,n.occurrence=i,n.result={token:void 0,occurrence:void 0,isEndOfRule:void 0},n}return e.prototype.startWalking=function(){return this.walk(this.topRule),this.result},e}($Y.RestWalker);Rr.AbstractNextTerminalAfterProductionWalker=kd;var TIe=function(r){Ic(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkMany=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Lt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkMany.call(this,t,i,n)},e}(kd);Rr.NextTerminalAfterManyWalker=TIe;var LIe=function(r){Ic(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkManySep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Lt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkManySep.call(this,t,i,n)},e}(kd);Rr.NextTerminalAfterManySepWalker=LIe;var OIe=function(r){Ic(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Lt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOne.call(this,t,i,n)},e}(kd);Rr.NextTerminalAfterAtLeastOneWalker=OIe;var MIe=function(r){Ic(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Lt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOneSep.call(this,t,i,n)},e}(kd);Rr.NextTerminalAfterAtLeastOneSepWalker=MIe;function tq(r,e,t){t===void 0&&(t=[]),t=(0,Lt.cloneArr)(t);var i=[],n=0;function s(c){return c.concat((0,Lt.drop)(r,n+1))}function o(c){var u=tq(s(c),e,t);return i.concat(u)}for(;t.length<e&&n<r.length;){var a=r[n];if(a instanceof kt.Alternative)return o(a.definition);if(a instanceof kt.NonTerminal)return o(a.definition);if(a instanceof kt.Option)i=o(a.definition);else if(a instanceof kt.RepetitionMandatory){var l=a.definition.concat([new kt.Repetition({definition:a.definition})]);return o(l)}else if(a instanceof kt.RepetitionMandatoryWithSeparator){var l=[new kt.Alternative({definition:a.definition}),new kt.Repetition({definition:[new kt.Terminal({terminalType:a.separator})].concat(a.definition)})];return o(l)}else if(a instanceof kt.RepetitionWithSeparator){var l=a.definition.concat([new kt.Repetition({definition:[new kt.Terminal({terminalType:a.separator})].concat(a.definition)})]);i=o(l)}else if(a instanceof kt.Repetition){var l=a.definition.concat([new kt.Repetition({definition:a.definition})]);i=o(l)}else{if(a instanceof kt.Alternation)return(0,Lt.forEach)(a.definition,function(c){(0,Lt.isEmpty)(c.definition)===!1&&(i=o(c.definition))}),i;if(a instanceof kt.Terminal)t.push(a.terminalType);else throw Error("non exhaustive match")}n++}return i.push({partialPath:t,suffixDef:(0,Lt.drop)(r,n)}),i}Rr.possiblePathsFrom=tq;function KIe(r,e,t,i){var n="EXIT_NONE_TERMINAL",s=[n],o="EXIT_ALTERNATIVE",a=!1,l=e.length,c=l-i-1,u=[],g=[];for(g.push({idx:-1,def:r,ruleStack:[],occurrenceStack:[]});!(0,Lt.isEmpty)(g);){var h=g.pop();if(h===o){a&&(0,Lt.last)(g).idx<=c&&g.pop();continue}var p=h.def,d=h.idx,m=h.ruleStack,y=h.occurrenceStack;if(!(0,Lt.isEmpty)(p)){var B=p[0];if(B===n){var S={idx:d,def:(0,Lt.drop)(p),ruleStack:(0,Lt.dropRight)(m),occurrenceStack:(0,Lt.dropRight)(y)};g.push(S)}else if(B instanceof kt.Terminal)if(d<l-1){var x=d+1,F=e[x];if(t(F,B.terminalType)){var S={idx:x,def:(0,Lt.drop)(p),ruleStack:m,occurrenceStack:y};g.push(S)}}else if(d===l-1)u.push({nextTokenType:B.terminalType,nextTokenOccurrence:B.idx,ruleStack:m,occurrenceStack:y}),a=!0;else throw Error("non exhaustive match");else if(B instanceof kt.NonTerminal){var H=(0,Lt.cloneArr)(m);H.push(B.nonTerminalName);var q=(0,Lt.cloneArr)(y);q.push(B.idx);var S={idx:d,def:B.definition.concat(s,(0,Lt.drop)(p)),ruleStack:H,occurrenceStack:q};g.push(S)}else if(B instanceof kt.Option){var _={idx:d,def:(0,Lt.drop)(p),ruleStack:m,occurrenceStack:y};g.push(_),g.push(o);var X={idx:d,def:B.definition.concat((0,Lt.drop)(p)),ruleStack:m,occurrenceStack:y};g.push(X)}else if(B instanceof kt.RepetitionMandatory){var W=new kt.Repetition({definition:B.definition,idx:B.idx}),Z=B.definition.concat([W],(0,Lt.drop)(p)),S={idx:d,def:Z,ruleStack:m,occurrenceStack:y};g.push(S)}else if(B instanceof kt.RepetitionMandatoryWithSeparator){var A=new kt.Terminal({terminalType:B.separator}),W=new kt.Repetition({definition:[A].concat(B.definition),idx:B.idx}),Z=B.definition.concat([W],(0,Lt.drop)(p)),S={idx:d,def:Z,ruleStack:m,occurrenceStack:y};g.push(S)}else if(B instanceof kt.RepetitionWithSeparator){var _={idx:d,def:(0,Lt.drop)(p),ruleStack:m,occurrenceStack:y};g.push(_),g.push(o);var A=new kt.Terminal({terminalType:B.separator}),ne=new kt.Repetition({definition:[A].concat(B.definition),idx:B.idx}),Z=B.definition.concat([ne],(0,Lt.drop)(p)),X={idx:d,def:Z,ruleStack:m,occurrenceStack:y};g.push(X)}else if(B instanceof kt.Repetition){var _={idx:d,def:(0,Lt.drop)(p),ruleStack:m,occurrenceStack:y};g.push(_),g.push(o);var ne=new kt.Repetition({definition:B.definition,idx:B.idx}),Z=B.definition.concat([ne],(0,Lt.drop)(p)),X={idx:d,def:Z,ruleStack:m,occurrenceStack:y};g.push(X)}else if(B instanceof kt.Alternation)for(var ue=B.definition.length-1;ue>=0;ue--){var te=B.definition[ue],O={idx:d,def:te.definition.concat((0,Lt.drop)(p)),ruleStack:m,occurrenceStack:y};g.push(O),g.push(o)}else if(B instanceof kt.Alternative)g.push({idx:d,def:B.definition.concat((0,Lt.drop)(p)),ruleStack:m,occurrenceStack:y});else if(B instanceof kt.Rule)g.push(UIe(B,d,m,y));else throw Error("non exhaustive match")}}return u}Rr.nextPossibleTokensAfter=KIe;function UIe(r,e,t,i){var n=(0,Lt.cloneArr)(t);n.push(r.name);var s=(0,Lt.cloneArr)(i);return s.push(1),{idx:e,def:r.definition,ruleStack:n,occurrenceStack:s}}});var Rd=I(Wt=>{"use strict";var nq=Wt&&Wt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Wt,"__esModule",{value:!0});Wt.areTokenCategoriesNotUsed=Wt.isStrictPrefixOfPath=Wt.containsPath=Wt.getLookaheadPathsForOptionalProd=Wt.getLookaheadPathsForOr=Wt.lookAheadSequenceFromAlternatives=Wt.buildSingleAlternativeLookaheadFunction=Wt.buildAlternativesLookAheadFunc=Wt.buildLookaheadFuncForOptionalProd=Wt.buildLookaheadFuncForOr=Wt.getProdType=Wt.PROD_TYPE=void 0;var ir=Kt(),rq=Dd(),HIe=ay(),fy=_g(),LA=mn(),jIe=$g(),si;(function(r){r[r.OPTION=0]="OPTION",r[r.REPETITION=1]="REPETITION",r[r.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",r[r.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",r[r.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",r[r.ALTERNATION=5]="ALTERNATION"})(si=Wt.PROD_TYPE||(Wt.PROD_TYPE={}));function GIe(r){if(r instanceof LA.Option)return si.OPTION;if(r instanceof LA.Repetition)return si.REPETITION;if(r instanceof LA.RepetitionMandatory)return si.REPETITION_MANDATORY;if(r instanceof LA.RepetitionMandatoryWithSeparator)return si.REPETITION_MANDATORY_WITH_SEPARATOR;if(r instanceof LA.RepetitionWithSeparator)return si.REPETITION_WITH_SEPARATOR;if(r instanceof LA.Alternation)return si.ALTERNATION;throw Error("non exhaustive match")}Wt.getProdType=GIe;function YIe(r,e,t,i,n,s){var o=oq(r,e,t),a=Xv(o)?fy.tokenStructuredMatcherNoCategories:fy.tokenStructuredMatcher;return s(o,i,a,n)}Wt.buildLookaheadFuncForOr=YIe;function qIe(r,e,t,i,n,s){var o=aq(r,e,n,t),a=Xv(o)?fy.tokenStructuredMatcherNoCategories:fy.tokenStructuredMatcher;return s(o[0],a,i)}Wt.buildLookaheadFuncForOptionalProd=qIe;function JIe(r,e,t,i){var n=r.length,s=(0,ir.every)(r,function(l){return(0,ir.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,ir.map)(l,function(x){return x.GATE}),u=0;u<n;u++){var g=r[u],h=g.length,p=c[u];if(p!==void 0&&p.call(this)===!1)continue;e:for(var d=0;d<h;d++){for(var m=g[d],y=m.length,B=0;B<y;B++){var S=this.LA(B+1);if(t(S,m[B])===!1)continue e}return u}}};if(s&&!i){var o=(0,ir.map)(r,function(l){return(0,ir.flatten)(l)}),a=(0,ir.reduce)(o,function(l,c,u){return(0,ir.forEach)(c,function(g){(0,ir.has)(l,g.tokenTypeIdx)||(l[g.tokenTypeIdx]=u),(0,ir.forEach)(g.categoryMatches,function(h){(0,ir.has)(l,h)||(l[h]=u)})}),l},[]);return function(){var l=this.LA(1);return a[l.tokenTypeIdx]}}else return function(){for(var l=0;l<n;l++){var c=r[l],u=c.length;e:for(var g=0;g<u;g++){for(var h=c[g],p=h.length,d=0;d<p;d++){var m=this.LA(d+1);if(t(m,h[d])===!1)continue e}return l}}}}Wt.buildAlternativesLookAheadFunc=JIe;function WIe(r,e,t){var i=(0,ir.every)(r,function(c){return c.length===1}),n=r.length;if(i&&!t){var s=(0,ir.flatten)(r);if(s.length===1&&(0,ir.isEmpty)(s[0].categoryMatches)){var o=s[0],a=o.tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===a}}else{var l=(0,ir.reduce)(s,function(c,u,g){return c[u.tokenTypeIdx]=!0,(0,ir.forEach)(u.categoryMatches,function(h){c[h]=!0}),c},[]);return function(){var c=this.LA(1);return l[c.tokenTypeIdx]===!0}}}else return function(){e:for(var c=0;c<n;c++){for(var u=r[c],g=u.length,h=0;h<g;h++){var p=this.LA(h+1);if(e(p,u[h])===!1)continue e}return!0}return!1}}Wt.buildSingleAlternativeLookaheadFunction=WIe;var zIe=function(r){nq(e,r);function e(t,i,n){var s=r.call(this)||this;return s.topProd=t,s.targetOccurrence=i,s.targetProdType=n,s}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.restDef},e.prototype.checkIsTarget=function(t,i,n,s){return t.idx===this.targetOccurrence&&this.targetProdType===i?(this.restDef=n.concat(s),!0):!1},e.prototype.walkOption=function(t,i,n){this.checkIsTarget(t,si.OPTION,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkAtLeastOne=function(t,i,n){this.checkIsTarget(t,si.REPETITION_MANDATORY,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkAtLeastOneSep=function(t,i,n){this.checkIsTarget(t,si.REPETITION_MANDATORY_WITH_SEPARATOR,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkMany=function(t,i,n){this.checkIsTarget(t,si.REPETITION,i,n)||r.prototype.walkOption.call(this,t,i,n)},e.prototype.walkManySep=function(t,i,n){this.checkIsTarget(t,si.REPETITION_WITH_SEPARATOR,i,n)||r.prototype.walkOption.call(this,t,i,n)},e}(HIe.RestWalker),sq=function(r){nq(e,r);function e(t,i,n){var s=r.call(this)||this;return s.targetOccurrence=t,s.targetProdType=i,s.targetRef=n,s.result=[],s}return e.prototype.checkIsTarget=function(t,i){t.idx===this.targetOccurrence&&this.targetProdType===i&&(this.targetRef===void 0||t===this.targetRef)&&(this.result=t.definition)},e.prototype.visitOption=function(t){this.checkIsTarget(t,si.OPTION)},e.prototype.visitRepetition=function(t){this.checkIsTarget(t,si.REPETITION)},e.prototype.visitRepetitionMandatory=function(t){this.checkIsTarget(t,si.REPETITION_MANDATORY)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.checkIsTarget(t,si.REPETITION_MANDATORY_WITH_SEPARATOR)},e.prototype.visitRepetitionWithSeparator=function(t){this.checkIsTarget(t,si.REPETITION_WITH_SEPARATOR)},e.prototype.visitAlternation=function(t){this.checkIsTarget(t,si.ALTERNATION)},e}(jIe.GAstVisitor);function iq(r){for(var e=new Array(r),t=0;t<r;t++)e[t]=[];return e}function zv(r){for(var e=[""],t=0;t<r.length;t++){for(var i=r[t],n=[],s=0;s<e.length;s++){var o=e[s];n.push(o+"_"+i.tokenTypeIdx);for(var a=0;a<i.categoryMatches.length;a++){var l="_"+i.categoryMatches[a];n.push(o+l)}}e=n}return e}function VIe(r,e,t){for(var i=0;i<r.length;i++)if(i!==t)for(var n=r[i],s=0;s<e.length;s++){var o=e[s];if(n[o]===!0)return!1}return!0}function Vv(r,e){for(var t=(0,ir.map)(r,function(u){return(0,rq.possiblePathsFrom)([u],1)}),i=iq(t.length),n=(0,ir.map)(t,function(u){var g={};return(0,ir.forEach)(u,function(h){var p=zv(h.partialPath);(0,ir.forEach)(p,function(d){g[d]=!0})}),g}),s=t,o=1;o<=e;o++){var a=s;s=iq(a.length);for(var l=function(u){for(var g=a[u],h=0;h<g.length;h++){var p=g[h].partialPath,d=g[h].suffixDef,m=zv(p),y=VIe(n,m,u);if(y||(0,ir.isEmpty)(d)||p.length===e){var B=i[u];if(Aq(B,p)===!1){B.push(p);for(var S=0;S<m.length;S++){var x=m[S];n[u][x]=!0}}}else{var F=(0,rq.possiblePathsFrom)(d,o+1,p);s[u]=s[u].concat(F),(0,ir.forEach)(F,function(H){var q=zv(H.partialPath);(0,ir.forEach)(q,function(_){n[u][_]=!0})})}}},c=0;c<a.length;c++)l(c)}return i}Wt.lookAheadSequenceFromAlternatives=Vv;function oq(r,e,t,i){var n=new sq(r,si.ALTERNATION,i);return e.accept(n),Vv(n.result,t)}Wt.getLookaheadPathsForOr=oq;function aq(r,e,t,i){var n=new sq(r,t);e.accept(n);var s=n.result,o=new zIe(e,r,t),a=o.startWalking(),l=new LA.Alternative({definition:s}),c=new LA.Alternative({definition:a});return Vv([l,c],i)}Wt.getLookaheadPathsForOptionalProd=aq;function Aq(r,e){e:for(var t=0;t<r.length;t++){var i=r[t];if(i.length===e.length){for(var n=0;n<i.length;n++){var s=e[n],o=i[n],a=s===o||o.categoryMatchesMap[s.tokenTypeIdx]!==void 0;if(a===!1)continue e}return!0}}return!1}Wt.containsPath=Aq;function XIe(r,e){return r.length<e.length&&(0,ir.every)(r,function(t,i){var n=e[i];return t===n||n.categoryMatchesMap[t.tokenTypeIdx]})}Wt.isStrictPrefixOfPath=XIe;function Xv(r){return(0,ir.every)(r,function(e){return(0,ir.every)(e,function(t){return(0,ir.every)(t,function(i){return(0,ir.isEmpty)(i.categoryMatches)})})})}Wt.areTokenCategoriesNotUsed=Xv});var rP=I(Jt=>{"use strict";var Zv=Jt&&Jt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Jt,"__esModule",{value:!0});Jt.checkPrefixAlternativesAmbiguities=Jt.validateSomeNonEmptyLookaheadPath=Jt.validateTooManyAlts=Jt.RepetionCollector=Jt.validateAmbiguousAlternationAlternatives=Jt.validateEmptyOrAlternative=Jt.getFirstNoneTerminal=Jt.validateNoLeftRecursion=Jt.validateRuleIsOverridden=Jt.validateRuleDoesNotAlreadyExist=Jt.OccurrenceValidationCollector=Jt.identifyProductionForDuplicates=Jt.validateGrammar=void 0;var _t=Kt(),Br=Kt(),No=Yn(),_v=Pd(),tf=Rd(),ZIe=Dd(),eo=mn(),$v=$g();function _Ie(r,e,t,i,n){var s=_t.map(r,function(p){return $Ie(p,i)}),o=_t.map(r,function(p){return eP(p,p,i)}),a=[],l=[],c=[];(0,Br.every)(o,Br.isEmpty)&&(a=(0,Br.map)(r,function(p){return fq(p,i)}),l=(0,Br.map)(r,function(p){return hq(p,e,i)}),c=Cq(r,e,i));var u=rye(r,t,i),g=(0,Br.map)(r,function(p){return dq(p,i)}),h=(0,Br.map)(r,function(p){return gq(p,r,n,i)});return _t.flatten(s.concat(c,o,a,l,u,g,h))}Jt.validateGrammar=_Ie;function $Ie(r,e){var t=new uq;r.accept(t);var i=t.allProductions,n=_t.groupBy(i,lq),s=_t.pick(n,function(a){return a.length>1}),o=_t.map(_t.values(s),function(a){var l=_t.first(a),c=e.buildDuplicateFoundError(r,a),u=(0,_v.getProductionDslName)(l),g={message:c,type:No.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:r.name,dslName:u,occurrence:l.idx},h=cq(l);return h&&(g.parameter=h),g});return o}function lq(r){return(0,_v.getProductionDslName)(r)+"_#_"+r.idx+"_#_"+cq(r)}Jt.identifyProductionForDuplicates=lq;function cq(r){return r instanceof eo.Terminal?r.terminalType.name:r instanceof eo.NonTerminal?r.nonTerminalName:""}var uq=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}($v.GAstVisitor);Jt.OccurrenceValidationCollector=uq;function gq(r,e,t,i){var n=[],s=(0,Br.reduce)(e,function(a,l){return l.name===r.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:r,grammarName:t});n.push({message:o,type:No.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:r.name})}return n}Jt.validateRuleDoesNotAlreadyExist=gq;function eye(r,e,t){var i=[],n;return _t.contains(e,r)||(n="Invalid rule override, rule: ->"+r+"<- cannot be overridden in the grammar: ->"+t+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:No.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:r})),i}Jt.validateRuleIsOverridden=eye;function eP(r,e,t,i){i===void 0&&(i=[]);var n=[],s=Fd(e.definition);if(_t.isEmpty(s))return[];var o=r.name,a=_t.contains(s,r);a&&n.push({message:t.buildLeftRecursionError({topLevelRule:r,leftRecursionPath:i}),type:No.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=_t.difference(s,i.concat([r])),c=_t.map(l,function(u){var g=_t.cloneArr(i);return g.push(u),eP(r,u,t,g)});return n.concat(_t.flatten(c))}Jt.validateNoLeftRecursion=eP;function Fd(r){var e=[];if(_t.isEmpty(r))return e;var t=_t.first(r);if(t instanceof eo.NonTerminal)e.push(t.referencedRule);else if(t instanceof eo.Alternative||t instanceof eo.Option||t instanceof eo.RepetitionMandatory||t instanceof eo.RepetitionMandatoryWithSeparator||t instanceof eo.RepetitionWithSeparator||t instanceof eo.Repetition)e=e.concat(Fd(t.definition));else if(t instanceof eo.Alternation)e=_t.flatten(_t.map(t.definition,function(o){return Fd(o.definition)}));else if(!(t instanceof eo.Terminal))throw Error("non exhaustive match");var i=(0,_v.isOptionalProd)(t),n=r.length>1;if(i&&n){var s=_t.drop(r);return e.concat(Fd(s))}else return e}Jt.getFirstNoneTerminal=Fd;var tP=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.alternations=[],t}return e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}($v.GAstVisitor);function fq(r,e){var t=new tP;r.accept(t);var i=t.alternations,n=_t.reduce(i,function(s,o){var a=_t.dropRight(o.definition),l=_t.map(a,function(c,u){var g=(0,ZIe.nextPossibleTokensAfter)([c],[],null,1);return _t.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:r,alternation:o,emptyChoiceIdx:u}),type:No.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:r.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(_t.compact(l))},[]);return n}Jt.validateEmptyOrAlternative=fq;function hq(r,e,t){var i=new tP;r.accept(i);var n=i.alternations;n=(0,Br.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=_t.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,tf.getLookaheadPathsForOr)(l,r,c,a),g=tye(u,a,r,t),h=mq(u,a,r,t);return o.concat(g,h)},[]);return s}Jt.validateAmbiguousAlternationAlternatives=hq;var pq=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}($v.GAstVisitor);Jt.RepetionCollector=pq;function dq(r,e){var t=new tP;r.accept(t);var i=t.alternations,n=_t.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:r,alternation:o}),type:No.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:r.name,occurrence:o.idx}),s},[]);return n}Jt.validateTooManyAlts=dq;function Cq(r,e,t){var i=[];return(0,Br.forEach)(r,function(n){var s=new pq;n.accept(s);var o=s.allProductions;(0,Br.forEach)(o,function(a){var l=(0,tf.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,tf.getLookaheadPathsForOptionalProd)(u,n,l,c),h=g[0];if((0,Br.isEmpty)((0,Br.flatten)(h))){var p=t.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:p,type:No.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}Jt.validateSomeNonEmptyLookaheadPath=Cq;function tye(r,e,t,i){var n=[],s=(0,Br.reduce)(r,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,Br.forEach)(l,function(u){var g=[c];(0,Br.forEach)(r,function(h,p){c!==p&&(0,tf.containsPath)(h,u)&&e.definition[p].ignoreAmbiguities!==!0&&g.push(p)}),g.length>1&&!(0,tf.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=_t.map(s,function(a){var l=(0,Br.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:No.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:t.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function mq(r,e,t,i){var n=[],s=(0,Br.reduce)(r,function(o,a,l){var c=(0,Br.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,Br.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,Br.findAll)(s,function(h){return e.definition[h.idx].ignoreAmbiguities!==!0&&h.idx<l&&(0,tf.isStrictPrefixOfPath)(h.path,c)}),g=(0,Br.map)(u,function(h){var p=[h.idx+1,l+1],d=e.idx===0?"":e.idx,m=i.buildAlternationPrefixAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:p,prefixPath:h.path});return{message:m,type:No.ParserDefinitionErrorType.AMBIGUOUS_PREFIX_ALTS,ruleName:t.name,occurrence:d,alternatives:p}});n=n.concat(g)}}),n}Jt.checkPrefixAlternativesAmbiguities=mq;function rye(r,e,t){var i=[],n=(0,Br.map)(e,function(s){return s.name});return(0,Br.forEach)(r,function(s){var o=s.name;if((0,Br.contains)(n,o)){var a=t.buildNamespaceConflictError(s);i.push({message:a,type:No.ParserDefinitionErrorType.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:o})}}),i}});var Iq=I(rf=>{"use strict";Object.defineProperty(rf,"__esModule",{value:!0});rf.validateGrammar=rf.resolveGrammar=void 0;var iP=Kt(),iye=_Y(),nye=rP(),Eq=xd();function sye(r){r=(0,iP.defaults)(r,{errMsgProvider:Eq.defaultGrammarResolverErrorProvider});var e={};return(0,iP.forEach)(r.rules,function(t){e[t.name]=t}),(0,iye.resolveGrammar)(e,r.errMsgProvider)}rf.resolveGrammar=sye;function oye(r){return r=(0,iP.defaults)(r,{errMsgProvider:Eq.defaultGrammarValidatorErrorProvider}),(0,nye.validateGrammar)(r.rules,r.maxLookahead,r.tokenTypes,r.errMsgProvider,r.grammarName)}rf.validateGrammar=oye});var nf=I(In=>{"use strict";var Nd=In&&In.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(In,"__esModule",{value:!0});In.EarlyExitException=In.NotAllInputParsedException=In.NoViableAltException=In.MismatchedTokenException=In.isRecognitionException=void 0;var aye=Kt(),yq="MismatchedTokenException",wq="NoViableAltException",Bq="EarlyExitException",bq="NotAllInputParsedException",Qq=[yq,wq,Bq,bq];Object.freeze(Qq);function Aye(r){return(0,aye.contains)(Qq,r.name)}In.isRecognitionException=Aye;var hy=function(r){Nd(e,r);function e(t,i){var n=this.constructor,s=r.call(this,t)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),lye=function(r){Nd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=yq,s}return e}(hy);In.MismatchedTokenException=lye;var cye=function(r){Nd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=wq,s}return e}(hy);In.NoViableAltException=cye;var uye=function(r){Nd(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.name=bq,n}return e}(hy);In.NotAllInputParsedException=uye;var gye=function(r){Nd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=Bq,s}return e}(hy);In.EarlyExitException=gye});var sP=I(Ki=>{"use strict";Object.defineProperty(Ki,"__esModule",{value:!0});Ki.attemptInRepetitionRecovery=Ki.Recoverable=Ki.InRuleRecoveryException=Ki.IN_RULE_RECOVERY_EXCEPTION=Ki.EOF_FOLLOW_KEY=void 0;var py=NA(),fs=Kt(),fye=nf(),hye=Jv(),pye=Yn();Ki.EOF_FOLLOW_KEY={};Ki.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function nP(r){this.name=Ki.IN_RULE_RECOVERY_EXCEPTION,this.message=r}Ki.InRuleRecoveryException=nP;nP.prototype=Error.prototype;var dye=function(){function r(){}return r.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,fs.has)(e,"recoveryEnabled")?e.recoveryEnabled:pye.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=Sq)},r.prototype.getTokenToInsert=function(e){var t=(0,py.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t},r.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},r.prototype.tryInRepetitionRecovery=function(e,t,i,n){for(var s=this,o=this.findReSyncTokenType(),a=this.exportLexerState(),l=[],c=!1,u=this.LA(1),g=this.LA(1),h=function(){var p=s.LA(0),d=s.errorMessageProvider.buildMismatchTokenMessage({expected:n,actual:u,previous:p,ruleName:s.getCurrRuleFullName()}),m=new fye.MismatchedTokenException(d,u,s.LA(0));m.resyncedTokens=(0,fs.dropRight)(l),s.SAVE_ERROR(m)};!c;)if(this.tokenMatcher(g,n)){h();return}else if(i.call(this)){h(),e.apply(this,t);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},r.prototype.shouldInRepetitionRecoveryBeTried=function(e,t,i){return!(i===!1||e===void 0||t===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t)))},r.prototype.getFollowsForInRuleRecovery=function(e,t){var i=this.getCurrentGrammarPath(e,t),n=this.getNextPossibleTokenTypes(i);return n},r.prototype.tryInRuleRecovery=function(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new nP("sad sad panda")},r.prototype.canPerformInRuleRecovery=function(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)},r.prototype.canRecoverWithSingleTokenInsertion=function(e,t){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,fs.isEmpty)(t))return!1;var n=this.LA(1),s=(0,fs.find)(t,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},r.prototype.canRecoverWithSingleTokenDeletion=function(e){var t=this.tokenMatcher(this.LA(2),e);return t},r.prototype.isInCurrentRuleReSyncSet=function(e){var t=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(t);return(0,fs.contains)(i,e)},r.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),t=this.LA(1),i=2;;){var n=t.tokenType;if((0,fs.contains)(e,n))return n;t=this.LA(i),i++}},r.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return Ki.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(i)}},r.prototype.buildFullFollowKeyStack=function(){var e=this,t=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,fs.map)(t,function(n,s){return s===0?Ki.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(t[s-1])}})},r.prototype.flattenFollowSet=function(){var e=this,t=(0,fs.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,fs.flatten)(t)},r.prototype.getFollowSetFromFollowKey=function(e){if(e===Ki.EOF_FOLLOW_KEY)return[py.EOF];var t=e.ruleName+e.idxInCallingRule+hye.IN+e.inRule;return this.resyncFollows[t]},r.prototype.addToResyncTokens=function(e,t){return this.tokenMatcher(e,py.EOF)||t.push(e),t},r.prototype.reSyncTo=function(e){for(var t=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,t);return(0,fs.dropRight)(t)},r.prototype.attemptInRepetitionRecovery=function(e,t,i,n,s,o,a){},r.prototype.getCurrentGrammarPath=function(e,t){var i=this.getHumanReadableRuleStack(),n=(0,fs.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:t};return s},r.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,fs.map)(this.RULE_STACK,function(t){return e.shortRuleNameToFullName(t)})},r}();Ki.Recoverable=dye;function Sq(r,e,t,i,n,s,o){var a=this.getKeyForAutomaticLookahead(i,n),l=this.firstAfterRepMap[a];if(l===void 0){var c=this.getCurrRuleFullName(),u=this.getGAstProductions()[c],g=new s(u,n);l=g.startWalking(),this.firstAfterRepMap[a]=l}var h=l.token,p=l.occurrence,d=l.isEndOfRule;this.RULE_STACK.length===1&&d&&h===void 0&&(h=py.EOF,p=1),this.shouldInRepetitionRecoveryBeTried(h,p,o)&&this.tryInRepetitionRecovery(r,e,t,h)}Ki.attemptInRepetitionRecovery=Sq});var dy=I(Gt=>{"use strict";Object.defineProperty(Gt,"__esModule",{value:!0});Gt.getKeyForAutomaticLookahead=Gt.AT_LEAST_ONE_SEP_IDX=Gt.MANY_SEP_IDX=Gt.AT_LEAST_ONE_IDX=Gt.MANY_IDX=Gt.OPTION_IDX=Gt.OR_IDX=Gt.BITS_FOR_ALT_IDX=Gt.BITS_FOR_RULE_IDX=Gt.BITS_FOR_OCCURRENCE_IDX=Gt.BITS_FOR_METHOD_TYPE=void 0;Gt.BITS_FOR_METHOD_TYPE=4;Gt.BITS_FOR_OCCURRENCE_IDX=8;Gt.BITS_FOR_RULE_IDX=12;Gt.BITS_FOR_ALT_IDX=8;Gt.OR_IDX=1<<Gt.BITS_FOR_OCCURRENCE_IDX;Gt.OPTION_IDX=2<<Gt.BITS_FOR_OCCURRENCE_IDX;Gt.MANY_IDX=3<<Gt.BITS_FOR_OCCURRENCE_IDX;Gt.AT_LEAST_ONE_IDX=4<<Gt.BITS_FOR_OCCURRENCE_IDX;Gt.MANY_SEP_IDX=5<<Gt.BITS_FOR_OCCURRENCE_IDX;Gt.AT_LEAST_ONE_SEP_IDX=6<<Gt.BITS_FOR_OCCURRENCE_IDX;function Cye(r,e,t){return t|e|r}Gt.getKeyForAutomaticLookahead=Cye;var Met=32-Gt.BITS_FOR_ALT_IDX});var Pq=I(Cy=>{"use strict";Object.defineProperty(Cy,"__esModule",{value:!0});Cy.LooksAhead=void 0;var Ra=Rd(),to=Kt(),vq=Yn(),Fa=dy(),yc=Pd(),mye=function(){function r(){}return r.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,to.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:vq.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,to.has)(e,"maxLookahead")?e.maxLookahead:vq.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,to.isES2015MapSupported)()?new Map:[],(0,to.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},r.prototype.preComputeLookaheadFunctions=function(e){var t=this;(0,to.forEach)(e,function(i){t.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,yc.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,to.forEach)(s,function(g){var h=g.idx===0?"":g.idx;t.TRACE_INIT(""+(0,yc.getProductionDslName)(g)+h,function(){var p=(0,Ra.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||t.maxLookahead,g.hasPredicates,t.dynamicTokensEnabled,t.lookAheadBuilderForAlternatives),d=(0,Fa.getKeyForAutomaticLookahead)(t.fullRuleNameToShort[i.name],Fa.OR_IDX,g.idx);t.setLaFuncCache(d,p)})}),(0,to.forEach)(o,function(g){t.computeLookaheadFunc(i,g.idx,Fa.MANY_IDX,Ra.PROD_TYPE.REPETITION,g.maxLookahead,(0,yc.getProductionDslName)(g))}),(0,to.forEach)(a,function(g){t.computeLookaheadFunc(i,g.idx,Fa.OPTION_IDX,Ra.PROD_TYPE.OPTION,g.maxLookahead,(0,yc.getProductionDslName)(g))}),(0,to.forEach)(l,function(g){t.computeLookaheadFunc(i,g.idx,Fa.AT_LEAST_ONE_IDX,Ra.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,yc.getProductionDslName)(g))}),(0,to.forEach)(c,function(g){t.computeLookaheadFunc(i,g.idx,Fa.AT_LEAST_ONE_SEP_IDX,Ra.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,yc.getProductionDslName)(g))}),(0,to.forEach)(u,function(g){t.computeLookaheadFunc(i,g.idx,Fa.MANY_SEP_IDX,Ra.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,yc.getProductionDslName)(g))})})})},r.prototype.computeLookaheadFunc=function(e,t,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(t===0?"":t),function(){var l=(0,Ra.buildLookaheadFuncForOptionalProd)(t,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,Fa.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,t);a.setLaFuncCache(c,l)})},r.prototype.lookAheadBuilderForOptional=function(e,t,i){return(0,Ra.buildSingleAlternativeLookaheadFunction)(e,t,i)},r.prototype.lookAheadBuilderForAlternatives=function(e,t,i,n){return(0,Ra.buildAlternativesLookAheadFunc)(e,t,i,n)},r.prototype.getKeyForAutomaticLookahead=function(e,t){var i=this.getLastExplicitRuleShortName();return(0,Fa.getKeyForAutomaticLookahead)(i,e,t)},r.prototype.getLaFuncFromCache=function(e){},r.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},r.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},r.prototype.setLaFuncCache=function(e,t){},r.prototype.setLaFuncCacheUsingMap=function(e,t){this.lookAheadFuncsCache.set(e,t)},r.prototype.setLaFuncUsingObj=function(e,t){this.lookAheadFuncsCache[e]=t},r}();Cy.LooksAhead=mye});var xq=I(To=>{"use strict";Object.defineProperty(To,"__esModule",{value:!0});To.addNoneTerminalToCst=To.addTerminalToCst=To.setNodeLocationFull=To.setNodeLocationOnlyOffset=void 0;function Eye(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.endOffset=e.endOffset):r.endOffset<e.endOffset&&(r.endOffset=e.endOffset)}To.setNodeLocationOnlyOffset=Eye;function Iye(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.startColumn=e.startColumn,r.startLine=e.startLine,r.endOffset=e.endOffset,r.endColumn=e.endColumn,r.endLine=e.endLine):r.endOffset<e.endOffset&&(r.endOffset=e.endOffset,r.endColumn=e.endColumn,r.endLine=e.endLine)}To.setNodeLocationFull=Iye;function yye(r,e,t){r.children[t]===void 0?r.children[t]=[e]:r.children[t].push(e)}To.addTerminalToCst=yye;function wye(r,e,t){r.children[e]===void 0?r.children[e]=[t]:r.children[e].push(t)}To.addNoneTerminalToCst=wye});var oP=I(OA=>{"use strict";Object.defineProperty(OA,"__esModule",{value:!0});OA.defineNameProp=OA.functionName=OA.classNameFromInstance=void 0;var Bye=Kt();function bye(r){return Dq(r.constructor)}OA.classNameFromInstance=bye;var kq="name";function Dq(r){var e=r.name;return e||"anonymous"}OA.functionName=Dq;function Qye(r,e){var t=Object.getOwnPropertyDescriptor(r,kq);return(0,Bye.isUndefined)(t)||t.configurable?(Object.defineProperty(r,kq,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}OA.defineNameProp=Qye});var Lq=I(vi=>{"use strict";Object.defineProperty(vi,"__esModule",{value:!0});vi.validateRedundantMethods=vi.validateMissingCstMethods=vi.validateVisitor=vi.CstVisitorDefinitionError=vi.createBaseVisitorConstructorWithDefaults=vi.createBaseSemanticVisitorConstructor=vi.defaultVisit=void 0;var hs=Kt(),Td=oP();function Rq(r,e){for(var t=(0,hs.keys)(r),i=t.length,n=0;n<i;n++)for(var s=t[n],o=r[s],a=o.length,l=0;l<a;l++){var c=o[l];c.tokenTypeIdx===void 0&&this[c.name](c.children,e)}}vi.defaultVisit=Rq;function Sye(r,e){var t=function(){};(0,Td.defineNameProp)(t,r+"BaseSemantics");var i={visit:function(n,s){if((0,hs.isArray)(n)&&(n=n[0]),!(0,hs.isUndefined)(n))return this[n.name](n.children,s)},validateVisitor:function(){var n=Fq(this,e);if(!(0,hs.isEmpty)(n)){var s=(0,hs.map)(n,function(o){return o.msg});throw Error("Errors Detected in CST Visitor <"+(0,Td.functionName)(this.constructor)+`>: + `+(""+s.join(` + +`).replace(/\n/g,` + `)))}}};return t.prototype=i,t.prototype.constructor=t,t._RULE_NAMES=e,t}vi.createBaseSemanticVisitorConstructor=Sye;function vye(r,e,t){var i=function(){};(0,Td.defineNameProp)(i,r+"BaseSemanticsWithDefaults");var n=Object.create(t.prototype);return(0,hs.forEach)(e,function(s){n[s]=Rq}),i.prototype=n,i.prototype.constructor=i,i}vi.createBaseVisitorConstructorWithDefaults=vye;var aP;(function(r){r[r.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",r[r.MISSING_METHOD=1]="MISSING_METHOD"})(aP=vi.CstVisitorDefinitionError||(vi.CstVisitorDefinitionError={}));function Fq(r,e){var t=Nq(r,e),i=Tq(r,e);return t.concat(i)}vi.validateVisitor=Fq;function Nq(r,e){var t=(0,hs.map)(e,function(i){if(!(0,hs.isFunction)(r[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,Td.functionName)(r.constructor)+" CST Visitor.",type:aP.MISSING_METHOD,methodName:i}});return(0,hs.compact)(t)}vi.validateMissingCstMethods=Nq;var Pye=["constructor","visit","validateVisitor"];function Tq(r,e){var t=[];for(var i in r)(0,hs.isFunction)(r[i])&&!(0,hs.contains)(Pye,i)&&!(0,hs.contains)(e,i)&&t.push({msg:"Redundant visitor method: <"+i+"> on "+(0,Td.functionName)(r.constructor)+` CST Visitor +There is no Grammar Rule corresponding to this method's name. +`,type:aP.REDUNDANT_METHOD,methodName:i});return t}vi.validateRedundantMethods=Tq});var Mq=I(my=>{"use strict";Object.defineProperty(my,"__esModule",{value:!0});my.TreeBuilder=void 0;var sf=xq(),Xr=Kt(),Oq=Lq(),xye=Yn(),kye=function(){function r(){}return r.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,Xr.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:xye.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=Xr.NOOP,this.cstFinallyStateUpdate=Xr.NOOP,this.cstPostTerminal=Xr.NOOP,this.cstPostNonTerminal=Xr.NOOP,this.cstPostRule=Xr.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=sf.setNodeLocationFull,this.setNodeLocationFromNode=sf.setNodeLocationFull,this.cstPostRule=Xr.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=Xr.NOOP,this.setNodeLocationFromNode=Xr.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=sf.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=sf.setNodeLocationOnlyOffset,this.cstPostRule=Xr.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=Xr.NOOP,this.setNodeLocationFromNode=Xr.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=Xr.NOOP,this.setNodeLocationFromNode=Xr.NOOP,this.cstPostRule=Xr.NOOP,this.setInitialNodeLocation=Xr.NOOP;else throw Error('Invalid <nodeLocationTracking> config option: "'+e.nodeLocationTracking+'"')},r.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},r.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},r.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.setInitialNodeLocationFullRegular=function(e){var t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.cstInvocationStateUpdate=function(e,t){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},r.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},r.prototype.cstPostRuleFull=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?(i.endOffset=t.endOffset,i.endLine=t.endLine,i.endColumn=t.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},r.prototype.cstPostRuleOnlyOffset=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?i.endOffset=t.endOffset:i.startOffset=NaN},r.prototype.cstPostTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,sf.addTerminalToCst)(i,t,e),this.setNodeLocationFromToken(i.location,t)},r.prototype.cstPostNonTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,sf.addNoneTerminalToCst)(i,t,e),this.setNodeLocationFromNode(i.location,e.location)},r.prototype.getBaseCstVisitorConstructor=function(){if((0,Xr.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,Oq.createBaseSemanticVisitorConstructor)(this.className,(0,Xr.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},r.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,Xr.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,Oq.createBaseVisitorConstructorWithDefaults)(this.className,(0,Xr.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},r.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},r.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},r.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},r}();my.TreeBuilder=kye});var Uq=I(Ey=>{"use strict";Object.defineProperty(Ey,"__esModule",{value:!0});Ey.LexerAdapter=void 0;var Kq=Yn(),Dye=function(){function r(){}return r.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(r.prototype,"input",{get:function(){return this.tokVector},set:function(e){if(this.selfAnalysisDone!==!0)throw Error("Missing <performSelfAnalysis> invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length},enumerable:!1,configurable:!0}),r.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):Kq.END_OF_FILE},r.prototype.LA=function(e){var t=this.currIdx+e;return t<0||this.tokVectorLength<=t?Kq.END_OF_FILE:this.tokVector[t]},r.prototype.consumeToken=function(){this.currIdx++},r.prototype.exportLexerState=function(){return this.currIdx},r.prototype.importLexerState=function(e){this.currIdx=e},r.prototype.resetLexerState=function(){this.currIdx=-1},r.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},r.prototype.getLexerPosition=function(){return this.exportLexerState()},r}();Ey.LexerAdapter=Dye});var jq=I(Iy=>{"use strict";Object.defineProperty(Iy,"__esModule",{value:!0});Iy.RecognizerApi=void 0;var Hq=Kt(),Rye=nf(),AP=Yn(),Fye=xd(),Nye=rP(),Tye=mn(),Lye=function(){function r(){}return r.prototype.ACTION=function(e){return e.call(this)},r.prototype.consume=function(e,t,i){return this.consumeInternal(t,e,i)},r.prototype.subrule=function(e,t,i){return this.subruleInternal(t,e,i)},r.prototype.option=function(e,t){return this.optionInternal(t,e)},r.prototype.or=function(e,t){return this.orInternal(t,e)},r.prototype.many=function(e,t){return this.manyInternal(e,t)},r.prototype.atLeastOne=function(e,t){return this.atLeastOneInternal(e,t)},r.prototype.CONSUME=function(e,t){return this.consumeInternal(e,0,t)},r.prototype.CONSUME1=function(e,t){return this.consumeInternal(e,1,t)},r.prototype.CONSUME2=function(e,t){return this.consumeInternal(e,2,t)},r.prototype.CONSUME3=function(e,t){return this.consumeInternal(e,3,t)},r.prototype.CONSUME4=function(e,t){return this.consumeInternal(e,4,t)},r.prototype.CONSUME5=function(e,t){return this.consumeInternal(e,5,t)},r.prototype.CONSUME6=function(e,t){return this.consumeInternal(e,6,t)},r.prototype.CONSUME7=function(e,t){return this.consumeInternal(e,7,t)},r.prototype.CONSUME8=function(e,t){return this.consumeInternal(e,8,t)},r.prototype.CONSUME9=function(e,t){return this.consumeInternal(e,9,t)},r.prototype.SUBRULE=function(e,t){return this.subruleInternal(e,0,t)},r.prototype.SUBRULE1=function(e,t){return this.subruleInternal(e,1,t)},r.prototype.SUBRULE2=function(e,t){return this.subruleInternal(e,2,t)},r.prototype.SUBRULE3=function(e,t){return this.subruleInternal(e,3,t)},r.prototype.SUBRULE4=function(e,t){return this.subruleInternal(e,4,t)},r.prototype.SUBRULE5=function(e,t){return this.subruleInternal(e,5,t)},r.prototype.SUBRULE6=function(e,t){return this.subruleInternal(e,6,t)},r.prototype.SUBRULE7=function(e,t){return this.subruleInternal(e,7,t)},r.prototype.SUBRULE8=function(e,t){return this.subruleInternal(e,8,t)},r.prototype.SUBRULE9=function(e,t){return this.subruleInternal(e,9,t)},r.prototype.OPTION=function(e){return this.optionInternal(e,0)},r.prototype.OPTION1=function(e){return this.optionInternal(e,1)},r.prototype.OPTION2=function(e){return this.optionInternal(e,2)},r.prototype.OPTION3=function(e){return this.optionInternal(e,3)},r.prototype.OPTION4=function(e){return this.optionInternal(e,4)},r.prototype.OPTION5=function(e){return this.optionInternal(e,5)},r.prototype.OPTION6=function(e){return this.optionInternal(e,6)},r.prototype.OPTION7=function(e){return this.optionInternal(e,7)},r.prototype.OPTION8=function(e){return this.optionInternal(e,8)},r.prototype.OPTION9=function(e){return this.optionInternal(e,9)},r.prototype.OR=function(e){return this.orInternal(e,0)},r.prototype.OR1=function(e){return this.orInternal(e,1)},r.prototype.OR2=function(e){return this.orInternal(e,2)},r.prototype.OR3=function(e){return this.orInternal(e,3)},r.prototype.OR4=function(e){return this.orInternal(e,4)},r.prototype.OR5=function(e){return this.orInternal(e,5)},r.prototype.OR6=function(e){return this.orInternal(e,6)},r.prototype.OR7=function(e){return this.orInternal(e,7)},r.prototype.OR8=function(e){return this.orInternal(e,8)},r.prototype.OR9=function(e){return this.orInternal(e,9)},r.prototype.MANY=function(e){this.manyInternal(0,e)},r.prototype.MANY1=function(e){this.manyInternal(1,e)},r.prototype.MANY2=function(e){this.manyInternal(2,e)},r.prototype.MANY3=function(e){this.manyInternal(3,e)},r.prototype.MANY4=function(e){this.manyInternal(4,e)},r.prototype.MANY5=function(e){this.manyInternal(5,e)},r.prototype.MANY6=function(e){this.manyInternal(6,e)},r.prototype.MANY7=function(e){this.manyInternal(7,e)},r.prototype.MANY8=function(e){this.manyInternal(8,e)},r.prototype.MANY9=function(e){this.manyInternal(9,e)},r.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},r.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},r.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},r.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},r.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},r.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},r.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},r.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},r.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},r.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},r.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},r.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},r.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},r.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},r.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},r.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},r.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},r.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},r.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},r.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},r.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},r.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},r.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},r.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},r.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},r.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},r.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},r.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},r.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},r.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},r.prototype.RULE=function(e,t,i){if(i===void 0&&(i=AP.DEFAULT_RULE_CONFIG),(0,Hq.contains)(this.definedRulesNames,e)){var n=Fye.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:AP.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,t,i);return this[e]=o,o},r.prototype.OVERRIDE_RULE=function(e,t,i){i===void 0&&(i=AP.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,Nye.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,t,i);return this[e]=s,s},r.prototype.BACKTRACK=function(e,t){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,t),!0}catch(n){if((0,Rye.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},r.prototype.getGAstProductions=function(){return this.gastProductionsCache},r.prototype.getSerializedGastProductions=function(){return(0,Tye.serializeGrammar)((0,Hq.values)(this.gastProductionsCache))},r}();Iy.RecognizerApi=Lye});var Jq=I(wy=>{"use strict";Object.defineProperty(wy,"__esModule",{value:!0});wy.RecognizerEngine=void 0;var Pr=Kt(),qn=dy(),yy=nf(),Gq=Rd(),of=Dd(),Yq=Yn(),Oye=sP(),qq=NA(),Ld=_g(),Mye=oP(),Kye=function(){function r(){}return r.prototype.initRecognizerEngine=function(e,t){if(this.className=(0,Mye.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=Ld.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Pr.has)(t,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a <serializedGrammar> property. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 + For Further details.`);if((0,Pr.isArray)(e)){if((0,Pr.isEmpty)(e))throw Error(`A Token Vocabulary cannot be empty. + Note that the first argument for the parser constructor + is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 + For Further details.`)}if((0,Pr.isArray)(e))this.tokensMap=(0,Pr.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Pr.has)(e,"modes")&&(0,Pr.every)((0,Pr.flatten)((0,Pr.values)(e.modes)),Ld.isTokenType)){var i=(0,Pr.flatten)((0,Pr.values)(e.modes)),n=(0,Pr.uniq)(i);this.tokensMap=(0,Pr.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Pr.isObject)(e))this.tokensMap=(0,Pr.cloneObj)(e);else throw new Error("<tokensDictionary> argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=qq.EOF;var s=(0,Pr.every)((0,Pr.values)(e),function(o){return(0,Pr.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?Ld.tokenStructuredMatcherNoCategories:Ld.tokenStructuredMatcher,(0,Ld.augmentTokenTypes)((0,Pr.values)(this.tokensMap))},r.prototype.defineRule=function(e,t,i){if(this.selfAnalysisDone)throw Error("Grammar rule <"+e+`> may not be defined after the 'performSelfAnalysis' method has been called' +Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);var n=(0,Pr.has)(i,"resyncEnabled")?i.resyncEnabled:Yq.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Pr.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:Yq.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<<qn.BITS_FOR_METHOD_TYPE+qn.BITS_FOR_OCCURRENCE_IDX;this.ruleShortNameIdx++,this.shortRuleNameToFull[o]=e,this.fullRuleNameToShort[e]=o;function a(u){try{if(this.outputCst===!0){t.apply(this,u);var g=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(g),g}else return t.apply(this,u)}catch(h){return this.invokeRuleCatch(h,n,s)}finally{this.ruleFinallyStateUpdate()}}var l=function(u,g){return u===void 0&&(u=0),this.ruleInvocationStateUpdate(o,e,u),a.call(this,g)},c="ruleName";return l[c]=e,l.originalGrammarAction=t,l},r.prototype.invokeRuleCatch=function(e,t,i){var n=this.RULE_STACK.length===1,s=t&&!this.isBackTracking()&&this.recoveryEnabled;if((0,yy.isRecognitionException)(e)){var o=e;if(s){var a=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(a))if(o.resyncedTokens=this.reSyncTo(a),this.outputCst){var l=this.CST_STACK[this.CST_STACK.length-1];return l.recoveredNode=!0,l}else return i();else{if(this.outputCst){var l=this.CST_STACK[this.CST_STACK.length-1];l.recoveredNode=!0,o.partialCstResult=l}throw o}}else{if(n)return this.moveToTerminatedState(),i();throw o}}else throw e},r.prototype.optionInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(qn.OPTION_IDX,t);return this.optionInternalLogic(e,t,i)},r.prototype.optionInternalLogic=function(e,t,i){var n=this,s=this.getLaFuncFromCache(i),o,a;if(e.DEF!==void 0){if(o=e.DEF,a=e.GATE,a!==void 0){var l=s;s=function(){return a.call(n)&&l.call(n)}}}else o=e;if(s.call(this)===!0)return o.call(this)},r.prototype.atLeastOneInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(qn.AT_LEAST_ONE_IDX,e);return this.atLeastOneInternalLogic(e,t,i)},r.prototype.atLeastOneInternalLogic=function(e,t,i){var n=this,s=this.getLaFuncFromCache(i),o,a;if(t.DEF!==void 0){if(o=t.DEF,a=t.GATE,a!==void 0){var l=s;s=function(){return a.call(n)&&l.call(n)}}}else o=t;if(s.call(this)===!0)for(var c=this.doSingleRepetition(o);s.call(this)===!0&&c===!0;)c=this.doSingleRepetition(o);else throw this.raiseEarlyExitException(e,Gq.PROD_TYPE.REPETITION_MANDATORY,t.ERR_MSG);this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,t],s,qn.AT_LEAST_ONE_IDX,e,of.NextTerminalAfterAtLeastOneWalker)},r.prototype.atLeastOneSepFirstInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(qn.AT_LEAST_ONE_SEP_IDX,e);this.atLeastOneSepFirstInternalLogic(e,t,i)},r.prototype.atLeastOneSepFirstInternalLogic=function(e,t,i){var n=this,s=t.DEF,o=t.SEP,a=this.getLaFuncFromCache(i);if(a.call(this)===!0){s.call(this);for(var l=function(){return n.tokenMatcher(n.LA(1),o)};this.tokenMatcher(this.LA(1),o)===!0;)this.CONSUME(o),s.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,o,l,s,of.NextTerminalAfterAtLeastOneSepWalker],l,qn.AT_LEAST_ONE_SEP_IDX,e,of.NextTerminalAfterAtLeastOneSepWalker)}else throw this.raiseEarlyExitException(e,Gq.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,t.ERR_MSG)},r.prototype.manyInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(qn.MANY_IDX,e);return this.manyInternalLogic(e,t,i)},r.prototype.manyInternalLogic=function(e,t,i){var n=this,s=this.getLaFuncFromCache(i),o,a;if(t.DEF!==void 0){if(o=t.DEF,a=t.GATE,a!==void 0){var l=s;s=function(){return a.call(n)&&l.call(n)}}}else o=t;for(var c=!0;s.call(this)===!0&&c===!0;)c=this.doSingleRepetition(o);this.attemptInRepetitionRecovery(this.manyInternal,[e,t],s,qn.MANY_IDX,e,of.NextTerminalAfterManyWalker,c)},r.prototype.manySepFirstInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(qn.MANY_SEP_IDX,e);this.manySepFirstInternalLogic(e,t,i)},r.prototype.manySepFirstInternalLogic=function(e,t,i){var n=this,s=t.DEF,o=t.SEP,a=this.getLaFuncFromCache(i);if(a.call(this)===!0){s.call(this);for(var l=function(){return n.tokenMatcher(n.LA(1),o)};this.tokenMatcher(this.LA(1),o)===!0;)this.CONSUME(o),s.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,o,l,s,of.NextTerminalAfterManySepWalker],l,qn.MANY_SEP_IDX,e,of.NextTerminalAfterManySepWalker)}},r.prototype.repetitionSepSecondInternal=function(e,t,i,n,s){for(;i();)this.CONSUME(t),n.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,t,i,n,s],i,qn.AT_LEAST_ONE_SEP_IDX,e,s)},r.prototype.doSingleRepetition=function(e){var t=this.getLexerPosition();e.call(this);var i=this.getLexerPosition();return i>t},r.prototype.orInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(qn.OR_IDX,t),n=(0,Pr.isArray)(e)?e:e.DEF,s=this.getLaFuncFromCache(i),o=s.call(this,n);if(o!==void 0){var a=n[o];return a.ALT.call(this)}this.raiseNoAltException(t,e.ERR_MSG)},r.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){var e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new yy.NotAllInputParsedException(t,e))}},r.prototype.subruleInternal=function(e,t,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,t,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},r.prototype.subruleInternalError=function(e,t,i){throw(0,yy.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,t!==void 0&&t.LABEL!==void 0?t.LABEL:i),delete e.partialCstResult),e},r.prototype.consumeInternal=function(e,t,i){var n;try{var s=this.LA(1);this.tokenMatcher(s,e)===!0?(this.consumeToken(),n=s):this.consumeInternalError(e,s,i)}catch(o){n=this.consumeInternalRecovery(e,t,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},r.prototype.consumeInternalError=function(e,t,i){var n,s=this.LA(0);throw i!==void 0&&i.ERR_MSG?n=i.ERR_MSG:n=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new yy.MismatchedTokenException(n,t,s))},r.prototype.consumeInternalRecovery=function(e,t,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===Oye.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},r.prototype.saveRecogState=function(){var e=this.errors,t=(0,Pr.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}},r.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},r.prototype.ruleInvocationStateUpdate=function(e,t,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t,e)},r.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},r.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},r.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},r.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),qq.EOF)},r.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},r}();wy.RecognizerEngine=Kye});var zq=I(By=>{"use strict";Object.defineProperty(By,"__esModule",{value:!0});By.ErrorHandler=void 0;var lP=nf(),cP=Kt(),Wq=Rd(),Uye=Yn(),Hye=function(){function r(){}return r.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,cP.has)(e,"errorMessageProvider")?e.errorMessageProvider:Uye.DEFAULT_PARSER_CONFIG.errorMessageProvider},r.prototype.SAVE_ERROR=function(e){if((0,lP.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,cP.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(r.prototype,"errors",{get:function(){return(0,cP.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),r.prototype.raiseEarlyExitException=function(e,t,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,Wq.getLookaheadPathsForOptionalProd)(e,s,t,this.maxLookahead),a=o[0],l=[],c=1;c<=this.maxLookahead;c++)l.push(this.LA(c));var u=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:a,actual:l,previous:this.LA(0),customUserDescription:i,ruleName:n});throw this.SAVE_ERROR(new lP.EarlyExitException(u,this.LA(1),this.LA(0)))},r.prototype.raiseNoAltException=function(e,t){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,Wq.getLookaheadPathsForOr)(e,n,this.maxLookahead),o=[],a=1;a<=this.maxLookahead;a++)o.push(this.LA(a));var l=this.LA(0),c=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:s,actual:o,previous:l,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new lP.NoViableAltException(c,this.LA(1),l))},r}();By.ErrorHandler=Hye});var Zq=I(by=>{"use strict";Object.defineProperty(by,"__esModule",{value:!0});by.ContentAssist=void 0;var Vq=Dd(),Xq=Kt(),jye=function(){function r(){}return r.prototype.initContentAssist=function(){},r.prototype.computeContentAssist=function(e,t){var i=this.gastProductionsCache[e];if((0,Xq.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,Vq.nextPossibleTokensAfter)([i],t,this.tokenMatcher,this.maxLookahead)},r.prototype.getNextPossibleTokenTypes=function(e){var t=(0,Xq.first)(e.ruleStack),i=this.getGAstProductions(),n=i[t],s=new Vq.NextAfterTokenWalker(n,e).startWalking();return s},r}();by.ContentAssist=jye});var sJ=I(vy=>{"use strict";Object.defineProperty(vy,"__esModule",{value:!0});vy.GastRecorder=void 0;var yn=Kt(),Lo=mn(),Gye=bd(),tJ=_g(),rJ=NA(),Yye=Yn(),qye=dy(),Sy={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(Sy);var _q=!0,$q=Math.pow(2,qye.BITS_FOR_OCCURRENCE_IDX)-1,iJ=(0,rJ.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:Gye.Lexer.NA});(0,tJ.augmentTokenTypes)([iJ]);var nJ=(0,rJ.createTokenInstance)(iJ,`This IToken indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze(nJ);var Jye={name:`This CSTNode indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},Wye=function(){function r(){}return r.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},r.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var t=function(n){var s=n>0?n:"";e["CONSUME"+s]=function(o,a){return this.consumeInternalRecord(o,n,a)},e["SUBRULE"+s]=function(o,a){return this.subruleInternalRecord(o,n,a)},e["OPTION"+s]=function(o){return this.optionInternalRecord(o,n)},e["OR"+s]=function(o){return this.orInternalRecord(o,n)},e["MANY"+s]=function(o){this.manyInternalRecord(n,o)},e["MANY_SEP"+s]=function(o){this.manySepFirstInternalRecord(n,o)},e["AT_LEAST_ONE"+s]=function(o){this.atLeastOneInternalRecord(n,o)},e["AT_LEAST_ONE_SEP"+s]=function(o){this.atLeastOneSepFirstInternalRecord(n,o)}},i=0;i<10;i++)t(i);e.consume=function(n,s,o){return this.consumeInternalRecord(s,n,o)},e.subrule=function(n,s,o){return this.subruleInternalRecord(s,n,o)},e.option=function(n,s){return this.optionInternalRecord(s,n)},e.or=function(n,s){return this.orInternalRecord(s,n)},e.many=function(n,s){this.manyInternalRecord(n,s)},e.atLeastOne=function(n,s){this.atLeastOneInternalRecord(n,s)},e.ACTION=e.ACTION_RECORD,e.BACKTRACK=e.BACKTRACK_RECORD,e.LA=e.LA_RECORD})},r.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var t=0;t<10;t++){var i=t>0?t:"";delete e["CONSUME"+i],delete e["SUBRULE"+i],delete e["OPTION"+i],delete e["OR"+i],delete e["MANY"+i],delete e["MANY_SEP"+i],delete e["AT_LEAST_ONE"+i],delete e["AT_LEAST_ONE_SEP"+i]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})},r.prototype.ACTION_RECORD=function(e){},r.prototype.BACKTRACK_RECORD=function(e,t){return function(){return!0}},r.prototype.LA_RECORD=function(e){return Yye.END_OF_FILE},r.prototype.topLevelRuleRecord=function(e,t){try{var i=new Lo.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),t.call(this),this.recordingProdStack.pop(),i}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` + This error was thrown during the "grammar recording phase" For more info see: + https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}},r.prototype.optionInternalRecord=function(e,t){return Od.call(this,Lo.Option,e,t)},r.prototype.atLeastOneInternalRecord=function(e,t){Od.call(this,Lo.RepetitionMandatory,t,e)},r.prototype.atLeastOneSepFirstInternalRecord=function(e,t){Od.call(this,Lo.RepetitionMandatoryWithSeparator,t,e,_q)},r.prototype.manyInternalRecord=function(e,t){Od.call(this,Lo.Repetition,t,e)},r.prototype.manySepFirstInternalRecord=function(e,t){Od.call(this,Lo.RepetitionWithSeparator,t,e,_q)},r.prototype.orInternalRecord=function(e,t){return zye.call(this,e,t)},r.prototype.subruleInternalRecord=function(e,t,i){if(Qy(t),!e||(0,yn.has)(e,"ruleName")===!1){var n=new Error("<SUBRULE"+eJ(t)+"> argument is invalid"+(" expecting a Parser method reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,yn.peek)(this.recordingProdStack),o=e.ruleName,a=new Lo.NonTerminal({idx:t,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?Jye:Sy},r.prototype.consumeInternalRecord=function(e,t,i){if(Qy(t),!(0,tJ.hasShortKeyProperty)(e)){var n=new Error("<CONSUME"+eJ(t)+"> argument is invalid"+(" expecting a TokenType reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,yn.peek)(this.recordingProdStack),o=new Lo.Terminal({idx:t,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),nJ},r}();vy.GastRecorder=Wye;function Od(r,e,t,i){i===void 0&&(i=!1),Qy(t);var n=(0,yn.peek)(this.recordingProdStack),s=(0,yn.isFunction)(e)?e:e.DEF,o=new r({definition:[],idx:t});return i&&(o.separator=e.SEP),(0,yn.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),Sy}function zye(r,e){var t=this;Qy(e);var i=(0,yn.peek)(this.recordingProdStack),n=(0,yn.isArray)(r)===!1,s=n===!1?r:r.DEF,o=new Lo.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&r.IGNORE_AMBIGUITIES===!0});(0,yn.has)(r,"MAX_LOOKAHEAD")&&(o.maxLookahead=r.MAX_LOOKAHEAD);var a=(0,yn.some)(s,function(l){return(0,yn.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,yn.forEach)(s,function(l){var c=new Lo.Alternative({definition:[]});o.definition.push(c),(0,yn.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,yn.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),t.recordingProdStack.push(c),l.ALT.call(t),t.recordingProdStack.pop()}),Sy}function eJ(r){return r===0?"":""+r}function Qy(r){if(r<0||r>$q){var e=new Error("Invalid DSL Method idx value: <"+r+`> + `+("Idx value must be a none negative value smaller than "+($q+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var aJ=I(Py=>{"use strict";Object.defineProperty(Py,"__esModule",{value:!0});Py.PerformanceTracer=void 0;var oJ=Kt(),Vye=Yn(),Xye=function(){function r(){}return r.prototype.initPerformanceTracer=function(e){if((0,oJ.has)(e,"traceInitPerf")){var t=e.traceInitPerf,i=typeof t=="number";this.traceInitMaxIdent=i?t:1/0,this.traceInitPerf=i?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=Vye.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent<this.traceInitMaxIdent&&console.log(i+"--> <"+e+">");var n=(0,oJ.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&a(i+"<-- <"+e+"> time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r}();Py.PerformanceTracer=Xye});var AJ=I(xy=>{"use strict";Object.defineProperty(xy,"__esModule",{value:!0});xy.applyMixins=void 0;function Zye(r,e){e.forEach(function(t){var i=t.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(r.prototype,n,s):r.prototype[n]=t.prototype[n]}})})}xy.applyMixins=Zye});var Yn=I(hr=>{"use strict";var uJ=hr&&hr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(hr,"__esModule",{value:!0});hr.EmbeddedActionsParser=hr.CstParser=hr.Parser=hr.EMPTY_ALT=hr.ParserDefinitionErrorType=hr.DEFAULT_RULE_CONFIG=hr.DEFAULT_PARSER_CONFIG=hr.END_OF_FILE=void 0;var $i=Kt(),_ye=zY(),lJ=NA(),gJ=xd(),cJ=Iq(),$ye=sP(),ewe=Pq(),twe=Mq(),rwe=Uq(),iwe=jq(),nwe=Jq(),swe=zq(),owe=Zq(),awe=sJ(),Awe=aJ(),lwe=AJ();hr.END_OF_FILE=(0,lJ.createTokenInstance)(lJ.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(hr.END_OF_FILE);hr.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:gJ.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});hr.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var cwe;(function(r){r[r.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",r[r.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",r[r.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",r[r.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",r[r.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",r[r.LEFT_RECURSION=5]="LEFT_RECURSION",r[r.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",r[r.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",r[r.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",r[r.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",r[r.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",r[r.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",r[r.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(cwe=hr.ParserDefinitionErrorType||(hr.ParserDefinitionErrorType={}));function uwe(r){return r===void 0&&(r=void 0),function(){return r}}hr.EMPTY_ALT=uwe;var ky=function(){function r(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(t),i.initLexerAdapter(),i.initLooksAhead(t),i.initRecognizerEngine(e,t),i.initRecoverable(t),i.initTreeBuilder(t),i.initContentAssist(),i.initGastRecorder(t),i.initPerformanceTracer(t),(0,$i.has)(t,"ignoredIssues"))throw new Error(`The <ignoredIssues> IParserConfig property has been deprecated. + Please use the <IGNORE_AMBIGUITIES> flag on the relevant DSL method instead. + See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES + For further details.`);this.skipValidations=(0,$i.has)(t,"skipValidations")?t.skipValidations:hr.DEFAULT_PARSER_CONFIG.skipValidations}return r.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},r.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var t;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,$i.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,$i.forEach)(e.definedRulesNames,function(s){var o=e[s],a=o.originalGrammarAction,l=void 0;e.TRACE_INIT(s+" Rule",function(){l=e.topLevelRuleRecord(s,a)}),e.gastProductionsCache[s]=l})}finally{e.disableRecording()}});var n=[];if(e.TRACE_INIT("Grammar Resolving",function(){n=(0,cJ.resolveGrammar)({rules:(0,$i.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,$i.isEmpty)(n)&&e.skipValidations===!1){var s=(0,cJ.validateGrammar)({rules:(0,$i.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,$i.values)(e.tokensMap),errMsgProvider:gJ.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,$i.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,_ye.computeAllProdsFollows)((0,$i.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,$i.values)(e.gastProductionsCache))})),!r.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,$i.isEmpty)(e.definitionErrors))throw t=(0,$i.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: + `+t.join(` +------------------------------- +`))})},r.DEFER_DEFINITION_ERRORS_HANDLING=!1,r}();hr.Parser=ky;(0,lwe.applyMixins)(ky,[$ye.Recoverable,ewe.LooksAhead,twe.TreeBuilder,rwe.LexerAdapter,nwe.RecognizerEngine,iwe.RecognizerApi,swe.ErrorHandler,owe.ContentAssist,awe.GastRecorder,Awe.PerformanceTracer]);var gwe=function(r){uJ(e,r);function e(t,i){i===void 0&&(i=hr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,$i.cloneObj)(i);return s.outputCst=!0,n=r.call(this,t,s)||this,n}return e}(ky);hr.CstParser=gwe;var fwe=function(r){uJ(e,r);function e(t,i){i===void 0&&(i=hr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,$i.cloneObj)(i);return s.outputCst=!1,n=r.call(this,t,s)||this,n}return e}(ky);hr.EmbeddedActionsParser=fwe});var hJ=I(Dy=>{"use strict";Object.defineProperty(Dy,"__esModule",{value:!0});Dy.createSyntaxDiagramsCode=void 0;var fJ=kv();function hwe(r,e){var t=e===void 0?{}:e,i=t.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+fJ.VERSION+"/diagrams/":i,s=t.css,o=s===void 0?"https://unpkg.com/chevrotain@"+fJ.VERSION+"/diagrams/diagrams.css":s,a=` +<!-- This is a generated file --> +<!DOCTYPE html> +<meta charset="utf-8"> +<style> + body { + background-color: hsl(30, 20%, 95%) + } +</style> + +`,l=` +<link rel='stylesheet' href='`+o+`'> +`,c=` +<script src='`+n+`vendor/railroad-diagrams.js'><\/script> +<script src='`+n+`src/diagrams_builder.js'><\/script> +<script src='`+n+`src/diagrams_behavior.js'><\/script> +<script src='`+n+`src/main.js'><\/script> +`,u=` +<div id="diagrams" align="center"></div> +`,g=` +<script> + window.serializedGrammar = `+JSON.stringify(r,null," ")+`; +<\/script> +`,h=` +<script> + var diagramsDiv = document.getElementById("diagrams"); + main.drawDiagramsFromSerializedGrammar(serializedGrammar, diagramsDiv); +<\/script> +`;return a+l+c+u+g+h}Dy.createSyntaxDiagramsCode=hwe});var CJ=I(qe=>{"use strict";Object.defineProperty(qe,"__esModule",{value:!0});qe.Parser=qe.createSyntaxDiagramsCode=qe.clearCache=qe.GAstVisitor=qe.serializeProduction=qe.serializeGrammar=qe.Terminal=qe.Rule=qe.RepetitionWithSeparator=qe.RepetitionMandatoryWithSeparator=qe.RepetitionMandatory=qe.Repetition=qe.Option=qe.NonTerminal=qe.Alternative=qe.Alternation=qe.defaultLexerErrorProvider=qe.NoViableAltException=qe.NotAllInputParsedException=qe.MismatchedTokenException=qe.isRecognitionException=qe.EarlyExitException=qe.defaultParserErrorProvider=qe.tokenName=qe.tokenMatcher=qe.tokenLabel=qe.EOF=qe.createTokenInstance=qe.createToken=qe.LexerDefinitionErrorType=qe.Lexer=qe.EMPTY_ALT=qe.ParserDefinitionErrorType=qe.EmbeddedActionsParser=qe.CstParser=qe.VERSION=void 0;var pwe=kv();Object.defineProperty(qe,"VERSION",{enumerable:!0,get:function(){return pwe.VERSION}});var Ry=Yn();Object.defineProperty(qe,"CstParser",{enumerable:!0,get:function(){return Ry.CstParser}});Object.defineProperty(qe,"EmbeddedActionsParser",{enumerable:!0,get:function(){return Ry.EmbeddedActionsParser}});Object.defineProperty(qe,"ParserDefinitionErrorType",{enumerable:!0,get:function(){return Ry.ParserDefinitionErrorType}});Object.defineProperty(qe,"EMPTY_ALT",{enumerable:!0,get:function(){return Ry.EMPTY_ALT}});var pJ=bd();Object.defineProperty(qe,"Lexer",{enumerable:!0,get:function(){return pJ.Lexer}});Object.defineProperty(qe,"LexerDefinitionErrorType",{enumerable:!0,get:function(){return pJ.LexerDefinitionErrorType}});var af=NA();Object.defineProperty(qe,"createToken",{enumerable:!0,get:function(){return af.createToken}});Object.defineProperty(qe,"createTokenInstance",{enumerable:!0,get:function(){return af.createTokenInstance}});Object.defineProperty(qe,"EOF",{enumerable:!0,get:function(){return af.EOF}});Object.defineProperty(qe,"tokenLabel",{enumerable:!0,get:function(){return af.tokenLabel}});Object.defineProperty(qe,"tokenMatcher",{enumerable:!0,get:function(){return af.tokenMatcher}});Object.defineProperty(qe,"tokenName",{enumerable:!0,get:function(){return af.tokenName}});var dwe=xd();Object.defineProperty(qe,"defaultParserErrorProvider",{enumerable:!0,get:function(){return dwe.defaultParserErrorProvider}});var Md=nf();Object.defineProperty(qe,"EarlyExitException",{enumerable:!0,get:function(){return Md.EarlyExitException}});Object.defineProperty(qe,"isRecognitionException",{enumerable:!0,get:function(){return Md.isRecognitionException}});Object.defineProperty(qe,"MismatchedTokenException",{enumerable:!0,get:function(){return Md.MismatchedTokenException}});Object.defineProperty(qe,"NotAllInputParsedException",{enumerable:!0,get:function(){return Md.NotAllInputParsedException}});Object.defineProperty(qe,"NoViableAltException",{enumerable:!0,get:function(){return Md.NoViableAltException}});var Cwe=Uv();Object.defineProperty(qe,"defaultLexerErrorProvider",{enumerable:!0,get:function(){return Cwe.defaultLexerErrorProvider}});var Oo=mn();Object.defineProperty(qe,"Alternation",{enumerable:!0,get:function(){return Oo.Alternation}});Object.defineProperty(qe,"Alternative",{enumerable:!0,get:function(){return Oo.Alternative}});Object.defineProperty(qe,"NonTerminal",{enumerable:!0,get:function(){return Oo.NonTerminal}});Object.defineProperty(qe,"Option",{enumerable:!0,get:function(){return Oo.Option}});Object.defineProperty(qe,"Repetition",{enumerable:!0,get:function(){return Oo.Repetition}});Object.defineProperty(qe,"RepetitionMandatory",{enumerable:!0,get:function(){return Oo.RepetitionMandatory}});Object.defineProperty(qe,"RepetitionMandatoryWithSeparator",{enumerable:!0,get:function(){return Oo.RepetitionMandatoryWithSeparator}});Object.defineProperty(qe,"RepetitionWithSeparator",{enumerable:!0,get:function(){return Oo.RepetitionWithSeparator}});Object.defineProperty(qe,"Rule",{enumerable:!0,get:function(){return Oo.Rule}});Object.defineProperty(qe,"Terminal",{enumerable:!0,get:function(){return Oo.Terminal}});var dJ=mn();Object.defineProperty(qe,"serializeGrammar",{enumerable:!0,get:function(){return dJ.serializeGrammar}});Object.defineProperty(qe,"serializeProduction",{enumerable:!0,get:function(){return dJ.serializeProduction}});var mwe=$g();Object.defineProperty(qe,"GAstVisitor",{enumerable:!0,get:function(){return mwe.GAstVisitor}});function Ewe(){console.warn(`The clearCache function was 'soft' removed from the Chevrotain API. + It performs no action other than printing this message. + Please avoid using it as it will be completely removed in the future`)}qe.clearCache=Ewe;var Iwe=hJ();Object.defineProperty(qe,"createSyntaxDiagramsCode",{enumerable:!0,get:function(){return Iwe.createSyntaxDiagramsCode}});var ywe=function(){function r(){throw new Error(`The Parser class has been deprecated, use CstParser or EmbeddedActionsParser instead. +See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_7-0-0`)}return r}();qe.Parser=ywe});var IJ=I((rtt,EJ)=>{var Fy=CJ(),Na=Fy.createToken,mJ=Fy.tokenMatcher,uP=Fy.Lexer,wwe=Fy.EmbeddedActionsParser;EJ.exports=r=>{let e=Na({name:"LogicalOperator",pattern:uP.NA}),t=Na({name:"Or",pattern:/\|/,categories:e}),i=Na({name:"Xor",pattern:/\^/,categories:e}),n=Na({name:"And",pattern:/&/,categories:e}),s=Na({name:"Not",pattern:/!/}),o=Na({name:"LParen",pattern:/\(/}),a=Na({name:"RParen",pattern:/\)/}),l=Na({name:"Query",pattern:r}),u=[Na({name:"WhiteSpace",pattern:/\s+/,group:uP.SKIPPED}),t,i,n,o,a,s,e,l],g=new uP(u);class h extends wwe{constructor(d){super(u),this.RULE("expression",()=>this.SUBRULE(this.logicalExpression)),this.RULE("logicalExpression",()=>{let y=this.SUBRULE(this.atomicExpression);return this.MANY(()=>{let B=y,S=this.CONSUME(e),x=this.SUBRULE2(this.atomicExpression);mJ(S,t)?y=F=>B(F)||x(F):mJ(S,i)?y=F=>!!(B(F)^x(F)):y=F=>B(F)&&x(F)}),y}),this.RULE("atomicExpression",()=>this.OR([{ALT:()=>this.SUBRULE(this.parenthesisExpression)},{ALT:()=>{let{image:m}=this.CONSUME(l);return y=>y(m)}},{ALT:()=>{this.CONSUME(s);let m=this.SUBRULE(this.atomicExpression);return y=>!m(y)}}])),this.RULE("parenthesisExpression",()=>{let m;return this.CONSUME(o),m=this.SUBRULE(this.expression),this.CONSUME(a),m}),this.performSelfAnalysis()}}return{TinylogicLexer:g,TinylogicParser:h}}});var yJ=I(Ny=>{var Bwe=IJ();Ny.makeParser=(r=/[a-z]+/)=>{let{TinylogicLexer:e,TinylogicParser:t}=Bwe(r),i=new t;return(n,s)=>{let o=e.tokenize(n);return i.input=o.tokens,i.expression()(s)}};Ny.parse=Ny.makeParser()});var BJ=I((ntt,wJ)=>{"use strict";wJ.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var gP=I((stt,QJ)=>{var Kd=BJ(),bJ={};for(let r of Object.keys(Kd))bJ[Kd[r]]=r;var st={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};QJ.exports=st;for(let r of Object.keys(st)){if(!("channels"in st[r]))throw new Error("missing channels property: "+r);if(!("labels"in st[r]))throw new Error("missing channel labels property: "+r);if(st[r].labels.length!==st[r].channels)throw new Error("channel and label counts mismatch: "+r);let{channels:e,labels:t}=st[r];delete st[r].channels,delete st[r].labels,Object.defineProperty(st[r],"channels",{value:e}),Object.defineProperty(st[r],"labels",{value:t})}st.rgb.hsl=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.min(e,t,i),s=Math.max(e,t,i),o=s-n,a,l;s===n?a=0:e===s?a=(t-i)/o:t===s?a=2+(i-e)/o:i===s&&(a=4+(e-t)/o),a=Math.min(a*60,360),a<0&&(a+=360);let c=(n+s)/2;return s===n?l=0:c<=.5?l=o/(s+n):l=o/(2-s-n),[a,l*100,c*100]};st.rgb.hsv=function(r){let e,t,i,n,s,o=r[0]/255,a=r[1]/255,l=r[2]/255,c=Math.max(o,a,l),u=c-Math.min(o,a,l),g=function(h){return(c-h)/6/u+1/2};return u===0?(n=0,s=0):(s=u/c,e=g(o),t=g(a),i=g(l),o===c?n=i-t:a===c?n=1/3+e-i:l===c&&(n=2/3+t-e),n<0?n+=1:n>1&&(n-=1)),[n*360,s*100,c*100]};st.rgb.hwb=function(r){let e=r[0],t=r[1],i=r[2],n=st.rgb.hsl(r)[0],s=1/255*Math.min(e,Math.min(t,i));return i=1-1/255*Math.max(e,Math.max(t,i)),[n,s*100,i*100]};st.rgb.cmyk=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.min(1-e,1-t,1-i),s=(1-e-n)/(1-n)||0,o=(1-t-n)/(1-n)||0,a=(1-i-n)/(1-n)||0;return[s*100,o*100,a*100,n*100]};function bwe(r,e){return(r[0]-e[0])**2+(r[1]-e[1])**2+(r[2]-e[2])**2}st.rgb.keyword=function(r){let e=bJ[r];if(e)return e;let t=1/0,i;for(let n of Object.keys(Kd)){let s=Kd[n],o=bwe(r,s);o<t&&(t=o,i=n)}return i};st.keyword.rgb=function(r){return Kd[r]};st.rgb.xyz=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255;e=e>.04045?((e+.055)/1.055)**2.4:e/12.92,t=t>.04045?((t+.055)/1.055)**2.4:t/12.92,i=i>.04045?((i+.055)/1.055)**2.4:i/12.92;let n=e*.4124+t*.3576+i*.1805,s=e*.2126+t*.7152+i*.0722,o=e*.0193+t*.1192+i*.9505;return[n*100,s*100,o*100]};st.rgb.lab=function(r){let e=st.rgb.xyz(r),t=e[0],i=e[1],n=e[2];t/=95.047,i/=100,n/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,i=i>.008856?i**(1/3):7.787*i+16/116,n=n>.008856?n**(1/3):7.787*n+16/116;let s=116*i-16,o=500*(t-i),a=200*(i-n);return[s,o,a]};st.hsl.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100,n,s,o;if(t===0)return o=i*255,[o,o,o];i<.5?n=i*(1+t):n=i+t-i*t;let a=2*i-n,l=[0,0,0];for(let c=0;c<3;c++)s=e+1/3*-(c-1),s<0&&s++,s>1&&s--,6*s<1?o=a+(n-a)*6*s:2*s<1?o=n:3*s<2?o=a+(n-a)*(2/3-s)*6:o=a,l[c]=o*255;return l};st.hsl.hsv=function(r){let e=r[0],t=r[1]/100,i=r[2]/100,n=t,s=Math.max(i,.01);i*=2,t*=i<=1?i:2-i,n*=s<=1?s:2-s;let o=(i+t)/2,a=i===0?2*n/(s+n):2*t/(i+t);return[e,a*100,o*100]};st.hsv.rgb=function(r){let e=r[0]/60,t=r[1]/100,i=r[2]/100,n=Math.floor(e)%6,s=e-Math.floor(e),o=255*i*(1-t),a=255*i*(1-t*s),l=255*i*(1-t*(1-s));switch(i*=255,n){case 0:return[i,l,o];case 1:return[a,i,o];case 2:return[o,i,l];case 3:return[o,a,i];case 4:return[l,o,i];case 5:return[i,o,a]}};st.hsv.hsl=function(r){let e=r[0],t=r[1]/100,i=r[2]/100,n=Math.max(i,.01),s,o;o=(2-t)*i;let a=(2-t)*n;return s=t*n,s/=a<=1?a:2-a,s=s||0,o/=2,[e,s*100,o*100]};st.hwb.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100,n=t+i,s;n>1&&(t/=n,i/=n);let o=Math.floor(6*e),a=1-i;s=6*e-o,(o&1)!==0&&(s=1-s);let l=t+s*(a-t),c,u,g;switch(o){default:case 6:case 0:c=a,u=l,g=t;break;case 1:c=l,u=a,g=t;break;case 2:c=t,u=a,g=l;break;case 3:c=t,u=l,g=a;break;case 4:c=l,u=t,g=a;break;case 5:c=a,u=t,g=l;break}return[c*255,u*255,g*255]};st.cmyk.rgb=function(r){let e=r[0]/100,t=r[1]/100,i=r[2]/100,n=r[3]/100,s=1-Math.min(1,e*(1-n)+n),o=1-Math.min(1,t*(1-n)+n),a=1-Math.min(1,i*(1-n)+n);return[s*255,o*255,a*255]};st.xyz.rgb=function(r){let e=r[0]/100,t=r[1]/100,i=r[2]/100,n,s,o;return n=e*3.2406+t*-1.5372+i*-.4986,s=e*-.9689+t*1.8758+i*.0415,o=e*.0557+t*-.204+i*1.057,n=n>.0031308?1.055*n**(1/2.4)-.055:n*12.92,s=s>.0031308?1.055*s**(1/2.4)-.055:s*12.92,o=o>.0031308?1.055*o**(1/2.4)-.055:o*12.92,n=Math.min(Math.max(0,n),1),s=Math.min(Math.max(0,s),1),o=Math.min(Math.max(0,o),1),[n*255,s*255,o*255]};st.xyz.lab=function(r){let e=r[0],t=r[1],i=r[2];e/=95.047,t/=100,i/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,t=t>.008856?t**(1/3):7.787*t+16/116,i=i>.008856?i**(1/3):7.787*i+16/116;let n=116*t-16,s=500*(e-t),o=200*(t-i);return[n,s,o]};st.lab.xyz=function(r){let e=r[0],t=r[1],i=r[2],n,s,o;s=(e+16)/116,n=t/500+s,o=s-i/200;let a=s**3,l=n**3,c=o**3;return s=a>.008856?a:(s-16/116)/7.787,n=l>.008856?l:(n-16/116)/7.787,o=c>.008856?c:(o-16/116)/7.787,n*=95.047,s*=100,o*=108.883,[n,s,o]};st.lab.lch=function(r){let e=r[0],t=r[1],i=r[2],n;n=Math.atan2(i,t)*360/2/Math.PI,n<0&&(n+=360);let o=Math.sqrt(t*t+i*i);return[e,o,n]};st.lch.lab=function(r){let e=r[0],t=r[1],n=r[2]/360*2*Math.PI,s=t*Math.cos(n),o=t*Math.sin(n);return[e,s,o]};st.rgb.ansi16=function(r,e=null){let[t,i,n]=r,s=e===null?st.rgb.hsv(r)[2]:e;if(s=Math.round(s/50),s===0)return 30;let o=30+(Math.round(n/255)<<2|Math.round(i/255)<<1|Math.round(t/255));return s===2&&(o+=60),o};st.hsv.ansi16=function(r){return st.rgb.ansi16(st.hsv.rgb(r),r[2])};st.rgb.ansi256=function(r){let e=r[0],t=r[1],i=r[2];return e===t&&t===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(i/255*5)};st.ansi16.rgb=function(r){let e=r%10;if(e===0||e===7)return r>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let t=(~~(r>50)+1)*.5,i=(e&1)*t*255,n=(e>>1&1)*t*255,s=(e>>2&1)*t*255;return[i,n,s]};st.ansi256.rgb=function(r){if(r>=232){let s=(r-232)*10+8;return[s,s,s]}r-=16;let e,t=Math.floor(r/36)/5*255,i=Math.floor((e=r%36)/6)/5*255,n=e%6/5*255;return[t,i,n]};st.rgb.hex=function(r){let t=(((Math.round(r[0])&255)<<16)+((Math.round(r[1])&255)<<8)+(Math.round(r[2])&255)).toString(16).toUpperCase();return"000000".substring(t.length)+t};st.hex.rgb=function(r){let e=r.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let t=e[0];e[0].length===3&&(t=t.split("").map(a=>a+a).join(""));let i=parseInt(t,16),n=i>>16&255,s=i>>8&255,o=i&255;return[n,s,o]};st.rgb.hcg=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.max(Math.max(e,t),i),s=Math.min(Math.min(e,t),i),o=n-s,a,l;return o<1?a=s/(1-o):a=0,o<=0?l=0:n===e?l=(t-i)/o%6:n===t?l=2+(i-e)/o:l=4+(e-t)/o,l/=6,l%=1,[l*360,o*100,a*100]};st.hsl.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=t<.5?2*e*t:2*e*(1-t),n=0;return i<1&&(n=(t-.5*i)/(1-i)),[r[0],i*100,n*100]};st.hsv.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=e*t,n=0;return i<1&&(n=(t-i)/(1-i)),[r[0],i*100,n*100]};st.hcg.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100;if(t===0)return[i*255,i*255,i*255];let n=[0,0,0],s=e%1*6,o=s%1,a=1-o,l=0;switch(Math.floor(s)){case 0:n[0]=1,n[1]=o,n[2]=0;break;case 1:n[0]=a,n[1]=1,n[2]=0;break;case 2:n[0]=0,n[1]=1,n[2]=o;break;case 3:n[0]=0,n[1]=a,n[2]=1;break;case 4:n[0]=o,n[1]=0,n[2]=1;break;default:n[0]=1,n[1]=0,n[2]=a}return l=(1-t)*i,[(t*n[0]+l)*255,(t*n[1]+l)*255,(t*n[2]+l)*255]};st.hcg.hsv=function(r){let e=r[1]/100,t=r[2]/100,i=e+t*(1-e),n=0;return i>0&&(n=e/i),[r[0],n*100,i*100]};st.hcg.hsl=function(r){let e=r[1]/100,i=r[2]/100*(1-e)+.5*e,n=0;return i>0&&i<.5?n=e/(2*i):i>=.5&&i<1&&(n=e/(2*(1-i))),[r[0],n*100,i*100]};st.hcg.hwb=function(r){let e=r[1]/100,t=r[2]/100,i=e+t*(1-e);return[r[0],(i-e)*100,(1-i)*100]};st.hwb.hcg=function(r){let e=r[1]/100,i=1-r[2]/100,n=i-e,s=0;return n<1&&(s=(i-n)/(1-n)),[r[0],n*100,s*100]};st.apple.rgb=function(r){return[r[0]/65535*255,r[1]/65535*255,r[2]/65535*255]};st.rgb.apple=function(r){return[r[0]/255*65535,r[1]/255*65535,r[2]/255*65535]};st.gray.rgb=function(r){return[r[0]/100*255,r[0]/100*255,r[0]/100*255]};st.gray.hsl=function(r){return[0,0,r[0]]};st.gray.hsv=st.gray.hsl;st.gray.hwb=function(r){return[0,100,r[0]]};st.gray.cmyk=function(r){return[0,0,0,r[0]]};st.gray.lab=function(r){return[r[0],0,0]};st.gray.hex=function(r){let e=Math.round(r[0]/100*255)&255,i=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(i.length)+i};st.rgb.gray=function(r){return[(r[0]+r[1]+r[2])/3/255*100]}});var vJ=I((ott,SJ)=>{var Ty=gP();function Qwe(){let r={},e=Object.keys(Ty);for(let t=e.length,i=0;i<t;i++)r[e[i]]={distance:-1,parent:null};return r}function Swe(r){let e=Qwe(),t=[r];for(e[r].distance=0;t.length;){let i=t.pop(),n=Object.keys(Ty[i]);for(let s=n.length,o=0;o<s;o++){let a=n[o],l=e[a];l.distance===-1&&(l.distance=e[i].distance+1,l.parent=i,t.unshift(a))}}return e}function vwe(r,e){return function(t){return e(r(t))}}function Pwe(r,e){let t=[e[r].parent,r],i=Ty[e[r].parent][r],n=e[r].parent;for(;e[n].parent;)t.unshift(e[n].parent),i=vwe(Ty[e[n].parent][n],i),n=e[n].parent;return i.conversion=t,i}SJ.exports=function(r){let e=Swe(r),t={},i=Object.keys(e);for(let n=i.length,s=0;s<n;s++){let o=i[s];e[o].parent!==null&&(t[o]=Pwe(o,e))}return t}});var xJ=I((att,PJ)=>{var fP=gP(),xwe=vJ(),Af={},kwe=Object.keys(fP);function Dwe(r){let e=function(...t){let i=t[0];return i==null?i:(i.length>1&&(t=i),r(t))};return"conversion"in r&&(e.conversion=r.conversion),e}function Rwe(r){let e=function(...t){let i=t[0];if(i==null)return i;i.length>1&&(t=i);let n=r(t);if(typeof n=="object")for(let s=n.length,o=0;o<s;o++)n[o]=Math.round(n[o]);return n};return"conversion"in r&&(e.conversion=r.conversion),e}kwe.forEach(r=>{Af[r]={},Object.defineProperty(Af[r],"channels",{value:fP[r].channels}),Object.defineProperty(Af[r],"labels",{value:fP[r].labels});let e=xwe(r);Object.keys(e).forEach(i=>{let n=e[i];Af[r][i]=Rwe(n),Af[r][i].raw=Dwe(n)})});PJ.exports=Af});var TJ=I((Att,NJ)=>{"use strict";var kJ=(r,e)=>(...t)=>`\x1B[${r(...t)+e}m`,DJ=(r,e)=>(...t)=>{let i=r(...t);return`\x1B[${38+e};5;${i}m`},RJ=(r,e)=>(...t)=>{let i=r(...t);return`\x1B[${38+e};2;${i[0]};${i[1]};${i[2]}m`},Ly=r=>r,FJ=(r,e,t)=>[r,e,t],lf=(r,e,t)=>{Object.defineProperty(r,e,{get:()=>{let i=t();return Object.defineProperty(r,e,{value:i,enumerable:!0,configurable:!0}),i},enumerable:!0,configurable:!0})},hP,cf=(r,e,t,i)=>{hP===void 0&&(hP=xJ());let n=i?10:0,s={};for(let[o,a]of Object.entries(hP)){let l=o==="ansi16"?"ansi":o;o===e?s[l]=r(t,n):typeof a=="object"&&(s[l]=r(a[e],n))}return s};function Fwe(){let r=new Map,e={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};e.color.gray=e.color.blackBright,e.bgColor.bgGray=e.bgColor.bgBlackBright,e.color.grey=e.color.blackBright,e.bgColor.bgGrey=e.bgColor.bgBlackBright;for(let[t,i]of Object.entries(e)){for(let[n,s]of Object.entries(i))e[n]={open:`\x1B[${s[0]}m`,close:`\x1B[${s[1]}m`},i[n]=e[n],r.set(s[0],s[1]);Object.defineProperty(e,t,{value:i,enumerable:!1})}return Object.defineProperty(e,"codes",{value:r,enumerable:!1}),e.color.close="\x1B[39m",e.bgColor.close="\x1B[49m",lf(e.color,"ansi",()=>cf(kJ,"ansi16",Ly,!1)),lf(e.color,"ansi256",()=>cf(DJ,"ansi256",Ly,!1)),lf(e.color,"ansi16m",()=>cf(RJ,"rgb",FJ,!1)),lf(e.bgColor,"ansi",()=>cf(kJ,"ansi16",Ly,!0)),lf(e.bgColor,"ansi256",()=>cf(DJ,"ansi256",Ly,!0)),lf(e.bgColor,"ansi16m",()=>cf(RJ,"rgb",FJ,!0)),e}Object.defineProperty(NJ,"exports",{enumerable:!0,get:Fwe})});var OJ=I((ltt,LJ)=>{"use strict";LJ.exports=(r,e=process.argv)=>{let t=r.startsWith("-")?"":r.length===1?"-":"--",i=e.indexOf(t+r),n=e.indexOf("--");return i!==-1&&(n===-1||i<n)}});var UJ=I((ctt,KJ)=>{"use strict";var Nwe=J("os"),MJ=J("tty"),ps=OJ(),{env:oi}=process,MA;ps("no-color")||ps("no-colors")||ps("color=false")||ps("color=never")?MA=0:(ps("color")||ps("colors")||ps("color=true")||ps("color=always"))&&(MA=1);"FORCE_COLOR"in oi&&(oi.FORCE_COLOR==="true"?MA=1:oi.FORCE_COLOR==="false"?MA=0:MA=oi.FORCE_COLOR.length===0?1:Math.min(parseInt(oi.FORCE_COLOR,10),3));function pP(r){return r===0?!1:{level:r,hasBasic:!0,has256:r>=2,has16m:r>=3}}function dP(r,e){if(MA===0)return 0;if(ps("color=16m")||ps("color=full")||ps("color=truecolor"))return 3;if(ps("color=256"))return 2;if(r&&!e&&MA===void 0)return 0;let t=MA||0;if(oi.TERM==="dumb")return t;if(process.platform==="win32"){let i=Nwe.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in oi)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(i=>i in oi)||oi.CI_NAME==="codeship"?1:t;if("TEAMCITY_VERSION"in oi)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(oi.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in oi)return 1;if(oi.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in oi){let i=parseInt((oi.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(oi.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(oi.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(oi.TERM)||"COLORTERM"in oi?1:t}function Twe(r){let e=dP(r,r&&r.isTTY);return pP(e)}KJ.exports={supportsColor:Twe,stdout:pP(dP(!0,MJ.isatty(1))),stderr:pP(dP(!0,MJ.isatty(2)))}});var jJ=I((utt,HJ)=>{"use strict";var Lwe=(r,e,t)=>{let i=r.indexOf(e);if(i===-1)return r;let n=e.length,s=0,o="";do o+=r.substr(s,i-s)+e+t,s=i+n,i=r.indexOf(e,s);while(i!==-1);return o+=r.substr(s),o},Owe=(r,e,t,i)=>{let n=0,s="";do{let o=r[i-1]==="\r";s+=r.substr(n,(o?i-1:i)-n)+e+(o?`\r +`:` +`)+t,n=i+1,i=r.indexOf(` +`,n)}while(i!==-1);return s+=r.substr(n),s};HJ.exports={stringReplaceAll:Lwe,stringEncaseCRLFWithFirstIndex:Owe}});var WJ=I((gtt,JJ)=>{"use strict";var Mwe=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,GJ=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,Kwe=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,Uwe=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,Hwe=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e","\x1B"],["a","\x07"]]);function qJ(r){let e=r[0]==="u",t=r[1]==="{";return e&&!t&&r.length===5||r[0]==="x"&&r.length===3?String.fromCharCode(parseInt(r.slice(1),16)):e&&t?String.fromCodePoint(parseInt(r.slice(2,-1),16)):Hwe.get(r)||r}function jwe(r,e){let t=[],i=e.trim().split(/\s*,\s*/g),n;for(let s of i){let o=Number(s);if(!Number.isNaN(o))t.push(o);else if(n=s.match(Kwe))t.push(n[2].replace(Uwe,(a,l,c)=>l?qJ(l):c));else throw new Error(`Invalid Chalk template style argument: ${s} (in style '${r}')`)}return t}function Gwe(r){GJ.lastIndex=0;let e=[],t;for(;(t=GJ.exec(r))!==null;){let i=t[1];if(t[2]){let n=jwe(i,t[2]);e.push([i].concat(n))}else e.push([i])}return e}function YJ(r,e){let t={};for(let n of e)for(let s of n.styles)t[s[0]]=n.inverse?null:s.slice(1);let i=r;for(let[n,s]of Object.entries(t))if(!!Array.isArray(s)){if(!(n in i))throw new Error(`Unknown Chalk style: ${n}`);i=s.length>0?i[n](...s):i[n]}return i}JJ.exports=(r,e)=>{let t=[],i=[],n=[];if(e.replace(Mwe,(s,o,a,l,c,u)=>{if(o)n.push(qJ(o));else if(l){let g=n.join("");n=[],i.push(t.length===0?g:YJ(r,t)(g)),t.push({inverse:a,styles:Gwe(l)})}else if(c){if(t.length===0)throw new Error("Found extraneous } in Chalk template literal");i.push(YJ(r,t)(n.join(""))),n=[],t.pop()}else n.push(u)}),i.push(n.join("")),t.length>0){let s=`Chalk template literal is missing ${t.length} closing bracket${t.length===1?"":"s"} (\`}\`)`;throw new Error(s)}return i.join("")}});var wP=I((ftt,ZJ)=>{"use strict";var Ud=TJ(),{stdout:mP,stderr:EP}=UJ(),{stringReplaceAll:Ywe,stringEncaseCRLFWithFirstIndex:qwe}=jJ(),zJ=["ansi","ansi","ansi256","ansi16m"],uf=Object.create(null),Jwe=(r,e={})=>{if(e.level>3||e.level<0)throw new Error("The `level` option should be an integer from 0 to 3");let t=mP?mP.level:0;r.level=e.level===void 0?t:e.level},IP=class{constructor(e){return VJ(e)}},VJ=r=>{let e={};return Jwe(e,r),e.template=(...t)=>Vwe(e.template,...t),Object.setPrototypeOf(e,Oy.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=IP,e.template};function Oy(r){return VJ(r)}for(let[r,e]of Object.entries(Ud))uf[r]={get(){let t=My(this,yP(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,r,{value:t}),t}};uf.visible={get(){let r=My(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:r}),r}};var XJ=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let r of XJ)uf[r]={get(){let{level:e}=this;return function(...t){let i=yP(Ud.color[zJ[e]][r](...t),Ud.color.close,this._styler);return My(this,i,this._isEmpty)}}};for(let r of XJ){let e="bg"+r[0].toUpperCase()+r.slice(1);uf[e]={get(){let{level:t}=this;return function(...i){let n=yP(Ud.bgColor[zJ[t]][r](...i),Ud.bgColor.close,this._styler);return My(this,n,this._isEmpty)}}}}var Wwe=Object.defineProperties(()=>{},{...uf,level:{enumerable:!0,get(){return this._generator.level},set(r){this._generator.level=r}}}),yP=(r,e,t)=>{let i,n;return t===void 0?(i=r,n=e):(i=t.openAll+r,n=e+t.closeAll),{open:r,close:e,openAll:i,closeAll:n,parent:t}},My=(r,e,t)=>{let i=(...n)=>zwe(i,n.length===1?""+n[0]:n.join(" "));return i.__proto__=Wwe,i._generator=r,i._styler=e,i._isEmpty=t,i},zwe=(r,e)=>{if(r.level<=0||!e)return r._isEmpty?"":e;let t=r._styler;if(t===void 0)return e;let{openAll:i,closeAll:n}=t;if(e.indexOf("\x1B")!==-1)for(;t!==void 0;)e=Ywe(e,t.close,t.open),t=t.parent;let s=e.indexOf(` +`);return s!==-1&&(e=qwe(e,n,i,s)),i+e+n},CP,Vwe=(r,...e)=>{let[t]=e;if(!Array.isArray(t))return e.join(" ");let i=e.slice(1),n=[t.raw[0]];for(let s=1;s<t.length;s++)n.push(String(i[s-1]).replace(/[{}\\]/g,"\\$&"),String(t.raw[s]));return CP===void 0&&(CP=WJ()),CP(r,n.join(""))};Object.defineProperties(Oy.prototype,uf);var Hd=Oy();Hd.supportsColor=mP;Hd.stderr=Oy({level:EP?EP.level:0});Hd.stderr.supportsColor=EP;Hd.Level={None:0,Basic:1,Ansi256:2,TrueColor:3,0:"None",1:"Basic",2:"Ansi256",3:"TrueColor"};ZJ.exports=Hd});var Ky=I(ds=>{"use strict";ds.isInteger=r=>typeof r=="number"?Number.isInteger(r):typeof r=="string"&&r.trim()!==""?Number.isInteger(Number(r)):!1;ds.find=(r,e)=>r.nodes.find(t=>t.type===e);ds.exceedsLimit=(r,e,t=1,i)=>i===!1||!ds.isInteger(r)||!ds.isInteger(e)?!1:(Number(e)-Number(r))/Number(t)>=i;ds.escapeNode=(r,e=0,t)=>{let i=r.nodes[e];!i||(t&&i.type===t||i.type==="open"||i.type==="close")&&i.escaped!==!0&&(i.value="\\"+i.value,i.escaped=!0)};ds.encloseBrace=r=>r.type!=="brace"?!1:r.commas>>0+r.ranges>>0===0?(r.invalid=!0,!0):!1;ds.isInvalidBrace=r=>r.type!=="brace"?!1:r.invalid===!0||r.dollar?!0:r.commas>>0+r.ranges>>0===0||r.open!==!0||r.close!==!0?(r.invalid=!0,!0):!1;ds.isOpenOrClose=r=>r.type==="open"||r.type==="close"?!0:r.open===!0||r.close===!0;ds.reduce=r=>r.reduce((e,t)=>(t.type==="text"&&e.push(t.value),t.type==="range"&&(t.type="text"),e),[]);ds.flatten=(...r)=>{let e=[],t=i=>{for(let n=0;n<i.length;n++){let s=i[n];Array.isArray(s)?t(s,e):s!==void 0&&e.push(s)}return e};return t(r),e}});var Uy=I((ptt,$J)=>{"use strict";var _J=Ky();$J.exports=(r,e={})=>{let t=(i,n={})=>{let s=e.escapeInvalid&&_J.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a="";if(i.value)return(s||o)&&_J.isOpenOrClose(i)?"\\"+i.value:i.value;if(i.value)return i.value;if(i.nodes)for(let l of i.nodes)a+=t(l);return a};return t(r)}});var t3=I((dtt,e3)=>{"use strict";e3.exports=function(r){return typeof r=="number"?r-r===0:typeof r=="string"&&r.trim()!==""?Number.isFinite?Number.isFinite(+r):isFinite(+r):!1}});var c3=I((Ctt,l3)=>{"use strict";var r3=t3(),wc=(r,e,t)=>{if(r3(r)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(e===void 0||r===e)return String(r);if(r3(e)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let i={relaxZeros:!0,...t};typeof i.strictZeros=="boolean"&&(i.relaxZeros=i.strictZeros===!1);let n=String(i.relaxZeros),s=String(i.shorthand),o=String(i.capture),a=String(i.wrap),l=r+":"+e+"="+n+s+o+a;if(wc.cache.hasOwnProperty(l))return wc.cache[l].result;let c=Math.min(r,e),u=Math.max(r,e);if(Math.abs(c-u)===1){let m=r+"|"+e;return i.capture?`(${m})`:i.wrap===!1?m:`(?:${m})`}let g=A3(r)||A3(e),h={min:r,max:e,a:c,b:u},p=[],d=[];if(g&&(h.isPadded=g,h.maxLen=String(h.max).length),c<0){let m=u<0?Math.abs(u):1;d=i3(m,Math.abs(c),h,i),c=h.a=0}return u>=0&&(p=i3(c,u,h,i)),h.negatives=d,h.positives=p,h.result=Xwe(d,p,i),i.capture===!0?h.result=`(${h.result})`:i.wrap!==!1&&p.length+d.length>1&&(h.result=`(?:${h.result})`),wc.cache[l]=h,h.result};function Xwe(r,e,t){let i=BP(r,e,"-",!1,t)||[],n=BP(e,r,"",!1,t)||[],s=BP(r,e,"-?",!0,t)||[];return i.concat(s).concat(n).join("|")}function Zwe(r,e){let t=1,i=1,n=s3(r,t),s=new Set([e]);for(;r<=n&&n<=e;)s.add(n),t+=1,n=s3(r,t);for(n=o3(e+1,i)-1;r<n&&n<=e;)s.add(n),i+=1,n=o3(e+1,i)-1;return s=[...s],s.sort(eBe),s}function _we(r,e,t){if(r===e)return{pattern:r,count:[],digits:0};let i=$we(r,e),n=i.length,s="",o=0;for(let a=0;a<n;a++){let[l,c]=i[a];l===c?s+=l:l!=="0"||c!=="9"?s+=tBe(l,c,t):o++}return o&&(s+=t.shorthand===!0?"\\d":"[0-9]"),{pattern:s,count:[o],digits:n}}function i3(r,e,t,i){let n=Zwe(r,e),s=[],o=r,a;for(let l=0;l<n.length;l++){let c=n[l],u=_we(String(o),String(c),i),g="";if(!t.isPadded&&a&&a.pattern===u.pattern){a.count.length>1&&a.count.pop(),a.count.push(u.count[0]),a.string=a.pattern+a3(a.count),o=c+1;continue}t.isPadded&&(g=rBe(c,t,i)),u.string=g+u.pattern+a3(u.count),s.push(u),o=c+1,a=u}return s}function BP(r,e,t,i,n){let s=[];for(let o of r){let{string:a}=o;!i&&!n3(e,"string",a)&&s.push(t+a),i&&n3(e,"string",a)&&s.push(t+a)}return s}function $we(r,e){let t=[];for(let i=0;i<r.length;i++)t.push([r[i],e[i]]);return t}function eBe(r,e){return r>e?1:e>r?-1:0}function n3(r,e,t){return r.some(i=>i[e]===t)}function s3(r,e){return Number(String(r).slice(0,-e)+"9".repeat(e))}function o3(r,e){return r-r%Math.pow(10,e)}function a3(r){let[e=0,t=""]=r;return t||e>1?`{${e+(t?","+t:"")}}`:""}function tBe(r,e,t){return`[${r}${e-r===1?"":"-"}${e}]`}function A3(r){return/^-?(0+)\d/.test(r)}function rBe(r,e,t){if(!e.isPadded)return r;let i=Math.abs(e.maxLen-String(r).length),n=t.relaxZeros!==!1;switch(i){case 0:return"";case 1:return n?"0?":"0";case 2:return n?"0{0,2}":"00";default:return n?`0{0,${i}}`:`0{${i}}`}}wc.cache={};wc.clearCache=()=>wc.cache={};l3.exports=wc});var SP=I((mtt,m3)=>{"use strict";var iBe=J("util"),f3=c3(),u3=r=>r!==null&&typeof r=="object"&&!Array.isArray(r),nBe=r=>e=>r===!0?Number(e):String(e),bP=r=>typeof r=="number"||typeof r=="string"&&r!=="",jd=r=>Number.isInteger(+r),QP=r=>{let e=`${r}`,t=-1;if(e[0]==="-"&&(e=e.slice(1)),e==="0")return!1;for(;e[++t]==="0";);return t>0},sBe=(r,e,t)=>typeof r=="string"||typeof e=="string"?!0:t.stringify===!0,oBe=(r,e,t)=>{if(e>0){let i=r[0]==="-"?"-":"";i&&(r=r.slice(1)),r=i+r.padStart(i?e-1:e,"0")}return t===!1?String(r):r},g3=(r,e)=>{let t=r[0]==="-"?"-":"";for(t&&(r=r.slice(1),e--);r.length<e;)r="0"+r;return t?"-"+r:r},aBe=(r,e)=>{r.negatives.sort((o,a)=>o<a?-1:o>a?1:0),r.positives.sort((o,a)=>o<a?-1:o>a?1:0);let t=e.capture?"":"?:",i="",n="",s;return r.positives.length&&(i=r.positives.join("|")),r.negatives.length&&(n=`-(${t}${r.negatives.join("|")})`),i&&n?s=`${i}|${n}`:s=i||n,e.wrap?`(${t}${s})`:s},h3=(r,e,t,i)=>{if(t)return f3(r,e,{wrap:!1,...i});let n=String.fromCharCode(r);if(r===e)return n;let s=String.fromCharCode(e);return`[${n}-${s}]`},p3=(r,e,t)=>{if(Array.isArray(r)){let i=t.wrap===!0,n=t.capture?"":"?:";return i?`(${n}${r.join("|")})`:r.join("|")}return f3(r,e,t)},d3=(...r)=>new RangeError("Invalid range arguments: "+iBe.inspect(...r)),C3=(r,e,t)=>{if(t.strictRanges===!0)throw d3([r,e]);return[]},ABe=(r,e)=>{if(e.strictRanges===!0)throw new TypeError(`Expected step "${r}" to be a number`);return[]},lBe=(r,e,t=1,i={})=>{let n=Number(r),s=Number(e);if(!Number.isInteger(n)||!Number.isInteger(s)){if(i.strictRanges===!0)throw d3([r,e]);return[]}n===0&&(n=0),s===0&&(s=0);let o=n>s,a=String(r),l=String(e),c=String(t);t=Math.max(Math.abs(t),1);let u=QP(a)||QP(l)||QP(c),g=u?Math.max(a.length,l.length,c.length):0,h=u===!1&&sBe(r,e,i)===!1,p=i.transform||nBe(h);if(i.toRegex&&t===1)return h3(g3(r,g),g3(e,g),!0,i);let d={negatives:[],positives:[]},m=S=>d[S<0?"negatives":"positives"].push(Math.abs(S)),y=[],B=0;for(;o?n>=s:n<=s;)i.toRegex===!0&&t>1?m(n):y.push(oBe(p(n,B),g,h)),n=o?n-t:n+t,B++;return i.toRegex===!0?t>1?aBe(d,i):p3(y,null,{wrap:!1,...i}):y},cBe=(r,e,t=1,i={})=>{if(!jd(r)&&r.length>1||!jd(e)&&e.length>1)return C3(r,e,i);let n=i.transform||(h=>String.fromCharCode(h)),s=`${r}`.charCodeAt(0),o=`${e}`.charCodeAt(0),a=s>o,l=Math.min(s,o),c=Math.max(s,o);if(i.toRegex&&t===1)return h3(l,c,!1,i);let u=[],g=0;for(;a?s>=o:s<=o;)u.push(n(s,g)),s=a?s-t:s+t,g++;return i.toRegex===!0?p3(u,null,{wrap:!1,options:i}):u},Hy=(r,e,t,i={})=>{if(e==null&&bP(r))return[r];if(!bP(r)||!bP(e))return C3(r,e,i);if(typeof t=="function")return Hy(r,e,1,{transform:t});if(u3(t))return Hy(r,e,0,t);let n={...i};return n.capture===!0&&(n.wrap=!0),t=t||n.step||1,jd(t)?jd(r)&&jd(e)?lBe(r,e,t,n):cBe(r,e,Math.max(Math.abs(t),1),n):t!=null&&!u3(t)?ABe(t,n):Hy(r,e,1,t)};m3.exports=Hy});var y3=I((Ett,I3)=>{"use strict";var uBe=SP(),E3=Ky(),gBe=(r,e={})=>{let t=(i,n={})=>{let s=E3.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a=s===!0||o===!0,l=e.escapeInvalid===!0?"\\":"",c="";if(i.isOpen===!0||i.isClose===!0)return l+i.value;if(i.type==="open")return a?l+i.value:"(";if(i.type==="close")return a?l+i.value:")";if(i.type==="comma")return i.prev.type==="comma"?"":a?i.value:"|";if(i.value)return i.value;if(i.nodes&&i.ranges>0){let u=E3.reduce(i.nodes),g=uBe(...u,{...e,wrap:!1,toRegex:!0});if(g.length!==0)return u.length>1&&g.length>1?`(${g})`:g}if(i.nodes)for(let u of i.nodes)c+=t(u,i);return c};return t(r)};I3.exports=gBe});var b3=I((Itt,B3)=>{"use strict";var fBe=SP(),w3=Uy(),gf=Ky(),Bc=(r="",e="",t=!1)=>{let i=[];if(r=[].concat(r),e=[].concat(e),!e.length)return r;if(!r.length)return t?gf.flatten(e).map(n=>`{${n}}`):e;for(let n of r)if(Array.isArray(n))for(let s of n)i.push(Bc(s,e,t));else for(let s of e)t===!0&&typeof s=="string"&&(s=`{${s}}`),i.push(Array.isArray(s)?Bc(n,s,t):n+s);return gf.flatten(i)},hBe=(r,e={})=>{let t=e.rangeLimit===void 0?1e3:e.rangeLimit,i=(n,s={})=>{n.queue=[];let o=s,a=s.queue;for(;o.type!=="brace"&&o.type!=="root"&&o.parent;)o=o.parent,a=o.queue;if(n.invalid||n.dollar){a.push(Bc(a.pop(),w3(n,e)));return}if(n.type==="brace"&&n.invalid!==!0&&n.nodes.length===2){a.push(Bc(a.pop(),["{}"]));return}if(n.nodes&&n.ranges>0){let g=gf.reduce(n.nodes);if(gf.exceedsLimit(...g,e.step,t))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let h=fBe(...g,e);h.length===0&&(h=w3(n,e)),a.push(Bc(a.pop(),h)),n.nodes=[];return}let l=gf.encloseBrace(n),c=n.queue,u=n;for(;u.type!=="brace"&&u.type!=="root"&&u.parent;)u=u.parent,c=u.queue;for(let g=0;g<n.nodes.length;g++){let h=n.nodes[g];if(h.type==="comma"&&n.type==="brace"){g===1&&c.push(""),c.push("");continue}if(h.type==="close"){a.push(Bc(a.pop(),c,l));continue}if(h.value&&h.type!=="open"){c.push(Bc(c.pop(),h.value));continue}h.nodes&&i(h,n)}return c};return gf.flatten(i(r))};B3.exports=hBe});var S3=I((ytt,Q3)=>{"use strict";Q3.exports={MAX_LENGTH:1024*64,CHAR_0:"0",CHAR_9:"9",CHAR_UPPERCASE_A:"A",CHAR_LOWERCASE_A:"a",CHAR_UPPERCASE_Z:"Z",CHAR_LOWERCASE_Z:"z",CHAR_LEFT_PARENTHESES:"(",CHAR_RIGHT_PARENTHESES:")",CHAR_ASTERISK:"*",CHAR_AMPERSAND:"&",CHAR_AT:"@",CHAR_BACKSLASH:"\\",CHAR_BACKTICK:"`",CHAR_CARRIAGE_RETURN:"\r",CHAR_CIRCUMFLEX_ACCENT:"^",CHAR_COLON:":",CHAR_COMMA:",",CHAR_DOLLAR:"$",CHAR_DOT:".",CHAR_DOUBLE_QUOTE:'"',CHAR_EQUAL:"=",CHAR_EXCLAMATION_MARK:"!",CHAR_FORM_FEED:"\f",CHAR_FORWARD_SLASH:"/",CHAR_HASH:"#",CHAR_HYPHEN_MINUS:"-",CHAR_LEFT_ANGLE_BRACKET:"<",CHAR_LEFT_CURLY_BRACE:"{",CHAR_LEFT_SQUARE_BRACKET:"[",CHAR_LINE_FEED:` +`,CHAR_NO_BREAK_SPACE:"\xA0",CHAR_PERCENT:"%",CHAR_PLUS:"+",CHAR_QUESTION_MARK:"?",CHAR_RIGHT_ANGLE_BRACKET:">",CHAR_RIGHT_CURLY_BRACE:"}",CHAR_RIGHT_SQUARE_BRACKET:"]",CHAR_SEMICOLON:";",CHAR_SINGLE_QUOTE:"'",CHAR_SPACE:" ",CHAR_TAB:" ",CHAR_UNDERSCORE:"_",CHAR_VERTICAL_LINE:"|",CHAR_ZERO_WIDTH_NOBREAK_SPACE:"\uFEFF"}});var D3=I((wtt,k3)=>{"use strict";var pBe=Uy(),{MAX_LENGTH:v3,CHAR_BACKSLASH:vP,CHAR_BACKTICK:dBe,CHAR_COMMA:CBe,CHAR_DOT:mBe,CHAR_LEFT_PARENTHESES:EBe,CHAR_RIGHT_PARENTHESES:IBe,CHAR_LEFT_CURLY_BRACE:yBe,CHAR_RIGHT_CURLY_BRACE:wBe,CHAR_LEFT_SQUARE_BRACKET:P3,CHAR_RIGHT_SQUARE_BRACKET:x3,CHAR_DOUBLE_QUOTE:BBe,CHAR_SINGLE_QUOTE:bBe,CHAR_NO_BREAK_SPACE:QBe,CHAR_ZERO_WIDTH_NOBREAK_SPACE:SBe}=S3(),vBe=(r,e={})=>{if(typeof r!="string")throw new TypeError("Expected a string");let t=e||{},i=typeof t.maxLength=="number"?Math.min(v3,t.maxLength):v3;if(r.length>i)throw new SyntaxError(`Input length (${r.length}), exceeds max characters (${i})`);let n={type:"root",input:r,nodes:[]},s=[n],o=n,a=n,l=0,c=r.length,u=0,g=0,h,p={},d=()=>r[u++],m=y=>{if(y.type==="text"&&a.type==="dot"&&(a.type="text"),a&&a.type==="text"&&y.type==="text"){a.value+=y.value;return}return o.nodes.push(y),y.parent=o,y.prev=a,a=y,y};for(m({type:"bos"});u<c;)if(o=s[s.length-1],h=d(),!(h===SBe||h===QBe)){if(h===vP){m({type:"text",value:(e.keepEscaping?h:"")+d()});continue}if(h===x3){m({type:"text",value:"\\"+h});continue}if(h===P3){l++;let y=!0,B;for(;u<c&&(B=d());){if(h+=B,B===P3){l++;continue}if(B===vP){h+=d();continue}if(B===x3&&(l--,l===0))break}m({type:"text",value:h});continue}if(h===EBe){o=m({type:"paren",nodes:[]}),s.push(o),m({type:"text",value:h});continue}if(h===IBe){if(o.type!=="paren"){m({type:"text",value:h});continue}o=s.pop(),m({type:"text",value:h}),o=s[s.length-1];continue}if(h===BBe||h===bBe||h===dBe){let y=h,B;for(e.keepQuotes!==!0&&(h="");u<c&&(B=d());){if(B===vP){h+=B+d();continue}if(B===y){e.keepQuotes===!0&&(h+=B);break}h+=B}m({type:"text",value:h});continue}if(h===yBe){g++;let B={type:"brace",open:!0,close:!1,dollar:a.value&&a.value.slice(-1)==="$"||o.dollar===!0,depth:g,commas:0,ranges:0,nodes:[]};o=m(B),s.push(o),m({type:"open",value:h});continue}if(h===wBe){if(o.type!=="brace"){m({type:"text",value:h});continue}let y="close";o=s.pop(),o.close=!0,m({type:y,value:h}),g--,o=s[s.length-1];continue}if(h===CBe&&g>0){if(o.ranges>0){o.ranges=0;let y=o.nodes.shift();o.nodes=[y,{type:"text",value:pBe(o)}]}m({type:"comma",value:h}),o.commas++;continue}if(h===mBe&&g>0&&o.commas===0){let y=o.nodes;if(g===0||y.length===0){m({type:"text",value:h});continue}if(a.type==="dot"){if(o.range=[],a.value+=h,a.type="range",o.nodes.length!==3&&o.nodes.length!==5){o.invalid=!0,o.ranges=0,a.type="text";continue}o.ranges++,o.args=[];continue}if(a.type==="range"){y.pop();let B=y[y.length-1];B.value+=a.value+h,a=B,o.ranges--;continue}m({type:"dot",value:h});continue}m({type:"text",value:h})}do if(o=s.pop(),o.type!=="root"){o.nodes.forEach(S=>{S.nodes||(S.type==="open"&&(S.isOpen=!0),S.type==="close"&&(S.isClose=!0),S.nodes||(S.type="text"),S.invalid=!0)});let y=s[s.length-1],B=y.nodes.indexOf(o);y.nodes.splice(B,1,...o.nodes)}while(s.length>0);return m({type:"eos"}),n};k3.exports=vBe});var N3=I((Btt,F3)=>{"use strict";var R3=Uy(),PBe=y3(),xBe=b3(),kBe=D3(),Jn=(r,e={})=>{let t=[];if(Array.isArray(r))for(let i of r){let n=Jn.create(i,e);Array.isArray(n)?t.push(...n):t.push(n)}else t=[].concat(Jn.create(r,e));return e&&e.expand===!0&&e.nodupes===!0&&(t=[...new Set(t)]),t};Jn.parse=(r,e={})=>kBe(r,e);Jn.stringify=(r,e={})=>R3(typeof r=="string"?Jn.parse(r,e):r,e);Jn.compile=(r,e={})=>(typeof r=="string"&&(r=Jn.parse(r,e)),PBe(r,e));Jn.expand=(r,e={})=>{typeof r=="string"&&(r=Jn.parse(r,e));let t=xBe(r,e);return e.noempty===!0&&(t=t.filter(Boolean)),e.nodupes===!0&&(t=[...new Set(t)]),t};Jn.create=(r,e={})=>r===""||r.length<3?[r]:e.expand!==!0?Jn.compile(r,e):Jn.expand(r,e);F3.exports=Jn});var Gd=I((btt,K3)=>{"use strict";var DBe=J("path"),Mo="\\\\/",T3=`[^${Mo}]`,Ta="\\.",RBe="\\+",FBe="\\?",jy="\\/",NBe="(?=.)",L3="[^/]",PP=`(?:${jy}|$)`,O3=`(?:^|${jy})`,xP=`${Ta}{1,2}${PP}`,TBe=`(?!${Ta})`,LBe=`(?!${O3}${xP})`,OBe=`(?!${Ta}{0,1}${PP})`,MBe=`(?!${xP})`,KBe=`[^.${jy}]`,UBe=`${L3}*?`,M3={DOT_LITERAL:Ta,PLUS_LITERAL:RBe,QMARK_LITERAL:FBe,SLASH_LITERAL:jy,ONE_CHAR:NBe,QMARK:L3,END_ANCHOR:PP,DOTS_SLASH:xP,NO_DOT:TBe,NO_DOTS:LBe,NO_DOT_SLASH:OBe,NO_DOTS_SLASH:MBe,QMARK_NO_DOT:KBe,STAR:UBe,START_ANCHOR:O3},HBe={...M3,SLASH_LITERAL:`[${Mo}]`,QMARK:T3,STAR:`${T3}*?`,DOTS_SLASH:`${Ta}{1,2}(?:[${Mo}]|$)`,NO_DOT:`(?!${Ta})`,NO_DOTS:`(?!(?:^|[${Mo}])${Ta}{1,2}(?:[${Mo}]|$))`,NO_DOT_SLASH:`(?!${Ta}{0,1}(?:[${Mo}]|$))`,NO_DOTS_SLASH:`(?!${Ta}{1,2}(?:[${Mo}]|$))`,QMARK_NO_DOT:`[^.${Mo}]`,START_ANCHOR:`(?:^|[${Mo}])`,END_ANCHOR:`(?:[${Mo}]|$)`},jBe={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};K3.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:jBe,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:DBe.sep,extglobChars(r){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${r.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(r){return r===!0?HBe:M3}}});var Yd=I(wn=>{"use strict";var GBe=J("path"),YBe=process.platform==="win32",{REGEX_BACKSLASH:qBe,REGEX_REMOVE_BACKSLASH:JBe,REGEX_SPECIAL_CHARS:WBe,REGEX_SPECIAL_CHARS_GLOBAL:zBe}=Gd();wn.isObject=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);wn.hasRegexChars=r=>WBe.test(r);wn.isRegexChar=r=>r.length===1&&wn.hasRegexChars(r);wn.escapeRegex=r=>r.replace(zBe,"\\$1");wn.toPosixSlashes=r=>r.replace(qBe,"/");wn.removeBackslashes=r=>r.replace(JBe,e=>e==="\\"?"":e);wn.supportsLookbehinds=()=>{let r=process.version.slice(1).split(".").map(Number);return r.length===3&&r[0]>=9||r[0]===8&&r[1]>=10};wn.isWindows=r=>r&&typeof r.windows=="boolean"?r.windows:YBe===!0||GBe.sep==="\\";wn.escapeLast=(r,e,t)=>{let i=r.lastIndexOf(e,t);return i===-1?r:r[i-1]==="\\"?wn.escapeLast(r,e,i-1):`${r.slice(0,i)}\\${r.slice(i)}`};wn.removePrefix=(r,e={})=>{let t=r;return t.startsWith("./")&&(t=t.slice(2),e.prefix="./"),t};wn.wrapOutput=(r,e={},t={})=>{let i=t.contains?"":"^",n=t.contains?"":"$",s=`${i}(?:${r})${n}`;return e.negated===!0&&(s=`(?:^(?!${s}).*$)`),s}});var W3=I((Stt,J3)=>{"use strict";var U3=Yd(),{CHAR_ASTERISK:kP,CHAR_AT:VBe,CHAR_BACKWARD_SLASH:qd,CHAR_COMMA:XBe,CHAR_DOT:DP,CHAR_EXCLAMATION_MARK:RP,CHAR_FORWARD_SLASH:q3,CHAR_LEFT_CURLY_BRACE:FP,CHAR_LEFT_PARENTHESES:NP,CHAR_LEFT_SQUARE_BRACKET:ZBe,CHAR_PLUS:_Be,CHAR_QUESTION_MARK:H3,CHAR_RIGHT_CURLY_BRACE:$Be,CHAR_RIGHT_PARENTHESES:j3,CHAR_RIGHT_SQUARE_BRACKET:e0e}=Gd(),G3=r=>r===q3||r===qd,Y3=r=>{r.isPrefix!==!0&&(r.depth=r.isGlobstar?1/0:1)},t0e=(r,e)=>{let t=e||{},i=r.length-1,n=t.parts===!0||t.scanToEnd===!0,s=[],o=[],a=[],l=r,c=-1,u=0,g=0,h=!1,p=!1,d=!1,m=!1,y=!1,B=!1,S=!1,x=!1,F=!1,H=!1,q=0,_,X,W={value:"",depth:0,isGlob:!1},Z=()=>c>=i,A=()=>l.charCodeAt(c+1),ne=()=>(_=X,l.charCodeAt(++c));for(;c<i;){X=ne();let ce;if(X===qd){S=W.backslashes=!0,X=ne(),X===FP&&(B=!0);continue}if(B===!0||X===FP){for(q++;Z()!==!0&&(X=ne());){if(X===qd){S=W.backslashes=!0,ne();continue}if(X===FP){q++;continue}if(B!==!0&&X===DP&&(X=ne())===DP){if(h=W.isBrace=!0,d=W.isGlob=!0,H=!0,n===!0)continue;break}if(B!==!0&&X===XBe){if(h=W.isBrace=!0,d=W.isGlob=!0,H=!0,n===!0)continue;break}if(X===$Be&&(q--,q===0)){B=!1,h=W.isBrace=!0,H=!0;break}}if(n===!0)continue;break}if(X===q3){if(s.push(c),o.push(W),W={value:"",depth:0,isGlob:!1},H===!0)continue;if(_===DP&&c===u+1){u+=2;continue}g=c+1;continue}if(t.noext!==!0&&(X===_Be||X===VBe||X===kP||X===H3||X===RP)===!0&&A()===NP){if(d=W.isGlob=!0,m=W.isExtglob=!0,H=!0,X===RP&&c===u&&(F=!0),n===!0){for(;Z()!==!0&&(X=ne());){if(X===qd){S=W.backslashes=!0,X=ne();continue}if(X===j3){d=W.isGlob=!0,H=!0;break}}continue}break}if(X===kP){if(_===kP&&(y=W.isGlobstar=!0),d=W.isGlob=!0,H=!0,n===!0)continue;break}if(X===H3){if(d=W.isGlob=!0,H=!0,n===!0)continue;break}if(X===ZBe){for(;Z()!==!0&&(ce=ne());){if(ce===qd){S=W.backslashes=!0,ne();continue}if(ce===e0e){p=W.isBracket=!0,d=W.isGlob=!0,H=!0;break}}if(n===!0)continue;break}if(t.nonegate!==!0&&X===RP&&c===u){x=W.negated=!0,u++;continue}if(t.noparen!==!0&&X===NP){if(d=W.isGlob=!0,n===!0){for(;Z()!==!0&&(X=ne());){if(X===NP){S=W.backslashes=!0,X=ne();continue}if(X===j3){H=!0;break}}continue}break}if(d===!0){if(H=!0,n===!0)continue;break}}t.noext===!0&&(m=!1,d=!1);let ue=l,te="",O="";u>0&&(te=l.slice(0,u),l=l.slice(u),g-=u),ue&&d===!0&&g>0?(ue=l.slice(0,g),O=l.slice(g)):d===!0?(ue="",O=l):ue=l,ue&&ue!==""&&ue!=="/"&&ue!==l&&G3(ue.charCodeAt(ue.length-1))&&(ue=ue.slice(0,-1)),t.unescape===!0&&(O&&(O=U3.removeBackslashes(O)),ue&&S===!0&&(ue=U3.removeBackslashes(ue)));let N={prefix:te,input:r,start:u,base:ue,glob:O,isBrace:h,isBracket:p,isGlob:d,isExtglob:m,isGlobstar:y,negated:x,negatedExtglob:F};if(t.tokens===!0&&(N.maxDepth=0,G3(X)||o.push(W),N.tokens=o),t.parts===!0||t.tokens===!0){let ce;for(let he=0;he<s.length;he++){let xe=ce?ce+1:u,De=s[he],Re=r.slice(xe,De);t.tokens&&(he===0&&u!==0?(o[he].isPrefix=!0,o[he].value=te):o[he].value=Re,Y3(o[he]),N.maxDepth+=o[he].depth),(he!==0||Re!=="")&&a.push(Re),ce=De}if(ce&&ce+1<r.length){let he=r.slice(ce+1);a.push(he),t.tokens&&(o[o.length-1].value=he,Y3(o[o.length-1]),N.maxDepth+=o[o.length-1].depth)}N.slashes=s,N.parts=a}return N};J3.exports=t0e});var X3=I((vtt,V3)=>{"use strict";var Gy=Gd(),Wn=Yd(),{MAX_LENGTH:Yy,POSIX_REGEX_SOURCE:r0e,REGEX_NON_SPECIAL_CHARS:i0e,REGEX_SPECIAL_CHARS_BACKREF:n0e,REPLACEMENTS:z3}=Gy,s0e=(r,e)=>{if(typeof e.expandRange=="function")return e.expandRange(...r,e);r.sort();let t=`[${r.join("-")}]`;try{new RegExp(t)}catch{return r.map(n=>Wn.escapeRegex(n)).join("..")}return t},ff=(r,e)=>`Missing ${r}: "${e}" - use "\\\\${e}" to match literal characters`,TP=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");r=z3[r]||r;let t={...e},i=typeof t.maxLength=="number"?Math.min(Yy,t.maxLength):Yy,n=r.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);let s={type:"bos",value:"",output:t.prepend||""},o=[s],a=t.capture?"":"?:",l=Wn.isWindows(e),c=Gy.globChars(l),u=Gy.extglobChars(c),{DOT_LITERAL:g,PLUS_LITERAL:h,SLASH_LITERAL:p,ONE_CHAR:d,DOTS_SLASH:m,NO_DOT:y,NO_DOT_SLASH:B,NO_DOTS_SLASH:S,QMARK:x,QMARK_NO_DOT:F,STAR:H,START_ANCHOR:q}=c,_=G=>`(${a}(?:(?!${q}${G.dot?m:g}).)*?)`,X=t.dot?"":y,W=t.dot?x:F,Z=t.bash===!0?_(t):H;t.capture&&(Z=`(${Z})`),typeof t.noext=="boolean"&&(t.noextglob=t.noext);let A={input:r,index:-1,start:0,dot:t.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:o};r=Wn.removePrefix(r,A),n=r.length;let ne=[],ue=[],te=[],O=s,N,ce=()=>A.index===n-1,he=A.peek=(G=1)=>r[A.index+G],xe=A.advance=()=>r[++A.index]||"",De=()=>r.slice(A.index+1),Re=(G="",fe=0)=>{A.consumed+=G,A.index+=fe},se=G=>{A.output+=G.output!=null?G.output:G.value,Re(G.value)},Ae=()=>{let G=1;for(;he()==="!"&&(he(2)!=="("||he(3)==="?");)xe(),A.start++,G++;return G%2===0?!1:(A.negated=!0,A.start++,!0)},ye=G=>{A[G]++,te.push(G)},ge=G=>{A[G]--,te.pop()},oe=G=>{if(O.type==="globstar"){let fe=A.braces>0&&(G.type==="comma"||G.type==="brace"),re=G.extglob===!0||ne.length&&(G.type==="pipe"||G.type==="paren");G.type!=="slash"&&G.type!=="paren"&&!fe&&!re&&(A.output=A.output.slice(0,-O.output.length),O.type="star",O.value="*",O.output=Z,A.output+=O.output)}if(ne.length&&G.type!=="paren"&&(ne[ne.length-1].inner+=G.value),(G.value||G.output)&&se(G),O&&O.type==="text"&&G.type==="text"){O.value+=G.value,O.output=(O.output||"")+G.value;return}G.prev=O,o.push(G),O=G},Ye=(G,fe)=>{let re={...u[fe],conditions:1,inner:""};re.prev=O,re.parens=A.parens,re.output=A.output;let de=(t.capture?"(":"")+re.open;ye("parens"),oe({type:G,value:fe,output:A.output?"":d}),oe({type:"paren",extglob:!0,value:xe(),output:de}),ne.push(re)},ie=G=>{let fe=G.close+(t.capture?")":""),re;if(G.type==="negate"){let de=Z;if(G.inner&&G.inner.length>1&&G.inner.includes("/")&&(de=_(t)),(de!==Z||ce()||/^\)+$/.test(De()))&&(fe=G.close=`)$))${de}`),G.inner.includes("*")&&(re=De())&&/^\.[^\\/.]+$/.test(re)){let Ze=TP(re,{...e,fastpaths:!1}).output;fe=G.close=`)${Ze})${de})`}G.prev.type==="bos"&&(A.negatedExtglob=!0)}oe({type:"paren",extglob:!0,value:N,output:fe}),ge("parens")};if(t.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(r)){let G=!1,fe=r.replace(n0e,(re,de,Ze,vt,mt,Tr)=>vt==="\\"?(G=!0,re):vt==="?"?de?de+vt+(mt?x.repeat(mt.length):""):Tr===0?W+(mt?x.repeat(mt.length):""):x.repeat(Ze.length):vt==="."?g.repeat(Ze.length):vt==="*"?de?de+vt+(mt?Z:""):Z:de?re:`\\${re}`);return G===!0&&(t.unescape===!0?fe=fe.replace(/\\/g,""):fe=fe.replace(/\\+/g,re=>re.length%2===0?"\\\\":re?"\\":"")),fe===r&&t.contains===!0?(A.output=r,A):(A.output=Wn.wrapOutput(fe,A,e),A)}for(;!ce();){if(N=xe(),N==="\0")continue;if(N==="\\"){let re=he();if(re==="/"&&t.bash!==!0||re==="."||re===";")continue;if(!re){N+="\\",oe({type:"text",value:N});continue}let de=/^\\+/.exec(De()),Ze=0;if(de&&de[0].length>2&&(Ze=de[0].length,A.index+=Ze,Ze%2!==0&&(N+="\\")),t.unescape===!0?N=xe():N+=xe(),A.brackets===0){oe({type:"text",value:N});continue}}if(A.brackets>0&&(N!=="]"||O.value==="["||O.value==="[^")){if(t.posix!==!1&&N===":"){let re=O.value.slice(1);if(re.includes("[")&&(O.posix=!0,re.includes(":"))){let de=O.value.lastIndexOf("["),Ze=O.value.slice(0,de),vt=O.value.slice(de+2),mt=r0e[vt];if(mt){O.value=Ze+mt,A.backtrack=!0,xe(),!s.output&&o.indexOf(O)===1&&(s.output=d);continue}}}(N==="["&&he()!==":"||N==="-"&&he()==="]")&&(N=`\\${N}`),N==="]"&&(O.value==="["||O.value==="[^")&&(N=`\\${N}`),t.posix===!0&&N==="!"&&O.value==="["&&(N="^"),O.value+=N,se({value:N});continue}if(A.quotes===1&&N!=='"'){N=Wn.escapeRegex(N),O.value+=N,se({value:N});continue}if(N==='"'){A.quotes=A.quotes===1?0:1,t.keepQuotes===!0&&oe({type:"text",value:N});continue}if(N==="("){ye("parens"),oe({type:"paren",value:N});continue}if(N===")"){if(A.parens===0&&t.strictBrackets===!0)throw new SyntaxError(ff("opening","("));let re=ne[ne.length-1];if(re&&A.parens===re.parens+1){ie(ne.pop());continue}oe({type:"paren",value:N,output:A.parens?")":"\\)"}),ge("parens");continue}if(N==="["){if(t.nobracket===!0||!De().includes("]")){if(t.nobracket!==!0&&t.strictBrackets===!0)throw new SyntaxError(ff("closing","]"));N=`\\${N}`}else ye("brackets");oe({type:"bracket",value:N});continue}if(N==="]"){if(t.nobracket===!0||O&&O.type==="bracket"&&O.value.length===1){oe({type:"text",value:N,output:`\\${N}`});continue}if(A.brackets===0){if(t.strictBrackets===!0)throw new SyntaxError(ff("opening","["));oe({type:"text",value:N,output:`\\${N}`});continue}ge("brackets");let re=O.value.slice(1);if(O.posix!==!0&&re[0]==="^"&&!re.includes("/")&&(N=`/${N}`),O.value+=N,se({value:N}),t.literalBrackets===!1||Wn.hasRegexChars(re))continue;let de=Wn.escapeRegex(O.value);if(A.output=A.output.slice(0,-O.value.length),t.literalBrackets===!0){A.output+=de,O.value=de;continue}O.value=`(${a}${de}|${O.value})`,A.output+=O.value;continue}if(N==="{"&&t.nobrace!==!0){ye("braces");let re={type:"brace",value:N,output:"(",outputIndex:A.output.length,tokensIndex:A.tokens.length};ue.push(re),oe(re);continue}if(N==="}"){let re=ue[ue.length-1];if(t.nobrace===!0||!re){oe({type:"text",value:N,output:N});continue}let de=")";if(re.dots===!0){let Ze=o.slice(),vt=[];for(let mt=Ze.length-1;mt>=0&&(o.pop(),Ze[mt].type!=="brace");mt--)Ze[mt].type!=="dots"&&vt.unshift(Ze[mt].value);de=s0e(vt,t),A.backtrack=!0}if(re.comma!==!0&&re.dots!==!0){let Ze=A.output.slice(0,re.outputIndex),vt=A.tokens.slice(re.tokensIndex);re.value=re.output="\\{",N=de="\\}",A.output=Ze;for(let mt of vt)A.output+=mt.output||mt.value}oe({type:"brace",value:N,output:de}),ge("braces"),ue.pop();continue}if(N==="|"){ne.length>0&&ne[ne.length-1].conditions++,oe({type:"text",value:N});continue}if(N===","){let re=N,de=ue[ue.length-1];de&&te[te.length-1]==="braces"&&(de.comma=!0,re="|"),oe({type:"comma",value:N,output:re});continue}if(N==="/"){if(O.type==="dot"&&A.index===A.start+1){A.start=A.index+1,A.consumed="",A.output="",o.pop(),O=s;continue}oe({type:"slash",value:N,output:p});continue}if(N==="."){if(A.braces>0&&O.type==="dot"){O.value==="."&&(O.output=g);let re=ue[ue.length-1];O.type="dots",O.output+=N,O.value+=N,re.dots=!0;continue}if(A.braces+A.parens===0&&O.type!=="bos"&&O.type!=="slash"){oe({type:"text",value:N,output:g});continue}oe({type:"dot",value:N,output:g});continue}if(N==="?"){if(!(O&&O.value==="(")&&t.noextglob!==!0&&he()==="("&&he(2)!=="?"){Ye("qmark",N);continue}if(O&&O.type==="paren"){let de=he(),Ze=N;if(de==="<"&&!Wn.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(O.value==="("&&!/[!=<:]/.test(de)||de==="<"&&!/<([!=]|\w+>)/.test(De()))&&(Ze=`\\${N}`),oe({type:"text",value:N,output:Ze});continue}if(t.dot!==!0&&(O.type==="slash"||O.type==="bos")){oe({type:"qmark",value:N,output:F});continue}oe({type:"qmark",value:N,output:x});continue}if(N==="!"){if(t.noextglob!==!0&&he()==="("&&(he(2)!=="?"||!/[!=<:]/.test(he(3)))){Ye("negate",N);continue}if(t.nonegate!==!0&&A.index===0){Ae();continue}}if(N==="+"){if(t.noextglob!==!0&&he()==="("&&he(2)!=="?"){Ye("plus",N);continue}if(O&&O.value==="("||t.regex===!1){oe({type:"plus",value:N,output:h});continue}if(O&&(O.type==="bracket"||O.type==="paren"||O.type==="brace")||A.parens>0){oe({type:"plus",value:N});continue}oe({type:"plus",value:h});continue}if(N==="@"){if(t.noextglob!==!0&&he()==="("&&he(2)!=="?"){oe({type:"at",extglob:!0,value:N,output:""});continue}oe({type:"text",value:N});continue}if(N!=="*"){(N==="$"||N==="^")&&(N=`\\${N}`);let re=i0e.exec(De());re&&(N+=re[0],A.index+=re[0].length),oe({type:"text",value:N});continue}if(O&&(O.type==="globstar"||O.star===!0)){O.type="star",O.star=!0,O.value+=N,O.output=Z,A.backtrack=!0,A.globstar=!0,Re(N);continue}let G=De();if(t.noextglob!==!0&&/^\([^?]/.test(G)){Ye("star",N);continue}if(O.type==="star"){if(t.noglobstar===!0){Re(N);continue}let re=O.prev,de=re.prev,Ze=re.type==="slash"||re.type==="bos",vt=de&&(de.type==="star"||de.type==="globstar");if(t.bash===!0&&(!Ze||G[0]&&G[0]!=="/")){oe({type:"star",value:N,output:""});continue}let mt=A.braces>0&&(re.type==="comma"||re.type==="brace"),Tr=ne.length&&(re.type==="pipe"||re.type==="paren");if(!Ze&&re.type!=="paren"&&!mt&&!Tr){oe({type:"star",value:N,output:""});continue}for(;G.slice(0,3)==="/**";){let ti=r[A.index+4];if(ti&&ti!=="/")break;G=G.slice(3),Re("/**",3)}if(re.type==="bos"&&ce()){O.type="globstar",O.value+=N,O.output=_(t),A.output=O.output,A.globstar=!0,Re(N);continue}if(re.type==="slash"&&re.prev.type!=="bos"&&!vt&&ce()){A.output=A.output.slice(0,-(re.output+O.output).length),re.output=`(?:${re.output}`,O.type="globstar",O.output=_(t)+(t.strictSlashes?")":"|$)"),O.value+=N,A.globstar=!0,A.output+=re.output+O.output,Re(N);continue}if(re.type==="slash"&&re.prev.type!=="bos"&&G[0]==="/"){let ti=G[1]!==void 0?"|$":"";A.output=A.output.slice(0,-(re.output+O.output).length),re.output=`(?:${re.output}`,O.type="globstar",O.output=`${_(t)}${p}|${p}${ti})`,O.value+=N,A.output+=re.output+O.output,A.globstar=!0,Re(N+xe()),oe({type:"slash",value:"/",output:""});continue}if(re.type==="bos"&&G[0]==="/"){O.type="globstar",O.value+=N,O.output=`(?:^|${p}|${_(t)}${p})`,A.output=O.output,A.globstar=!0,Re(N+xe()),oe({type:"slash",value:"/",output:""});continue}A.output=A.output.slice(0,-O.output.length),O.type="globstar",O.output=_(t),O.value+=N,A.output+=O.output,A.globstar=!0,Re(N);continue}let fe={type:"star",value:N,output:Z};if(t.bash===!0){fe.output=".*?",(O.type==="bos"||O.type==="slash")&&(fe.output=X+fe.output),oe(fe);continue}if(O&&(O.type==="bracket"||O.type==="paren")&&t.regex===!0){fe.output=N,oe(fe);continue}(A.index===A.start||O.type==="slash"||O.type==="dot")&&(O.type==="dot"?(A.output+=B,O.output+=B):t.dot===!0?(A.output+=S,O.output+=S):(A.output+=X,O.output+=X),he()!=="*"&&(A.output+=d,O.output+=d)),oe(fe)}for(;A.brackets>0;){if(t.strictBrackets===!0)throw new SyntaxError(ff("closing","]"));A.output=Wn.escapeLast(A.output,"["),ge("brackets")}for(;A.parens>0;){if(t.strictBrackets===!0)throw new SyntaxError(ff("closing",")"));A.output=Wn.escapeLast(A.output,"("),ge("parens")}for(;A.braces>0;){if(t.strictBrackets===!0)throw new SyntaxError(ff("closing","}"));A.output=Wn.escapeLast(A.output,"{"),ge("braces")}if(t.strictSlashes!==!0&&(O.type==="star"||O.type==="bracket")&&oe({type:"maybe_slash",value:"",output:`${p}?`}),A.backtrack===!0){A.output="";for(let G of A.tokens)A.output+=G.output!=null?G.output:G.value,G.suffix&&(A.output+=G.suffix)}return A};TP.fastpaths=(r,e)=>{let t={...e},i=typeof t.maxLength=="number"?Math.min(Yy,t.maxLength):Yy,n=r.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);r=z3[r]||r;let s=Wn.isWindows(e),{DOT_LITERAL:o,SLASH_LITERAL:a,ONE_CHAR:l,DOTS_SLASH:c,NO_DOT:u,NO_DOTS:g,NO_DOTS_SLASH:h,STAR:p,START_ANCHOR:d}=Gy.globChars(s),m=t.dot?g:u,y=t.dot?h:u,B=t.capture?"":"?:",S={negated:!1,prefix:""},x=t.bash===!0?".*?":p;t.capture&&(x=`(${x})`);let F=X=>X.noglobstar===!0?x:`(${B}(?:(?!${d}${X.dot?c:o}).)*?)`,H=X=>{switch(X){case"*":return`${m}${l}${x}`;case".*":return`${o}${l}${x}`;case"*.*":return`${m}${x}${o}${l}${x}`;case"*/*":return`${m}${x}${a}${l}${y}${x}`;case"**":return m+F(t);case"**/*":return`(?:${m}${F(t)}${a})?${y}${l}${x}`;case"**/*.*":return`(?:${m}${F(t)}${a})?${y}${x}${o}${l}${x}`;case"**/.*":return`(?:${m}${F(t)}${a})?${o}${l}${x}`;default:{let W=/^(.*?)\.(\w+)$/.exec(X);if(!W)return;let Z=H(W[1]);return Z?Z+o+W[2]:void 0}}},q=Wn.removePrefix(r,S),_=H(q);return _&&t.strictSlashes!==!0&&(_+=`${a}?`),_};V3.exports=TP});var _3=I((Ptt,Z3)=>{"use strict";var o0e=J("path"),a0e=W3(),LP=X3(),OP=Yd(),A0e=Gd(),l0e=r=>r&&typeof r=="object"&&!Array.isArray(r),Kr=(r,e,t=!1)=>{if(Array.isArray(r)){let u=r.map(h=>Kr(h,e,t));return h=>{for(let p of u){let d=p(h);if(d)return d}return!1}}let i=l0e(r)&&r.tokens&&r.input;if(r===""||typeof r!="string"&&!i)throw new TypeError("Expected pattern to be a non-empty string");let n=e||{},s=OP.isWindows(e),o=i?Kr.compileRe(r,e):Kr.makeRe(r,e,!1,!0),a=o.state;delete o.state;let l=()=>!1;if(n.ignore){let u={...e,ignore:null,onMatch:null,onResult:null};l=Kr(n.ignore,u,t)}let c=(u,g=!1)=>{let{isMatch:h,match:p,output:d}=Kr.test(u,o,e,{glob:r,posix:s}),m={glob:r,state:a,regex:o,posix:s,input:u,output:d,match:p,isMatch:h};return typeof n.onResult=="function"&&n.onResult(m),h===!1?(m.isMatch=!1,g?m:!1):l(u)?(typeof n.onIgnore=="function"&&n.onIgnore(m),m.isMatch=!1,g?m:!1):(typeof n.onMatch=="function"&&n.onMatch(m),g?m:!0)};return t&&(c.state=a),c};Kr.test=(r,e,t,{glob:i,posix:n}={})=>{if(typeof r!="string")throw new TypeError("Expected input to be a string");if(r==="")return{isMatch:!1,output:""};let s=t||{},o=s.format||(n?OP.toPosixSlashes:null),a=r===i,l=a&&o?o(r):r;return a===!1&&(l=o?o(r):r,a=l===i),(a===!1||s.capture===!0)&&(s.matchBase===!0||s.basename===!0?a=Kr.matchBase(r,e,t,n):a=e.exec(l)),{isMatch:Boolean(a),match:a,output:l}};Kr.matchBase=(r,e,t,i=OP.isWindows(t))=>(e instanceof RegExp?e:Kr.makeRe(e,t)).test(o0e.basename(r));Kr.isMatch=(r,e,t)=>Kr(e,t)(r);Kr.parse=(r,e)=>Array.isArray(r)?r.map(t=>Kr.parse(t,e)):LP(r,{...e,fastpaths:!1});Kr.scan=(r,e)=>a0e(r,e);Kr.compileRe=(r,e,t=!1,i=!1)=>{if(t===!0)return r.output;let n=e||{},s=n.contains?"":"^",o=n.contains?"":"$",a=`${s}(?:${r.output})${o}`;r&&r.negated===!0&&(a=`^(?!${a}).*$`);let l=Kr.toRegex(a,e);return i===!0&&(l.state=r),l};Kr.makeRe=(r,e={},t=!1,i=!1)=>{if(!r||typeof r!="string")throw new TypeError("Expected a non-empty string");let n={negated:!1,fastpaths:!0};return e.fastpaths!==!1&&(r[0]==="."||r[0]==="*")&&(n.output=LP.fastpaths(r,e)),n.output||(n=LP(r,e)),Kr.compileRe(n,e,t,i)};Kr.toRegex=(r,e)=>{try{let t=e||{};return new RegExp(r,t.flags||(t.nocase?"i":""))}catch(t){if(e&&e.debug===!0)throw t;return/$^/}};Kr.constants=A0e;Z3.exports=Kr});var MP=I((xtt,$3)=>{"use strict";$3.exports=_3()});var Bn=I((ktt,iW)=>{"use strict";var tW=J("util"),rW=N3(),Ko=MP(),KP=Yd(),eW=r=>r===""||r==="./",br=(r,e,t)=>{e=[].concat(e),r=[].concat(r);let i=new Set,n=new Set,s=new Set,o=0,a=u=>{s.add(u.output),t&&t.onResult&&t.onResult(u)};for(let u=0;u<e.length;u++){let g=Ko(String(e[u]),{...t,onResult:a},!0),h=g.state.negated||g.state.negatedExtglob;h&&o++;for(let p of r){let d=g(p,!0);!(h?!d.isMatch:d.isMatch)||(h?i.add(d.output):(i.delete(d.output),n.add(d.output)))}}let c=(o===e.length?[...s]:[...n]).filter(u=>!i.has(u));if(t&&c.length===0){if(t.failglob===!0)throw new Error(`No matches found for "${e.join(", ")}"`);if(t.nonull===!0||t.nullglob===!0)return t.unescape?e.map(u=>u.replace(/\\/g,"")):e}return c};br.match=br;br.matcher=(r,e)=>Ko(r,e);br.isMatch=(r,e,t)=>Ko(e,t)(r);br.any=br.isMatch;br.not=(r,e,t={})=>{e=[].concat(e).map(String);let i=new Set,n=[],o=br(r,e,{...t,onResult:a=>{t.onResult&&t.onResult(a),n.push(a.output)}});for(let a of n)o.includes(a)||i.add(a);return[...i]};br.contains=(r,e,t)=>{if(typeof r!="string")throw new TypeError(`Expected a string: "${tW.inspect(r)}"`);if(Array.isArray(e))return e.some(i=>br.contains(r,i,t));if(typeof e=="string"){if(eW(r)||eW(e))return!1;if(r.includes(e)||r.startsWith("./")&&r.slice(2).includes(e))return!0}return br.isMatch(r,e,{...t,contains:!0})};br.matchKeys=(r,e,t)=>{if(!KP.isObject(r))throw new TypeError("Expected the first argument to be an object");let i=br(Object.keys(r),e,t),n={};for(let s of i)n[s]=r[s];return n};br.some=(r,e,t)=>{let i=[].concat(r);for(let n of[].concat(e)){let s=Ko(String(n),t);if(i.some(o=>s(o)))return!0}return!1};br.every=(r,e,t)=>{let i=[].concat(r);for(let n of[].concat(e)){let s=Ko(String(n),t);if(!i.every(o=>s(o)))return!1}return!0};br.all=(r,e,t)=>{if(typeof r!="string")throw new TypeError(`Expected a string: "${tW.inspect(r)}"`);return[].concat(e).every(i=>Ko(i,t)(r))};br.capture=(r,e,t)=>{let i=KP.isWindows(t),s=Ko.makeRe(String(r),{...t,capture:!0}).exec(i?KP.toPosixSlashes(e):e);if(s)return s.slice(1).map(o=>o===void 0?"":o)};br.makeRe=(...r)=>Ko.makeRe(...r);br.scan=(...r)=>Ko.scan(...r);br.parse=(r,e)=>{let t=[];for(let i of[].concat(r||[]))for(let n of rW(String(i),e))t.push(Ko.parse(n,e));return t};br.braces=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");return e&&e.nobrace===!0||!/\{.*\}/.test(r)?[r]:rW(r,e)};br.braceExpand=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");return br.braces(r,{...e,expand:!0})};iW.exports=br});var sW=I((Dtt,nW)=>{"use strict";nW.exports=({onlyFirst:r=!1}={})=>{let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,r?void 0:"g")}});var aW=I((Rtt,oW)=>{"use strict";var c0e=sW();oW.exports=r=>typeof r=="string"?r.replace(c0e(),""):r});var yW=I((Gtt,IW)=>{"use strict";IW.exports=(...r)=>[...new Set([].concat(...r))]});var sx=I((Ytt,bW)=>{"use strict";var B0e=J("stream"),wW=B0e.PassThrough,b0e=Array.prototype.slice;bW.exports=Q0e;function Q0e(){let r=[],e=!1,t=b0e.call(arguments),i=t[t.length-1];i&&!Array.isArray(i)&&i.pipe==null?t.pop():i={};let n=i.end!==!1;i.objectMode==null&&(i.objectMode=!0),i.highWaterMark==null&&(i.highWaterMark=64*1024);let s=wW(i);function o(){for(let c=0,u=arguments.length;c<u;c++)r.push(BW(arguments[c],i));return a(),this}function a(){if(e)return;e=!0;let c=r.shift();if(!c){process.nextTick(l);return}Array.isArray(c)||(c=[c]);let u=c.length+1;function g(){--u>0||(e=!1,a())}function h(p){function d(){p.removeListener("merge2UnpipeEnd",d),p.removeListener("end",d),g()}if(p._readableState.endEmitted)return g();p.on("merge2UnpipeEnd",d),p.on("end",d),p.pipe(s,{end:!1}),p.resume()}for(let p=0;p<c.length;p++)h(c[p]);g()}function l(){return e=!1,s.emit("queueDrain"),n&&s.end()}return s.setMaxListeners(0),s.add=o,s.on("unpipe",function(c){c.emit("merge2UnpipeEnd")}),t.length&&o.apply(null,t),s}function BW(r,e){if(Array.isArray(r))for(let t=0,i=r.length;t<i;t++)r[t]=BW(r[t],e);else{if(!r._readableState&&r.pipe&&(r=r.pipe(wW(e))),!r._readableState||!r.pause||!r.pipe)throw new Error("Only readable stream can be merged.");r.pause()}return r}});var QW=I(Xy=>{"use strict";Object.defineProperty(Xy,"__esModule",{value:!0});function S0e(r){return r.reduce((e,t)=>[].concat(e,t),[])}Xy.flatten=S0e;function v0e(r,e){let t=[[]],i=0;for(let n of r)e(n)?(i++,t[i]=[]):t[i].push(n);return t}Xy.splitWhen=v0e});var SW=I(ox=>{"use strict";Object.defineProperty(ox,"__esModule",{value:!0});function P0e(r){return r.code==="ENOENT"}ox.isEnoentCodeError=P0e});var vW=I(Ax=>{"use strict";Object.defineProperty(Ax,"__esModule",{value:!0});var ax=class{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}};function x0e(r,e){return new ax(r,e)}Ax.createDirentFromStats=x0e});var PW=I(yf=>{"use strict";Object.defineProperty(yf,"__esModule",{value:!0});var k0e=J("path"),D0e=2,R0e=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g;function F0e(r){return r.replace(/\\/g,"/")}yf.unixify=F0e;function N0e(r,e){return k0e.resolve(r,e)}yf.makeAbsolute=N0e;function T0e(r){return r.replace(R0e,"\\$2")}yf.escape=T0e;function L0e(r){if(r.charAt(0)==="."){let e=r.charAt(1);if(e==="/"||e==="\\")return r.slice(D0e)}return r}yf.removeLeadingDotSegment=L0e});var kW=I((Vtt,xW)=>{xW.exports=function(e){if(typeof e!="string"||e==="")return!1;for(var t;t=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(t[2])return!0;e=e.slice(t.index+t[0].length)}return!1}});var FW=I((Xtt,RW)=>{var O0e=kW(),DW={"{":"}","(":")","[":"]"},M0e=function(r){if(r[0]==="!")return!0;for(var e=0,t=-2,i=-2,n=-2,s=-2,o=-2;e<r.length;){if(r[e]==="*"||r[e+1]==="?"&&/[\].+)]/.test(r[e])||i!==-1&&r[e]==="["&&r[e+1]!=="]"&&(i<e&&(i=r.indexOf("]",e)),i>e&&(o===-1||o>i||(o=r.indexOf("\\",e),o===-1||o>i)))||n!==-1&&r[e]==="{"&&r[e+1]!=="}"&&(n=r.indexOf("}",e),n>e&&(o=r.indexOf("\\",e),o===-1||o>n))||s!==-1&&r[e]==="("&&r[e+1]==="?"&&/[:!=]/.test(r[e+2])&&r[e+3]!==")"&&(s=r.indexOf(")",e),s>e&&(o=r.indexOf("\\",e),o===-1||o>s))||t!==-1&&r[e]==="("&&r[e+1]!=="|"&&(t<e&&(t=r.indexOf("|",e)),t!==-1&&r[t+1]!==")"&&(s=r.indexOf(")",t),s>t&&(o=r.indexOf("\\",t),o===-1||o>s))))return!0;if(r[e]==="\\"){var a=r[e+1];e+=2;var l=DW[a];if(l){var c=r.indexOf(l,e);c!==-1&&(e=c+1)}if(r[e]==="!")return!0}else e++}return!1},K0e=function(r){if(r[0]==="!")return!0;for(var e=0;e<r.length;){if(/[*?{}()[\]]/.test(r[e]))return!0;if(r[e]==="\\"){var t=r[e+1];e+=2;var i=DW[t];if(i){var n=r.indexOf(i,e);n!==-1&&(e=n+1)}if(r[e]==="!")return!0}else e++}return!1};RW.exports=function(e,t){if(typeof e!="string"||e==="")return!1;if(O0e(e))return!0;var i=M0e;return t&&t.strict===!1&&(i=K0e),i(e)}});var TW=I((Ztt,NW)=>{"use strict";var U0e=FW(),H0e=J("path").posix.dirname,j0e=J("os").platform()==="win32",lx="/",G0e=/\\/g,Y0e=/[\{\[].*[\}\]]$/,q0e=/(^|[^\\])([\{\[]|\([^\)]+$)/,J0e=/\\([\!\*\?\|\[\]\(\)\{\}])/g;NW.exports=function(e,t){var i=Object.assign({flipBackslashes:!0},t);i.flipBackslashes&&j0e&&e.indexOf(lx)<0&&(e=e.replace(G0e,lx)),Y0e.test(e)&&(e+=lx),e+="a";do e=H0e(e);while(U0e(e)||q0e.test(e));return e.replace(J0e,"$1")}});var YW=I(Zr=>{"use strict";Object.defineProperty(Zr,"__esModule",{value:!0});var W0e=J("path"),z0e=TW(),LW=Bn(),V0e=MP(),OW="**",X0e="\\",Z0e=/[*?]|^!/,_0e=/\[.*]/,$0e=/(?:^|[^!*+?@])\(.*\|.*\)/,ebe=/[!*+?@]\(.*\)/,tbe=/{.*(?:,|\.\.).*}/;function MW(r,e={}){return!KW(r,e)}Zr.isStaticPattern=MW;function KW(r,e={}){return!!(e.caseSensitiveMatch===!1||r.includes(X0e)||Z0e.test(r)||_0e.test(r)||$0e.test(r)||e.extglob!==!1&&ebe.test(r)||e.braceExpansion!==!1&&tbe.test(r))}Zr.isDynamicPattern=KW;function rbe(r){return Zy(r)?r.slice(1):r}Zr.convertToPositivePattern=rbe;function ibe(r){return"!"+r}Zr.convertToNegativePattern=ibe;function Zy(r){return r.startsWith("!")&&r[1]!=="("}Zr.isNegativePattern=Zy;function UW(r){return!Zy(r)}Zr.isPositivePattern=UW;function nbe(r){return r.filter(Zy)}Zr.getNegativePatterns=nbe;function sbe(r){return r.filter(UW)}Zr.getPositivePatterns=sbe;function obe(r){return z0e(r,{flipBackslashes:!1})}Zr.getBaseDirectory=obe;function abe(r){return r.includes(OW)}Zr.hasGlobStar=abe;function HW(r){return r.endsWith("/"+OW)}Zr.endsWithSlashGlobStar=HW;function Abe(r){let e=W0e.basename(r);return HW(r)||MW(e)}Zr.isAffectDepthOfReadingPattern=Abe;function lbe(r){return r.reduce((e,t)=>e.concat(jW(t)),[])}Zr.expandPatternsWithBraceExpansion=lbe;function jW(r){return LW.braces(r,{expand:!0,nodupes:!0})}Zr.expandBraceExpansion=jW;function cbe(r,e){let t=V0e.scan(r,Object.assign(Object.assign({},e),{parts:!0}));return t.parts.length===0?[r]:t.parts}Zr.getPatternParts=cbe;function GW(r,e){return LW.makeRe(r,e)}Zr.makeRe=GW;function ube(r,e){return r.map(t=>GW(t,e))}Zr.convertPatternsToRe=ube;function gbe(r,e){return e.some(t=>t.test(r))}Zr.matchAny=gbe});var JW=I(cx=>{"use strict";Object.defineProperty(cx,"__esModule",{value:!0});var fbe=sx();function hbe(r){let e=fbe(r);return r.forEach(t=>{t.once("error",i=>e.emit("error",i))}),e.once("close",()=>qW(r)),e.once("end",()=>qW(r)),e}cx.merge=hbe;function qW(r){r.forEach(e=>e.emit("close"))}});var WW=I(_y=>{"use strict";Object.defineProperty(_y,"__esModule",{value:!0});function pbe(r){return typeof r=="string"}_y.isString=pbe;function dbe(r){return r===""}_y.isEmpty=dbe});var Ma=I(Oa=>{"use strict";Object.defineProperty(Oa,"__esModule",{value:!0});var Cbe=QW();Oa.array=Cbe;var mbe=SW();Oa.errno=mbe;var Ebe=vW();Oa.fs=Ebe;var Ibe=PW();Oa.path=Ibe;var ybe=YW();Oa.pattern=ybe;var wbe=JW();Oa.stream=wbe;var Bbe=WW();Oa.string=Bbe});var _W=I(Ka=>{"use strict";Object.defineProperty(Ka,"__esModule",{value:!0});var Sc=Ma();function bbe(r,e){let t=zW(r),i=VW(r,e.ignore),n=t.filter(l=>Sc.pattern.isStaticPattern(l,e)),s=t.filter(l=>Sc.pattern.isDynamicPattern(l,e)),o=ux(n,i,!1),a=ux(s,i,!0);return o.concat(a)}Ka.generate=bbe;function ux(r,e,t){let i=XW(r);return"."in i?[gx(".",r,e,t)]:ZW(i,e,t)}Ka.convertPatternsToTasks=ux;function zW(r){return Sc.pattern.getPositivePatterns(r)}Ka.getPositivePatterns=zW;function VW(r,e){return Sc.pattern.getNegativePatterns(r).concat(e).map(Sc.pattern.convertToPositivePattern)}Ka.getNegativePatternsAsPositive=VW;function XW(r){let e={};return r.reduce((t,i)=>{let n=Sc.pattern.getBaseDirectory(i);return n in t?t[n].push(i):t[n]=[i],t},e)}Ka.groupPatternsByBaseDirectory=XW;function ZW(r,e,t){return Object.keys(r).map(i=>gx(i,r[i],e,t))}Ka.convertPatternGroupsToTasks=ZW;function gx(r,e,t,i){return{dynamic:i,positive:e,negative:t,base:r,patterns:[].concat(e,t.map(Sc.pattern.convertToNegativePattern))}}Ka.convertPatternGroupToTask=gx});var e4=I($y=>{"use strict";Object.defineProperty($y,"__esModule",{value:!0});$y.read=void 0;function Qbe(r,e,t){e.fs.lstat(r,(i,n)=>{if(i!==null){$W(t,i);return}if(!n.isSymbolicLink()||!e.followSymbolicLink){fx(t,n);return}e.fs.stat(r,(s,o)=>{if(s!==null){if(e.throwErrorOnBrokenSymbolicLink){$W(t,s);return}fx(t,n);return}e.markSymbolicLink&&(o.isSymbolicLink=()=>!0),fx(t,o)})})}$y.read=Qbe;function $W(r,e){r(e)}function fx(r,e){r(null,e)}});var t4=I(ew=>{"use strict";Object.defineProperty(ew,"__esModule",{value:!0});ew.read=void 0;function Sbe(r,e){let t=e.fs.lstatSync(r);if(!t.isSymbolicLink()||!e.followSymbolicLink)return t;try{let i=e.fs.statSync(r);return e.markSymbolicLink&&(i.isSymbolicLink=()=>!0),i}catch(i){if(!e.throwErrorOnBrokenSymbolicLink)return t;throw i}}ew.read=Sbe});var r4=I(KA=>{"use strict";Object.defineProperty(KA,"__esModule",{value:!0});KA.createFileSystemAdapter=KA.FILE_SYSTEM_ADAPTER=void 0;var tw=J("fs");KA.FILE_SYSTEM_ADAPTER={lstat:tw.lstat,stat:tw.stat,lstatSync:tw.lstatSync,statSync:tw.statSync};function vbe(r){return r===void 0?KA.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},KA.FILE_SYSTEM_ADAPTER),r)}KA.createFileSystemAdapter=vbe});var i4=I(px=>{"use strict";Object.defineProperty(px,"__esModule",{value:!0});var Pbe=r4(),hx=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=Pbe.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,t){return e!=null?e:t}};px.default=hx});var vc=I(UA=>{"use strict";Object.defineProperty(UA,"__esModule",{value:!0});UA.statSync=UA.stat=UA.Settings=void 0;var n4=e4(),xbe=t4(),dx=i4();UA.Settings=dx.default;function kbe(r,e,t){if(typeof e=="function"){n4.read(r,Cx(),e);return}n4.read(r,Cx(e),t)}UA.stat=kbe;function Dbe(r,e){let t=Cx(e);return xbe.read(r,t)}UA.statSync=Dbe;function Cx(r={}){return r instanceof dx.default?r:new dx.default(r)}});var o4=I((Art,s4)=>{s4.exports=Rbe;function Rbe(r,e){var t,i,n,s=!0;Array.isArray(r)?(t=[],i=r.length):(n=Object.keys(r),t={},i=n.length);function o(l){function c(){e&&e(l,t),e=null}s?process.nextTick(c):c()}function a(l,c,u){t[l]=u,(--i===0||c)&&o(c)}i?n?n.forEach(function(l){r[l](function(c,u){a(l,c,u)})}):r.forEach(function(l,c){l(function(u,g){a(c,u,g)})}):o(null),s=!1}});var mx=I(iw=>{"use strict";Object.defineProperty(iw,"__esModule",{value:!0});iw.IS_SUPPORT_READDIR_WITH_FILE_TYPES=void 0;var rw=process.versions.node.split(".");if(rw[0]===void 0||rw[1]===void 0)throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);var a4=Number.parseInt(rw[0],10),Fbe=Number.parseInt(rw[1],10),A4=10,Nbe=10,Tbe=a4>A4,Lbe=a4===A4&&Fbe>=Nbe;iw.IS_SUPPORT_READDIR_WITH_FILE_TYPES=Tbe||Lbe});var l4=I(nw=>{"use strict";Object.defineProperty(nw,"__esModule",{value:!0});nw.createDirentFromStats=void 0;var Ex=class{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}};function Obe(r,e){return new Ex(r,e)}nw.createDirentFromStats=Obe});var Ix=I(sw=>{"use strict";Object.defineProperty(sw,"__esModule",{value:!0});sw.fs=void 0;var Mbe=l4();sw.fs=Mbe});var yx=I(ow=>{"use strict";Object.defineProperty(ow,"__esModule",{value:!0});ow.joinPathSegments=void 0;function Kbe(r,e,t){return r.endsWith(t)?r+e:r+t+e}ow.joinPathSegments=Kbe});var p4=I(HA=>{"use strict";Object.defineProperty(HA,"__esModule",{value:!0});HA.readdir=HA.readdirWithFileTypes=HA.read=void 0;var Ube=vc(),c4=o4(),Hbe=mx(),u4=Ix(),g4=yx();function jbe(r,e,t){if(!e.stats&&Hbe.IS_SUPPORT_READDIR_WITH_FILE_TYPES){f4(r,e,t);return}h4(r,e,t)}HA.read=jbe;function f4(r,e,t){e.fs.readdir(r,{withFileTypes:!0},(i,n)=>{if(i!==null){aw(t,i);return}let s=n.map(a=>({dirent:a,name:a.name,path:g4.joinPathSegments(r,a.name,e.pathSegmentSeparator)}));if(!e.followSymbolicLinks){wx(t,s);return}let o=s.map(a=>Gbe(a,e));c4(o,(a,l)=>{if(a!==null){aw(t,a);return}wx(t,l)})})}HA.readdirWithFileTypes=f4;function Gbe(r,e){return t=>{if(!r.dirent.isSymbolicLink()){t(null,r);return}e.fs.stat(r.path,(i,n)=>{if(i!==null){if(e.throwErrorOnBrokenSymbolicLink){t(i);return}t(null,r);return}r.dirent=u4.fs.createDirentFromStats(r.name,n),t(null,r)})}}function h4(r,e,t){e.fs.readdir(r,(i,n)=>{if(i!==null){aw(t,i);return}let s=n.map(o=>{let a=g4.joinPathSegments(r,o,e.pathSegmentSeparator);return l=>{Ube.stat(a,e.fsStatSettings,(c,u)=>{if(c!==null){l(c);return}let g={name:o,path:a,dirent:u4.fs.createDirentFromStats(o,u)};e.stats&&(g.stats=u),l(null,g)})}});c4(s,(o,a)=>{if(o!==null){aw(t,o);return}wx(t,a)})})}HA.readdir=h4;function aw(r,e){r(e)}function wx(r,e){r(null,e)}});var I4=I(jA=>{"use strict";Object.defineProperty(jA,"__esModule",{value:!0});jA.readdir=jA.readdirWithFileTypes=jA.read=void 0;var Ybe=vc(),qbe=mx(),d4=Ix(),C4=yx();function Jbe(r,e){return!e.stats&&qbe.IS_SUPPORT_READDIR_WITH_FILE_TYPES?m4(r,e):E4(r,e)}jA.read=Jbe;function m4(r,e){return e.fs.readdirSync(r,{withFileTypes:!0}).map(i=>{let n={dirent:i,name:i.name,path:C4.joinPathSegments(r,i.name,e.pathSegmentSeparator)};if(n.dirent.isSymbolicLink()&&e.followSymbolicLinks)try{let s=e.fs.statSync(n.path);n.dirent=d4.fs.createDirentFromStats(n.name,s)}catch(s){if(e.throwErrorOnBrokenSymbolicLink)throw s}return n})}jA.readdirWithFileTypes=m4;function E4(r,e){return e.fs.readdirSync(r).map(i=>{let n=C4.joinPathSegments(r,i,e.pathSegmentSeparator),s=Ybe.statSync(n,e.fsStatSettings),o={name:i,path:n,dirent:d4.fs.createDirentFromStats(i,s)};return e.stats&&(o.stats=s),o})}jA.readdir=E4});var y4=I(GA=>{"use strict";Object.defineProperty(GA,"__esModule",{value:!0});GA.createFileSystemAdapter=GA.FILE_SYSTEM_ADAPTER=void 0;var wf=J("fs");GA.FILE_SYSTEM_ADAPTER={lstat:wf.lstat,stat:wf.stat,lstatSync:wf.lstatSync,statSync:wf.statSync,readdir:wf.readdir,readdirSync:wf.readdirSync};function Wbe(r){return r===void 0?GA.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},GA.FILE_SYSTEM_ADAPTER),r)}GA.createFileSystemAdapter=Wbe});var w4=I(bx=>{"use strict";Object.defineProperty(bx,"__esModule",{value:!0});var zbe=J("path"),Vbe=vc(),Xbe=y4(),Bx=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=Xbe.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,zbe.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new Vbe.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return e!=null?e:t}};bx.default=Bx});var Aw=I(YA=>{"use strict";Object.defineProperty(YA,"__esModule",{value:!0});YA.Settings=YA.scandirSync=YA.scandir=void 0;var B4=p4(),Zbe=I4(),Qx=w4();YA.Settings=Qx.default;function _be(r,e,t){if(typeof e=="function"){B4.read(r,Sx(),e);return}B4.read(r,Sx(e),t)}YA.scandir=_be;function $be(r,e){let t=Sx(e);return Zbe.read(r,t)}YA.scandirSync=$be;function Sx(r={}){return r instanceof Qx.default?r:new Qx.default(r)}});var Q4=I((mrt,b4)=>{"use strict";function eQe(r){var e=new r,t=e;function i(){var s=e;return s.next?e=s.next:(e=new r,t=e),s.next=null,s}function n(s){t.next=s,t=s}return{get:i,release:n}}b4.exports=eQe});var v4=I((Ert,vx)=>{"use strict";var tQe=Q4();function S4(r,e,t){if(typeof r=="function"&&(t=e,e=r,r=null),t<1)throw new Error("fastqueue concurrency must be greater than 1");var i=tQe(rQe),n=null,s=null,o=0,a=null,l={push:m,drain:Es,saturated:Es,pause:u,paused:!1,concurrency:t,running:c,resume:p,idle:d,length:g,getQueue:h,unshift:y,empty:Es,kill:S,killAndDrain:x,error:F};return l;function c(){return o}function u(){l.paused=!0}function g(){for(var H=n,q=0;H;)H=H.next,q++;return q}function h(){for(var H=n,q=[];H;)q.push(H.value),H=H.next;return q}function p(){if(!!l.paused){l.paused=!1;for(var H=0;H<l.concurrency;H++)o++,B()}}function d(){return o===0&&l.length()===0}function m(H,q){var _=i.get();_.context=r,_.release=B,_.value=H,_.callback=q||Es,_.errorHandler=a,o===l.concurrency||l.paused?s?(s.next=_,s=_):(n=_,s=_,l.saturated()):(o++,e.call(r,_.value,_.worked))}function y(H,q){var _=i.get();_.context=r,_.release=B,_.value=H,_.callback=q||Es,o===l.concurrency||l.paused?n?(_.next=n,n=_):(n=_,s=_,l.saturated()):(o++,e.call(r,_.value,_.worked))}function B(H){H&&i.release(H);var q=n;q?l.paused?o--:(s===n&&(s=null),n=q.next,q.next=null,e.call(r,q.value,q.worked),s===null&&l.empty()):--o===0&&l.drain()}function S(){n=null,s=null,l.drain=Es}function x(){n=null,s=null,l.drain(),l.drain=Es}function F(H){a=H}}function Es(){}function rQe(){this.value=null,this.callback=Es,this.next=null,this.release=Es,this.context=null,this.errorHandler=null;var r=this;this.worked=function(t,i){var n=r.callback,s=r.errorHandler,o=r.value;r.value=null,r.callback=Es,r.errorHandler&&s(t,o),n.call(r.context,t,i),r.release(r)}}function iQe(r,e,t){typeof r=="function"&&(t=e,e=r,r=null);function i(u,g){e.call(this,u).then(function(h){g(null,h)},g)}var n=S4(r,i,t),s=n.push,o=n.unshift;return n.push=a,n.unshift=l,n.drained=c,n;function a(u){var g=new Promise(function(h,p){s(u,function(d,m){if(d){p(d);return}h(m)})});return g.catch(Es),g}function l(u){var g=new Promise(function(h,p){o(u,function(d,m){if(d){p(d);return}h(m)})});return g.catch(Es),g}function c(){var u=n.drain,g=new Promise(function(h){n.drain=function(){u(),h()}});return g}}vx.exports=S4;vx.exports.promise=iQe});var lw=I(jo=>{"use strict";Object.defineProperty(jo,"__esModule",{value:!0});jo.joinPathSegments=jo.replacePathSegmentSeparator=jo.isAppliedFilter=jo.isFatalError=void 0;function nQe(r,e){return r.errorFilter===null?!0:!r.errorFilter(e)}jo.isFatalError=nQe;function sQe(r,e){return r===null||r(e)}jo.isAppliedFilter=sQe;function oQe(r,e){return r.split(/[/\\]/).join(e)}jo.replacePathSegmentSeparator=oQe;function aQe(r,e,t){return r===""?e:r.endsWith(t)?r+e:r+t+e}jo.joinPathSegments=aQe});var kx=I(xx=>{"use strict";Object.defineProperty(xx,"__esModule",{value:!0});var AQe=lw(),Px=class{constructor(e,t){this._root=e,this._settings=t,this._root=AQe.replacePathSegmentSeparator(e,t.pathSegmentSeparator)}};xx.default=Px});var Fx=I(Rx=>{"use strict";Object.defineProperty(Rx,"__esModule",{value:!0});var lQe=J("events"),cQe=Aw(),uQe=v4(),cw=lw(),gQe=kx(),Dx=class extends gQe.default{constructor(e,t){super(e,t),this._settings=t,this._scandir=cQe.scandir,this._emitter=new lQe.EventEmitter,this._queue=uQe(this._worker.bind(this),this._settings.concurrency),this._isFatalError=!1,this._isDestroyed=!1,this._queue.drain=()=>{this._isFatalError||this._emitter.emit("end")}}read(){return this._isFatalError=!1,this._isDestroyed=!1,setImmediate(()=>{this._pushToQueue(this._root,this._settings.basePath)}),this._emitter}get isDestroyed(){return this._isDestroyed}destroy(){if(this._isDestroyed)throw new Error("The reader is already destroyed");this._isDestroyed=!0,this._queue.killAndDrain()}onEntry(e){this._emitter.on("entry",e)}onError(e){this._emitter.once("error",e)}onEnd(e){this._emitter.once("end",e)}_pushToQueue(e,t){let i={directory:e,base:t};this._queue.push(i,n=>{n!==null&&this._handleError(n)})}_worker(e,t){this._scandir(e.directory,this._settings.fsScandirSettings,(i,n)=>{if(i!==null){t(i,void 0);return}for(let s of n)this._handleEntry(s,e.base);t(null,void 0)})}_handleError(e){this._isDestroyed||!cw.isFatalError(this._settings,e)||(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,t){if(this._isDestroyed||this._isFatalError)return;let i=e.path;t!==void 0&&(e.path=cw.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),cw.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&cw.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_emitEntry(e){this._emitter.emit("entry",e)}};Rx.default=Dx});var P4=I(Tx=>{"use strict";Object.defineProperty(Tx,"__esModule",{value:!0});var fQe=Fx(),Nx=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new fQe.default(this._root,this._settings),this._storage=new Set}read(e){this._reader.onError(t=>{hQe(e,t)}),this._reader.onEntry(t=>{this._storage.add(t)}),this._reader.onEnd(()=>{pQe(e,[...this._storage])}),this._reader.read()}};Tx.default=Nx;function hQe(r,e){r(e)}function pQe(r,e){r(null,e)}});var x4=I(Ox=>{"use strict";Object.defineProperty(Ox,"__esModule",{value:!0});var dQe=J("stream"),CQe=Fx(),Lx=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new CQe.default(this._root,this._settings),this._stream=new dQe.Readable({objectMode:!0,read:()=>{},destroy:()=>{this._reader.isDestroyed||this._reader.destroy()}})}read(){return this._reader.onError(e=>{this._stream.emit("error",e)}),this._reader.onEntry(e=>{this._stream.push(e)}),this._reader.onEnd(()=>{this._stream.push(null)}),this._reader.read(),this._stream}};Ox.default=Lx});var k4=I(Kx=>{"use strict";Object.defineProperty(Kx,"__esModule",{value:!0});var mQe=Aw(),uw=lw(),EQe=kx(),Mx=class extends EQe.default{constructor(){super(...arguments),this._scandir=mQe.scandirSync,this._storage=new Set,this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),[...this._storage]}_pushToQueue(e,t){this._queue.add({directory:e,base:t})}_handleQueue(){for(let e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,t){try{let i=this._scandir(e,this._settings.fsScandirSettings);for(let n of i)this._handleEntry(n,t)}catch(i){this._handleError(i)}}_handleError(e){if(!!uw.isFatalError(this._settings,e))throw e}_handleEntry(e,t){let i=e.path;t!==void 0&&(e.path=uw.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),uw.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&uw.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_pushToStorage(e){this._storage.add(e)}};Kx.default=Mx});var D4=I(Hx=>{"use strict";Object.defineProperty(Hx,"__esModule",{value:!0});var IQe=k4(),Ux=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new IQe.default(this._root,this._settings)}read(){return this._reader.read()}};Hx.default=Ux});var R4=I(Gx=>{"use strict";Object.defineProperty(Gx,"__esModule",{value:!0});var yQe=J("path"),wQe=Aw(),jx=class{constructor(e={}){this._options=e,this.basePath=this._getValue(this._options.basePath,void 0),this.concurrency=this._getValue(this._options.concurrency,Number.POSITIVE_INFINITY),this.deepFilter=this._getValue(this._options.deepFilter,null),this.entryFilter=this._getValue(this._options.entryFilter,null),this.errorFilter=this._getValue(this._options.errorFilter,null),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,yQe.sep),this.fsScandirSettings=new wQe.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return e!=null?e:t}};Gx.default=jx});var qx=I(Go=>{"use strict";Object.defineProperty(Go,"__esModule",{value:!0});Go.Settings=Go.walkStream=Go.walkSync=Go.walk=void 0;var F4=P4(),BQe=x4(),bQe=D4(),Yx=R4();Go.Settings=Yx.default;function QQe(r,e,t){if(typeof e=="function"){new F4.default(r,gw()).read(e);return}new F4.default(r,gw(e)).read(t)}Go.walk=QQe;function SQe(r,e){let t=gw(e);return new bQe.default(r,t).read()}Go.walkSync=SQe;function vQe(r,e){let t=gw(e);return new BQe.default(r,t).read()}Go.walkStream=vQe;function gw(r={}){return r instanceof Yx.default?r:new Yx.default(r)}});var zx=I(Wx=>{"use strict";Object.defineProperty(Wx,"__esModule",{value:!0});var PQe=J("path"),xQe=vc(),N4=Ma(),Jx=class{constructor(e){this._settings=e,this._fsStatSettings=new xQe.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return PQe.resolve(this._settings.cwd,e)}_makeEntry(e,t){let i={name:t,path:t,dirent:N4.fs.createDirentFromStats(t,e)};return this._settings.stats&&(i.stats=e),i}_isFatalError(e){return!N4.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}};Wx.default=Jx});var Zx=I(Xx=>{"use strict";Object.defineProperty(Xx,"__esModule",{value:!0});var kQe=J("stream"),DQe=vc(),RQe=qx(),FQe=zx(),Vx=class extends FQe.default{constructor(){super(...arguments),this._walkStream=RQe.walkStream,this._stat=DQe.stat}dynamic(e,t){return this._walkStream(e,t)}static(e,t){let i=e.map(this._getFullEntryPath,this),n=new kQe.PassThrough({objectMode:!0});n._write=(s,o,a)=>this._getEntry(i[s],e[s],t).then(l=>{l!==null&&t.entryFilter(l)&&n.push(l),s===i.length-1&&n.end(),a()}).catch(a);for(let s=0;s<i.length;s++)n.write(s);return n}_getEntry(e,t,i){return this._getStat(e).then(n=>this._makeEntry(n,t)).catch(n=>{if(i.errorFilter(n))return null;throw n})}_getStat(e){return new Promise((t,i)=>{this._stat(e,this._fsStatSettings,(n,s)=>n===null?t(s):i(n))})}};Xx.default=Vx});var T4=I($x=>{"use strict";Object.defineProperty($x,"__esModule",{value:!0});var Bf=Ma(),_x=class{constructor(e,t,i){this._patterns=e,this._settings=t,this._micromatchOptions=i,this._storage=[],this._fillStorage()}_fillStorage(){let e=Bf.pattern.expandPatternsWithBraceExpansion(this._patterns);for(let t of e){let i=this._getPatternSegments(t),n=this._splitSegmentsIntoSections(i);this._storage.push({complete:n.length<=1,pattern:t,segments:i,sections:n})}}_getPatternSegments(e){return Bf.pattern.getPatternParts(e,this._micromatchOptions).map(i=>Bf.pattern.isDynamicPattern(i,this._settings)?{dynamic:!0,pattern:i,patternRe:Bf.pattern.makeRe(i,this._micromatchOptions)}:{dynamic:!1,pattern:i})}_splitSegmentsIntoSections(e){return Bf.array.splitWhen(e,t=>t.dynamic&&Bf.pattern.hasGlobStar(t.pattern))}};$x.default=_x});var L4=I(tk=>{"use strict";Object.defineProperty(tk,"__esModule",{value:!0});var NQe=T4(),ek=class extends NQe.default{match(e){let t=e.split("/"),i=t.length,n=this._storage.filter(s=>!s.complete||s.segments.length>i);for(let s of n){let o=s.sections[0];if(!s.complete&&i>o.length||t.every((l,c)=>{let u=s.segments[c];return!!(u.dynamic&&u.patternRe.test(l)||!u.dynamic&&u.pattern===l)}))return!0}return!1}};tk.default=ek});var O4=I(ik=>{"use strict";Object.defineProperty(ik,"__esModule",{value:!0});var fw=Ma(),TQe=L4(),rk=class{constructor(e,t){this._settings=e,this._micromatchOptions=t}getFilter(e,t,i){let n=this._getMatcher(t),s=this._getNegativePatternsRe(i);return o=>this._filter(e,o,n,s)}_getMatcher(e){return new TQe.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){let t=e.filter(fw.pattern.isAffectDepthOfReadingPattern);return fw.pattern.convertPatternsToRe(t,this._micromatchOptions)}_filter(e,t,i,n){let s=this._getEntryLevel(e,t.path);if(this._isSkippedByDeep(s)||this._isSkippedSymbolicLink(t))return!1;let o=fw.path.removeLeadingDotSegment(t.path);return this._isSkippedByPositivePatterns(o,i)?!1:this._isSkippedByNegativePatterns(o,n)}_isSkippedByDeep(e){return e>=this._settings.deep}_isSkippedSymbolicLink(e){return!this._settings.followSymbolicLinks&&e.dirent.isSymbolicLink()}_getEntryLevel(e,t){let i=e.split("/").length;return t.split("/").length-(e===""?0:i)}_isSkippedByPositivePatterns(e,t){return!this._settings.baseNameMatch&&!t.match(e)}_isSkippedByNegativePatterns(e,t){return!fw.pattern.matchAny(e,t)}};ik.default=rk});var M4=I(sk=>{"use strict";Object.defineProperty(sk,"__esModule",{value:!0});var _d=Ma(),nk=class{constructor(e,t){this._settings=e,this._micromatchOptions=t,this.index=new Map}getFilter(e,t){let i=_d.pattern.convertPatternsToRe(e,this._micromatchOptions),n=_d.pattern.convertPatternsToRe(t,this._micromatchOptions);return s=>this._filter(s,i,n)}_filter(e,t,i){if(this._settings.unique){if(this._isDuplicateEntry(e))return!1;this._createIndexRecord(e)}if(this._onlyFileFilter(e)||this._onlyDirectoryFilter(e)||this._isSkippedByAbsoluteNegativePatterns(e,i))return!1;let n=this._settings.baseNameMatch?e.name:e.path;return this._isMatchToPatterns(n,t)&&!this._isMatchToPatterns(e.path,i)}_isDuplicateEntry(e){return this.index.has(e.path)}_createIndexRecord(e){this.index.set(e.path,void 0)}_onlyFileFilter(e){return this._settings.onlyFiles&&!e.dirent.isFile()}_onlyDirectoryFilter(e){return this._settings.onlyDirectories&&!e.dirent.isDirectory()}_isSkippedByAbsoluteNegativePatterns(e,t){if(!this._settings.absolute)return!1;let i=_d.path.makeAbsolute(this._settings.cwd,e.path);return this._isMatchToPatterns(i,t)}_isMatchToPatterns(e,t){let i=_d.path.removeLeadingDotSegment(e);return _d.pattern.matchAny(i,t)}};sk.default=nk});var K4=I(ak=>{"use strict";Object.defineProperty(ak,"__esModule",{value:!0});var LQe=Ma(),ok=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return LQe.errno.isEnoentCodeError(e)||this._settings.suppressErrors}};ak.default=ok});var H4=I(lk=>{"use strict";Object.defineProperty(lk,"__esModule",{value:!0});var U4=Ma(),Ak=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let t=e.path;return this._settings.absolute&&(t=U4.path.makeAbsolute(this._settings.cwd,t),t=U4.path.unixify(t)),this._settings.markDirectories&&e.dirent.isDirectory()&&(t+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:t}):t}};lk.default=Ak});var hw=I(uk=>{"use strict";Object.defineProperty(uk,"__esModule",{value:!0});var OQe=J("path"),MQe=O4(),KQe=M4(),UQe=K4(),HQe=H4(),ck=class{constructor(e){this._settings=e,this.errorFilter=new UQe.default(this._settings),this.entryFilter=new KQe.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new MQe.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new HQe.default(this._settings)}_getRootDirectory(e){return OQe.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){let t=e.base==="."?"":e.base;return{basePath:t,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(t,e.positive,e.negative),entryFilter:this.entryFilter.getFilter(e.positive,e.negative),errorFilter:this.errorFilter.getFilter(),followSymbolicLinks:this._settings.followSymbolicLinks,fs:this._settings.fs,stats:this._settings.stats,throwErrorOnBrokenSymbolicLink:this._settings.throwErrorOnBrokenSymbolicLink,transform:this.entryTransformer.getTransformer()}}_getMicromatchOptions(){return{dot:this._settings.dot,matchBase:this._settings.baseNameMatch,nobrace:!this._settings.braceExpansion,nocase:!this._settings.caseSensitiveMatch,noext:!this._settings.extglob,noglobstar:!this._settings.globstar,posix:!0,strictSlashes:!1}}};uk.default=ck});var j4=I(fk=>{"use strict";Object.defineProperty(fk,"__esModule",{value:!0});var jQe=Zx(),GQe=hw(),gk=class extends GQe.default{constructor(){super(...arguments),this._reader=new jQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e),n=[];return new Promise((s,o)=>{let a=this.api(t,e,i);a.once("error",o),a.on("data",l=>n.push(i.transform(l))),a.once("end",()=>s(n))})}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};fk.default=gk});var G4=I(pk=>{"use strict";Object.defineProperty(pk,"__esModule",{value:!0});var YQe=J("stream"),qQe=Zx(),JQe=hw(),hk=class extends JQe.default{constructor(){super(...arguments),this._reader=new qQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e),n=this.api(t,e,i),s=new YQe.Readable({objectMode:!0,read:()=>{}});return n.once("error",o=>s.emit("error",o)).on("data",o=>s.emit("data",i.transform(o))).once("end",()=>s.emit("end")),s.once("close",()=>n.destroy()),s}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};pk.default=hk});var Y4=I(Ck=>{"use strict";Object.defineProperty(Ck,"__esModule",{value:!0});var WQe=vc(),zQe=qx(),VQe=zx(),dk=class extends VQe.default{constructor(){super(...arguments),this._walkSync=zQe.walkSync,this._statSync=WQe.statSync}dynamic(e,t){return this._walkSync(e,t)}static(e,t){let i=[];for(let n of e){let s=this._getFullEntryPath(n),o=this._getEntry(s,n,t);o===null||!t.entryFilter(o)||i.push(o)}return i}_getEntry(e,t,i){try{let n=this._getStat(e);return this._makeEntry(n,t)}catch(n){if(i.errorFilter(n))return null;throw n}}_getStat(e){return this._statSync(e,this._fsStatSettings)}};Ck.default=dk});var q4=I(Ek=>{"use strict";Object.defineProperty(Ek,"__esModule",{value:!0});var XQe=Y4(),ZQe=hw(),mk=class extends ZQe.default{constructor(){super(...arguments),this._reader=new XQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e);return this.api(t,e,i).map(i.transform)}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};Ek.default=mk});var J4=I($d=>{"use strict";Object.defineProperty($d,"__esModule",{value:!0});var bf=J("fs"),_Qe=J("os"),$Qe=_Qe.cpus().length;$d.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:bf.lstat,lstatSync:bf.lstatSync,stat:bf.stat,statSync:bf.statSync,readdir:bf.readdir,readdirSync:bf.readdirSync};var Ik=class{constructor(e={}){this._options=e,this.absolute=this._getValue(this._options.absolute,!1),this.baseNameMatch=this._getValue(this._options.baseNameMatch,!1),this.braceExpansion=this._getValue(this._options.braceExpansion,!0),this.caseSensitiveMatch=this._getValue(this._options.caseSensitiveMatch,!0),this.concurrency=this._getValue(this._options.concurrency,$Qe),this.cwd=this._getValue(this._options.cwd,process.cwd()),this.deep=this._getValue(this._options.deep,1/0),this.dot=this._getValue(this._options.dot,!1),this.extglob=this._getValue(this._options.extglob,!0),this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!0),this.fs=this._getFileSystemMethods(this._options.fs),this.globstar=this._getValue(this._options.globstar,!0),this.ignore=this._getValue(this._options.ignore,[]),this.markDirectories=this._getValue(this._options.markDirectories,!1),this.objectMode=this._getValue(this._options.objectMode,!1),this.onlyDirectories=this._getValue(this._options.onlyDirectories,!1),this.onlyFiles=this._getValue(this._options.onlyFiles,!0),this.stats=this._getValue(this._options.stats,!1),this.suppressErrors=this._getValue(this._options.suppressErrors,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!1),this.unique=this._getValue(this._options.unique,!0),this.onlyDirectories&&(this.onlyFiles=!1),this.stats&&(this.objectMode=!0)}_getValue(e,t){return e===void 0?t:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},$d.DEFAULT_FILE_SYSTEM_ADAPTER),e)}};$d.default=Ik});var pw=I((Grt,z4)=>{"use strict";var W4=_W(),eSe=j4(),tSe=G4(),rSe=q4(),yk=J4(),Pc=Ma();async function wk(r,e){Qf(r);let t=Bk(r,eSe.default,e),i=await Promise.all(t);return Pc.array.flatten(i)}(function(r){function e(o,a){Qf(o);let l=Bk(o,rSe.default,a);return Pc.array.flatten(l)}r.sync=e;function t(o,a){Qf(o);let l=Bk(o,tSe.default,a);return Pc.stream.merge(l)}r.stream=t;function i(o,a){Qf(o);let l=[].concat(o),c=new yk.default(a);return W4.generate(l,c)}r.generateTasks=i;function n(o,a){Qf(o);let l=new yk.default(a);return Pc.pattern.isDynamicPattern(o,l)}r.isDynamicPattern=n;function s(o){return Qf(o),Pc.path.escape(o)}r.escapePath=s})(wk||(wk={}));function Bk(r,e,t){let i=[].concat(r),n=new yk.default(t),s=W4.generate(i,n),o=new e(n);return s.map(o.read,o)}function Qf(r){if(![].concat(r).every(i=>Pc.string.isString(i)&&!Pc.string.isEmpty(i)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}z4.exports=wk});var X4=I(xc=>{"use strict";var{promisify:iSe}=J("util"),V4=J("fs");async function bk(r,e,t){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);try{return(await iSe(V4[r])(t))[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}function Qk(r,e,t){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);try{return V4[r](t)[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}xc.isFile=bk.bind(null,"stat","isFile");xc.isDirectory=bk.bind(null,"stat","isDirectory");xc.isSymlink=bk.bind(null,"lstat","isSymbolicLink");xc.isFileSync=Qk.bind(null,"statSync","isFile");xc.isDirectorySync=Qk.bind(null,"statSync","isDirectory");xc.isSymlinkSync=Qk.bind(null,"lstatSync","isSymbolicLink")});var t8=I((qrt,Sk)=>{"use strict";var kc=J("path"),Z4=X4(),_4=r=>r.length>1?`{${r.join(",")}}`:r[0],$4=(r,e)=>{let t=r[0]==="!"?r.slice(1):r;return kc.isAbsolute(t)?t:kc.join(e,t)},nSe=(r,e)=>kc.extname(r)?`**/${r}`:`**/${r}.${_4(e)}`,e8=(r,e)=>{if(e.files&&!Array.isArray(e.files))throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof e.files}\``);if(e.extensions&&!Array.isArray(e.extensions))throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof e.extensions}\``);return e.files&&e.extensions?e.files.map(t=>kc.posix.join(r,nSe(t,e.extensions))):e.files?e.files.map(t=>kc.posix.join(r,`**/${t}`)):e.extensions?[kc.posix.join(r,`**/*.${_4(e.extensions)}`)]:[kc.posix.join(r,"**")]};Sk.exports=async(r,e)=>{if(e={cwd:process.cwd(),...e},typeof e.cwd!="string")throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof e.cwd}\``);let t=await Promise.all([].concat(r).map(async i=>await Z4.isDirectory($4(i,e.cwd))?e8(i,e):i));return[].concat.apply([],t)};Sk.exports.sync=(r,e)=>{if(e={cwd:process.cwd(),...e},typeof e.cwd!="string")throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof e.cwd}\``);let t=[].concat(r).map(i=>Z4.isDirectorySync($4(i,e.cwd))?e8(i,e):i);return[].concat.apply([],t)}});var l8=I((Jrt,A8)=>{function r8(r){return Array.isArray(r)?r:[r]}var o8="",i8=" ",vk="\\",sSe=/^\s+$/,oSe=/^\\!/,aSe=/^\\#/,ASe=/\r?\n/g,lSe=/^\.*\/|^\.+$/,Pk="/",n8=typeof Symbol<"u"?Symbol.for("node-ignore"):"node-ignore",cSe=(r,e,t)=>Object.defineProperty(r,e,{value:t}),uSe=/([0-z])-([0-z])/g,gSe=r=>r.replace(uSe,(e,t,i)=>t.charCodeAt(0)<=i.charCodeAt(0)?e:o8),fSe=r=>{let{length:e}=r;return r.slice(0,e-e%2)},hSe=[[/\\?\s+$/,r=>r.indexOf("\\")===0?i8:o8],[/\\\s/g,()=>i8],[/[\\$.|*+(){^]/g,r=>`\\${r}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(r,e,t)=>e+6<t.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)\\\*(?=.+)/g,(r,e)=>`${e}[^\\/]*`],[/\\\\\\(?=[$.|*+(){^])/g,()=>vk],[/\\\\/g,()=>vk],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(r,e,t,i,n)=>e===vk?`\\[${t}${fSe(i)}${n}`:n==="]"&&i.length%2===0?`[${gSe(t)}${i}]`:"[]"],[/(?:[^*])$/,r=>/\/$/.test(r)?`${r}$`:`${r}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(r,e)=>`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`]],s8=Object.create(null),pSe=(r,e)=>{let t=s8[r];return t||(t=hSe.reduce((i,n)=>i.replace(n[0],n[1].bind(r)),r),s8[r]=t),e?new RegExp(t,"i"):new RegExp(t)},Dk=r=>typeof r=="string",dSe=r=>r&&Dk(r)&&!sSe.test(r)&&r.indexOf("#")!==0,CSe=r=>r.split(ASe),xk=class{constructor(e,t,i,n){this.origin=e,this.pattern=t,this.negative=i,this.regex=n}},mSe=(r,e)=>{let t=r,i=!1;r.indexOf("!")===0&&(i=!0,r=r.substr(1)),r=r.replace(oSe,"!").replace(aSe,"#");let n=pSe(r,e);return new xk(t,r,i,n)},ESe=(r,e)=>{throw new e(r)},Ua=(r,e,t)=>Dk(r)?r?Ua.isNotRelative(r)?t(`path should be a \`path.relative()\`d string, but got "${e}"`,RangeError):!0:t("path must not be empty",TypeError):t(`path must be a string, but got \`${e}\``,TypeError),a8=r=>lSe.test(r);Ua.isNotRelative=a8;Ua.convert=r=>r;var kk=class{constructor({ignorecase:e=!0}={}){cSe(this,n8,!0),this._rules=[],this._ignorecase=e,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[n8]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(dSe(e)){let t=mSe(e,this._ignorecase);this._added=!0,this._rules.push(t)}}add(e){return this._added=!1,r8(Dk(e)?CSe(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,t){let i=!1,n=!1;return this._rules.forEach(s=>{let{negative:o}=s;if(n===o&&i!==n||o&&!i&&!n&&!t)return;s.regex.test(e)&&(i=!o,n=o)}),{ignored:i,unignored:n}}_test(e,t,i,n){let s=e&&Ua.convert(e);return Ua(s,e,ESe),this._t(s,t,i,n)}_t(e,t,i,n){if(e in t)return t[e];if(n||(n=e.split(Pk)),n.pop(),!n.length)return t[e]=this._testOne(e,i);let s=this._t(n.join(Pk)+Pk,t,i,n);return t[e]=s.ignored?s:this._testOne(e,i)}ignores(e){return this._test(e,this._ignoreCache,!1).ignored}createFilter(){return e=>!this.ignores(e)}filter(e){return r8(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},dw=r=>new kk(r),ISe=()=>!1,ySe=r=>Ua(r&&Ua.convert(r),r,ISe);dw.isPathValid=ySe;dw.default=dw;A8.exports=dw;if(typeof process<"u"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let r=t=>/^\\\\\?\\/.test(t)||/["<>|\u0000-\u001F]+/u.test(t)?t:t.replace(/\\/g,"/");Ua.convert=r;let e=/^[a-z]:\//i;Ua.isNotRelative=t=>e.test(t)||a8(t)}});var u8=I((Wrt,c8)=>{"use strict";c8.exports=r=>{let e=/^\\\\\?\\/.test(r),t=/[^\u0000-\u0080]+/.test(r);return e||t?r:r.replace(/\\/g,"/")}});var m8=I((zrt,Rk)=>{"use strict";var{promisify:wSe}=J("util"),g8=J("fs"),Ha=J("path"),f8=pw(),BSe=l8(),eC=u8(),h8=["**/node_modules/**","**/flow-typed/**","**/coverage/**","**/.git"],bSe=wSe(g8.readFile),QSe=r=>e=>e.startsWith("!")?"!"+Ha.posix.join(r,e.slice(1)):Ha.posix.join(r,e),SSe=(r,e)=>{let t=eC(Ha.relative(e.cwd,Ha.dirname(e.fileName)));return r.split(/\r?\n/).filter(Boolean).filter(i=>!i.startsWith("#")).map(QSe(t))},p8=r=>{let e=BSe();for(let t of r)e.add(SSe(t.content,{cwd:t.cwd,fileName:t.filePath}));return e},vSe=(r,e)=>{if(r=eC(r),Ha.isAbsolute(e)){if(eC(e).startsWith(r))return e;throw new Error(`Path ${e} is not in cwd ${r}`)}return Ha.join(r,e)},d8=(r,e)=>t=>r.ignores(eC(Ha.relative(e,vSe(e,t.path||t)))),PSe=async(r,e)=>{let t=Ha.join(e,r),i=await bSe(t,"utf8");return{cwd:e,filePath:t,content:i}},xSe=(r,e)=>{let t=Ha.join(e,r),i=g8.readFileSync(t,"utf8");return{cwd:e,filePath:t,content:i}},C8=({ignore:r=[],cwd:e=eC(process.cwd())}={})=>({ignore:r,cwd:e});Rk.exports=async r=>{r=C8(r);let e=await f8("**/.gitignore",{ignore:h8.concat(r.ignore),cwd:r.cwd}),t=await Promise.all(e.map(n=>PSe(n,r.cwd))),i=p8(t);return d8(i,r.cwd)};Rk.exports.sync=r=>{r=C8(r);let t=f8.sync("**/.gitignore",{ignore:h8.concat(r.ignore),cwd:r.cwd}).map(n=>xSe(n,r.cwd)),i=p8(t);return d8(i,r.cwd)}});var I8=I((Vrt,E8)=>{"use strict";var{Transform:kSe}=J("stream"),Cw=class extends kSe{constructor(){super({objectMode:!0})}},Fk=class extends Cw{constructor(e){super(),this._filter=e}_transform(e,t,i){this._filter(e)&&this.push(e),i()}},Nk=class extends Cw{constructor(){super(),this._pushed=new Set}_transform(e,t,i){this._pushed.has(e)||(this.push(e),this._pushed.add(e)),i()}};E8.exports={FilterStream:Fk,UniqueStream:Nk}});var Mk=I((Xrt,Dc)=>{"use strict";var w8=J("fs"),mw=yW(),DSe=sx(),Ew=pw(),Iw=t8(),Tk=m8(),{FilterStream:RSe,UniqueStream:FSe}=I8(),B8=()=>!1,y8=r=>r[0]==="!",NSe=r=>{if(!r.every(e=>typeof e=="string"))throw new TypeError("Patterns must be a string or an array of strings")},TSe=(r={})=>{if(!r.cwd)return;let e;try{e=w8.statSync(r.cwd)}catch{return}if(!e.isDirectory())throw new Error("The `cwd` option must be a path to a directory")},LSe=r=>r.stats instanceof w8.Stats?r.path:r,yw=(r,e)=>{r=mw([].concat(r)),NSe(r),TSe(e);let t=[];e={ignore:[],expandDirectories:!0,...e};for(let[i,n]of r.entries()){if(y8(n))continue;let s=r.slice(i).filter(a=>y8(a)).map(a=>a.slice(1)),o={...e,ignore:e.ignore.concat(s)};t.push({pattern:n,options:o})}return t},OSe=(r,e)=>{let t={};return r.options.cwd&&(t.cwd=r.options.cwd),Array.isArray(r.options.expandDirectories)?t={...t,files:r.options.expandDirectories}:typeof r.options.expandDirectories=="object"&&(t={...t,...r.options.expandDirectories}),e(r.pattern,t)},Lk=(r,e)=>r.options.expandDirectories?OSe(r,e):[r.pattern],b8=r=>r&&r.gitignore?Tk.sync({cwd:r.cwd,ignore:r.ignore}):B8,Ok=r=>e=>{let{options:t}=r;return t.ignore&&Array.isArray(t.ignore)&&t.expandDirectories&&(t.ignore=Iw.sync(t.ignore)),{pattern:e,options:t}};Dc.exports=async(r,e)=>{let t=yw(r,e),i=async()=>e&&e.gitignore?Tk({cwd:e.cwd,ignore:e.ignore}):B8,n=async()=>{let l=await Promise.all(t.map(async c=>{let u=await Lk(c,Iw);return Promise.all(u.map(Ok(c)))}));return mw(...l)},[s,o]=await Promise.all([i(),n()]),a=await Promise.all(o.map(l=>Ew(l.pattern,l.options)));return mw(...a).filter(l=>!s(LSe(l)))};Dc.exports.sync=(r,e)=>{let t=yw(r,e),i=[];for(let o of t){let a=Lk(o,Iw.sync).map(Ok(o));i.push(...a)}let n=b8(e),s=[];for(let o of i)s=mw(s,Ew.sync(o.pattern,o.options));return s.filter(o=>!n(o))};Dc.exports.stream=(r,e)=>{let t=yw(r,e),i=[];for(let a of t){let l=Lk(a,Iw.sync).map(Ok(a));i.push(...l)}let n=b8(e),s=new RSe(a=>!n(a)),o=new FSe;return DSe(i.map(a=>Ew.stream(a.pattern,a.options))).pipe(s).pipe(o)};Dc.exports.generateGlobTasks=yw;Dc.exports.hasMagic=(r,e)=>[].concat(r).some(t=>Ew.isDynamicPattern(t,e));Dc.exports.gitignore=Tk});var vn=I((fit,K8)=>{function XSe(r){var e=typeof r;return r!=null&&(e=="object"||e=="function")}K8.exports=XSe});var Wk=I((hit,U8)=>{var ZSe=typeof global=="object"&&global&&global.Object===Object&&global;U8.exports=ZSe});var Is=I((pit,H8)=>{var _Se=Wk(),$Se=typeof self=="object"&&self&&self.Object===Object&&self,eve=_Se||$Se||Function("return this")();H8.exports=eve});var G8=I((dit,j8)=>{var tve=Is(),rve=function(){return tve.Date.now()};j8.exports=rve});var q8=I((Cit,Y8)=>{var ive=/\s/;function nve(r){for(var e=r.length;e--&&ive.test(r.charAt(e)););return e}Y8.exports=nve});var W8=I((mit,J8)=>{var sve=q8(),ove=/^\s+/;function ave(r){return r&&r.slice(0,sve(r)+1).replace(ove,"")}J8.exports=ave});var Nc=I((Eit,z8)=>{var Ave=Is(),lve=Ave.Symbol;z8.exports=lve});var _8=I((Iit,Z8)=>{var V8=Nc(),X8=Object.prototype,cve=X8.hasOwnProperty,uve=X8.toString,gC=V8?V8.toStringTag:void 0;function gve(r){var e=cve.call(r,gC),t=r[gC];try{r[gC]=void 0;var i=!0}catch{}var n=uve.call(r);return i&&(e?r[gC]=t:delete r[gC]),n}Z8.exports=gve});var ez=I((yit,$8)=>{var fve=Object.prototype,hve=fve.toString;function pve(r){return hve.call(r)}$8.exports=pve});var Tc=I((wit,iz)=>{var tz=Nc(),dve=_8(),Cve=ez(),mve="[object Null]",Eve="[object Undefined]",rz=tz?tz.toStringTag:void 0;function Ive(r){return r==null?r===void 0?Eve:mve:rz&&rz in Object(r)?dve(r):Cve(r)}iz.exports=Ive});var Jo=I((Bit,nz)=>{function yve(r){return r!=null&&typeof r=="object"}nz.exports=yve});var fC=I((bit,sz)=>{var wve=Tc(),Bve=Jo(),bve="[object Symbol]";function Qve(r){return typeof r=="symbol"||Bve(r)&&wve(r)==bve}sz.exports=Qve});var lz=I((Qit,Az)=>{var Sve=W8(),oz=vn(),vve=fC(),az=0/0,Pve=/^[-+]0x[0-9a-f]+$/i,xve=/^0b[01]+$/i,kve=/^0o[0-7]+$/i,Dve=parseInt;function Rve(r){if(typeof r=="number")return r;if(vve(r))return az;if(oz(r)){var e=typeof r.valueOf=="function"?r.valueOf():r;r=oz(e)?e+"":e}if(typeof r!="string")return r===0?r:+r;r=Sve(r);var t=xve.test(r);return t||kve.test(r)?Dve(r.slice(2),t?2:8):Pve.test(r)?az:+r}Az.exports=Rve});var gz=I((Sit,uz)=>{var Fve=vn(),zk=G8(),cz=lz(),Nve="Expected a function",Tve=Math.max,Lve=Math.min;function Ove(r,e,t){var i,n,s,o,a,l,c=0,u=!1,g=!1,h=!0;if(typeof r!="function")throw new TypeError(Nve);e=cz(e)||0,Fve(t)&&(u=!!t.leading,g="maxWait"in t,s=g?Tve(cz(t.maxWait)||0,e):s,h="trailing"in t?!!t.trailing:h);function p(q){var _=i,X=n;return i=n=void 0,c=q,o=r.apply(X,_),o}function d(q){return c=q,a=setTimeout(B,e),u?p(q):o}function m(q){var _=q-l,X=q-c,W=e-_;return g?Lve(W,s-X):W}function y(q){var _=q-l,X=q-c;return l===void 0||_>=e||_<0||g&&X>=s}function B(){var q=zk();if(y(q))return S(q);a=setTimeout(B,m(q))}function S(q){return a=void 0,h&&i?p(q):(i=n=void 0,o)}function x(){a!==void 0&&clearTimeout(a),c=0,i=l=n=a=void 0}function F(){return a===void 0?o:S(zk())}function H(){var q=zk(),_=y(q);if(i=arguments,n=this,l=q,_){if(a===void 0)return d(l);if(g)return clearTimeout(a),a=setTimeout(B,e),p(l)}return a===void 0&&(a=setTimeout(B,e)),o}return H.cancel=x,H.flush=F,H}uz.exports=Ove});var hz=I((vit,fz)=>{var Mve=gz(),Kve=vn(),Uve="Expected a function";function Hve(r,e,t){var i=!0,n=!0;if(typeof r!="function")throw new TypeError(Uve);return Kve(t)&&(i="leading"in t?!!t.leading:i,n="trailing"in t?!!t.trailing:n),Mve(r,e,{leading:i,maxWait:e,trailing:n})}fz.exports=Hve});var Ya=I((Ga,Gw)=>{"use strict";Object.defineProperty(Ga,"__esModule",{value:!0});var bz=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];function tPe(r){return bz.includes(r)}var rPe=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","FormData","URLSearchParams","HTMLElement",...bz];function iPe(r){return rPe.includes(r)}var nPe=["null","undefined","string","number","bigint","boolean","symbol"];function sPe(r){return nPe.includes(r)}function Lf(r){return e=>typeof e===r}var{toString:Qz}=Object.prototype,mC=r=>{let e=Qz.call(r).slice(8,-1);if(/HTML\w+Element/.test(e)&&V.domElement(r))return"HTMLElement";if(iPe(e))return e},ar=r=>e=>mC(e)===r;function V(r){if(r===null)return"null";switch(typeof r){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"function":return"Function";case"bigint":return"bigint";case"symbol":return"symbol";default:}if(V.observable(r))return"Observable";if(V.array(r))return"Array";if(V.buffer(r))return"Buffer";let e=mC(r);if(e)return e;if(r instanceof String||r instanceof Boolean||r instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}V.undefined=Lf("undefined");V.string=Lf("string");var oPe=Lf("number");V.number=r=>oPe(r)&&!V.nan(r);V.bigint=Lf("bigint");V.function_=Lf("function");V.null_=r=>r===null;V.class_=r=>V.function_(r)&&r.toString().startsWith("class ");V.boolean=r=>r===!0||r===!1;V.symbol=Lf("symbol");V.numericString=r=>V.string(r)&&!V.emptyStringOrWhitespace(r)&&!Number.isNaN(Number(r));V.array=(r,e)=>Array.isArray(r)?V.function_(e)?r.every(e):!0:!1;V.buffer=r=>{var e,t,i,n;return(n=(i=(t=(e=r)===null||e===void 0?void 0:e.constructor)===null||t===void 0?void 0:t.isBuffer)===null||i===void 0?void 0:i.call(t,r))!==null&&n!==void 0?n:!1};V.nullOrUndefined=r=>V.null_(r)||V.undefined(r);V.object=r=>!V.null_(r)&&(typeof r=="object"||V.function_(r));V.iterable=r=>{var e;return V.function_((e=r)===null||e===void 0?void 0:e[Symbol.iterator])};V.asyncIterable=r=>{var e;return V.function_((e=r)===null||e===void 0?void 0:e[Symbol.asyncIterator])};V.generator=r=>V.iterable(r)&&V.function_(r.next)&&V.function_(r.throw);V.asyncGenerator=r=>V.asyncIterable(r)&&V.function_(r.next)&&V.function_(r.throw);V.nativePromise=r=>ar("Promise")(r);var aPe=r=>{var e,t;return V.function_((e=r)===null||e===void 0?void 0:e.then)&&V.function_((t=r)===null||t===void 0?void 0:t.catch)};V.promise=r=>V.nativePromise(r)||aPe(r);V.generatorFunction=ar("GeneratorFunction");V.asyncGeneratorFunction=r=>mC(r)==="AsyncGeneratorFunction";V.asyncFunction=r=>mC(r)==="AsyncFunction";V.boundFunction=r=>V.function_(r)&&!r.hasOwnProperty("prototype");V.regExp=ar("RegExp");V.date=ar("Date");V.error=ar("Error");V.map=r=>ar("Map")(r);V.set=r=>ar("Set")(r);V.weakMap=r=>ar("WeakMap")(r);V.weakSet=r=>ar("WeakSet")(r);V.int8Array=ar("Int8Array");V.uint8Array=ar("Uint8Array");V.uint8ClampedArray=ar("Uint8ClampedArray");V.int16Array=ar("Int16Array");V.uint16Array=ar("Uint16Array");V.int32Array=ar("Int32Array");V.uint32Array=ar("Uint32Array");V.float32Array=ar("Float32Array");V.float64Array=ar("Float64Array");V.bigInt64Array=ar("BigInt64Array");V.bigUint64Array=ar("BigUint64Array");V.arrayBuffer=ar("ArrayBuffer");V.sharedArrayBuffer=ar("SharedArrayBuffer");V.dataView=ar("DataView");V.directInstanceOf=(r,e)=>Object.getPrototypeOf(r)===e.prototype;V.urlInstance=r=>ar("URL")(r);V.urlString=r=>{if(!V.string(r))return!1;try{return new URL(r),!0}catch{return!1}};V.truthy=r=>Boolean(r);V.falsy=r=>!r;V.nan=r=>Number.isNaN(r);V.primitive=r=>V.null_(r)||sPe(typeof r);V.integer=r=>Number.isInteger(r);V.safeInteger=r=>Number.isSafeInteger(r);V.plainObject=r=>{if(Qz.call(r)!=="[object Object]")return!1;let e=Object.getPrototypeOf(r);return e===null||e===Object.getPrototypeOf({})};V.typedArray=r=>tPe(mC(r));var APe=r=>V.safeInteger(r)&&r>=0;V.arrayLike=r=>!V.nullOrUndefined(r)&&!V.function_(r)&&APe(r.length);V.inRange=(r,e)=>{if(V.number(e))return r>=Math.min(0,e)&&r<=Math.max(e,0);if(V.array(e)&&e.length===2)return r>=Math.min(...e)&&r<=Math.max(...e);throw new TypeError(`Invalid range: ${JSON.stringify(e)}`)};var lPe=1,cPe=["innerHTML","ownerDocument","style","attributes","nodeValue"];V.domElement=r=>V.object(r)&&r.nodeType===lPe&&V.string(r.nodeName)&&!V.plainObject(r)&&cPe.every(e=>e in r);V.observable=r=>{var e,t,i,n;return r?r===((t=(e=r)[Symbol.observable])===null||t===void 0?void 0:t.call(e))||r===((n=(i=r)["@@observable"])===null||n===void 0?void 0:n.call(i)):!1};V.nodeStream=r=>V.object(r)&&V.function_(r.pipe)&&!V.observable(r);V.infinite=r=>r===1/0||r===-1/0;var Sz=r=>e=>V.integer(e)&&Math.abs(e%2)===r;V.evenInteger=Sz(0);V.oddInteger=Sz(1);V.emptyArray=r=>V.array(r)&&r.length===0;V.nonEmptyArray=r=>V.array(r)&&r.length>0;V.emptyString=r=>V.string(r)&&r.length===0;V.nonEmptyString=r=>V.string(r)&&r.length>0;var uPe=r=>V.string(r)&&!/\S/.test(r);V.emptyStringOrWhitespace=r=>V.emptyString(r)||uPe(r);V.emptyObject=r=>V.object(r)&&!V.map(r)&&!V.set(r)&&Object.keys(r).length===0;V.nonEmptyObject=r=>V.object(r)&&!V.map(r)&&!V.set(r)&&Object.keys(r).length>0;V.emptySet=r=>V.set(r)&&r.size===0;V.nonEmptySet=r=>V.set(r)&&r.size>0;V.emptyMap=r=>V.map(r)&&r.size===0;V.nonEmptyMap=r=>V.map(r)&&r.size>0;V.propertyKey=r=>V.any([V.string,V.number,V.symbol],r);V.formData=r=>ar("FormData")(r);V.urlSearchParams=r=>ar("URLSearchParams")(r);var vz=(r,e,t)=>{if(!V.function_(e))throw new TypeError(`Invalid predicate: ${JSON.stringify(e)}`);if(t.length===0)throw new TypeError("Invalid number of values");return r.call(t,e)};V.any=(r,...e)=>(V.array(r)?r:[r]).some(i=>vz(Array.prototype.some,i,e));V.all=(r,...e)=>vz(Array.prototype.every,r,e);var je=(r,e,t,i={})=>{if(!r){let{multipleValues:n}=i,s=n?`received values of types ${[...new Set(t.map(o=>`\`${V(o)}\``))].join(", ")}`:`received value of type \`${V(t)}\``;throw new TypeError(`Expected value which is \`${e}\`, ${s}.`)}};Ga.assert={undefined:r=>je(V.undefined(r),"undefined",r),string:r=>je(V.string(r),"string",r),number:r=>je(V.number(r),"number",r),bigint:r=>je(V.bigint(r),"bigint",r),function_:r=>je(V.function_(r),"Function",r),null_:r=>je(V.null_(r),"null",r),class_:r=>je(V.class_(r),"Class",r),boolean:r=>je(V.boolean(r),"boolean",r),symbol:r=>je(V.symbol(r),"symbol",r),numericString:r=>je(V.numericString(r),"string with a number",r),array:(r,e)=>{je(V.array(r),"Array",r),e&&r.forEach(e)},buffer:r=>je(V.buffer(r),"Buffer",r),nullOrUndefined:r=>je(V.nullOrUndefined(r),"null or undefined",r),object:r=>je(V.object(r),"Object",r),iterable:r=>je(V.iterable(r),"Iterable",r),asyncIterable:r=>je(V.asyncIterable(r),"AsyncIterable",r),generator:r=>je(V.generator(r),"Generator",r),asyncGenerator:r=>je(V.asyncGenerator(r),"AsyncGenerator",r),nativePromise:r=>je(V.nativePromise(r),"native Promise",r),promise:r=>je(V.promise(r),"Promise",r),generatorFunction:r=>je(V.generatorFunction(r),"GeneratorFunction",r),asyncGeneratorFunction:r=>je(V.asyncGeneratorFunction(r),"AsyncGeneratorFunction",r),asyncFunction:r=>je(V.asyncFunction(r),"AsyncFunction",r),boundFunction:r=>je(V.boundFunction(r),"Function",r),regExp:r=>je(V.regExp(r),"RegExp",r),date:r=>je(V.date(r),"Date",r),error:r=>je(V.error(r),"Error",r),map:r=>je(V.map(r),"Map",r),set:r=>je(V.set(r),"Set",r),weakMap:r=>je(V.weakMap(r),"WeakMap",r),weakSet:r=>je(V.weakSet(r),"WeakSet",r),int8Array:r=>je(V.int8Array(r),"Int8Array",r),uint8Array:r=>je(V.uint8Array(r),"Uint8Array",r),uint8ClampedArray:r=>je(V.uint8ClampedArray(r),"Uint8ClampedArray",r),int16Array:r=>je(V.int16Array(r),"Int16Array",r),uint16Array:r=>je(V.uint16Array(r),"Uint16Array",r),int32Array:r=>je(V.int32Array(r),"Int32Array",r),uint32Array:r=>je(V.uint32Array(r),"Uint32Array",r),float32Array:r=>je(V.float32Array(r),"Float32Array",r),float64Array:r=>je(V.float64Array(r),"Float64Array",r),bigInt64Array:r=>je(V.bigInt64Array(r),"BigInt64Array",r),bigUint64Array:r=>je(V.bigUint64Array(r),"BigUint64Array",r),arrayBuffer:r=>je(V.arrayBuffer(r),"ArrayBuffer",r),sharedArrayBuffer:r=>je(V.sharedArrayBuffer(r),"SharedArrayBuffer",r),dataView:r=>je(V.dataView(r),"DataView",r),urlInstance:r=>je(V.urlInstance(r),"URL",r),urlString:r=>je(V.urlString(r),"string with a URL",r),truthy:r=>je(V.truthy(r),"truthy",r),falsy:r=>je(V.falsy(r),"falsy",r),nan:r=>je(V.nan(r),"NaN",r),primitive:r=>je(V.primitive(r),"primitive",r),integer:r=>je(V.integer(r),"integer",r),safeInteger:r=>je(V.safeInteger(r),"integer",r),plainObject:r=>je(V.plainObject(r),"plain object",r),typedArray:r=>je(V.typedArray(r),"TypedArray",r),arrayLike:r=>je(V.arrayLike(r),"array-like",r),domElement:r=>je(V.domElement(r),"HTMLElement",r),observable:r=>je(V.observable(r),"Observable",r),nodeStream:r=>je(V.nodeStream(r),"Node.js Stream",r),infinite:r=>je(V.infinite(r),"infinite number",r),emptyArray:r=>je(V.emptyArray(r),"empty array",r),nonEmptyArray:r=>je(V.nonEmptyArray(r),"non-empty array",r),emptyString:r=>je(V.emptyString(r),"empty string",r),nonEmptyString:r=>je(V.nonEmptyString(r),"non-empty string",r),emptyStringOrWhitespace:r=>je(V.emptyStringOrWhitespace(r),"empty string or whitespace",r),emptyObject:r=>je(V.emptyObject(r),"empty object",r),nonEmptyObject:r=>je(V.nonEmptyObject(r),"non-empty object",r),emptySet:r=>je(V.emptySet(r),"empty set",r),nonEmptySet:r=>je(V.nonEmptySet(r),"non-empty set",r),emptyMap:r=>je(V.emptyMap(r),"empty map",r),nonEmptyMap:r=>je(V.nonEmptyMap(r),"non-empty map",r),propertyKey:r=>je(V.propertyKey(r),"PropertyKey",r),formData:r=>je(V.formData(r),"FormData",r),urlSearchParams:r=>je(V.urlSearchParams(r),"URLSearchParams",r),evenInteger:r=>je(V.evenInteger(r),"even integer",r),oddInteger:r=>je(V.oddInteger(r),"odd integer",r),directInstanceOf:(r,e)=>je(V.directInstanceOf(r,e),"T",r),inRange:(r,e)=>je(V.inRange(r,e),"in range",r),any:(r,...e)=>je(V.any(r,...e),"predicate returns truthy for any value",e,{multipleValues:!0}),all:(r,...e)=>je(V.all(r,...e),"predicate returns truthy for all values",e,{multipleValues:!0})};Object.defineProperties(V,{class:{value:V.class_},function:{value:V.function_},null:{value:V.null_}});Object.defineProperties(Ga.assert,{class:{value:Ga.assert.class_},function:{value:Ga.assert.function_},null:{value:Ga.assert.null_}});Ga.default=V;Gw.exports=V;Gw.exports.default=V;Gw.exports.assert=Ga.assert});var Pz=I((hnt,dD)=>{"use strict";var Yw=class extends Error{constructor(e){super(e||"Promise was canceled"),this.name="CancelError"}get isCanceled(){return!0}},Of=class{static fn(e){return(...t)=>new Of((i,n,s)=>{t.push(s),e(...t).then(i,n)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((t,i)=>{this._reject=i;let n=a=>{this._isPending=!1,t(a)},s=a=>{this._isPending=!1,i(a)},o=a=>{if(!this._isPending)throw new Error("The `onCancel` handler was attached after the promise settled.");this._cancelHandlers.push(a)};return Object.defineProperties(o,{shouldReject:{get:()=>this._rejectOnCancel,set:a=>{this._rejectOnCancel=a}}}),e(n,s,o)})}then(e,t){return this._promise.then(e,t)}catch(e){return this._promise.catch(e)}finally(e){return this._promise.finally(e)}cancel(e){if(!(!this._isPending||this._isCanceled)){if(this._cancelHandlers.length>0)try{for(let t of this._cancelHandlers)t()}catch(t){this._reject(t)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new Yw(e))}}get isCanceled(){return this._isCanceled}};Object.setPrototypeOf(Of.prototype,Promise.prototype);dD.exports=Of;dD.exports.CancelError=Yw});var xz=I((mD,ED)=>{"use strict";Object.defineProperty(mD,"__esModule",{value:!0});var gPe=J("tls"),CD=(r,e)=>{let t;typeof e=="function"?t={connect:e}:t=e;let i=typeof t.connect=="function",n=typeof t.secureConnect=="function",s=typeof t.close=="function",o=()=>{i&&t.connect(),r instanceof gPe.TLSSocket&&n&&(r.authorized?t.secureConnect():r.authorizationError||r.once("secureConnect",t.secureConnect)),s&&r.once("close",t.close)};r.writable&&!r.connecting?o():r.connecting?r.once("connect",o):r.destroyed&&s&&t.close(r._hadError)};mD.default=CD;ED.exports=CD;ED.exports.default=CD});var kz=I((yD,wD)=>{"use strict";Object.defineProperty(yD,"__esModule",{value:!0});var fPe=xz(),hPe=Number(process.versions.node.split(".")[0]),ID=r=>{let e={start:Date.now(),socket:void 0,lookup:void 0,connect:void 0,secureConnect:void 0,upload:void 0,response:void 0,end:void 0,error:void 0,abort:void 0,phases:{wait:void 0,dns:void 0,tcp:void 0,tls:void 0,request:void 0,firstByte:void 0,download:void 0,total:void 0}};r.timings=e;let t=o=>{let a=o.emit.bind(o);o.emit=(l,...c)=>(l==="error"&&(e.error=Date.now(),e.phases.total=e.error-e.start,o.emit=a),a(l,...c))};t(r),r.prependOnceListener("abort",()=>{e.abort=Date.now(),(!e.response||hPe>=13)&&(e.phases.total=Date.now()-e.start)});let i=o=>{e.socket=Date.now(),e.phases.wait=e.socket-e.start;let a=()=>{e.lookup=Date.now(),e.phases.dns=e.lookup-e.socket};o.prependOnceListener("lookup",a),fPe.default(o,{connect:()=>{e.connect=Date.now(),e.lookup===void 0&&(o.removeListener("lookup",a),e.lookup=e.connect,e.phases.dns=e.lookup-e.socket),e.phases.tcp=e.connect-e.lookup},secureConnect:()=>{e.secureConnect=Date.now(),e.phases.tls=e.secureConnect-e.connect}})};r.socket?i(r.socket):r.prependOnceListener("socket",i);let n=()=>{var o;e.upload=Date.now(),e.phases.request=e.upload-(o=e.secureConnect,o!=null?o:e.connect)};return(()=>typeof r.writableFinished=="boolean"?r.writableFinished:r.finished&&r.outputSize===0&&(!r.socket||r.socket.writableLength===0))()?n():r.prependOnceListener("finish",n),r.prependOnceListener("response",o=>{e.response=Date.now(),e.phases.firstByte=e.response-e.upload,o.timings=e,t(o),o.prependOnceListener("end",()=>{e.end=Date.now(),e.phases.download=e.end-e.response,e.phases.total=e.end-e.start})}),e};yD.default=ID;wD.exports=ID;wD.exports.default=ID});var Oz=I((pnt,QD)=>{"use strict";var{V4MAPPED:pPe,ADDRCONFIG:dPe,ALL:Lz,promises:{Resolver:Dz},lookup:CPe}=J("dns"),{promisify:BD}=J("util"),mPe=J("os"),Mf=Symbol("cacheableLookupCreateConnection"),bD=Symbol("cacheableLookupInstance"),Rz=Symbol("expires"),EPe=typeof Lz=="number",Fz=r=>{if(!(r&&typeof r.createConnection=="function"))throw new Error("Expected an Agent instance as the first argument")},IPe=r=>{for(let e of r)e.family!==6&&(e.address=`::ffff:${e.address}`,e.family=6)},Nz=()=>{let r=!1,e=!1;for(let t of Object.values(mPe.networkInterfaces()))for(let i of t)if(!i.internal&&(i.family==="IPv6"?e=!0:r=!0,r&&e))return{has4:r,has6:e};return{has4:r,has6:e}},yPe=r=>Symbol.iterator in r,Tz={ttl:!0},wPe={all:!0},qw=class{constructor({cache:e=new Map,maxTtl:t=1/0,fallbackDuration:i=3600,errorTtl:n=.15,resolver:s=new Dz,lookup:o=CPe}={}){if(this.maxTtl=t,this.errorTtl=n,this._cache=e,this._resolver=s,this._dnsLookup=BD(o),this._resolver instanceof Dz?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=BD(this._resolver.resolve4.bind(this._resolver)),this._resolve6=BD(this._resolver.resolve6.bind(this._resolver))),this._iface=Nz(),this._pending={},this._nextRemovalTime=!1,this._hostnamesToFallback=new Set,i<1)this._fallback=!1;else{this._fallback=!0;let a=setInterval(()=>{this._hostnamesToFallback.clear()},i*1e3);a.unref&&a.unref()}this.lookup=this.lookup.bind(this),this.lookupAsync=this.lookupAsync.bind(this)}set servers(e){this.clear(),this._resolver.setServers(e)}get servers(){return this._resolver.getServers()}lookup(e,t,i){if(typeof t=="function"?(i=t,t={}):typeof t=="number"&&(t={family:t}),!i)throw new Error("Callback must be a function.");this.lookupAsync(e,t).then(n=>{t.all?i(null,n):i(null,n.address,n.family,n.expires,n.ttl)},i)}async lookupAsync(e,t={}){typeof t=="number"&&(t={family:t});let i=await this.query(e);if(t.family===6){let n=i.filter(s=>s.family===6);t.hints&pPe&&(EPe&&t.hints&Lz||n.length===0)?IPe(i):i=n}else t.family===4&&(i=i.filter(n=>n.family===4));if(t.hints&dPe){let{_iface:n}=this;i=i.filter(s=>s.family===6?n.has6:n.has4)}if(i.length===0){let n=new Error(`cacheableLookup ENOTFOUND ${e}`);throw n.code="ENOTFOUND",n.hostname=e,n}return t.all?i:i[0]}async query(e){let t=await this._cache.get(e);if(!t){let i=this._pending[e];if(i)t=await i;else{let n=this.queryAndCache(e);this._pending[e]=n,t=await n}}return t=t.map(i=>({...i})),t}async _resolve(e){let t=async c=>{try{return await c}catch(u){if(u.code==="ENODATA"||u.code==="ENOTFOUND")return[];throw u}},[i,n]=await Promise.all([this._resolve4(e,Tz),this._resolve6(e,Tz)].map(c=>t(c))),s=0,o=0,a=0,l=Date.now();for(let c of i)c.family=4,c.expires=l+c.ttl*1e3,s=Math.max(s,c.ttl);for(let c of n)c.family=6,c.expires=l+c.ttl*1e3,o=Math.max(o,c.ttl);return i.length>0?n.length>0?a=Math.min(s,o):a=s:a=o,{entries:[...i,...n],cacheTtl:a}}async _lookup(e){try{return{entries:await this._dnsLookup(e,{all:!0}),cacheTtl:0}}catch{return{entries:[],cacheTtl:0}}}async _set(e,t,i){if(this.maxTtl>0&&i>0){i=Math.min(i,this.maxTtl)*1e3,t[Rz]=Date.now()+i;try{await this._cache.set(e,t,i)}catch(n){this.lookupAsync=async()=>{let s=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw s.cause=n,s}}yPe(this._cache)&&this._tick(i)}}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,wPe);try{let t=await this._resolve(e);t.entries.length===0&&this._fallback&&(t=await this._lookup(e),t.entries.length!==0&&this._hostnamesToFallback.add(e));let i=t.entries.length===0?this.errorTtl:t.cacheTtl;return await this._set(e,t.entries,i),delete this._pending[e],t.entries}catch(t){throw delete this._pending[e],t}}_tick(e){let t=this._nextRemovalTime;(!t||e<t)&&(clearTimeout(this._removalTimeout),this._nextRemovalTime=e,this._removalTimeout=setTimeout(()=>{this._nextRemovalTime=!1;let i=1/0,n=Date.now();for(let[s,o]of this._cache){let a=o[Rz];n>=a?this._cache.delete(s):a<i&&(i=a)}i!==1/0&&this._tick(i-n)},e),this._removalTimeout.unref&&this._removalTimeout.unref())}install(e){if(Fz(e),Mf in e)throw new Error("CacheableLookup has been already installed");e[Mf]=e.createConnection,e[bD]=this,e.createConnection=(t,i)=>("lookup"in t||(t.lookup=this.lookup),e[Mf](t,i))}uninstall(e){if(Fz(e),e[Mf]){if(e[bD]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[Mf],delete e[Mf],delete e[bD]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=Nz(),(e.has4&&!this._iface.has4||e.has6&&!this._iface.has6)&&this._cache.clear()}clear(e){if(e){this._cache.delete(e);return}this._cache.clear()}};QD.exports=qw;QD.exports.default=qw});var Uz=I((dnt,SD)=>{"use strict";var BPe=typeof URL>"u"?J("url").URL:URL,bPe="text/plain",QPe="us-ascii",Mz=(r,e)=>e.some(t=>t instanceof RegExp?t.test(r):t===r),SPe=(r,{stripHash:e})=>{let t=r.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!t)throw new Error(`Invalid URL: ${r}`);let i=t[1].split(";"),n=t[2],s=e?"":t[3],o=!1;i[i.length-1]==="base64"&&(i.pop(),o=!0);let a=(i.shift()||"").toLowerCase(),c=[...i.map(u=>{let[g,h=""]=u.split("=").map(p=>p.trim());return g==="charset"&&(h=h.toLowerCase(),h===QPe)?"":`${g}${h?`=${h}`:""}`}).filter(Boolean)];return o&&c.push("base64"),(c.length!==0||a&&a!==bPe)&&c.unshift(a),`data:${c.join(";")},${o?n.trim():n}${s?`#${s}`:""}`},Kz=(r,e)=>{if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},Reflect.has(e,"normalizeHttps"))throw new Error("options.normalizeHttps is renamed to options.forceHttp");if(Reflect.has(e,"normalizeHttp"))throw new Error("options.normalizeHttp is renamed to options.forceHttps");if(Reflect.has(e,"stripFragment"))throw new Error("options.stripFragment is renamed to options.stripHash");if(r=r.trim(),/^data:/i.test(r))return SPe(r,e);let t=r.startsWith("//");!t&&/^\.*\//.test(r)||(r=r.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new BPe(r);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&n.protocol==="https:"&&(n.protocol="http:"),e.forceHttps&&n.protocol==="http:"&&(n.protocol="https:"),e.stripAuthentication&&(n.username="",n.password=""),e.stripHash&&(n.hash=""),n.pathname&&(n.pathname=n.pathname.replace(/((?!:).|^)\/{2,}/g,(s,o)=>/^(?!\/)/g.test(o)?`${o}/`:"/")),n.pathname&&(n.pathname=decodeURI(n.pathname)),e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let s=n.pathname.split("/"),o=s[s.length-1];Mz(o,e.removeDirectoryIndex)&&(s=s.slice(0,s.length-1),n.pathname=s.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let s of[...n.searchParams.keys()])Mz(s,e.removeQueryParameters)&&n.searchParams.delete(s);return e.sortQueryParameters&&n.searchParams.sort(),e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,"")),r=n.toString(),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&(r=r.replace(/\/$/,"")),t&&!e.normalizeProtocol&&(r=r.replace(/^http:\/\//,"//")),e.stripProtocol&&(r=r.replace(/^(?:https?:)?\/\//,"")),r};SD.exports=Kz;SD.exports.default=Kz});var Gz=I((Cnt,jz)=>{jz.exports=Hz;function Hz(r,e){if(r&&e)return Hz(r)(e);if(typeof r!="function")throw new TypeError("need wrapper function");return Object.keys(r).forEach(function(i){t[i]=r[i]}),t;function t(){for(var i=new Array(arguments.length),n=0;n<i.length;n++)i[n]=arguments[n];var s=r.apply(this,i),o=i[i.length-1];return typeof s=="function"&&s!==o&&Object.keys(o).forEach(function(a){s[a]=o[a]}),s}}});var PD=I((mnt,vD)=>{var Yz=Gz();vD.exports=Yz(Jw);vD.exports.strict=Yz(qz);Jw.proto=Jw(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return Jw(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return qz(this)},configurable:!0})});function Jw(r){var e=function(){return e.called?e.value:(e.called=!0,e.value=r.apply(this,arguments))};return e.called=!1,e}function qz(r){var e=function(){if(e.called)throw new Error(e.onceError);return e.called=!0,e.value=r.apply(this,arguments)},t=r.name||"Function wrapped with `once`";return e.onceError=t+" shouldn't be called more than once",e.called=!1,e}});var xD=I((Ent,Wz)=>{var vPe=PD(),PPe=function(){},xPe=function(r){return r.setHeader&&typeof r.abort=="function"},kPe=function(r){return r.stdio&&Array.isArray(r.stdio)&&r.stdio.length===3},Jz=function(r,e,t){if(typeof e=="function")return Jz(r,null,e);e||(e={}),t=vPe(t||PPe);var i=r._writableState,n=r._readableState,s=e.readable||e.readable!==!1&&r.readable,o=e.writable||e.writable!==!1&&r.writable,a=function(){r.writable||l()},l=function(){o=!1,s||t.call(r)},c=function(){s=!1,o||t.call(r)},u=function(d){t.call(r,d?new Error("exited with error code: "+d):null)},g=function(d){t.call(r,d)},h=function(){if(s&&!(n&&n.ended))return t.call(r,new Error("premature close"));if(o&&!(i&&i.ended))return t.call(r,new Error("premature close"))},p=function(){r.req.on("finish",l)};return xPe(r)?(r.on("complete",l),r.on("abort",h),r.req?p():r.on("request",p)):o&&!i&&(r.on("end",a),r.on("close",a)),kPe(r)&&r.on("exit",u),r.on("end",c),r.on("finish",l),e.error!==!1&&r.on("error",g),r.on("close",h),function(){r.removeListener("complete",l),r.removeListener("abort",h),r.removeListener("request",p),r.req&&r.req.removeListener("finish",l),r.removeListener("end",a),r.removeListener("close",a),r.removeListener("finish",l),r.removeListener("exit",u),r.removeListener("end",c),r.removeListener("error",g),r.removeListener("close",h)}};Wz.exports=Jz});var Xz=I((Int,Vz)=>{var DPe=PD(),RPe=xD(),kD=J("fs"),EC=function(){},FPe=/^v?\.0/.test(process.version),Ww=function(r){return typeof r=="function"},NPe=function(r){return!FPe||!kD?!1:(r instanceof(kD.ReadStream||EC)||r instanceof(kD.WriteStream||EC))&&Ww(r.close)},TPe=function(r){return r.setHeader&&Ww(r.abort)},LPe=function(r,e,t,i){i=DPe(i);var n=!1;r.on("close",function(){n=!0}),RPe(r,{readable:e,writable:t},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,NPe(r))return r.close(EC);if(TPe(r))return r.abort();if(Ww(r.destroy))return r.destroy();i(o||new Error("stream was destroyed"))}}},zz=function(r){r()},OPe=function(r,e){return r.pipe(e)},MPe=function(){var r=Array.prototype.slice.call(arguments),e=Ww(r[r.length-1]||EC)&&r.pop()||EC;if(Array.isArray(r[0])&&(r=r[0]),r.length<2)throw new Error("pump requires two streams per minimum");var t,i=r.map(function(n,s){var o=s<r.length-1,a=s>0;return LPe(n,o,a,function(l){t||(t=l),l&&i.forEach(zz),!o&&(i.forEach(zz),e(t))})});return r.reduce(OPe)};Vz.exports=MPe});var _z=I((ynt,Zz)=>{"use strict";var{PassThrough:KPe}=J("stream");Zz.exports=r=>{r={...r};let{array:e}=r,{encoding:t}=r,i=t==="buffer",n=!1;e?n=!(t||i):t=t||"utf8",i&&(t=null);let s=new KPe({objectMode:n});t&&s.setEncoding(t);let o=0,a=[];return s.on("data",l=>{a.push(l),n?o=a.length:o+=l.length}),s.getBufferedValue=()=>e?a:i?Buffer.concat(a,o):a.join(""),s.getBufferedLength=()=>o,s}});var $z=I((wnt,Kf)=>{"use strict";var UPe=Xz(),HPe=_z(),zw=class extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}};async function Vw(r,e){if(!r)return Promise.reject(new Error("Expected a stream"));e={maxBuffer:1/0,...e};let{maxBuffer:t}=e,i;return await new Promise((n,s)=>{let o=a=>{a&&(a.bufferedData=i.getBufferedValue()),s(a)};i=UPe(r,HPe(e),a=>{if(a){o(a);return}n()}),i.on("data",()=>{i.getBufferedLength()>t&&o(new zw)})}),i.getBufferedValue()}Kf.exports=Vw;Kf.exports.default=Vw;Kf.exports.buffer=(r,e)=>Vw(r,{...e,encoding:"buffer"});Kf.exports.array=(r,e)=>Vw(r,{...e,array:!0});Kf.exports.MaxBufferError=zw});var t5=I((bnt,e5)=>{"use strict";var jPe=new Set([200,203,204,206,300,301,404,405,410,414,501]),GPe=new Set([200,203,204,300,301,302,303,307,308,404,405,410,414,501]),YPe=new Set([500,502,503,504]),qPe={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},JPe={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function Mc(r){let e=parseInt(r,10);return isFinite(e)?e:0}function WPe(r){return r?YPe.has(r.status):!0}function DD(r){let e={};if(!r)return e;let t=r.trim().split(/\s*,\s*/);for(let i of t){let[n,s]=i.split(/\s*=\s*/,2);e[n]=s===void 0?!0:s.replace(/^"|"$/g,"")}return e}function zPe(r){let e=[];for(let t in r){let i=r[t];e.push(i===!0?t:t+"="+i)}if(!!e.length)return e.join(", ")}e5.exports=class{constructor(e,t,{shared:i,cacheHeuristic:n,immutableMinTimeToLive:s,ignoreCargoCult:o,_fromObject:a}={}){if(a){this._fromObject(a);return}if(!t||!t.headers)throw Error("Response headers missing");this._assertRequestHasHeaders(e),this._responseTime=this.now(),this._isShared=i!==!1,this._cacheHeuristic=n!==void 0?n:.1,this._immutableMinTtl=s!==void 0?s:24*3600*1e3,this._status="status"in t?t.status:200,this._resHeaders=t.headers,this._rescc=DD(t.headers["cache-control"]),this._method="method"in e?e.method:"GET",this._url=e.url,this._host=e.headers.host,this._noAuthorization=!e.headers.authorization,this._reqHeaders=t.headers.vary?e.headers:null,this._reqcc=DD(e.headers["cache-control"]),o&&"pre-check"in this._rescc&&"post-check"in this._rescc&&(delete this._rescc["pre-check"],delete this._rescc["post-check"],delete this._rescc["no-cache"],delete this._rescc["no-store"],delete this._rescc["must-revalidate"],this._resHeaders=Object.assign({},this._resHeaders,{"cache-control":zPe(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),t.headers["cache-control"]==null&&/no-cache/.test(t.headers.pragma)&&(this._rescc["no-cache"]=!0)}now(){return Date.now()}storable(){return!!(!this._reqcc["no-store"]&&(this._method==="GET"||this._method==="HEAD"||this._method==="POST"&&this._hasExplicitExpiration())&&GPe.has(this._status)&&!this._rescc["no-store"]&&(!this._isShared||!this._rescc.private)&&(!this._isShared||this._noAuthorization||this._allowsStoringAuthenticated())&&(this._resHeaders.expires||this._rescc["max-age"]||this._isShared&&this._rescc["s-maxage"]||this._rescc.public||jPe.has(this._status)))}_hasExplicitExpiration(){return this._isShared&&this._rescc["s-maxage"]||this._rescc["max-age"]||this._resHeaders.expires}_assertRequestHasHeaders(e){if(!e||!e.headers)throw Error("Request headers missing")}satisfiesWithoutRevalidation(e){this._assertRequestHasHeaders(e);let t=DD(e.headers["cache-control"]);return t["no-cache"]||/no-cache/.test(e.headers.pragma)||t["max-age"]&&this.age()>t["max-age"]||t["min-fresh"]&&this.timeToLive()<1e3*t["min-fresh"]||this.stale()&&!(t["max-stale"]&&!this._rescc["must-revalidate"]&&(t["max-stale"]===!0||t["max-stale"]>this.age()-this.maxAge()))?!1:this._requestMatches(e,!1)}_requestMatches(e,t){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||t&&e.method==="HEAD")&&this._varyMatches(e)}_allowsStoringAuthenticated(){return this._rescc["must-revalidate"]||this._rescc.public||this._rescc["s-maxage"]}_varyMatches(e){if(!this._resHeaders.vary)return!0;if(this._resHeaders.vary==="*")return!1;let t=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(let i of t)if(e.headers[i]!==this._reqHeaders[i])return!1;return!0}_copyWithoutHopByHopHeaders(e){let t={};for(let i in e)qPe[i]||(t[i]=e[i]);if(e.connection){let i=e.connection.trim().split(/\s*,\s*/);for(let n of i)delete t[n]}if(t.warning){let i=t.warning.split(/,/).filter(n=>!/^\s*1[0-9][0-9]/.test(n));i.length?t.warning=i.join(",").trim():delete t.warning}return t}responseHeaders(){let e=this._copyWithoutHopByHopHeaders(this._resHeaders),t=this.age();return t>3600*24&&!this._hasExplicitExpiration()&&this.maxAge()>3600*24&&(e.warning=(e.warning?`${e.warning}, `:"")+'113 - "rfc7234 5.5.4"'),e.age=`${Math.round(t)}`,e.date=new Date(this.now()).toUTCString(),e}date(){let e=Date.parse(this._resHeaders.date);return isFinite(e)?e:this._responseTime}age(){let e=this._ageValue(),t=(this.now()-this._responseTime)/1e3;return e+t}_ageValue(){return Mc(this._resHeaders.age)}maxAge(){if(!this.storable()||this._rescc["no-cache"]||this._isShared&&this._resHeaders["set-cookie"]&&!this._rescc.public&&!this._rescc.immutable||this._resHeaders.vary==="*")return 0;if(this._isShared){if(this._rescc["proxy-revalidate"])return 0;if(this._rescc["s-maxage"])return Mc(this._rescc["s-maxage"])}if(this._rescc["max-age"])return Mc(this._rescc["max-age"]);let e=this._rescc.immutable?this._immutableMinTtl:0,t=this.date();if(this._resHeaders.expires){let i=Date.parse(this._resHeaders.expires);return Number.isNaN(i)||i<t?0:Math.max(e,(i-t)/1e3)}if(this._resHeaders["last-modified"]){let i=Date.parse(this._resHeaders["last-modified"]);if(isFinite(i)&&t>i)return Math.max(e,(t-i)/1e3*this._cacheHeuristic)}return e}timeToLive(){let e=this.maxAge()-this.age(),t=e+Mc(this._rescc["stale-if-error"]),i=e+Mc(this._rescc["stale-while-revalidate"]);return Math.max(0,e,t,i)*1e3}stale(){return this.maxAge()<=this.age()}_useStaleIfError(){return this.maxAge()+Mc(this._rescc["stale-if-error"])>this.age()}useStaleWhileRevalidate(){return this.maxAge()+Mc(this._rescc["stale-while-revalidate"])>this.age()}static fromObject(e){return new this(void 0,void 0,{_fromObject:e})}_fromObject(e){if(this._responseTime)throw Error("Reinitialized");if(!e||e.v!==1)throw Error("Invalid serialization");this._responseTime=e.t,this._isShared=e.sh,this._cacheHeuristic=e.ch,this._immutableMinTtl=e.imm!==void 0?e.imm:24*3600*1e3,this._status=e.st,this._resHeaders=e.resh,this._rescc=e.rescc,this._method=e.m,this._url=e.u,this._host=e.h,this._noAuthorization=e.a,this._reqHeaders=e.reqh,this._reqcc=e.reqcc}toObject(){return{v:1,t:this._responseTime,sh:this._isShared,ch:this._cacheHeuristic,imm:this._immutableMinTtl,st:this._status,resh:this._resHeaders,rescc:this._rescc,m:this._method,u:this._url,h:this._host,a:this._noAuthorization,reqh:this._reqHeaders,reqcc:this._reqcc}}revalidationHeaders(e){this._assertRequestHasHeaders(e);let t=this._copyWithoutHopByHopHeaders(e.headers);if(delete t["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete t["if-none-match"],delete t["if-modified-since"],t;if(this._resHeaders.etag&&(t["if-none-match"]=t["if-none-match"]?`${t["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag),t["accept-ranges"]||t["if-match"]||t["if-unmodified-since"]||this._method&&this._method!="GET"){if(delete t["if-modified-since"],t["if-none-match"]){let n=t["if-none-match"].split(/,/).filter(s=>!/^\s*W\//.test(s));n.length?t["if-none-match"]=n.join(",").trim():delete t["if-none-match"]}}else this._resHeaders["last-modified"]&&!t["if-modified-since"]&&(t["if-modified-since"]=this._resHeaders["last-modified"]);return t}revalidatedPolicy(e,t){if(this._assertRequestHasHeaders(e),this._useStaleIfError()&&WPe(t))return{modified:!1,matches:!1,policy:this};if(!t||!t.headers)throw Error("Response headers missing");let i=!1;if(t.status!==void 0&&t.status!=304?i=!1:t.headers.etag&&!/^\s*W\//.test(t.headers.etag)?i=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag:this._resHeaders.etag&&t.headers.etag?i=this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?i=this._resHeaders["last-modified"]===t.headers["last-modified"]:!this._resHeaders.etag&&!this._resHeaders["last-modified"]&&!t.headers.etag&&!t.headers["last-modified"]&&(i=!0),!i)return{policy:new this.constructor(e,t),modified:t.status!=304,matches:!1};let n={};for(let o in this._resHeaders)n[o]=o in t.headers&&!JPe[o]?t.headers[o]:this._resHeaders[o];let s=Object.assign({},t,{status:this._status,method:this._method,headers:n});return{policy:new this.constructor(e,s,{shared:this._isShared,cacheHeuristic:this._cacheHeuristic,immutableMinTimeToLive:this._immutableMinTtl}),modified:!1,matches:!0}}}});var Xw=I((Qnt,r5)=>{"use strict";r5.exports=r=>{let e={};for(let[t,i]of Object.entries(r))e[t.toLowerCase()]=i;return e}});var n5=I((Snt,i5)=>{"use strict";var VPe=J("stream").Readable,XPe=Xw(),RD=class extends VPe{constructor(e,t,i,n){if(typeof e!="number")throw new TypeError("Argument `statusCode` should be a number");if(typeof t!="object")throw new TypeError("Argument `headers` should be an object");if(!(i instanceof Buffer))throw new TypeError("Argument `body` should be a buffer");if(typeof n!="string")throw new TypeError("Argument `url` should be a string");super(),this.statusCode=e,this.headers=XPe(t),this.body=i,this.url=n}_read(){this.push(this.body),this.push(null)}};i5.exports=RD});var o5=I((vnt,s5)=>{"use strict";var ZPe=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];s5.exports=(r,e)=>{let t=new Set(Object.keys(r).concat(ZPe));for(let i of t)i in e||(e[i]=typeof r[i]=="function"?r[i].bind(r):r[i])}});var A5=I((Pnt,a5)=>{"use strict";var _Pe=J("stream").PassThrough,$Pe=o5(),exe=r=>{if(!(r&&r.pipe))throw new TypeError("Parameter `response` must be a response stream.");let e=new _Pe;return $Pe(r,e),r.pipe(e)};a5.exports=exe});var l5=I(FD=>{FD.stringify=function r(e){if(typeof e>"u")return e;if(e&&Buffer.isBuffer(e))return JSON.stringify(":base64:"+e.toString("base64"));if(e&&e.toJSON&&(e=e.toJSON()),e&&typeof e=="object"){var t="",i=Array.isArray(e);t=i?"[":"{";var n=!0;for(var s in e){var o=typeof e[s]=="function"||!i&&typeof e[s]>"u";Object.hasOwnProperty.call(e,s)&&!o&&(n||(t+=","),n=!1,i?e[s]==null?t+="null":t+=r(e[s]):e[s]!==void 0&&(t+=r(s)+":"+r(e[s])))}return t+=i?"]":"}",t}else return typeof e=="string"?JSON.stringify(/^:/.test(e)?":"+e:e):typeof e>"u"?"null":JSON.stringify(e)};FD.parse=function(r){return JSON.parse(r,function(e,t){return typeof t=="string"?/^:base64:/.test(t)?Buffer.from(t.substring(8),"base64"):/^:/.test(t)?t.substring(1):t:t})}});var g5=I((knt,u5)=>{"use strict";var txe=J("events"),c5=l5(),rxe=r=>{let e={redis:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql"};if(r.adapter||r.uri){let t=r.adapter||/^[^:]*/.exec(r.uri)[0];return new(J(e[t]))(r)}return new Map},ND=class extends txe{constructor(e,t){if(super(),this.opts=Object.assign({namespace:"keyv",serialize:c5.stringify,deserialize:c5.parse},typeof e=="string"?{uri:e}:e,t),!this.opts.store){let i=Object.assign({},this.opts);this.opts.store=rxe(i)}typeof this.opts.store.on=="function"&&this.opts.store.on("error",i=>this.emit("error",i)),this.opts.store.namespace=this.opts.namespace}_getKeyPrefix(e){return`${this.opts.namespace}:${e}`}get(e,t){e=this._getKeyPrefix(e);let{store:i}=this.opts;return Promise.resolve().then(()=>i.get(e)).then(n=>typeof n=="string"?this.opts.deserialize(n):n).then(n=>{if(n!==void 0){if(typeof n.expires=="number"&&Date.now()>n.expires){this.delete(e);return}return t&&t.raw?n:n.value}})}set(e,t,i){e=this._getKeyPrefix(e),typeof i>"u"&&(i=this.opts.ttl),i===0&&(i=void 0);let{store:n}=this.opts;return Promise.resolve().then(()=>{let s=typeof i=="number"?Date.now()+i:null;return t={value:t,expires:s},this.opts.serialize(t)}).then(s=>n.set(e,s,i)).then(()=>!0)}delete(e){e=this._getKeyPrefix(e);let{store:t}=this.opts;return Promise.resolve().then(()=>t.delete(e))}clear(){let{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}};u5.exports=ND});var p5=I((Rnt,h5)=>{"use strict";var ixe=J("events"),Zw=J("url"),nxe=Uz(),sxe=$z(),TD=t5(),f5=n5(),oxe=Xw(),axe=A5(),Axe=g5(),oo=class{constructor(e,t){if(typeof e!="function")throw new TypeError("Parameter `request` must be a function");return this.cache=new Axe({uri:typeof t=="string"&&t,store:typeof t!="string"&&t,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(t,i)=>{let n;if(typeof t=="string")n=LD(Zw.parse(t)),t={};else if(t instanceof Zw.URL)n=LD(Zw.parse(t.toString())),t={};else{let[g,...h]=(t.path||"").split("?"),p=h.length>0?`?${h.join("?")}`:"";n=LD({...t,pathname:g,search:p})}t={headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1,...t,...lxe(n)},t.headers=oxe(t.headers);let s=new ixe,o=nxe(Zw.format(n),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),a=`${t.method}:${o}`,l=!1,c=!1,u=g=>{c=!0;let h=!1,p,d=new Promise(y=>{p=()=>{h||(h=!0,y())}}),m=y=>{if(l&&!g.forceRefresh){y.status=y.statusCode;let S=TD.fromObject(l.cachePolicy).revalidatedPolicy(g,y);if(!S.modified){let x=S.policy.responseHeaders();y=new f5(l.statusCode,x,l.body,l.url),y.cachePolicy=S.policy,y.fromCache=!0}}y.fromCache||(y.cachePolicy=new TD(g,y,g),y.fromCache=!1);let B;g.cache&&y.cachePolicy.storable()?(B=axe(y),(async()=>{try{let S=sxe.buffer(y);if(await Promise.race([d,new Promise(q=>y.once("end",q))]),h)return;let x=await S,F={cachePolicy:y.cachePolicy.toObject(),url:y.url,statusCode:y.fromCache?l.statusCode:y.statusCode,body:x},H=g.strictTtl?y.cachePolicy.timeToLive():void 0;g.maxTtl&&(H=H?Math.min(H,g.maxTtl):g.maxTtl),await this.cache.set(a,F,H)}catch(S){s.emit("error",new oo.CacheError(S))}})()):g.cache&&l&&(async()=>{try{await this.cache.delete(a)}catch(S){s.emit("error",new oo.CacheError(S))}})(),s.emit("response",B||y),typeof i=="function"&&i(B||y)};try{let y=e(g,m);y.once("error",p),y.once("abort",p),s.emit("request",y)}catch(y){s.emit("error",new oo.RequestError(y))}};return(async()=>{let g=async p=>{await Promise.resolve();let d=p.cache?await this.cache.get(a):void 0;if(typeof d>"u")return u(p);let m=TD.fromObject(d.cachePolicy);if(m.satisfiesWithoutRevalidation(p)&&!p.forceRefresh){let y=m.responseHeaders(),B=new f5(d.statusCode,y,d.body,d.url);B.cachePolicy=m,B.fromCache=!0,s.emit("response",B),typeof i=="function"&&i(B)}else l=d,p.headers=m.revalidationHeaders(p),u(p)},h=p=>s.emit("error",new oo.CacheError(p));this.cache.once("error",h),s.on("response",()=>this.cache.removeListener("error",h));try{await g(t)}catch(p){t.automaticFailover&&!c&&u(t),s.emit("error",new oo.CacheError(p))}})(),s}}};function lxe(r){let e={...r};return e.path=`${r.pathname||"/"}${r.search||""}`,delete e.pathname,delete e.search,e}function LD(r){return{protocol:r.protocol,auth:r.auth,hostname:r.hostname||r.host||"localhost",port:r.port,pathname:r.pathname,search:r.search}}oo.RequestError=class extends Error{constructor(r){super(r.message),this.name="RequestError",Object.assign(this,r)}};oo.CacheError=class extends Error{constructor(r){super(r.message),this.name="CacheError",Object.assign(this,r)}};h5.exports=oo});var C5=I((Tnt,d5)=>{"use strict";var cxe=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];d5.exports=(r,e)=>{if(e._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");let t=new Set(Object.keys(r).concat(cxe)),i={};for(let n of t)n in e||(i[n]={get(){let s=r[n];return typeof s=="function"?s.bind(r):s},set(s){r[n]=s},enumerable:!0,configurable:!1});return Object.defineProperties(e,i),r.once("aborted",()=>{e.destroy(),e.emit("aborted")}),r.once("close",()=>{r.complete&&e.readable?e.once("end",()=>{e.emit("close")}):e.emit("close")}),e}});var E5=I((Lnt,m5)=>{"use strict";var{Transform:uxe,PassThrough:gxe}=J("stream"),OD=J("zlib"),fxe=C5();m5.exports=r=>{let e=(r.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(e))return r;let t=e==="br";if(t&&typeof OD.createBrotliDecompress!="function")return r.destroy(new Error("Brotli is not supported on Node.js < 12")),r;let i=!0,n=new uxe({transform(a,l,c){i=!1,c(null,a)},flush(a){a()}}),s=new gxe({autoDestroy:!1,destroy(a,l){r.destroy(),l(a)}}),o=t?OD.createBrotliDecompress():OD.createUnzip();return o.once("error",a=>{if(i&&!r.readable){s.end();return}s.destroy(a)}),fxe(r,s),r.pipe(n).pipe(o).pipe(s),s}});var KD=I((Ont,I5)=>{"use strict";var MD=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,t){if(this.cache.set(e,t),this._size++,this._size>=this.maxSize){if(this._size=0,typeof this.onEviction=="function")for(let[i,n]of this.oldCache.entries())this.onEviction(i,n);this.oldCache=this.cache,this.cache=new Map}}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){let t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e))return this.oldCache.get(e)}delete(e){let t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache)yield e;for(let e of this.oldCache){let[t]=e;this.cache.has(t)||(yield e)}}get size(){let e=0;for(let t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}};I5.exports=MD});var HD=I((Mnt,b5)=>{"use strict";var hxe=J("events"),pxe=J("tls"),dxe=J("http2"),Cxe=KD(),sn=Symbol("currentStreamsCount"),y5=Symbol("request"),ws=Symbol("cachedOriginSet"),Uf=Symbol("gracefullyClosing"),mxe=["maxDeflateDynamicTableSize","maxSessionMemory","maxHeaderListPairs","maxOutstandingPings","maxReservedRemoteStreams","maxSendHeaderBlockLength","paddingStrategy","localAddress","path","rejectUnauthorized","minDHSize","ca","cert","clientCertEngine","ciphers","key","pfx","servername","minVersion","maxVersion","secureProtocol","crl","honorCipherOrder","ecdhCurve","dhparam","secureOptions","sessionIdContext"],Exe=(r,e,t)=>{let i=0,n=r.length;for(;i<n;){let s=i+n>>>1;t(r[s],e)?i=s+1:n=s}return i},Ixe=(r,e)=>r.remoteSettings.maxConcurrentStreams>e.remoteSettings.maxConcurrentStreams,UD=(r,e)=>{for(let t of r)t[ws].length<e[ws].length&&t[ws].every(i=>e[ws].includes(i))&&t[sn]+e[sn]<=e.remoteSettings.maxConcurrentStreams&&B5(t)},yxe=(r,e)=>{for(let t of r)e[ws].length<t[ws].length&&e[ws].every(i=>t[ws].includes(i))&&e[sn]+t[sn]<=t.remoteSettings.maxConcurrentStreams&&B5(e)},w5=({agent:r,isFree:e})=>{let t={};for(let i in r.sessions){let s=r.sessions[i].filter(o=>{let a=o[Wo.kCurrentStreamsCount]<o.remoteSettings.maxConcurrentStreams;return e?a:!a});s.length!==0&&(t[i]=s)}return t},B5=r=>{r[Uf]=!0,r[sn]===0&&r.close()},Wo=class extends hxe{constructor({timeout:e=6e4,maxSessions:t=1/0,maxFreeSessions:i=10,maxCachedTlsSessions:n=100}={}){super(),this.sessions={},this.queue={},this.timeout=e,this.maxSessions=t,this.maxFreeSessions=i,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new Cxe({maxSize:n})}static normalizeOrigin(e,t){return typeof e=="string"&&(e=new URL(e)),t&&e.hostname!==t&&(e.hostname=t),e.origin}normalizeOptions(e){let t="";if(e)for(let i of mxe)e[i]&&(t+=`:${e[i]}`);return t}_tryToCreateNewSession(e,t){if(!(e in this.queue)||!(t in this.queue[e]))return;let i=this.queue[e][t];this._sessionsCount<this.maxSessions&&!i.completed&&(i.completed=!0,i())}getSession(e,t,i){return new Promise((n,s)=>{Array.isArray(i)?(i=[...i],n()):i=[{resolve:n,reject:s}];let o=this.normalizeOptions(t),a=Wo.normalizeOrigin(e,t&&t.servername);if(a===void 0){for(let{reject:u}of i)u(new TypeError("The `origin` argument needs to be a string or an URL object"));return}if(o in this.sessions){let u=this.sessions[o],g=-1,h=-1,p;for(let d of u){let m=d.remoteSettings.maxConcurrentStreams;if(m<g)break;if(d[ws].includes(a)){let y=d[sn];if(y>=m||d[Uf]||d.destroyed)continue;p||(g=m),y>h&&(p=d,h=y)}}if(p){if(i.length!==1){for(let{reject:d}of i){let m=new Error(`Expected the length of listeners to be 1, got ${i.length}. +Please report this to https://github.com/szmarczak/http2-wrapper/`);d(m)}return}i[0].resolve(p);return}}if(o in this.queue){if(a in this.queue[o]){this.queue[o][a].listeners.push(...i),this._tryToCreateNewSession(o,a);return}}else this.queue[o]={};let l=()=>{o in this.queue&&this.queue[o][a]===c&&(delete this.queue[o][a],Object.keys(this.queue[o]).length===0&&delete this.queue[o])},c=()=>{let u=`${a}:${o}`,g=!1;try{let h=dxe.connect(e,{createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(u),...t});h[sn]=0,h[Uf]=!1;let p=()=>h[sn]<h.remoteSettings.maxConcurrentStreams,d=!0;h.socket.once("session",y=>{this.tlsSessionCache.set(u,y)}),h.once("error",y=>{for(let{reject:B}of i)B(y);this.tlsSessionCache.delete(u)}),h.setTimeout(this.timeout,()=>{h.destroy()}),h.once("close",()=>{if(g){d&&this._freeSessionsCount--,this._sessionsCount--;let y=this.sessions[o];y.splice(y.indexOf(h),1),y.length===0&&delete this.sessions[o]}else{let y=new Error("Session closed without receiving a SETTINGS frame");y.code="HTTP2WRAPPER_NOSETTINGS";for(let{reject:B}of i)B(y);l()}this._tryToCreateNewSession(o,a)});let m=()=>{if(!(!(o in this.queue)||!p())){for(let y of h[ws])if(y in this.queue[o]){let{listeners:B}=this.queue[o][y];for(;B.length!==0&&p();)B.shift().resolve(h);let S=this.queue[o];if(S[y].listeners.length===0&&(delete S[y],Object.keys(S).length===0)){delete this.queue[o];break}if(!p())break}}};h.on("origin",()=>{h[ws]=h.originSet,p()&&(m(),UD(this.sessions[o],h))}),h.once("remoteSettings",()=>{if(h.ref(),h.unref(),this._sessionsCount++,c.destroyed){let y=new Error("Agent has been destroyed");for(let B of i)B.reject(y);h.destroy();return}h[ws]=h.originSet;{let y=this.sessions;if(o in y){let B=y[o];B.splice(Exe(B,h,Ixe),0,h)}else y[o]=[h]}this._freeSessionsCount+=1,g=!0,this.emit("session",h),m(),l(),h[sn]===0&&this._freeSessionsCount>this.maxFreeSessions&&h.close(),i.length!==0&&(this.getSession(a,t,i),i.length=0),h.on("remoteSettings",()=>{m(),UD(this.sessions[o],h)})}),h[y5]=h.request,h.request=(y,B)=>{if(h[Uf])throw new Error("The session is gracefully closing. No new streams are allowed.");let S=h[y5](y,B);return h.ref(),++h[sn],h[sn]===h.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,S.once("close",()=>{if(d=p(),--h[sn],!h.destroyed&&!h.closed&&(yxe(this.sessions[o],h),p()&&!h.closed)){d||(this._freeSessionsCount++,d=!0);let x=h[sn]===0;x&&h.unref(),x&&(this._freeSessionsCount>this.maxFreeSessions||h[Uf])?h.close():(UD(this.sessions[o],h),m())}}),S}}catch(h){for(let p of i)p.reject(h);l()}};c.listeners=i,c.completed=!1,c.destroyed=!1,this.queue[o][a]=c,this._tryToCreateNewSession(o,a)})}request(e,t,i,n){return new Promise((s,o)=>{this.getSession(e,t,[{reject:o,resolve:a=>{try{s(a.request(i,n))}catch(l){o(l)}}}])})}createConnection(e,t){return Wo.connect(e,t)}static connect(e,t){t.ALPNProtocols=["h2"];let i=e.port||443,n=e.hostname||e.host;return typeof t.servername>"u"&&(t.servername=n),pxe.connect(i,n,t)}closeFreeSessions(){for(let e of Object.values(this.sessions))for(let t of e)t[sn]===0&&t.close()}destroy(e){for(let t of Object.values(this.sessions))for(let i of t)i.destroy(e);for(let t of Object.values(this.queue))for(let i of Object.values(t))i.destroyed=!0;this.queue={}}get freeSessions(){return w5({agent:this,isFree:!0})}get busySessions(){return w5({agent:this,isFree:!1})}};Wo.kCurrentStreamsCount=sn;Wo.kGracefullyClosing=Uf;b5.exports={Agent:Wo,globalAgent:new Wo}});var GD=I((Knt,Q5)=>{"use strict";var{Readable:wxe}=J("stream"),jD=class extends wxe{constructor(e,t){super({highWaterMark:t,autoDestroy:!1}),this.statusCode=null,this.statusMessage="",this.httpVersion="2.0",this.httpVersionMajor=2,this.httpVersionMinor=0,this.headers={},this.trailers={},this.req=null,this.aborted=!1,this.complete=!1,this.upgrade=null,this.rawHeaders=[],this.rawTrailers=[],this.socket=e,this.connection=e,this._dumped=!1}_destroy(e){this.req._request.destroy(e)}setTimeout(e,t){return this.req.setTimeout(e,t),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}};Q5.exports=jD});var YD=I((Unt,S5)=>{"use strict";S5.exports=r=>{let e={protocol:r.protocol,hostname:typeof r.hostname=="string"&&r.hostname.startsWith("[")?r.hostname.slice(1,-1):r.hostname,host:r.host,hash:r.hash,search:r.search,pathname:r.pathname,href:r.href,path:`${r.pathname||""}${r.search||""}`};return typeof r.port=="string"&&r.port.length!==0&&(e.port=Number(r.port)),(r.username||r.password)&&(e.auth=`${r.username||""}:${r.password||""}`),e}});var P5=I((Hnt,v5)=>{"use strict";v5.exports=(r,e,t)=>{for(let i of t)r.on(i,(...n)=>e.emit(i,...n))}});var k5=I((jnt,x5)=>{"use strict";x5.exports=r=>{switch(r){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}});var R5=I((Ynt,D5)=>{"use strict";var Hf=(r,e,t)=>{D5.exports[e]=class extends r{constructor(...n){super(typeof t=="string"?t:t(n)),this.name=`${super.name} [${e}]`,this.code=e}}};Hf(TypeError,"ERR_INVALID_ARG_TYPE",r=>{let e=r[0].includes(".")?"property":"argument",t=r[1],i=Array.isArray(t);return i&&(t=`${t.slice(0,-1).join(", ")} or ${t.slice(-1)}`),`The "${r[0]}" ${e} must be ${i?"one of":"of"} type ${t}. Received ${typeof r[2]}`});Hf(TypeError,"ERR_INVALID_PROTOCOL",r=>`Protocol "${r[0]}" not supported. Expected "${r[1]}"`);Hf(Error,"ERR_HTTP_HEADERS_SENT",r=>`Cannot ${r[0]} headers after they are sent to the client`);Hf(TypeError,"ERR_INVALID_HTTP_TOKEN",r=>`${r[0]} must be a valid HTTP token [${r[1]}]`);Hf(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",r=>`Invalid value "${r[0]} for header "${r[1]}"`);Hf(TypeError,"ERR_INVALID_CHAR",r=>`Invalid character in ${r[0]} [${r[1]}]`)});var VD=I((qnt,K5)=>{"use strict";var Bxe=J("http2"),{Writable:bxe}=J("stream"),{Agent:F5,globalAgent:Qxe}=HD(),Sxe=GD(),vxe=YD(),Pxe=P5(),xxe=k5(),{ERR_INVALID_ARG_TYPE:qD,ERR_INVALID_PROTOCOL:kxe,ERR_HTTP_HEADERS_SENT:N5,ERR_INVALID_HTTP_TOKEN:Dxe,ERR_HTTP_INVALID_HEADER_VALUE:Rxe,ERR_INVALID_CHAR:Fxe}=R5(),{HTTP2_HEADER_STATUS:T5,HTTP2_HEADER_METHOD:L5,HTTP2_HEADER_PATH:O5,HTTP2_METHOD_CONNECT:Nxe}=Bxe.constants,Ui=Symbol("headers"),JD=Symbol("origin"),WD=Symbol("session"),M5=Symbol("options"),_w=Symbol("flushedHeaders"),IC=Symbol("jobs"),Txe=/^[\^`\-\w!#$%&*+.|~]+$/,Lxe=/[^\t\u0020-\u007E\u0080-\u00FF]/,zD=class extends bxe{constructor(e,t,i){super({autoDestroy:!1});let n=typeof e=="string"||e instanceof URL;if(n&&(e=vxe(e instanceof URL?e:new URL(e))),typeof t=="function"||t===void 0?(i=t,t=n?e:{...e}):t={...e,...t},t.h2session)this[WD]=t.h2session;else if(t.agent===!1)this.agent=new F5({maxFreeSessions:0});else if(typeof t.agent>"u"||t.agent===null)typeof t.createConnection=="function"?(this.agent=new F5({maxFreeSessions:0}),this.agent.createConnection=t.createConnection):this.agent=Qxe;else if(typeof t.agent.request=="function")this.agent=t.agent;else throw new qD("options.agent",["Agent-like Object","undefined","false"],t.agent);if(t.protocol&&t.protocol!=="https:")throw new kxe(t.protocol,"https:");let s=t.port||t.defaultPort||this.agent&&this.agent.defaultPort||443,o=t.hostname||t.host||"localhost";delete t.hostname,delete t.host,delete t.port;let{timeout:a}=t;if(t.timeout=void 0,this[Ui]=Object.create(null),this[IC]=[],this.socket=null,this.connection=null,this.method=t.method||"GET",this.path=t.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,t.headers)for(let[l,c]of Object.entries(t.headers))this.setHeader(l,c);t.auth&&!("authorization"in this[Ui])&&(this[Ui].authorization="Basic "+Buffer.from(t.auth).toString("base64")),t.session=t.tlsSession,t.path=t.socketPath,this[M5]=t,s===443?(this[JD]=`https://${o}`,":authority"in this[Ui]||(this[Ui][":authority"]=o)):(this[JD]=`https://${o}:${s}`,":authority"in this[Ui]||(this[Ui][":authority"]=`${o}:${s}`)),a&&this.setTimeout(a),i&&this.once("response",i),this[_w]=!1}get method(){return this[Ui][L5]}set method(e){e&&(this[Ui][L5]=e.toUpperCase())}get path(){return this[Ui][O5]}set path(e){e&&(this[Ui][O5]=e)}get _mustNotHaveABody(){return this.method==="GET"||this.method==="HEAD"||this.method==="DELETE"}_write(e,t,i){if(this._mustNotHaveABody){i(new Error("The GET, HEAD and DELETE methods must NOT have a body"));return}this.flushHeaders();let n=()=>this._request.write(e,t,i);this._request?n():this[IC].push(n)}_final(e){if(this.destroyed)return;this.flushHeaders();let t=()=>{if(this._mustNotHaveABody){e();return}this._request.end(e)};this._request?t():this[IC].push(t)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,t){this.res&&this.res._dump(),this._request&&this._request.destroy(),t(e)}async flushHeaders(){if(this[_w]||this.destroyed)return;this[_w]=!0;let e=this.method===Nxe,t=i=>{if(this._request=i,this.destroyed){i.destroy();return}e||Pxe(i,this,["timeout","continue","close","error"]);let n=o=>(...a)=>{!this.writable&&!this.destroyed?o(...a):this.once("finish",()=>{o(...a)})};i.once("response",n((o,a,l)=>{let c=new Sxe(this.socket,i.readableHighWaterMark);this.res=c,c.req=this,c.statusCode=o[T5],c.headers=o,c.rawHeaders=l,c.once("end",()=>{this.aborted?(c.aborted=!0,c.emit("aborted")):(c.complete=!0,c.socket=null,c.connection=null)}),e?(c.upgrade=!0,this.emit("connect",c,i,Buffer.alloc(0))?this.emit("close"):i.destroy()):(i.on("data",u=>{!c._dumped&&!c.push(u)&&i.pause()}),i.once("end",()=>{c.push(null)}),this.emit("response",c)||c._dump())})),i.once("headers",n(o=>this.emit("information",{statusCode:o[T5]}))),i.once("trailers",n((o,a,l)=>{let{res:c}=this;c.trailers=o,c.rawTrailers=l}));let{socket:s}=i.session;this.socket=s,this.connection=s;for(let o of this[IC])o();this.emit("socket",this.socket)};if(this[WD])try{t(this[WD].request(this[Ui]))}catch(i){this.emit("error",i)}else{this.reusedSocket=!0;try{t(await this.agent.request(this[JD],this[M5],this[Ui]))}catch(i){this.emit("error",i)}}}getHeader(e){if(typeof e!="string")throw new qD("name","string",e);return this[Ui][e.toLowerCase()]}get headersSent(){return this[_w]}removeHeader(e){if(typeof e!="string")throw new qD("name","string",e);if(this.headersSent)throw new N5("remove");delete this[Ui][e.toLowerCase()]}setHeader(e,t){if(this.headersSent)throw new N5("set");if(typeof e!="string"||!Txe.test(e)&&!xxe(e))throw new Dxe("Header name",e);if(typeof t>"u")throw new Rxe(t,e);if(Lxe.test(t))throw new Fxe("header content",e);this[Ui][e.toLowerCase()]=t}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,t){let i=()=>this._request.setTimeout(e,t);return this._request?i():this[IC].push(i),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}};K5.exports=zD});var H5=I((Jnt,U5)=>{"use strict";var Oxe=J("tls");U5.exports=(r={})=>new Promise((e,t)=>{let i=Oxe.connect(r,()=>{r.resolveSocket?(i.off("error",t),e({alpnProtocol:i.alpnProtocol,socket:i})):(i.destroy(),e({alpnProtocol:i.alpnProtocol}))});i.on("error",t)})});var G5=I((Wnt,j5)=>{"use strict";var Mxe=J("net");j5.exports=r=>{let e=r.host,t=r.headers&&r.headers.host;return t&&(t.startsWith("[")?t.indexOf("]")===-1?e=t:e=t.slice(1,-1):e=t.split(":",1)[0]),Mxe.isIP(e)?"":e}});var J5=I((znt,ZD)=>{"use strict";var Y5=J("http"),XD=J("https"),Kxe=H5(),Uxe=KD(),Hxe=VD(),jxe=G5(),Gxe=YD(),$w=new Uxe({maxSize:100}),yC=new Map,q5=(r,e,t)=>{e._httpMessage={shouldKeepAlive:!0};let i=()=>{r.emit("free",e,t)};e.on("free",i);let n=()=>{r.removeSocket(e,t)};e.on("close",n);let s=()=>{r.removeSocket(e,t),e.off("close",n),e.off("free",i),e.off("agentRemove",s)};e.on("agentRemove",s),r.emit("free",e,t)},Yxe=async r=>{let e=`${r.host}:${r.port}:${r.ALPNProtocols.sort()}`;if(!$w.has(e)){if(yC.has(e))return(await yC.get(e)).alpnProtocol;let{path:t,agent:i}=r;r.path=r.socketPath;let n=Kxe(r);yC.set(e,n);try{let{socket:s,alpnProtocol:o}=await n;if($w.set(e,o),r.path=t,o==="h2")s.destroy();else{let{globalAgent:a}=XD,l=XD.Agent.prototype.createConnection;i?i.createConnection===l?q5(i,s,r):s.destroy():a.createConnection===l?q5(a,s,r):s.destroy()}return yC.delete(e),o}catch(s){throw yC.delete(e),s}}return $w.get(e)};ZD.exports=async(r,e,t)=>{if((typeof r=="string"||r instanceof URL)&&(r=Gxe(new URL(r))),typeof e=="function"&&(t=e,e=void 0),e={ALPNProtocols:["h2","http/1.1"],...r,...e,resolveSocket:!0},!Array.isArray(e.ALPNProtocols)||e.ALPNProtocols.length===0)throw new Error("The `ALPNProtocols` option must be an Array with at least one entry");e.protocol=e.protocol||"https:";let i=e.protocol==="https:";e.host=e.hostname||e.host||"localhost",e.session=e.tlsSession,e.servername=e.servername||jxe(e),e.port=e.port||(i?443:80),e._defaultAgent=i?XD.globalAgent:Y5.globalAgent;let n=e.agent;if(n){if(n.addRequest)throw new Error("The `options.agent` object can contain only `http`, `https` or `http2` properties");e.agent=n[i?"https":"http"]}return i&&await Yxe(e)==="h2"?(n&&(e.agent=n.http2),new Hxe(e,t)):Y5.request(e,t)};ZD.exports.protocolCache=$w});var z5=I((Vnt,W5)=>{"use strict";var qxe=J("http2"),Jxe=HD(),_D=VD(),Wxe=GD(),zxe=J5(),Vxe=(r,e,t)=>new _D(r,e,t),Xxe=(r,e,t)=>{let i=new _D(r,e,t);return i.end(),i};W5.exports={...qxe,ClientRequest:_D,IncomingMessage:Wxe,...Jxe,request:Vxe,get:Xxe,auto:zxe}});var eR=I($D=>{"use strict";Object.defineProperty($D,"__esModule",{value:!0});var V5=Ya();$D.default=r=>V5.default.nodeStream(r)&&V5.default.function_(r.getBoundary)});var $5=I(tR=>{"use strict";Object.defineProperty(tR,"__esModule",{value:!0});var Z5=J("fs"),_5=J("util"),X5=Ya(),Zxe=eR(),_xe=_5.promisify(Z5.stat);tR.default=async(r,e)=>{if(e&&"content-length"in e)return Number(e["content-length"]);if(!r)return 0;if(X5.default.string(r))return Buffer.byteLength(r);if(X5.default.buffer(r))return r.length;if(Zxe.default(r))return _5.promisify(r.getLength.bind(r))();if(r instanceof Z5.ReadStream){let{size:t}=await _xe(r.path);return t===0?void 0:t}}});var iR=I(rR=>{"use strict";Object.defineProperty(rR,"__esModule",{value:!0});function $xe(r,e,t){let i={};for(let n of t)i[n]=(...s)=>{e.emit(n,...s)},r.on(n,i[n]);return()=>{for(let n of t)r.off(n,i[n])}}rR.default=$xe});var e6=I(nR=>{"use strict";Object.defineProperty(nR,"__esModule",{value:!0});nR.default=()=>{let r=[];return{once(e,t,i){e.once(t,i),r.push({origin:e,event:t,fn:i})},unhandleAll(){for(let e of r){let{origin:t,event:i,fn:n}=e;t.removeListener(i,n)}r.length=0}}}});var r6=I(wC=>{"use strict";Object.defineProperty(wC,"__esModule",{value:!0});wC.TimeoutError=void 0;var eke=J("net"),tke=e6(),t6=Symbol("reentry"),rke=()=>{},eB=class extends Error{constructor(e,t){super(`Timeout awaiting '${t}' for ${e}ms`),this.event=t,this.name="TimeoutError",this.code="ETIMEDOUT"}};wC.TimeoutError=eB;wC.default=(r,e,t)=>{if(t6 in r)return rke;r[t6]=!0;let i=[],{once:n,unhandleAll:s}=tke.default(),o=(g,h,p)=>{var d;let m=setTimeout(h,g,g,p);(d=m.unref)===null||d===void 0||d.call(m);let y=()=>{clearTimeout(m)};return i.push(y),y},{host:a,hostname:l}=t,c=(g,h)=>{r.destroy(new eB(g,h))},u=()=>{for(let g of i)g();s()};if(r.once("error",g=>{if(u(),r.listenerCount("error")===0)throw g}),r.once("close",u),n(r,"response",g=>{n(g,"end",u)}),typeof e.request<"u"&&o(e.request,c,"request"),typeof e.socket<"u"){let g=()=>{c(e.socket,"socket")};r.setTimeout(e.socket,g),i.push(()=>{r.removeListener("timeout",g)})}return n(r,"socket",g=>{var h;let{socketPath:p}=r;if(g.connecting){let d=Boolean(p!=null?p:eke.isIP((h=l!=null?l:a)!==null&&h!==void 0?h:"")!==0);if(typeof e.lookup<"u"&&!d&&typeof g.address().address>"u"){let m=o(e.lookup,c,"lookup");n(g,"lookup",m)}if(typeof e.connect<"u"){let m=()=>o(e.connect,c,"connect");d?n(g,"connect",m()):n(g,"lookup",y=>{y===null&&n(g,"connect",m())})}typeof e.secureConnect<"u"&&t.protocol==="https:"&&n(g,"connect",()=>{let m=o(e.secureConnect,c,"secureConnect");n(g,"secureConnect",m)})}if(typeof e.send<"u"){let d=()=>o(e.send,c,"send");g.connecting?n(g,"connect",()=>{n(r,"upload-complete",d())}):n(r,"upload-complete",d())}}),typeof e.response<"u"&&n(r,"upload-complete",()=>{let g=o(e.response,c,"response");n(r,"response",g)}),u}});var n6=I(sR=>{"use strict";Object.defineProperty(sR,"__esModule",{value:!0});var i6=Ya();sR.default=r=>{r=r;let e={protocol:r.protocol,hostname:i6.default.string(r.hostname)&&r.hostname.startsWith("[")?r.hostname.slice(1,-1):r.hostname,host:r.host,hash:r.hash,search:r.search,pathname:r.pathname,href:r.href,path:`${r.pathname||""}${r.search||""}`};return i6.default.string(r.port)&&r.port.length>0&&(e.port=Number(r.port)),(r.username||r.password)&&(e.auth=`${r.username||""}:${r.password||""}`),e}});var s6=I(oR=>{"use strict";Object.defineProperty(oR,"__esModule",{value:!0});var ike=J("url"),nke=["protocol","host","hostname","port","pathname","search"];oR.default=(r,e)=>{var t,i;if(e.path){if(e.pathname)throw new TypeError("Parameters `path` and `pathname` are mutually exclusive.");if(e.search)throw new TypeError("Parameters `path` and `search` are mutually exclusive.");if(e.searchParams)throw new TypeError("Parameters `path` and `searchParams` are mutually exclusive.")}if(e.search&&e.searchParams)throw new TypeError("Parameters `search` and `searchParams` are mutually exclusive.");if(!r){if(!e.protocol)throw new TypeError("No URL protocol specified");r=`${e.protocol}//${(i=(t=e.hostname)!==null&&t!==void 0?t:e.host)!==null&&i!==void 0?i:""}`}let n=new ike.URL(r);if(e.path){let s=e.path.indexOf("?");s===-1?e.pathname=e.path:(e.pathname=e.path.slice(0,s),e.search=e.path.slice(s+1)),delete e.path}for(let s of nke)e[s]&&(n[s]=e[s].toString());return n}});var o6=I(AR=>{"use strict";Object.defineProperty(AR,"__esModule",{value:!0});var aR=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,t){typeof e=="object"?this.weakMap.set(e,t):this.map.set(e,t)}get(e){return typeof e=="object"?this.weakMap.get(e):this.map.get(e)}has(e){return typeof e=="object"?this.weakMap.has(e):this.map.has(e)}};AR.default=aR});var cR=I(lR=>{"use strict";Object.defineProperty(lR,"__esModule",{value:!0});var ske=async r=>{let e=[],t=0;for await(let i of r)e.push(i),t+=Buffer.byteLength(i);return Buffer.isBuffer(e[0])?Buffer.concat(e,t):Buffer.from(e.join(""))};lR.default=ske});var A6=I(Kc=>{"use strict";Object.defineProperty(Kc,"__esModule",{value:!0});Kc.dnsLookupIpVersionToFamily=Kc.isDnsLookupIpVersion=void 0;var a6={auto:0,ipv4:4,ipv6:6};Kc.isDnsLookupIpVersion=r=>r in a6;Kc.dnsLookupIpVersionToFamily=r=>{if(Kc.isDnsLookupIpVersion(r))return a6[r];throw new Error("Invalid DNS lookup IP version")}});var uR=I(tB=>{"use strict";Object.defineProperty(tB,"__esModule",{value:!0});tB.isResponseOk=void 0;tB.isResponseOk=r=>{let{statusCode:e}=r,t=r.request.options.followRedirect?299:399;return e>=200&&e<=t||e===304}});var c6=I(gR=>{"use strict";Object.defineProperty(gR,"__esModule",{value:!0});var l6=new Set;gR.default=r=>{l6.has(r)||(l6.add(r),process.emitWarning(`Got: ${r}`,{type:"DeprecationWarning"}))}});var u6=I(fR=>{"use strict";Object.defineProperty(fR,"__esModule",{value:!0});var dr=Ya(),oke=(r,e)=>{if(dr.default.null_(r.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");dr.assert.any([dr.default.string,dr.default.undefined],r.encoding),dr.assert.any([dr.default.boolean,dr.default.undefined],r.resolveBodyOnly),dr.assert.any([dr.default.boolean,dr.default.undefined],r.methodRewriting),dr.assert.any([dr.default.boolean,dr.default.undefined],r.isStream),dr.assert.any([dr.default.string,dr.default.undefined],r.responseType),r.responseType===void 0&&(r.responseType="text");let{retry:t}=r;if(e?r.retry={...e.retry}:r.retry={calculateDelay:i=>i.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},dr.default.object(t)?(r.retry={...r.retry,...t},r.retry.methods=[...new Set(r.retry.methods.map(i=>i.toUpperCase()))],r.retry.statusCodes=[...new Set(r.retry.statusCodes)],r.retry.errorCodes=[...new Set(r.retry.errorCodes)]):dr.default.number(t)&&(r.retry.limit=t),dr.default.undefined(r.retry.maxRetryAfter)&&(r.retry.maxRetryAfter=Math.min(...[r.timeout.request,r.timeout.connect].filter(dr.default.number))),dr.default.object(r.pagination)){e&&(r.pagination={...e.pagination,...r.pagination});let{pagination:i}=r;if(!dr.default.function_(i.transform))throw new Error("`options.pagination.transform` must be implemented");if(!dr.default.function_(i.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!dr.default.function_(i.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!dr.default.function_(i.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return r.responseType==="json"&&r.headers.accept===void 0&&(r.headers.accept="application/json"),r};fR.default=oke});var g6=I(BC=>{"use strict";Object.defineProperty(BC,"__esModule",{value:!0});BC.retryAfterStatusCodes=void 0;BC.retryAfterStatusCodes=new Set([413,429,503]);var ake=({attemptCount:r,retryOptions:e,error:t,retryAfter:i})=>{if(r>e.limit)return 0;let n=e.methods.includes(t.options.method),s=e.errorCodes.includes(t.code),o=t.response&&e.statusCodes.includes(t.response.statusCode);if(!n||!s&&!o)return 0;if(t.response){if(i)return e.maxRetryAfter===void 0||i>e.maxRetryAfter?0:i;if(t.response.statusCode===413)return 0}let a=Math.random()*100;return 2**(r-1)*1e3+a};BC.default=ake});var SC=I(Ut=>{"use strict";Object.defineProperty(Ut,"__esModule",{value:!0});Ut.UnsupportedProtocolError=Ut.ReadError=Ut.TimeoutError=Ut.UploadError=Ut.CacheError=Ut.HTTPError=Ut.MaxRedirectsError=Ut.RequestError=Ut.setNonEnumerableProperties=Ut.knownHookEvents=Ut.withoutBody=Ut.kIsNormalizedAlready=void 0;var f6=J("util"),h6=J("stream"),Ake=J("fs"),zA=J("url"),p6=J("http"),hR=J("http"),lke=J("https"),cke=kz(),uke=Oz(),d6=p5(),gke=E5(),fke=z5(),hke=Xw(),Ce=Ya(),pke=$5(),C6=eR(),dke=iR(),m6=r6(),Cke=n6(),E6=s6(),mke=o6(),Eke=cR(),I6=A6(),Ike=uR(),VA=c6(),yke=u6(),wke=g6(),pR,xi=Symbol("request"),nB=Symbol("response"),jf=Symbol("responseSize"),Gf=Symbol("downloadedSize"),Yf=Symbol("bodySize"),qf=Symbol("uploadedSize"),rB=Symbol("serverResponsesPiped"),y6=Symbol("unproxyEvents"),w6=Symbol("isFromCache"),dR=Symbol("cancelTimeouts"),B6=Symbol("startedReading"),Jf=Symbol("stopReading"),iB=Symbol("triggerRead"),XA=Symbol("body"),bC=Symbol("jobs"),b6=Symbol("originalResponse"),Q6=Symbol("retryTimeout");Ut.kIsNormalizedAlready=Symbol("isNormalizedAlready");var Bke=Ce.default.string(process.versions.brotli);Ut.withoutBody=new Set(["GET","HEAD"]);Ut.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];function bke(r){for(let e in r){let t=r[e];if(!Ce.default.string(t)&&!Ce.default.number(t)&&!Ce.default.boolean(t)&&!Ce.default.null_(t)&&!Ce.default.undefined(t))throw new TypeError(`The \`searchParams\` value '${String(t)}' must be a string, number, boolean or null`)}}function Qke(r){return Ce.default.object(r)&&!("statusCode"in r)}var CR=new mke.default,Ske=async r=>new Promise((e,t)=>{let i=n=>{t(n)};r.pending||e(),r.once("error",i),r.once("ready",()=>{r.off("error",i),e()})}),vke=new Set([300,301,302,303,304,307,308]),Pke=["context","body","json","form"];Ut.setNonEnumerableProperties=(r,e)=>{let t={};for(let i of r)if(!!i)for(let n of Pke)n in i&&(t[n]={writable:!0,configurable:!0,enumerable:!1,value:i[n]});Object.defineProperties(e,t)};var _r=class extends Error{constructor(e,t,i){var n;if(super(e),Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=t.code,i instanceof uB?(Object.defineProperty(this,"request",{enumerable:!1,value:i}),Object.defineProperty(this,"response",{enumerable:!1,value:i[nB]}),Object.defineProperty(this,"options",{enumerable:!1,value:i.options})):Object.defineProperty(this,"options",{enumerable:!1,value:i}),this.timings=(n=this.request)===null||n===void 0?void 0:n.timings,Ce.default.string(t.stack)&&Ce.default.string(this.stack)){let s=this.stack.indexOf(this.message)+this.message.length,o=this.stack.slice(s).split(` +`).reverse(),a=t.stack.slice(t.stack.indexOf(t.message)+t.message.length).split(` +`).reverse();for(;a.length!==0&&a[0]===o[0];)o.shift();this.stack=`${this.stack.slice(0,s)}${o.reverse().join(` +`)}${a.reverse().join(` +`)}`}}};Ut.RequestError=_r;var sB=class extends _r{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e),this.name="MaxRedirectsError"}};Ut.MaxRedirectsError=sB;var oB=class extends _r{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request),this.name="HTTPError"}};Ut.HTTPError=oB;var aB=class extends _r{constructor(e,t){super(e.message,e,t),this.name="CacheError"}};Ut.CacheError=aB;var AB=class extends _r{constructor(e,t){super(e.message,e,t),this.name="UploadError"}};Ut.UploadError=AB;var lB=class extends _r{constructor(e,t,i){super(e.message,e,i),this.name="TimeoutError",this.event=e.event,this.timings=t}};Ut.TimeoutError=lB;var QC=class extends _r{constructor(e,t){super(e.message,e,t),this.name="ReadError"}};Ut.ReadError=QC;var cB=class extends _r{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e),this.name="UnsupportedProtocolError"}};Ut.UnsupportedProtocolError=cB;var xke=["socket","connect","continue","information","upgrade","timeout"],uB=class extends h6.Duplex{constructor(e,t={},i){super({autoDestroy:!1,highWaterMark:0}),this[Gf]=0,this[qf]=0,this.requestInitialized=!1,this[rB]=new Set,this.redirects=[],this[Jf]=!1,this[iB]=!1,this[bC]=[],this.retryCount=0,this._progressCallbacks=[];let n=()=>this._unlockWrite(),s=()=>this._lockWrite();this.on("pipe",c=>{c.prependListener("data",n),c.on("data",s),c.prependListener("end",n),c.on("end",s)}),this.on("unpipe",c=>{c.off("data",n),c.off("data",s),c.off("end",n),c.off("end",s)}),this.on("pipe",c=>{c instanceof hR.IncomingMessage&&(this.options.headers={...c.headers,...this.options.headers})});let{json:o,body:a,form:l}=t;if((o||a||l)&&this._lockWrite(),Ut.kIsNormalizedAlready in t)this.options=t;else try{this.options=this.constructor.normalizeArguments(e,t,i)}catch(c){Ce.default.nodeStream(t.body)&&t.body.destroy(),this.destroy(c);return}(async()=>{var c;try{this.options.body instanceof Ake.ReadStream&&await Ske(this.options.body);let{url:u}=this.options;if(!u)throw new TypeError("Missing `url` property");if(this.requestUrl=u.toString(),decodeURI(this.requestUrl),await this._finalizeBody(),await this._makeRequest(),this.destroyed){(c=this[xi])===null||c===void 0||c.destroy();return}for(let g of this[bC])g();this[bC].length=0,this.requestInitialized=!0}catch(u){if(u instanceof _r){this._beforeError(u);return}this.destroyed||this.destroy(u)}})()}static normalizeArguments(e,t,i){var n,s,o,a,l;let c=t;if(Ce.default.object(e)&&!Ce.default.urlInstance(e))t={...i,...e,...t};else{if(e&&t&&t.url!==void 0)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");t={...i,...t},e!==void 0&&(t.url=e),Ce.default.urlInstance(t.url)&&(t.url=new zA.URL(t.url.toString()))}if(t.cache===!1&&(t.cache=void 0),t.dnsCache===!1&&(t.dnsCache=void 0),Ce.assert.any([Ce.default.string,Ce.default.undefined],t.method),Ce.assert.any([Ce.default.object,Ce.default.undefined],t.headers),Ce.assert.any([Ce.default.string,Ce.default.urlInstance,Ce.default.undefined],t.prefixUrl),Ce.assert.any([Ce.default.object,Ce.default.undefined],t.cookieJar),Ce.assert.any([Ce.default.object,Ce.default.string,Ce.default.undefined],t.searchParams),Ce.assert.any([Ce.default.object,Ce.default.string,Ce.default.undefined],t.cache),Ce.assert.any([Ce.default.object,Ce.default.number,Ce.default.undefined],t.timeout),Ce.assert.any([Ce.default.object,Ce.default.undefined],t.context),Ce.assert.any([Ce.default.object,Ce.default.undefined],t.hooks),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.decompress),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.ignoreInvalidCookies),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.followRedirect),Ce.assert.any([Ce.default.number,Ce.default.undefined],t.maxRedirects),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.throwHttpErrors),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.http2),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.allowGetBody),Ce.assert.any([Ce.default.string,Ce.default.undefined],t.localAddress),Ce.assert.any([I6.isDnsLookupIpVersion,Ce.default.undefined],t.dnsLookupIpVersion),Ce.assert.any([Ce.default.object,Ce.default.undefined],t.https),Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.rejectUnauthorized),t.https&&(Ce.assert.any([Ce.default.boolean,Ce.default.undefined],t.https.rejectUnauthorized),Ce.assert.any([Ce.default.function_,Ce.default.undefined],t.https.checkServerIdentity),Ce.assert.any([Ce.default.string,Ce.default.object,Ce.default.array,Ce.default.undefined],t.https.certificateAuthority),Ce.assert.any([Ce.default.string,Ce.default.object,Ce.default.array,Ce.default.undefined],t.https.key),Ce.assert.any([Ce.default.string,Ce.default.object,Ce.default.array,Ce.default.undefined],t.https.certificate),Ce.assert.any([Ce.default.string,Ce.default.undefined],t.https.passphrase),Ce.assert.any([Ce.default.string,Ce.default.buffer,Ce.default.array,Ce.default.undefined],t.https.pfx)),Ce.assert.any([Ce.default.object,Ce.default.undefined],t.cacheOptions),Ce.default.string(t.method)?t.method=t.method.toUpperCase():t.method="GET",t.headers===(i==null?void 0:i.headers)?t.headers={...t.headers}:t.headers=hke({...i==null?void 0:i.headers,...t.headers}),"slashes"in t)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in t)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in t&&t.searchParams&&t.searchParams!==(i==null?void 0:i.searchParams)){let p;if(Ce.default.string(t.searchParams)||t.searchParams instanceof zA.URLSearchParams)p=new zA.URLSearchParams(t.searchParams);else{bke(t.searchParams),p=new zA.URLSearchParams;for(let d in t.searchParams){let m=t.searchParams[d];m===null?p.append(d,""):m!==void 0&&p.append(d,m)}}(n=i==null?void 0:i.searchParams)===null||n===void 0||n.forEach((d,m)=>{p.has(m)||p.append(m,d)}),t.searchParams=p}if(t.username=(s=t.username)!==null&&s!==void 0?s:"",t.password=(o=t.password)!==null&&o!==void 0?o:"",Ce.default.undefined(t.prefixUrl)?t.prefixUrl=(a=i==null?void 0:i.prefixUrl)!==null&&a!==void 0?a:"":(t.prefixUrl=t.prefixUrl.toString(),t.prefixUrl!==""&&!t.prefixUrl.endsWith("/")&&(t.prefixUrl+="/")),Ce.default.string(t.url)){if(t.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");t.url=E6.default(t.prefixUrl+t.url,t)}else(Ce.default.undefined(t.url)&&t.prefixUrl!==""||t.protocol)&&(t.url=E6.default(t.prefixUrl,t));if(t.url){"port"in t&&delete t.port;let{prefixUrl:p}=t;Object.defineProperty(t,"prefixUrl",{set:m=>{let y=t.url;if(!y.href.startsWith(m))throw new Error(`Cannot change \`prefixUrl\` from ${p} to ${m}: ${y.href}`);t.url=new zA.URL(m+y.href.slice(p.length)),p=m},get:()=>p});let{protocol:d}=t.url;if(d==="unix:"&&(d="http:",t.url=new zA.URL(`http://unix${t.url.pathname}${t.url.search}`)),t.searchParams&&(t.url.search=t.searchParams.toString()),d!=="http:"&&d!=="https:")throw new cB(t);t.username===""?t.username=t.url.username:t.url.username=t.username,t.password===""?t.password=t.url.password:t.url.password=t.password}let{cookieJar:u}=t;if(u){let{setCookie:p,getCookieString:d}=u;Ce.assert.function_(p),Ce.assert.function_(d),p.length===4&&d.length===0&&(p=f6.promisify(p.bind(t.cookieJar)),d=f6.promisify(d.bind(t.cookieJar)),t.cookieJar={setCookie:p,getCookieString:d})}let{cache:g}=t;if(g&&(CR.has(g)||CR.set(g,new d6((p,d)=>{let m=p[xi](p,d);return Ce.default.promise(m)&&(m.once=(y,B)=>{if(y==="error")m.catch(B);else if(y==="abort")(async()=>{try{(await m).once("abort",B)}catch{}})();else throw new Error(`Unknown HTTP2 promise event: ${y}`);return m}),m},g))),t.cacheOptions={...t.cacheOptions},t.dnsCache===!0)pR||(pR=new uke.default),t.dnsCache=pR;else if(!Ce.default.undefined(t.dnsCache)&&!t.dnsCache.lookup)throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${Ce.default(t.dnsCache)}`);Ce.default.number(t.timeout)?t.timeout={request:t.timeout}:i&&t.timeout!==i.timeout?t.timeout={...i.timeout,...t.timeout}:t.timeout={...t.timeout},t.context||(t.context={});let h=t.hooks===(i==null?void 0:i.hooks);t.hooks={...t.hooks};for(let p of Ut.knownHookEvents)if(p in t.hooks)if(Ce.default.array(t.hooks[p]))t.hooks[p]=[...t.hooks[p]];else throw new TypeError(`Parameter \`${p}\` must be an Array, got ${Ce.default(t.hooks[p])}`);else t.hooks[p]=[];if(i&&!h)for(let p of Ut.knownHookEvents)i.hooks[p].length>0&&(t.hooks[p]=[...i.hooks[p],...t.hooks[p]]);if("family"in t&&VA.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),i!=null&&i.https&&(t.https={...i.https,...t.https}),"rejectUnauthorized"in t&&VA.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in t&&VA.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in t&&VA.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in t&&VA.default('"options.key" was never documented, please use "options.https.key"'),"cert"in t&&VA.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in t&&VA.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in t&&VA.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in t)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(t.agent){for(let p in t.agent)if(p!=="http"&&p!=="https"&&p!=="http2")throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${p}\``)}return t.maxRedirects=(l=t.maxRedirects)!==null&&l!==void 0?l:0,Ut.setNonEnumerableProperties([i,c],t),yke.default(t,i)}_lockWrite(){let e=()=>{throw new TypeError("The payload has been already provided")};this.write=e,this.end=e}_unlockWrite(){this.write=super.write,this.end=super.end}async _finalizeBody(){let{options:e}=this,{headers:t}=e,i=!Ce.default.undefined(e.form),n=!Ce.default.undefined(e.json),s=!Ce.default.undefined(e.body),o=i||n||s,a=Ut.withoutBody.has(e.method)&&!(e.method==="GET"&&e.allowGetBody);if(this._cannotHaveBody=a,o){if(a)throw new TypeError(`The \`${e.method}\` method cannot be used with a body`);if([s,i,n].filter(l=>l).length>1)throw new TypeError("The `body`, `json` and `form` options are mutually exclusive");if(s&&!(e.body instanceof h6.Readable)&&!Ce.default.string(e.body)&&!Ce.default.buffer(e.body)&&!C6.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(i&&!Ce.default.object(e.form))throw new TypeError("The `form` option must be an Object");{let l=!Ce.default.string(t["content-type"]);s?(C6.default(e.body)&&l&&(t["content-type"]=`multipart/form-data; boundary=${e.body.getBoundary()}`),this[XA]=e.body):i?(l&&(t["content-type"]="application/x-www-form-urlencoded"),this[XA]=new zA.URLSearchParams(e.form).toString()):(l&&(t["content-type"]="application/json"),this[XA]=e.stringifyJson(e.json));let c=await pke.default(this[XA],e.headers);Ce.default.undefined(t["content-length"])&&Ce.default.undefined(t["transfer-encoding"])&&!a&&!Ce.default.undefined(c)&&(t["content-length"]=String(c))}}else a?this._lockWrite():this._unlockWrite();this[Yf]=Number(t["content-length"])||void 0}async _onResponseBase(e){let{options:t}=this,{url:i}=t;this[b6]=e,t.decompress&&(e=gke(e));let n=e.statusCode,s=e;s.statusMessage=s.statusMessage?s.statusMessage:p6.STATUS_CODES[n],s.url=t.url.toString(),s.requestUrl=this.requestUrl,s.redirectUrls=this.redirects,s.request=this,s.isFromCache=e.fromCache||!1,s.ip=this.ip,s.retryCount=this.retryCount,this[w6]=s.isFromCache,this[jf]=Number(e.headers["content-length"])||void 0,this[nB]=e,e.once("end",()=>{this[jf]=this[Gf],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",a=>{e.destroy(),this._beforeError(new QC(a,this))}),e.once("aborted",()=>{this._beforeError(new QC({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);let o=e.headers["set-cookie"];if(Ce.default.object(t.cookieJar)&&o){let a=o.map(async l=>t.cookieJar.setCookie(l,i.toString()));t.ignoreInvalidCookies&&(a=a.map(async l=>l.catch(()=>{})));try{await Promise.all(a)}catch(l){this._beforeError(l);return}}if(t.followRedirect&&e.headers.location&&vke.has(n)){if(e.resume(),this[xi]&&(this[dR](),delete this[xi],this[y6]()),(n===303&&t.method!=="GET"&&t.method!=="HEAD"||!t.methodRewriting)&&(t.method="GET","body"in t&&delete t.body,"json"in t&&delete t.json,"form"in t&&delete t.form,this[XA]=void 0,delete t.headers["content-length"]),this.redirects.length>=t.maxRedirects){this._beforeError(new sB(this));return}try{let l=Buffer.from(e.headers.location,"binary").toString(),c=new zA.URL(l,i),u=c.toString();decodeURI(u),c.hostname!==i.hostname||c.port!==i.port?("host"in t.headers&&delete t.headers.host,"cookie"in t.headers&&delete t.headers.cookie,"authorization"in t.headers&&delete t.headers.authorization,(t.username||t.password)&&(t.username="",t.password="")):(c.username=t.username,c.password=t.password),this.redirects.push(u),t.url=c;for(let g of t.hooks.beforeRedirect)await g(t,s);this.emit("redirect",s,t),await this._makeRequest()}catch(l){this._beforeError(l);return}return}if(t.isStream&&t.throwHttpErrors&&!Ike.isResponseOk(s)){this._beforeError(new oB(s));return}e.on("readable",()=>{this[iB]&&this._read()}),this.on("resume",()=>{e.resume()}),this.on("pause",()=>{e.pause()}),e.once("end",()=>{this.push(null)}),this.emit("response",e);for(let a of this[rB])if(!a.headersSent){for(let l in e.headers){let c=t.decompress?l!=="content-encoding":!0,u=e.headers[l];c&&a.setHeader(l,u)}a.statusCode=n}}async _onResponse(e){try{await this._onResponseBase(e)}catch(t){this._beforeError(t)}}_onRequest(e){let{options:t}=this,{timeout:i,url:n}=t;cke.default(e),this[dR]=m6.default(e,i,n);let s=t.cache?"cacheableResponse":"response";e.once(s,l=>{this._onResponse(l)}),e.once("error",l=>{var c;e.destroy(),(c=e.res)===null||c===void 0||c.removeAllListeners("end"),l=l instanceof m6.TimeoutError?new lB(l,this.timings,this):new _r(l.message,l,this),this._beforeError(l)}),this[y6]=dke.default(e,this,xke),this[xi]=e,this.emit("uploadProgress",this.uploadProgress);let o=this[XA],a=this.redirects.length===0?this:e;Ce.default.nodeStream(o)?(o.pipe(a),o.once("error",l=>{this._beforeError(new AB(l,this))})):(this._unlockWrite(),Ce.default.undefined(o)?(this._cannotHaveBody||this._noPipe)&&(a.end(),this._lockWrite()):(this._writeRequest(o,void 0,()=>{}),a.end(),this._lockWrite())),this.emit("request",e)}async _createCacheableRequest(e,t){return new Promise((i,n)=>{Object.assign(t,Cke.default(e)),delete t.url;let s,o=CR.get(t.cache)(t,async a=>{a._readableState.autoDestroy=!1,s&&(await s).emit("cacheableResponse",a),i(a)});t.url=e,o.once("error",n),o.once("request",async a=>{s=a,i(s)})})}async _makeRequest(){var e,t,i,n,s;let{options:o}=this,{headers:a}=o;for(let B in a)if(Ce.default.undefined(a[B]))delete a[B];else if(Ce.default.null_(a[B]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${B}\` header`);if(o.decompress&&Ce.default.undefined(a["accept-encoding"])&&(a["accept-encoding"]=Bke?"gzip, deflate, br":"gzip, deflate"),o.cookieJar){let B=await o.cookieJar.getCookieString(o.url.toString());Ce.default.nonEmptyString(B)&&(o.headers.cookie=B)}for(let B of o.hooks.beforeRequest){let S=await B(o);if(!Ce.default.undefined(S)){o.request=()=>S;break}}o.body&&this[XA]!==o.body&&(this[XA]=o.body);let{agent:l,request:c,timeout:u,url:g}=o;if(o.dnsCache&&!("lookup"in o)&&(o.lookup=o.dnsCache.lookup),g.hostname==="unix"){let B=/(?<socketPath>.+?):(?<path>.+)/.exec(`${g.pathname}${g.search}`);if(B!=null&&B.groups){let{socketPath:S,path:x}=B.groups;Object.assign(o,{socketPath:S,path:x,host:""})}}let h=g.protocol==="https:",p;o.http2?p=fke.auto:p=h?lke.request:p6.request;let d=(e=o.request)!==null&&e!==void 0?e:p,m=o.cache?this._createCacheableRequest:d;l&&!o.http2&&(o.agent=l[h?"https":"http"]),o[xi]=d,delete o.request,delete o.timeout;let y=o;if(y.shared=(t=o.cacheOptions)===null||t===void 0?void 0:t.shared,y.cacheHeuristic=(i=o.cacheOptions)===null||i===void 0?void 0:i.cacheHeuristic,y.immutableMinTimeToLive=(n=o.cacheOptions)===null||n===void 0?void 0:n.immutableMinTimeToLive,y.ignoreCargoCult=(s=o.cacheOptions)===null||s===void 0?void 0:s.ignoreCargoCult,o.dnsLookupIpVersion!==void 0)try{y.family=I6.dnsLookupIpVersionToFamily(o.dnsLookupIpVersion)}catch{throw new Error("Invalid `dnsLookupIpVersion` option value")}o.https&&("rejectUnauthorized"in o.https&&(y.rejectUnauthorized=o.https.rejectUnauthorized),o.https.checkServerIdentity&&(y.checkServerIdentity=o.https.checkServerIdentity),o.https.certificateAuthority&&(y.ca=o.https.certificateAuthority),o.https.certificate&&(y.cert=o.https.certificate),o.https.key&&(y.key=o.https.key),o.https.passphrase&&(y.passphrase=o.https.passphrase),o.https.pfx&&(y.pfx=o.https.pfx));try{let B=await m(g,y);Ce.default.undefined(B)&&(B=p(g,y)),o.request=c,o.timeout=u,o.agent=l,o.https&&("rejectUnauthorized"in o.https&&delete y.rejectUnauthorized,o.https.checkServerIdentity&&delete y.checkServerIdentity,o.https.certificateAuthority&&delete y.ca,o.https.certificate&&delete y.cert,o.https.key&&delete y.key,o.https.passphrase&&delete y.passphrase,o.https.pfx&&delete y.pfx),Qke(B)?this._onRequest(B):this.writable?(this.once("finish",()=>{this._onResponse(B)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(B)}catch(B){throw B instanceof d6.CacheError?new aB(B,this):new _r(B.message,B,this)}}async _error(e){try{for(let t of this.options.hooks.beforeError)e=await t(e)}catch(t){e=new _r(t.message,t,this)}this.destroy(e)}_beforeError(e){if(this[Jf])return;let{options:t}=this,i=this.retryCount+1;this[Jf]=!0,e instanceof _r||(e=new _r(e.message,e,this));let n=e,{response:s}=n;(async()=>{if(s&&!s.body){s.setEncoding(this._readableState.encoding);try{s.rawBody=await Eke.default(s),s.body=s.rawBody.toString()}catch{}}if(this.listenerCount("retry")!==0){let o;try{let a;s&&"retry-after"in s.headers&&(a=Number(s.headers["retry-after"]),Number.isNaN(a)?(a=Date.parse(s.headers["retry-after"])-Date.now(),a<=0&&(a=1)):a*=1e3),o=await t.retry.calculateDelay({attemptCount:i,retryOptions:t.retry,error:n,retryAfter:a,computedValue:wke.default({attemptCount:i,retryOptions:t.retry,error:n,retryAfter:a,computedValue:0})})}catch(a){this._error(new _r(a.message,a,this));return}if(o){let a=async()=>{try{for(let l of this.options.hooks.beforeRetry)await l(this.options,n,i)}catch(l){this._error(new _r(l.message,e,this));return}this.destroyed||(this.destroy(),this.emit("retry",i,e))};this[Q6]=setTimeout(a,o);return}}this._error(n)})()}_read(){this[iB]=!0;let e=this[nB];if(e&&!this[Jf]){e.readableLength&&(this[iB]=!1);let t;for(;(t=e.read())!==null;){this[Gf]+=t.length,this[B6]=!0;let i=this.downloadProgress;i.percent<1&&this.emit("downloadProgress",i),this.push(t)}}}_write(e,t,i){let n=()=>{this._writeRequest(e,t,i)};this.requestInitialized?n():this[bC].push(n)}_writeRequest(e,t,i){this[xi].destroyed||(this._progressCallbacks.push(()=>{this[qf]+=Buffer.byteLength(e,t);let n=this.uploadProgress;n.percent<1&&this.emit("uploadProgress",n)}),this[xi].write(e,t,n=>{!n&&this._progressCallbacks.length>0&&this._progressCallbacks.shift()(),i(n)}))}_final(e){let t=()=>{for(;this._progressCallbacks.length!==0;)this._progressCallbacks.shift()();if(!(xi in this)){e();return}if(this[xi].destroyed){e();return}this[xi].end(i=>{i||(this[Yf]=this[qf],this.emit("uploadProgress",this.uploadProgress),this[xi].emit("upload-complete")),e(i)})};this.requestInitialized?t():this[bC].push(t)}_destroy(e,t){var i;this[Jf]=!0,clearTimeout(this[Q6]),xi in this&&(this[dR](),!((i=this[nB])===null||i===void 0)&&i.complete||this[xi].destroy()),e!==null&&!Ce.default.undefined(e)&&!(e instanceof _r)&&(e=new _r(e.message,e,this)),t(e)}get _isAboutToError(){return this[Jf]}get ip(){var e;return(e=this.socket)===null||e===void 0?void 0:e.remoteAddress}get aborted(){var e,t,i;return((t=(e=this[xi])===null||e===void 0?void 0:e.destroyed)!==null&&t!==void 0?t:this.destroyed)&&!(!((i=this[b6])===null||i===void 0)&&i.complete)}get socket(){var e,t;return(t=(e=this[xi])===null||e===void 0?void 0:e.socket)!==null&&t!==void 0?t:void 0}get downloadProgress(){let e;return this[jf]?e=this[Gf]/this[jf]:this[jf]===this[Gf]?e=1:e=0,{percent:e,transferred:this[Gf],total:this[jf]}}get uploadProgress(){let e;return this[Yf]?e=this[qf]/this[Yf]:this[Yf]===this[qf]?e=1:e=0,{percent:e,transferred:this[qf],total:this[Yf]}}get timings(){var e;return(e=this[xi])===null||e===void 0?void 0:e.timings}get isFromCache(){return this[w6]}pipe(e,t){if(this[B6])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof hR.ServerResponse&&this[rB].add(e),super.pipe(e,t)}unpipe(e){return e instanceof hR.ServerResponse&&this[rB].delete(e),super.unpipe(e),this}};Ut.default=uB});var vC=I(ao=>{"use strict";var kke=ao&&ao.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),Dke=ao&&ao.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&kke(e,r,t)};Object.defineProperty(ao,"__esModule",{value:!0});ao.CancelError=ao.ParseError=void 0;var S6=SC(),mR=class extends S6.RequestError{constructor(e,t){let{options:i}=t.request;super(`${e.message} in "${i.url.toString()}"`,e,t.request),this.name="ParseError"}};ao.ParseError=mR;var ER=class extends S6.RequestError{constructor(e){super("Promise was canceled",{},e),this.name="CancelError"}get isCanceled(){return!0}};ao.CancelError=ER;Dke(SC(),ao)});var P6=I(IR=>{"use strict";Object.defineProperty(IR,"__esModule",{value:!0});var v6=vC(),Rke=(r,e,t,i)=>{let{rawBody:n}=r;try{if(e==="text")return n.toString(i);if(e==="json")return n.length===0?"":t(n.toString());if(e==="buffer")return n;throw new v6.ParseError({message:`Unknown body type '${e}'`,name:"Error"},r)}catch(s){throw new v6.ParseError(s,r)}};IR.default=Rke});var yR=I(ZA=>{"use strict";var Fke=ZA&&ZA.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),Nke=ZA&&ZA.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Fke(e,r,t)};Object.defineProperty(ZA,"__esModule",{value:!0});var Tke=J("events"),Lke=Ya(),Oke=Pz(),gB=vC(),x6=P6(),k6=SC(),Mke=iR(),Kke=cR(),D6=uR(),Uke=["request","response","redirect","uploadProgress","downloadProgress"];function R6(r){let e,t,i=new Tke.EventEmitter,n=new Oke((o,a,l)=>{let c=u=>{let g=new k6.default(void 0,r);g.retryCount=u,g._noPipe=!0,l(()=>g.destroy()),l.shouldReject=!1,l(()=>a(new gB.CancelError(g))),e=g,g.once("response",async d=>{var m;if(d.retryCount=u,d.request.aborted)return;let y;try{y=await Kke.default(g),d.rawBody=y}catch{return}if(g._isAboutToError)return;let B=((m=d.headers["content-encoding"])!==null&&m!==void 0?m:"").toLowerCase(),S=["gzip","deflate","br"].includes(B),{options:x}=g;if(S&&!x.decompress)d.body=y;else try{d.body=x6.default(d,x.responseType,x.parseJson,x.encoding)}catch(F){if(d.body=y.toString(),D6.isResponseOk(d)){g._beforeError(F);return}}try{for(let[F,H]of x.hooks.afterResponse.entries())d=await H(d,async q=>{let _=k6.default.normalizeArguments(void 0,{...q,retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1},x);_.hooks.afterResponse=_.hooks.afterResponse.slice(0,F);for(let W of _.hooks.beforeRetry)await W(_);let X=R6(_);return l(()=>{X.catch(()=>{}),X.cancel()}),X})}catch(F){g._beforeError(new gB.RequestError(F.message,F,g));return}if(!D6.isResponseOk(d)){g._beforeError(new gB.HTTPError(d));return}t=d,o(g.options.resolveBodyOnly?d.body:d)});let h=d=>{if(n.isCanceled)return;let{options:m}=g;if(d instanceof gB.HTTPError&&!m.throwHttpErrors){let{response:y}=d;o(g.options.resolveBodyOnly?y.body:y);return}a(d)};g.once("error",h);let p=g.options.body;g.once("retry",(d,m)=>{var y,B;if(p===((y=m.request)===null||y===void 0?void 0:y.options.body)&&Lke.default.nodeStream((B=m.request)===null||B===void 0?void 0:B.options.body)){h(m);return}c(d)}),Mke.default(g,i,Uke)};c(0)});n.on=(o,a)=>(i.on(o,a),n);let s=o=>{let a=(async()=>{await n;let{options:l}=t.request;return x6.default(t,o,l.parseJson,l.encoding)})();return Object.defineProperties(a,Object.getOwnPropertyDescriptors(n)),a};return n.json=()=>{let{headers:o}=e.options;return!e.writableFinished&&o.accept===void 0&&(o.accept="application/json"),s("json")},n.buffer=()=>s("buffer"),n.text=()=>s("text"),n}ZA.default=R6;Nke(vC(),ZA)});var F6=I(wR=>{"use strict";Object.defineProperty(wR,"__esModule",{value:!0});var Hke=vC();function jke(r,...e){let t=(async()=>{if(r instanceof Hke.RequestError)try{for(let n of e)if(n)for(let s of n)r=await s(r)}catch(n){r=n}throw r})(),i=()=>t;return t.json=i,t.text=i,t.buffer=i,t.on=i,t}wR.default=jke});var L6=I(BR=>{"use strict";Object.defineProperty(BR,"__esModule",{value:!0});var N6=Ya();function T6(r){for(let e of Object.values(r))(N6.default.plainObject(e)||N6.default.array(e))&&T6(e);return Object.freeze(r)}BR.default=T6});var M6=I(O6=>{"use strict";Object.defineProperty(O6,"__esModule",{value:!0})});var bR=I(bs=>{"use strict";var Gke=bs&&bs.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),Yke=bs&&bs.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Gke(e,r,t)};Object.defineProperty(bs,"__esModule",{value:!0});bs.defaultHandler=void 0;var K6=Ya(),Bs=yR(),qke=F6(),hB=SC(),Jke=L6(),Wke={RequestError:Bs.RequestError,CacheError:Bs.CacheError,ReadError:Bs.ReadError,HTTPError:Bs.HTTPError,MaxRedirectsError:Bs.MaxRedirectsError,TimeoutError:Bs.TimeoutError,ParseError:Bs.ParseError,CancelError:Bs.CancelError,UnsupportedProtocolError:Bs.UnsupportedProtocolError,UploadError:Bs.UploadError},zke=async r=>new Promise(e=>{setTimeout(e,r)}),{normalizeArguments:fB}=hB.default,U6=(...r)=>{let e;for(let t of r)e=fB(void 0,t,e);return e},Vke=r=>r.isStream?new hB.default(void 0,r):Bs.default(r),Xke=r=>"defaults"in r&&"options"in r.defaults,Zke=["get","post","put","patch","head","delete"];bs.defaultHandler=(r,e)=>e(r);var H6=(r,e)=>{if(r)for(let t of r)t(e)},j6=r=>{r._rawHandlers=r.handlers,r.handlers=r.handlers.map(i=>(n,s)=>{let o,a=i(n,l=>(o=s(l),o));if(a!==o&&!n.isStream&&o){let l=a,{then:c,catch:u,finally:g}=l;Object.setPrototypeOf(l,Object.getPrototypeOf(o)),Object.defineProperties(l,Object.getOwnPropertyDescriptors(o)),l.then=c,l.catch=u,l.finally=g}return a});let e=(i,n={},s)=>{var o,a;let l=0,c=u=>r.handlers[l++](u,l===r.handlers.length?Vke:c);if(K6.default.plainObject(i)){let u={...i,...n};hB.setNonEnumerableProperties([i,n],u),n=u,i=void 0}try{let u;try{H6(r.options.hooks.init,n),H6((o=n.hooks)===null||o===void 0?void 0:o.init,n)}catch(h){u=h}let g=fB(i,n,s!=null?s:r.options);if(g[hB.kIsNormalizedAlready]=!0,u)throw new Bs.RequestError(u.message,u,g);return c(g)}catch(u){if(n.isStream)throw u;return qke.default(u,r.options.hooks.beforeError,(a=n.hooks)===null||a===void 0?void 0:a.beforeError)}};e.extend=(...i)=>{let n=[r.options],s=[...r._rawHandlers],o;for(let a of i)Xke(a)?(n.push(a.defaults.options),s.push(...a.defaults._rawHandlers),o=a.defaults.mutableDefaults):(n.push(a),"handlers"in a&&s.push(...a.handlers),o=a.mutableDefaults);return s=s.filter(a=>a!==bs.defaultHandler),s.length===0&&s.push(bs.defaultHandler),j6({options:U6(...n),handlers:s,mutableDefaults:Boolean(o)})};let t=async function*(i,n){let s=fB(i,n,r.options);s.resolveBodyOnly=!1;let o=s.pagination;if(!K6.default.object(o))throw new TypeError("`options.pagination` must be implemented");let a=[],{countLimit:l}=o,c=0;for(;c<o.requestLimit;){c!==0&&await zke(o.backoff);let u=await e(void 0,void 0,s),g=await o.transform(u),h=[];for(let d of g)if(o.filter(d,a,h)&&(!o.shouldContinue(d,a,h)||(yield d,o.stackAllItems&&a.push(d),h.push(d),--l<=0)))return;let p=o.paginate(u,a,h);if(p===!1)return;p===u.request.options?s=u.request.options:p!==void 0&&(s=fB(void 0,p,s)),c++}};e.paginate=t,e.paginate.all=async(i,n)=>{let s=[];for await(let o of t(i,n))s.push(o);return s},e.paginate.each=t,e.stream=(i,n)=>e(i,{...n,isStream:!0});for(let i of Zke)e[i]=(n,s)=>e(n,{...s,method:i}),e.stream[i]=(n,s)=>e(n,{...s,method:i,isStream:!0});return Object.assign(e,Wke),Object.defineProperty(e,"defaults",{value:r.mutableDefaults?r:Jke.default(r),writable:r.mutableDefaults,configurable:r.mutableDefaults,enumerable:!0}),e.mergeOptions=U6,e};bs.default=j6;Yke(M6(),bs)});var dB=I((qa,pB)=>{"use strict";var _ke=qa&&qa.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),G6=qa&&qa.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&_ke(e,r,t)};Object.defineProperty(qa,"__esModule",{value:!0});var $ke=J("url"),Y6=bR(),eDe={options:{method:"GET",retry:{limit:2,methods:["GET","PUT","HEAD","DELETE","OPTIONS","TRACE"],statusCodes:[408,413,429,500,502,503,504,521,522,524],errorCodes:["ETIMEDOUT","ECONNRESET","EADDRINUSE","ECONNREFUSED","EPIPE","ENOTFOUND","ENETUNREACH","EAI_AGAIN"],maxRetryAfter:void 0,calculateDelay:({computedValue:r})=>r},timeout:{},headers:{"user-agent":"got (https://github.com/sindresorhus/got)"},hooks:{init:[],beforeRequest:[],beforeRedirect:[],beforeRetry:[],beforeError:[],afterResponse:[]},cache:void 0,dnsCache:void 0,decompress:!0,throwHttpErrors:!0,followRedirect:!0,isStream:!1,responseType:"text",resolveBodyOnly:!1,maxRedirects:10,prefixUrl:"",methodRewriting:!0,ignoreInvalidCookies:!1,context:{},http2:!1,allowGetBody:!1,https:void 0,pagination:{transform:r=>r.request.options.responseType==="json"?r.body:JSON.parse(r.body),paginate:r=>{if(!Reflect.has(r.headers,"link"))return!1;let e=r.headers.link.split(","),t;for(let i of e){let n=i.split(";");if(n[1].includes("next")){t=n[0].trimStart().trim(),t=t.slice(1,-1);break}}return t?{url:new $ke.URL(t)}:!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:1/0,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:r=>JSON.parse(r),stringifyJson:r=>JSON.stringify(r),cacheOptions:{}},handlers:[Y6.defaultHandler],mutableDefaults:!1},QR=Y6.default(eDe);qa.default=QR;pB.exports=QR;pB.exports.default=QR;pB.exports.__esModule=!0;G6(bR(),qa);G6(yR(),qa)});var z6=I(Wf=>{"use strict";var mst=J("net"),tDe=J("tls"),SR=J("http"),q6=J("https"),rDe=J("events"),Est=J("assert"),iDe=J("util");Wf.httpOverHttp=nDe;Wf.httpsOverHttp=sDe;Wf.httpOverHttps=oDe;Wf.httpsOverHttps=aDe;function nDe(r){var e=new Ja(r);return e.request=SR.request,e}function sDe(r){var e=new Ja(r);return e.request=SR.request,e.createSocket=J6,e.defaultPort=443,e}function oDe(r){var e=new Ja(r);return e.request=q6.request,e}function aDe(r){var e=new Ja(r);return e.request=q6.request,e.createSocket=J6,e.defaultPort=443,e}function Ja(r){var e=this;e.options=r||{},e.proxyOptions=e.options.proxy||{},e.maxSockets=e.options.maxSockets||SR.Agent.defaultMaxSockets,e.requests=[],e.sockets=[],e.on("free",function(i,n,s,o){for(var a=W6(n,s,o),l=0,c=e.requests.length;l<c;++l){var u=e.requests[l];if(u.host===a.host&&u.port===a.port){e.requests.splice(l,1),u.request.onSocket(i);return}}i.destroy(),e.removeSocket(i)})}iDe.inherits(Ja,rDe.EventEmitter);Ja.prototype.addRequest=function(e,t,i,n){var s=this,o=vR({request:e},s.options,W6(t,i,n));if(s.sockets.length>=this.maxSockets){s.requests.push(o);return}s.createSocket(o,function(a){a.on("free",l),a.on("close",c),a.on("agentRemove",c),e.onSocket(a);function l(){s.emit("free",a,o)}function c(u){s.removeSocket(a),a.removeListener("free",l),a.removeListener("close",c),a.removeListener("agentRemove",c)}})};Ja.prototype.createSocket=function(e,t){var i=this,n={};i.sockets.push(n);var s=vR({},i.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:!1,headers:{host:e.host+":"+e.port}});e.localAddress&&(s.localAddress=e.localAddress),s.proxyAuth&&(s.headers=s.headers||{},s.headers["Proxy-Authorization"]="Basic "+new Buffer(s.proxyAuth).toString("base64")),_A("making CONNECT request");var o=i.request(s);o.useChunkedEncodingByDefault=!1,o.once("response",a),o.once("upgrade",l),o.once("connect",c),o.once("error",u),o.end();function a(g){g.upgrade=!0}function l(g,h,p){process.nextTick(function(){c(g,h,p)})}function c(g,h,p){if(o.removeAllListeners(),h.removeAllListeners(),g.statusCode!==200){_A("tunneling socket could not be established, statusCode=%d",g.statusCode),h.destroy();var d=new Error("tunneling socket could not be established, statusCode="+g.statusCode);d.code="ECONNRESET",e.request.emit("error",d),i.removeSocket(n);return}if(p.length>0){_A("got illegal response body from proxy"),h.destroy();var d=new Error("got illegal response body from proxy");d.code="ECONNRESET",e.request.emit("error",d),i.removeSocket(n);return}return _A("tunneling connection has established"),i.sockets[i.sockets.indexOf(n)]=h,t(h)}function u(g){o.removeAllListeners(),_A(`tunneling socket could not be established, cause=%s +`,g.message,g.stack);var h=new Error("tunneling socket could not be established, cause="+g.message);h.code="ECONNRESET",e.request.emit("error",h),i.removeSocket(n)}};Ja.prototype.removeSocket=function(e){var t=this.sockets.indexOf(e);if(t!==-1){this.sockets.splice(t,1);var i=this.requests.shift();i&&this.createSocket(i,function(n){i.request.onSocket(n)})}};function J6(r,e){var t=this;Ja.prototype.createSocket.call(t,r,function(i){var n=r.request.getHeader("host"),s=vR({},t.options,{socket:i,servername:n?n.replace(/:.*$/,""):r.host}),o=tDe.connect(0,s);t.sockets[t.sockets.indexOf(i)]=o,e(o)})}function W6(r,e,t){return typeof r=="string"?{host:r,port:e,localAddress:t}:r}function vR(r){for(var e=1,t=arguments.length;e<t;++e){var i=arguments[e];if(typeof i=="object")for(var n=Object.keys(i),s=0,o=n.length;s<o;++s){var a=n[s];i[a]!==void 0&&(r[a]=i[a])}}return r}var _A;process.env.NODE_DEBUG&&/\btunnel\b/.test(process.env.NODE_DEBUG)?_A=function(){var r=Array.prototype.slice.call(arguments);typeof r[0]=="string"?r[0]="TUNNEL: "+r[0]:r.unshift("TUNNEL:"),console.error.apply(console,r)}:_A=function(){};Wf.debug=_A});var X6=I((yst,V6)=>{V6.exports=z6()});var a9=I((EB,FR)=>{var o9=Object.assign({},J("fs")),RR=function(){var r=typeof document<"u"&&document.currentScript?document.currentScript.src:void 0;return typeof __filename<"u"&&(r=r||__filename),function(e){e=e||{};var t=typeof e<"u"?e:{},i,n;t.ready=new Promise(function(f,E){i=f,n=E});var s={},o;for(o in t)t.hasOwnProperty(o)&&(s[o]=t[o]);var a=[],l="./this.program",c=function(f,E){throw E},u=!1,g=!0,h="";function p(f){return t.locateFile?t.locateFile(f,h):h+f}var d,m,y,B;g&&(u?h=J("path").dirname(h)+"/":h=__dirname+"/",d=function(E,w){var k=pa(E);return k?w?k:k.toString():(y||(y=o9),B||(B=J("path")),E=B.normalize(E),y.readFileSync(E,w?null:"utf8"))},m=function(E){var w=d(E,!0);return w.buffer||(w=new Uint8Array(w)),te(w.buffer),w},process.argv.length>1&&(l=process.argv[1].replace(/\\/g,"/")),a=process.argv.slice(2),c=function(f){process.exit(f)},t.inspect=function(){return"[Emscripten Module object]"});var S=t.print||console.log.bind(console),x=t.printErr||console.warn.bind(console);for(o in s)s.hasOwnProperty(o)&&(t[o]=s[o]);s=null,t.arguments&&(a=t.arguments),t.thisProgram&&(l=t.thisProgram),t.quit&&(c=t.quit);var F=16;function H(f,E){return E||(E=F),Math.ceil(f/E)*E}var q=0,_=function(f){q=f},X;t.wasmBinary&&(X=t.wasmBinary);var W=t.noExitRuntime||!0;typeof WebAssembly!="object"&&Ir("no native wasm support detected");function Z(f,E,w){switch(E=E||"i8",E.charAt(E.length-1)==="*"&&(E="i32"),E){case"i1":return ie[f>>0];case"i8":return ie[f>>0];case"i16":return fe[f>>1];case"i32":return de[f>>2];case"i64":return de[f>>2];case"float":return vt[f>>2];case"double":return mt[f>>3];default:Ir("invalid type for getValue: "+E)}return null}var A,ne=!1,ue;function te(f,E){f||Ir("Assertion failed: "+E)}function O(f){var E=t["_"+f];return te(E,"Cannot call unknown function "+f+", make sure it is exported"),E}function N(f,E,w,k,L){var T={string:function(nt){var wt=0;if(nt!=null&&nt!==0){var Ii=(nt.length<<2)+1;wt=GE(Ii),se(nt,wt,Ii)}return wt},array:function(nt){var wt=GE(nt.length);return ge(nt,wt),wt}};function ee(nt){return E==="string"?De(nt):E==="boolean"?Boolean(nt):nt}var Ie=O(f),Oe=[],it=0;if(k)for(var at=0;at<k.length;at++){var Ue=T[w[at]];Ue?(it===0&&(it=tS()),Oe[at]=Ue(k[at])):Oe[at]=k[at]}var Ve=Ie.apply(null,Oe);return Ve=ee(Ve),it!==0&&rS(it),Ve}function ce(f,E,w,k){w=w||[];var L=w.every(function(ee){return ee==="number"}),T=E!=="string";return T&&L&&!k?O(f):function(){return N(f,E,w,arguments,k)}}var he=typeof TextDecoder<"u"?new TextDecoder("utf8"):void 0;function xe(f,E,w){for(var k=E+w,L=E;f[L]&&!(L>=k);)++L;if(L-E>16&&f.subarray&&he)return he.decode(f.subarray(E,L));for(var T="";E<L;){var ee=f[E++];if(!(ee&128)){T+=String.fromCharCode(ee);continue}var Ie=f[E++]&63;if((ee&224)==192){T+=String.fromCharCode((ee&31)<<6|Ie);continue}var Oe=f[E++]&63;if((ee&240)==224?ee=(ee&15)<<12|Ie<<6|Oe:ee=(ee&7)<<18|Ie<<12|Oe<<6|f[E++]&63,ee<65536)T+=String.fromCharCode(ee);else{var it=ee-65536;T+=String.fromCharCode(55296|it>>10,56320|it&1023)}}return T}function De(f,E){return f?xe(G,f,E):""}function Re(f,E,w,k){if(!(k>0))return 0;for(var L=w,T=w+k-1,ee=0;ee<f.length;++ee){var Ie=f.charCodeAt(ee);if(Ie>=55296&&Ie<=57343){var Oe=f.charCodeAt(++ee);Ie=65536+((Ie&1023)<<10)|Oe&1023}if(Ie<=127){if(w>=T)break;E[w++]=Ie}else if(Ie<=2047){if(w+1>=T)break;E[w++]=192|Ie>>6,E[w++]=128|Ie&63}else if(Ie<=65535){if(w+2>=T)break;E[w++]=224|Ie>>12,E[w++]=128|Ie>>6&63,E[w++]=128|Ie&63}else{if(w+3>=T)break;E[w++]=240|Ie>>18,E[w++]=128|Ie>>12&63,E[w++]=128|Ie>>6&63,E[w++]=128|Ie&63}}return E[w]=0,w-L}function se(f,E,w){return Re(f,G,E,w)}function Ae(f){for(var E=0,w=0;w<f.length;++w){var k=f.charCodeAt(w);k>=55296&&k<=57343&&(k=65536+((k&1023)<<10)|f.charCodeAt(++w)&1023),k<=127?++E:k<=2047?E+=2:k<=65535?E+=3:E+=4}return E}function ye(f){var E=Ae(f)+1,w=pt(E);return w&&Re(f,ie,w,E),w}function ge(f,E){ie.set(f,E)}function oe(f,E){return f%E>0&&(f+=E-f%E),f}var Ye,ie,G,fe,re,de,Ze,vt,mt;function Tr(f){Ye=f,t.HEAP8=ie=new Int8Array(f),t.HEAP16=fe=new Int16Array(f),t.HEAP32=de=new Int32Array(f),t.HEAPU8=G=new Uint8Array(f),t.HEAPU16=re=new Uint16Array(f),t.HEAPU32=Ze=new Uint32Array(f),t.HEAPF32=vt=new Float32Array(f),t.HEAPF64=mt=new Float64Array(f)}var ti=t.INITIAL_MEMORY||16777216,ui,gr=[],gi=[],ri=[],Ms=!1;function fr(){if(t.preRun)for(typeof t.preRun=="function"&&(t.preRun=[t.preRun]);t.preRun.length;)ua(t.preRun.shift());yo(gr)}function Ei(){Ms=!0,!t.noFSInit&&!Q.init.initialized&&Q.init(),ns.init(),yo(gi)}function rs(){if(t.postRun)for(typeof t.postRun=="function"&&(t.postRun=[t.postRun]);t.postRun.length;)gg(t.postRun.shift());yo(ri)}function ua(f){gr.unshift(f)}function CA(f){gi.unshift(f)}function gg(f){ri.unshift(f)}var is=0,mA=null,ga=null;function wp(f){return f}function EA(f){is++,t.monitorRunDependencies&&t.monitorRunDependencies(is)}function IA(f){if(is--,t.monitorRunDependencies&&t.monitorRunDependencies(is),is==0&&(mA!==null&&(clearInterval(mA),mA=null),ga)){var E=ga;ga=null,E()}}t.preloadedImages={},t.preloadedAudios={};function Ir(f){t.onAbort&&t.onAbort(f),f+="",x(f),ne=!0,ue=1,f="abort("+f+"). Build with -s ASSERTIONS=1 for more info.";var E=new WebAssembly.RuntimeError(f);throw n(E),E}var Nl="data:application/octet-stream;base64,";function fg(f){return f.startsWith(Nl)}var Io="data:application/octet-stream;base64,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ACgCFC0AAiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQADIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAQgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABSAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAGIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAcgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAJIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAogACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACyAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAMIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAA0gACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ADiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAPIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhRBEGo2AhQgACAAKAIIQQFrIgE2AgggAQ0ACyAAIAAoAhhB8f8DcDYCGCAAIAAoAgxB8f8DcDYCDAwBCwsgACgCEARAA0AgACgCEEEQTwRAIAAgACgCEEEQazYCECAAIAAoAhQtAAAgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AASAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQACIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAMgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAFIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAYgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AByAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAIIAAoAhhqNgIYIAAgACgCGCAAKAIMajYC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NgIYIAEoAgxCADcDICABKAIMQgA3AyggASgCDEEANgIwIAEoAgxBADYCNCABKAIMQQA2AjggASgCDEEANgI8IAEoAgxBADsBQCABKAIMQYCA2I14NgJEIAEoAgxCADcDSCABKAIMQQA7AVAgASgCDEEAOwFSIAEoAgxBADYCVAvSEwEBfyMAQbABayIDJAAgAyAANgKoASADIAE2AqQBIAMgAjYCoAEgA0EANgKQASADIAMoAqQBKAIwQQAQOjYClAEgAyADKAKkASgCOEEAEDo2ApgBAkACQAJAAkAgAygClAFBAkYEQCADKAKYAUEBRg0BCyADKAKUAUEBRgRAIAMoApgBQQJGDQELIAMoApQBQQJHDQEgAygCmAFBAkcNAQsgAygCpAEiACAALwEMQYAQcjsBDAwBCyADKAKkASIAIAAvAQxB/+8DcTsBDCADKAKUAUECRgRAIANB9eABIAMoAqQBKAIwIAMoAqgBQQhqEI4BNgKQASADKAKQAUUEQCADQX82AqwBDAMLCwJAIAMoAqABQYACcQ0AIAMoApgBQQJHDQAgA0H1xgEgAygCpAEoAjggAygCqAFBCGoQjgE2AkggAygCSEUEQCADKAKQARAjIANBfzYCrAEMAwsgAygCSCADKAKQATYCACADIAMoAkg2ApABCwsCQCADKAKkAS8BUkUEQCADKAKkASIAIAAvAQxB/v8DcTsBDAwBCyADKAKkASIAIAAvAQxBAXI7AQwLIAMgAygCpAEgAygCoAEQZUEBcToAhgEgAyADKAKgAUGACnFBgApHBH8gAy0AhgEFQQELQQFxOgCHASADAn9BASADKAKkAS8BUkGBAkYNABpBASADKAKkAS8BUkGCAkYNABogAygCpAEvAVJBgwJGC0EBcToAhQEgAy0AhwFBAXEEQCADIANBIGpCHBApNgIcIAMoAhxFBEAgAygCqAFBCGpBDkEAEBQgAygCkAEQIyADQX82AqwBDAILAkAgAygCoAFBgAJxBEACQCADKAKgAUGACHENACADKAKkASkDIEL/////D1YNACADKAKkASkDKEL/////D1gNAgsgAygCHCADKAKkASkDKBAtIAMoAhwgAygCpAEpAyAQLQwBCwJAAkAgAygCoAFBgAhxDQAgAygCpAEpAyBC/////w9WDQAgAygCpAEpAyhC/////w9WDQAgAygCpAEpA0hC/////w9YDQELIAMoAqQBKQMoQv////8PWgRAIAMoAhwgAygCpAEpAygQLQsgAygCpAEpAyBC/////w9aBEAgAygCHCADKAKkASkDIBAtCyADKAKkASkDSEL/////D1oEQCADKAIcIAMoAqQBKQNIEC0LCwsCfyMAQRBrIgAgAygCHDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIcEBYgAygCkAEQIyADQX82AqwBDAILIANBAQJ/IwBBEGsiACADKAIcNgIMAn4gACgCDC0AAEEBcQRAIAAoAgwpAxAMAQtCAAunQf//A3ELIANBIGpBgAYQVTYCjAEgAygCHBAWIAMoAowBIAMoApABNgIAIAMgAygCjAE2ApABCyADLQCFAUEBcQRAIAMgA0EVakIHECk2AhAgAygCEEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAgsgAygCEEECEB8gAygCEEG9EkECEEEgAygCECADKAKkAS8BUkH/AXEQlgEgAygCECADKAKkASgCEEH//wNxEB8CfyMAQRBrIgAgAygCEDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIQEBYgAygCkAEQIyADQX82AqwBDAILIANBgbICQQcgA0EVakGABhBVNgIMIAMoAhAQFiADKAIMIAMoApABNgIAIAMgAygCDDYCkAELIAMgA0HQAGpCLhApIgA2AkwgAEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAQsgAygCTEHxEkH2EiADKAKgAUGAAnEbQQQQQSADKAKgAUGAAnFFBEAgAygCTCADLQCGAUEBcQR/QS0FIAMoAqQBLwEIC0H//wNxEB8LIAMoAkwgAy0AhgFBAXEEf0EtBSADKAKkAS8BCgtB//8DcRAfIAMoAkwgAygCpAEvAQwQHwJAIAMtAIUBQQFxBEAgAygCTEHjABAfDAELIAMoAkwgAygCpAEoAhBB//8DcRAfCyADKAKkASgCFCADQZ4BaiADQZwBahCNASADKAJMIAMvAZ4BEB8gAygCTCADLwGcARAfAkACQCADLQCFAUEBcUUNACADKAKkASkDKEIUWg0AIAMoAkxBABAhDAELIAMoAkwgAygCpAEoAhgQIQsCQAJAIAMoAqABQYACcUGAAkcNACADKAKkASkDIEL/////D1QEQCADKAKkASkDKEL/////D1QNAQsgAygCTEF/ECEgAygCTEF/ECEMAQsCQCADKAKkASkDIEL/////D1QEQCADKAJMIAMoAqQBKQMgpxAhDAELIAMoAkxBfxAhCwJAIAMoAqQBKQMoQv////8PVARAIAMoAkwgAygCpAEpAyinECEMAQsgAygCTEF/ECELCyADKAJMIAMoAqQBKAIwEFFB//8DcRAfIAMgAygCpAEoAjQgAygCoAEQkgFB//8DcSADKAKQAUGABhCSAUH//wNxajYCiAEgAygCTCADKAKIAUH//wNxEB8gAygCoAFBgAJxRQRAIAMoAkwgAygCpAEoAjgQUUH//wNxEB8gAygCTCADKAKkASgCPEH//wNxEB8gAygCTCADKAKkAS8BQBAfIAMoAkwgAygCpAEoAkQQIQJAIAMoAqQBKQNIQv////8PVARAIAMoAkwgAygCpAEpA0inECEMAQsgAygCTEF/ECELCwJ/IwBBEGsiACADKAJMNgIMIAAoAgwtAABBAXFFCwRAIAMoAqgBQQhqQRRBABAUIAMoAkwQFiADKAKQARAjIANBfzYCrAEMAQsgAygCqAEgA0HQAGoCfiMAQRBrIgAgAygCTDYCDAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALCxA2QQBIBEAgAygCTBAWIAMoApABECMgA0F/NgKsAQwBCyADKAJMEBYgAygCpAEoAjAEQCADKAKoASADKAKkASgCMBCFAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEEQCADKAKoASADKAKQAUGABhCRAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEQIyADKAKkASgCNARAIAMoAqgBIAMoAqQBKAI0IAMoAqABEJEBQQBIBEAgA0F/NgKsAQwCCwsgAygCoAFBgAJxRQRAIAMoAqQBKAI4BEAgAygCqAEgAygCpAEoAjgQhQFBAEgEQCADQX82AqwBDAMLCwsgAyADLQCHAUEBcTYCrAELIAMoAqwBIQAgA0GwAWokACAAC+ACAQF/IwBBIGsiBCQAIAQgADsBGiAEIAE7ARggBCACNgIUIAQgAzYCECAEQRAQGCIANgIMAkAg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AAAgAygCHEHcFmogAygCDEECdGooAgAgAygCHEHYKGpqLQAASg0ADAELIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhxB3BZqIAMoAgxBAnRqKAIANgIAIAMgAygCDDYCFCADIAMoAgxBAXQ2AgwMAQsLIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhA2AgAL1xMBA38jAEEwayICJAAgAiAANgIsIAIgATYCKCACIAIoAigoAgA2AiQgAiACKAIoKAIIKAIANgIgIAIgAigCKCgCCCgCDDYCHCACQX82AhAgAigCLEEANgLQKCACKAIsQb0ENgLUKCACQQA2AhgDQCACKAIYIAIoAhxIBEACQCACKAIkIAIoAhhBAnRqLwEABEAgAiACKAIYIgE2AhAgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQAgBCAANgLQKCAAQQJ0IANqIAE2AgAgAigCGCACKAIsQdgoampBADoAAAwBCyACKAIkIAIoAhhBAnRqQQA7AQILIAIgAigCGEEBajYCGAwBCwsDQCACKAIsKALQKEECSARAAkAgAigCEEECSARAIAIgAigCEEEBaiIANgIQDAELQQAhAAsgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQEgBCABNgLQKCABQQJ0IANqIAA2AgAgAiAANgIMIAIoAiQgAigCDEECdGpBATsBACACKAIMIAIoAixB2ChqakEAOgAAIAIoAiwiACAAKAKoLUEBazYCqC0gAigCIARAIAIoAiwiACAAKAKsLSACKAIgIAIoAgxBAnRqLwECazYCrC0LDAELCyACKAIoIAIoAhA2AgQgAiACKAIsKALQKEECbTYCGANAIAIoAhhBAU4EQCACKAIsIAIoAiQgAigCGBB5IAIgAigCGEEBazYCGAwBCwsgAiACKAIcNgIMA0AgAiACKAIsKALgFjYCGCACKAIsQdwWaiEBIAIoAiwiAygC0CghACADIABBAWs2AtAoIAIoAiwgAEECdCABaigCADYC4BYgAigCLCACKAIkQQEQeSACIAIoAiwoAuAWNgIUIAIoAhghASACKAIsQdwWaiEDIAIoAiwiBCgC1ChBAWshACAEIAA2AtQoIABBAnQgA2ogATYCACACKAIUIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQQFrIQAgBCAANgLUKCAA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AQsgAigCCEEANgIAIAIoAghCADcDECACKAIIQgA3AwggAigCCEIANwMgIAIoAghCADcDGCACKAIIQQA2AiggAigCCEEAOgAsIAIoAgggAikDECACKAIMEI8BQQFxRQRAIAIoAggQJSACQQA2AhwMAQsgAiACKAIINgIcCyACKAIcIQEgAkEgaiQAIAEL1gIBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADQQxqQgQQKTYCCAJAIAMoAghFBEAgA0F/NgIcDAELA0AgAygCFARAIAMoAhQoAgQgAygCEHFBgAZxBEAgAygCCEIAECwaIAMoAgggAygCFC8BCBAfIAMoAgggAygCFC8BChAfAn8jAEEQayIAIAMoAgg2AgwgACgCDC0AAEEBcUULBEAgAygCGEEIakEUQQAQFCADKAIIEBYgA0F/NgIcDAQLIAMoAhggA0EMakIEEDZBAEgEQCADKAIIEBYgA0F/NgIcDAQLIAMoAhQvAQoEQCADKAIYIAMoAhQoAgwgAygCFC8BCq0QNkEASARAIAMoAggQFiADQX82AhwMBQsLCyADIAMoAhQoAgA2AhQMAQsLIAMoAggQFiADQQA2AhwLIAMoAhwhACADQSBqJAAgAAtoAQF/IwBBEGsiAiAANgIMIAIgATYCCCACQQA7AQYDQCACKAIMBEAgAigCDCgCBCACKAIIcUGABnEEQCACIAIoAgwvAQogAi8BBkEEamo7AQYLIAIgAigCDCgCADYCDAwBCwsgAi8BBgvwAQEBfyMAQRBrIgEkACABIAA2AgwgASABKAIMNgIIIAFBADYCBANAIAEoAgwEQAJAAkAgASgCDC8BCEH1xgFGDQAgASgCDC8BCEH14AFGDQAgASgCDC8BCEGBsgJGDQAgASgCDC8BCEEBRw0BCyABIAEoAgwoAgA2AgAgASgCCCABKAIMRgRAIAEgASgCADYCCAsgASgCDEEANgIAIAEoAgwQIyABKAIEBEAgASgCBCABKAIANgIACyABIAEoAgA2AgwMAgsgASABKAIMNgIEIAEgASgCDCgCADYCDAwBCwsgASgCCCEAIAFBEGokACAAC7IEAQF/IwBBQGoiBSQAIAUgADYCOCAFIAE7ATYgBSACNgIwIAUgAzYCLCAFIAQ2AiggBSAFKAI4IAUvATatECkiADYC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IAEoAhBB//8DRgRAIAEgASgCDDYCEAsgASgCCEH//wNGBEAgASABKAIENgIICwJAIAEoApQBQQRxRQ0AIAEoAgggASgCBEYEQCABKAIQIAEoAgxGDQELIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELAkAgASgCEEUEQCABKAIIRQ0BCyABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AyggASABKAKkARAxNwMgIAEpAyggASkDIFIEQCABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AzAgASABKAKkARAxNwOAAQJ/IwBBEGsiBSABKAKkATYCDCAFKAIMLQAAQQFxRQsEQCABKAKQAUEUQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABLQAXQQFxBEAgASgCpAEQFgsCQCABKQOAAUL///////////8AWARAIAEpA4ABIAEpA4ABIAEpAzB8WA0BCyABKAKQAUEEQRYQFCABQQA2AqwBDAELIAEpA4ABIAEpAzB8IAEpA5gBIAEpAzh8VgRAIAEoApABQRVBABAUIAFBADYCrAEMAQsCQCABKAKUAUEEcUUNACABKQOAASABKQMwfCABKQOYASABKQM4fFENACABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEpAyggASkDMEIugFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEgASkDKCABKAKQARCQASIFNgKMASAFRQRAIAFBADYCrAEMAQsgASgCjAFBAToALCABKAKMASABKQMwNwMYIAEoAowBIAEpA4ABNwMgIAEgASgCjAE2AqwBCyABKAKsASEFIAFBsAFqJAAgACAFNgJQDAELIAAoAmQgACkDMBAsGiAAKAJkIQUgACkDWCEJIAAoAmgoAhQhBiAAKAJUIQcjAEHQAGsiASQAIAEgBTYCSCABIAk3A0AgASAGNgI8IAEgBzYCOAJAIAEoAkgQMEIWVARAIAEoAjhBFUEAEBQgAUEANgJMDAELIwBBEGsiBSABKAJINgIMIAECfiAFKAIMLQAAQQFxBEAgBSgCDCkDEAwBC0IACzcDCCABKAJI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ECADQcgAEBgiADYCDAJAIABFBEAgAygCEEEBQbSbASgCABAUIANBADYCHAwBCyADKAIMIAMoAhA2AgAgAygCDCADLQAbQQFxOgAEIAMoAgwgAygCFDYCCAJAIAMoAgwoAghBAU4EQCADKAIMKAIIQQlMDQELIAMoAgxBCTYCCAsgAygCDEEAOgAMIAMoAgxBADYCMCADKAIMQQA2AjQgAygCDEEANgI4IAMgAygCDDYCHAsgAygCHCEAIANBIGokACAACzgBAX8jAEEQayIBIAA2AgwgASgCDEEANgIAIAEoAgxBADYCBCABKAIMQQA2AgggASgCDEEAOgAMC+MIAQF/IwBBQGoiAiAANgI4IAIgATYCNCACIAIoAjgoAnw2AjAgAiACKAI4KAI4IAIoAjgoAmxqNgIsIAIgAigCOCgCeDYCICACIAIoAjgoApABNgIcIAICfyACKAI4KAJsIAIoAjgoAixBhgJrSwRAIAIoAjgoAmwgAigCOCgCLEGGAmtrDAELQQALNgIYIAIgAigCOCgCQDYCFCACIAIoAjgoAjQ2AhAgAiACKAI4KAI4IAIoAjgoAmxqQYICajYCDCACIAIoAiwgAigCIEEBa2otAAA6AAsgAiACKAIsIAIoAiBqLQAAOgAKIAIoAjgoAnggAigCOCgCjAFPBEAgAiACKAIwQQJ2NgIwCyACKAIcIAIoAjgoAnRLBEAgAiACKAI4KAJ0NgIcCwNAAkAgAiACKAI4KAI4IAIoAjRqNgIoAkAgAigCKCACKAIgai0AACACLQAKRw0AIAIoAiggAigCIEEBa2otAAAgAi0AC0cNACACKAIoLQAAIAIoAiwtAABHDQAgAiACKAIoIgBBAWo2AiggAC0AASACKAIsLQABRwRADAELIAIgAigCLEECajYCLCACIAIoAihBAWo2AigDQCACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AigCf0EAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEGCAms2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEEBayIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5IQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAiwgAigCKCgCDEEFa0kEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcTYCECACKAIoQQBBACACKAIQEF0gAigCKCgCCCACKAIoKAIUQQRraiACKAIcOgAAIAIoAigoAgggAigCKCgCFEEDa2ogAigCHEEIdjoAACACKAIoKAIIIAIoAigoAhRBAmtqIAIoAhxBf3M6AAAgAigCKCgCCCACKAIoKAIUQQFraiACKAIcQX9zQQh2OgAAIAIoAigoAgAQHCACKAIYBEAgAigCGCACKAIcSwRAIAIgAigCHDYCGAsgAigCKCgCACgCDCACKAIoKAI4IAIoAigoAlxqIAIoAhgQGRogAigCKCgCACIAIAIoAhggACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCGGs2AhAgAigCKCgCACIAIAIoAhggACgCFGo2AhQgAigCKCIAIAIoAhggACgCXGo2AlwgAiACKAIcIAIoAhhrNgIcCyACKAIcBEAgAigCKCgCACACKAIoKAIAKAIMIAIoAhwQdhogAigCKCgCACIAIAIoAhwgACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCHGs2AhAgAigCKCgCACIAIAIoAhwgACgCFGo2AhQLIAIoAhBFDQELCyACIAIoAgwgAigCKCgCACgCBGs2AgwgAigCDARAAkAgAigCDCACKAIoKAIsTwRAIAIoAihBAjYCsC0gAigCKCgCOCACKAIoKAIAKAIAIAIoAigoAixrIAIoAigoAiwQGRogAigCKCACKAIoKAIsNgJsDAELIAIoAgwgAigCKCgCPCACKAIoKAJsa08EQCACKAIoIgAgACgCbCACKAIoKAIsazYCbCACKAIoKAI4IAIoAigoAjggAigCKCgCLGogAigCKCgCbBAZGiACKAIoKAKwLUECSQRAIAIoAigiACAAKAKwLUEBajYCsC0LCyACKAIoKAI4IAIoAigoAmxqIAIoAigoAgAoAgAgAigCDGsgAigCDBAZGiACKAIoIgAgAigCDCAAKAJsajYCbAsgAigCKCACKAIoKAJsNgJcIAIoAigiAQJ/IAIoAgwgAigCKCgCLCACKAIoKAK0LWtLBEAgAigCKCgCLCACKAIoKAK0LWsMAQsgAigCDAsgASgCtC1qNgK0LQsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCwJAIAIoAhAEQCACQQM2AiwMAQsCQCACKAIkRQ0AIAIoAiRBBEYNACACKAIoKAIAKAIEDQAgAigCKCgCbCACKAIoKAJcRw0AIAJBATYCLAwBCyACIAIoAigoAjwgAigCKCgCbGtBAWs2AhQCQCACKAIoKAIAKAIEIAIoAhRNDQAgAigCKCgCXCACKAIoKAIsSA0AIAIoAigiACAAKAJcIAIoAigoAixrNgJcIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBkaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsgAiACKAIoKAIsIAIoAhRqNgIUCyACKAIUIAIoAigoAgAoAgRLBEAgAiACKAIoKAIAKAIENgIUCyACKAIUBEAgAigCKCgCACACKAIoKAI4IAIoAigoAmxqIAIoAhQQdhogAigCKCIAIAIoAhQgACgCbGo2AmwLIAIoAigoAsAtIAIoAigoAmxJBEAgAigCKCACKAIoKAJsNgLALQsgAiACKAIoKAK8LUEqakEDdTYCFCACIAIoAigoAgwgAigCFGtB//8DSwR/Qf//AwUgAigCKCgCDCACKAIUaws2AhQgAgJ/IAIoAhQgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAhQLNgIgIAIgAigCKCgCbCACKAIoKAJcazYCGAJAIAIoAhggAigCIEkEQCACKAIYRQRAIAIoAiRBBEcNAgsgAigCJEUNASACKAIoKAIAKAIEDQEgAigCGCACKAIUSw0BCyACAn8gAigCGCACKAIUSwRAIAIoAhQMAQsgAigCGAs2AhwgAgJ/QQAgAigCJEEERw0AGkEAIAIoAigoAgAoAgQNABogAigCHCACKAIYRgtBAXE2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBdIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHAsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHgEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIc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DQAgAiEAIANBAWsiAw0ACwsgBCgCFBogASACNgKgAQwCCyMAQRBrIgAgASgCqAEoAgQ2AgwgAUEAIAAoAgxrQQJ0QajZAGooAgA2AqABDAELIAFBADYCoAELCwJAIAEoAqABRQRAIAEgASgCpAE2AqwBDAELIAEgASgCoAEQLgJ/IAEoAqQBBEAgASgCpAEQLkECagwBC0EAC2pBAWoQGCIANgIcIABFBEAgAUG4EygCADYCrAEMAQsgASgCHCEAAn8gASgCpAEEQCABKAKkAQwBC0H6EgshA0HfEkH6EiABKAKkARshAiABIAEoAqABNgIIIAEgAjYCBCABIAM2AgAgAEG+CiABEG8gASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAsIAEEBQTgQfwszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGRogACAAKAIUIAFqNgIUIAILjwUCBn4BfyABIAEoAgBBD2pBcHEiAUEQajYCACAAAnwgASkDACEDIAEpAwghBiMAQSBrIggkAAJAIAZC////////////AIMiBEKAgICAgIDAgDx9IARCgICAgICAwP/DAH1UBEAgBkIEhiADQjyIhCEEIANC//////////8PgyIDQoGAgICAgICACFoEQCAEQoGAgICAgICAwAB8IQIMAgsgBEKAgICAgICAgEB9IQIgA0KAgICAgICAgAiFQgBSDQEgAiAEQgGDfCECDAELIANQIARCgICAgICAwP//AFQgBEKAgICAgIDA//8AURtFBEAgBkIEhiADQjyIhEL/////////A4NCgICAgICAgPz/AIQhAgwBC0KAgICAgICA+P8AIQIgBEL///////+//8MAVg0AQgAhAiAEQjCIpyIAQZH3AEkNACADIQIgBkL///////8/g0KAgICAgIDAAIQiBSEHAkAgAEGB9wBrIgFBwABxBEAgAiABQUBqrYYhB0IAIQIMAQsgAUUNACAHIAGtIgSGIAJBwAAgAWutiIQhByACIASGIQILIAggAjcDECAIIAc3AxgCQEGB+AAgAGsiAEHAAHEEQCAFIABBQGqtiCEDQgAhBQwBCyAARQ0AIAVBwAAgAGuthiADIACtIgKIhCEDIAUgAoghBQsgCCADNwMAIAggBTcDCCAIKQMI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ADYCtC0gASgCFEEERgRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQEQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUECNgIcDAILIAFBAzYCHAwBCyABKAIYKAKgLQRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQAQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUEANgIcDAILCyABQQE2AhwLIAEoAhwhAiABQSBqJAAgAgwBCwJ/IAAoAiwoAogBQQNGBEAgACgCLCECIAAoAjQhAyMAQTBrIgEkACABIAI2AiggASADNgIkAkADQAJAIAEoAigoAnRBggJNBEAgASgCKBBcAkAgASgCKCgCdEGCAksNACABKAIkDQAgAUEANgIsDAQLIAEoAigoAnRFDQELIAEoAihBADYCYAJAIAEoAigoAnRBA0kNACABKAIoKAJsRQ0AIAEgASgCKCgCOCABKAIoKAJsakEBazYCGCABIAEoAhgtAAA2AhwgASgCHCECIAEgASgCGCIDQQFqNgIYAkAgAy0AASACRw0AIAEoAhwhAiABIAEoAhgiA0EBajYCGCADLQABIAJHDQAgASgCHCECIAEgASgCGCIDQQFqNgIYIAMtAAEgAkcNACABIAEoAigoAjggASgCKCgCbGpBggJqNgIUA0AgASgCHCECIAEgASgCGCIDQQFqNgIYAn9BACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABog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AS8BEiECIAEgASgCSCIDQQFqNgJIIAMgAjoAAAwCCyABKAIMQRBxBEAgASABLwESNgIIIAEgASgCDEEPcTYCDCABKAIMBEAgASgCKCABKAIMSQRAIAEgASgCUCICQQFqNgJQIAEgASgCLCACLQAAIAEoAih0ajYCLCABIAEoAihBCGo2AigLIAEgASgCCCABKAIsQQEgASgCDHRBAWtxajYCCCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoCyABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiAgASgCLCABKAIYcUECdGooAQA2ARACQANAIAEgAS0AETYCDCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgAS0AEDYCDCABKAIMQRBxBEAgASABLwESNgIEIAEgASgCDEEPcTYCDCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKAsLIAEgASgCBCABKAIsQQEgASgCDHRBAWtxajYCBCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgASgCSCABKAJEazYCDAJAIAEoAgQgASgCDEsEQCABIAEoAgQgASgCDGs2AgwgASgCDCABKAI4SwRAIAEoAlQoAsQ3BEAgASgCXEHdDDYCGCABKAJUQdH+ADYCBAwKCwsgASABKAIwNgIAAkAgASgCNEUEQCABIAEoAgAgASgCPCABKAIMa2o2AgAgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAkggASgCBGs2AgALDAELAkAgASgCNCABKAIMSQRAIAEgASgCACABKAI8IAEoAjRqIAEoAgxrajYCACABIAEoAgwgASgCNGs2AgwgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAjA2AgAgASgCNCABKAIISQRAIAEgASgCNDYCDCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsMAQsgASABKAIAIAEoAjQgASgCDGtqNgIAIAEoAgwgASgCCEkEQCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsLA0AgASgCCEECSwRAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCCEEDazYCCAwBCwsMAQsgASABKAJIIAEoAgRrNgIAA0AgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIIQQNrNgIIIAEoAghBAksNAAsLIAEoAggEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEoAghBAUsEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAACwsMAgsgASgCDEHAAHFFBEAgASABKAIgIAEvARIgASgCLEEBIAEoAgx0QQFrcWpBAnRqKAEANgEQDAELCyAB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AG5hbgAvZGV2L3VyYW5kb20AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoAGluZgBpbnZhbGlkIHdpbmRvdyBzaXplAFJlYWQtb25seSBhcmNoaXZlAE5vdCBhIHppcCBhcmNoaXZlAFJlc291cmNlIHN0aWxsIGluIHVzZQBNYWxsb2MgZmFpbHVyZQBpbnZhbGlkIGJsb2NrIHR5cGUARmFpbHVyZSB0byBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUAQ2FuJ3Qgb3BlbiBmaWxlAE5vIHN1Y2ggZmlsZQBQcmVtYXR1cmUgZW5kIG9mIGZpbGUAQ2FuJ3QgcmVtb3ZlIGZpbGUAaW52YWxpZCBsaXRlcmFsL2xlbmd0aCBjb2RlAGludmFsaWQgZGlzdGFuY2UgY29kZQB1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZABzdHJlYW0gZW5kAENvbXByZXNzZWQgZGF0YSBpbnZhbGlkAE11bHRpLWRpc2sgemlwIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQAT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQARW5jcnlwdGlvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABFbnRyeSBoYXMgYmVlbiBkZWxldGVkAENvbnRhaW5pbmcgemlwIGFyY2hpdmUgd2FzIGNsb3NlZABDbG9zaW5nIHppcCBhcmNoaXZlIGZhaWxlZABSZW5hbWluZyB0ZW1wb3JhcnkgZmlsZSBmYWlsZWQARW50cnkgaGFzIGJlZW4gY2hhbmdlZABObyBwYXNzd29yZCBwcm92aWRlZABXcm9uZyBwYXNzd29yZCBwcm92aWRlZABVbmtub3duIGVycm9yICVkAHJiAHIrYgByd2EAJXMuWFhYWFhYAE5BTgBJTkYAQUUAMS4yLjExAC9wcm9jL3NlbGYvZmQvAC4AKG51bGwpADogAFBLBgcA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0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJANMBCQAzAAkAMwEJALMACQCzAQkAcwAJAHMBCQDzAAkA8wEJAAsACQALAQkAiwAJAIsBCQBLAAkASwEJAMsACQDLAQkAKwAJACsBCQCrAAkAqwEJAGsACQBrAQkA6wAJAOsBCQAbAAkAGwEJAJsACQCbAQkAWwAJAFsBCQDbAAkA2wEJADsACQA7AQkAuwAJALsBCQB7AAkAewEJAPsACQD7AQkABwAJAAcBCQCHAAkAhwEJAEcACQBHAQkAxwAJAMcBCQAnAAkAJwEJAKcACQCnAQkAZwAJAGcBCQDnAAkA5wEJABcACQAXAQkAlwAJAJcBCQBXAAkAVwEJANcACQDXAQkANwAJADcBCQC3AAkAtwEJAHcACQB3AQkA9wAJAPcBCQAPAAkADwEJAI8ACQCPAQkATwAJAE8BCQDPAAkAzwEJAC8ACQAvAQkArwAJAK8BCQBvAAkAbwEJAO8ACQDvAQkAHwAJAB8BCQCfAAkAnwEJAF8ACQBfAQkA3wAJAN8BCQA/AAkAPwEJAL8ACQC/AQkAfwAJAH8BCQD/AAkA/wEJAAAABwBAAAcAIAAHAGAABwAQAAcAUAAHADAABwBwAAcACAAHAEgABwAoAAcAaAAHABgABwBYAAcAOAAHAHgABwAEAAcARAAHACQABwBkAAcAFAAHAFQABwA0AAcAdAAHAAMACACDAAgAQwAIAMMACAAjAAgAowAIAGMACADjAAgAAAAFABAABQAIAAUAGAAFAAQABQAUAAUADAAFABwABQACAAUAEgAFAAoABQAaAAUABgAFABYABQAOAAUAHgAFAAEABQARAAUACQAFABkABQAFAAUAFQAFAA0ABQAdAAUAAwAFABMABQALAAUAGwAFAAcABQAXAAUAQbDqAAtNAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQaDrAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdDsAAsjAgAAAAMAAAAHAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AQYTtAAtpAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4AAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAEGE7gALegEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAAABAACAAQAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAMS4yLjExAEGI7wALbQcAAAAEAAQACAAEAAgAAAAEAAUAEAAIAAgAAAAEAAYAIAAgAAgAAAAEAAQAEAAQAAkAAAAIABAAIAAgAAkAAAAIABAAgACAAAkAAAAIACAAgAAAAQkAAAAgAIAAAgEABAkAAAAgAAIBAgEAEAkAQYDwAAulAgMABAAFAAYABwAIAAkACgALAA0ADwARABMAFwAbAB8AIwArADMAOwBDAFMAYwBzAIMAowDDAOMAAgEAAAAAAAAQABAAEAAQABAAEAAQABAAEQARABEAEQASABIAEgASABMAEwATABMAFAAUABQAFAAVABUAFQAVABAATQDKAAAAAQACAAMABAAFAAcACQANABEAGQAhADEAQQBhAIEAwQABAYEBAQIBAwEEAQYBCAEMARABGAEgATABQAFgAAAAABAAEAAQABAAEQARABIAEgATABMAFAAUABUAFQAWABYAFwAXABgAGAAZABkAGgAaABsAGwAcABwAHQAdAEAAQAAQABEAEgAAAAgABwAJAAYACgAFAAsABAAMAAMADQACAA4AAQAPAEGw8gALwRFgBwAAAAhQAAAIEAAUCHMAEgcfAAAIcAAACDAAAAnAABAHCgAACGAAAAggAAAJoAAACAAAAAiAAAAIQAAACeAAEAcGAAAIWAAACBgAAAmQABMHOwAACHgAAAg4AAAJ0AARBxEAAAhoAAAIKAAACbAAAAgIAAAIiAAACEgAAAnwABAHBAAACFQAAAgUABUI4wATBysAAAh0AAAINAAACcgAEQcNAAAIZAAACCQAAAmoAAAIBAAACIQAAAhEAAAJ6AAQBwgAAAhcAAAIHAAACZgAFAdTAAAIfAAACDwAAAnYABIHFwAACGwAAAgsAAAJuAAACAwAAAiMAAAITAAACfgAEAcDAAAIUgAACBIAFQijABMHIwAACHIAAAgyAAAJxAARBwsAAAhiAAAIIgAACaQAAAgCAAAIggAACEIAAAnkABAHBwAACFoAAAgaAAAJlAAUB0MAAAh6AAAIOgAACdQAEgcTAAAIagAACCoAAAm0AAAICgAACIoAAAhKAAAJ9AAQBwUAAAhWAAAIFgBACAAAEwczAAAIdgAACDYAAAnMABEHDwAACGYAAAgmAAAJrAAACAYAAAiGAAAIRgAACewAEAcJAAAIXgAACB4AAAmcABQHYwAACH4AAAg+AAAJ3AASBxsAAAhuAAAILgAACbwAAAgOAAAIjgAACE4AAAn8AGAHAAAACFEAAAgRABUIgwASBx8AAAhxAAAIMQAACcIAEAcKAAAIYQAACCEAAAmiAAAIAQAACIEAAAhBAAAJ4gAQBwYAAAhZAAAIGQAACZIAEwc7AAAIeQAACDkAAAnSABEHEQAACGkAAAgpAAAJsgAACAkAAAiJAAAISQAACfIAEAcEAAAIVQAACBUAEAgCARMHKwAACHUAAAg1AAAJygARBw0AAAhlAAAIJQAACaoAAAgFAAAIhQAACEUAAAnqABAHCAAACF0AAAgdAAAJmgAUB1MAAAh9AAAIPQAACdoAEgcXAAAIbQAACC0AAAm6AAAIDQAACI0AAAhNAAAJ+gAQBwMAAAhTAAAIEwAVCMMAEwcjAAAIcwAACDMAAAnGABEHCwAACGMAAAgjAAAJpgAACAMAAAiDAAAIQwAACeYAEAcHAAAIWwAACBsAAAmWABQHQwAACHsAAAg7AAAJ1gASBxMAAAhrAAAIKwAACbYAAAgLAAAIiwAACEsAAAn2ABAHBQAACFcAAAgXAEAIAAATBzMAAAh3AAAINwAACc4AEQcPAAAIZwAACCcAAAmuAAAIBwAACIcAAAhHAAAJ7gAQBwkAAAhfAAAIHwAACZ4AFAdjAAAIfwAACD8AAAneABIHGwAACG8AAAgvAAAJvgAACA8AAAiPAAAITwAACf4AYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwQAQBwoAAAhgAAAIIAAACaEAAAgAAAAIgAAACEAAAAnhABAHBgAACFgAAAgYAAAJkQATBzsAAAh4AAAIOAAACdEAEQcRAAAIaAAACCgAAAmxAAAICAAACIgAAAhIAAAJ8QAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnJABEHDQAACGQAAAgkAAAJqQAACAQAAAiEAAAIRAAACekAEAcIAAAIXAAACBwAAAmZABQHUwAACHwAAAg8AAAJ2QASBxcAAAhsAAAILAAACbkAAAgMAAAIjAAACEwAAAn5ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcUAEQcLAAAIYgAACCIAAAmlAAAIAgAACIIAAAhCAAAJ5QAQBwcAAAhaAAAIGgAACZUAFAdDAAAIegAACDoAAAnVABIHEwAACGoAAAgqAAAJtQAACAoAAAiKAAAISgAACfUAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzQARBw8AAAhmAAAIJgAACa0AAAgGAAAIhgAACEYAAAntABAHCQAACF4AAAgeAAAJnQAUB2MAAAh+AAAIPgAACd0AEgcbAAAIbgAACC4AAAm9AAAIDgAACI4AAAhOAAAJ/QBgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnDABAHCgAACGEAAAghAAAJowAACAEAAAiBAAAIQQAACeMAEAcGAAAIWQAACBkAAAmTABMHOwAACHkAAAg5AAAJ0wARBxEAAAhpAAAIKQAACbMAAAgJAAAIiQAACEkAAAnzABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcsAEQcNAAAIZQAACCUAAAmrAAAIBQAACIUAAAhFAAAJ6wAQBwgAAAhdAAAIHQAACZsAFAdTAAAIfQAACD0AAAnbABIHFwAACG0AAAgtAAAJuwAACA0AAAiNAAAITQAACfsAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxwARBwsAAAhjAAAIIwAACacAAAgDAAAIgwAACEMAAAnnABAHBwAACFsAAAgbAAAJlwAUB0MAAAh7AAAIOwAACdcAEgcTAAAIawAACCsAAAm3AAAICwAACIsAAAhLAAAJ9wAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnPABEHDwAACGcAAAgnAAAJrwAACAcAAAiHAAAIRwAACe8AEAcJAAAIXwAACB8AAAmfABQHYwAACH8AAAg/AAAJ3wASBxsAAAhvAAAILwAACb8AAAgPAAAIjwAACE8AAAn/ABAFAQAXBQEBEwURABsFARARBQUAGQUBBBUFQQAdBQFAEAUDABgFAQIUBSEAHAUBIBIFCQAaBQEIFgWBAEAFAAAQBQIAFwWBARMFGQAbBQEYEQUHABkFAQYVBWEAHQUBYBAFBAAYBQEDFAUxABwFATASBQ0AGgUBDBYFwQBABQAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAQYGEAQshCwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAEG7hAELAQwAQceEAQsVDAAAAAAMAAAAAAkMAAAAAAAMAAAMAEH1hAELAQ4AQYGFAQsVDQAAAAQNAAAAAAkOAAAAAAAOAAAOAEGvhQELARAAQbuFAQseDwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAEHyhQELDhIAAAASEhIAAAAAAAAJAEGjhgELAQsAQa+GAQsVCgAAAAAKAAAAAAkLAAAAAAALAAALAEHdhgELAQwAQemGAQsnDAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGAEG0hwELARkAQduHAQsF//////8AQaCIAQtXGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAEGAiQELig5JbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBObyBlcnJvciBpbmZvcm1hdGlvbgBBkJcBC1JQUFAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAEAAAAIAAAAlEsAALRLAEGQmQELAgxQAEHImQELCR8AAADkTAAAAwBB5JkBC4wBLfRRWM+MscBG9rXLKTEDxwRbcDC0Xf0geH+LmthZKVBoSImrp1YDbP+3zYg/1He0K6WjcPG65Kj8QYP92W/hinovLXSWBx8NCV4Ddixw90ClLKdvV0GoqnTfoFhkA0rHxDxTrq9fGAQVseNtKIarDKS/Q/DpUIE5VxZSN/////////////////////8=";fg(Io)||(Io=p(Io));function hg(f){try{if(f==Io&&X)return new Uint8Array(X);var E=pa(f);if(E)return E;if(m)return m(f);throw"sync fetching of the wasm failed: you can preload it to Module['wasmBinary'] manually, or emcc.py will do that for you when generating HTML (but not JS)"}catch(w){Ir(w)}}function Bp(f,E){var w,k,L;try{L=hg(f),k=new WebAssembly.Module(L),w=new WebAssembly.Instance(k,E)}catch(ee){var T=ee.toString();throw x("failed to compile wasm module: "+T),(T.includes("imported Memory")||T.includes("memory import"))&&x("Memory size incompatibility issues may be due to changing INITIAL_MEMORY at runtime to something too large. Use ALLOW_MEMORY_GROWTH to allow any size memory (and also make sure not to set INITIAL_MEMORY at runtime to something smaller than it was at compile time)."),ee}return[w,k]}function bp(){var f={a:da};function E(L,T){var ee=L.exports;t.asm=ee,A=t.asm.u,Tr(A.buffer),ui=t.asm.pa,CA(t.asm.v),IA("wasm-instantiate")}if(EA("wasm-instantiate"),t.instantiateWasm)try{var w=t.instantiateWasm(f,E);return w}catch(L){return x("Module.instantiateWasm callback failed with error: "+L),!1}var k=Bp(Io,f);return E(k[0]),t.asm}var Qr,Ri;function yo(f){for(;f.length>0;){var E=f.shift();if(typeof E=="function"){E(t);continue}var w=E.func;typeof w=="number"?E.arg===void 0?ui.get(w)():ui.get(w)(E.arg):w(E.arg===void 0?null:E.arg)}}function Nn(f,E){var w=new Date(de[f>>2]*1e3);de[E>>2]=w.getUTCSeconds(),de[E+4>>2]=w.getUTCMinutes(),de[E+8>>2]=w.getUTCHours(),de[E+12>>2]=w.getUTCDate(),de[E+16>>2]=w.getUTCMonth(),de[E+20>>2]=w.getUTCFullYear()-1900,de[E+24>>2]=w.getUTCDay(),de[E+36>>2]=0,de[E+32>>2]=0;var k=Date.UTC(w.getUTCFullYear(),0,1,0,0,0,0),L=(w.getTime()-k)/(1e3*60*60*24)|0;return de[E+28>>2]=L,Nn.GMTString||(Nn.GMTString=ye("GMT")),de[E+40>>2]=Nn.GMTString,E}function ae(f,E){return Nn(f,E)}var yt={splitPath:function(f){var E=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return E.exec(f).slice(1)},normalizeArray:function(f,E){for(var w=0,k=f.length-1;k>=0;k--){var L=f[k];L==="."?f.splice(k,1):L===".."?(f.splice(k,1),w++):w&&(f.splice(k,1),w--)}if(E)for(;w;w--)f.unshift("..");return f},normalize:function(f){var E=f.charAt(0)==="/",w=f.substr(-1)==="/";return f=yt.normalizeArray(f.split("/").filter(function(k){return!!k}),!E).join("/"),!f&&!E&&(f="."),f&&w&&(f+="/"),(E?"/":"")+f},dirname:function(f){var E=yt.splitPath(f),w=E[0],k=E[1];return!w&&!k?".":(k&&(k=k.substr(0,k.length-1)),w+k)},basename:function(f){if(f==="/")return"/";f=yt.normalize(f),f=f.replace(/\/$/,"");var E=f.lastIndexOf("/");return E===-1?f:f.substr(E+1)},extname:function(f){return yt.splitPath(f)[3]},join:function(){var f=Array.prototype.slice.call(arguments,0);return yt.normalize(f.join("/"))},join2:function(f,E){return yt.normalize(f+"/"+E)}};function Tl(){if(typeof crypto=="object"&&typeof crypto.getRandomValues=="function"){var f=new Uint8Array(1);return function(){return crypto.getRandomValues(f),f[0]}}else if(g)try{var E=J("crypto");return function(){return E.randomBytes(1)[0]}}catch{}return function(){Ir("randomDevice")}}var Tn={resolve:function(){for(var f="",E=!1,w=arguments.length-1;w>=-1&&!E;w--){var k=w>=0?arguments[w]:Q.cwd();if(typeof k!="string")throw new TypeError("Arguments to path.resolve must be strings");if(!k)return"";f=k+"/"+f,E=k.charAt(0)==="/"}return f=yt.normalizeArray(f.split("/").filter(function(L){return!!L}),!E).join("/"),(E?"/":"")+f||"."},relative:function(f,E){f=Tn.resolve(f).substr(1),E=Tn.resolve(E).substr(1);function w(it){for(var at=0;at<it.length&&it[at]==="";at++);for(var Ue=it.length-1;Ue>=0&&it[Ue]==="";Ue--);return at>Ue?[]:it.slice(at,Ue-at+1)}for(var k=w(f.split("/")),L=w(E.split("/")),T=Math.min(k.length,L.length),ee=T,Ie=0;Ie<T;Ie++)if(k[Ie]!==L[Ie]){ee=Ie;break}for(var Oe=[],Ie=ee;Ie<k.length;Ie++)Oe.push("..");return Oe=Oe.concat(L.slice(ee)),Oe.join("/")}},ns={ttys:[],init:function(){},shutdown:function(){},register:function(f,E){ns.ttys[f]={input:[],output:[],ops:E},Q.registerDevice(f,ns.stream_ops)},stream_ops:{open:function(f){var E=ns.ttys[f.node.rdev];if(!E)throw new Q.ErrnoError(43);f.tty=E,f.seekable=!1},close:function(f){f.tty.ops.flush(f.tty)},flush:function(f){f.tty.ops.flush(f.tty)},read:function(f,E,w,k,L){if(!f.tty||!f.tty.ops.get_char)throw new Q.ErrnoError(60);for(var T=0,ee=0;ee<k;ee++){var Ie;try{Ie=f.tty.ops.get_char(f.tty)}catch{throw new Q.ErrnoError(29)}if(Ie===void 0&&T===0)throw new Q.ErrnoError(6);if(Ie==null)break;T++,E[w+ee]=Ie}return T&&(f.node.timestamp=Date.now()),T},write:function(f,E,w,k,L){if(!f.tty||!f.tty.ops.put_char)throw new Q.ErrnoError(60);try{for(var T=0;T<k;T++)f.tty.ops.put_char(f.tty,E[w+T])}catch{throw new Q.ErrnoError(29)}return k&&(f.node.timestamp=Date.now()),T}},default_tty_ops:{get_char:function(f){if(!f.input.length){var E=null;if(g){var w=256,k=Buffer.alloc?Buffer.alloc(w):new Buffer(w),L=0;try{L=y.readSync(process.stdin.fd,k,0,w,null)}catch(T){if(T.toString().includes("EOF"))L=0;else throw T}L>0?E=k.slice(0,L).toString("utf-8"):E=null}else typeof window<"u"&&typeof window.prompt=="function"?(E=window.prompt("Input: "),E!==null&&(E+=` +`)):typeof readline=="function"&&(E=readline(),E!==null&&(E+=` +`));if(!E)return null;f.input=wA(E,!0)}return f.input.shift()},put_char:function(f,E){E===null||E===10?(S(xe(f.output,0)),f.output=[]):E!=0&&f.output.push(E)},flush:function(f){f.output&&f.output.length>0&&(S(xe(f.output,0)),f.output=[])}},default_tty1_ops:{put_char:function(f,E){E===null||E===10?(x(xe(f.output,0)),f.output=[]):E!=0&&f.output.push(E)},flush:function(f){f.output&&f.output.length>0&&(x(xe(f.output,0)),f.output=[])}}};function ss(f){for(var E=H(f,65536),w=pt(E);f<E;)ie[w+f++]=0;return w}var ut={ops_table:null,mount:function(f){return ut.createNode(null,"/",16895,0)},createNode:function(f,E,w,k){if(Q.isBlkdev(w)||Q.isFIFO(w))throw new Q.ErrnoError(63);ut.ops_table||(ut.ops_table={dir:{node:{getattr:ut.node_ops.getattr,setattr:ut.node_ops.setattr,lookup:ut.node_ops.lookup,mknod:ut.node_ops.mknod,rename:ut.node_ops.rename,unlink:ut.node_ops.unlink,rmdir:ut.node_ops.rmdir,readdir:ut.node_ops.readdir,symlink:ut.node_ops.symlink},stream:{llseek:ut.stream_ops.llseek}},file:{node:{getattr:ut.node_ops.getattr,setattr:ut.node_ops.setattr},stream:{llseek:ut.stream_ops.llseek,read:ut.stream_ops.read,write:ut.stream_ops.write,allocate:ut.stream_ops.allocate,mmap:ut.stream_ops.mmap,msync:ut.stream_ops.msync}},link:{node:{getattr:ut.node_ops.getattr,setattr:ut.node_ops.setattr,readlink:ut.node_ops.readlink},stream:{}},chrdev:{node:{getattr:ut.node_ops.getattr,setattr:ut.node_ops.setattr},stream:Q.chrdev_stream_ops}});var L=Q.createNode(f,E,w,k);return Q.isDir(L.mode)?(L.node_ops=ut.ops_table.dir.node,L.stream_ops=ut.ops_table.dir.stream,L.contents={}):Q.isFile(L.mode)?(L.node_ops=ut.ops_table.file.node,L.stream_ops=ut.ops_table.file.stream,L.usedBytes=0,L.contents=null):Q.isLink(L.mode)?(L.node_ops=ut.ops_table.link.node,L.stream_ops=ut.ops_table.link.stream):Q.isChrdev(L.mode)&&(L.node_ops=ut.ops_table.chrdev.node,L.stream_ops=ut.ops_table.chrdev.stream),L.timestamp=Date.now(),f&&(f.contents[E]=L,f.timestamp=L.timestamp),L},getFileDataAsTypedArray:function(f){return f.contents?f.contents.subarray?f.contents.subarray(0,f.usedBytes):new Uint8Array(f.contents):new Uint8Array(0)},expandFileStorage:function(f,E){var w=f.contents?f.contents.length:0;if(!(w>=E)){var k=1024*1024;E=Math.max(E,w*(w<k?2:1.125)>>>0),w!=0&&(E=Math.max(E,256));var L=f.contents;f.contents=new Uint8Array(E),f.usedBytes>0&&f.contents.set(L.subarray(0,f.usedBytes),0)}},resizeFileStorage:function(f,E){if(f.usedBytes!=E)if(E==0)f.contents=null,f.usedBytes=0;else{var w=f.contents;f.contents=new Uint8Array(E),w&&f.contents.set(w.subarray(0,Math.min(E,f.usedBytes))),f.usedBytes=E}},node_ops:{getattr:function(f){var E={};return E.dev=Q.isChrdev(f.mode)?f.id:1,E.ino=f.id,E.mode=f.mode,E.nlink=1,E.uid=0,E.gid=0,E.rdev=f.rdev,Q.isDir(f.mode)?E.size=4096:Q.isFile(f.mode)?E.size=f.usedBytes:Q.isLink(f.mode)?E.size=f.link.length:E.size=0,E.atime=new Date(f.timestamp),E.mtime=new Date(f.timestamp),E.ctime=new Date(f.timestamp),E.blksize=4096,E.blocks=Math.ceil(E.size/E.blksize),E},setattr:function(f,E){E.mode!==void 0&&(f.mode=E.mode),E.timestamp!==void 0&&(f.timestamp=E.timestamp),E.size!==void 0&&ut.resizeFileStorage(f,E.size)},lookup:function(f,E){throw Q.genericErrors[44]},mknod:function(f,E,w,k){return ut.createNode(f,E,w,k)},rename:function(f,E,w){if(Q.isDir(f.mode)){var k;try{k=Q.lookupNode(E,w)}catch{}if(k)for(var L in k.contents)throw new Q.ErrnoError(55)}delete f.parent.contents[f.name],f.parent.timestamp=Date.now(),f.name=w,E.contents[w]=f,E.timestamp=f.parent.timestamp,f.parent=E},unlink:function(f,E){delete f.contents[E],f.timestamp=Date.now()},rmdir:function(f,E){var w=Q.lookupNode(f,E);for(var k in w.contents)throw new Q.ErrnoError(55);delete f.contents[E],f.timestamp=Date.now()},readdir:function(f){var E=[".",".."];for(var w in f.contents)!f.contents.hasOwnProperty(w)||E.push(w);return E},symlink:function(f,E,w){var k=ut.createNode(f,E,41471,0);return k.link=w,k},readlink:function(f){if(!Q.isLink(f.mode))throw new Q.ErrnoError(28);return f.link}},stream_ops:{read:function(f,E,w,k,L){var T=f.node.contents;if(L>=f.node.usedBytes)return 0;var ee=Math.min(f.node.usedBytes-L,k);if(ee>8&&T.subarray)E.set(T.subarray(L,L+ee),w);else for(var Ie=0;Ie<ee;Ie++)E[w+Ie]=T[L+Ie];return ee},write:function(f,E,w,k,L,T){if(E.buffer===ie.buffer&&(T=!1),!k)return 0;var ee=f.node;if(ee.timestamp=Date.now(),E.subarray&&(!ee.contents||ee.contents.subarray)){if(T)return ee.contents=E.subarray(w,w+k),ee.usedBytes=k,k;if(ee.usedBytes===0&&L===0)return ee.contents=E.slice(w,w+k),ee.usedBytes=k,k;if(L+k<=ee.usedBytes)return ee.contents.set(E.subarray(w,w+k),L),k}if(ut.expandFileStorage(ee,L+k),ee.contents.subarray&&E.subarray)ee.contents.set(E.subarray(w,w+k),L);else for(var Ie=0;Ie<k;Ie++)ee.contents[L+Ie]=E[w+Ie];return ee.usedBytes=Math.max(ee.usedBytes,L+k),k},llseek:function(f,E,w){var k=E;if(w===1?k+=f.position:w===2&&Q.isFile(f.node.mode)&&(k+=f.node.usedBytes),k<0)throw new Q.ErrnoError(28);return k},allocate:function(f,E,w){ut.expandFileStorage(f.node,E+w),f.node.usedBytes=Math.max(f.node.usedBytes,E+w)},mmap:function(f,E,w,k,L,T){if(E!==0)throw new Q.ErrnoError(28);if(!Q.isFile(f.node.mode))throw new Q.ErrnoError(43);var ee,Ie,Oe=f.node.contents;if(!(T&2)&&Oe.buffer===Ye)Ie=!1,ee=Oe.byteOffset;else{if((k>0||k+w<Oe.length)&&(Oe.subarray?Oe=Oe.subarray(k,k+w):Oe=Array.prototype.slice.call(Oe,k,k+w)),Ie=!0,ee=ss(w),!ee)throw new Q.ErrnoError(48);ie.set(Oe,ee)}return{ptr:ee,allocated:Ie}},msync:function(f,E,w,k,L){if(!Q.isFile(f.node.mode))throw new Q.ErrnoError(43);if(L&2)return 0;var T=ut.stream_ops.write(f,E,0,k,w,!1);return 0}}},wo={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135},At={isWindows:!1,staticInit:function(){At.isWindows=!!process.platform.match(/^win/);var f={fs:Ne.constants};f.fs&&(f=f.fs),At.flagsForNodeMap={1024:f.O_APPEND,64:f.O_CREAT,128:f.O_EXCL,256:f.O_NOCTTY,0:f.O_RDONLY,2:f.O_RDWR,4096:f.O_SYNC,512:f.O_TRUNC,1:f.O_WRONLY}},bufferFrom:function(f){return Buffer.alloc?Buffer.from(f):new Buffer(f)},convertNodeCode:function(f){var E=f.code;return wo[E]},mount:function(f){return At.createNode(null,"/",At.getMode(f.opts.root),0)},createNode:function(f,E,w,k){if(!Q.isDir(w)&&!Q.isFile(w)&&!Q.isLink(w))throw new Q.ErrnoError(28);var L=Q.createNode(f,E,w);return L.node_ops=At.node_ops,L.stream_ops=At.stream_ops,L},getMode:function(f){var E;try{E=Ne.lstatSync(f),At.isWindows&&(E.mode=E.mode|(E.mode&292)>>2)}catch(w){throw w.code?new Q.ErrnoError(At.convertNodeCode(w)):w}return E.mode},realPath:function(f){for(var E=[];f.parent!==f;)E.push(f.name),f=f.parent;return E.push(f.mount.opts.root),E.reverse(),yt.join.apply(null,E)},flagsForNode:function(f){f&=-2097153,f&=-2049,f&=-32769,f&=-524289;var E=0;for(var w in At.flagsForNodeMap)f&w&&(E|=At.flagsForNodeMap[w],f^=w);if(f)throw new Q.ErrnoError(28);return E},node_ops:{getattr:function(f){var E=At.realPath(f),w;try{w=Ne.lstatSync(E)}catch(k){throw k.code?new Q.ErrnoError(At.convertNodeCode(k)):k}return At.isWindows&&!w.blksize&&(w.blksize=4096),At.isWindows&&!w.blocks&&(w.blocks=(w.size+w.blksize-1)/w.blksize|0),{dev:w.dev,ino:w.ino,mode:w.mode,nlink:w.nlink,uid:w.uid,gid:w.gid,rdev:w.rdev,size:w.size,atime:w.atime,mtime:w.mtime,ctime:w.ctime,blksize:w.blksize,blocks:w.blocks}},setattr:function(f,E){var w=At.realPath(f);try{if(E.mode!==void 0&&(Ne.chmodSync(w,E.mode),f.mode=E.mode),E.timestamp!==void 0){var k=new Date(E.timestamp);Ne.utimesSync(w,k,k)}E.size!==void 0&&Ne.truncateSync(w,E.size)}catch(L){throw L.code?new Q.ErrnoError(At.convertNodeCode(L)):L}},lookup:function(f,E){var w=yt.join2(At.realPath(f),E),k=At.getMode(w);return At.createNode(f,E,k)},mknod:function(f,E,w,k){var L=At.createNode(f,E,w,k),T=At.realPath(L);try{Q.isDir(L.mode)?Ne.mkdirSync(T,L.mode):Ne.writeFileSync(T,"",{mode:L.mode})}catch(ee){throw ee.code?new Q.ErrnoError(At.convertNodeCode(ee)):ee}return L},rename:function(f,E,w){var k=At.realPath(f),L=yt.join2(At.realPath(E),w);try{Ne.renameSync(k,L)}catch(T){throw T.code?new Q.ErrnoError(At.convertNodeCode(T)):T}f.name=w},unlink:function(f,E){var w=yt.join2(At.realPath(f),E);try{Ne.unlinkSync(w)}catch(k){throw k.code?new Q.ErrnoError(At.convertNodeCode(k)):k}},rmdir:function(f,E){var w=yt.join2(At.realPath(f),E);try{Ne.rmdirSync(w)}catch(k){throw k.code?new Q.ErrnoError(At.convertNodeCode(k)):k}},readdir:function(f){var E=At.realPath(f);try{return Ne.readdirSync(E)}catch(w){throw w.code?new Q.ErrnoError(At.convertNodeCode(w)):w}},symlink:function(f,E,w){var k=yt.join2(At.realPath(f),E);try{Ne.symlinkSync(w,k)}catch(L){throw L.code?new Q.ErrnoError(At.convertNodeCode(L)):L}},readlink:function(f){var E=At.realPath(f);try{return E=Ne.readlinkSync(E),E=Cg.relative(Cg.resolve(f.mount.opts.root),E),E}catch(w){throw w.code?new Q.ErrnoError(At.convertNodeCode(w)):w}}},stream_ops:{open:function(f){var E=At.realPath(f.node);try{Q.isFile(f.node.mode)&&(f.nfd=Ne.openSync(E,At.flagsForNode(f.flags)))}catch(w){throw w.code?new Q.ErrnoError(At.convertNodeCode(w)):w}},close:function(f){try{Q.isFile(f.node.mode)&&f.nfd&&Ne.closeSync(f.nfd)}catch(E){throw E.code?new Q.ErrnoError(At.convertNodeCode(E)):E}},read:function(f,E,w,k,L){if(k===0)return 0;try{return Ne.readSync(f.nfd,At.bufferFrom(E.buffer),w,k,L)}catch(T){throw new Q.ErrnoError(At.convertNodeCode(T))}},write:function(f,E,w,k,L){try{return Ne.writeSync(f.nfd,At.bufferFrom(E.buffer),w,k,L)}catch(T){throw new Q.ErrnoError(At.convertNodeCode(T))}},llseek:function(f,E,w){var k=E;if(w===1)k+=f.position;else if(w===2&&Q.isFile(f.node.mode))try{var L=Ne.fstatSync(f.nfd);k+=L.size}catch(T){throw new Q.ErrnoError(At.convertNodeCode(T))}if(k<0)throw new Q.ErrnoError(28);return k},mmap:function(f,E,w,k,L,T){if(E!==0)throw new Q.ErrnoError(28);if(!Q.isFile(f.node.mode))throw new Q.ErrnoError(43);var ee=ss(w);return At.stream_ops.read(f,ie,ee,w,k),{ptr:ee,allocated:!0}},msync:function(f,E,w,k,L){if(!Q.isFile(f.node.mode))throw new Q.ErrnoError(43);if(L&2)return 0;var T=At.stream_ops.write(f,E,0,k,w,!1);return 0}}},An={lookupPath:function(f){return{path:f,node:{mode:At.getMode(f)}}},createStandardStreams:function(){Q.streams[0]={fd:0,nfd:0,position:0,path:"",flags:0,tty:!0,seekable:!1};for(var f=1;f<3;f++)Q.streams[f]={fd:f,nfd:f,position:0,path:"",flags:577,tty:!0,seekable:!1}},cwd:function(){return process.cwd()},chdir:function(){process.chdir.apply(void 0,arguments)},mknod:function(f,E){Q.isDir(f)?Ne.mkdirSync(f,E):Ne.writeFileSync(f,"",{mode:E})},mkdir:function(){Ne.mkdirSync.apply(void 0,arguments)},symlink:function(){Ne.symlinkSync.apply(void 0,arguments)},rename:function(){Ne.renameSync.apply(void 0,arguments)},rmdir:function(){Ne.rmdirSync.apply(void 0,arguments)},readdir:function(){Ne.readdirSync.apply(void 0,arguments)},unlink:function(){Ne.unlinkSync.apply(void 0,arguments)},readlink:function(){return Ne.readlinkSync.apply(void 0,arguments)},stat:function(){return Ne.statSync.apply(void 0,arguments)},lstat:function(){return Ne.lstatSync.apply(void 0,arguments)},chmod:function(){Ne.chmodSync.apply(void 0,arguments)},fchmod:function(){Ne.fchmodSync.apply(void 0,arguments)},chown:function(){Ne.chownSync.apply(void 0,arguments)},fchown:function(){Ne.fchownSync.apply(void 0,arguments)},truncate:function(){Ne.truncateSync.apply(void 0,arguments)},ftruncate:function(f,E){if(E<0)throw new Q.ErrnoError(28);Ne.ftruncateSync.apply(void 0,arguments)},utime:function(){Ne.utimesSync.apply(void 0,arguments)},open:function(f,E,w,k){typeof E=="string"&&(E=Us.modeStringToFlags(E));var L=Ne.openSync(f,At.flagsForNode(E),w),T=k!=null?k:Q.nextfd(L),ee={fd:T,nfd:L,position:0,path:f,flags:E,seekable:!0};return Q.streams[T]=ee,ee},close:function(f){f.stream_ops||Ne.closeSync(f.nfd),Q.closeStream(f.fd)},llseek:function(f,E,w){if(f.stream_ops)return Us.llseek(f,E,w);var k=E;if(w===1)k+=f.position;else if(w===2)k+=Ne.fstatSync(f.nfd).size;else if(w!==0)throw new Q.ErrnoError(wo.EINVAL);if(k<0)throw new Q.ErrnoError(wo.EINVAL);return f.position=k,k},read:function(f,E,w,k,L){if(f.stream_ops)return Us.read(f,E,w,k,L);var T=typeof L<"u";!T&&f.seekable&&(L=f.position);var ee=Ne.readSync(f.nfd,At.bufferFrom(E.buffer),w,k,L);return T||(f.position+=ee),ee},write:function(f,E,w,k,L){if(f.stream_ops)return Us.write(f,E,w,k,L);f.flags&+"1024"&&Q.llseek(f,0,+"2");var T=typeof L<"u";!T&&f.seekable&&(L=f.position);var ee=Ne.writeSync(f.nfd,At.bufferFrom(E.buffer),w,k,L);return T||(f.position+=ee),ee},allocate:function(){throw new Q.ErrnoError(wo.EOPNOTSUPP)},mmap:function(f,E,w,k,L,T){if(f.stream_ops)return Us.mmap(f,E,w,k,L,T);if(E!==0)throw new Q.ErrnoError(28);var ee=ss(w);return Q.read(f,ie,ee,w,k),{ptr:ee,allocated:!0}},msync:function(f,E,w,k,L){return f.stream_ops?Us.msync(f,E,w,k,L):(L&2||Q.write(f,E,0,k,w),0)},munmap:function(){return 0},ioctl:function(){throw new Q.ErrnoError(wo.ENOTTY)}},Q={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:!1,ignorePermissions:!0,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:function(f,E){if(f=Tn.resolve(Q.cwd(),f),E=E||{},!f)return{path:"",node:null};var w={follow_mount:!0,recurse_count:0};for(var k in w)E[k]===void 0&&(E[k]=w[k]);if(E.recurse_count>8)throw new Q.ErrnoError(32);for(var L=yt.normalizeArray(f.split("/").filter(function(Ve){return!!Ve}),!1),T=Q.root,ee="/",Ie=0;Ie<L.length;Ie++){var Oe=Ie===L.length-1;if(Oe&&E.parent)break;if(T=Q.lookupNode(T,L[Ie]),ee=yt.join2(ee,L[Ie]),Q.isMountpoint(T)&&(!Oe||Oe&&E.follow_mount)&&(T=T.mounted.root),!Oe||E.follow)for(var it=0;Q.isLink(T.mode);){var at=Q.readlink(ee);ee=Tn.resolve(yt.dirname(ee),at);var Ue=Q.lookupPath(ee,{recurse_count:E.recurse_count});if(T=Ue.node,it++>40)throw new Q.ErrnoError(32)}}return{path:ee,node:T}},getPath:function(f){for(var E;;){if(Q.isRoot(f)){var w=f.mount.mountpoint;return E?w[w.length-1]!=="/"?w+"/"+E:w+E:w}E=E?f.name+"/"+E:f.name,f=f.parent}},hashName:function(f,E){for(var w=0,k=0;k<E.length;k++)w=(w<<5)-w+E.charCodeAt(k)|0;return(f+w>>>0)%Q.nameTable.length},hashAddNode:function(f){var E=Q.hashName(f.parent.id,f.name);f.name_next=Q.nameTable[E],Q.nameTable[E]=f},hashRemoveNode:function(f){var E=Q.hashName(f.parent.id,f.name);if(Q.nameTable[E]===f)Q.nameTable[E]=f.name_next;else for(var w=Q.nameTable[E];w;){if(w.name_next===f){w.name_next=f.name_next;break}w=w.name_next}},lookupNode:function(f,E){var w=Q.mayLookup(f);if(w)throw new Q.ErrnoError(w,f);for(var k=Q.hashName(f.id,E),L=Q.nameTable[k];L;L=L.name_next){var T=L.name;if(L.parent.id===f.id&&T===E)return L}return Q.lookup(f,E)},createNode:function(f,E,w,k){var L=new Q.FSNode(f,E,w,k);return Q.hashAddNode(L),L},destroyNode:function(f){Q.hashRemoveNode(f)},isRoot:function(f){return f===f.parent},isMountpoint:function(f){return!!f.mounted},isFile:function(f){return(f&61440)===32768},isDir:function(f){return(f&61440)===16384},isLink:function(f){return(f&61440)===40960},isChrdev:function(f){return(f&61440)===8192},isBlkdev:function(f){return(f&61440)===24576},isFIFO:function(f){return(f&61440)===4096},isSocket:function(f){return(f&49152)===49152},flagModes:{r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},modeStringToFlags:function(f){var E=Q.flagModes[f];if(typeof E>"u")throw new Error("Unknown file open mode: "+f);return E},flagsToPermissionString:function(f){var E=["r","w","rw"][f&3];return f&512&&(E+="w"),E},nodePermissions:function(f,E){return Q.ignorePermissions?0:E.includes("r")&&!(f.mode&292)||E.includes("w")&&!(f.mode&146)||E.includes("x")&&!(f.mode&73)?2:0},mayLookup:function(f){var E=Q.nodePermissions(f,"x");return E||(f.node_ops.lookup?0:2)},mayCreate:function(f,E){try{var w=Q.lookupNode(f,E);return 20}catch{}return Q.nodePermissions(f,"wx")},mayDelete:function(f,E,w){var k;try{k=Q.lookupNode(f,E)}catch(T){return T.errno}var L=Q.nodePermissions(f,"wx");if(L)return L;if(w){if(!Q.isDir(k.mode))return 54;if(Q.isRoot(k)||Q.getPath(k)===Q.cwd())return 10}else if(Q.isDir(k.mode))return 31;return 0},mayOpen:function(f,E){return f?Q.isLink(f.mode)?32:Q.isDir(f.mode)&&(Q.flagsToPermissionString(E)!=="r"||E&512)?31:Q.nodePermissions(f,Q.flagsToPermissionString(E)):44},MAX_OPEN_FDS:4096,nextfd:function(f,E){f=f||0,E=E||Q.MAX_OPEN_FDS;for(var w=f;w<=E;w++)if(!Q.streams[w])return w;throw new Q.ErrnoError(33)},getStream:function(f){return Q.streams[f]},createStream:function(f,E,w){Q.FSStream||(Q.FSStream=function(){},Q.FSStream.prototype={object:{get:function(){return this.node},set:function(ee){this.node=ee}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}});var k=new Q.FSStream;for(var L in f)k[L]=f[L];f=k;var T=Q.nextfd(E,w);return f.fd=T,Q.streams[T]=f,f},closeStream:function(f){Q.streams[f]=null},chrdev_stream_ops:{open:function(f){var E=Q.getDevice(f.node.rdev);f.stream_ops=E.stream_ops,f.stream_ops.open&&f.stream_ops.open(f)},llseek:function(){throw new Q.ErrnoError(70)}},major:function(f){return f>>8},minor:function(f){return f&255},makedev:function(f,E){return f<<8|E},registerDevice:function(f,E){Q.devices[f]={stream_ops:E}},getDevice:function(f){return Q.devices[f]},getMounts:function(f){for(var E=[],w=[f];w.length;){var k=w.pop();E.push(k),w.push.apply(w,k.mounts)}return E},syncfs:function(f,E){typeof f=="function"&&(E=f,f=!1),Q.syncFSRequests++,Q.syncFSRequests>1&&x("warning: "+Q.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var w=Q.getMounts(Q.root.mount),k=0;function L(ee){return Q.syncFSRequests--,E(ee)}function T(ee){if(ee)return T.errored?void 0:(T.errored=!0,L(ee));++k>=w.length&&L(null)}w.forEach(function(ee){if(!ee.type.syncfs)return T(null);ee.type.syncfs(ee,f,T)})},mount:function(f,E,w){var k=w==="/",L=!w,T;if(k&&Q.root)throw new Q.ErrnoError(10);if(!k&&!L){var ee=Q.lookupPath(w,{follow_mount:!1});if(w=ee.path,T=ee.node,Q.isMountpoint(T))throw new Q.ErrnoError(10);if(!Q.isDir(T.mode))throw new Q.ErrnoError(54)}var Ie={type:f,opts:E,mountpoint:w,mounts:[]},Oe=f.mount(Ie);return Oe.mount=Ie,Ie.root=Oe,k?Q.root=Oe:T&&(T.mounted=Ie,T.mount&&T.mount.mounts.push(Ie)),Oe},unmount:function(f){var E=Q.lookupPath(f,{follow_mount:!1});if(!Q.isMountpoint(E.node))throw new Q.ErrnoError(28);var w=E.node,k=w.mounted,L=Q.getMounts(k);Object.keys(Q.nameTable).forEach(function(ee){for(var Ie=Q.nameTable[ee];Ie;){var Oe=Ie.name_next;L.includes(Ie.mount)&&Q.destroyNode(Ie),Ie=Oe}}),w.mounted=null;var T=w.mount.mounts.indexOf(k);w.mount.mounts.splice(T,1)},lookup:function(f,E){return f.node_ops.lookup(f,E)},mknod:function(f,E,w){var k=Q.lookupPath(f,{parent:!0}),L=k.node,T=yt.basename(f);if(!T||T==="."||T==="..")throw new Q.ErrnoError(28);var ee=Q.mayCreate(L,T);if(ee)throw new Q.ErrnoError(ee);if(!L.node_ops.mknod)throw new Q.ErrnoError(63);return L.node_ops.mknod(L,T,E,w)},create:function(f,E){return E=E!==void 0?E:438,E&=4095,E|=32768,Q.mknod(f,E,0)},mkdir:function(f,E){return E=E!==void 0?E:511,E&=1023,E|=16384,Q.mknod(f,E,0)},mkdirTree:function(f,E){for(var w=f.split("/"),k="",L=0;L<w.length;++L)if(!!w[L]){k+="/"+w[L];try{Q.mkdir(k,E)}catch(T){if(T.errno!=20)throw T}}},mkdev:function(f,E,w){return typeof w>"u"&&(w=E,E=438),E|=8192,Q.mknod(f,E,w)},symlink:function(f,E){if(!Tn.resolve(f))throw new Q.ErrnoError(44);var w=Q.lookupPath(E,{parent:!0}),k=w.node;if(!k)throw new Q.ErrnoError(44);var L=yt.basename(E),T=Q.mayCreate(k,L);if(T)throw new Q.ErrnoError(T);if(!k.node_ops.symlink)throw new Q.ErrnoError(63);return k.node_ops.symlink(k,L,f)},rename:function(f,E){var w=yt.dirname(f),k=yt.dirname(E),L=yt.basename(f),T=yt.basename(E),ee,Ie,Oe;if(ee=Q.lookupPath(f,{parent:!0}),Ie=ee.node,ee=Q.lookupPath(E,{parent:!0}),Oe=ee.node,!Ie||!Oe)throw new Q.ErrnoError(44);if(Ie.mount!==Oe.mount)throw new Q.ErrnoError(75);var it=Q.lookupNode(Ie,L),at=Tn.relative(f,k);if(at.charAt(0)!==".")throw new Q.ErrnoError(28);if(at=Tn.relative(E,w),at.charAt(0)!==".")throw new Q.ErrnoError(55);var Ue;try{Ue=Q.lookupNode(Oe,T)}catch{}if(it!==Ue){var Ve=Q.isDir(it.mode),nt=Q.mayDelete(Ie,L,Ve);if(nt)throw new Q.ErrnoError(nt);if(nt=Ue?Q.mayDelete(Oe,T,Ve):Q.mayCreate(Oe,T),nt)throw new Q.ErrnoError(nt);if(!Ie.node_ops.rename)throw new Q.ErrnoError(63);if(Q.isMountpoint(it)||Ue&&Q.isMountpoint(Ue))throw new Q.ErrnoError(10);if(Oe!==Ie&&(nt=Q.nodePermissions(Ie,"w"),nt))throw new Q.ErrnoError(nt);try{Q.trackingDelegate.willMovePath&&Q.trackingDelegate.willMovePath(f,E)}catch(wt){x("FS.trackingDelegate['willMovePath']('"+f+"', '"+E+"') threw an exception: "+wt.message)}Q.hashRemoveNode(it);try{Ie.node_ops.rename(it,Oe,T)}catch(wt){throw wt}finally{Q.hashAddNode(it)}try{Q.trackingDelegate.onMovePath&&Q.trackingDelegate.onMovePath(f,E)}catch(wt){x("FS.trackingDelegate['onMovePath']('"+f+"', '"+E+"') threw an exception: "+wt.message)}}},rmdir:function(f){var E=Q.lookupPath(f,{parent:!0}),w=E.node,k=yt.basename(f),L=Q.lookupNode(w,k),T=Q.mayDelete(w,k,!0);if(T)throw new Q.ErrnoError(T);if(!w.node_ops.rmdir)throw new Q.ErrnoError(63);if(Q.isMountpoint(L))throw new Q.ErrnoError(10);try{Q.trackingDelegate.willDeletePath&&Q.trackingDelegate.willDeletePath(f)}catch(ee){x("FS.trackingDelegate['willDeletePath']('"+f+"') threw an exception: "+ee.message)}w.node_ops.rmdir(w,k),Q.destroyNode(L);try{Q.trackingDelegate.onDeletePath&&Q.trackingDelegate.onDeletePath(f)}catch(ee){x("FS.trackingDelegate['onDeletePath']('"+f+"') threw an exception: "+ee.message)}},readdir:function(f){var E=Q.lookupPath(f,{follow:!0}),w=E.node;if(!w.node_ops.readdir)throw new Q.ErrnoError(54);return w.node_ops.readdir(w)},unlink:function(f){var E=Q.lookupPath(f,{parent:!0}),w=E.node,k=yt.basename(f),L=Q.lookupNode(w,k),T=Q.mayDelete(w,k,!1);if(T)throw new Q.ErrnoError(T);if(!w.node_ops.unlink)throw new Q.ErrnoError(63);if(Q.isMountpoint(L))throw new Q.ErrnoError(10);try{Q.trackingDelegate.willDeletePath&&Q.trackingDelegate.willDeletePath(f)}catch(ee){x("FS.trackingDelegate['willDeletePath']('"+f+"') threw an exception: "+ee.message)}w.node_ops.unlink(w,k),Q.destroyNode(L);try{Q.trackingDelegate.onDeletePath&&Q.trackingDelegate.onDeletePath(f)}catch(ee){x("FS.trackingDelegate['onDeletePath']('"+f+"') threw an exception: "+ee.message)}},readlink:function(f){var E=Q.lookupPath(f),w=E.node;if(!w)throw new Q.ErrnoError(44);if(!w.node_ops.readlink)throw new Q.ErrnoError(28);return Tn.resolve(Q.getPath(w.parent),w.node_ops.readlink(w))},stat:function(f,E){var w=Q.lookupPath(f,{follow:!E}),k=w.node;if(!k)throw new Q.ErrnoError(44);if(!k.node_ops.getattr)throw new Q.ErrnoError(63);return k.node_ops.getattr(k)},lstat:function(f){return Q.stat(f,!0)},chmod:function(f,E,w){var k;if(typeof f=="string"){var L=Q.lookupPath(f,{follow:!w});k=L.node}else k=f;if(!k.node_ops.setattr)throw new Q.ErrnoError(63);k.node_ops.setattr(k,{mode:E&4095|k.mode&-4096,timestamp:Date.now()})},lchmod:function(f,E){Q.chmod(f,E,!0)},fchmod:function(f,E){var w=Q.getStream(f);if(!w)throw new Q.ErrnoError(8);Q.chmod(w.node,E)},chown:function(f,E,w,k){var L;if(typeof f=="string"){var T=Q.lookupPath(f,{follow:!k});L=T.node}else L=f;if(!L.node_ops.setattr)throw new Q.ErrnoError(63);L.node_ops.setattr(L,{timestamp:Date.now()})},lchown:function(f,E,w){Q.chown(f,E,w,!0)},fchown:function(f,E,w){var k=Q.getStream(f);if(!k)throw new Q.ErrnoError(8);Q.chown(k.node,E,w)},truncate:function(f,E){if(E<0)throw new Q.ErrnoError(28);var w;if(typeof f=="string"){var k=Q.lookupPath(f,{follow:!0});w=k.node}else w=f;if(!w.node_ops.setattr)throw new Q.ErrnoError(63);if(Q.isDir(w.mode))throw new Q.ErrnoError(31);if(!Q.isFile(w.mode))throw new Q.ErrnoError(28);var L=Q.nodePermissions(w,"w");if(L)throw new Q.ErrnoError(L);w.node_ops.setattr(w,{size:E,timestamp:Date.now()})},ftruncate:function(f,E){var w=Q.getStream(f);if(!w)throw new Q.ErrnoError(8);if((w.flags&2097155)===0)throw new Q.ErrnoError(28);Q.truncate(w.node,E)},utime:function(f,E,w){var k=Q.lookupPath(f,{follow:!0}),L=k.node;L.node_ops.setattr(L,{timestamp:Math.max(E,w)})},open:function(f,E,w,k,L){if(f==="")throw new Q.ErrnoError(44);E=typeof E=="string"?Q.modeStringToFlags(E):E,w=typeof w>"u"?438:w,E&64?w=w&4095|32768:w=0;var T;if(typeof f=="object")T=f;else{f=yt.normalize(f);try{var ee=Q.lookupPath(f,{follow:!(E&131072)});T=ee.node}catch{}}var Ie=!1;if(E&64)if(T){if(E&128)throw new Q.ErrnoError(20)}else T=Q.mknod(f,w,0),Ie=!0;if(!T)throw new Q.ErrnoError(44);if(Q.isChrdev(T.mode)&&(E&=-513),E&65536&&!Q.isDir(T.mode))throw new Q.ErrnoError(54);if(!Ie){var Oe=Q.mayOpen(T,E);if(Oe)throw new Q.ErrnoError(Oe)}E&512&&Q.truncate(T,0),E&=-131713;var it=Q.createStream({node:T,path:Q.getPath(T),flags:E,seekable:!0,position:0,stream_ops:T.stream_ops,ungotten:[],error:!1},k,L);it.stream_ops.open&&it.stream_ops.open(it),t.logReadFiles&&!(E&1)&&(Q.readFiles||(Q.readFiles={}),f in Q.readFiles||(Q.readFiles[f]=1,x("FS.trackingDelegate error on read file: "+f)));try{if(Q.trackingDelegate.onOpenFile){var at=0;(E&2097155)!==1&&(at|=Q.tracking.openFlags.READ),(E&2097155)!==0&&(at|=Q.tracking.openFlags.WRITE),Q.trackingDelegate.onOpenFile(f,at)}}catch(Ue){x("FS.trackingDelegate['onOpenFile']('"+f+"', flags) threw an exception: "+Ue.message)}return it},close:function(f){if(Q.isClosed(f))throw new Q.ErrnoError(8);f.getdents&&(f.getdents=null);try{f.stream_ops.close&&f.stream_ops.close(f)}catch(E){throw E}finally{Q.closeStream(f.fd)}f.fd=null},isClosed:function(f){return f.fd===null},llseek:function(f,E,w){if(Q.isClosed(f))throw new Q.ErrnoError(8);if(!f.seekable||!f.stream_ops.llseek)throw new Q.ErrnoError(70);if(w!=0&&w!=1&&w!=2)throw new Q.ErrnoError(28);return f.position=f.stream_ops.llseek(f,E,w),f.ungotten=[],f.position},read:function(f,E,w,k,L){if(k<0||L<0)throw new Q.ErrnoError(28);if(Q.isClosed(f))throw new Q.ErrnoError(8);if((f.flags&2097155)===1)throw new Q.ErrnoError(8);if(Q.isDir(f.node.mode))throw new Q.ErrnoError(31);if(!f.stream_ops.read)throw new Q.ErrnoError(28);var T=typeof L<"u";if(!T)L=f.position;else if(!f.seekable)throw new Q.ErrnoError(70);var ee=f.stream_ops.read(f,E,w,k,L);return T||(f.position+=ee),ee},write:function(f,E,w,k,L,T){if(k<0||L<0)throw new Q.ErrnoError(28);if(Q.isClosed(f))throw new Q.ErrnoError(8);if((f.flags&2097155)===0)throw new Q.ErrnoError(8);if(Q.isDir(f.node.mode))throw new Q.ErrnoError(31);if(!f.stream_ops.write)throw new Q.ErrnoError(28);f.seekable&&f.flags&1024&&Q.llseek(f,0,2);var ee=typeof L<"u";if(!ee)L=f.position;else if(!f.seekable)throw new Q.ErrnoError(70);var Ie=f.stream_ops.write(f,E,w,k,L,T);ee||(f.position+=Ie);try{f.path&&Q.trackingDelegate.onWriteToFile&&Q.trackingDelegate.onWriteToFile(f.path)}catch(Oe){x("FS.trackingDelegate['onWriteToFile']('"+f.path+"') threw an exception: "+Oe.message)}return Ie},allocate:function(f,E,w){if(Q.isClosed(f))throw new Q.ErrnoError(8);if(E<0||w<=0)throw new Q.ErrnoError(28);if((f.flags&2097155)===0)throw new Q.ErrnoError(8);if(!Q.isFile(f.node.mode)&&!Q.isDir(f.node.mode))throw new Q.ErrnoError(43);if(!f.stream_ops.allocate)throw new Q.ErrnoError(138);f.stream_ops.allocate(f,E,w)},mmap:function(f,E,w,k,L,T){if((L&2)!==0&&(T&2)===0&&(f.flags&2097155)!==2)throw new Q.ErrnoError(2);if((f.flags&2097155)===1)throw new Q.ErrnoError(2);if(!f.stream_ops.mmap)throw new Q.ErrnoError(43);return f.stream_ops.mmap(f,E,w,k,L,T)},msync:function(f,E,w,k,L){return!f||!f.stream_ops.msync?0:f.stream_ops.msync(f,E,w,k,L)},munmap:function(f){return 0},ioctl:function(f,E,w){if(!f.stream_ops.ioctl)throw new Q.ErrnoError(59);return f.stream_ops.ioctl(f,E,w)},readFile:function(f,E){if(E=E||{},E.flags=E.flags||0,E.encoding=E.encoding||"binary",E.encoding!=="utf8"&&E.encoding!=="binary")throw new Error('Invalid encoding type "'+E.encoding+'"');var w,k=Q.open(f,E.flags),L=Q.stat(f),T=L.size,ee=new Uint8Array(T);return Q.read(k,ee,0,T,0),E.encoding==="utf8"?w=xe(ee,0):E.encoding==="binary"&&(w=ee),Q.close(k),w},writeFile:function(f,E,w){w=w||{},w.flags=w.flags||577;var k=Q.open(f,w.flags,w.mode);if(typeof E=="string"){var L=new Uint8Array(Ae(E)+1),T=Re(E,L,0,L.length);Q.write(k,L,0,T,void 0,w.canOwn)}else if(ArrayBuffer.isView(E))Q.write(k,E,0,E.byteLength,void 0,w.canOwn);else throw new Error("Unsupported data type");Q.close(k)},cwd:function(){return Q.currentPath},chdir:function(f){var E=Q.lookupPath(f,{follow:!0});if(E.node===null)throw new Q.ErrnoError(44);if(!Q.isDir(E.node.mode))throw new Q.ErrnoError(54);var w=Q.nodePermissions(E.node,"x");if(w)throw new Q.ErrnoError(w);Q.currentPath=E.path},createDefaultDirectories:function(){Q.mkdir("/tmp"),Q.mkdir("/home"),Q.mkdir("/home/web_user")},createDefaultDevices:function(){Q.mkdir("/dev"),Q.registerDevice(Q.makedev(1,3),{read:function(){return 0},write:function(E,w,k,L,T){return L}}),Q.mkdev("/dev/null",Q.makedev(1,3)),ns.register(Q.makedev(5,0),ns.default_tty_ops),ns.register(Q.makedev(6,0),ns.default_tty1_ops),Q.mkdev("/dev/tty",Q.makedev(5,0)),Q.mkdev("/dev/tty1",Q.makedev(6,0));var f=Tl();Q.createDevice("/dev","random",f),Q.createDevice("/dev","urandom",f),Q.mkdir("/dev/shm"),Q.mkdir("/dev/shm/tmp")},createSpecialDirectories:function(){Q.mkdir("/proc");var f=Q.mkdir("/proc/self");Q.mkdir("/proc/self/fd"),Q.mount({mount:function(){var E=Q.createNode(f,"fd",16895,73);return E.node_ops={lookup:function(w,k){var L=+k,T=Q.getStream(L);if(!T)throw new Q.ErrnoError(8);var ee={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:function(){return T.path}}};return ee.parent=ee,ee}},E}},{},"/proc/self/fd")},createStandardStreams:function(){t.stdin?Q.createDevice("/dev","stdin",t.stdin):Q.symlink("/dev/tty","/dev/stdin"),t.stdout?Q.createDevice("/dev","stdout",null,t.stdout):Q.symlink("/dev/tty","/dev/stdout"),t.stderr?Q.createDevice("/dev","stderr",null,t.stderr):Q.symlink("/dev/tty1","/dev/stderr");var f=Q.open("/dev/stdin",0),E=Q.open("/dev/stdout",1),w=Q.open("/dev/stderr",1)},ensureErrnoError:function(){Q.ErrnoError||(Q.ErrnoError=function(E,w){this.node=w,this.setErrno=function(k){this.errno=k},this.setErrno(E),this.message="FS error"},Q.ErrnoError.prototype=new Error,Q.ErrnoError.prototype.constructor=Q.ErrnoError,[44].forEach(function(f){Q.genericErrors[f]=new Q.ErrnoError(f),Q.genericErrors[f].stack="<generic error, no stack>"}))},staticInit:function(){Q.ensureErrnoError(),Q.nameTable=new Array(4096),Q.mount(ut,{},"/"),Q.createDefaultDirectories(),Q.createDefaultDevices(),Q.createSpecialDirectories(),Q.filesystems={MEMFS:ut,NODEFS:At}},init:function(f,E,w){Q.init.initialized=!0,Q.ensureErrnoError(),t.stdin=f||t.stdin,t.stdout=E||t.stdout,t.stderr=w||t.stderr,Q.createStandardStreams()},quit:function(){Q.init.initialized=!1;var f=t._fflush;f&&f(0);for(var E=0;E<Q.streams.length;E++){var w=Q.streams[E];!w||Q.close(w)}},getMode:function(f,E){var w=0;return f&&(w|=365),E&&(w|=146),w},findObject:function(f,E){var w=Q.analyzePath(f,E);return w.exists?w.object:null},analyzePath:function(f,E){try{var w=Q.lookupPath(f,{follow:!E});f=w.path}catch{}var k={isRoot:!1,exists:!1,error:0,name:null,path:null,object:null,parentExists:!1,parentPath:null,parentObject:null};try{var w=Q.lookupPath(f,{parent:!0});k.parentExists=!0,k.parentPath=w.path,k.parentObject=w.node,k.name=yt.basename(f),w=Q.lookupPath(f,{follow:!E}),k.exists=!0,k.path=w.path,k.object=w.node,k.name=w.node.name,k.isRoot=w.path==="/"}catch(L){k.error=L.errno}return k},createPath:function(f,E,w,k){f=typeof f=="string"?f:Q.getPath(f);for(var L=E.split("/").reverse();L.length;){var T=L.pop();if(!!T){var ee=yt.join2(f,T);try{Q.mkdir(ee)}catch{}f=ee}}return ee},createFile:function(f,E,w,k,L){var T=yt.join2(typeof f=="string"?f:Q.getPath(f),E),ee=Q.getMode(k,L);return Q.create(T,ee)},createDataFile:function(f,E,w,k,L,T){var ee=E?yt.join2(typeof f=="string"?f:Q.getPath(f),E):f,Ie=Q.getMode(k,L),Oe=Q.create(ee,Ie);if(w){if(typeof w=="string"){for(var it=new Array(w.length),at=0,Ue=w.length;at<Ue;++at)it[at]=w.charCodeAt(at);w=it}Q.chmod(Oe,Ie|146);var Ve=Q.open(Oe,577);Q.write(Ve,w,0,w.length,0,T),Q.close(Ve),Q.chmod(Oe,Ie)}return Oe},createDevice:function(f,E,w,k){var L=yt.join2(typeof f=="string"?f:Q.getPath(f),E),T=Q.getMode(!!w,!!k);Q.createDevice.major||(Q.createDevice.major=64);var ee=Q.makedev(Q.createDevice.major++,0);return Q.registerDevice(ee,{open:function(Ie){Ie.seekable=!1},close:function(Ie){k&&k.buffer&&k.buffer.length&&k(10)},read:function(Ie,Oe,it,at,Ue){for(var Ve=0,nt=0;nt<at;nt++){var wt;try{wt=w()}catch{throw new Q.ErrnoError(29)}if(wt===void 0&&Ve===0)throw new Q.ErrnoError(6);if(wt==null)break;Ve++,Oe[it+nt]=wt}return Ve&&(Ie.node.timestamp=Date.now()),Ve},write:function(Ie,Oe,it,at,Ue){for(var Ve=0;Ve<at;Ve++)try{k(Oe[it+Ve])}catch{throw new Q.ErrnoError(29)}return at&&(Ie.node.timestamp=Date.now()),Ve}}),Q.mkdev(L,T,ee)},forceLoadFile:function(f){if(f.isDevice||f.isFolder||f.link||f.contents)return!0;if(typeof XMLHttpRequest<"u")throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");if(d)try{f.contents=wA(d(f.url),!0),f.usedBytes=f.contents.length}catch{throw new Q.ErrnoError(29)}else throw new Error("Cannot load without read() or XMLHttpRequest.")},createLazyFile:function(f,E,w,k,L){function T(){this.lengthKnown=!1,this.chunks=[]}if(T.prototype.get=function(Ve){if(!(Ve>this.length-1||Ve<0)){var nt=Ve%this.chunkSize,wt=Ve/this.chunkSize|0;return this.getter(wt)[nt]}},T.prototype.setDataGetter=function(Ve){this.getter=Ve},T.prototype.cacheLength=function(){var Ve=new XMLHttpRequest;if(Ve.open("HEAD",w,!1),Ve.send(null),!(Ve.status>=200&&Ve.status<300||Ve.status===304))throw new Error("Couldn't load "+w+". Status: "+Ve.status);var nt=Number(Ve.getResponseHeader("Content-length")),wt,Ii=(wt=Ve.getResponseHeader("Accept-Ranges"))&&wt==="bytes",cn=(wt=Ve.getResponseHeader("Content-Encoding"))&&wt==="gzip",ii=1024*1024;Ii||(ii=nt);var Be=function(On,Ia){if(On>Ia)throw new Error("invalid range ("+On+", "+Ia+") or no bytes requested!");if(Ia>nt-1)throw new Error("only "+nt+" bytes available! programmer error!");var Sr=new XMLHttpRequest;if(Sr.open("GET",w,!1),nt!==ii&&Sr.setRequestHeader("Range","bytes="+On+"-"+Ia),typeof Uint8Array<"u"&&(Sr.responseType="arraybuffer"),Sr.overrideMimeType&&Sr.overrideMimeType("text/plain; charset=x-user-defined"),Sr.send(null),!(Sr.status>=200&&Sr.status<300||Sr.status===304))throw new Error("Couldn't load "+w+". Status: "+Sr.status);return Sr.response!==void 0?new Uint8Array(Sr.response||[]):wA(Sr.responseText||"",!0)},yi=this;yi.setDataGetter(function(On){var Ia=On*ii,Sr=(On+1)*ii-1;if(Sr=Math.min(Sr,nt-1),typeof yi.chunks[On]>"u"&&(yi.chunks[On]=Be(Ia,Sr)),typeof yi.chunks[On]>"u")throw new Error("doXHR failed!");return yi.chunks[On]}),(cn||!nt)&&(ii=nt=1,nt=this.getter(0).length,ii=nt,S("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=nt,this._chunkSize=ii,this.lengthKnown=!0},typeof XMLHttpRequest<"u"){if(!u)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var ee=new T;Object.defineProperties(ee,{length:{get:function(){return this.lengthKnown||this.cacheLength(),this._length}},chunkSize:{get:function(){return this.lengthKnown||this.cacheLength(),this._chunkSize}}});var Ie={isDevice:!1,contents:ee}}else var Ie={isDevice:!1,url:w};var Oe=Q.createFile(f,E,Ie,k,L);Ie.contents?Oe.contents=Ie.contents:Ie.url&&(Oe.contents=null,Oe.url=Ie.url),Object.defineProperties(Oe,{usedBytes:{get:function(){return this.contents.length}}});var it={},at=Object.keys(Oe.stream_ops);return at.forEach(function(Ue){var Ve=Oe.stream_ops[Ue];it[Ue]=function(){return Q.forceLoadFile(Oe),Ve.apply(null,arguments)}}),it.read=function(Ve,nt,wt,Ii,cn){Q.forceLoadFile(Oe);var ii=Ve.node.contents;if(cn>=ii.length)return 0;var Be=Math.min(ii.length-cn,Ii);if(ii.slice)for(var yi=0;yi<Be;yi++)nt[wt+yi]=ii[cn+yi];else for(var yi=0;yi<Be;yi++)nt[wt+yi]=ii.get(cn+yi);return Be},Oe.stream_ops=it,Oe},createPreloadedFile:function(f,E,w,k,L,T,ee,Ie,Oe,it){Browser.init();var at=E?Tn.resolve(yt.join2(f,E)):f,Ue="cp "+at;function Ve(nt){function wt(cn){it&&it(),Ie||Q.createDataFile(f,E,cn,k,L,Oe),T&&T(),IA(Ue)}var Ii=!1;t.preloadPlugins.forEach(function(cn){Ii||cn.canHandle(at)&&(cn.handle(nt,at,wt,function(){ee&&ee(),IA(Ue)}),Ii=!0)}),Ii||wt(nt)}EA(Ue),typeof w=="string"?Browser.asyncLoad(w,function(nt){Ve(nt)},ee):Ve(w)},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:function(){return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(f,E,w){E=E||function(){},w=w||function(){};var k=Q.indexedDB();try{var L=k.open(Q.DB_NAME(),Q.DB_VERSION)}catch(T){return w(T)}L.onupgradeneeded=function(){S("creating db");var ee=L.result;ee.createObjectStore(Q.DB_STORE_NAME)},L.onsuccess=function(){var ee=L.result,Ie=ee.transaction([Q.DB_STORE_NAME],"readwrite"),Oe=Ie.objectStore(Q.DB_STORE_NAME),it=0,at=0,Ue=f.length;function Ve(){at==0?E():w()}f.forEach(function(nt){var wt=Oe.put(Q.analyzePath(nt).object.contents,nt);wt.onsuccess=function(){it++,it+at==Ue&&Ve()},wt.onerror=function(){at++,it+at==Ue&&Ve()}}),Ie.onerror=w},L.onerror=w},loadFilesFromDB:function(f,E,w){E=E||function(){},w=w||function(){};var k=Q.indexedDB();try{var L=k.open(Q.DB_NAME(),Q.DB_VERSION)}catch(T){return w(T)}L.onupgradeneeded=w,L.onsuccess=function(){var ee=L.result;try{var Ie=ee.transaction([Q.DB_STORE_NAME],"readonly")}catch(nt){w(nt);return}var Oe=Ie.objectStore(Q.DB_STORE_NAME),it=0,at=0,Ue=f.length;function Ve(){at==0?E():w()}f.forEach(function(nt){var wt=Oe.get(nt);wt.onsuccess=function(){Q.analyzePath(nt).exists&&Q.unlink(nt),Q.createDataFile(yt.dirname(nt),yt.basename(nt),wt.result,!0,!0,!0),it++,it+at==Ue&&Ve()},wt.onerror=function(){at++,it+at==Ue&&Ve()}}),Ie.onerror=w},L.onerror=w}},Nt={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(f,E,w){if(E[0]==="/")return E;var k;if(f===-100)k=Q.cwd();else{var L=Q.getStream(f);if(!L)throw new Q.ErrnoError(8);k=L.path}if(E.length==0){if(!w)throw new Q.ErrnoError(44);return k}return yt.join2(k,E)},doStat:function(f,E,w){try{var k=f(E)}catch(L){if(L&&L.node&&yt.normalize(E)!==yt.normalize(Q.getPath(L.node)))return-54;throw L}return de[w>>2]=k.dev,de[w+4>>2]=0,de[w+8>>2]=k.ino,de[w+12>>2]=k.mode,de[w+16>>2]=k.nlink,de[w+20>>2]=k.uid,de[w+24>>2]=k.gid,de[w+28>>2]=k.rdev,de[w+32>>2]=0,Ri=[k.size>>>0,(Qr=k.size,+Math.abs(Qr)>=1?Qr>0?(Math.min(+Math.floor(Qr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Qr-+(~~Qr>>>0))/4294967296)>>>0:0)],de[w+40>>2]=Ri[0],de[w+44>>2]=Ri[1],de[w+48>>2]=4096,de[w+52>>2]=k.blocks,de[w+56>>2]=k.atime.getTime()/1e3|0,de[w+60>>2]=0,de[w+64>>2]=k.mtime.getTime()/1e3|0,de[w+68>>2]=0,de[w+72>>2]=k.ctime.getTime()/1e3|0,de[w+76>>2]=0,Ri=[k.ino>>>0,(Qr=k.ino,+Math.abs(Qr)>=1?Qr>0?(Math.min(+Math.floor(Qr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Qr-+(~~Qr>>>0))/4294967296)>>>0:0)],de[w+80>>2]=Ri[0],de[w+84>>2]=Ri[1],0},doMsync:function(f,E,w,k,L){var T=G.slice(f,f+w);Q.msync(E,T,L,w,k)},doMkdir:function(f,E){return f=yt.normalize(f),f[f.length-1]==="/"&&(f=f.substr(0,f.length-1)),Q.mkdir(f,E,0),0},doMknod:function(f,E,w){switch(E&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return Q.mknod(f,E,w),0},doReadlink:function(f,E,w){if(w<=0)return-28;var k=Q.readlink(f),L=Math.min(w,Ae(k)),T=ie[E+L];return se(k,E,w+1),ie[E+L]=T,L},doAccess:function(f,E){if(E&-8)return-28;var w,k=Q.lookupPath(f,{follow:!0});if(w=k.node,!w)return-44;var L="";return E&4&&(L+="r"),E&2&&(L+="w"),E&1&&(L+="x"),L&&Q.nodePermissions(w,L)?-2:0},doDup:function(f,E,w){var k=Q.getStream(w);return k&&Q.close(k),Q.open(f,E,0,w,w).fd},doReadv:function(f,E,w,k){for(var L=0,T=0;T<w;T++){var ee=de[E+T*8>>2],Ie=de[E+(T*8+4)>>2],Oe=Q.read(f,ie,ee,Ie,k);if(Oe<0)return-1;if(L+=Oe,Oe<Ie)break}return L},doWritev:function(f,E,w,k){for(var L=0,T=0;T<w;T++){var ee=de[E+T*8>>2],Ie=de[E+(T*8+4)>>2],Oe=Q.write(f,ie,ee,Ie,k);if(Oe<0)return-1;L+=Oe}return L},varargs:void 0,get:function(){Nt.varargs+=4;var f=de[Nt.varargs-4>>2];return f},getStr:function(f){var E=De(f);return E},getStreamFromFD:function(f){var E=Q.getStream(f);if(!E)throw new Q.ErrnoError(8);return E},get64:function(f,E){return f}};function pg(f,E){try{return f=Nt.getStr(f),Q.chmod(f,E),0}catch(w){return(typeof Q>"u"||!(w instanceof Q.ErrnoError))&&Ir(w),-w.errno}}function Ll(f){return de[Xt()>>2]=f,f}function Qp(f,E,w){Nt.varargs=w;try{var k=Nt.getStreamFromFD(f);switch(E){case 0:{var L=Nt.get();if(L<0)return-28;var T;return T=Q.open(k.path,k.flags,0,L),T.fd}case 1:case 2:return 0;case 3:return k.flags;case 4:{var L=Nt.get();return k.flags|=L,0}case 12:{var L=Nt.get(),ee=0;return fe[L+ee>>1]=2,0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:return Ll(28),-1;default:return-28}}catch(Ie){return(typeof Q>"u"||!(Ie instanceof Q.ErrnoError))&&Ir(Ie),-Ie.errno}}function Sp(f,E){try{var w=Nt.getStreamFromFD(f);return Nt.doStat(Q.stat,w.path,E)}catch(k){return(typeof Q>"u"||!(k instanceof Q.ErrnoError))&&Ir(k),-k.errno}}function vp(f,E,w){Nt.varargs=w;try{var k=Nt.getStreamFromFD(f);switch(E){case 21509:case 21505:return k.tty?0:-59;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return k.tty?0:-59;case 21519:{if(!k.tty)return-59;var L=Nt.get();return de[L>>2]=0,0}case 21520:return k.tty?-28:-59;case 21531:{var L=Nt.get();return Q.ioctl(k,E,L)}case 21523:return k.tty?0:-59;case 21524:return k.tty?0:-59;default:Ir("bad ioctl syscall "+E)}}catch(T){return(typeof Q>"u"||!(T instanceof Q.ErrnoError))&&Ir(T),-T.errno}}function Pp(f,E,w){Nt.varargs=w;try{var k=Nt.getStr(f),L=w?Nt.get():0,T=Q.open(k,E,L);return T.fd}catch(ee){return(typeof Q>"u"||!(ee instanceof Q.ErrnoError))&&Ir(ee),-ee.errno}}function xp(f,E){try{return f=Nt.getStr(f),E=Nt.getStr(E),Q.rename(f,E),0}catch(w){return(typeof Q>"u"||!(w instanceof Q.ErrnoError))&&Ir(w),-w.errno}}function j(f){try{return f=Nt.getStr(f),Q.rmdir(f),0}catch(E){return(typeof Q>"u"||!(E instanceof Q.ErrnoError))&&Ir(E),-E.errno}}function Et(f,E){try{return f=Nt.getStr(f),Nt.doStat(Q.stat,f,E)}catch(w){return(typeof Q>"u"||!(w instanceof Q.ErrnoError))&&Ir(w),-w.errno}}function yA(f){try{return f=Nt.getStr(f),Q.unlink(f),0}catch(E){return(typeof Q>"u"||!(E instanceof Q.ErrnoError))&&Ir(E),-E.errno}}function Wi(f,E,w){G.copyWithin(f,E,E+w)}function Ol(f){try{return A.grow(f-Ye.byteLength+65535>>>16),Tr(A.buffer),1}catch{}}function ze(f){var E=G.length;f=f>>>0;var w=2147483648;if(f>w)return!1;for(var k=1;k<=4;k*=2){var L=E*(1+.2/k);L=Math.min(L,f+100663296);var T=Math.min(w,oe(Math.max(f,L),65536)),ee=Ol(T);if(ee)return!0}return!1}function fa(f){try{var E=Nt.getStreamFromFD(f);return Q.close(E),0}catch(w){return(typeof Q>"u"||!(w instanceof Q.ErrnoError))&&Ir(w),w.errno}}function dg(f,E){try{var w=Nt.getStreamFromFD(f),k=w.tty?2:Q.isDir(w.mode)?3:Q.isLink(w.mode)?7:4;return ie[E>>0]=k,0}catch(L){return(typeof Q>"u"||!(L instanceof Q.ErrnoError))&&Ir(L),L.errno}}function OE(f,E,w,k){try{var L=Nt.getStreamFromFD(f),T=Nt.doReadv(L,E,w);return de[k>>2]=T,0}catch(ee){return(typeof Q>"u"||!(ee instanceof Q.ErrnoError))&&Ir(ee),ee.errno}}function kp(f,E,w,k,L){try{var T=Nt.getStreamFromFD(f),ee=4294967296,Ie=w*ee+(E>>>0),Oe=9007199254740992;return Ie<=-Oe||Ie>=Oe?-61:(Q.llseek(T,Ie,k),Ri=[T.position>>>0,(Qr=T.position,+Math.abs(Qr)>=1?Qr>0?(Math.min(+Math.floor(Qr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Qr-+(~~Qr>>>0))/4294967296)>>>0:0)],de[L>>2]=Ri[0],de[L+4>>2]=Ri[1],T.getdents&&Ie===0&&k===0&&(T.getdents=null),0)}catch(it){return(typeof Q>"u"||!(it instanceof Q.ErrnoError))&&Ir(it),it.errno}}function ME(f,E,w,k){try{var L=Nt.getStreamFromFD(f),T=Nt.doWritev(L,E,w);return de[k>>2]=T,0}catch(ee){return(typeof Q>"u"||!(ee instanceof Q.ErrnoError))&&Ir(ee),ee.errno}}function sr(f){_(f)}function Ln(f){var E=Date.now()/1e3|0;return f&&(de[f>>2]=E),E}function Ml(){if(Ml.called)return;Ml.called=!0;var f=new Date().getFullYear(),E=new Date(f,0,1),w=new Date(f,6,1),k=E.getTimezoneOffset(),L=w.getTimezoneOffset(),T=Math.max(k,L);de[eS()>>2]=T*60,de[jE()>>2]=Number(k!=L);function ee(Ue){var Ve=Ue.toTimeString().match(/\(([A-Za-z ]+)\)$/);return Ve?Ve[1]:"GMT"}var Ie=ee(E),Oe=ee(w),it=ye(Ie),at=ye(Oe);L<k?(de[ql()>>2]=it,de[ql()+4>>2]=at):(de[ql()>>2]=at,de[ql()+4>>2]=it)}function Dp(f){Ml();var E=Date.UTC(de[f+20>>2]+1900,de[f+16>>2],de[f+12>>2],de[f+8>>2],de[f+4>>2],de[f>>2],0),w=new Date(E);de[f+24>>2]=w.getUTCDay();var k=Date.UTC(w.getUTCFullYear(),0,1,0,0,0,0),L=(w.getTime()-k)/(1e3*60*60*24)|0;return de[f+28>>2]=L,w.getTime()/1e3|0}var Ks=function(f,E,w,k){f||(f=this),this.parent=f,this.mount=f.mount,this.mounted=null,this.id=Q.nextInode++,this.name=E,this.mode=w,this.node_ops={},this.stream_ops={},this.rdev=k},ha=365,ln=146;if(Object.defineProperties(Ks.prototype,{read:{get:function(){return(this.mode&ha)===ha},set:function(f){f?this.mode|=ha:this.mode&=~ha}},write:{get:function(){return(this.mode&ln)===ln},set:function(f){f?this.mode|=ln:this.mode&=~ln}},isFolder:{get:function(){return Q.isDir(this.mode)}},isDevice:{get:function(){return Q.isChrdev(this.mode)}}}),Q.FSNode=Ks,Q.staticInit(),g){var Ne=o9,Cg=J("path");At.staticInit()}if(g){var Kl=function(f){return function(){try{return f.apply(this,arguments)}catch(E){throw E.code?new Q.ErrnoError(wo[E.code]):E}}},Us=Object.assign({},Q);for(var Ul in An)Q[Ul]=Kl(An[Ul])}else throw new Error("NODERAWFS is currently only supported on Node.js environment.");function wA(f,E,w){var k=w>0?w:Ae(f)+1,L=new Array(k),T=Re(f,L,0,L.length);return E&&(L.length=T),L}var mg=typeof atob=="function"?atob:function(f){var E="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",w="",k,L,T,ee,Ie,Oe,it,at=0;f=f.replace(/[^A-Za-z0-9\+\/\=]/g,"");do ee=E.indexOf(f.charAt(at++)),Ie=E.indexOf(f.charAt(at++)),Oe=E.indexOf(f.charAt(at++)),it=E.indexOf(f.charAt(at++)),k=ee<<2|Ie>>4,L=(Ie&15)<<4|Oe>>2,T=(Oe&3)<<6|it,w=w+String.fromCharCode(k),Oe!==64&&(w=w+String.fromCharCode(L)),it!==64&&(w=w+String.fromCharCode(T));while(at<f.length);return w};function Eg(f){if(typeof g=="boolean"&&g){var E;try{E=Buffer.from(f,"base64")}catch{E=new Buffer(f,"base64")}return new Uint8Array(E.buffer,E.byteOffset,E.byteLength)}try{for(var w=mg(f),k=new Uint8Array(w.length),L=0;L<w.length;++L)k[L]=w.charCodeAt(L);return k}catch{throw new Error("Converting base64 string to bytes failed.")}}function pa(f){if(!!fg(f))return Eg(f.slice(Nl.length))}var da={s:ae,p:pg,e:Qp,k:Sp,o:vp,q:Pp,i:xp,r:j,c:Et,h:yA,l:Wi,m:ze,f:fa,j:dg,g:OE,n:kp,d:ME,a:sr,b:Ln,t:Dp},tt=bp(),Bo=t.___wasm_call_ctors=tt.v,BA=t._zip_ext_count_symlinks=tt.w,Rp=t._zip_file_get_external_attributes=tt.x,Ca=t._zipstruct_stat=tt.y,Hl=t._zipstruct_statS=tt.z,jl=t._zipstruct_stat_name=tt.A,bA=t._zipstruct_stat_index=tt.B,ma=t._zipstruct_stat_size=tt.C,Fp=t._zipstruct_stat_mtime=tt.D,KE=t._zipstruct_stat_crc=tt.E,Gl=t._zipstruct_error=tt.F,UE=t._zipstruct_errorS=tt.G,Np=t._zipstruct_error_code_zip=tt.H,Yl=t._zipstruct_stat_comp_size=tt.I,Lr=t._zipstruct_stat_comp_method=tt.J,HE=t._zip_close=tt.K,Hs=t._zip_delete=tt.L,js=t._zip_dir_add=tt.M,Ig=t._zip_discard=tt.N,QA=t._zip_error_init_with_code=tt.O,D=t._zip_get_error=tt.P,Y=t._zip_file_get_error=tt.Q,pe=t._zip_error_strerror=tt.R,Le=t._zip_fclose=tt.S,ke=t._zip_file_add=tt.T,Je=t._free=tt.U,pt=t._malloc=tt.V,Xt=t.___errno_location=tt.W,Ea=t._zip_source_error=tt.X,D1=t._zip_source_seek=tt.Y,Gs=t._zip_file_set_external_attributes=tt.Z,yg=t._zip_file_set_mtime=tt._,JQ=t._zip_fopen=tt.$,R1=t._zip_fopen_index=tt.aa,F1=t._zip_fread=tt.ba,WQ=t._zip_get_name=tt.ca,N1=t._zip_get_num_entries=tt.da,T1=t._zip_source_read=tt.ea,zQ=t._zip_name_locate=tt.fa,L1=t._zip_open=tt.ga,O1=t._zip_open_from_source=tt.ha,VQ=t._zip_set_file_compression=tt.ia,M1=t._zip_source_buffer=tt.ja,K1=t._zip_source_buffer_create=tt.ka,XQ=t._zip_source_close=tt.la,U1=t._zip_source_free=tt.ma,H1=t._zip_source_keep=tt.na,j1=t._zip_source_open=tt.oa,G1=t._zip_source_set_mtime=tt.qa,ZQ=t._zip_source_tell=tt.ra,_Q=t._zip_stat=tt.sa,$Q=t._zip_stat_index=tt.ta,ql=t.__get_tzname=tt.ua,jE=t.__get_daylight=tt.va,eS=t.__get_timezone=tt.wa,tS=t.stackSave=tt.xa,rS=t.stackRestore=tt.ya,GE=t.stackAlloc=tt.za;t.cwrap=ce,t.getValue=Z;var Jl;ga=function f(){Jl||wg(),Jl||(ga=f)};function wg(f){if(f=f||a,is>0||(fr(),is>0))return;function E(){Jl||(Jl=!0,t.calledRun=!0,!ne&&(Ei(),i(t),t.onRuntimeInitialized&&t.onRuntimeInitialized(),rs()))}t.setStatus?(t.setStatus("Running..."),setTimeout(function(){setTimeout(function(){t.setStatus("")},1),E()},1)):E()}if(t.run=wg,t.preInit)for(typeof t.preInit=="function"&&(t.preInit=[t.preInit]);t.preInit.length>0;)t.preInit.pop()();return wg(),e}}();typeof EB=="object"&&typeof FR=="object"?FR.exports=RR:typeof define=="function"&&define.amd?define([],function(){return RR}):typeof EB=="object"&&(EB.createModule=RR)});var D9=I((rot,k9)=>{function QDe(r,e){for(var t=-1,i=r==null?0:r.length,n=Array(i);++t<i;)n[t]=e(r[t],t,r);return n}k9.exports=QDe});var Ss=I((iot,R9)=>{var SDe=Array.isArray;R9.exports=SDe});var M9=I((not,O9)=>{var F9=Nc(),vDe=D9(),PDe=Ss(),xDe=fC(),kDe=1/0,N9=F9?F9.prototype:void 0,T9=N9?N9.toString:void 0;function L9(r){if(typeof r=="string")return r;if(PDe(r))return vDe(r,L9)+"";if(xDe(r))return T9?T9.call(r):"";var e=r+"";return e=="0"&&1/r==-kDe?"-0":e}O9.exports=L9});var Vf=I((sot,K9)=>{var DDe=M9();function RDe(r){return r==null?"":DDe(r)}K9.exports=RDe});var HR=I((oot,U9)=>{function FDe(r,e,t){var i=-1,n=r.length;e<0&&(e=-e>n?0:n+e),t=t>n?n:t,t<0&&(t+=n),n=e>t?0:t-e>>>0,e>>>=0;for(var s=Array(n);++i<n;)s[i]=r[i+e];return s}U9.exports=FDe});var j9=I((aot,H9)=>{var NDe=HR();function TDe(r,e,t){var i=r.length;return t=t===void 0?i:t,!e&&t>=i?r:NDe(r,e,t)}H9.exports=TDe});var jR=I((Aot,G9)=>{var LDe="\\ud800-\\udfff",ODe="\\u0300-\\u036f",MDe="\\ufe20-\\ufe2f",KDe="\\u20d0-\\u20ff",UDe=ODe+MDe+KDe,HDe="\\ufe0e\\ufe0f",jDe="\\u200d",GDe=RegExp("["+jDe+LDe+UDe+HDe+"]");function YDe(r){return GDe.test(r)}G9.exports=YDe});var q9=I((lot,Y9)=>{function qDe(r){return r.split("")}Y9.exports=qDe});var $9=I((cot,_9)=>{var J9="\\ud800-\\udfff",JDe="\\u0300-\\u036f",WDe="\\ufe20-\\ufe2f",zDe="\\u20d0-\\u20ff",VDe=JDe+WDe+zDe,XDe="\\ufe0e\\ufe0f",ZDe="["+J9+"]",GR="["+VDe+"]",YR="\\ud83c[\\udffb-\\udfff]",_De="(?:"+GR+"|"+YR+")",W9="[^"+J9+"]",z9="(?:\\ud83c[\\udde6-\\uddff]){2}",V9="[\\ud800-\\udbff][\\udc00-\\udfff]",$De="\\u200d",X9=_De+"?",Z9="["+XDe+"]?",eRe="(?:"+$De+"(?:"+[W9,z9,V9].join("|")+")"+Z9+X9+")*",tRe=Z9+X9+eRe,rRe="(?:"+[W9+GR+"?",GR,z9,V9,ZDe].join("|")+")",iRe=RegExp(YR+"(?="+YR+")|"+rRe+tRe,"g");function nRe(r){return r.match(iRe)||[]}_9.exports=nRe});var tV=I((uot,eV)=>{var sRe=q9(),oRe=jR(),aRe=$9();function ARe(r){return oRe(r)?aRe(r):sRe(r)}eV.exports=ARe});var iV=I((got,rV)=>{var lRe=j9(),cRe=jR(),uRe=tV(),gRe=Vf();function fRe(r){return function(e){e=gRe(e);var t=cRe(e)?uRe(e):void 0,i=t?t[0]:e.charAt(0),n=t?lRe(t,1).join(""):e.slice(1);return i[r]()+n}}rV.exports=fRe});var sV=I((fot,nV)=>{var hRe=iV(),pRe=hRe("toUpperCase");nV.exports=pRe});var PB=I((hot,oV)=>{var dRe=Vf(),CRe=sV();function mRe(r){return CRe(dRe(r).toLowerCase())}oV.exports=mRe});var aV=I((pot,xB)=>{function ERe(){var r=0,e=1,t=2,i=3,n=4,s=5,o=6,a=7,l=8,c=9,u=10,g=11,h=12,p=13,d=14,m=15,y=16,B=17,S=0,x=1,F=2,H=3,q=4;function _(A,ne){return 55296<=A.charCodeAt(ne)&&A.charCodeAt(ne)<=56319&&56320<=A.charCodeAt(ne+1)&&A.charCodeAt(ne+1)<=57343}function X(A,ne){ne===void 0&&(ne=0);var ue=A.charCodeAt(ne);if(55296<=ue&&ue<=56319&&ne<A.length-1){var te=ue,O=A.charCodeAt(ne+1);return 56320<=O&&O<=57343?(te-55296)*1024+(O-56320)+65536:te}if(56320<=ue&&ue<=57343&&ne>=1){var te=A.charCodeAt(ne-1),O=ue;return 55296<=te&&te<=56319?(te-55296)*1024+(O-56320)+65536:O}return ue}function W(A,ne,ue){var te=[A].concat(ne).concat([ue]),O=te[te.length-2],N=ue,ce=te.lastIndexOf(d);if(ce>1&&te.slice(1,ce).every(function(De){return De==i})&&[i,p,B].indexOf(A)==-1)return F;var he=te.lastIndexOf(n);if(he>0&&te.slice(1,he).every(function(De){return De==n})&&[h,n].indexOf(O)==-1)return te.filter(function(De){return De==n}).length%2==1?H:q;if(O==r&&N==e)return S;if(O==t||O==r||O==e)return N==d&&ne.every(function(De){return De==i})?F:x;if(N==t||N==r||N==e)return x;if(O==o&&(N==o||N==a||N==c||N==u))return S;if((O==c||O==a)&&(N==a||N==l))return S;if((O==u||O==l)&&N==l)return S;if(N==i||N==m)return S;if(N==s)return S;if(O==h)return S;var xe=te.indexOf(i)!=-1?te.lastIndexOf(i)-1:te.length-2;return[p,B].indexOf(te[xe])!=-1&&te.slice(xe+1,-1).every(function(De){return De==i})&&N==d||O==m&&[y,B].indexOf(N)!=-1?S:ne.indexOf(n)!=-1?F:O==n&&N==n?S:x}this.nextBreak=function(A,ne){if(ne===void 0&&(ne=0),ne<0)return 0;if(ne>=A.length-1)return A.length;for(var ue=Z(X(A,ne)),te=[],O=ne+1;O<A.length;O++)if(!_(A,O-1)){var N=Z(X(A,O));if(W(ue,te,N))return O;te.push(N)}return A.length},this.splitGraphemes=function(A){for(var ne=[],ue=0,te;(te=this.nextBreak(A,ue))<A.length;)ne.push(A.slice(ue,te)),ue=te;return ue<A.length&&ne.push(A.slice(ue)),ne},this.iterateGraphemes=function(A){var ne=0,ue={next:function(){var te,O;return(O=this.nextBreak(A,ne))<A.length?(te=A.slice(ne,O),ne=O,{value:te,done:!1}):ne<A.length?(te=A.slice(ne),ne=A.length,{value:te,done:!1}):{value:void 0,done:!0}}.bind(this)};return typeof Symbol<"u"&&Symbol.iterator&&(ue[Symbol.iterator]=function(){return ue}),ue},this.countGraphemes=function(A){for(var ne=0,ue=0,te;(te=this.nextBreak(A,ue))<A.length;)ue=te,ne++;return ue<A.length&&ne++,ne};function Z(A){return 1536<=A&&A<=1541||A==1757||A==1807||A==2274||A==3406||A==69821||70082<=A&&A<=70083||A==72250||72326<=A&&A<=72329||A==73030?h:A==13?r:A==10?e:0<=A&&A<=9||11<=A&&A<=12||14<=A&&A<=31||127<=A&&A<=159||A==173||A==1564||A==6158||A==8203||8206<=A&&A<=8207||A==8232||A==8233||8234<=A&&A<=8238||8288<=A&&A<=8292||A==8293||8294<=A&&A<=8303||55296<=A&&A<=57343||A==65279||65520<=A&&A<=65528||65529<=A&&A<=65531||113824<=A&&A<=113827||119155<=A&&A<=119162||A==917504||A==917505||917506<=A&&A<=917535||917632<=A&&A<=917759||918e3<=A&&A<=921599?t:768<=A&&A<=879||1155<=A&&A<=1159||1160<=A&&A<=1161||1425<=A&&A<=1469||A==1471||1473<=A&&A<=1474||1476<=A&&A<=1477||A==1479||1552<=A&&A<=1562||1611<=A&&A<=1631||A==1648||1750<=A&&A<=1756||1759<=A&&A<=1764||1767<=A&&A<=1768||1770<=A&&A<=1773||A==1809||1840<=A&&A<=1866||1958<=A&&A<=1968||2027<=A&&A<=2035||2070<=A&&A<=2073||2075<=A&&A<=2083||2085<=A&&A<=2087||2089<=A&&A<=2093||2137<=A&&A<=2139||2260<=A&&A<=2273||2275<=A&&A<=2306||A==2362||A==2364||2369<=A&&A<=2376||A==2381||2385<=A&&A<=2391||2402<=A&&A<=2403||A==2433||A==2492||A==2494||2497<=A&&A<=2500||A==2509||A==2519||2530<=A&&A<=2531||2561<=A&&A<=2562||A==2620||2625<=A&&A<=2626||2631<=A&&A<=2632||2635<=A&&A<=2637||A==2641||2672<=A&&A<=2673||A==2677||2689<=A&&A<=2690||A==2748||2753<=A&&A<=2757||2759<=A&&A<=2760||A==2765||2786<=A&&A<=2787||2810<=A&&A<=2815||A==2817||A==2876||A==2878||A==2879||2881<=A&&A<=2884||A==2893||A==2902||A==2903||2914<=A&&A<=2915||A==2946||A==3006||A==3008||A==3021||A==3031||A==3072||3134<=A&&A<=3136||3142<=A&&A<=3144||3146<=A&&A<=3149||3157<=A&&A<=3158||3170<=A&&A<=3171||A==3201||A==3260||A==3263||A==3266||A==3270||3276<=A&&A<=3277||3285<=A&&A<=3286||3298<=A&&A<=3299||3328<=A&&A<=3329||3387<=A&&A<=3388||A==3390||3393<=A&&A<=3396||A==3405||A==3415||3426<=A&&A<=3427||A==3530||A==3535||3538<=A&&A<=3540||A==3542||A==3551||A==3633||3636<=A&&A<=3642||3655<=A&&A<=3662||A==3761||3764<=A&&A<=3769||3771<=A&&A<=3772||3784<=A&&A<=3789||3864<=A&&A<=3865||A==3893||A==3895||A==3897||3953<=A&&A<=3966||3968<=A&&A<=3972||3974<=A&&A<=3975||3981<=A&&A<=3991||3993<=A&&A<=4028||A==4038||4141<=A&&A<=4144||4146<=A&&A<=4151||4153<=A&&A<=4154||4157<=A&&A<=4158||4184<=A&&A<=4185||4190<=A&&A<=4192||4209<=A&&A<=4212||A==4226||4229<=A&&A<=4230||A==4237||A==4253||4957<=A&&A<=4959||5906<=A&&A<=5908||5938<=A&&A<=5940||5970<=A&&A<=5971||6002<=A&&A<=6003||6068<=A&&A<=6069||6071<=A&&A<=6077||A==6086||6089<=A&&A<=6099||A==6109||6155<=A&&A<=6157||6277<=A&&A<=6278||A==6313||6432<=A&&A<=6434||6439<=A&&A<=6440||A==6450||6457<=A&&A<=6459||6679<=A&&A<=6680||A==6683||A==6742||6744<=A&&A<=6750||A==6752||A==6754||6757<=A&&A<=6764||6771<=A&&A<=6780||A==6783||6832<=A&&A<=6845||A==6846||6912<=A&&A<=6915||A==6964||6966<=A&&A<=6970||A==6972||A==6978||7019<=A&&A<=7027||7040<=A&&A<=7041||7074<=A&&A<=7077||7080<=A&&A<=7081||7083<=A&&A<=7085||A==7142||7144<=A&&A<=7145||A==7149||7151<=A&&A<=7153||7212<=A&&A<=7219||7222<=A&&A<=7223||7376<=A&&A<=7378||7380<=A&&A<=7392||7394<=A&&A<=7400||A==7405||A==7412||7416<=A&&A<=7417||7616<=A&&A<=7673||7675<=A&&A<=7679||A==8204||8400<=A&&A<=8412||8413<=A&&A<=8416||A==8417||8418<=A&&A<=8420||8421<=A&&A<=8432||11503<=A&&A<=11505||A==11647||11744<=A&&A<=11775||12330<=A&&A<=12333||12334<=A&&A<=12335||12441<=A&&A<=12442||A==42607||42608<=A&&A<=42610||42612<=A&&A<=42621||42654<=A&&A<=42655||42736<=A&&A<=42737||A==43010||A==43014||A==43019||43045<=A&&A<=43046||43204<=A&&A<=43205||43232<=A&&A<=43249||43302<=A&&A<=43309||43335<=A&&A<=43345||43392<=A&&A<=43394||A==43443||43446<=A&&A<=43449||A==43452||A==43493||43561<=A&&A<=43566||43569<=A&&A<=43570||43573<=A&&A<=43574||A==43587||A==43596||A==43644||A==43696||43698<=A&&A<=43700||43703<=A&&A<=43704||43710<=A&&A<=43711||A==43713||43756<=A&&A<=43757||A==43766||A==44005||A==44008||A==44013||A==64286||65024<=A&&A<=65039||65056<=A&&A<=65071||65438<=A&&A<=65439||A==66045||A==66272||66422<=A&&A<=66426||68097<=A&&A<=68099||68101<=A&&A<=68102||68108<=A&&A<=68111||68152<=A&&A<=68154||A==68159||68325<=A&&A<=68326||A==69633||69688<=A&&A<=69702||69759<=A&&A<=69761||69811<=A&&A<=69814||69817<=A&&A<=69818||69888<=A&&A<=69890||69927<=A&&A<=69931||69933<=A&&A<=69940||A==70003||70016<=A&&A<=70017||70070<=A&&A<=70078||70090<=A&&A<=70092||70191<=A&&A<=70193||A==70196||70198<=A&&A<=70199||A==70206||A==70367||70371<=A&&A<=70378||70400<=A&&A<=70401||A==70460||A==70462||A==70464||A==70487||70502<=A&&A<=70508||70512<=A&&A<=70516||70712<=A&&A<=70719||70722<=A&&A<=70724||A==70726||A==70832||70835<=A&&A<=70840||A==70842||A==70845||70847<=A&&A<=70848||70850<=A&&A<=70851||A==71087||71090<=A&&A<=71093||71100<=A&&A<=71101||71103<=A&&A<=71104||71132<=A&&A<=71133||71219<=A&&A<=71226||A==71229||71231<=A&&A<=71232||A==71339||A==71341||71344<=A&&A<=71349||A==71351||71453<=A&&A<=71455||71458<=A&&A<=71461||71463<=A&&A<=71467||72193<=A&&A<=72198||72201<=A&&A<=72202||72243<=A&&A<=72248||72251<=A&&A<=72254||A==72263||72273<=A&&A<=72278||72281<=A&&A<=72283||72330<=A&&A<=72342||72344<=A&&A<=72345||72752<=A&&A<=72758||72760<=A&&A<=72765||A==72767||72850<=A&&A<=72871||72874<=A&&A<=72880||72882<=A&&A<=72883||72885<=A&&A<=72886||73009<=A&&A<=73014||A==73018||73020<=A&&A<=73021||73023<=A&&A<=73029||A==73031||92912<=A&&A<=92916||92976<=A&&A<=92982||94095<=A&&A<=94098||113821<=A&&A<=113822||A==119141||119143<=A&&A<=119145||119150<=A&&A<=119154||119163<=A&&A<=119170||119173<=A&&A<=119179||119210<=A&&A<=119213||119362<=A&&A<=119364||121344<=A&&A<=121398||121403<=A&&A<=121452||A==121461||A==121476||121499<=A&&A<=121503||121505<=A&&A<=121519||122880<=A&&A<=122886||122888<=A&&A<=122904||122907<=A&&A<=122913||122915<=A&&A<=122916||122918<=A&&A<=122922||125136<=A&&A<=125142||125252<=A&&A<=125258||917536<=A&&A<=917631||917760<=A&&A<=917999?i:127462<=A&&A<=127487?n:A==2307||A==2363||2366<=A&&A<=2368||2377<=A&&A<=2380||2382<=A&&A<=2383||2434<=A&&A<=2435||2495<=A&&A<=2496||2503<=A&&A<=2504||2507<=A&&A<=2508||A==2563||2622<=A&&A<=2624||A==2691||2750<=A&&A<=2752||A==2761||2763<=A&&A<=2764||2818<=A&&A<=2819||A==2880||2887<=A&&A<=2888||2891<=A&&A<=2892||A==3007||3009<=A&&A<=3010||3014<=A&&A<=3016||3018<=A&&A<=3020||3073<=A&&A<=3075||3137<=A&&A<=3140||3202<=A&&A<=3203||A==3262||3264<=A&&A<=3265||3267<=A&&A<=3268||3271<=A&&A<=3272||3274<=A&&A<=3275||3330<=A&&A<=3331||3391<=A&&A<=3392||3398<=A&&A<=3400||3402<=A&&A<=3404||3458<=A&&A<=3459||3536<=A&&A<=3537||3544<=A&&A<=3550||3570<=A&&A<=3571||A==3635||A==3763||3902<=A&&A<=3903||A==3967||A==4145||4155<=A&&A<=4156||4182<=A&&A<=4183||A==4228||A==6070||6078<=A&&A<=6085||6087<=A&&A<=6088||6435<=A&&A<=6438||6441<=A&&A<=6443||6448<=A&&A<=6449||6451<=A&&A<=6456||6681<=A&&A<=6682||A==6741||A==6743||6765<=A&&A<=6770||A==6916||A==6965||A==6971||6973<=A&&A<=6977||6979<=A&&A<=6980||A==7042||A==7073||7078<=A&&A<=7079||A==7082||A==7143||7146<=A&&A<=7148||A==7150||7154<=A&&A<=7155||7204<=A&&A<=7211||7220<=A&&A<=7221||A==7393||7410<=A&&A<=7411||A==7415||43043<=A&&A<=43044||A==43047||43136<=A&&A<=43137||43188<=A&&A<=43203||43346<=A&&A<=43347||A==43395||43444<=A&&A<=43445||43450<=A&&A<=43451||43453<=A&&A<=43456||43567<=A&&A<=43568||43571<=A&&A<=43572||A==43597||A==43755||43758<=A&&A<=43759||A==43765||44003<=A&&A<=44004||44006<=A&&A<=44007||44009<=A&&A<=44010||A==44012||A==69632||A==69634||A==69762||69808<=A&&A<=69810||69815<=A&&A<=69816||A==69932||A==70018||70067<=A&&A<=70069||70079<=A&&A<=70080||70188<=A&&A<=70190||70194<=A&&A<=70195||A==70197||70368<=A&&A<=70370||70402<=A&&A<=70403||A==70463||70465<=A&&A<=70468||70471<=A&&A<=70472||70475<=A&&A<=70477||70498<=A&&A<=70499||70709<=A&&A<=70711||70720<=A&&A<=70721||A==70725||70833<=A&&A<=70834||A==70841||70843<=A&&A<=70844||A==70846||A==70849||71088<=A&&A<=71089||71096<=A&&A<=71099||A==71102||71216<=A&&A<=71218||71227<=A&&A<=71228||A==71230||A==71340||71342<=A&&A<=71343||A==71350||71456<=A&&A<=71457||A==71462||72199<=A&&A<=72200||A==72249||72279<=A&&A<=72280||A==72343||A==72751||A==72766||A==72873||A==72881||A==72884||94033<=A&&A<=94078||A==119142||A==119149?s:4352<=A&&A<=4447||43360<=A&&A<=43388?o:4448<=A&&A<=4519||55216<=A&&A<=55238?a:4520<=A&&A<=4607||55243<=A&&A<=55291?l:A==44032||A==44060||A==44088||A==44116||A==44144||A==44172||A==44200||A==44228||A==44256||A==44284||A==44312||A==44340||A==44368||A==44396||A==44424||A==44452||A==44480||A==44508||A==44536||A==44564||A==44592||A==44620||A==44648||A==44676||A==44704||A==44732||A==44760||A==44788||A==44816||A==44844||A==44872||A==44900||A==44928||A==44956||A==44984||A==45012||A==45040||A==45068||A==45096||A==45124||A==45152||A==45180||A==45208||A==45236||A==45264||A==45292||A==45320||A==45348||A==45376||A==45404||A==45432||A==45460||A==45488||A==45516||A==45544||A==45572||A==45600||A==45628||A==45656||A==45684||A==45712||A==45740||A==45768||A==45796||A==45824||A==45852||A==45880||A==45908||A==45936||A==45964||A==45992||A==46020||A==46048||A==46076||A==46104||A==46132||A==46160||A==46188||A==46216||A==46244||A==46272||A==46300||A==46328||A==46356||A==46384||A==46412||A==46440||A==46468||A==46496||A==46524||A==46552||A==46580||A==46608||A==46636||A==46664||A==46692||A==46720||A==46748||A==46776||A==46804||A==46832||A==46860||A==46888||A==46916||A==46944||A==46972||A==47e3||A==47028||A==47056||A==47084||A==47112||A==47140||A==47168||A==47196||A==47224||A==47252||A==47280||A==47308||A==47336||A==47364||A==47392||A==47420||A==47448||A==47476||A==47504||A==47532||A==47560||A==47588||A==47616||A==47644||A==47672||A==47700||A==47728||A==47756||A==47784||A==47812||A==47840||A==47868||A==47896||A==47924||A==47952||A==47980||A==48008||A==48036||A==48064||A==48092||A==48120||A==48148||A==48176||A==48204||A==48232||A==48260||A==48288||A==48316||A==48344||A==48372||A==48400||A==48428||A==48456||A==48484||A==48512||A==48540||A==48568||A==48596||A==48624||A==48652||A==48680||A==48708||A==48736||A==48764||A==48792||A==48820||A==48848||A==48876||A==48904||A==48932||A==48960||A==48988||A==49016||A==49044||A==49072||A==49100||A==49128||A==49156||A==49184||A==49212||A==49240||A==49268||A==49296||A==49324||A==49352||A==49380||A==49408||A==49436||A==49464||A==49492||A==49520||A==49548||A==49576||A==49604||A==49632||A==49660||A==49688||A==49716||A==49744||A==49772||A==49800||A==49828||A==49856||A==49884||A==49912||A==49940||A==49968||A==49996||A==50024||A==50052||A==50080||A==50108||A==50136||A==50164||A==50192||A==50220||A==50248||A==50276||A==50304||A==50332||A==50360||A==50388||A==50416||A==50444||A==50472||A==50500||A==50528||A==50556||A==50584||A==50612||A==50640||A==50668||A==50696||A==50724||A==50752||A==50780||A==50808||A==50836||A==50864||A==50892||A==50920||A==50948||A==50976||A==51004||A==51032||A==51060||A==51088||A==51116||A==51144||A==51172||A==51200||A==51228||A==51256||A==51284||A==51312||A==51340||A==51368||A==51396||A==51424||A==51452||A==51480||A==51508||A==51536||A==51564||A==51592||A==51620||A==51648||A==51676||A==51704||A==51732||A==51760||A==51788||A==51816||A==51844||A==51872||A==51900||A==51928||A==51956||A==51984||A==52012||A==52040||A==52068||A==52096||A==52124||A==52152||A==52180||A==52208||A==52236||A==52264||A==52292||A==52320||A==52348||A==52376||A==52404||A==52432||A==52460||A==52488||A==52516||A==52544||A==52572||A==52600||A==52628||A==52656||A==52684||A==52712||A==52740||A==52768||A==52796||A==52824||A==52852||A==52880||A==52908||A==52936||A==52964||A==52992||A==53020||A==53048||A==53076||A==53104||A==53132||A==53160||A==53188||A==53216||A==53244||A==53272||A==53300||A==53328||A==53356||A==53384||A==53412||A==53440||A==53468||A==53496||A==53524||A==53552||A==53580||A==53608||A==53636||A==53664||A==53692||A==53720||A==53748||A==53776||A==53804||A==53832||A==53860||A==53888||A==53916||A==53944||A==53972||A==54e3||A==54028||A==54056||A==54084||A==54112||A==54140||A==54168||A==54196||A==54224||A==54252||A==54280||A==54308||A==54336||A==54364||A==54392||A==54420||A==54448||A==54476||A==54504||A==54532||A==54560||A==54588||A==54616||A==54644||A==54672||A==54700||A==54728||A==54756||A==54784||A==54812||A==54840||A==54868||A==54896||A==54924||A==54952||A==54980||A==55008||A==55036||A==55064||A==55092||A==55120||A==55148||A==55176?c:44033<=A&&A<=44059||44061<=A&&A<=44087||44089<=A&&A<=44115||44117<=A&&A<=44143||44145<=A&&A<=44171||44173<=A&&A<=44199||44201<=A&&A<=44227||44229<=A&&A<=44255||44257<=A&&A<=44283||44285<=A&&A<=44311||44313<=A&&A<=44339||44341<=A&&A<=44367||44369<=A&&A<=44395||44397<=A&&A<=44423||44425<=A&&A<=44451||44453<=A&&A<=44479||44481<=A&&A<=44507||44509<=A&&A<=44535||44537<=A&&A<=44563||44565<=A&&A<=44591||44593<=A&&A<=44619||44621<=A&&A<=44647||44649<=A&&A<=44675||44677<=A&&A<=44703||44705<=A&&A<=44731||44733<=A&&A<=44759||44761<=A&&A<=44787||44789<=A&&A<=44815||44817<=A&&A<=44843||44845<=A&&A<=44871||44873<=A&&A<=44899||44901<=A&&A<=44927||44929<=A&&A<=44955||44957<=A&&A<=44983||44985<=A&&A<=45011||45013<=A&&A<=45039||45041<=A&&A<=45067||45069<=A&&A<=45095||45097<=A&&A<=45123||45125<=A&&A<=45151||45153<=A&&A<=45179||45181<=A&&A<=45207||45209<=A&&A<=45235||45237<=A&&A<=45263||45265<=A&&A<=45291||45293<=A&&A<=45319||45321<=A&&A<=45347||45349<=A&&A<=45375||45377<=A&&A<=45403||45405<=A&&A<=45431||45433<=A&&A<=45459||45461<=A&&A<=45487||45489<=A&&A<=45515||45517<=A&&A<=45543||45545<=A&&A<=45571||45573<=A&&A<=45599||45601<=A&&A<=45627||45629<=A&&A<=45655||45657<=A&&A<=45683||45685<=A&&A<=45711||45713<=A&&A<=45739||45741<=A&&A<=45767||45769<=A&&A<=45795||45797<=A&&A<=45823||45825<=A&&A<=45851||45853<=A&&A<=45879||45881<=A&&A<=45907||45909<=A&&A<=45935||45937<=A&&A<=45963||45965<=A&&A<=45991||45993<=A&&A<=46019||46021<=A&&A<=46047||46049<=A&&A<=46075||46077<=A&&A<=46103||46105<=A&&A<=46131||46133<=A&&A<=46159||46161<=A&&A<=46187||46189<=A&&A<=46215||46217<=A&&A<=46243||46245<=A&&A<=46271||46273<=A&&A<=46299||46301<=A&&A<=46327||46329<=A&&A<=46355||46357<=A&&A<=46383||46385<=A&&A<=46411||46413<=A&&A<=46439||46441<=A&&A<=46467||46469<=A&&A<=46495||46497<=A&&A<=46523||46525<=A&&A<=46551||46553<=A&&A<=46579||46581<=A&&A<=46607||46609<=A&&A<=46635||46637<=A&&A<=46663||46665<=A&&A<=46691||46693<=A&&A<=46719||46721<=A&&A<=46747||46749<=A&&A<=46775||46777<=A&&A<=46803||46805<=A&&A<=46831||46833<=A&&A<=46859||46861<=A&&A<=46887||46889<=A&&A<=46915||46917<=A&&A<=46943||46945<=A&&A<=46971||46973<=A&&A<=46999||47001<=A&&A<=47027||47029<=A&&A<=47055||47057<=A&&A<=47083||47085<=A&&A<=47111||47113<=A&&A<=47139||47141<=A&&A<=47167||47169<=A&&A<=47195||47197<=A&&A<=47223||47225<=A&&A<=47251||47253<=A&&A<=47279||47281<=A&&A<=47307||47309<=A&&A<=47335||47337<=A&&A<=47363||47365<=A&&A<=47391||47393<=A&&A<=47419||47421<=A&&A<=47447||47449<=A&&A<=47475||47477<=A&&A<=47503||47505<=A&&A<=47531||47533<=A&&A<=47559||47561<=A&&A<=47587||47589<=A&&A<=47615||47617<=A&&A<=47643||47645<=A&&A<=47671||47673<=A&&A<=47699||47701<=A&&A<=47727||47729<=A&&A<=47755||47757<=A&&A<=47783||47785<=A&&A<=47811||47813<=A&&A<=47839||47841<=A&&A<=47867||47869<=A&&A<=47895||47897<=A&&A<=47923||47925<=A&&A<=47951||47953<=A&&A<=47979||47981<=A&&A<=48007||48009<=A&&A<=48035||48037<=A&&A<=48063||48065<=A&&A<=48091||48093<=A&&A<=48119||48121<=A&&A<=48147||48149<=A&&A<=48175||48177<=A&&A<=48203||48205<=A&&A<=48231||48233<=A&&A<=48259||48261<=A&&A<=48287||48289<=A&&A<=48315||48317<=A&&A<=48343||48345<=A&&A<=48371||48373<=A&&A<=48399||48401<=A&&A<=48427||48429<=A&&A<=48455||48457<=A&&A<=48483||48485<=A&&A<=48511||48513<=A&&A<=48539||48541<=A&&A<=48567||48569<=A&&A<=48595||48597<=A&&A<=48623||48625<=A&&A<=48651||48653<=A&&A<=48679||48681<=A&&A<=48707||48709<=A&&A<=48735||48737<=A&&A<=48763||48765<=A&&A<=48791||48793<=A&&A<=48819||48821<=A&&A<=48847||48849<=A&&A<=48875||48877<=A&&A<=48903||48905<=A&&A<=48931||48933<=A&&A<=48959||48961<=A&&A<=48987||48989<=A&&A<=49015||49017<=A&&A<=49043||49045<=A&&A<=49071||49073<=A&&A<=49099||49101<=A&&A<=49127||49129<=A&&A<=49155||49157<=A&&A<=49183||49185<=A&&A<=49211||49213<=A&&A<=49239||49241<=A&&A<=49267||49269<=A&&A<=49295||49297<=A&&A<=49323||49325<=A&&A<=49351||49353<=A&&A<=49379||49381<=A&&A<=49407||49409<=A&&A<=49435||49437<=A&&A<=49463||49465<=A&&A<=49491||49493<=A&&A<=49519||49521<=A&&A<=49547||49549<=A&&A<=49575||49577<=A&&A<=49603||49605<=A&&A<=49631||49633<=A&&A<=49659||49661<=A&&A<=49687||49689<=A&&A<=49715||49717<=A&&A<=49743||49745<=A&&A<=49771||49773<=A&&A<=49799||49801<=A&&A<=49827||49829<=A&&A<=49855||49857<=A&&A<=49883||49885<=A&&A<=49911||49913<=A&&A<=49939||49941<=A&&A<=49967||49969<=A&&A<=49995||49997<=A&&A<=50023||50025<=A&&A<=50051||50053<=A&&A<=50079||50081<=A&&A<=50107||50109<=A&&A<=50135||50137<=A&&A<=50163||50165<=A&&A<=50191||50193<=A&&A<=50219||50221<=A&&A<=50247||50249<=A&&A<=50275||50277<=A&&A<=50303||50305<=A&&A<=50331||50333<=A&&A<=50359||50361<=A&&A<=50387||50389<=A&&A<=50415||50417<=A&&A<=50443||50445<=A&&A<=50471||50473<=A&&A<=50499||50501<=A&&A<=50527||50529<=A&&A<=50555||50557<=A&&A<=50583||50585<=A&&A<=50611||50613<=A&&A<=50639||50641<=A&&A<=50667||50669<=A&&A<=50695||50697<=A&&A<=50723||50725<=A&&A<=50751||50753<=A&&A<=50779||50781<=A&&A<=50807||50809<=A&&A<=50835||50837<=A&&A<=50863||50865<=A&&A<=50891||50893<=A&&A<=50919||50921<=A&&A<=50947||50949<=A&&A<=50975||50977<=A&&A<=51003||51005<=A&&A<=51031||51033<=A&&A<=51059||51061<=A&&A<=51087||51089<=A&&A<=51115||51117<=A&&A<=51143||51145<=A&&A<=51171||51173<=A&&A<=51199||51201<=A&&A<=51227||51229<=A&&A<=51255||51257<=A&&A<=51283||51285<=A&&A<=51311||51313<=A&&A<=51339||51341<=A&&A<=51367||51369<=A&&A<=51395||51397<=A&&A<=51423||51425<=A&&A<=51451||51453<=A&&A<=51479||51481<=A&&A<=51507||51509<=A&&A<=51535||51537<=A&&A<=51563||51565<=A&&A<=51591||51593<=A&&A<=51619||51621<=A&&A<=51647||51649<=A&&A<=51675||51677<=A&&A<=51703||51705<=A&&A<=51731||51733<=A&&A<=51759||51761<=A&&A<=51787||51789<=A&&A<=51815||51817<=A&&A<=51843||51845<=A&&A<=51871||51873<=A&&A<=51899||51901<=A&&A<=51927||51929<=A&&A<=51955||51957<=A&&A<=51983||51985<=A&&A<=52011||52013<=A&&A<=52039||52041<=A&&A<=52067||52069<=A&&A<=52095||52097<=A&&A<=52123||52125<=A&&A<=52151||52153<=A&&A<=52179||52181<=A&&A<=52207||52209<=A&&A<=52235||52237<=A&&A<=52263||52265<=A&&A<=52291||52293<=A&&A<=52319||52321<=A&&A<=52347||52349<=A&&A<=52375||52377<=A&&A<=52403||52405<=A&&A<=52431||52433<=A&&A<=52459||52461<=A&&A<=52487||52489<=A&&A<=52515||52517<=A&&A<=52543||52545<=A&&A<=52571||52573<=A&&A<=52599||52601<=A&&A<=52627||52629<=A&&A<=52655||52657<=A&&A<=52683||52685<=A&&A<=52711||52713<=A&&A<=52739||52741<=A&&A<=52767||52769<=A&&A<=52795||52797<=A&&A<=52823||52825<=A&&A<=52851||52853<=A&&A<=52879||52881<=A&&A<=52907||52909<=A&&A<=52935||52937<=A&&A<=52963||52965<=A&&A<=52991||52993<=A&&A<=53019||53021<=A&&A<=53047||53049<=A&&A<=53075||53077<=A&&A<=53103||53105<=A&&A<=53131||53133<=A&&A<=53159||53161<=A&&A<=53187||53189<=A&&A<=53215||53217<=A&&A<=53243||53245<=A&&A<=53271||53273<=A&&A<=53299||53301<=A&&A<=53327||53329<=A&&A<=53355||53357<=A&&A<=53383||53385<=A&&A<=53411||53413<=A&&A<=53439||53441<=A&&A<=53467||53469<=A&&A<=53495||53497<=A&&A<=53523||53525<=A&&A<=53551||53553<=A&&A<=53579||53581<=A&&A<=53607||53609<=A&&A<=53635||53637<=A&&A<=53663||53665<=A&&A<=53691||53693<=A&&A<=53719||53721<=A&&A<=53747||53749<=A&&A<=53775||53777<=A&&A<=53803||53805<=A&&A<=53831||53833<=A&&A<=53859||53861<=A&&A<=53887||53889<=A&&A<=53915||53917<=A&&A<=53943||53945<=A&&A<=53971||53973<=A&&A<=53999||54001<=A&&A<=54027||54029<=A&&A<=54055||54057<=A&&A<=54083||54085<=A&&A<=54111||54113<=A&&A<=54139||54141<=A&&A<=54167||54169<=A&&A<=54195||54197<=A&&A<=54223||54225<=A&&A<=54251||54253<=A&&A<=54279||54281<=A&&A<=54307||54309<=A&&A<=54335||54337<=A&&A<=54363||54365<=A&&A<=54391||54393<=A&&A<=54419||54421<=A&&A<=54447||54449<=A&&A<=54475||54477<=A&&A<=54503||54505<=A&&A<=54531||54533<=A&&A<=54559||54561<=A&&A<=54587||54589<=A&&A<=54615||54617<=A&&A<=54643||54645<=A&&A<=54671||54673<=A&&A<=54699||54701<=A&&A<=54727||54729<=A&&A<=54755||54757<=A&&A<=54783||54785<=A&&A<=54811||54813<=A&&A<=54839||54841<=A&&A<=54867||54869<=A&&A<=54895||54897<=A&&A<=54923||54925<=A&&A<=54951||54953<=A&&A<=54979||54981<=A&&A<=55007||55009<=A&&A<=55035||55037<=A&&A<=55063||55065<=A&&A<=55091||55093<=A&&A<=55119||55121<=A&&A<=55147||55149<=A&&A<=55175||55177<=A&&A<=55203?u:A==9757||A==9977||9994<=A&&A<=9997||A==127877||127938<=A&&A<=127940||A==127943||127946<=A&&A<=127948||128066<=A&&A<=128067||128070<=A&&A<=128080||A==128110||128112<=A&&A<=128120||A==128124||128129<=A&&A<=128131||128133<=A&&A<=128135||A==128170||128372<=A&&A<=128373||A==128378||A==128400||128405<=A&&A<=128406||128581<=A&&A<=128583||128587<=A&&A<=128591||A==128675||128692<=A&&A<=128694||A==128704||A==128716||129304<=A&&A<=129308||129310<=A&&A<=129311||A==129318||129328<=A&&A<=129337||129341<=A&&A<=129342||129489<=A&&A<=129501?p:127995<=A&&A<=127999?d:A==8205?m:A==9792||A==9794||9877<=A&&A<=9878||A==9992||A==10084||A==127752||A==127806||A==127859||A==127891||A==127908||A==127912||A==127979||A==127981||A==128139||128187<=A&&A<=128188||A==128295||A==128300||A==128488||A==128640||A==128658?y:128102<=A&&A<=128105?B:g}return this}typeof xB<"u"&&xB.exports&&(xB.exports=ERe)});var lV=I((dot,AV)=>{var IRe=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,kB;function yRe(){if(kB)return kB;if(typeof Intl.Segmenter<"u"){let r=new Intl.Segmenter("en",{granularity:"grapheme"});return kB=e=>Array.from(r.segment(e),({segment:t})=>t)}else{let r=aV(),e=new r;return kB=t=>e.splitGraphemes(t)}}AV.exports=(r,e=0,t=r.length)=>{if(e<0||t<0)throw new RangeError("Negative indices aren't supported by this implementation");let i=t-e,n="",s=0,o=0;for(;r.length>0;){let a=r.match(IRe)||[r,r,void 0],l=yRe()(a[1]),c=Math.min(e-s,l.length);l=l.slice(c);let u=Math.min(i-o,l.length);n+=l.slice(0,u).join(""),s+=c,o+=u,typeof a[2]<"u"&&(n+=a[2]),r=r.slice(a[0].length)}return n}});var Xf=I((Lot,QV)=>{"use strict";var bV=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"]]);QV.exports=r=>r?Object.keys(r).map(e=>[bV.has(e)?bV.get(e):e,r[e]]).reduce((e,t)=>(e[t[0]]=t[1],e),Object.create(null)):{}});var _f=I((Oot,NV)=>{"use strict";var SV=typeof process=="object"&&process?process:{stdout:null,stderr:null},NRe=J("events"),vV=J("stream"),PV=J("string_decoder").StringDecoder,za=Symbol("EOF"),Va=Symbol("maybeEmitEnd"),tl=Symbol("emittedEnd"),LB=Symbol("emittingEnd"),TC=Symbol("emittedError"),OB=Symbol("closed"),xV=Symbol("read"),MB=Symbol("flush"),kV=Symbol("flushChunk"),Pn=Symbol("encoding"),Xa=Symbol("decoder"),KB=Symbol("flowing"),LC=Symbol("paused"),Zf=Symbol("resume"),di=Symbol("bufferLength"),XR=Symbol("bufferPush"),ZR=Symbol("bufferShift"),Hi=Symbol("objectMode"),ji=Symbol("destroyed"),_R=Symbol("emitData"),DV=Symbol("emitEnd"),$R=Symbol("emitEnd2"),Za=Symbol("async"),OC=r=>Promise.resolve().then(r),RV=global._MP_NO_ITERATOR_SYMBOLS_!=="1",TRe=RV&&Symbol.asyncIterator||Symbol("asyncIterator not implemented"),LRe=RV&&Symbol.iterator||Symbol("iterator not implemented"),ORe=r=>r==="end"||r==="finish"||r==="prefinish",MRe=r=>r instanceof ArrayBuffer||typeof r=="object"&&r.constructor&&r.constructor.name==="ArrayBuffer"&&r.byteLength>=0,KRe=r=>!Buffer.isBuffer(r)&&ArrayBuffer.isView(r),UB=class{constructor(e,t,i){this.src=e,this.dest=t,this.opts=i,this.ondrain=()=>e[Zf](),t.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},eF=class extends UB{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,i){super(e,t,i),this.proxyErrors=n=>t.emit("error",n),e.on("error",this.proxyErrors)}};NV.exports=class FV extends vV{constructor(e){super(),this[KB]=!1,this[LC]=!1,this.pipes=[],this.buffer=[],this[Hi]=e&&e.objectMode||!1,this[Hi]?this[Pn]=null:this[Pn]=e&&e.encoding||null,this[Pn]==="buffer"&&(this[Pn]=null),this[Za]=e&&!!e.async||!1,this[Xa]=this[Pn]?new PV(this[Pn]):null,this[za]=!1,this[tl]=!1,this[LB]=!1,this[OB]=!1,this[TC]=null,this.writable=!0,this.readable=!0,this[di]=0,this[ji]=!1}get bufferLength(){return this[di]}get encoding(){return this[Pn]}set encoding(e){if(this[Hi])throw new Error("cannot set encoding in objectMode");if(this[Pn]&&e!==this[Pn]&&(this[Xa]&&this[Xa].lastNeed||this[di]))throw new Error("cannot change encoding");this[Pn]!==e&&(this[Xa]=e?new PV(e):null,this.buffer.length&&(this.buffer=this.buffer.map(t=>this[Xa].write(t)))),this[Pn]=e}setEncoding(e){this.encoding=e}get objectMode(){return this[Hi]}set objectMode(e){this[Hi]=this[Hi]||!!e}get async(){return this[Za]}set async(e){this[Za]=this[Za]||!!e}write(e,t,i){if(this[za])throw new Error("write after end");if(this[ji])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8");let n=this[Za]?OC:s=>s();return!this[Hi]&&!Buffer.isBuffer(e)&&(KRe(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):MRe(e)?e=Buffer.from(e):typeof e!="string"&&(this.objectMode=!0)),this[Hi]?(this.flowing&&this[di]!==0&&this[MB](!0),this.flowing?this.emit("data",e):this[XR](e),this[di]!==0&&this.emit("readable"),i&&n(i),this.flowing):e.length?(typeof e=="string"&&!(t===this[Pn]&&!this[Xa].lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[Pn]&&(e=this[Xa].write(e)),this.flowing&&this[di]!==0&&this[MB](!0),this.flowing?this.emit("data",e):this[XR](e),this[di]!==0&&this.emit("readable"),i&&n(i),this.flowing):(this[di]!==0&&this.emit("readable"),i&&n(i),this.flowing)}read(e){if(this[ji])return null;if(this[di]===0||e===0||e>this[di])return this[Va](),null;this[Hi]&&(e=null),this.buffer.length>1&&!this[Hi]&&(this.encoding?this.buffer=[this.buffer.join("")]:this.buffer=[Buffer.concat(this.buffer,this[di])]);let t=this[xV](e||null,this.buffer[0]);return this[Va](),t}[xV](e,t){return e===t.length||e===null?this[ZR]():(this.buffer[0]=t.slice(e),t=t.slice(0,e),this[di]-=e),this.emit("data",t),!this.buffer.length&&!this[za]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=null),typeof t=="function"&&(i=t,t="utf8"),e&&this.write(e,t),i&&this.once("end",i),this[za]=!0,this.writable=!1,(this.flowing||!this[LC])&&this[Va](),this}[Zf](){this[ji]||(this[LC]=!1,this[KB]=!0,this.emit("resume"),this.buffer.length?this[MB]():this[za]?this[Va]():this.emit("drain"))}resume(){return this[Zf]()}pause(){this[KB]=!1,this[LC]=!0}get destroyed(){return this[ji]}get flowing(){return this[KB]}get paused(){return this[LC]}[XR](e){this[Hi]?this[di]+=1:this[di]+=e.length,this.buffer.push(e)}[ZR](){return this.buffer.length&&(this[Hi]?this[di]-=1:this[di]-=this.buffer[0].length),this.buffer.shift()}[MB](e){do;while(this[kV](this[ZR]()));!e&&!this.buffer.length&&!this[za]&&this.emit("drain")}[kV](e){return e?(this.emit("data",e),this.flowing):!1}pipe(e,t){if(this[ji])return;let i=this[tl];return t=t||{},e===SV.stdout||e===SV.stderr?t.end=!1:t.end=t.end!==!1,t.proxyErrors=!!t.proxyErrors,i?t.end&&e.end():(this.pipes.push(t.proxyErrors?new eF(this,e,t):new UB(this,e,t)),this[Za]?OC(()=>this[Zf]()):this[Zf]()),e}unpipe(e){let t=this.pipes.find(i=>i.dest===e);t&&(this.pipes.splice(this.pipes.indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){let i=super.on(e,t);return e==="data"&&!this.pipes.length&&!this.flowing?this[Zf]():e==="readable"&&this[di]!==0?super.emit("readable"):ORe(e)&&this[tl]?(super.emit(e),this.removeAllListeners(e)):e==="error"&&this[TC]&&(this[Za]?OC(()=>t.call(this,this[TC])):t.call(this,this[TC])),i}get emittedEnd(){return this[tl]}[Va](){!this[LB]&&!this[tl]&&!this[ji]&&this.buffer.length===0&&this[za]&&(this[LB]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[OB]&&this.emit("close"),this[LB]=!1)}emit(e,t,...i){if(e!=="error"&&e!=="close"&&e!==ji&&this[ji])return;if(e==="data")return t?this[Za]?OC(()=>this[_R](t)):this[_R](t):!1;if(e==="end")return this[DV]();if(e==="close"){if(this[OB]=!0,!this[tl]&&!this[ji])return;let s=super.emit("close");return this.removeAllListeners("close"),s}else if(e==="error"){this[TC]=t;let s=super.emit("error",t);return this[Va](),s}else if(e==="resume"){let s=super.emit("resume");return this[Va](),s}else if(e==="finish"||e==="prefinish"){let s=super.emit(e);return this.removeAllListeners(e),s}let n=super.emit(e,t,...i);return this[Va](),n}[_R](e){for(let i of this.pipes)i.dest.write(e)===!1&&this.pause();let t=super.emit("data",e);return this[Va](),t}[DV](){this[tl]||(this[tl]=!0,this.readable=!1,this[Za]?OC(()=>this[$R]()):this[$R]())}[$R](){if(this[Xa]){let t=this[Xa].end();if(t){for(let i of this.pipes)i.dest.write(t);super.emit("data",t)}}for(let t of this.pipes)t.end();let e=super.emit("end");return this.removeAllListeners("end"),e}collect(){let e=[];this[Hi]||(e.dataLength=0);let t=this.promise();return this.on("data",i=>{e.push(i),this[Hi]||(e.dataLength+=i.length)}),t.then(()=>e)}concat(){return this[Hi]?Promise.reject(new Error("cannot concat in objectMode")):this.collect().then(e=>this[Hi]?Promise.reject(new Error("cannot concat in objectMode")):this[Pn]?e.join(""):Buffer.concat(e,e.dataLength))}promise(){return new Promise((e,t)=>{this.on(ji,()=>t(new Error("stream destroyed"))),this.on("error",i=>t(i)),this.on("end",()=>e())})}[TRe](){return{next:()=>{let t=this.read();if(t!==null)return Promise.resolve({done:!1,value:t});if(this[za])return Promise.resolve({done:!0});let i=null,n=null,s=c=>{this.removeListener("data",o),this.removeListener("end",a),n(c)},o=c=>{this.removeListener("error",s),this.removeListener("end",a),this.pause(),i({value:c,done:!!this[za]})},a=()=>{this.removeListener("error",s),this.removeListener("data",o),i({done:!0})},l=()=>s(new Error("stream destroyed"));return new Promise((c,u)=>{n=u,i=c,this.once(ji,l),this.once("error",s),this.once("end",a),this.once("data",o)})}}}[LRe](){return{next:()=>{let t=this.read();return{value:t,done:t===null}}}}destroy(e){return this[ji]?(e?this.emit("error",e):this.emit(ji),this):(this[ji]=!0,this.buffer.length=0,this[di]=0,typeof this.close=="function"&&!this[OB]&&this.close(),e?this.emit("error",e):this.emit(ji),this)}static isStream(e){return!!e&&(e instanceof FV||e instanceof vV||e instanceof NRe&&(typeof e.pipe=="function"||typeof e.write=="function"&&typeof e.end=="function"))}}});var LV=I((Mot,TV)=>{var URe=J("zlib").constants||{ZLIB_VERNUM:4736};TV.exports=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},URe))});var dF=I(Xn=>{"use strict";var sF=J("assert"),rl=J("buffer").Buffer,KV=J("zlib"),jc=Xn.constants=LV(),HRe=_f(),OV=rl.concat,Gc=Symbol("_superWrite"),eh=class extends Error{constructor(e){super("zlib: "+e.message),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,this.constructor)}get name(){return"ZlibError"}},jRe=Symbol("opts"),MC=Symbol("flushFlag"),MV=Symbol("finishFlushFlag"),pF=Symbol("fullFlushFlag"),Ar=Symbol("handle"),HB=Symbol("onError"),$f=Symbol("sawError"),tF=Symbol("level"),rF=Symbol("strategy"),iF=Symbol("ended"),Kot=Symbol("_defaultFullFlush"),jB=class extends HRe{constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");super(e),this[$f]=!1,this[iF]=!1,this[jRe]=e,this[MC]=e.flush,this[MV]=e.finishFlush;try{this[Ar]=new KV[t](e)}catch(i){throw new eh(i)}this[HB]=i=>{this[$f]||(this[$f]=!0,this.close(),this.emit("error",i))},this[Ar].on("error",i=>this[HB](new eh(i))),this.once("end",()=>this.close)}close(){this[Ar]&&(this[Ar].close(),this[Ar]=null,this.emit("close"))}reset(){if(!this[$f])return sF(this[Ar],"zlib binding closed"),this[Ar].reset()}flush(e){this.ended||(typeof e!="number"&&(e=this[pF]),this.write(Object.assign(rl.alloc(0),{[MC]:e})))}end(e,t,i){return e&&this.write(e,t),this.flush(this[MV]),this[iF]=!0,super.end(null,null,i)}get ended(){return this[iF]}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=rl.from(e,t)),this[$f])return;sF(this[Ar],"zlib binding closed");let n=this[Ar]._handle,s=n.close;n.close=()=>{};let o=this[Ar].close;this[Ar].close=()=>{},rl.concat=c=>c;let a;try{let c=typeof e[MC]=="number"?e[MC]:this[MC];a=this[Ar]._processChunk(e,c),rl.concat=OV}catch(c){rl.concat=OV,this[HB](new eh(c))}finally{this[Ar]&&(this[Ar]._handle=n,n.close=s,this[Ar].close=o,this[Ar].removeAllListeners("error"))}this[Ar]&&this[Ar].on("error",c=>this[HB](new eh(c)));let l;if(a)if(Array.isArray(a)&&a.length>0){l=this[Gc](rl.from(a[0]));for(let c=1;c<a.length;c++)l=this[Gc](a[c])}else l=this[Gc](rl.from(a));return i&&i(),l}[Gc](e){return super.write(e)}},_a=class extends jB{constructor(e,t){e=e||{},e.flush=e.flush||jc.Z_NO_FLUSH,e.finishFlush=e.finishFlush||jc.Z_FINISH,super(e,t),this[pF]=jc.Z_FULL_FLUSH,this[tF]=e.level,this[rF]=e.strategy}params(e,t){if(!this[$f]){if(!this[Ar])throw new Error("cannot switch params when binding is closed");if(!this[Ar].params)throw new Error("not supported in this implementation");if(this[tF]!==e||this[rF]!==t){this.flush(jc.Z_SYNC_FLUSH),sF(this[Ar],"zlib binding closed");let i=this[Ar].flush;this[Ar].flush=(n,s)=>{this.flush(n),s()};try{this[Ar].params(e,t)}finally{this[Ar].flush=i}this[Ar]&&(this[tF]=e,this[rF]=t)}}}},oF=class extends _a{constructor(e){super(e,"Deflate")}},aF=class extends _a{constructor(e){super(e,"Inflate")}},nF=Symbol("_portable"),AF=class extends _a{constructor(e){super(e,"Gzip"),this[nF]=e&&!!e.portable}[Gc](e){return this[nF]?(this[nF]=!1,e[9]=255,super[Gc](e)):super[Gc](e)}},lF=class extends _a{constructor(e){super(e,"Gunzip")}},cF=class extends _a{constructor(e){super(e,"DeflateRaw")}},uF=class extends _a{constructor(e){super(e,"InflateRaw")}},gF=class extends _a{constructor(e){super(e,"Unzip")}},GB=class extends jB{constructor(e,t){e=e||{},e.flush=e.flush||jc.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||jc.BROTLI_OPERATION_FINISH,super(e,t),this[pF]=jc.BROTLI_OPERATION_FLUSH}},fF=class extends GB{constructor(e){super(e,"BrotliCompress")}},hF=class extends GB{constructor(e){super(e,"BrotliDecompress")}};Xn.Deflate=oF;Xn.Inflate=aF;Xn.Gzip=AF;Xn.Gunzip=lF;Xn.DeflateRaw=cF;Xn.InflateRaw=uF;Xn.Unzip=gF;typeof KV.BrotliCompress=="function"?(Xn.BrotliCompress=fF,Xn.BrotliDecompress=hF):Xn.BrotliCompress=Xn.BrotliDecompress=class{constructor(){throw new Error("Brotli is not supported in this version of Node.js")}}});var th=I((jot,UV)=>{var GRe=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;UV.exports=GRe!=="win32"?r=>r:r=>r&&r.replace(/\\/g,"/")});var YB=I((Yot,HV)=>{"use strict";var YRe=_f(),CF=th(),mF=Symbol("slurp");HV.exports=class extends YRe{constructor(e,t,i){switch(super(),this.pause(),this.extended=t,this.globalExtended=i,this.header=e,this.startBlockSize=512*Math.ceil(e.size/512),this.blockRemain=this.startBlockSize,this.remain=e.size,this.type=e.type,this.meta=!1,this.ignore=!1,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}this.path=CF(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=e.size,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=CF(e.linkpath),this.uname=e.uname,this.gname=e.gname,t&&this[mF](t),i&&this[mF](i,!0)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,n=this.blockRemain;return this.remain=Math.max(0,i-t),this.blockRemain=Math.max(0,n-t),this.ignore?!0:i>=t?super.write(e):super.write(e.slice(0,i))}[mF](e,t){for(let i in e)e[i]!==null&&e[i]!==void 0&&!(t&&i==="path")&&(this[i]=i==="path"||i==="linkpath"?CF(e[i]):e[i])}}});var EF=I(qB=>{"use strict";qB.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);qB.code=new Map(Array.from(qB.name).map(r=>[r[1],r[0]]))});var qV=I((Jot,YV)=>{"use strict";var qRe=(r,e)=>{if(Number.isSafeInteger(r))r<0?WRe(r,e):JRe(r,e);else throw Error("cannot encode number outside of javascript safe integer range");return e},JRe=(r,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=r&255,r=Math.floor(r/256)},WRe=(r,e)=>{e[0]=255;var t=!1;r=r*-1;for(var i=e.length;i>1;i--){var n=r&255;r=Math.floor(r/256),t?e[i-1]=jV(n):n===0?e[i-1]=0:(t=!0,e[i-1]=GV(n))}},zRe=r=>{let e=r[0],t=e===128?XRe(r.slice(1,r.length)):e===255?VRe(r):null;if(t===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(t))throw Error("parsed number outside of javascript safe integer range");return t},VRe=r=>{for(var e=r.length,t=0,i=!1,n=e-1;n>-1;n--){var s=r[n],o;i?o=jV(s):s===0?o=s:(i=!0,o=GV(s)),o!==0&&(t-=o*Math.pow(256,e-n-1))}return t},XRe=r=>{for(var e=r.length,t=0,i=e-1;i>-1;i--){var n=r[i];n!==0&&(t+=n*Math.pow(256,e-i-1))}return t},jV=r=>(255^r)&255,GV=r=>(255^r)+1&255;YV.exports={encode:qRe,parse:zRe}});var ih=I((Wot,WV)=>{"use strict";var IF=EF(),rh=J("path").posix,JV=qV(),yF=Symbol("slurp"),Zn=Symbol("type"),bF=class{constructor(e,t,i,n){this.cksumValid=!1,this.needPax=!1,this.nullBlock=!1,this.block=null,this.path=null,this.mode=null,this.uid=null,this.gid=null,this.size=null,this.mtime=null,this.cksum=null,this[Zn]="0",this.linkpath=null,this.uname=null,this.gname=null,this.devmaj=0,this.devmin=0,this.atime=null,this.ctime=null,Buffer.isBuffer(e)?this.decode(e,t||0,i,n):e&&this.set(e)}decode(e,t,i,n){if(t||(t=0),!e||!(e.length>=t+512))throw new Error("need 512 bytes for header");if(this.path=Yc(e,t,100),this.mode=il(e,t+100,8),this.uid=il(e,t+108,8),this.gid=il(e,t+116,8),this.size=il(e,t+124,12),this.mtime=wF(e,t+136,12),this.cksum=il(e,t+148,12),this[yF](i),this[yF](n,!0),this[Zn]=Yc(e,t+156,1),this[Zn]===""&&(this[Zn]="0"),this[Zn]==="0"&&this.path.substr(-1)==="/"&&(this[Zn]="5"),this[Zn]==="5"&&(this.size=0),this.linkpath=Yc(e,t+157,100),e.slice(t+257,t+265).toString()==="ustar\x0000")if(this.uname=Yc(e,t+265,32),this.gname=Yc(e,t+297,32),this.devmaj=il(e,t+329,8),this.devmin=il(e,t+337,8),e[t+475]!==0){let o=Yc(e,t+345,155);this.path=o+"/"+this.path}else{let o=Yc(e,t+345,130);o&&(this.path=o+"/"+this.path),this.atime=wF(e,t+476,12),this.ctime=wF(e,t+488,12)}let s=8*32;for(let o=t;o<t+148;o++)s+=e[o];for(let o=t+156;o<t+512;o++)s+=e[o];this.cksumValid=s===this.cksum,this.cksum===null&&s===8*32&&(this.nullBlock=!0)}[yF](e,t){for(let i in e)e[i]!==null&&e[i]!==void 0&&!(t&&i==="path")&&(this[i]=e[i])}encode(e,t){if(e||(e=this.block=Buffer.alloc(512),t=0),t||(t=0),!(e.length>=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,n=ZRe(this.path||"",i),s=n[0],o=n[1];this.needPax=n[2],this.needPax=qc(e,t,100,s)||this.needPax,this.needPax=nl(e,t+100,8,this.mode)||this.needPax,this.needPax=nl(e,t+108,8,this.uid)||this.needPax,this.needPax=nl(e,t+116,8,this.gid)||this.needPax,this.needPax=nl(e,t+124,12,this.size)||this.needPax,this.needPax=BF(e,t+136,12,this.mtime)||this.needPax,e[t+156]=this[Zn].charCodeAt(0),this.needPax=qc(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=qc(e,t+265,32,this.uname)||this.needPax,this.needPax=qc(e,t+297,32,this.gname)||this.needPax,this.needPax=nl(e,t+329,8,this.devmaj)||this.needPax,this.needPax=nl(e,t+337,8,this.devmin)||this.needPax,this.needPax=qc(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=qc(e,t+345,155,o)||this.needPax:(this.needPax=qc(e,t+345,130,o)||this.needPax,this.needPax=BF(e,t+476,12,this.atime)||this.needPax,this.needPax=BF(e,t+488,12,this.ctime)||this.needPax);let a=8*32;for(let l=t;l<t+148;l++)a+=e[l];for(let l=t+156;l<t+512;l++)a+=e[l];return this.cksum=a,nl(e,t+148,8,this.cksum),this.cksumValid=!0,this.needPax}set(e){for(let t in e)e[t]!==null&&e[t]!==void 0&&(this[t]=e[t])}get type(){return IF.name.get(this[Zn])||this[Zn]}get typeKey(){return this[Zn]}set type(e){IF.code.has(e)?this[Zn]=IF.code.get(e):this[Zn]=e}},ZRe=(r,e)=>{let i=r,n="",s,o=rh.parse(r).root||".";if(Buffer.byteLength(i)<100)s=[i,n,!1];else{n=rh.dirname(i),i=rh.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(n)<=e?s=[i,n,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(n)<=e?s=[i.substr(0,100-1),n,!0]:(i=rh.join(rh.basename(n),i),n=rh.dirname(n));while(n!==o&&!s);s||(s=[r.substr(0,100-1),"",!0])}return s},Yc=(r,e,t)=>r.slice(e,e+t).toString("utf8").replace(/\0.*/,""),wF=(r,e,t)=>_Re(il(r,e,t)),_Re=r=>r===null?null:new Date(r*1e3),il=(r,e,t)=>r[e]&128?JV.parse(r.slice(e,e+t)):eFe(r,e,t),$Re=r=>isNaN(r)?null:r,eFe=(r,e,t)=>$Re(parseInt(r.slice(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),tFe={12:8589934591,8:2097151},nl=(r,e,t,i)=>i===null?!1:i>tFe[t]||i<0?(JV.encode(i,r.slice(e,e+t)),!0):(rFe(r,e,t,i),!1),rFe=(r,e,t,i)=>r.write(iFe(i,t),e,t,"ascii"),iFe=(r,e)=>nFe(Math.floor(r).toString(8),e),nFe=(r,e)=>(r.length===e-1?r:new Array(e-r.length-1).join("0")+r+" ")+"\0",BF=(r,e,t,i)=>i===null?!1:nl(r,e,t,i.getTime()/1e3),sFe=new Array(156).join("\0"),qc=(r,e,t,i)=>i===null?!1:(r.write(i+sFe,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t);WV.exports=bF});var JB=I((zot,zV)=>{"use strict";var oFe=ih(),aFe=J("path"),KC=class{constructor(e,t){this.atime=e.atime||null,this.charset=e.charset||null,this.comment=e.comment||null,this.ctime=e.ctime||null,this.gid=e.gid||null,this.gname=e.gname||null,this.linkpath=e.linkpath||null,this.mtime=e.mtime||null,this.path=e.path||null,this.size=e.size||null,this.uid=e.uid||null,this.uname=e.uname||null,this.dev=e.dev||null,this.ino=e.ino||null,this.nlink=e.nlink||null,this.global=t||!1}encode(){let e=this.encodeBody();if(e==="")return null;let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),n=Buffer.allocUnsafe(i);for(let s=0;s<512;s++)n[s]=0;new oFe({path:("PaxHeader/"+aFe.basename(this.path)).slice(0,99),mode:this.mode||420,uid:this.uid||null,gid:this.gid||null,size:t,mtime:this.mtime||null,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime||null,ctime:this.ctime||null}).encode(n),n.write(e,512,t,"utf8");for(let s=t+512;s<n.length;s++)n[s]=0;return n}encodeBody(){return this.encodeField("path")+this.encodeField("ctime")+this.encodeField("atime")+this.encodeField("dev")+this.encodeField("ino")+this.encodeField("nlink")+this.encodeField("charset")+this.encodeField("comment")+this.encodeField("gid")+this.encodeField("gname")+this.encodeField("linkpath")+this.encodeField("mtime")+this.encodeField("size")+this.encodeField("uid")+this.encodeField("uname")}encodeField(e){if(this[e]===null||this[e]===void 0)return"";let t=this[e]instanceof Date?this[e].getTime()/1e3:this[e],i=" "+(e==="dev"||e==="ino"||e==="nlink"?"SCHILY.":"")+e+"="+t+` +`,n=Buffer.byteLength(i),s=Math.floor(Math.log(n)/Math.log(10))+1;return n+s>=Math.pow(10,s)&&(s+=1),s+n+i}};KC.parse=(r,e,t)=>new KC(AFe(lFe(r),e),t);var AFe=(r,e)=>e?Object.keys(r).reduce((t,i)=>(t[i]=r[i],t),e):r,lFe=r=>r.replace(/\n$/,"").split(` +`).reduce(cFe,Object.create(null)),cFe=(r,e)=>{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return r;e=e.substr((t+" ").length);let i=e.split("="),n=i.shift().replace(/^SCHILY\.(dev|ino|nlink)/,"$1");if(!n)return r;let s=i.join("=");return r[n]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n)?new Date(s*1e3):/^[0-9]+$/.test(s)?+s:s,r};zV.exports=KC});var nh=I((Vot,VV)=>{VV.exports=r=>{let e=r.length-1,t=-1;for(;e>-1&&r.charAt(e)==="/";)t=e,e--;return t===-1?r:r.slice(0,t)}});var WB=I((Xot,XV)=>{"use strict";XV.exports=r=>class extends r{warn(e,t,i={}){this.file&&(i.file=this.file),this.cwd&&(i.cwd=this.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!this.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),this.emit("warn",i.tarCode,t,i)):t instanceof Error?this.emit("error",Object.assign(t,i)):this.emit("error",Object.assign(new Error(`${e}: ${t}`),i))}}});var SF=I((_ot,ZV)=>{"use strict";var zB=["|","<",">","?",":"],QF=zB.map(r=>String.fromCharCode(61440+r.charCodeAt(0))),uFe=new Map(zB.map((r,e)=>[r,QF[e]])),gFe=new Map(QF.map((r,e)=>[r,zB[e]]));ZV.exports={encode:r=>zB.reduce((e,t)=>e.split(t).join(uFe.get(t)),r),decode:r=>QF.reduce((e,t)=>e.split(t).join(gFe.get(t)),r)}});var vF=I(($ot,$V)=>{var{isAbsolute:fFe,parse:_V}=J("path").win32;$V.exports=r=>{let e="",t=_V(r);for(;fFe(r)||t.root;){let i=r.charAt(0)==="/"&&r.slice(0,4)!=="//?/"?"/":t.root;r=r.substr(i.length),e+=i,t=_V(r)}return[e,r]}});var t7=I((eat,e7)=>{"use strict";e7.exports=(r,e,t)=>(r&=4095,t&&(r=(r|384)&-19),e&&(r&256&&(r|=64),r&32&&(r|=8),r&4&&(r|=1)),r)});var OF=I((iat,p7)=>{"use strict";var A7=_f(),l7=JB(),c7=ih(),Xo=J("fs"),r7=J("path"),Vo=th(),hFe=nh(),u7=(r,e)=>e?(r=Vo(r).replace(/^\.(\/|$)/,""),hFe(e)+"/"+r):Vo(r),pFe=16*1024*1024,i7=Symbol("process"),n7=Symbol("file"),s7=Symbol("directory"),xF=Symbol("symlink"),o7=Symbol("hardlink"),UC=Symbol("header"),VB=Symbol("read"),kF=Symbol("lstat"),XB=Symbol("onlstat"),DF=Symbol("onread"),RF=Symbol("onreadlink"),FF=Symbol("openfile"),NF=Symbol("onopenfile"),sl=Symbol("close"),ZB=Symbol("mode"),TF=Symbol("awaitDrain"),PF=Symbol("ondrain"),Zo=Symbol("prefix"),a7=Symbol("hadError"),g7=WB(),dFe=SF(),f7=vF(),h7=t7(),_B=g7(class extends A7{constructor(e,t){if(t=t||{},super(t),typeof e!="string")throw new TypeError("path is required");this.path=Vo(e),this.portable=!!t.portable,this.myuid=process.getuid&&process.getuid()||0,this.myuser=process.env.USER||"",this.maxReadSize=t.maxReadSize||pFe,this.linkCache=t.linkCache||new Map,this.statCache=t.statCache||new Map,this.preservePaths=!!t.preservePaths,this.cwd=Vo(t.cwd||process.cwd()),this.strict=!!t.strict,this.noPax=!!t.noPax,this.noMtime=!!t.noMtime,this.mtime=t.mtime||null,this.prefix=t.prefix?Vo(t.prefix):null,this.fd=null,this.blockLen=null,this.blockRemain=null,this.buf=null,this.offset=null,this.length=null,this.pos=null,this.remain=null,typeof t.onwarn=="function"&&this.on("warn",t.onwarn);let i=!1;if(!this.preservePaths){let[n,s]=f7(this.path);n&&(this.path=s,i=n)}this.win32=!!t.win32||process.platform==="win32",this.win32&&(this.path=dFe.decode(this.path.replace(/\\/g,"/")),e=e.replace(/\\/g,"/")),this.absolute=Vo(t.absolute||r7.resolve(this.cwd,e)),this.path===""&&(this.path="./"),i&&this.warn("TAR_ENTRY_INFO",`stripping ${i} from absolute path`,{entry:this,path:i+this.path}),this.statCache.has(this.absolute)?this[XB](this.statCache.get(this.absolute)):this[kF]()}emit(e,...t){return e==="error"&&(this[a7]=!0),super.emit(e,...t)}[kF](){Xo.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[XB](t)})}[XB](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=mFe(e),this.emit("stat",e),this[i7]()}[i7](){switch(this.type){case"File":return this[n7]();case"Directory":return this[s7]();case"SymbolicLink":return this[xF]();default:return this.end()}}[ZB](e){return h7(e,this.type==="Directory",this.portable)}[Zo](e){return u7(e,this.prefix)}[UC](){this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.header=new c7({path:this[Zo](this.path),linkpath:this.type==="Link"?this[Zo](this.linkpath):this.linkpath,mode:this[ZB](this.stat.mode),uid:this.portable?null:this.stat.uid,gid:this.portable?null:this.stat.gid,size:this.stat.size,mtime:this.noMtime?null:this.mtime||this.stat.mtime,type:this.type,uname:this.portable?null:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?null:this.stat.atime,ctime:this.portable?null:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new l7({atime:this.portable?null:this.header.atime,ctime:this.portable?null:this.header.ctime,gid:this.portable?null:this.header.gid,mtime:this.noMtime?null:this.mtime||this.header.mtime,path:this[Zo](this.path),linkpath:this.type==="Link"?this[Zo](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?null:this.header.uid,uname:this.portable?null:this.header.uname,dev:this.portable?null:this.stat.dev,ino:this.portable?null:this.stat.ino,nlink:this.portable?null:this.stat.nlink}).encode()),super.write(this.header.block)}[s7](){this.path.substr(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[UC](),this.end()}[xF](){Xo.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[RF](t)})}[RF](e){this.linkpath=Vo(e),this[UC](),this.end()}[o7](e){this.type="Link",this.linkpath=Vo(r7.relative(this.cwd,e)),this.stat.size=0,this[UC](),this.end()}[n7](){if(this.stat.nlink>1){let e=this.stat.dev+":"+this.stat.ino;if(this.linkCache.has(e)){let t=this.linkCache.get(e);if(t.indexOf(this.cwd)===0)return this[o7](t)}this.linkCache.set(e,this.absolute)}if(this[UC](),this.stat.size===0)return this.end();this[FF]()}[FF](){Xo.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[NF](t)})}[NF](e){if(this.fd=e,this[a7])return this[sl]();this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let t=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(t),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[VB]()}[VB](){let{fd:e,buf:t,offset:i,length:n,pos:s}=this;Xo.read(e,t,i,n,s,(o,a)=>{if(o)return this[sl](()=>this.emit("error",o));this[DF](a)})}[sl](e){Xo.close(this.fd,e)}[DF](e){if(e<=0&&this.remain>0){let n=new Error("encountered unexpected EOF");return n.path=this.absolute,n.syscall="read",n.code="EOF",this[sl](()=>this.emit("error",n))}if(e>this.remain){let n=new Error("did not encounter expected EOF");return n.path=this.absolute,n.syscall="read",n.code="EOF",this[sl](()=>this.emit("error",n))}if(e===this.remain)for(let n=e;n<this.length&&e<this.blockRemain;n++)this.buf[n+this.offset]=0,e++,this.remain++;let t=this.offset===0&&e===this.buf.length?this.buf:this.buf.slice(this.offset,this.offset+e);this.write(t)?this[PF]():this[TF](()=>this[PF]())}[TF](e){this.once("drain",e)}write(e){if(this.blockRemain<e.length){let t=new Error("writing more data than expected");return t.path=this.absolute,this.emit("error",t)}return this.remain-=e.length,this.blockRemain-=e.length,this.pos+=e.length,this.offset+=e.length,super.write(e)}[PF](){if(!this.remain)return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),this[sl](e=>e?this.emit("error",e):this.end());this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[VB]()}}),LF=class extends _B{[kF](){this[XB](Xo.lstatSync(this.absolute))}[xF](){this[RF](Xo.readlinkSync(this.absolute))}[FF](){this[NF](Xo.openSync(this.absolute,"r"))}[VB](){let e=!0;try{let{fd:t,buf:i,offset:n,length:s,pos:o}=this,a=Xo.readSync(t,i,n,s,o);this[DF](a),e=!1}finally{if(e)try{this[sl](()=>{})}catch{}}}[TF](e){e()}[sl](e){Xo.closeSync(this.fd),e()}},CFe=g7(class extends A7{constructor(e,t){t=t||{},super(t),this.preservePaths=!!t.preservePaths,this.portable=!!t.portable,this.strict=!!t.strict,this.noPax=!!t.noPax,this.noMtime=!!t.noMtime,this.readEntry=e,this.type=e.type,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=t.prefix||null,this.path=Vo(e.path),this.mode=this[ZB](e.mode),this.uid=this.portable?null:e.uid,this.gid=this.portable?null:e.gid,this.uname=this.portable?null:e.uname,this.gname=this.portable?null:e.gname,this.size=e.size,this.mtime=this.noMtime?null:t.mtime||e.mtime,this.atime=this.portable?null:e.atime,this.ctime=this.portable?null:e.ctime,this.linkpath=Vo(e.linkpath),typeof t.onwarn=="function"&&this.on("warn",t.onwarn);let i=!1;if(!this.preservePaths){let[n,s]=f7(this.path);n&&(this.path=s,i=n)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.header=new c7({path:this[Zo](this.path),linkpath:this.type==="Link"?this[Zo](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?null:this.uid,gid:this.portable?null:this.gid,size:this.size,mtime:this.noMtime?null:this.mtime,type:this.type,uname:this.portable?null:this.uname,atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime}),i&&this.warn("TAR_ENTRY_INFO",`stripping ${i} from absolute path`,{entry:this,path:i+this.path}),this.header.encode()&&!this.noPax&&super.write(new l7({atime:this.portable?null:this.atime,ctime:this.portable?null:this.ctime,gid:this.portable?null:this.gid,mtime:this.noMtime?null:this.mtime,path:this[Zo](this.path),linkpath:this.type==="Link"?this[Zo](this.linkpath):this.linkpath,size:this.size,uid:this.portable?null:this.uid,uname:this.portable?null:this.uname,dev:this.portable?null:this.readEntry.dev,ino:this.portable?null:this.readEntry.ino,nlink:this.portable?null:this.readEntry.nlink}).encode()),super.write(this.header.block),e.pipe(this)}[Zo](e){return u7(e,this.prefix)}[ZB](e){return h7(e,this.type==="Directory",this.portable)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=t,super.write(e)}end(){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),super.end()}});_B.Sync=LF;_B.Tar=CFe;var mFe=r=>r.isFile()?"File":r.isDirectory()?"Directory":r.isSymbolicLink()?"SymbolicLink":"Unsupported";p7.exports=_B});var a0=I((sat,w7)=>{"use strict";var s0=class{constructor(e,t){this.path=e||"./",this.absolute=t,this.entry=null,this.stat=null,this.readdir=null,this.pending=!1,this.ignore=!1,this.piped=!1}},EFe=_f(),IFe=dF(),yFe=YB(),JF=OF(),wFe=JF.Sync,BFe=JF.Tar,bFe=JI(),d7=Buffer.alloc(1024),t0=Symbol("onStat"),$B=Symbol("ended"),_o=Symbol("queue"),sh=Symbol("current"),Jc=Symbol("process"),e0=Symbol("processing"),C7=Symbol("processJob"),$o=Symbol("jobs"),MF=Symbol("jobDone"),r0=Symbol("addFSEntry"),m7=Symbol("addTarEntry"),jF=Symbol("stat"),GF=Symbol("readdir"),i0=Symbol("onreaddir"),n0=Symbol("pipe"),E7=Symbol("entry"),KF=Symbol("entryOpt"),YF=Symbol("writeEntryClass"),y7=Symbol("write"),UF=Symbol("ondrain"),o0=J("fs"),I7=J("path"),QFe=WB(),HF=th(),WF=QFe(class extends EFe{constructor(e){super(e),e=e||Object.create(null),this.opt=e,this.file=e.file||"",this.cwd=e.cwd||process.cwd(),this.maxReadSize=e.maxReadSize,this.preservePaths=!!e.preservePaths,this.strict=!!e.strict,this.noPax=!!e.noPax,this.prefix=HF(e.prefix||""),this.linkCache=e.linkCache||new Map,this.statCache=e.statCache||new Map,this.readdirCache=e.readdirCache||new Map,this[YF]=JF,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),this.portable=!!e.portable,this.zip=null,e.gzip?(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new IFe.Gzip(e.gzip),this.zip.on("data",t=>super.write(t)),this.zip.on("end",t=>super.end()),this.zip.on("drain",t=>this[UF]()),this.on("resume",t=>this.zip.resume())):this.on("drain",this[UF]),this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,this.mtime=e.mtime||null,this.filter=typeof e.filter=="function"?e.filter:t=>!0,this[_o]=new bFe,this[$o]=0,this.jobs=+e.jobs||4,this[e0]=!1,this[$B]=!1}[y7](e){return super.write(e)}add(e){return this.write(e),this}end(e){return e&&this.write(e),this[$B]=!0,this[Jc](),this}write(e){if(this[$B])throw new Error("write after end");return e instanceof yFe?this[m7](e):this[r0](e),this.flowing}[m7](e){let t=HF(I7.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let i=new s0(e.path,t,!1);i.entry=new BFe(e,this[KF](i)),i.entry.on("end",n=>this[MF](i)),this[$o]+=1,this[_o].push(i)}this[Jc]()}[r0](e){let t=HF(I7.resolve(this.cwd,e));this[_o].push(new s0(e,t)),this[Jc]()}[jF](e){e.pending=!0,this[$o]+=1;let t=this.follow?"stat":"lstat";o0[t](e.absolute,(i,n)=>{e.pending=!1,this[$o]-=1,i?this.emit("error",i):this[t0](e,n)})}[t0](e,t){this.statCache.set(e.absolute,t),e.stat=t,this.filter(e.path,t)||(e.ignore=!0),this[Jc]()}[GF](e){e.pending=!0,this[$o]+=1,o0.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[$o]-=1,t)return this.emit("error",t);this[i0](e,i)})}[i0](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[Jc]()}[Jc](){if(!this[e0]){this[e0]=!0;for(let e=this[_o].head;e!==null&&this[$o]<this.jobs;e=e.next)if(this[C7](e.value),e.value.ignore){let t=e.next;this[_o].removeNode(e),e.next=t}this[e0]=!1,this[$B]&&!this[_o].length&&this[$o]===0&&(this.zip?this.zip.end(d7):(super.write(d7),super.end()))}}get[sh](){return this[_o]&&this[_o].head&&this[_o].head.value}[MF](e){this[_o].shift(),this[$o]-=1,this[Jc]()}[C7](e){if(!e.pending){if(e.entry){e===this[sh]&&!e.piped&&this[n0](e);return}if(e.stat||(this.statCache.has(e.absolute)?this[t0](e,this.statCache.get(e.absolute)):this[jF](e)),!!e.stat&&!e.ignore&&!(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir&&(this.readdirCache.has(e.absolute)?this[i0](e,this.readdirCache.get(e.absolute)):this[GF](e),!e.readdir))){if(e.entry=this[E7](e),!e.entry){e.ignore=!0;return}e===this[sh]&&!e.piped&&this[n0](e)}}}[KF](e){return{onwarn:(t,i,n)=>this.warn(t,i,n),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix}}[E7](e){this[$o]+=1;try{return new this[YF](e.path,this[KF](e)).on("end",()=>this[MF](e)).on("error",t=>this.emit("error",t))}catch(t){this.emit("error",t)}}[UF](){this[sh]&&this[sh].entry&&this[sh].entry.resume()}[n0](e){e.piped=!0,e.readdir&&e.readdir.forEach(n=>{let s=e.path,o=s==="./"?"":s.replace(/\/*$/,"/");this[r0](o+n)});let t=e.entry,i=this.zip;i?t.on("data",n=>{i.write(n)||t.pause()}):t.on("data",n=>{super.write(n)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}}),qF=class extends WF{constructor(e){super(e),this[YF]=wFe}pause(){}resume(){}[jF](e){let t=this.follow?"statSync":"lstatSync";this[t0](e,o0[t](e.absolute))}[GF](e,t){this[i0](e,o0.readdirSync(e.absolute))}[n0](e){let t=e.entry,i=this.zip;e.readdir&&e.readdir.forEach(n=>{let s=e.path,o=s==="./"?"":s.replace(/\/*$/,"/");this[r0](o+n)}),i?t.on("data",n=>{i.write(n)}):t.on("data",n=>{super[y7](n)})}};WF.Sync=qF;w7.exports=WF});var fh=I(jC=>{"use strict";var SFe=_f(),vFe=J("events").EventEmitter,xn=J("fs"),XF=xn.writev;if(!XF){let r=process.binding("fs"),e=r.FSReqWrap||r.FSReqCallback;XF=(t,i,n,s)=>{let o=(l,c)=>s(l,c,i),a=new e;a.oncomplete=o,r.writeBuffers(t,i,n,a)}}var uh=Symbol("_autoClose"),Ao=Symbol("_close"),HC=Symbol("_ended"),er=Symbol("_fd"),B7=Symbol("_finished"),al=Symbol("_flags"),zF=Symbol("_flush"),ZF=Symbol("_handleChunk"),_F=Symbol("_makeBuf"),g0=Symbol("_mode"),A0=Symbol("_needDrain"),lh=Symbol("_onerror"),gh=Symbol("_onopen"),VF=Symbol("_onread"),ah=Symbol("_onwrite"),Al=Symbol("_open"),$a=Symbol("_path"),Wc=Symbol("_pos"),ea=Symbol("_queue"),Ah=Symbol("_read"),b7=Symbol("_readSize"),ol=Symbol("_reading"),l0=Symbol("_remain"),Q7=Symbol("_size"),c0=Symbol("_write"),oh=Symbol("_writing"),u0=Symbol("_defaultFlag"),ch=Symbol("_errored"),f0=class extends SFe{constructor(e,t){if(t=t||{},super(t),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[ch]=!1,this[er]=typeof t.fd=="number"?t.fd:null,this[$a]=e,this[b7]=t.readSize||16*1024*1024,this[ol]=!1,this[Q7]=typeof t.size=="number"?t.size:1/0,this[l0]=this[Q7],this[uh]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[er]=="number"?this[Ah]():this[Al]()}get fd(){return this[er]}get path(){return this[$a]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[Al](){xn.open(this[$a],"r",(e,t)=>this[gh](e,t))}[gh](e,t){e?this[lh](e):(this[er]=t,this.emit("open",t),this[Ah]())}[_F](){return Buffer.allocUnsafe(Math.min(this[b7],this[l0]))}[Ah](){if(!this[ol]){this[ol]=!0;let e=this[_F]();if(e.length===0)return process.nextTick(()=>this[VF](null,0,e));xn.read(this[er],e,0,e.length,null,(t,i,n)=>this[VF](t,i,n))}}[VF](e,t,i){this[ol]=!1,e?this[lh](e):this[ZF](t,i)&&this[Ah]()}[Ao](){if(this[uh]&&typeof this[er]=="number"){let e=this[er];this[er]=null,xn.close(e,t=>t?this.emit("error",t):this.emit("close"))}}[lh](e){this[ol]=!0,this[Ao](),this.emit("error",e)}[ZF](e,t){let i=!1;return this[l0]-=e,e>0&&(i=super.write(e<t.length?t.slice(0,e):t)),(e===0||this[l0]<=0)&&(i=!1,this[Ao](),super.end()),i}emit(e,t){switch(e){case"prefinish":case"finish":break;case"drain":typeof this[er]=="number"&&this[Ah]();break;case"error":return this[ch]?void 0:(this[ch]=!0,super.emit(e,t));default:return super.emit(e,t)}}},$F=class extends f0{[Al](){let e=!0;try{this[gh](null,xn.openSync(this[$a],"r")),e=!1}finally{e&&this[Ao]()}}[Ah](){let e=!0;try{if(!this[ol]){this[ol]=!0;do{let t=this[_F](),i=t.length===0?0:xn.readSync(this[er],t,0,t.length,null);if(!this[ZF](i,t))break}while(!0);this[ol]=!1}e=!1}finally{e&&this[Ao]()}}[Ao](){if(this[uh]&&typeof this[er]=="number"){let e=this[er];this[er]=null,xn.closeSync(e),this.emit("close")}}},h0=class extends vFe{constructor(e,t){t=t||{},super(t),this.readable=!1,this.writable=!0,this[ch]=!1,this[oh]=!1,this[HC]=!1,this[A0]=!1,this[ea]=[],this[$a]=e,this[er]=typeof t.fd=="number"?t.fd:null,this[g0]=t.mode===void 0?438:t.mode,this[Wc]=typeof t.start=="number"?t.start:null,this[uh]=typeof t.autoClose=="boolean"?t.autoClose:!0;let i=this[Wc]!==null?"r+":"w";this[u0]=t.flags===void 0,this[al]=this[u0]?i:t.flags,this[er]===null&&this[Al]()}emit(e,t){if(e==="error"){if(this[ch])return;this[ch]=!0}return super.emit(e,t)}get fd(){return this[er]}get path(){return this[$a]}[lh](e){this[Ao](),this[oh]=!0,this.emit("error",e)}[Al](){xn.open(this[$a],this[al],this[g0],(e,t)=>this[gh](e,t))}[gh](e,t){this[u0]&&this[al]==="r+"&&e&&e.code==="ENOENT"?(this[al]="w",this[Al]()):e?this[lh](e):(this[er]=t,this.emit("open",t),this[zF]())}end(e,t){return e&&this.write(e,t),this[HC]=!0,!this[oh]&&!this[ea].length&&typeof this[er]=="number"&&this[ah](null,0),this}write(e,t){return typeof e=="string"&&(e=Buffer.from(e,t)),this[HC]?(this.emit("error",new Error("write() after end()")),!1):this[er]===null||this[oh]||this[ea].length?(this[ea].push(e),this[A0]=!0,!1):(this[oh]=!0,this[c0](e),!0)}[c0](e){xn.write(this[er],e,0,e.length,this[Wc],(t,i)=>this[ah](t,i))}[ah](e,t){e?this[lh](e):(this[Wc]!==null&&(this[Wc]+=t),this[ea].length?this[zF]():(this[oh]=!1,this[HC]&&!this[B7]?(this[B7]=!0,this[Ao](),this.emit("finish")):this[A0]&&(this[A0]=!1,this.emit("drain"))))}[zF](){if(this[ea].length===0)this[HC]&&this[ah](null,0);else if(this[ea].length===1)this[c0](this[ea].pop());else{let e=this[ea];this[ea]=[],XF(this[er],e,this[Wc],(t,i)=>this[ah](t,i))}}[Ao](){if(this[uh]&&typeof this[er]=="number"){let e=this[er];this[er]=null,xn.close(e,t=>t?this.emit("error",t):this.emit("close"))}}},eN=class extends h0{[Al](){let e;if(this[u0]&&this[al]==="r+")try{e=xn.openSync(this[$a],this[al],this[g0])}catch(t){if(t.code==="ENOENT")return this[al]="w",this[Al]();throw t}else e=xn.openSync(this[$a],this[al],this[g0]);this[gh](null,e)}[Ao](){if(this[uh]&&typeof this[er]=="number"){let e=this[er];this[er]=null,xn.closeSync(e),this.emit("close")}}[c0](e){let t=!0;try{this[ah](null,xn.writeSync(this[er],e,0,e.length,this[Wc])),t=!1}finally{if(t)try{this[Ao]()}catch{}}}};jC.ReadStream=f0;jC.ReadStreamSync=$F;jC.WriteStream=h0;jC.WriteStreamSync=eN});var y0=I((Aat,R7)=>{"use strict";var PFe=WB(),xFe=ih(),kFe=J("events"),DFe=JI(),RFe=1024*1024,FFe=YB(),S7=JB(),NFe=dF(),tN=Buffer.from([31,139]),vs=Symbol("state"),zc=Symbol("writeEntry"),eA=Symbol("readEntry"),rN=Symbol("nextEntry"),v7=Symbol("processEntry"),Ps=Symbol("extendedHeader"),GC=Symbol("globalExtendedHeader"),ll=Symbol("meta"),P7=Symbol("emitMeta"),Cr=Symbol("buffer"),tA=Symbol("queue"),Vc=Symbol("ended"),x7=Symbol("emittedEnd"),Xc=Symbol("emit"),kn=Symbol("unzip"),p0=Symbol("consumeChunk"),d0=Symbol("consumeChunkSub"),iN=Symbol("consumeBody"),k7=Symbol("consumeMeta"),D7=Symbol("consumeHeader"),C0=Symbol("consuming"),nN=Symbol("bufferConcat"),sN=Symbol("maybeEnd"),YC=Symbol("writing"),cl=Symbol("aborted"),m0=Symbol("onDone"),Zc=Symbol("sawValidEntry"),E0=Symbol("sawNullBlock"),I0=Symbol("sawEOF"),TFe=r=>!0;R7.exports=PFe(class extends kFe{constructor(e){e=e||{},super(e),this.file=e.file||"",this[Zc]=null,this.on(m0,t=>{(this[vs]==="begin"||this[Zc]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(m0,e.ondone):this.on(m0,t=>{this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||RFe,this.filter=typeof e.filter=="function"?e.filter:TFe,this.writable=!0,this.readable=!1,this[tA]=new DFe,this[Cr]=null,this[eA]=null,this[zc]=null,this[vs]="begin",this[ll]="",this[Ps]=null,this[GC]=null,this[Vc]=!1,this[kn]=null,this[cl]=!1,this[E0]=!1,this[I0]=!1,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onentry=="function"&&this.on("entry",e.onentry)}[D7](e,t){this[Zc]===null&&(this[Zc]=!1);let i;try{i=new xFe(e,t,this[Ps],this[GC])}catch(n){return this.warn("TAR_ENTRY_INVALID",n)}if(i.nullBlock)this[E0]?(this[I0]=!0,this[vs]==="begin"&&(this[vs]="header"),this[Xc]("eof")):(this[E0]=!0,this[Xc]("nullBlock"));else if(this[E0]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let n=i.type;if(/^(Symbolic)?Link$/.test(n)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(n)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let s=this[zc]=new FFe(i,this[Ps],this[GC]);if(!this[Zc])if(s.remain){let o=()=>{s.invalid||(this[Zc]=!0)};s.on("end",o)}else this[Zc]=!0;s.meta?s.size>this.maxMetaEntrySize?(s.ignore=!0,this[Xc]("ignoredEntry",s),this[vs]="ignore",s.resume()):s.size>0&&(this[ll]="",s.on("data",o=>this[ll]+=o),this[vs]="meta"):(this[Ps]=null,s.ignore=s.ignore||!this.filter(s.path,s),s.ignore?(this[Xc]("ignoredEntry",s),this[vs]=s.remain?"ignore":"header",s.resume()):(s.remain?this[vs]="body":(this[vs]="header",s.end()),this[eA]?this[tA].push(s):(this[tA].push(s),this[rN]())))}}}[v7](e){let t=!0;return e?Array.isArray(e)?this.emit.apply(this,e):(this[eA]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",i=>this[rN]()),t=!1)):(this[eA]=null,t=!1),t}[rN](){do;while(this[v7](this[tA].shift()));if(!this[tA].length){let e=this[eA];!e||e.flowing||e.size===e.remain?this[YC]||this.emit("drain"):e.once("drain",i=>this.emit("drain"))}}[iN](e,t){let i=this[zc],n=i.blockRemain,s=n>=e.length&&t===0?e:e.slice(t,t+n);return i.write(s),i.blockRemain||(this[vs]="header",this[zc]=null,i.end()),s.length}[k7](e,t){let i=this[zc],n=this[iN](e,t);return this[zc]||this[P7](i),n}[Xc](e,t,i){!this[tA].length&&!this[eA]?this.emit(e,t,i):this[tA].push([e,t,i])}[P7](e){switch(this[Xc]("meta",this[ll]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[Ps]=S7.parse(this[ll],this[Ps],!1);break;case"GlobalExtendedHeader":this[GC]=S7.parse(this[ll],this[GC],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":this[Ps]=this[Ps]||Object.create(null),this[Ps].path=this[ll].replace(/\0.*/,"");break;case"NextFileHasLongLinkpath":this[Ps]=this[Ps]||Object.create(null),this[Ps].linkpath=this[ll].replace(/\0.*/,"");break;default:throw new Error("unknown meta: "+e.type)}}abort(e){this[cl]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e){if(this[cl])return;if(this[kn]===null&&e){if(this[Cr]&&(e=Buffer.concat([this[Cr],e]),this[Cr]=null),e.length<tN.length)return this[Cr]=e,!0;for(let i=0;this[kn]===null&&i<tN.length;i++)e[i]!==tN[i]&&(this[kn]=!1);if(this[kn]===null){let i=this[Vc];this[Vc]=!1,this[kn]=new NFe.Unzip,this[kn].on("data",s=>this[p0](s)),this[kn].on("error",s=>this.abort(s)),this[kn].on("end",s=>{this[Vc]=!0,this[p0]()}),this[YC]=!0;let n=this[kn][i?"end":"write"](e);return this[YC]=!1,n}}this[YC]=!0,this[kn]?this[kn].write(e):this[p0](e),this[YC]=!1;let t=this[tA].length?!1:this[eA]?this[eA].flowing:!0;return!t&&!this[tA].length&&this[eA].once("drain",i=>this.emit("drain")),t}[nN](e){e&&!this[cl]&&(this[Cr]=this[Cr]?Buffer.concat([this[Cr],e]):e)}[sN](){if(this[Vc]&&!this[x7]&&!this[cl]&&!this[C0]){this[x7]=!0;let e=this[zc];if(e&&e.blockRemain){let t=this[Cr]?this[Cr].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[Cr]&&e.write(this[Cr]),e.end()}this[Xc](m0)}}[p0](e){if(this[C0])this[nN](e);else if(!e&&!this[Cr])this[sN]();else{if(this[C0]=!0,this[Cr]){this[nN](e);let t=this[Cr];this[Cr]=null,this[d0](t)}else this[d0](e);for(;this[Cr]&&this[Cr].length>=512&&!this[cl]&&!this[I0];){let t=this[Cr];this[Cr]=null,this[d0](t)}this[C0]=!1}(!this[Cr]||this[Vc])&&this[sN]()}[d0](e){let t=0,i=e.length;for(;t+512<=i&&!this[cl]&&!this[I0];)switch(this[vs]){case"begin":case"header":this[D7](e,t),t+=512;break;case"ignore":case"body":t+=this[iN](e,t);break;case"meta":t+=this[k7](e,t);break;default:throw new Error("invalid state: "+this[vs])}t<i&&(this[Cr]?this[Cr]=Buffer.concat([e.slice(t),this[Cr]]):this[Cr]=e.slice(t))}end(e){this[cl]||(this[kn]?this[kn].end(e):(this[Vc]=!0,this.write(e)))}})});var w0=I((lat,L7)=>{"use strict";var LFe=Xf(),N7=y0(),hh=J("fs"),OFe=fh(),F7=J("path"),oN=nh();L7.exports=(r,e,t)=>{typeof r=="function"?(t=r,e=null,r={}):Array.isArray(r)&&(e=r,r={}),typeof e=="function"&&(t=e,e=null),e?e=Array.from(e):e=[];let i=LFe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return e.length&&KFe(i,e),i.noResume||MFe(i),i.file&&i.sync?UFe(i):i.file?HFe(i,t):T7(i)};var MFe=r=>{let e=r.onentry;r.onentry=e?t=>{e(t),t.resume()}:t=>t.resume()},KFe=(r,e)=>{let t=new Map(e.map(s=>[oN(s),!0])),i=r.filter,n=(s,o)=>{let a=o||F7.parse(s).root||".",l=s===a?!1:t.has(s)?t.get(s):n(F7.dirname(s),a);return t.set(s,l),l};r.filter=i?(s,o)=>i(s,o)&&n(oN(s)):s=>n(oN(s))},UFe=r=>{let e=T7(r),t=r.file,i=!0,n;try{let s=hh.statSync(t),o=r.maxReadSize||16*1024*1024;if(s.size<o)e.end(hh.readFileSync(t));else{let a=0,l=Buffer.allocUnsafe(o);for(n=hh.openSync(t,"r");a<s.size;){let c=hh.readSync(n,l,0,o,a);a+=c,e.write(l.slice(0,c))}e.end()}i=!1}finally{if(i&&n)try{hh.closeSync(n)}catch{}}},HFe=(r,e)=>{let t=new N7(r),i=r.maxReadSize||16*1024*1024,n=r.file,s=new Promise((o,a)=>{t.on("error",a),t.on("end",o),hh.stat(n,(l,c)=>{if(l)a(l);else{let u=new OFe.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(t)}})});return e?s.then(e,e):s},T7=r=>new N7(r)});var j7=I((cat,H7)=>{"use strict";var jFe=Xf(),B0=a0(),O7=fh(),M7=w0(),K7=J("path");H7.exports=(r,e,t)=>{if(typeof e=="function"&&(t=e),Array.isArray(r)&&(e=r,r={}),!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");e=Array.from(e);let i=jFe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return i.file&&i.sync?GFe(i,e):i.file?YFe(i,e,t):i.sync?qFe(i,e):JFe(i,e)};var GFe=(r,e)=>{let t=new B0.Sync(r),i=new O7.WriteStreamSync(r.file,{mode:r.mode||438});t.pipe(i),U7(t,e)},YFe=(r,e,t)=>{let i=new B0(r),n=new O7.WriteStream(r.file,{mode:r.mode||438});i.pipe(n);let s=new Promise((o,a)=>{n.on("error",a),n.on("close",o),i.on("error",a)});return aN(i,e),t?s.then(t,t):s},U7=(r,e)=>{e.forEach(t=>{t.charAt(0)==="@"?M7({file:K7.resolve(r.cwd,t.substr(1)),sync:!0,noResume:!0,onentry:i=>r.add(i)}):r.add(t)}),r.end()},aN=(r,e)=>{for(;e.length;){let t=e.shift();if(t.charAt(0)==="@")return M7({file:K7.resolve(r.cwd,t.substr(1)),noResume:!0,onentry:i=>r.add(i)}).then(i=>aN(r,e));r.add(t)}r.end()},qFe=(r,e)=>{let t=new B0.Sync(r);return U7(t,e),t},JFe=(r,e)=>{let t=new B0(r);return aN(t,e),t}});var AN=I((uat,V7)=>{"use strict";var WFe=Xf(),G7=a0(),_n=J("fs"),Y7=fh(),q7=w0(),J7=J("path"),W7=ih();V7.exports=(r,e,t)=>{let i=WFe(r);if(!i.file)throw new TypeError("file is required");if(i.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),i.sync?zFe(i,e):XFe(i,e,t)};var zFe=(r,e)=>{let t=new G7.Sync(r),i=!0,n,s;try{try{n=_n.openSync(r.file,"r+")}catch(l){if(l.code==="ENOENT")n=_n.openSync(r.file,"w+");else throw l}let o=_n.fstatSync(n),a=Buffer.alloc(512);e:for(s=0;s<o.size;s+=512){for(let u=0,g=0;u<512;u+=g){if(g=_n.readSync(n,a,u,a.length-u,s+u),s===0&&a[0]===31&&a[1]===139)throw new Error("cannot append to compressed archives");if(!g)break e}let l=new W7(a);if(!l.cksumValid)break;let c=512*Math.ceil(l.size/512);if(s+c+512>o.size)break;s+=c,r.mtimeCache&&r.mtimeCache.set(l.path,l.mtime)}i=!1,VFe(r,t,s,n,e)}finally{if(i)try{_n.closeSync(n)}catch{}}},VFe=(r,e,t,i,n)=>{let s=new Y7.WriteStreamSync(r.file,{fd:i,start:t});e.pipe(s),ZFe(e,n)},XFe=(r,e,t)=>{e=Array.from(e);let i=new G7(r),n=(o,a,l)=>{let c=(d,m)=>{d?_n.close(o,y=>l(d)):l(null,m)},u=0;if(a===0)return c(null,0);let g=0,h=Buffer.alloc(512),p=(d,m)=>{if(d)return c(d);if(g+=m,g<512&&m)return _n.read(o,h,g,h.length-g,u+g,p);if(u===0&&h[0]===31&&h[1]===139)return c(new Error("cannot append to compressed archives"));if(g<512)return c(null,u);let y=new W7(h);if(!y.cksumValid)return c(null,u);let B=512*Math.ceil(y.size/512);if(u+B+512>a||(u+=B+512,u>=a))return c(null,u);r.mtimeCache&&r.mtimeCache.set(y.path,y.mtime),g=0,_n.read(o,h,0,512,u,p)};_n.read(o,h,0,512,u,p)},s=new Promise((o,a)=>{i.on("error",a);let l="r+",c=(u,g)=>{if(u&&u.code==="ENOENT"&&l==="r+")return l="w+",_n.open(r.file,l,c);if(u)return a(u);_n.fstat(g,(h,p)=>{if(h)return _n.close(g,()=>a(h));n(g,p.size,(d,m)=>{if(d)return a(d);let y=new Y7.WriteStream(r.file,{fd:g,start:m});i.pipe(y),y.on("error",a),y.on("close",o),z7(i,e)})})};_n.open(r.file,l,c)});return t?s.then(t,t):s},ZFe=(r,e)=>{e.forEach(t=>{t.charAt(0)==="@"?q7({file:J7.resolve(r.cwd,t.substr(1)),sync:!0,noResume:!0,onentry:i=>r.add(i)}):r.add(t)}),r.end()},z7=(r,e)=>{for(;e.length;){let t=e.shift();if(t.charAt(0)==="@")return q7({file:J7.resolve(r.cwd,t.substr(1)),noResume:!0,onentry:i=>r.add(i)}).then(i=>z7(r,e));r.add(t)}r.end()}});var Z7=I((gat,X7)=>{"use strict";var _Fe=Xf(),$Fe=AN();X7.exports=(r,e,t)=>{let i=_Fe(r);if(!i.file)throw new TypeError("file is required");if(i.gzip)throw new TypeError("cannot append to compressed archives");if(!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");return e=Array.from(e),eNe(i),$Fe(i,e,t)};var eNe=r=>{let e=r.filter;r.mtimeCache||(r.mtimeCache=new Map),r.filter=e?(t,i)=>e(t,i)&&!(r.mtimeCache.get(t)>i.mtime):(t,i)=>!(r.mtimeCache.get(t)>i.mtime)}});var eX=I((fat,$7)=>{var{promisify:_7}=J("util"),ul=J("fs"),tNe=r=>{if(!r)r={mode:511,fs:ul};else if(typeof r=="object")r={mode:511,fs:ul,...r};else if(typeof r=="number")r={mode:r,fs:ul};else if(typeof r=="string")r={mode:parseInt(r,8),fs:ul};else throw new TypeError("invalid options argument");return r.mkdir=r.mkdir||r.fs.mkdir||ul.mkdir,r.mkdirAsync=_7(r.mkdir),r.stat=r.stat||r.fs.stat||ul.stat,r.statAsync=_7(r.stat),r.statSync=r.statSync||r.fs.statSync||ul.statSync,r.mkdirSync=r.mkdirSync||r.fs.mkdirSync||ul.mkdirSync,r};$7.exports=tNe});var rX=I((hat,tX)=>{var rNe=process.platform,{resolve:iNe,parse:nNe}=J("path"),sNe=r=>{if(/\0/.test(r))throw Object.assign(new TypeError("path must be a string without null bytes"),{path:r,code:"ERR_INVALID_ARG_VALUE"});if(r=iNe(r),rNe==="win32"){let e=/[*|"<>?:]/,{root:t}=nNe(r);if(e.test(r.substr(t.length)))throw Object.assign(new Error("Illegal characters in path."),{path:r,code:"EINVAL"})}return r};tX.exports=sNe});var aX=I((pat,oX)=>{var{dirname:iX}=J("path"),nX=(r,e,t=void 0)=>t===e?Promise.resolve():r.statAsync(e).then(i=>i.isDirectory()?t:void 0,i=>i.code==="ENOENT"?nX(r,iX(e),e):void 0),sX=(r,e,t=void 0)=>{if(t!==e)try{return r.statSync(e).isDirectory()?t:void 0}catch(i){return i.code==="ENOENT"?sX(r,iX(e),e):void 0}};oX.exports={findMade:nX,findMadeSync:sX}});var uN=I((dat,lX)=>{var{dirname:AX}=J("path"),lN=(r,e,t)=>{e.recursive=!1;let i=AX(r);return i===r?e.mkdirAsync(r,e).catch(n=>{if(n.code!=="EISDIR")throw n}):e.mkdirAsync(r,e).then(()=>t||r,n=>{if(n.code==="ENOENT")return lN(i,e).then(s=>lN(r,e,s));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;return e.statAsync(r).then(s=>{if(s.isDirectory())return t;throw n},()=>{throw n})})},cN=(r,e,t)=>{let i=AX(r);if(e.recursive=!1,i===r)try{return e.mkdirSync(r,e)}catch(n){if(n.code!=="EISDIR")throw n;return}try{return e.mkdirSync(r,e),t||r}catch(n){if(n.code==="ENOENT")return cN(r,e,cN(i,e,t));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;try{if(!e.statSync(r).isDirectory())throw n}catch{throw n}}};lX.exports={mkdirpManual:lN,mkdirpManualSync:cN}});var gX=I((Cat,uX)=>{var{dirname:cX}=J("path"),{findMade:oNe,findMadeSync:aNe}=aX(),{mkdirpManual:ANe,mkdirpManualSync:lNe}=uN(),cNe=(r,e)=>(e.recursive=!0,cX(r)===r?e.mkdirAsync(r,e):oNe(e,r).then(i=>e.mkdirAsync(r,e).then(()=>i).catch(n=>{if(n.code==="ENOENT")return ANe(r,e);throw n}))),uNe=(r,e)=>{if(e.recursive=!0,cX(r)===r)return e.mkdirSync(r,e);let i=aNe(e,r);try{return e.mkdirSync(r,e),i}catch(n){if(n.code==="ENOENT")return lNe(r,e);throw n}};uX.exports={mkdirpNative:cNe,mkdirpNativeSync:uNe}});var dX=I((mat,pX)=>{var fX=J("fs"),gNe=process.version,gN=gNe.replace(/^v/,"").split("."),hX=+gN[0]>10||+gN[0]==10&&+gN[1]>=12,fNe=hX?r=>r.mkdir===fX.mkdir:()=>!1,hNe=hX?r=>r.mkdirSync===fX.mkdirSync:()=>!1;pX.exports={useNative:fNe,useNativeSync:hNe}});var wX=I((Eat,yX)=>{var ph=eX(),dh=rX(),{mkdirpNative:CX,mkdirpNativeSync:mX}=gX(),{mkdirpManual:EX,mkdirpManualSync:IX}=uN(),{useNative:pNe,useNativeSync:dNe}=dX(),Ch=(r,e)=>(r=dh(r),e=ph(e),pNe(e)?CX(r,e):EX(r,e)),CNe=(r,e)=>(r=dh(r),e=ph(e),dNe(e)?mX(r,e):IX(r,e));Ch.sync=CNe;Ch.native=(r,e)=>CX(dh(r),ph(e));Ch.manual=(r,e)=>EX(dh(r),ph(e));Ch.nativeSync=(r,e)=>mX(dh(r),ph(e));Ch.manualSync=(r,e)=>IX(dh(r),ph(e));yX.exports=Ch});var xX=I((Iat,PX)=>{"use strict";var xs=J("fs"),_c=J("path"),mNe=xs.lchown?"lchown":"chown",ENe=xs.lchownSync?"lchownSync":"chownSync",bX=xs.lchown&&!process.version.match(/v1[1-9]+\./)&&!process.version.match(/v10\.[6-9]/),BX=(r,e,t)=>{try{return xs[ENe](r,e,t)}catch(i){if(i.code!=="ENOENT")throw i}},INe=(r,e,t)=>{try{return xs.chownSync(r,e,t)}catch(i){if(i.code!=="ENOENT")throw i}},yNe=bX?(r,e,t,i)=>n=>{!n||n.code!=="EISDIR"?i(n):xs.chown(r,e,t,i)}:(r,e,t,i)=>i,fN=bX?(r,e,t)=>{try{return BX(r,e,t)}catch(i){if(i.code!=="EISDIR")throw i;INe(r,e,t)}}:(r,e,t)=>BX(r,e,t),wNe=process.version,QX=(r,e,t)=>xs.readdir(r,e,t),BNe=(r,e)=>xs.readdirSync(r,e);/^v4\./.test(wNe)&&(QX=(r,e,t)=>xs.readdir(r,t));var b0=(r,e,t,i)=>{xs[mNe](r,e,t,yNe(r,e,t,n=>{i(n&&n.code!=="ENOENT"?n:null)}))},SX=(r,e,t,i,n)=>{if(typeof e=="string")return xs.lstat(_c.resolve(r,e),(s,o)=>{if(s)return n(s.code!=="ENOENT"?s:null);o.name=e,SX(r,o,t,i,n)});if(e.isDirectory())hN(_c.resolve(r,e.name),t,i,s=>{if(s)return n(s);let o=_c.resolve(r,e.name);b0(o,t,i,n)});else{let s=_c.resolve(r,e.name);b0(s,t,i,n)}},hN=(r,e,t,i)=>{QX(r,{withFileTypes:!0},(n,s)=>{if(n){if(n.code==="ENOENT")return i();if(n.code!=="ENOTDIR"&&n.code!=="ENOTSUP")return i(n)}if(n||!s.length)return b0(r,e,t,i);let o=s.length,a=null,l=c=>{if(!a){if(c)return i(a=c);if(--o===0)return b0(r,e,t,i)}};s.forEach(c=>SX(r,c,e,t,l))})},bNe=(r,e,t,i)=>{if(typeof e=="string")try{let n=xs.lstatSync(_c.resolve(r,e));n.name=e,e=n}catch(n){if(n.code==="ENOENT")return;throw n}e.isDirectory()&&vX(_c.resolve(r,e.name),t,i),fN(_c.resolve(r,e.name),t,i)},vX=(r,e,t)=>{let i;try{i=BNe(r,{withFileTypes:!0})}catch(n){if(n.code==="ENOENT")return;if(n.code==="ENOTDIR"||n.code==="ENOTSUP")return fN(r,e,t);throw n}return i&&i.length&&i.forEach(n=>bNe(r,n,e,t)),fN(r,e,t)};PX.exports=hN;hN.sync=vX});var FX=I((yat,pN)=>{"use strict";var kX=wX(),ks=J("fs"),Q0=J("path"),DX=xX(),lo=th(),S0=class extends Error{constructor(e,t){super("Cannot extract through symbolic link"),this.path=t,this.symlink=e}get name(){return"SylinkError"}},v0=class extends Error{constructor(e,t){super(t+": Cannot cd into '"+e+"'"),this.path=e,this.code=t}get name(){return"CwdError"}},P0=(r,e)=>r.get(lo(e)),qC=(r,e,t)=>r.set(lo(e),t),QNe=(r,e)=>{ks.stat(r,(t,i)=>{(t||!i.isDirectory())&&(t=new v0(r,t&&t.code||"ENOTDIR")),e(t)})};pN.exports=(r,e,t)=>{r=lo(r);let i=e.umask,n=e.mode|448,s=(n&i)!==0,o=e.uid,a=e.gid,l=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),c=e.preserve,u=e.unlink,g=e.cache,h=lo(e.cwd),p=(y,B)=>{y?t(y):(qC(g,r,!0),B&&l?DX(B,o,a,S=>p(S)):s?ks.chmod(r,n,t):t())};if(g&&P0(g,r)===!0)return p();if(r===h)return QNe(r,p);if(c)return kX(r,{mode:n}).then(y=>p(null,y),p);let m=lo(Q0.relative(h,r)).split("/");x0(h,m,n,g,u,h,null,p)};var x0=(r,e,t,i,n,s,o,a)=>{if(!e.length)return a(null,o);let l=e.shift(),c=lo(Q0.resolve(r+"/"+l));if(P0(i,c))return x0(c,e,t,i,n,s,o,a);ks.mkdir(c,t,RX(c,e,t,i,n,s,o,a))},RX=(r,e,t,i,n,s,o,a)=>l=>{l?ks.lstat(r,(c,u)=>{if(c)c.path=c.path&&lo(c.path),a(c);else if(u.isDirectory())x0(r,e,t,i,n,s,o,a);else if(n)ks.unlink(r,g=>{if(g)return a(g);ks.mkdir(r,t,RX(r,e,t,i,n,s,o,a))});else{if(u.isSymbolicLink())return a(new S0(r,r+"/"+e.join("/")));a(l)}}):(o=o||r,x0(r,e,t,i,n,s,o,a))},SNe=r=>{let e=!1,t="ENOTDIR";try{e=ks.statSync(r).isDirectory()}catch(i){t=i.code}finally{if(!e)throw new v0(r,t)}};pN.exports.sync=(r,e)=>{r=lo(r);let t=e.umask,i=e.mode|448,n=(i&t)!==0,s=e.uid,o=e.gid,a=typeof s=="number"&&typeof o=="number"&&(s!==e.processUid||o!==e.processGid),l=e.preserve,c=e.unlink,u=e.cache,g=lo(e.cwd),h=y=>{qC(u,r,!0),y&&a&&DX.sync(y,s,o),n&&ks.chmodSync(r,i)};if(u&&P0(u,r)===!0)return h();if(r===g)return SNe(g),h();if(l)return h(kX.sync(r,i));let d=lo(Q0.relative(g,r)).split("/"),m=null;for(let y=d.shift(),B=g;y&&(B+="/"+y);y=d.shift())if(B=lo(Q0.resolve(B)),!P0(u,B))try{ks.mkdirSync(B,i),m=m||B,qC(u,B,!0)}catch{let x=ks.lstatSync(B);if(x.isDirectory()){qC(u,B,!0);continue}else if(c){ks.unlinkSync(B),ks.mkdirSync(B,i),m=m||B,qC(u,B,!0);continue}else if(x.isSymbolicLink())return new S0(B,B+"/"+d.join("/"))}return h(m)}});var CN=I((wat,NX)=>{var dN=Object.create(null),{hasOwnProperty:vNe}=Object.prototype;NX.exports=r=>(vNe.call(dN,r)||(dN[r]=r.normalize("NFKD")),dN[r])});var MX=I((Bat,OX)=>{var TX=J("assert"),PNe=CN(),xNe=nh(),{join:LX}=J("path"),kNe=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,DNe=kNe==="win32";OX.exports=()=>{let r=new Map,e=new Map,t=c=>c.split("/").slice(0,-1).reduce((g,h)=>(g.length&&(h=LX(g[g.length-1],h)),g.push(h||"/"),g),[]),i=new Set,n=c=>{let u=e.get(c);if(!u)throw new Error("function does not have any path reservations");return{paths:u.paths.map(g=>r.get(g)),dirs:[...u.dirs].map(g=>r.get(g))}},s=c=>{let{paths:u,dirs:g}=n(c);return u.every(h=>h[0]===c)&&g.every(h=>h[0]instanceof Set&&h[0].has(c))},o=c=>i.has(c)||!s(c)?!1:(i.add(c),c(()=>a(c)),!0),a=c=>{if(!i.has(c))return!1;let{paths:u,dirs:g}=e.get(c),h=new Set;return u.forEach(p=>{let d=r.get(p);TX.equal(d[0],c),d.length===1?r.delete(p):(d.shift(),typeof d[0]=="function"?h.add(d[0]):d[0].forEach(m=>h.add(m)))}),g.forEach(p=>{let d=r.get(p);TX(d[0]instanceof Set),d[0].size===1&&d.length===1?r.delete(p):d[0].size===1?(d.shift(),h.add(d[0])):d[0].delete(c)}),i.delete(c),h.forEach(p=>o(p)),!0};return{check:s,reserve:(c,u)=>{c=DNe?["win32 parallelization disabled"]:c.map(h=>PNe(xNe(LX(h))).toLowerCase());let g=new Set(c.map(h=>t(h)).reduce((h,p)=>h.concat(p)));return e.set(u,{dirs:g,paths:c}),c.forEach(h=>{let p=r.get(h);p?p.push(u):r.set(h,[u])}),g.forEach(h=>{let p=r.get(h);p?p[p.length-1]instanceof Set?p[p.length-1].add(u):p.push(new Set([u])):r.set(h,[new Set([u])])}),o(u)}}}});var HX=I((bat,UX)=>{var RNe=process.platform,FNe=RNe==="win32",NNe=global.__FAKE_TESTING_FS__||J("fs"),{O_CREAT:TNe,O_TRUNC:LNe,O_WRONLY:ONe,UV_FS_O_FILEMAP:KX=0}=NNe.constants,MNe=FNe&&!!KX,KNe=512*1024,UNe=KX|LNe|TNe|ONe;UX.exports=MNe?r=>r<KNe?UNe:"w":()=>"w"});var SN=I((Qat,tZ)=>{"use strict";var HNe=J("assert"),jNe=y0(),Ht=J("fs"),GNe=fh(),rA=J("path"),_X=FX(),jX=SF(),YNe=MX(),qNe=vF(),$n=th(),JNe=nh(),WNe=CN(),GX=Symbol("onEntry"),IN=Symbol("checkFs"),YX=Symbol("checkFs2"),R0=Symbol("pruneCache"),yN=Symbol("isReusable"),Ds=Symbol("makeFs"),wN=Symbol("file"),BN=Symbol("directory"),F0=Symbol("link"),qX=Symbol("symlink"),JX=Symbol("hardlink"),WX=Symbol("unsupported"),zX=Symbol("checkPath"),gl=Symbol("mkdir"),Gi=Symbol("onError"),k0=Symbol("pending"),VX=Symbol("pend"),mh=Symbol("unpend"),mN=Symbol("ended"),EN=Symbol("maybeClose"),bN=Symbol("skip"),JC=Symbol("doChown"),WC=Symbol("uid"),zC=Symbol("gid"),VC=Symbol("checkedCwd"),$X=J("crypto"),eZ=HX(),zNe=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,XC=zNe==="win32",VNe=(r,e)=>{if(!XC)return Ht.unlink(r,e);let t=r+".DELETE."+$X.randomBytes(16).toString("hex");Ht.rename(r,t,i=>{if(i)return e(i);Ht.unlink(t,e)})},XNe=r=>{if(!XC)return Ht.unlinkSync(r);let e=r+".DELETE."+$X.randomBytes(16).toString("hex");Ht.renameSync(r,e),Ht.unlinkSync(e)},XX=(r,e,t)=>r===r>>>0?r:e===e>>>0?e:t,ZX=r=>WNe(JNe($n(r))).toLowerCase(),ZNe=(r,e)=>{e=ZX(e);for(let t of r.keys()){let i=ZX(t);(i===e||i.indexOf(e+"/")===0)&&r.delete(t)}},_Ne=r=>{for(let e of r.keys())r.delete(e)},ZC=class extends jNe{constructor(e){if(e||(e={}),e.ondone=t=>{this[mN]=!0,this[EN]()},super(e),this[VC]=!1,this.reservations=YNe(),this.transform=typeof e.transform=="function"?e.transform:null,this.writable=!0,this.readable=!1,this[k0]=0,this[mN]=!1,this.dirCache=e.dirCache||new Map,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=null,this.gid=null,this.setOwner=!1;e.preserveOwner===void 0&&typeof e.uid!="number"?this.preserveOwner=process.getuid&&process.getuid()===0:this.preserveOwner=!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():null,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():null,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||XC,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=$n(rA.resolve(e.cwd||process.cwd())),this.strip=+e.strip||0,this.processUmask=e.noChmod?0:process.umask(),this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",t=>this[GX](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[EN](){this[mN]&&this[k0]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close"))}[zX](e){if(this.strip){let t=$n(e.path).split("/");if(t.length<this.strip)return!1;if(e.path=t.slice(this.strip).join("/"),e.type==="Link"){let i=$n(e.linkpath).split("/");if(i.length>=this.strip)e.linkpath=i.slice(this.strip).join("/");else return!1}}if(!this.preservePaths){let t=$n(e.path),i=t.split("/");if(i.includes("..")||XC&&/^[a-z]:\.\.$/i.test(i[0]))return this.warn("TAR_ENTRY_ERROR","path contains '..'",{entry:e,path:t}),!1;let[n,s]=qNe(t);n&&(e.path=s,this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:e,path:t}))}if(rA.isAbsolute(e.path)?e.absolute=$n(rA.resolve(e.path)):e.absolute=$n(rA.resolve(this.cwd,e.path)),!this.preservePaths&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:$n(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:t}=rA.win32.parse(e.absolute);e.absolute=t+jX.encode(e.absolute.substr(t.length));let{root:i}=rA.win32.parse(e.path);e.path=i+jX.encode(e.path.substr(i.length))}return!0}[GX](e){if(!this[zX](e))return e.resume();switch(HNe.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[IN](e);case"CharacterDevice":case"BlockDevice":case"FIFO":default:return this[WX](e)}}[Gi](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[mh](),t.resume())}[gl](e,t,i){_X($n(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:t,noChmod:this.noChmod},i)}[JC](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[WC](e){return XX(this.uid,e.uid,this.processUid)}[zC](e){return XX(this.gid,e.gid,this.processGid)}[wN](e,t){let i=e.mode&4095||this.fmode,n=new GNe.WriteStream(e.absolute,{flags:eZ(e.size),mode:i,autoClose:!1});n.on("error",l=>{n.fd&&Ht.close(n.fd,()=>{}),n.write=()=>!0,this[Gi](l,e),t()});let s=1,o=l=>{if(l){n.fd&&Ht.close(n.fd,()=>{}),this[Gi](l,e),t();return}--s===0&&Ht.close(n.fd,c=>{c?this[Gi](c,e):this[mh](),t()})};n.on("finish",l=>{let c=e.absolute,u=n.fd;if(e.mtime&&!this.noMtime){s++;let g=e.atime||new Date,h=e.mtime;Ht.futimes(u,g,h,p=>p?Ht.utimes(c,g,h,d=>o(d&&p)):o())}if(this[JC](e)){s++;let g=this[WC](e),h=this[zC](e);Ht.fchown(u,g,h,p=>p?Ht.chown(c,g,h,d=>o(d&&p)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",l=>{this[Gi](l,e),t()}),e.pipe(a)),a.pipe(n)}[BN](e,t){let i=e.mode&4095||this.dmode;this[gl](e.absolute,i,n=>{if(n){this[Gi](n,e),t();return}let s=1,o=a=>{--s===0&&(t(),this[mh](),e.resume())};e.mtime&&!this.noMtime&&(s++,Ht.utimes(e.absolute,e.atime||new Date,e.mtime,o)),this[JC](e)&&(s++,Ht.chown(e.absolute,this[WC](e),this[zC](e),o)),o()})}[WX](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[qX](e,t){this[F0](e,e.linkpath,"symlink",t)}[JX](e,t){let i=$n(rA.resolve(this.cwd,e.linkpath));this[F0](e,i,"link",t)}[VX](){this[k0]++}[mh](){this[k0]--,this[EN]()}[bN](e){this[mh](),e.resume()}[yN](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&!XC}[IN](e){this[VX]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[YX](e,i))}[R0](e){e.type==="SymbolicLink"?_Ne(this.dirCache):e.type!=="Directory"&&ZNe(this.dirCache,e.absolute)}[YX](e,t){this[R0](e);let i=a=>{this[R0](e),t(a)},n=()=>{this[gl](this.cwd,this.dmode,a=>{if(a){this[Gi](a,e),i();return}this[VC]=!0,s()})},s=()=>{if(e.absolute!==this.cwd){let a=$n(rA.dirname(e.absolute));if(a!==this.cwd)return this[gl](a,this.dmode,l=>{if(l){this[Gi](l,e),i();return}o()})}o()},o=()=>{Ht.lstat(e.absolute,(a,l)=>{if(l&&(this.keep||this.newer&&l.mtime>e.mtime)){this[bN](e),i();return}if(a||this[yN](e,l))return this[Ds](null,e,i);if(l.isDirectory()){if(e.type==="Directory"){let c=!this.noChmod&&e.mode&&(l.mode&4095)!==e.mode,u=g=>this[Ds](g,e,i);return c?Ht.chmod(e.absolute,e.mode,u):u()}if(e.absolute!==this.cwd)return Ht.rmdir(e.absolute,c=>this[Ds](c,e,i))}if(e.absolute===this.cwd)return this[Ds](null,e,i);VNe(e.absolute,c=>this[Ds](c,e,i))})};this[VC]?s():n()}[Ds](e,t,i){if(e){this[Gi](e,t),i();return}switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[wN](t,i);case"Link":return this[JX](t,i);case"SymbolicLink":return this[qX](t,i);case"Directory":case"GNUDumpDir":return this[BN](t,i)}}[F0](e,t,i,n){Ht[i](t,e.absolute,s=>{s?this[Gi](s,e):(this[mh](),e.resume()),n()})}},D0=r=>{try{return[null,r()]}catch(e){return[e,null]}},QN=class extends ZC{[Ds](e,t){return super[Ds](e,t,()=>{})}[IN](e){if(this[R0](e),!this[VC]){let s=this[gl](this.cwd,this.dmode);if(s)return this[Gi](s,e);this[VC]=!0}if(e.absolute!==this.cwd){let s=$n(rA.dirname(e.absolute));if(s!==this.cwd){let o=this[gl](s,this.dmode);if(o)return this[Gi](o,e)}}let[t,i]=D0(()=>Ht.lstatSync(e.absolute));if(i&&(this.keep||this.newer&&i.mtime>e.mtime))return this[bN](e);if(t||this[yN](e,i))return this[Ds](null,e);if(i.isDirectory()){if(e.type==="Directory"){let o=!this.noChmod&&e.mode&&(i.mode&4095)!==e.mode,[a]=o?D0(()=>{Ht.chmodSync(e.absolute,e.mode)}):[];return this[Ds](a,e)}let[s]=D0(()=>Ht.rmdirSync(e.absolute));this[Ds](s,e)}let[n]=e.absolute===this.cwd?[]:D0(()=>XNe(e.absolute));this[Ds](n,e)}[wN](e,t){let i=e.mode&4095||this.fmode,n=a=>{let l;try{Ht.closeSync(s)}catch(c){l=c}(a||l)&&this[Gi](a||l,e),t()},s;try{s=Ht.openSync(e.absolute,eZ(e.size),i)}catch(a){return n(a)}let o=this.transform&&this.transform(e)||e;o!==e&&(o.on("error",a=>this[Gi](a,e)),e.pipe(o)),o.on("data",a=>{try{Ht.writeSync(s,a,0,a.length)}catch(l){n(l)}}),o.on("end",a=>{let l=null;if(e.mtime&&!this.noMtime){let c=e.atime||new Date,u=e.mtime;try{Ht.futimesSync(s,c,u)}catch(g){try{Ht.utimesSync(e.absolute,c,u)}catch{l=g}}}if(this[JC](e)){let c=this[WC](e),u=this[zC](e);try{Ht.fchownSync(s,c,u)}catch(g){try{Ht.chownSync(e.absolute,c,u)}catch{l=l||g}}}n(l)})}[BN](e,t){let i=e.mode&4095||this.dmode,n=this[gl](e.absolute,i);if(n){this[Gi](n,e),t();return}if(e.mtime&&!this.noMtime)try{Ht.utimesSync(e.absolute,e.atime||new Date,e.mtime)}catch{}if(this[JC](e))try{Ht.chownSync(e.absolute,this[WC](e),this[zC](e))}catch{}t(),e.resume()}[gl](e,t){try{return _X.sync($n(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cache:this.dirCache,cwd:this.cwd,mode:t})}catch(i){return i}}[F0](e,t,i,n){try{Ht[i+"Sync"](t,e.absolute),n(),e.resume()}catch(s){return this[Gi](s,e)}}};ZC.Sync=QN;tZ.exports=ZC});var oZ=I((Sat,sZ)=>{"use strict";var $Ne=Xf(),N0=SN(),iZ=J("fs"),nZ=fh(),rZ=J("path"),vN=nh();sZ.exports=(r,e,t)=>{typeof r=="function"?(t=r,e=null,r={}):Array.isArray(r)&&(e=r,r={}),typeof e=="function"&&(t=e,e=null),e?e=Array.from(e):e=[];let i=$Ne(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return e.length&&eTe(i,e),i.file&&i.sync?tTe(i):i.file?rTe(i,t):i.sync?iTe(i):nTe(i)};var eTe=(r,e)=>{let t=new Map(e.map(s=>[vN(s),!0])),i=r.filter,n=(s,o)=>{let a=o||rZ.parse(s).root||".",l=s===a?!1:t.has(s)?t.get(s):n(rZ.dirname(s),a);return t.set(s,l),l};r.filter=i?(s,o)=>i(s,o)&&n(vN(s)):s=>n(vN(s))},tTe=r=>{let e=new N0.Sync(r),t=r.file,i=iZ.statSync(t),n=r.maxReadSize||16*1024*1024;new nZ.ReadStreamSync(t,{readSize:n,size:i.size}).pipe(e)},rTe=(r,e)=>{let t=new N0(r),i=r.maxReadSize||16*1024*1024,n=r.file,s=new Promise((o,a)=>{t.on("error",a),t.on("close",o),iZ.stat(n,(l,c)=>{if(l)a(l);else{let u=new nZ.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(t)}})});return e?s.then(e,e):s},iTe=r=>new N0.Sync(r),nTe=r=>new N0(r)});var aZ=I(li=>{"use strict";li.c=li.create=j7();li.r=li.replace=AN();li.t=li.list=w0();li.u=li.update=Z7();li.x=li.extract=oZ();li.Pack=a0();li.Unpack=SN();li.Parse=y0();li.ReadEntry=YB();li.WriteEntry=OF();li.Header=ih();li.Pax=JB();li.types=EF()});var uZ=I((xat,cZ)=>{var PN;cZ.exports.getContent=()=>(typeof PN>"u"&&(PN=J("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),PN)});var CZ=I((xN,dZ)=>{(function(r,e){typeof xN=="object"?dZ.exports=e():typeof define=="function"&&define.amd?define(e):r.treeify=e()})(xN,function(){function r(n,s){var o=s?"\u2514":"\u251C";return n?o+="\u2500 ":o+="\u2500\u2500\u2510",o}function e(n,s){var o=[];for(var a in n)!n.hasOwnProperty(a)||s&&typeof n[a]=="function"||o.push(a);return o}function t(n,s,o,a,l,c,u){var g="",h=0,p,d,m=a.slice(0);if(m.push([s,o])&&a.length>0&&(a.forEach(function(B,S){S>0&&(g+=(B[1]?" ":"\u2502")+" "),!d&&B[0]===s&&(d=!0)}),g+=r(n,o)+n,l&&(typeof s!="object"||s instanceof Date)&&(g+=": "+s),d&&(g+=" (circular ref.)"),u(g)),!d&&typeof s=="object"){var y=e(s,c);y.forEach(function(B){p=++h===y.length,t(B,s[B],p,m,l,c,u)})}}var i={};return i.asLines=function(n,s,o,a){var l=typeof o!="function"?o:!1;t(".",n,!1,[],s,l,a||o)},i.asTree=function(n,s,o){var a="";return t(".",n,!1,[],s,o,function(l){a+=l+` +`}),a},i})});var M0=I((_at,vZ)=>{var wTe=Ss(),BTe=fC(),bTe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,QTe=/^\w*$/;function STe(r,e){if(wTe(r))return!1;var t=typeof r;return t=="number"||t=="symbol"||t=="boolean"||r==null||BTe(r)?!0:QTe.test(r)||!bTe.test(r)||e!=null&&r in Object(e)}vZ.exports=STe});var K0=I(($at,PZ)=>{var vTe=Tc(),PTe=vn(),xTe="[object AsyncFunction]",kTe="[object Function]",DTe="[object GeneratorFunction]",RTe="[object Proxy]";function FTe(r){if(!PTe(r))return!1;var e=vTe(r);return e==kTe||e==DTe||e==xTe||e==RTe}PZ.exports=FTe});var kZ=I((eAt,xZ)=>{var NTe=Is(),TTe=NTe["__core-js_shared__"];xZ.exports=TTe});var FZ=I((tAt,RZ)=>{var ON=kZ(),DZ=function(){var r=/[^.]+$/.exec(ON&&ON.keys&&ON.keys.IE_PROTO||"");return r?"Symbol(src)_1."+r:""}();function LTe(r){return!!DZ&&DZ in r}RZ.exports=LTe});var MN=I((rAt,NZ)=>{var OTe=Function.prototype,MTe=OTe.toString;function KTe(r){if(r!=null){try{return MTe.call(r)}catch{}try{return r+""}catch{}}return""}NZ.exports=KTe});var LZ=I((iAt,TZ)=>{var UTe=K0(),HTe=FZ(),jTe=vn(),GTe=MN(),YTe=/[\\^$.*+?()[\]{}|]/g,qTe=/^\[object .+?Constructor\]$/,JTe=Function.prototype,WTe=Object.prototype,zTe=JTe.toString,VTe=WTe.hasOwnProperty,XTe=RegExp("^"+zTe.call(VTe).replace(YTe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function ZTe(r){if(!jTe(r)||HTe(r))return!1;var e=UTe(r)?XTe:qTe;return e.test(GTe(r))}TZ.exports=ZTe});var MZ=I((nAt,OZ)=>{function _Te(r,e){return r==null?void 0:r[e]}OZ.exports=_Te});var hl=I((sAt,KZ)=>{var $Te=LZ(),eLe=MZ();function tLe(r,e){var t=eLe(r,e);return $Te(t)?t:void 0}KZ.exports=tLe});var $C=I((oAt,UZ)=>{var rLe=hl(),iLe=rLe(Object,"create");UZ.exports=iLe});var GZ=I((aAt,jZ)=>{var HZ=$C();function nLe(){this.__data__=HZ?HZ(null):{},this.size=0}jZ.exports=nLe});var qZ=I((AAt,YZ)=>{function sLe(r){var e=this.has(r)&&delete this.__data__[r];return this.size-=e?1:0,e}YZ.exports=sLe});var WZ=I((lAt,JZ)=>{var oLe=$C(),aLe="__lodash_hash_undefined__",ALe=Object.prototype,lLe=ALe.hasOwnProperty;function cLe(r){var e=this.__data__;if(oLe){var t=e[r];return t===aLe?void 0:t}return lLe.call(e,r)?e[r]:void 0}JZ.exports=cLe});var VZ=I((cAt,zZ)=>{var uLe=$C(),gLe=Object.prototype,fLe=gLe.hasOwnProperty;function hLe(r){var e=this.__data__;return uLe?e[r]!==void 0:fLe.call(e,r)}zZ.exports=hLe});var ZZ=I((uAt,XZ)=>{var pLe=$C(),dLe="__lodash_hash_undefined__";function CLe(r,e){var t=this.__data__;return this.size+=this.has(r)?0:1,t[r]=pLe&&e===void 0?dLe:e,this}XZ.exports=CLe});var $Z=I((gAt,_Z)=>{var mLe=GZ(),ELe=qZ(),ILe=WZ(),yLe=VZ(),wLe=ZZ();function Eh(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e<t;){var i=r[e];this.set(i[0],i[1])}}Eh.prototype.clear=mLe;Eh.prototype.delete=ELe;Eh.prototype.get=ILe;Eh.prototype.has=yLe;Eh.prototype.set=wLe;_Z.exports=Eh});var t_=I((fAt,e_)=>{function BLe(){this.__data__=[],this.size=0}e_.exports=BLe});var Ih=I((hAt,r_)=>{function bLe(r,e){return r===e||r!==r&&e!==e}r_.exports=bLe});var em=I((pAt,i_)=>{var QLe=Ih();function SLe(r,e){for(var t=r.length;t--;)if(QLe(r[t][0],e))return t;return-1}i_.exports=SLe});var s_=I((dAt,n_)=>{var vLe=em(),PLe=Array.prototype,xLe=PLe.splice;function kLe(r){var e=this.__data__,t=vLe(e,r);if(t<0)return!1;var i=e.length-1;return t==i?e.pop():xLe.call(e,t,1),--this.size,!0}n_.exports=kLe});var a_=I((CAt,o_)=>{var DLe=em();function RLe(r){var e=this.__data__,t=DLe(e,r);return t<0?void 0:e[t][1]}o_.exports=RLe});var l_=I((mAt,A_)=>{var FLe=em();function NLe(r){return FLe(this.__data__,r)>-1}A_.exports=NLe});var u_=I((EAt,c_)=>{var TLe=em();function LLe(r,e){var t=this.__data__,i=TLe(t,r);return i<0?(++this.size,t.push([r,e])):t[i][1]=e,this}c_.exports=LLe});var tm=I((IAt,g_)=>{var OLe=t_(),MLe=s_(),KLe=a_(),ULe=l_(),HLe=u_();function yh(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e<t;){var i=r[e];this.set(i[0],i[1])}}yh.prototype.clear=OLe;yh.prototype.delete=MLe;yh.prototype.get=KLe;yh.prototype.has=ULe;yh.prototype.set=HLe;g_.exports=yh});var U0=I((yAt,f_)=>{var jLe=hl(),GLe=Is(),YLe=jLe(GLe,"Map");f_.exports=YLe});var d_=I((wAt,p_)=>{var h_=$Z(),qLe=tm(),JLe=U0();function WLe(){this.size=0,this.__data__={hash:new h_,map:new(JLe||qLe),string:new h_}}p_.exports=WLe});var m_=I((BAt,C_)=>{function zLe(r){var e=typeof r;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?r!=="__proto__":r===null}C_.exports=zLe});var rm=I((bAt,E_)=>{var VLe=m_();function XLe(r,e){var t=r.__data__;return VLe(e)?t[typeof e=="string"?"string":"hash"]:t.map}E_.exports=XLe});var y_=I((QAt,I_)=>{var ZLe=rm();function _Le(r){var e=ZLe(this,r).delete(r);return this.size-=e?1:0,e}I_.exports=_Le});var B_=I((SAt,w_)=>{var $Le=rm();function eOe(r){return $Le(this,r).get(r)}w_.exports=eOe});var Q_=I((vAt,b_)=>{var tOe=rm();function rOe(r){return tOe(this,r).has(r)}b_.exports=rOe});var v_=I((PAt,S_)=>{var iOe=rm();function nOe(r,e){var t=iOe(this,r),i=t.size;return t.set(r,e),this.size+=t.size==i?0:1,this}S_.exports=nOe});var H0=I((xAt,P_)=>{var sOe=d_(),oOe=y_(),aOe=B_(),AOe=Q_(),lOe=v_();function wh(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e<t;){var i=r[e];this.set(i[0],i[1])}}wh.prototype.clear=sOe;wh.prototype.delete=oOe;wh.prototype.get=aOe;wh.prototype.has=AOe;wh.prototype.set=lOe;P_.exports=wh});var D_=I((kAt,k_)=>{var x_=H0(),cOe="Expected a function";function KN(r,e){if(typeof r!="function"||e!=null&&typeof e!="function")throw new TypeError(cOe);var t=function(){var i=arguments,n=e?e.apply(this,i):i[0],s=t.cache;if(s.has(n))return s.get(n);var o=r.apply(this,i);return t.cache=s.set(n,o)||s,o};return t.cache=new(KN.Cache||x_),t}KN.Cache=x_;k_.exports=KN});var F_=I((DAt,R_)=>{var uOe=D_(),gOe=500;function fOe(r){var e=uOe(r,function(i){return t.size===gOe&&t.clear(),i}),t=e.cache;return e}R_.exports=fOe});var T_=I((RAt,N_)=>{var hOe=F_(),pOe=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,dOe=/\\(\\)?/g,COe=hOe(function(r){var e=[];return r.charCodeAt(0)===46&&e.push(""),r.replace(pOe,function(t,i,n,s){e.push(n?s.replace(dOe,"$1"):i||t)}),e});N_.exports=COe});var Bh=I((FAt,L_)=>{var mOe=Ss(),EOe=M0(),IOe=T_(),yOe=Vf();function wOe(r,e){return mOe(r)?r:EOe(r,e)?[r]:IOe(yOe(r))}L_.exports=wOe});var $c=I((NAt,O_)=>{var BOe=fC(),bOe=1/0;function QOe(r){if(typeof r=="string"||BOe(r))return r;var e=r+"";return e=="0"&&1/r==-bOe?"-0":e}O_.exports=QOe});var im=I((TAt,M_)=>{var SOe=Bh(),vOe=$c();function POe(r,e){e=SOe(e,r);for(var t=0,i=e.length;r!=null&&t<i;)r=r[vOe(e[t++])];return t&&t==i?r:void 0}M_.exports=POe});var UN=I((LAt,K_)=>{var xOe=hl(),kOe=function(){try{var r=xOe(Object,"defineProperty");return r({},"",{}),r}catch{}}();K_.exports=kOe});var bh=I((OAt,H_)=>{var U_=UN();function DOe(r,e,t){e=="__proto__"&&U_?U_(r,e,{configurable:!0,enumerable:!0,value:t,writable:!0}):r[e]=t}H_.exports=DOe});var j0=I((MAt,j_)=>{var ROe=bh(),FOe=Ih(),NOe=Object.prototype,TOe=NOe.hasOwnProperty;function LOe(r,e,t){var i=r[e];(!(TOe.call(r,e)&&FOe(i,t))||t===void 0&&!(e in r))&&ROe(r,e,t)}j_.exports=LOe});var nm=I((KAt,G_)=>{var OOe=9007199254740991,MOe=/^(?:0|[1-9]\d*)$/;function KOe(r,e){var t=typeof r;return e=e==null?OOe:e,!!e&&(t=="number"||t!="symbol"&&MOe.test(r))&&r>-1&&r%1==0&&r<e}G_.exports=KOe});var HN=I((UAt,q_)=>{var UOe=j0(),HOe=Bh(),jOe=nm(),Y_=vn(),GOe=$c();function YOe(r,e,t,i){if(!Y_(r))return r;e=HOe(e,r);for(var n=-1,s=e.length,o=s-1,a=r;a!=null&&++n<s;){var l=GOe(e[n]),c=t;if(l==="__proto__"||l==="constructor"||l==="prototype")return r;if(n!=o){var u=a[l];c=i?i(u,l,a):void 0,c===void 0&&(c=Y_(u)?u:jOe(e[n+1])?[]:{})}UOe(a,l,c),a=a[l]}return r}q_.exports=YOe});var W_=I((HAt,J_)=>{var qOe=im(),JOe=HN(),WOe=Bh();function zOe(r,e,t){for(var i=-1,n=e.length,s={};++i<n;){var o=e[i],a=qOe(r,o);t(a,o)&&JOe(s,WOe(o,r),a)}return s}J_.exports=zOe});var V_=I((jAt,z_)=>{function VOe(r,e){return r!=null&&e in Object(r)}z_.exports=VOe});var Z_=I((GAt,X_)=>{var XOe=Tc(),ZOe=Jo(),_Oe="[object Arguments]";function $Oe(r){return ZOe(r)&&XOe(r)==_Oe}X_.exports=$Oe});var sm=I((YAt,e$)=>{var __=Z_(),eMe=Jo(),$_=Object.prototype,tMe=$_.hasOwnProperty,rMe=$_.propertyIsEnumerable,iMe=__(function(){return arguments}())?__:function(r){return eMe(r)&&tMe.call(r,"callee")&&!rMe.call(r,"callee")};e$.exports=iMe});var G0=I((qAt,t$)=>{var nMe=9007199254740991;function sMe(r){return typeof r=="number"&&r>-1&&r%1==0&&r<=nMe}t$.exports=sMe});var jN=I((JAt,r$)=>{var oMe=Bh(),aMe=sm(),AMe=Ss(),lMe=nm(),cMe=G0(),uMe=$c();function gMe(r,e,t){e=oMe(e,r);for(var i=-1,n=e.length,s=!1;++i<n;){var o=uMe(e[i]);if(!(s=r!=null&&t(r,o)))break;r=r[o]}return s||++i!=n?s:(n=r==null?0:r.length,!!n&&cMe(n)&&lMe(o,n)&&(AMe(r)||aMe(r)))}r$.exports=gMe});var GN=I((WAt,i$)=>{var fMe=V_(),hMe=jN();function pMe(r,e){return r!=null&&hMe(r,e,fMe)}i$.exports=pMe});var s$=I((zAt,n$)=>{var dMe=W_(),CMe=GN();function mMe(r,e){return dMe(r,e,function(t,i){return CMe(r,i)})}n$.exports=mMe});var Y0=I((VAt,o$)=>{function EMe(r,e){for(var t=-1,i=e.length,n=r.length;++t<i;)r[n+t]=e[t];return r}o$.exports=EMe});var c$=I((XAt,l$)=>{var a$=Nc(),IMe=sm(),yMe=Ss(),A$=a$?a$.isConcatSpreadable:void 0;function wMe(r){return yMe(r)||IMe(r)||!!(A$&&r&&r[A$])}l$.exports=wMe});var f$=I((ZAt,g$)=>{var BMe=Y0(),bMe=c$();function u$(r,e,t,i,n){var s=-1,o=r.length;for(t||(t=bMe),n||(n=[]);++s<o;){var a=r[s];e>0&&t(a)?e>1?u$(a,e-1,t,i,n):BMe(n,a):i||(n[n.length]=a)}return n}g$.exports=u$});var p$=I((_At,h$)=>{var QMe=f$();function SMe(r){var e=r==null?0:r.length;return e?QMe(r,1):[]}h$.exports=SMe});var C$=I(($At,d$)=>{function vMe(r,e,t){switch(t.length){case 0:return r.call(e);case 1:return r.call(e,t[0]);case 2:return r.call(e,t[0],t[1]);case 3:return r.call(e,t[0],t[1],t[2])}return r.apply(e,t)}d$.exports=vMe});var YN=I((elt,E$)=>{var PMe=C$(),m$=Math.max;function xMe(r,e,t){return e=m$(e===void 0?r.length-1:e,0),function(){for(var i=arguments,n=-1,s=m$(i.length-e,0),o=Array(s);++n<s;)o[n]=i[e+n];n=-1;for(var a=Array(e+1);++n<e;)a[n]=i[n];return a[e]=t(o),PMe(r,this,a)}}E$.exports=xMe});var y$=I((tlt,I$)=>{function kMe(r){return function(){return r}}I$.exports=kMe});var q0=I((rlt,w$)=>{function DMe(r){return r}w$.exports=DMe});var Q$=I((ilt,b$)=>{var RMe=y$(),B$=UN(),FMe=q0(),NMe=B$?function(r,e){return B$(r,"toString",{configurable:!0,enumerable:!1,value:RMe(e),writable:!0})}:FMe;b$.exports=NMe});var v$=I((nlt,S$)=>{var TMe=800,LMe=16,OMe=Date.now;function MMe(r){var e=0,t=0;return function(){var i=OMe(),n=LMe-(i-t);if(t=i,n>0){if(++e>=TMe)return arguments[0]}else e=0;return r.apply(void 0,arguments)}}S$.exports=MMe});var qN=I((slt,P$)=>{var KMe=Q$(),UMe=v$(),HMe=UMe(KMe);P$.exports=HMe});var k$=I((olt,x$)=>{var jMe=p$(),GMe=YN(),YMe=qN();function qMe(r){return YMe(GMe(r,void 0,jMe),r+"")}x$.exports=qMe});var R$=I((alt,D$)=>{var JMe=s$(),WMe=k$(),zMe=WMe(function(r,e){return r==null?{}:JMe(r,e)});D$.exports=zMe});var G$=I((kct,j$)=>{"use strict";var _N;try{_N=Map}catch{}var $N;try{$N=Set}catch{}function U$(r,e,t){if(!r||typeof r!="object"||typeof r=="function")return r;if(r.nodeType&&"cloneNode"in r)return r.cloneNode(!0);if(r instanceof Date)return new Date(r.getTime());if(r instanceof RegExp)return new RegExp(r);if(Array.isArray(r))return r.map(H$);if(_N&&r instanceof _N)return new Map(Array.from(r.entries()));if($N&&r instanceof $N)return new Set(Array.from(r.values()));if(r instanceof Object){e.push(r);var i=Object.create(r);t.push(i);for(var n in r){var s=e.findIndex(function(o){return o===r[n]});i[n]=s>-1?t[s]:U$(r[n],e,t)}return i}return r}function H$(r){return U$(r,[],[])}j$.exports=H$});var am=I(eT=>{"use strict";Object.defineProperty(eT,"__esModule",{value:!0});eT.default=l1e;var i1e=Object.prototype.toString,n1e=Error.prototype.toString,s1e=RegExp.prototype.toString,o1e=typeof Symbol<"u"?Symbol.prototype.toString:()=>"",a1e=/^Symbol\((.*)\)(.*)$/;function A1e(r){return r!=+r?"NaN":r===0&&1/r<0?"-0":""+r}function Y$(r,e=!1){if(r==null||r===!0||r===!1)return""+r;let t=typeof r;if(t==="number")return A1e(r);if(t==="string")return e?`"${r}"`:r;if(t==="function")return"[Function "+(r.name||"anonymous")+"]";if(t==="symbol")return o1e.call(r).replace(a1e,"Symbol($1)");let i=i1e.call(r).slice(8,-1);return i==="Date"?isNaN(r.getTime())?""+r:r.toISOString(r):i==="Error"||r instanceof Error?"["+n1e.call(r)+"]":i==="RegExp"?s1e.call(r):null}function l1e(r,e){let t=Y$(r,e);return t!==null?t:JSON.stringify(r,function(i,n){let s=Y$(this[i],e);return s!==null?s:n},2)}});var nA=I(mi=>{"use strict";Object.defineProperty(mi,"__esModule",{value:!0});mi.default=mi.array=mi.object=mi.boolean=mi.date=mi.number=mi.string=mi.mixed=void 0;var q$=c1e(am());function c1e(r){return r&&r.__esModule?r:{default:r}}var J$={default:"${path} is invalid",required:"${path} is a required field",oneOf:"${path} must be one of the following values: ${values}",notOneOf:"${path} must not be one of the following values: ${values}",notType:({path:r,type:e,value:t,originalValue:i})=>{let n=i!=null&&i!==t,s=`${r} must be a \`${e}\` type, but the final value was: \`${(0,q$.default)(t,!0)}\``+(n?` (cast from the value \`${(0,q$.default)(i,!0)}\`).`:".");return t===null&&(s+='\n If "null" is intended as an empty value be sure to mark the schema as `.nullable()`'),s},defined:"${path} must be defined"};mi.mixed=J$;var W$={length:"${path} must be exactly ${length} characters",min:"${path} must be at least ${min} characters",max:"${path} must be at most ${max} characters",matches:'${path} must match the following: "${regex}"',email:"${path} must be a valid email",url:"${path} must be a valid URL",uuid:"${path} must be a valid UUID",trim:"${path} must be a trimmed string",lowercase:"${path} must be a lowercase string",uppercase:"${path} must be a upper case string"};mi.string=W$;var z$={min:"${path} must be greater than or equal to ${min}",max:"${path} must be less than or equal to ${max}",lessThan:"${path} must be less than ${less}",moreThan:"${path} must be greater than ${more}",positive:"${path} must be a positive number",negative:"${path} must be a negative number",integer:"${path} must be an integer"};mi.number=z$;var V$={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"};mi.date=V$;var X$={isValue:"${path} field must be ${value}"};mi.boolean=X$;var Z$={noUnknown:"${path} field has unspecified keys: ${unknown}"};mi.object=Z$;var _$={min:"${path} field must have at least ${min} items",max:"${path} field must have less than or equal to ${max} items",length:"${path} must be have ${length} items"};mi.array=_$;var u1e=Object.assign(Object.create(null),{mixed:J$,string:W$,number:z$,date:V$,object:Z$,array:_$,boolean:X$});mi.default=u1e});var eee=I((Fct,$$)=>{var g1e=Object.prototype,f1e=g1e.hasOwnProperty;function h1e(r,e){return r!=null&&f1e.call(r,e)}$$.exports=h1e});var Am=I((Nct,tee)=>{var p1e=eee(),d1e=jN();function C1e(r,e){return r!=null&&d1e(r,e,p1e)}tee.exports=C1e});var Ph=I($0=>{"use strict";Object.defineProperty($0,"__esModule",{value:!0});$0.default=void 0;var m1e=r=>r&&r.__isYupSchema__;$0.default=m1e});var iee=I(eb=>{"use strict";Object.defineProperty(eb,"__esModule",{value:!0});eb.default=void 0;var E1e=ree(Am()),I1e=ree(Ph());function ree(r){return r&&r.__esModule?r:{default:r}}var tT=class{constructor(e,t){if(this.refs=e,this.refs=e,typeof t=="function"){this.fn=t;return}if(!(0,E1e.default)(t,"is"))throw new TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw new TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:i,then:n,otherwise:s}=t,o=typeof i=="function"?i:(...a)=>a.every(l=>l===i);this.fn=function(...a){let l=a.pop(),c=a.pop(),u=o(...a)?n:s;if(!!u)return typeof u=="function"?u(c):c.concat(u.resolve(l))}}resolve(e,t){let i=this.refs.map(s=>s.getValue(t==null?void 0:t.value,t==null?void 0:t.parent,t==null?void 0:t.context)),n=this.fn.apply(e,i.concat(e,t));if(n===void 0||n===e)return e;if(!(0,I1e.default)(n))throw new TypeError("conditions must return a schema object");return n.resolve(t)}},y1e=tT;eb.default=y1e});var iT=I(rT=>{"use strict";Object.defineProperty(rT,"__esModule",{value:!0});rT.default=w1e;function w1e(r){return r==null?[]:[].concat(r)}});var eu=I(tb=>{"use strict";Object.defineProperty(tb,"__esModule",{value:!0});tb.default=void 0;var B1e=nee(am()),b1e=nee(iT());function nee(r){return r&&r.__esModule?r:{default:r}}function nT(){return nT=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},nT.apply(this,arguments)}var Q1e=/\$\{\s*(\w+)\s*\}/g,xh=class extends Error{static formatError(e,t){let i=t.label||t.path||"this";return i!==t.path&&(t=nT({},t,{path:i})),typeof e=="string"?e.replace(Q1e,(n,s)=>(0,B1e.default)(t[s])):typeof e=="function"?e(t):e}static isError(e){return e&&e.name==="ValidationError"}constructor(e,t,i,n){super(),this.name="ValidationError",this.value=t,this.path=i,this.type=n,this.errors=[],this.inner=[],(0,b1e.default)(e).forEach(s=>{xh.isError(s)?(this.errors.push(...s.errors),this.inner=this.inner.concat(s.inner.length?s.inner:s)):this.errors.push(s)}),this.message=this.errors.length>1?`${this.errors.length} errors occurred`:this.errors[0],Error.captureStackTrace&&Error.captureStackTrace(this,xh)}};tb.default=xh});var rb=I(oT=>{"use strict";Object.defineProperty(oT,"__esModule",{value:!0});oT.default=P1e;var sT=S1e(eu());function S1e(r){return r&&r.__esModule?r:{default:r}}var v1e=r=>{let e=!1;return(...t)=>{e||(e=!0,r(...t))}};function P1e(r,e){let{endEarly:t,tests:i,args:n,value:s,errors:o,sort:a,path:l}=r,c=v1e(e),u=i.length,g=[];if(o=o||[],!u)return o.length?c(new sT.default(o,s,l)):c(null,s);for(let h=0;h<i.length;h++){let p=i[h];p(n,function(m){if(m){if(!sT.default.isError(m))return c(m,s);if(t)return m.value=s,c(m,s);g.push(m)}if(--u<=0){if(g.length&&(a&&g.sort(a),o.length&&g.push(...o),o=g),o.length){c(new sT.default(o,s,l),s);return}c(null,s)}})}}});var oee=I((Uct,see)=>{function x1e(r){return function(e,t,i){for(var n=-1,s=Object(e),o=i(e),a=o.length;a--;){var l=o[r?a:++n];if(t(s[l],l,s)===!1)break}return e}}see.exports=x1e});var aT=I((Hct,aee)=>{var k1e=oee(),D1e=k1e();aee.exports=D1e});var lee=I((jct,Aee)=>{function R1e(r,e){for(var t=-1,i=Array(r);++t<r;)i[t]=e(t);return i}Aee.exports=R1e});var uee=I((Gct,cee)=>{function F1e(){return!1}cee.exports=F1e});var cm=I((lm,kh)=>{var N1e=Is(),T1e=uee(),hee=typeof lm=="object"&&lm&&!lm.nodeType&&lm,gee=hee&&typeof kh=="object"&&kh&&!kh.nodeType&&kh,L1e=gee&&gee.exports===hee,fee=L1e?N1e.Buffer:void 0,O1e=fee?fee.isBuffer:void 0,M1e=O1e||T1e;kh.exports=M1e});var dee=I((Yct,pee)=>{var K1e=Tc(),U1e=G0(),H1e=Jo(),j1e="[object Arguments]",G1e="[object Array]",Y1e="[object Boolean]",q1e="[object Date]",J1e="[object Error]",W1e="[object Function]",z1e="[object Map]",V1e="[object Number]",X1e="[object Object]",Z1e="[object RegExp]",_1e="[object Set]",$1e="[object String]",eKe="[object WeakMap]",tKe="[object ArrayBuffer]",rKe="[object DataView]",iKe="[object Float32Array]",nKe="[object Float64Array]",sKe="[object Int8Array]",oKe="[object Int16Array]",aKe="[object Int32Array]",AKe="[object Uint8Array]",lKe="[object Uint8ClampedArray]",cKe="[object Uint16Array]",uKe="[object Uint32Array]",mr={};mr[iKe]=mr[nKe]=mr[sKe]=mr[oKe]=mr[aKe]=mr[AKe]=mr[lKe]=mr[cKe]=mr[uKe]=!0;mr[j1e]=mr[G1e]=mr[tKe]=mr[Y1e]=mr[rKe]=mr[q1e]=mr[J1e]=mr[W1e]=mr[z1e]=mr[V1e]=mr[X1e]=mr[Z1e]=mr[_1e]=mr[$1e]=mr[eKe]=!1;function gKe(r){return H1e(r)&&U1e(r.length)&&!!mr[K1e(r)]}pee.exports=gKe});var ib=I((qct,Cee)=>{function fKe(r){return function(e){return r(e)}}Cee.exports=fKe});var nb=I((um,Dh)=>{var hKe=Wk(),mee=typeof um=="object"&&um&&!um.nodeType&&um,gm=mee&&typeof Dh=="object"&&Dh&&!Dh.nodeType&&Dh,pKe=gm&&gm.exports===mee,AT=pKe&&hKe.process,dKe=function(){try{var r=gm&&gm.require&&gm.require("util").types;return r||AT&&AT.binding&&AT.binding("util")}catch{}}();Dh.exports=dKe});var sb=I((Jct,yee)=>{var CKe=dee(),mKe=ib(),Eee=nb(),Iee=Eee&&Eee.isTypedArray,EKe=Iee?mKe(Iee):CKe;yee.exports=EKe});var lT=I((Wct,wee)=>{var IKe=lee(),yKe=sm(),wKe=Ss(),BKe=cm(),bKe=nm(),QKe=sb(),SKe=Object.prototype,vKe=SKe.hasOwnProperty;function PKe(r,e){var t=wKe(r),i=!t&&yKe(r),n=!t&&!i&&BKe(r),s=!t&&!i&&!n&&QKe(r),o=t||i||n||s,a=o?IKe(r.length,String):[],l=a.length;for(var c in r)(e||vKe.call(r,c))&&!(o&&(c=="length"||n&&(c=="offset"||c=="parent")||s&&(c=="buffer"||c=="byteLength"||c=="byteOffset")||bKe(c,l)))&&a.push(c);return a}wee.exports=PKe});var ob=I((zct,Bee)=>{var xKe=Object.prototype;function kKe(r){var e=r&&r.constructor,t=typeof e=="function"&&e.prototype||xKe;return r===t}Bee.exports=kKe});var cT=I((Vct,bee)=>{function DKe(r,e){return function(t){return r(e(t))}}bee.exports=DKe});var See=I((Xct,Qee)=>{var RKe=cT(),FKe=RKe(Object.keys,Object);Qee.exports=FKe});var Pee=I((Zct,vee)=>{var NKe=ob(),TKe=See(),LKe=Object.prototype,OKe=LKe.hasOwnProperty;function MKe(r){if(!NKe(r))return TKe(r);var e=[];for(var t in Object(r))OKe.call(r,t)&&t!="constructor"&&e.push(t);return e}vee.exports=MKe});var fm=I((_ct,xee)=>{var KKe=K0(),UKe=G0();function HKe(r){return r!=null&&UKe(r.length)&&!KKe(r)}xee.exports=HKe});var Rh=I(($ct,kee)=>{var jKe=lT(),GKe=Pee(),YKe=fm();function qKe(r){return YKe(r)?jKe(r):GKe(r)}kee.exports=qKe});var uT=I((eut,Dee)=>{var JKe=aT(),WKe=Rh();function zKe(r,e){return r&&JKe(r,e,WKe)}Dee.exports=zKe});var Fee=I((tut,Ree)=>{var VKe=tm();function XKe(){this.__data__=new VKe,this.size=0}Ree.exports=XKe});var Tee=I((rut,Nee)=>{function ZKe(r){var e=this.__data__,t=e.delete(r);return this.size=e.size,t}Nee.exports=ZKe});var Oee=I((iut,Lee)=>{function _Ke(r){return this.__data__.get(r)}Lee.exports=_Ke});var Kee=I((nut,Mee)=>{function $Ke(r){return this.__data__.has(r)}Mee.exports=$Ke});var Hee=I((sut,Uee)=>{var eUe=tm(),tUe=U0(),rUe=H0(),iUe=200;function nUe(r,e){var t=this.__data__;if(t instanceof eUe){var i=t.__data__;if(!tUe||i.length<iUe-1)return i.push([r,e]),this.size=++t.size,this;t=this.__data__=new rUe(i)}return t.set(r,e),this.size=t.size,this}Uee.exports=nUe});var hm=I((out,jee)=>{var sUe=tm(),oUe=Fee(),aUe=Tee(),AUe=Oee(),lUe=Kee(),cUe=Hee();function Fh(r){var e=this.__data__=new sUe(r);this.size=e.size}Fh.prototype.clear=oUe;Fh.prototype.delete=aUe;Fh.prototype.get=AUe;Fh.prototype.has=lUe;Fh.prototype.set=cUe;jee.exports=Fh});var Yee=I((aut,Gee)=>{var uUe="__lodash_hash_undefined__";function gUe(r){return this.__data__.set(r,uUe),this}Gee.exports=gUe});var Jee=I((Aut,qee)=>{function fUe(r){return this.__data__.has(r)}qee.exports=fUe});var zee=I((lut,Wee)=>{var hUe=H0(),pUe=Yee(),dUe=Jee();function ab(r){var e=-1,t=r==null?0:r.length;for(this.__data__=new hUe;++e<t;)this.add(r[e])}ab.prototype.add=ab.prototype.push=pUe;ab.prototype.has=dUe;Wee.exports=ab});var Xee=I((cut,Vee)=>{function CUe(r,e){for(var t=-1,i=r==null?0:r.length;++t<i;)if(e(r[t],t,r))return!0;return!1}Vee.exports=CUe});var _ee=I((uut,Zee)=>{function mUe(r,e){return r.has(e)}Zee.exports=mUe});var gT=I((gut,$ee)=>{var EUe=zee(),IUe=Xee(),yUe=_ee(),wUe=1,BUe=2;function bUe(r,e,t,i,n,s){var o=t&wUe,a=r.length,l=e.length;if(a!=l&&!(o&&l>a))return!1;var c=s.get(r),u=s.get(e);if(c&&u)return c==e&&u==r;var g=-1,h=!0,p=t&BUe?new EUe:void 0;for(s.set(r,e),s.set(e,r);++g<a;){var d=r[g],m=e[g];if(i)var y=o?i(m,d,g,e,r,s):i(d,m,g,r,e,s);if(y!==void 0){if(y)continue;h=!1;break}if(p){if(!IUe(e,function(B,S){if(!yUe(p,S)&&(d===B||n(d,B,t,i,s)))return p.push(S)})){h=!1;break}}else if(!(d===m||n(d,m,t,i,s))){h=!1;break}}return s.delete(r),s.delete(e),h}$ee.exports=bUe});var fT=I((fut,ete)=>{var QUe=Is(),SUe=QUe.Uint8Array;ete.exports=SUe});var rte=I((hut,tte)=>{function vUe(r){var e=-1,t=Array(r.size);return r.forEach(function(i,n){t[++e]=[n,i]}),t}tte.exports=vUe});var nte=I((put,ite)=>{function PUe(r){var e=-1,t=Array(r.size);return r.forEach(function(i){t[++e]=i}),t}ite.exports=PUe});var lte=I((dut,Ate)=>{var ste=Nc(),ote=fT(),xUe=Ih(),kUe=gT(),DUe=rte(),RUe=nte(),FUe=1,NUe=2,TUe="[object Boolean]",LUe="[object Date]",OUe="[object Error]",MUe="[object Map]",KUe="[object Number]",UUe="[object RegExp]",HUe="[object Set]",jUe="[object String]",GUe="[object Symbol]",YUe="[object ArrayBuffer]",qUe="[object DataView]",ate=ste?ste.prototype:void 0,hT=ate?ate.valueOf:void 0;function JUe(r,e,t,i,n,s,o){switch(t){case qUe:if(r.byteLength!=e.byteLength||r.byteOffset!=e.byteOffset)return!1;r=r.buffer,e=e.buffer;case YUe:return!(r.byteLength!=e.byteLength||!s(new ote(r),new ote(e)));case TUe:case LUe:case KUe:return xUe(+r,+e);case OUe:return r.name==e.name&&r.message==e.message;case UUe:case jUe:return r==e+"";case MUe:var a=DUe;case HUe:var l=i&FUe;if(a||(a=RUe),r.size!=e.size&&!l)return!1;var c=o.get(r);if(c)return c==e;i|=NUe,o.set(r,e);var u=kUe(a(r),a(e),i,n,s,o);return o.delete(r),u;case GUe:if(hT)return hT.call(r)==hT.call(e)}return!1}Ate.exports=JUe});var pT=I((Cut,cte)=>{var WUe=Y0(),zUe=Ss();function VUe(r,e,t){var i=e(r);return zUe(r)?i:WUe(i,t(r))}cte.exports=VUe});var gte=I((mut,ute)=>{function XUe(r,e){for(var t=-1,i=r==null?0:r.length,n=0,s=[];++t<i;){var o=r[t];e(o,t,r)&&(s[n++]=o)}return s}ute.exports=XUe});var dT=I((Eut,fte)=>{function ZUe(){return[]}fte.exports=ZUe});var Ab=I((Iut,pte)=>{var _Ue=gte(),$Ue=dT(),e2e=Object.prototype,t2e=e2e.propertyIsEnumerable,hte=Object.getOwnPropertySymbols,r2e=hte?function(r){return r==null?[]:(r=Object(r),_Ue(hte(r),function(e){return t2e.call(r,e)}))}:$Ue;pte.exports=r2e});var CT=I((yut,dte)=>{var i2e=pT(),n2e=Ab(),s2e=Rh();function o2e(r){return i2e(r,s2e,n2e)}dte.exports=o2e});var Ete=I((wut,mte)=>{var Cte=CT(),a2e=1,A2e=Object.prototype,l2e=A2e.hasOwnProperty;function c2e(r,e,t,i,n,s){var o=t&a2e,a=Cte(r),l=a.length,c=Cte(e),u=c.length;if(l!=u&&!o)return!1;for(var g=l;g--;){var h=a[g];if(!(o?h in e:l2e.call(e,h)))return!1}var p=s.get(r),d=s.get(e);if(p&&d)return p==e&&d==r;var m=!0;s.set(r,e),s.set(e,r);for(var y=o;++g<l;){h=a[g];var B=r[h],S=e[h];if(i)var x=o?i(S,B,h,e,r,s):i(B,S,h,r,e,s);if(!(x===void 0?B===S||n(B,S,t,i,s):x)){m=!1;break}y||(y=h=="constructor")}if(m&&!y){var F=r.constructor,H=e.constructor;F!=H&&"constructor"in r&&"constructor"in e&&!(typeof F=="function"&&F instanceof F&&typeof H=="function"&&H instanceof H)&&(m=!1)}return s.delete(r),s.delete(e),m}mte.exports=c2e});var yte=I((But,Ite)=>{var u2e=hl(),g2e=Is(),f2e=u2e(g2e,"DataView");Ite.exports=f2e});var Bte=I((but,wte)=>{var h2e=hl(),p2e=Is(),d2e=h2e(p2e,"Promise");wte.exports=d2e});var Qte=I((Qut,bte)=>{var C2e=hl(),m2e=Is(),E2e=C2e(m2e,"Set");bte.exports=E2e});var vte=I((Sut,Ste)=>{var I2e=hl(),y2e=Is(),w2e=I2e(y2e,"WeakMap");Ste.exports=w2e});var pm=I((vut,Nte)=>{var mT=yte(),ET=U0(),IT=Bte(),yT=Qte(),wT=vte(),Fte=Tc(),Nh=MN(),Pte="[object Map]",B2e="[object Object]",xte="[object Promise]",kte="[object Set]",Dte="[object WeakMap]",Rte="[object DataView]",b2e=Nh(mT),Q2e=Nh(ET),S2e=Nh(IT),v2e=Nh(yT),P2e=Nh(wT),tu=Fte;(mT&&tu(new mT(new ArrayBuffer(1)))!=Rte||ET&&tu(new ET)!=Pte||IT&&tu(IT.resolve())!=xte||yT&&tu(new yT)!=kte||wT&&tu(new wT)!=Dte)&&(tu=function(r){var e=Fte(r),t=e==B2e?r.constructor:void 0,i=t?Nh(t):"";if(i)switch(i){case b2e:return Rte;case Q2e:return Pte;case S2e:return xte;case v2e:return kte;case P2e:return Dte}return e});Nte.exports=tu});var jte=I((Put,Hte)=>{var BT=hm(),x2e=gT(),k2e=lte(),D2e=Ete(),Tte=pm(),Lte=Ss(),Ote=cm(),R2e=sb(),F2e=1,Mte="[object Arguments]",Kte="[object Array]",lb="[object Object]",N2e=Object.prototype,Ute=N2e.hasOwnProperty;function T2e(r,e,t,i,n,s){var o=Lte(r),a=Lte(e),l=o?Kte:Tte(r),c=a?Kte:Tte(e);l=l==Mte?lb:l,c=c==Mte?lb:c;var u=l==lb,g=c==lb,h=l==c;if(h&&Ote(r)){if(!Ote(e))return!1;o=!0,u=!1}if(h&&!u)return s||(s=new BT),o||R2e(r)?x2e(r,e,t,i,n,s):k2e(r,e,l,t,i,n,s);if(!(t&F2e)){var p=u&&Ute.call(r,"__wrapped__"),d=g&&Ute.call(e,"__wrapped__");if(p||d){var m=p?r.value():r,y=d?e.value():e;return s||(s=new BT),n(m,y,t,i,s)}}return h?(s||(s=new BT),D2e(r,e,t,i,n,s)):!1}Hte.exports=T2e});var bT=I((xut,qte)=>{var L2e=jte(),Gte=Jo();function Yte(r,e,t,i,n){return r===e?!0:r==null||e==null||!Gte(r)&&!Gte(e)?r!==r&&e!==e:L2e(r,e,t,i,Yte,n)}qte.exports=Yte});var Wte=I((kut,Jte)=>{var O2e=hm(),M2e=bT(),K2e=1,U2e=2;function H2e(r,e,t,i){var n=t.length,s=n,o=!i;if(r==null)return!s;for(r=Object(r);n--;){var a=t[n];if(o&&a[2]?a[1]!==r[a[0]]:!(a[0]in r))return!1}for(;++n<s;){a=t[n];var l=a[0],c=r[l],u=a[1];if(o&&a[2]){if(c===void 0&&!(l in r))return!1}else{var g=new O2e;if(i)var h=i(c,u,l,r,e,g);if(!(h===void 0?M2e(u,c,K2e|U2e,i,g):h))return!1}}return!0}Jte.exports=H2e});var QT=I((Dut,zte)=>{var j2e=vn();function G2e(r){return r===r&&!j2e(r)}zte.exports=G2e});var Xte=I((Rut,Vte)=>{var Y2e=QT(),q2e=Rh();function J2e(r){for(var e=q2e(r),t=e.length;t--;){var i=e[t],n=r[i];e[t]=[i,n,Y2e(n)]}return e}Vte.exports=J2e});var ST=I((Fut,Zte)=>{function W2e(r,e){return function(t){return t==null?!1:t[r]===e&&(e!==void 0||r in Object(t))}}Zte.exports=W2e});var $te=I((Nut,_te)=>{var z2e=Wte(),V2e=Xte(),X2e=ST();function Z2e(r){var e=V2e(r);return e.length==1&&e[0][2]?X2e(e[0][0],e[0][1]):function(t){return t===r||z2e(t,r,e)}}_te.exports=Z2e});var cb=I((Tut,ere)=>{var _2e=im();function $2e(r,e,t){var i=r==null?void 0:_2e(r,e);return i===void 0?t:i}ere.exports=$2e});var rre=I((Lut,tre)=>{var eHe=bT(),tHe=cb(),rHe=GN(),iHe=M0(),nHe=QT(),sHe=ST(),oHe=$c(),aHe=1,AHe=2;function lHe(r,e){return iHe(r)&&nHe(e)?sHe(oHe(r),e):function(t){var i=tHe(t,r);return i===void 0&&i===e?rHe(t,r):eHe(e,i,aHe|AHe)}}tre.exports=lHe});var nre=I((Out,ire)=>{function cHe(r){return function(e){return e==null?void 0:e[r]}}ire.exports=cHe});var ore=I((Mut,sre)=>{var uHe=im();function gHe(r){return function(e){return uHe(e,r)}}sre.exports=gHe});var Are=I((Kut,are)=>{var fHe=nre(),hHe=ore(),pHe=M0(),dHe=$c();function CHe(r){return pHe(r)?fHe(dHe(r)):hHe(r)}are.exports=CHe});var vT=I((Uut,lre)=>{var mHe=$te(),EHe=rre(),IHe=q0(),yHe=Ss(),wHe=Are();function BHe(r){return typeof r=="function"?r:r==null?IHe:typeof r=="object"?yHe(r)?EHe(r[0],r[1]):mHe(r):wHe(r)}lre.exports=BHe});var PT=I((Hut,cre)=>{var bHe=bh(),QHe=uT(),SHe=vT();function vHe(r,e){var t={};return e=SHe(e,3),QHe(r,function(i,n,s){bHe(t,n,e(i,n,s))}),t}cre.exports=vHe});var dm=I((jut,pre)=>{"use strict";function ru(r){this._maxSize=r,this.clear()}ru.prototype.clear=function(){this._size=0,this._values=Object.create(null)};ru.prototype.get=function(r){return this._values[r]};ru.prototype.set=function(r,e){return this._size>=this._maxSize&&this.clear(),r in this._values||this._size++,this._values[r]=e};var PHe=/[^.^\]^[]+|(?=\[\]|\.\.)/g,hre=/^\d+$/,xHe=/^\d/,kHe=/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,DHe=/^\s*(['"]?)(.*?)(\1)\s*$/,DT=512,ure=new ru(DT),gre=new ru(DT),fre=new ru(DT);pre.exports={Cache:ru,split:kT,normalizePath:xT,setter:function(r){var e=xT(r);return gre.get(r)||gre.set(r,function(i,n){for(var s=0,o=e.length,a=i;s<o-1;){var l=e[s];if(l==="__proto__"||l==="constructor"||l==="prototype")return i;a=a[e[s++]]}a[e[s]]=n})},getter:function(r,e){var t=xT(r);return fre.get(r)||fre.set(r,function(n){for(var s=0,o=t.length;s<o;)if(n!=null||!e)n=n[t[s++]];else return;return n})},join:function(r){return r.reduce(function(e,t){return e+(RT(t)||hre.test(t)?"["+t+"]":(e?".":"")+t)},"")},forEach:function(r,e,t){RHe(Array.isArray(r)?r:kT(r),e,t)}};function xT(r){return ure.get(r)||ure.set(r,kT(r).map(function(e){return e.replace(DHe,"$2")}))}function kT(r){return r.match(PHe)}function RHe(r,e,t){var i=r.length,n,s,o,a;for(s=0;s<i;s++)n=r[s],n&&(THe(n)&&(n='"'+n+'"'),a=RT(n),o=!a&&/^\d+$/.test(n),e.call(t,n,a,o,s,r))}function RT(r){return typeof r=="string"&&r&&["'",'"'].indexOf(r.charAt(0))!==-1}function FHe(r){return r.match(xHe)&&!r.match(hre)}function NHe(r){return kHe.test(r)}function THe(r){return!RT(r)&&(FHe(r)||NHe(r))}});var iu=I(mm=>{"use strict";Object.defineProperty(mm,"__esModule",{value:!0});mm.create=OHe;mm.default=void 0;var LHe=dm(),ub={context:"$",value:"."};function OHe(r,e){return new Cm(r,e)}var Cm=class{constructor(e,t={}){if(typeof e!="string")throw new TypeError("ref must be a string, got: "+e);if(this.key=e.trim(),e==="")throw new TypeError("ref must be a non-empty string");this.isContext=this.key[0]===ub.context,this.isValue=this.key[0]===ub.value,this.isSibling=!this.isContext&&!this.isValue;let i=this.isContext?ub.context:this.isValue?ub.value:"";this.path=this.key.slice(i.length),this.getter=this.path&&(0,LHe.getter)(this.path,!0),this.map=t.map}getValue(e,t,i){let n=this.isContext?i:this.isValue?e:t;return this.getter&&(n=this.getter(n||{})),this.map&&(n=this.map(n)),n}cast(e,t){return this.getValue(e,t==null?void 0:t.parent,t==null?void 0:t.context)}resolve(){return this}describe(){return{type:"ref",key:this.key}}toString(){return`Ref(${this.key})`}static isRef(e){return e&&e.__isYupRef}};mm.default=Cm;Cm.prototype.__isYupRef=!0});var dre=I(NT=>{"use strict";Object.defineProperty(NT,"__esModule",{value:!0});NT.default=HHe;var MHe=FT(PT()),gb=FT(eu()),KHe=FT(iu());function FT(r){return r&&r.__esModule?r:{default:r}}function fb(){return fb=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},fb.apply(this,arguments)}function UHe(r,e){if(r==null)return{};var t={},i=Object.keys(r),n,s;for(s=0;s<i.length;s++)n=i[s],!(e.indexOf(n)>=0)&&(t[n]=r[n]);return t}function HHe(r){function e(t,i){let{value:n,path:s="",label:o,options:a,originalValue:l,sync:c}=t,u=UHe(t,["value","path","label","options","originalValue","sync"]),{name:g,test:h,params:p,message:d}=r,{parent:m,context:y}=a;function B(q){return KHe.default.isRef(q)?q.getValue(n,m,y):q}function S(q={}){let _=(0,MHe.default)(fb({value:n,originalValue:l,label:o,path:q.path||s},p,q.params),B),X=new gb.default(gb.default.formatError(q.message||d,_),n,_.path,q.type||g);return X.params=_,X}let x=fb({path:s,parent:m,type:g,createError:S,resolve:B,options:a,originalValue:l},u);if(!c){try{Promise.resolve(h.call(x,n,x)).then(q=>{gb.default.isError(q)?i(q):q?i(null,q):i(S())})}catch(q){i(q)}return}let F;try{var H;if(F=h.call(x,n,x),typeof((H=F)==null?void 0:H.then)=="function")throw new Error(`Validation test of type: "${x.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(q){i(q);return}gb.default.isError(F)?i(F):F?i(null,F):i(S())}return e.OPTIONS=r,e}});var TT=I(Em=>{"use strict";Object.defineProperty(Em,"__esModule",{value:!0});Em.getIn=Cre;Em.default=void 0;var jHe=dm(),GHe=r=>r.substr(0,r.length-1).substr(1);function Cre(r,e,t,i=t){let n,s,o;return e?((0,jHe.forEach)(e,(a,l,c)=>{let u=l?GHe(a):a;if(r=r.resolve({context:i,parent:n,value:t}),r.innerType){let g=c?parseInt(u,10):0;if(t&&g>=t.length)throw new Error(`Yup.reach cannot resolve an array item at index: ${a}, in the path: ${e}. because there is no value at that index. `);n=t,t=t&&t[g],r=r.innerType}if(!c){if(!r.fields||!r.fields[u])throw new Error(`The schema does not contain the path: ${e}. (failed at: ${o} which is a type: "${r._type}")`);n=t,t=t&&t[u],r=r.fields[u]}s=u,o=l?"["+a+"]":"."+a}),{schema:r,parent:n,parentPath:s}):{parent:n,parentPath:e,schema:r}}var YHe=(r,e,t,i)=>Cre(r,e,t,i).schema,qHe=YHe;Em.default=qHe});var Ere=I(hb=>{"use strict";Object.defineProperty(hb,"__esModule",{value:!0});hb.default=void 0;var mre=JHe(iu());function JHe(r){return r&&r.__esModule?r:{default:r}}var Im=class{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,t]of this.refs)e.push(t.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){mre.default.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){mre.default.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let i,n=this.refs.values();for(;i=n.next(),!i.done;)if(t(i.value)===e)return!0;return!1}clone(){let e=new Im;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let i=this.clone();return e.list.forEach(n=>i.add(n)),e.refs.forEach(n=>i.add(n)),t.list.forEach(n=>i.delete(n)),t.refs.forEach(n=>i.delete(n)),i}};hb.default=Im});var oA=I(db=>{"use strict";Object.defineProperty(db,"__esModule",{value:!0});db.default=void 0;var Ire=sA(G$()),Th=nA(),WHe=sA(iee()),yre=sA(rb()),pb=sA(dre()),wre=sA(am()),zHe=sA(iu()),VHe=TT(),XHe=sA(iT()),Bre=sA(eu()),bre=sA(Ere());function sA(r){return r&&r.__esModule?r:{default:r}}function Rs(){return Rs=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},Rs.apply(this,arguments)}var co=class{constructor(e){this.deps=[],this.conditions=[],this._whitelist=new bre.default,this._blacklist=new bre.default,this.exclusiveTests=Object.create(null),this.tests=[],this.transforms=[],this.withMutation(()=>{this.typeError(Th.mixed.notType)}),this.type=(e==null?void 0:e.type)||"mixed",this.spec=Rs({strip:!1,strict:!1,abortEarly:!0,recursive:!0,nullable:!1,presence:"optional"},e==null?void 0:e.spec)}get _type(){return this.type}_typeCheck(e){return!0}clone(e){if(this._mutate)return e&&Object.assign(this.spec,e),this;let t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=Rs({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=(0,Ire.default)(Rs({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(e.length===0)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let i=e(this);return this._mutate=t,i}concat(e){if(!e||e===this)return this;if(e.type!==this.type&&this.type!=="mixed")throw new TypeError(`You cannot \`concat()\` schema's of different types: ${this.type} and ${e.type}`);let t=this,i=e.clone(),n=Rs({},t.spec,i.spec);return i.spec=n,i._typeError||(i._typeError=t._typeError),i._whitelistError||(i._whitelistError=t._whitelistError),i._blacklistError||(i._blacklistError=t._blacklistError),i._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),i._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),i.tests=t.tests,i.exclusiveTests=t.exclusiveTests,i.withMutation(s=>{e.tests.forEach(o=>{s.test(o.OPTIONS)})}),i}isType(e){return this.spec.nullable&&e===null?!0:this._typeCheck(e)}resolve(e){let t=this;if(t.conditions.length){let i=t.conditions;t=t.clone(),t.conditions=[],t=i.reduce((n,s)=>s.resolve(n,e),t),t=t.resolve(e)}return t}cast(e,t={}){let i=this.resolve(Rs({value:e},t)),n=i._cast(e,t);if(e!==void 0&&t.assert!==!1&&i.isType(n)!==!0){let s=(0,wre.default)(e),o=(0,wre.default)(n);throw new TypeError(`The value of ${t.path||"field"} could not be cast to a value that satisfies the schema type: "${i._type}". + +attempted value: ${s} +`+(o!==s?`result of cast: ${o}`:""))}return n}_cast(e,t){let i=e===void 0?e:this.transforms.reduce((n,s)=>s.call(this,n,e,this),e);return i===void 0&&(i=this.getDefault()),i}_validate(e,t={},i){let{sync:n,path:s,from:o=[],originalValue:a=e,strict:l=this.spec.strict,abortEarly:c=this.spec.abortEarly}=t,u=e;l||(u=this._cast(u,Rs({assert:!1},t)));let g={value:u,path:s,options:t,originalValue:a,schema:this,label:this.spec.label,sync:n,from:o},h=[];this._typeError&&h.push(this._typeError),this._whitelistError&&h.push(this._whitelistError),this._blacklistError&&h.push(this._blacklistError),(0,yre.default)({args:g,value:u,path:s,sync:n,tests:h,endEarly:c},p=>{if(p)return void i(p,u);(0,yre.default)({tests:this.tests,args:g,path:s,sync:n,value:u,endEarly:c},i)})}validate(e,t,i){let n=this.resolve(Rs({},t,{value:e}));return typeof i=="function"?n._validate(e,t,i):new Promise((s,o)=>n._validate(e,t,(a,l)=>{a?o(a):s(l)}))}validateSync(e,t){let i=this.resolve(Rs({},t,{value:e})),n;return i._validate(e,Rs({},t,{sync:!0}),(s,o)=>{if(s)throw s;n=o}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,i=>{if(Bre.default.isError(i))return!1;throw i})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(i){if(Bre.default.isError(i))return!1;throw i}}_getDefault(){let e=this.spec.default;return e==null?e:typeof e=="function"?e.call(this):(0,Ire.default)(e)}getDefault(e){return this.resolve(e||{})._getDefault()}default(e){return arguments.length===0?this._getDefault():this.clone({default:e})}strict(e=!0){var t=this.clone();return t.spec.strict=e,t}_isPresent(e){return e!=null}defined(e=Th.mixed.defined){return this.test({message:e,name:"defined",exclusive:!0,test(t){return t!==void 0}})}required(e=Th.mixed.required){return this.clone({presence:"required"}).withMutation(t=>t.test({message:e,name:"required",exclusive:!0,test(i){return this.schema._isPresent(i)}}))}notRequired(){var e=this.clone({presence:"optional"});return e.tests=e.tests.filter(t=>t.OPTIONS.name!=="required"),e}nullable(e=!0){var t=this.clone({nullable:e!==!1});return t}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(e.length===1?typeof e[0]=="function"?t={test:e[0]}:t=e[0]:e.length===2?t={name:e[0],test:e[1]}:t={name:e[0],message:e[1],test:e[2]},t.message===void 0&&(t.message=Th.mixed.default),typeof t.test!="function")throw new TypeError("`test` is a required parameters");let i=this.clone(),n=(0,pb.default)(t),s=t.exclusive||t.name&&i.exclusiveTests[t.name]===!0;if(t.exclusive&&!t.name)throw new TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(i.exclusiveTests[t.name]=!!t.exclusive),i.tests=i.tests.filter(o=>!(o.OPTIONS.name===t.name&&(s||o.OPTIONS.test===n.OPTIONS.test))),i.tests.push(n),i}when(e,t){!Array.isArray(e)&&typeof e!="string"&&(t=e,e=".");let i=this.clone(),n=(0,XHe.default)(e).map(s=>new zHe.default(s));return n.forEach(s=>{s.isSibling&&i.deps.push(s.key)}),i.conditions.push(new WHe.default(n,t)),i}typeError(e){var t=this.clone();return t._typeError=(0,pb.default)({message:e,name:"typeError",test(i){return i!==void 0&&!this.schema.isType(i)?this.createError({params:{type:this.schema._type}}):!0}}),t}oneOf(e,t=Th.mixed.oneOf){var i=this.clone();return e.forEach(n=>{i._whitelist.add(n),i._blacklist.delete(n)}),i._whitelistError=(0,pb.default)({message:t,name:"oneOf",test(n){if(n===void 0)return!0;let s=this.schema._whitelist;return s.has(n,this.resolve)?!0:this.createError({params:{values:s.toArray().join(", ")}})}}),i}notOneOf(e,t=Th.mixed.notOneOf){var i=this.clone();return e.forEach(n=>{i._blacklist.add(n),i._whitelist.delete(n)}),i._blacklistError=(0,pb.default)({message:t,name:"notOneOf",test(n){let s=this.schema._blacklist;return s.has(n,this.resolve)?this.createError({params:{values:s.toArray().join(", ")}}):!0}}),i}strip(e=!0){let t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:i}=e.spec;return{meta:i,label:t,type:e.type,oneOf:e._whitelist.describe(),notOneOf:e._blacklist.describe(),tests:e.tests.map(s=>({name:s.OPTIONS.name,params:s.OPTIONS.params})).filter((s,o,a)=>a.findIndex(l=>l.name===s.name)===o)}}};db.default=co;co.prototype.__isYupSchema__=!0;for(let r of["validate","validateSync"])co.prototype[`${r}At`]=function(e,t,i={}){let{parent:n,parentPath:s,schema:o}=(0,VHe.getIn)(this,e,t,i.context);return o[r](n&&n[s],Rs({},i,{parent:n,path:e}))};for(let r of["equals","is"])co.prototype[r]=co.prototype.oneOf;for(let r of["not","nope"])co.prototype[r]=co.prototype.notOneOf;co.prototype.optional=co.prototype.notRequired});var Sre=I(ym=>{"use strict";Object.defineProperty(ym,"__esModule",{value:!0});ym.create=Qre;ym.default=void 0;var ZHe=_He(oA());function _He(r){return r&&r.__esModule?r:{default:r}}var LT=ZHe.default,$He=LT;ym.default=$He;function Qre(){return new LT}Qre.prototype=LT.prototype});var Lh=I(Cb=>{"use strict";Object.defineProperty(Cb,"__esModule",{value:!0});Cb.default=void 0;var eje=r=>r==null;Cb.default=eje});var Dre=I(Bm=>{"use strict";Object.defineProperty(Bm,"__esModule",{value:!0});Bm.create=kre;Bm.default=void 0;var tje=xre(oA()),vre=nA(),Pre=xre(Lh());function xre(r){return r&&r.__esModule?r:{default:r}}function kre(){return new wm}var wm=class extends tje.default{constructor(){super({type:"boolean"}),this.withMutation(()=>{this.transform(function(e){if(!this.isType(e)){if(/^(true|1)$/i.test(String(e)))return!0;if(/^(false|0)$/i.test(String(e)))return!1}return e})})}_typeCheck(e){return e instanceof Boolean&&(e=e.valueOf()),typeof e=="boolean"}isTrue(e=vre.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test(t){return(0,Pre.default)(t)||t===!0}})}isFalse(e=vre.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test(t){return(0,Pre.default)(t)||t===!1}})}};Bm.default=wm;kre.prototype=wm.prototype});var Nre=I(Qm=>{"use strict";Object.defineProperty(Qm,"__esModule",{value:!0});Qm.create=Fre;Qm.default=void 0;var ra=nA(),aA=Rre(Lh()),rje=Rre(oA());function Rre(r){return r&&r.__esModule?r:{default:r}}var ije=/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,nje=/^((https?|ftp):)?\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,sje=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,oje=r=>(0,aA.default)(r)||r===r.trim(),aje={}.toString();function Fre(){return new bm}var bm=class extends rje.default{constructor(){super({type:"string"}),this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=e!=null&&e.toString?e.toString():e;return t===aje?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),typeof e=="string"}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=ra.string.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(i){return(0,aA.default)(i)||i.length===this.resolve(e)}})}min(e,t=ra.string.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,aA.default)(i)||i.length>=this.resolve(e)}})}max(e,t=ra.string.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(i){return(0,aA.default)(i)||i.length<=this.resolve(e)}})}matches(e,t){let i=!1,n,s;return t&&(typeof t=="object"?{excludeEmptyString:i=!1,message:n,name:s}=t:n=t),this.test({name:s||"matches",message:n||ra.string.matches,params:{regex:e},test:o=>(0,aA.default)(o)||o===""&&i||o.search(e)!==-1})}email(e=ra.string.email){return this.matches(ije,{name:"email",message:e,excludeEmptyString:!0})}url(e=ra.string.url){return this.matches(nje,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=ra.string.uuid){return this.matches(sje,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>e===null?"":e)}trim(e=ra.string.trim){return this.transform(t=>t!=null?t.trim():t).test({message:e,name:"trim",test:oje})}lowercase(e=ra.string.lowercase){return this.transform(t=>(0,aA.default)(t)?t:t.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:t=>(0,aA.default)(t)||t===t.toLowerCase()})}uppercase(e=ra.string.uppercase){return this.transform(t=>(0,aA.default)(t)?t:t.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:t=>(0,aA.default)(t)||t===t.toUpperCase()})}};Qm.default=bm;Fre.prototype=bm.prototype});var Ore=I(vm=>{"use strict";Object.defineProperty(vm,"__esModule",{value:!0});vm.create=Lre;vm.default=void 0;var nu=nA(),su=Tre(Lh()),Aje=Tre(oA());function Tre(r){return r&&r.__esModule?r:{default:r}}var lje=r=>r!=+r;function Lre(){return new Sm}var Sm=class extends Aje.default{constructor(){super({type:"number"}),this.withMutation(()=>{this.transform(function(e){let t=e;if(typeof t=="string"){if(t=t.replace(/\s/g,""),t==="")return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),typeof e=="number"&&!lje(e)}min(e,t=nu.number.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,su.default)(i)||i>=this.resolve(e)}})}max(e,t=nu.number.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(i){return(0,su.default)(i)||i<=this.resolve(e)}})}lessThan(e,t=nu.number.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(i){return(0,su.default)(i)||i<this.resolve(e)}})}moreThan(e,t=nu.number.moreThan){return this.test({message:t,name:"min",exclusive:!0,params:{more:e},test(i){return(0,su.default)(i)||i>this.resolve(e)}})}positive(e=nu.number.positive){return this.moreThan(0,e)}negative(e=nu.number.negative){return this.lessThan(0,e)}integer(e=nu.number.integer){return this.test({name:"integer",message:e,test:t=>(0,su.default)(t)||Number.isInteger(t)})}truncate(){return this.transform(e=>(0,su.default)(e)?e:e|0)}round(e){var t,i=["ceil","floor","round","trunc"];if(e=((t=e)==null?void 0:t.toLowerCase())||"round",e==="trunc")return this.truncate();if(i.indexOf(e.toLowerCase())===-1)throw new TypeError("Only valid options for round() are: "+i.join(", "));return this.transform(n=>(0,su.default)(n)?n:Math[e](n))}};vm.default=Sm;Lre.prototype=Sm.prototype});var Mre=I(OT=>{"use strict";Object.defineProperty(OT,"__esModule",{value:!0});OT.default=uje;var cje=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function uje(r){var e=[1,4,5,6,7,10,11],t=0,i,n;if(n=cje.exec(r)){for(var s=0,o;o=e[s];++s)n[o]=+n[o]||0;n[2]=(+n[2]||1)-1,n[3]=+n[3]||1,n[7]=n[7]?String(n[7]).substr(0,3):0,(n[8]===void 0||n[8]==="")&&(n[9]===void 0||n[9]==="")?i=+new Date(n[1],n[2],n[3],n[4],n[5],n[6],n[7]):(n[8]!=="Z"&&n[9]!==void 0&&(t=n[10]*60+n[11],n[9]==="+"&&(t=0-t)),i=Date.UTC(n[1],n[2],n[3],n[4],n[5]+t,n[6],n[7]))}else i=Date.parse?Date.parse(r):NaN;return i}});var Hre=I(Pm=>{"use strict";Object.defineProperty(Pm,"__esModule",{value:!0});Pm.create=KT;Pm.default=void 0;var gje=mb(Mre()),Kre=nA(),Ure=mb(Lh()),fje=mb(iu()),hje=mb(oA());function mb(r){return r&&r.__esModule?r:{default:r}}var MT=new Date(""),pje=r=>Object.prototype.toString.call(r)==="[object Date]";function KT(){return new Oh}var Oh=class extends hje.default{constructor(){super({type:"date"}),this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=(0,gje.default)(e),isNaN(e)?MT:new Date(e))})})}_typeCheck(e){return pje(e)&&!isNaN(e.getTime())}prepareParam(e,t){let i;if(fje.default.isRef(e))i=e;else{let n=this.cast(e);if(!this._typeCheck(n))throw new TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);i=n}return i}min(e,t=Kre.date.min){let i=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(n){return(0,Ure.default)(n)||n>=this.resolve(i)}})}max(e,t=Kre.date.max){var i=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(n){return(0,Ure.default)(n)||n<=this.resolve(i)}})}};Pm.default=Oh;Oh.INVALID_DATE=MT;KT.prototype=Oh.prototype;KT.INVALID_DATE=MT});var Gre=I((tgt,jre)=>{function dje(r,e,t,i){var n=-1,s=r==null?0:r.length;for(i&&s&&(t=r[++n]);++n<s;)t=e(t,r[n],n,r);return t}jre.exports=dje});var qre=I((rgt,Yre)=>{function Cje(r){return function(e){return r==null?void 0:r[e]}}Yre.exports=Cje});var Wre=I((igt,Jre)=>{var mje=qre(),Eje={\u00C0:"A",\u00C1:"A",\u00C2:"A",\u00C3:"A",\u00C4:"A",\u00C5:"A",\u00E0:"a",\u00E1:"a",\u00E2:"a",\u00E3:"a",\u00E4:"a",\u00E5:"a",\u00C7:"C",\u00E7:"c",\u00D0:"D",\u00F0:"d",\u00C8:"E",\u00C9:"E",\u00CA:"E",\u00CB:"E",\u00E8:"e",\u00E9:"e",\u00EA:"e",\u00EB:"e",\u00CC:"I",\u00CD:"I",\u00CE:"I",\u00CF:"I",\u00EC:"i",\u00ED:"i",\u00EE:"i",\u00EF:"i",\u00D1:"N",\u00F1:"n",\u00D2:"O",\u00D3:"O",\u00D4:"O",\u00D5:"O",\u00D6:"O",\u00D8:"O",\u00F2:"o",\u00F3:"o",\u00F4:"o",\u00F5:"o",\u00F6:"o",\u00F8:"o",\u00D9:"U",\u00DA:"U",\u00DB:"U",\u00DC:"U",\u00F9:"u",\u00FA:"u",\u00FB:"u",\u00FC:"u",\u00DD:"Y",\u00FD:"y",\u00FF:"y",\u00C6:"Ae",\u00E6:"ae",\u00DE:"Th",\u00FE:"th",\u00DF:"ss",\u0100:"A",\u0102:"A",\u0104:"A",\u0101:"a",\u0103:"a",\u0105:"a",\u0106:"C",\u0108:"C",\u010A:"C",\u010C:"C",\u0107:"c",\u0109:"c",\u010B:"c",\u010D:"c",\u010E:"D",\u0110:"D",\u010F:"d",\u0111:"d",\u0112:"E",\u0114:"E",\u0116:"E",\u0118:"E",\u011A:"E",\u0113:"e",\u0115:"e",\u0117:"e",\u0119:"e",\u011B:"e",\u011C:"G",\u011E:"G",\u0120:"G",\u0122:"G",\u011D:"g",\u011F:"g",\u0121:"g",\u0123:"g",\u0124:"H",\u0126:"H",\u0125:"h",\u0127:"h",\u0128:"I",\u012A:"I",\u012C:"I",\u012E:"I",\u0130:"I",\u0129:"i",\u012B:"i",\u012D:"i",\u012F:"i",\u0131:"i",\u0134:"J",\u0135:"j",\u0136:"K",\u0137:"k",\u0138:"k",\u0139:"L",\u013B:"L",\u013D:"L",\u013F:"L",\u0141:"L",\u013A:"l",\u013C:"l",\u013E:"l",\u0140:"l",\u0142:"l",\u0143:"N",\u0145:"N",\u0147:"N",\u014A:"N",\u0144:"n",\u0146:"n",\u0148:"n",\u014B:"n",\u014C:"O",\u014E:"O",\u0150:"O",\u014D:"o",\u014F:"o",\u0151:"o",\u0154:"R",\u0156:"R",\u0158:"R",\u0155:"r",\u0157:"r",\u0159:"r",\u015A:"S",\u015C:"S",\u015E:"S",\u0160:"S",\u015B:"s",\u015D:"s",\u015F:"s",\u0161:"s",\u0162:"T",\u0164:"T",\u0166:"T",\u0163:"t",\u0165:"t",\u0167:"t",\u0168:"U",\u016A:"U",\u016C:"U",\u016E:"U",\u0170:"U",\u0172:"U",\u0169:"u",\u016B:"u",\u016D:"u",\u016F:"u",\u0171:"u",\u0173:"u",\u0174:"W",\u0175:"w",\u0176:"Y",\u0177:"y",\u0178:"Y",\u0179:"Z",\u017B:"Z",\u017D:"Z",\u017A:"z",\u017C:"z",\u017E:"z",\u0132:"IJ",\u0133:"ij",\u0152:"Oe",\u0153:"oe",\u0149:"'n",\u017F:"s"},Ije=mje(Eje);Jre.exports=Ije});var Vre=I((ngt,zre)=>{var yje=Wre(),wje=Vf(),Bje=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,bje="\\u0300-\\u036f",Qje="\\ufe20-\\ufe2f",Sje="\\u20d0-\\u20ff",vje=bje+Qje+Sje,Pje="["+vje+"]",xje=RegExp(Pje,"g");function kje(r){return r=wje(r),r&&r.replace(Bje,yje).replace(xje,"")}zre.exports=kje});var Zre=I((sgt,Xre)=>{var Dje=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;function Rje(r){return r.match(Dje)||[]}Xre.exports=Rje});var $re=I((ogt,_re)=>{var Fje=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;function Nje(r){return Fje.test(r)}_re.exports=Nje});var mie=I((agt,Cie)=>{var nie="\\ud800-\\udfff",Tje="\\u0300-\\u036f",Lje="\\ufe20-\\ufe2f",Oje="\\u20d0-\\u20ff",Mje=Tje+Lje+Oje,sie="\\u2700-\\u27bf",oie="a-z\\xdf-\\xf6\\xf8-\\xff",Kje="\\xac\\xb1\\xd7\\xf7",Uje="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",Hje="\\u2000-\\u206f",jje=" \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",aie="A-Z\\xc0-\\xd6\\xd8-\\xde",Gje="\\ufe0e\\ufe0f",Aie=Kje+Uje+Hje+jje,lie="['\u2019]",eie="["+Aie+"]",Yje="["+Mje+"]",cie="\\d+",qje="["+sie+"]",uie="["+oie+"]",gie="[^"+nie+Aie+cie+sie+oie+aie+"]",Jje="\\ud83c[\\udffb-\\udfff]",Wje="(?:"+Yje+"|"+Jje+")",zje="[^"+nie+"]",fie="(?:\\ud83c[\\udde6-\\uddff]){2}",hie="[\\ud800-\\udbff][\\udc00-\\udfff]",Mh="["+aie+"]",Vje="\\u200d",tie="(?:"+uie+"|"+gie+")",Xje="(?:"+Mh+"|"+gie+")",rie="(?:"+lie+"(?:d|ll|m|re|s|t|ve))?",iie="(?:"+lie+"(?:D|LL|M|RE|S|T|VE))?",pie=Wje+"?",die="["+Gje+"]?",Zje="(?:"+Vje+"(?:"+[zje,fie,hie].join("|")+")"+die+pie+")*",_je="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",$je="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",eGe=die+pie+Zje,tGe="(?:"+[qje,fie,hie].join("|")+")"+eGe,rGe=RegExp([Mh+"?"+uie+"+"+rie+"(?="+[eie,Mh,"$"].join("|")+")",Xje+"+"+iie+"(?="+[eie,Mh+tie,"$"].join("|")+")",Mh+"?"+tie+"+"+rie,Mh+"+"+iie,$je,_je,cie,tGe].join("|"),"g");function iGe(r){return r.match(rGe)||[]}Cie.exports=iGe});var Iie=I((Agt,Eie)=>{var nGe=Zre(),sGe=$re(),oGe=Vf(),aGe=mie();function AGe(r,e,t){return r=oGe(r),e=t?void 0:e,e===void 0?sGe(r)?aGe(r):nGe(r):r.match(e)||[]}Eie.exports=AGe});var UT=I((lgt,yie)=>{var lGe=Gre(),cGe=Vre(),uGe=Iie(),gGe="['\u2019]",fGe=RegExp(gGe,"g");function hGe(r){return function(e){return lGe(uGe(cGe(e).replace(fGe,"")),r,"")}}yie.exports=hGe});var Bie=I((cgt,wie)=>{var pGe=UT(),dGe=pGe(function(r,e,t){return r+(t?"_":"")+e.toLowerCase()});wie.exports=dGe});var Qie=I((ugt,bie)=>{var CGe=PB(),mGe=UT(),EGe=mGe(function(r,e,t){return e=e.toLowerCase(),r+(t?CGe(e):e)});bie.exports=EGe});var vie=I((ggt,Sie)=>{var IGe=bh(),yGe=uT(),wGe=vT();function BGe(r,e){var t={};return e=wGe(e,3),yGe(r,function(i,n,s){IGe(t,e(i,n,s),i)}),t}Sie.exports=BGe});var xie=I((fgt,HT)=>{HT.exports=function(r){return Pie(bGe(r),r)};HT.exports.array=Pie;function Pie(r,e){var t=r.length,i=new Array(t),n={},s=t,o=QGe(e),a=SGe(r);for(e.forEach(function(c){if(!a.has(c[0])||!a.has(c[1]))throw new Error("Unknown node. There is an unknown node in the supplied edges.")});s--;)n[s]||l(r[s],s,new Set);return i;function l(c,u,g){if(g.has(c)){var h;try{h=", node was:"+JSON.stringify(c)}catch{h=""}throw new Error("Cyclic dependency"+h)}if(!a.has(c))throw new Error("Found unknown node. Make sure to provided all involved nodes. Unknown node: "+JSON.stringify(c));if(!n[u]){n[u]=!0;var p=o.get(c)||new Set;if(p=Array.from(p),u=p.length){g.add(c);do{var d=p[--u];l(d,a.get(d),g)}while(u);g.delete(c)}i[--t]=c}}}function bGe(r){for(var e=new Set,t=0,i=r.length;t<i;t++){var n=r[t];e.add(n[0]),e.add(n[1])}return Array.from(e)}function QGe(r){for(var e=new Map,t=0,i=r.length;t<i;t++){var n=r[t];e.has(n[0])||e.set(n[0],new Set),e.has(n[1])||e.set(n[1],new Set),e.get(n[0]).add(n[1])}return e}function SGe(r){for(var e=new Map,t=0,i=r.length;t<i;t++)e.set(r[t],t);return e}});var kie=I(jT=>{"use strict";Object.defineProperty(jT,"__esModule",{value:!0});jT.default=RGe;var vGe=Eb(Am()),PGe=Eb(xie()),xGe=dm(),kGe=Eb(iu()),DGe=Eb(Ph());function Eb(r){return r&&r.__esModule?r:{default:r}}function RGe(r,e=[]){let t=[],i=[];function n(s,o){var a=(0,xGe.split)(s)[0];~i.indexOf(a)||i.push(a),~e.indexOf(`${o}-${a}`)||t.push([o,a])}for(let s in r)if((0,vGe.default)(r,s)){let o=r[s];~i.indexOf(s)||i.push(s),kGe.default.isRef(o)&&o.isSibling?n(o.path,s):(0,DGe.default)(o)&&"deps"in o&&o.deps.forEach(a=>n(a,s))}return PGe.default.array(i,t).reverse()}});var Rie=I(GT=>{"use strict";Object.defineProperty(GT,"__esModule",{value:!0});GT.default=FGe;function Die(r,e){let t=1/0;return r.some((i,n)=>{var s;if(((s=e.path)==null?void 0:s.indexOf(i))!==-1)return t=n,!0}),t}function FGe(r){return(e,t)=>Die(r,e)-Die(r,t)}});var Kie=I(km=>{"use strict";Object.defineProperty(km,"__esModule",{value:!0});km.create=Mie;km.default=void 0;var Fie=ia(Am()),Nie=ia(Bie()),NGe=ia(Qie()),TGe=ia(vie()),LGe=ia(PT()),OGe=dm(),Tie=nA(),MGe=ia(kie()),Oie=ia(Rie()),KGe=ia(rb()),UGe=ia(eu()),YT=ia(oA());function ia(r){return r&&r.__esModule?r:{default:r}}function Kh(){return Kh=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},Kh.apply(this,arguments)}var Lie=r=>Object.prototype.toString.call(r)==="[object Object]";function HGe(r,e){let t=Object.keys(r.fields);return Object.keys(e).filter(i=>t.indexOf(i)===-1)}var jGe=(0,Oie.default)([]),xm=class extends YT.default{constructor(e){super({type:"object"}),this.fields=Object.create(null),this._sortErrors=jGe,this._nodes=[],this._excludedEdges=[],this.withMutation(()=>{this.transform(function(i){if(typeof i=="string")try{i=JSON.parse(i)}catch{i=null}return this.isType(i)?i:null}),e&&this.shape(e)})}_typeCheck(e){return Lie(e)||typeof e=="function"}_cast(e,t={}){var i;let n=super._cast(e,t);if(n===void 0)return this.getDefault();if(!this._typeCheck(n))return n;let s=this.fields,o=(i=t.stripUnknown)!=null?i:this.spec.noUnknown,a=this._nodes.concat(Object.keys(n).filter(g=>this._nodes.indexOf(g)===-1)),l={},c=Kh({},t,{parent:l,__validating:t.__validating||!1}),u=!1;for(let g of a){let h=s[g],p=(0,Fie.default)(n,g);if(h){let d,m=n[g];c.path=(t.path?`${t.path}.`:"")+g,h=h.resolve({value:m,context:t.context,parent:l});let y="spec"in h?h.spec:void 0,B=y==null?void 0:y.strict;if(y!=null&&y.strip){u=u||g in n;continue}d=!t.__validating||!B?h.cast(n[g],c):n[g],d!==void 0&&(l[g]=d)}else p&&!o&&(l[g]=n[g]);l[g]!==n[g]&&(u=!0)}return u?l:n}_validate(e,t={},i){let n=[],{sync:s,from:o=[],originalValue:a=e,abortEarly:l=this.spec.abortEarly,recursive:c=this.spec.recursive}=t;o=[{schema:this,value:a},...o],t.__validating=!0,t.originalValue=a,t.from=o,super._validate(e,t,(u,g)=>{if(u){if(!UGe.default.isError(u)||l)return void i(u,g);n.push(u)}if(!c||!Lie(g)){i(n[0]||null,g);return}a=a||g;let h=this._nodes.map(p=>(d,m)=>{let y=p.indexOf(".")===-1?(t.path?`${t.path}.`:"")+p:`${t.path||""}["${p}"]`,B=this.fields[p];if(B&&"validate"in B){B.validate(g[p],Kh({},t,{path:y,from:o,strict:!0,parent:g,originalValue:a[p]}),m);return}m(null)});(0,KGe.default)({sync:s,tests:h,value:g,errors:n,endEarly:l,sort:this._sortErrors,path:t.path},i)})}clone(e){let t=super.clone(e);return t.fields=Kh({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),i=t.fields;for(let[n,s]of Object.entries(this.fields)){let o=i[n];o===void 0?i[n]=s:o instanceof YT.default&&s instanceof YT.default&&(i[n]=s.concat(o))}return t.withMutation(()=>t.shape(i))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let i=this.fields[t];e[t]="default"in i?i.getDefault():void 0}),e}_getDefault(){if("default"in this.spec)return super._getDefault();if(!!this._nodes.length)return this.getDefaultFromShape()}shape(e,t=[]){let i=this.clone(),n=Object.assign(i.fields,e);if(i.fields=n,i._sortErrors=(0,Oie.default)(Object.keys(n)),t.length){Array.isArray(t[0])||(t=[t]);let s=t.map(([o,a])=>`${o}-${a}`);i._excludedEdges=i._excludedEdges.concat(s)}return i._nodes=(0,MGe.default)(n,i._excludedEdges),i}pick(e){let t={};for(let i of e)this.fields[i]&&(t[i]=this.fields[i]);return this.clone().withMutation(i=>(i.fields={},i.shape(t)))}omit(e){let t=this.clone(),i=t.fields;t.fields={};for(let n of e)delete i[n];return t.withMutation(()=>t.shape(i))}from(e,t,i){let n=(0,OGe.getter)(e,!0);return this.transform(s=>{if(s==null)return s;let o=s;return(0,Fie.default)(s,e)&&(o=Kh({},s),i||delete o[e],o[t]=n(s)),o})}noUnknown(e=!0,t=Tie.object.noUnknown){typeof e=="string"&&(t=e,e=!0);let i=this.test({name:"noUnknown",exclusive:!0,message:t,test(n){if(n==null)return!0;let s=HGe(this.schema,n);return!e||s.length===0||this.createError({params:{unknown:s.join(", ")}})}});return i.spec.noUnknown=e,i}unknown(e=!0,t=Tie.object.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&(0,TGe.default)(t,(i,n)=>e(n)))}camelCase(){return this.transformKeys(NGe.default)}snakeCase(){return this.transformKeys(Nie.default)}constantCase(){return this.transformKeys(e=>(0,Nie.default)(e).toUpperCase())}describe(){let e=super.describe();return e.fields=(0,LGe.default)(this.fields,t=>t.describe()),e}};km.default=xm;function Mie(r){return new xm(r)}Mie.prototype=xm.prototype});var Hie=I(Rm=>{"use strict";Object.defineProperty(Rm,"__esModule",{value:!0});Rm.create=Uie;Rm.default=void 0;var qT=Uh(Lh()),GGe=Uh(Ph()),YGe=Uh(am()),JT=nA(),qGe=Uh(rb()),JGe=Uh(eu()),WGe=Uh(oA());function Uh(r){return r&&r.__esModule?r:{default:r}}function Ib(){return Ib=Object.assign||function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(r[i]=t[i])}return r},Ib.apply(this,arguments)}function Uie(r){return new Dm(r)}var Dm=class extends WGe.default{constructor(e){super({type:"array"}),this.innerType=e,this.withMutation(()=>{this.transform(function(t){if(typeof t=="string")try{t=JSON.parse(t)}catch{t=null}return this.isType(t)?t:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let i=super._cast(e,t);if(!this._typeCheck(i)||!this.innerType)return i;let n=!1,s=i.map((o,a)=>{let l=this.innerType.cast(o,Ib({},t,{path:`${t.path||""}[${a}]`}));return l!==o&&(n=!0),l});return n?s:i}_validate(e,t={},i){var n,s;let o=[],a=t.sync,l=t.path,c=this.innerType,u=(n=t.abortEarly)!=null?n:this.spec.abortEarly,g=(s=t.recursive)!=null?s:this.spec.recursive,h=t.originalValue!=null?t.originalValue:e;super._validate(e,t,(p,d)=>{if(p){if(!JGe.default.isError(p)||u)return void i(p,d);o.push(p)}if(!g||!c||!this._typeCheck(d)){i(o[0]||null,d);return}h=h||d;let m=new Array(d.length);for(let y=0;y<d.length;y++){let B=d[y],S=`${t.path||""}[${y}]`,x=Ib({},t,{path:S,strict:!0,parent:d,index:y,originalValue:h[y]});m[y]=(F,H)=>c.validate(B,x,H)}(0,qGe.default)({sync:a,path:l,value:d,errors:o,endEarly:u,tests:m},i)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!(0,GGe.default)(e))throw new TypeError("`array.of()` sub-schema must be a valid yup schema not: "+(0,YGe.default)(e));return t.innerType=e,t}length(e,t=JT.array.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(i){return(0,qT.default)(i)||i.length===this.resolve(e)}})}min(e,t){return t=t||JT.array.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,qT.default)(i)||i.length>=this.resolve(e)}})}max(e,t){return t=t||JT.array.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(i){return(0,qT.default)(i)||i.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:t==null?[]:[].concat(t))}compact(e){let t=e?(i,n,s)=>!e(i,n,s):i=>!!i;return this.transform(i=>i!=null?i.filter(t):i)}describe(){let e=super.describe();return this.innerType&&(e.innerType=this.innerType.describe()),e}nullable(e=!0){return super.nullable(e)}defined(){return super.defined()}required(e){return super.required(e)}};Rm.default=Dm;Uie.prototype=Dm.prototype});var jie=I(Fm=>{"use strict";Object.defineProperty(Fm,"__esModule",{value:!0});Fm.create=XGe;Fm.default=void 0;var zGe=VGe(Ph());function VGe(r){return r&&r.__esModule?r:{default:r}}function XGe(r){return new yb(r)}var yb=class{constructor(e){this.type="lazy",this.__isYupSchema__=!0,this._resolve=(t,i={})=>{let n=this.builder(t,i);if(!(0,zGe.default)(n))throw new TypeError("lazy() functions must return a valid schema");return n.resolve(i)},this.builder=e}resolve(e){return this._resolve(e.value,e)}cast(e,t){return this._resolve(e,t).cast(e,t)}validate(e,t,i){return this._resolve(e,t).validate(e,t,i)}validateSync(e,t){return this._resolve(e,t).validateSync(e,t)}validateAt(e,t,i){return this._resolve(t,i).validateAt(e,t,i)}validateSyncAt(e,t,i){return this._resolve(t,i).validateSyncAt(e,t,i)}describe(){return null}isValid(e,t){return this._resolve(e,t).isValid(e,t)}isValidSync(e,t){return this._resolve(e,t).isValidSync(e,t)}},ZGe=yb;Fm.default=ZGe});var Gie=I(WT=>{"use strict";Object.defineProperty(WT,"__esModule",{value:!0});WT.default=eYe;var _Ge=$Ge(nA());function $Ge(r){return r&&r.__esModule?r:{default:r}}function eYe(r){Object.keys(r).forEach(e=>{Object.keys(r[e]).forEach(t=>{_Ge.default[e][t]=r[e][t]})})}});var VT=I(Er=>{"use strict";Object.defineProperty(Er,"__esModule",{value:!0});Er.addMethod=aYe;Object.defineProperty(Er,"MixedSchema",{enumerable:!0,get:function(){return Yie.default}});Object.defineProperty(Er,"mixed",{enumerable:!0,get:function(){return Yie.create}});Object.defineProperty(Er,"BooleanSchema",{enumerable:!0,get:function(){return zT.default}});Object.defineProperty(Er,"bool",{enumerable:!0,get:function(){return zT.create}});Object.defineProperty(Er,"boolean",{enumerable:!0,get:function(){return zT.create}});Object.defineProperty(Er,"StringSchema",{enumerable:!0,get:function(){return qie.default}});Object.defineProperty(Er,"string",{enumerable:!0,get:function(){return qie.create}});Object.defineProperty(Er,"NumberSchema",{enumerable:!0,get:function(){return Jie.default}});Object.defineProperty(Er,"number",{enumerable:!0,get:function(){return Jie.create}});Object.defineProperty(Er,"DateSchema",{enumerable:!0,get:function(){return Wie.default}});Object.defineProperty(Er,"date",{enumerable:!0,get:function(){return Wie.create}});Object.defineProperty(Er,"ObjectSchema",{enumerable:!0,get:function(){return zie.default}});Object.defineProperty(Er,"object",{enumerable:!0,get:function(){return zie.create}});Object.defineProperty(Er,"ArraySchema",{enumerable:!0,get:function(){return Vie.default}});Object.defineProperty(Er,"array",{enumerable:!0,get:function(){return Vie.create}});Object.defineProperty(Er,"ref",{enumerable:!0,get:function(){return tYe.create}});Object.defineProperty(Er,"lazy",{enumerable:!0,get:function(){return rYe.create}});Object.defineProperty(Er,"ValidationError",{enumerable:!0,get:function(){return iYe.default}});Object.defineProperty(Er,"reach",{enumerable:!0,get:function(){return nYe.default}});Object.defineProperty(Er,"isSchema",{enumerable:!0,get:function(){return Xie.default}});Object.defineProperty(Er,"setLocale",{enumerable:!0,get:function(){return sYe.default}});Object.defineProperty(Er,"BaseSchema",{enumerable:!0,get:function(){return oYe.default}});var Yie=ou(Sre()),zT=ou(Dre()),qie=ou(Nre()),Jie=ou(Ore()),Wie=ou(Hre()),zie=ou(Kie()),Vie=ou(Hie()),tYe=iu(),rYe=jie(),iYe=Nm(eu()),nYe=Nm(TT()),Xie=Nm(Ph()),sYe=Nm(Gie()),oYe=Nm(oA());function Nm(r){return r&&r.__esModule?r:{default:r}}function Zie(){if(typeof WeakMap!="function")return null;var r=new WeakMap;return Zie=function(){return r},r}function ou(r){if(r&&r.__esModule)return r;if(r===null||typeof r!="object"&&typeof r!="function")return{default:r};var e=Zie();if(e&&e.has(r))return e.get(r);var t={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var n in r)if(Object.prototype.hasOwnProperty.call(r,n)){var s=i?Object.getOwnPropertyDescriptor(r,n):null;s&&(s.get||s.set)?Object.defineProperty(t,n,s):t[n]=r[n]}return t.default=r,e&&e.set(r,t),t}function aYe(r,e,t){if(!r||!(0,Xie.default)(r.prototype))throw new TypeError("You must provide a yup schema constructor function");if(typeof e!="string")throw new TypeError("A Method name must be provided");if(typeof t!="function")throw new TypeError("Method function must be provided");r.prototype[e]=t}});var rne=I((Fgt,Lm)=>{"use strict";var cYe=process.env.TERM_PROGRAM==="Hyper",uYe=process.platform==="win32",$ie=process.platform==="linux",XT={ballotDisabled:"\u2612",ballotOff:"\u2610",ballotOn:"\u2611",bullet:"\u2022",bulletWhite:"\u25E6",fullBlock:"\u2588",heart:"\u2764",identicalTo:"\u2261",line:"\u2500",mark:"\u203B",middot:"\xB7",minus:"\uFF0D",multiplication:"\xD7",obelus:"\xF7",pencilDownRight:"\u270E",pencilRight:"\u270F",pencilUpRight:"\u2710",percent:"%",pilcrow2:"\u2761",pilcrow:"\xB6",plusMinus:"\xB1",section:"\xA7",starsOff:"\u2606",starsOn:"\u2605",upDownArrow:"\u2195"},ene=Object.assign({},XT,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),tne=Object.assign({},XT,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",question:"?",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:$ie?"\u25B8":"\u276F",pointerSmall:$ie?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});Lm.exports=uYe&&!cYe?ene:tne;Reflect.defineProperty(Lm.exports,"common",{enumerable:!1,value:XT});Reflect.defineProperty(Lm.exports,"windows",{enumerable:!1,value:ene});Reflect.defineProperty(Lm.exports,"other",{enumerable:!1,value:tne})});var uo=I((Ngt,ZT)=>{"use strict";var gYe=r=>r!==null&&typeof r=="object"&&!Array.isArray(r),fYe=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,ine=()=>{let r={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(r.enabled=process.env.FORCE_COLOR!=="0");let e=s=>{let o=s.open=`\x1B[${s.codes[0]}m`,a=s.close=`\x1B[${s.codes[1]}m`,l=s.regex=new RegExp(`\\u001b\\[${s.codes[1]}m`,"g");return s.wrap=(c,u)=>{c.includes(a)&&(c=c.replace(l,a+o));let g=o+c+a;return u?g.replace(/\r*\n/g,`${a}$&${o}`):g},s},t=(s,o,a)=>typeof s=="function"?s(o):s.wrap(o,a),i=(s,o)=>{if(s===""||s==null)return"";if(r.enabled===!1)return s;if(r.visible===!1)return"";let a=""+s,l=a.includes(` +`),c=o.length;for(c>0&&o.includes("unstyle")&&(o=[...new Set(["unstyle",...o])].reverse());c-- >0;)a=t(r.styles[o[c]],a,l);return a},n=(s,o,a)=>{r.styles[s]=e({name:s,codes:o}),(r.keys[a]||(r.keys[a]=[])).push(s),Reflect.defineProperty(r,s,{configurable:!0,enumerable:!0,set(c){r.alias(s,c)},get(){let c=u=>i(u,c.stack);return Reflect.setPrototypeOf(c,r),c.stack=this.stack?this.stack.concat(s):[s],c}})};return n("reset",[0,0],"modifier"),n("bold",[1,22],"modifier"),n("dim",[2,22],"modifier"),n("italic",[3,23],"modifier"),n("underline",[4,24],"modifier"),n("inverse",[7,27],"modifier"),n("hidden",[8,28],"modifier"),n("strikethrough",[9,29],"modifier"),n("black",[30,39],"color"),n("red",[31,39],"color"),n("green",[32,39],"color"),n("yellow",[33,39],"color"),n("blue",[34,39],"color"),n("magenta",[35,39],"color"),n("cyan",[36,39],"color"),n("white",[37,39],"color"),n("gray",[90,39],"color"),n("grey",[90,39],"color"),n("bgBlack",[40,49],"bg"),n("bgRed",[41,49],"bg"),n("bgGreen",[42,49],"bg"),n("bgYellow",[43,49],"bg"),n("bgBlue",[44,49],"bg"),n("bgMagenta",[45,49],"bg"),n("bgCyan",[46,49],"bg"),n("bgWhite",[47,49],"bg"),n("blackBright",[90,39],"bright"),n("redBright",[91,39],"bright"),n("greenBright",[92,39],"bright"),n("yellowBright",[93,39],"bright"),n("blueBright",[94,39],"bright"),n("magentaBright",[95,39],"bright"),n("cyanBright",[96,39],"bright"),n("whiteBright",[97,39],"bright"),n("bgBlackBright",[100,49],"bgBright"),n("bgRedBright",[101,49],"bgBright"),n("bgGreenBright",[102,49],"bgBright"),n("bgYellowBright",[103,49],"bgBright"),n("bgBlueBright",[104,49],"bgBright"),n("bgMagentaBright",[105,49],"bgBright"),n("bgCyanBright",[106,49],"bgBright"),n("bgWhiteBright",[107,49],"bgBright"),r.ansiRegex=fYe,r.hasColor=r.hasAnsi=s=>(r.ansiRegex.lastIndex=0,typeof s=="string"&&s!==""&&r.ansiRegex.test(s)),r.alias=(s,o)=>{let a=typeof o=="string"?r[o]:o;if(typeof a!="function")throw new TypeError("Expected alias to be the name of an existing color (string) or a function");a.stack||(Reflect.defineProperty(a,"name",{value:s}),r.styles[s]=a,a.stack=[s]),Reflect.defineProperty(r,s,{configurable:!0,enumerable:!0,set(l){r.alias(s,l)},get(){let l=c=>i(c,l.stack);return Reflect.setPrototypeOf(l,r),l.stack=this.stack?this.stack.concat(a.stack):a.stack,l}})},r.theme=s=>{if(!gYe(s))throw new TypeError("Expected theme to be an object");for(let o of Object.keys(s))r.alias(o,s[o]);return r},r.alias("unstyle",s=>typeof s=="string"&&s!==""?(r.ansiRegex.lastIndex=0,s.replace(r.ansiRegex,"")):""),r.alias("noop",s=>s),r.none=r.clear=r.noop,r.stripColor=r.unstyle,r.symbols=rne(),r.define=n,r};ZT.exports=ine();ZT.exports.create=ine});var Yi=I(Ft=>{"use strict";var hYe=Object.prototype.toString,Fs=uo(),nne=!1,_T=[],sne={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};Ft.longest=(r,e)=>r.reduce((t,i)=>Math.max(t,e?i[e].length:i.length),0);Ft.hasColor=r=>!!r&&Fs.hasColor(r);var Bb=Ft.isObject=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);Ft.nativeType=r=>hYe.call(r).slice(8,-1).toLowerCase().replace(/\s/g,"");Ft.isAsyncFn=r=>Ft.nativeType(r)==="asyncfunction";Ft.isPrimitive=r=>r!=null&&typeof r!="object"&&typeof r!="function";Ft.resolve=(r,e,...t)=>typeof e=="function"?e.call(r,...t):e;Ft.scrollDown=(r=[])=>[...r.slice(1),r[0]];Ft.scrollUp=(r=[])=>[r.pop(),...r];Ft.reorder=(r=[])=>{let e=r.slice();return e.sort((t,i)=>t.index>i.index?1:t.index<i.index?-1:0),e};Ft.swap=(r,e,t)=>{let i=r.length,n=t===i?0:t<0?i-1:t,s=r[e];r[e]=r[n],r[n]=s};Ft.width=(r,e=80)=>{let t=r&&r.columns?r.columns:e;return r&&typeof r.getWindowSize=="function"&&(t=r.getWindowSize()[0]),process.platform==="win32"?t-1:t};Ft.height=(r,e=20)=>{let t=r&&r.rows?r.rows:e;return r&&typeof r.getWindowSize=="function"&&(t=r.getWindowSize()[1]),t};Ft.wordWrap=(r,e={})=>{if(!r)return r;typeof e=="number"&&(e={width:e});let{indent:t="",newline:i=` +`+t,width:n=80}=e,s=(i+t).match(/[^\S\n]/g)||[];n-=s.length;let o=`.{1,${n}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,a=r.trim(),l=new RegExp(o,"g"),c=a.match(l)||[];return c=c.map(u=>u.replace(/\n$/,"")),e.padEnd&&(c=c.map(u=>u.padEnd(n," "))),e.padStart&&(c=c.map(u=>u.padStart(n," "))),t+c.join(i)};Ft.unmute=r=>{let e=r.stack.find(i=>Fs.keys.color.includes(i));return e?Fs[e]:r.stack.find(i=>i.slice(2)==="bg")?Fs[e.slice(2)]:i=>i};Ft.pascal=r=>r?r[0].toUpperCase()+r.slice(1):"";Ft.inverse=r=>{if(!r||!r.stack)return r;let e=r.stack.find(i=>Fs.keys.color.includes(i));if(e){let i=Fs["bg"+Ft.pascal(e)];return i?i.black:r}let t=r.stack.find(i=>i.slice(0,2)==="bg");return t?Fs[t.slice(2).toLowerCase()]||r:Fs.none};Ft.complement=r=>{if(!r||!r.stack)return r;let e=r.stack.find(i=>Fs.keys.color.includes(i)),t=r.stack.find(i=>i.slice(0,2)==="bg");if(e&&!t)return Fs[sne[e]||e];if(t){let i=t.slice(2).toLowerCase(),n=sne[i];return n&&Fs["bg"+Ft.pascal(n)]||r}return Fs.none};Ft.meridiem=r=>{let e=r.getHours(),t=r.getMinutes(),i=e>=12?"pm":"am";e=e%12;let n=e===0?12:e,s=t<10?"0"+t:t;return n+":"+s+" "+i};Ft.set=(r={},e="",t)=>e.split(".").reduce((i,n,s,o)=>{let a=o.length-1>s?i[n]||{}:t;return!Ft.isObject(a)&&s<o.length-1&&(a={}),i[n]=a},r);Ft.get=(r={},e="",t)=>{let i=r[e]==null?e.split(".").reduce((n,s)=>n&&n[s],r):r[e];return i==null?t:i};Ft.mixin=(r,e)=>{if(!Bb(r))return e;if(!Bb(e))return r;for(let t of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,t);if(i.hasOwnProperty("value"))if(r.hasOwnProperty(t)&&Bb(i.value)){let n=Object.getOwnPropertyDescriptor(r,t);Bb(n.value)?r[t]=Ft.merge({},r[t],e[t]):Reflect.defineProperty(r,t,i)}else Reflect.defineProperty(r,t,i);else Reflect.defineProperty(r,t,i)}return r};Ft.merge=(...r)=>{let e={};for(let t of r)Ft.mixin(e,t);return e};Ft.mixinEmitter=(r,e)=>{let t=e.constructor.prototype;for(let i of Object.keys(t)){let n=t[i];typeof n=="function"?Ft.define(r,i,n.bind(e)):Ft.define(r,i,n)}};Ft.onExit=r=>{let e=(t,i)=>{nne||(nne=!0,_T.forEach(n=>n()),t===!0&&process.exit(128+i))};_T.length===0&&(process.once("SIGTERM",e.bind(null,!0,15)),process.once("SIGINT",e.bind(null,!0,2)),process.once("exit",e)),_T.push(r)};Ft.define=(r,e,t)=>{Reflect.defineProperty(r,e,{value:t})};Ft.defineExport=(r,e,t)=>{let i;Reflect.defineProperty(r,e,{enumerable:!0,configurable:!0,set(n){i=n},get(){return i?i():t()}})}});var one=I(jh=>{"use strict";jh.ctrl={a:"first",b:"backward",c:"cancel",d:"deleteForward",e:"last",f:"forward",g:"reset",i:"tab",k:"cutForward",l:"reset",n:"newItem",m:"cancel",j:"submit",p:"search",r:"remove",s:"save",u:"undo",w:"cutLeft",x:"toggleCursor",v:"paste"};jh.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};jh.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};jh.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};jh.keys={pageup:"pageUp",pagedown:"pageDown",home:"home",end:"end",cancel:"cancel",delete:"deleteForward",backspace:"delete",down:"down",enter:"submit",escape:"cancel",left:"left",space:"space",number:"number",return:"submit",right:"right",tab:"next",up:"up"}});var lne=I((Ogt,Ane)=>{"use strict";var ane=J("readline"),pYe=one(),dYe=/^(?:\x1b)([a-zA-Z0-9])$/,CYe=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,mYe={OP:"f1",OQ:"f2",OR:"f3",OS:"f4","[11~":"f1","[12~":"f2","[13~":"f3","[14~":"f4","[[A":"f1","[[B":"f2","[[C":"f3","[[D":"f4","[[E":"f5","[15~":"f5","[17~":"f6","[18~":"f7","[19~":"f8","[20~":"f9","[21~":"f10","[23~":"f11","[24~":"f12","[A":"up","[B":"down","[C":"right","[D":"left","[E":"clear","[F":"end","[H":"home",OA:"up",OB:"down",OC:"right",OD:"left",OE:"clear",OF:"end",OH:"home","[1~":"home","[2~":"insert","[3~":"delete","[4~":"end","[5~":"pageup","[6~":"pagedown","[[5~":"pageup","[[6~":"pagedown","[7~":"home","[8~":"end","[a":"up","[b":"down","[c":"right","[d":"left","[e":"clear","[2$":"insert","[3$":"delete","[5$":"pageup","[6$":"pagedown","[7$":"home","[8$":"end",Oa:"up",Ob:"down",Oc:"right",Od:"left",Oe:"clear","[2^":"insert","[3^":"delete","[5^":"pageup","[6^":"pagedown","[7^":"home","[8^":"end","[Z":"tab"};function EYe(r){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(r)}function IYe(r){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(r)}var bb=(r="",e={})=>{let t,i={name:e.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:r,raw:r,...e};if(Buffer.isBuffer(r)?r[0]>127&&r[1]===void 0?(r[0]-=128,r="\x1B"+String(r)):r=String(r):r!==void 0&&typeof r!="string"?r=String(r):r||(r=i.sequence||""),i.sequence=i.sequence||r||i.name,r==="\r")i.raw=void 0,i.name="return";else if(r===` +`)i.name="enter";else if(r===" ")i.name="tab";else if(r==="\b"||r==="\x7F"||r==="\x1B\x7F"||r==="\x1B\b")i.name="backspace",i.meta=r.charAt(0)==="\x1B";else if(r==="\x1B"||r==="\x1B\x1B")i.name="escape",i.meta=r.length===2;else if(r===" "||r==="\x1B ")i.name="space",i.meta=r.length===2;else if(r<="")i.name=String.fromCharCode(r.charCodeAt(0)+"a".charCodeAt(0)-1),i.ctrl=!0;else if(r.length===1&&r>="0"&&r<="9")i.name="number";else if(r.length===1&&r>="a"&&r<="z")i.name=r;else if(r.length===1&&r>="A"&&r<="Z")i.name=r.toLowerCase(),i.shift=!0;else if(t=dYe.exec(r))i.meta=!0,i.shift=/^[A-Z]$/.test(t[1]);else if(t=CYe.exec(r)){let n=[...r];n[0]==="\x1B"&&n[1]==="\x1B"&&(i.option=!0);let s=[t[1],t[2],t[4],t[6]].filter(Boolean).join(""),o=(t[3]||t[5]||1)-1;i.ctrl=!!(o&4),i.meta=!!(o&10),i.shift=!!(o&1),i.code=s,i.name=mYe[s],i.shift=EYe(s)||i.shift,i.ctrl=IYe(s)||i.ctrl}return i};bb.listen=(r={},e)=>{let{stdin:t}=r;if(!t||t!==process.stdin&&!t.isTTY)throw new Error("Invalid stream passed");let i=ane.createInterface({terminal:!0,input:t});ane.emitKeypressEvents(t,i);let n=(a,l)=>e(a,bb(a,l),i),s=t.isRaw;return t.isTTY&&t.setRawMode(!0),t.on("keypress",n),i.resume(),()=>{t.isTTY&&t.setRawMode(s),t.removeListener("keypress",n),i.pause(),i.close()}};bb.action=(r,e,t)=>{let i={...pYe,...t};return e.ctrl?(e.action=i.ctrl[e.name],e):e.option&&i.option?(e.action=i.option[e.name],e):e.shift?(e.action=i.shift[e.name],e):(e.action=i.keys[e.name],e)};Ane.exports=bb});var une=I((Mgt,cne)=>{"use strict";cne.exports=r=>{r.timers=r.timers||{};let e=r.options.timers;if(!!e)for(let t of Object.keys(e)){let i=e[t];typeof i=="number"&&(i={interval:i}),yYe(r,t,i)}};function yYe(r,e,t={}){let i=r.timers[e]={name:e,start:Date.now(),ms:0,tick:0},n=t.interval||120;i.frames=t.frames||[],i.loading=!0;let s=setInterval(()=>{i.ms=Date.now()-i.start,i.tick++,r.render()},n);return i.stop=()=>{i.loading=!1,clearInterval(s)},Reflect.defineProperty(i,"interval",{value:s}),r.once("close",()=>i.stop()),i.stop}});var fne=I((Kgt,gne)=>{"use strict";var{define:wYe,width:BYe}=Yi(),$T=class{constructor(e){let t=e.options;wYe(this,"_prompt",e),this.type=e.type,this.name=e.name,this.message="",this.header="",this.footer="",this.error="",this.hint="",this.input="",this.cursor=0,this.index=0,this.lines=0,this.tick=0,this.prompt="",this.buffer="",this.width=BYe(t.stdout||process.stdout),Object.assign(this,t),this.name=this.name||this.message,this.message=this.message||this.name,this.symbols=e.symbols,this.styles=e.styles,this.required=new Set,this.cancelled=!1,this.submitted=!1}clone(){let e={...this};return e.status=this.status,e.buffer=Buffer.from(e.buffer),delete e.clone,e}set color(e){this._color=e}get color(){let e=this.prompt.styles;if(this.cancelled)return e.cancelled;if(this.submitted)return e.submitted;let t=this._color||e[this.status];return typeof t=="function"?t:e.pending}set loading(e){this._loading=e}get loading(){return typeof this._loading=="boolean"?this._loading:this.loadingChoices?"choices":!1}get status(){return this.cancelled?"cancelled":this.submitted?"submitted":"pending"}};gne.exports=$T});var pne=I((Ugt,hne)=>{"use strict";var eL=Yi(),ki=uo(),tL={default:ki.noop,noop:ki.noop,set inverse(r){this._inverse=r},get inverse(){return this._inverse||eL.inverse(this.primary)},set complement(r){this._complement=r},get complement(){return this._complement||eL.complement(this.primary)},primary:ki.cyan,success:ki.green,danger:ki.magenta,strong:ki.bold,warning:ki.yellow,muted:ki.dim,disabled:ki.gray,dark:ki.dim.gray,underline:ki.underline,set info(r){this._info=r},get info(){return this._info||this.primary},set em(r){this._em=r},get em(){return this._em||this.primary.underline},set heading(r){this._heading=r},get heading(){return this._heading||this.muted.underline},set pending(r){this._pending=r},get pending(){return this._pending||this.primary},set submitted(r){this._submitted=r},get submitted(){return this._submitted||this.success},set cancelled(r){this._cancelled=r},get cancelled(){return this._cancelled||this.danger},set typing(r){this._typing=r},get typing(){return this._typing||this.dim},set placeholder(r){this._placeholder=r},get placeholder(){return this._placeholder||this.primary.dim},set highlight(r){this._highlight=r},get highlight(){return this._highlight||this.inverse}};tL.merge=(r={})=>{r.styles&&typeof r.styles.enabled=="boolean"&&(ki.enabled=r.styles.enabled),r.styles&&typeof r.styles.visible=="boolean"&&(ki.visible=r.styles.visible);let e=eL.merge({},tL,r.styles);delete e.merge;for(let t of Object.keys(ki))e.hasOwnProperty(t)||Reflect.defineProperty(e,t,{get:()=>ki[t]});for(let t of Object.keys(ki.styles))e.hasOwnProperty(t)||Reflect.defineProperty(e,t,{get:()=>ki[t]});return e};hne.exports=tL});var Cne=I((Hgt,dne)=>{"use strict";var rL=process.platform==="win32",AA=uo(),bYe=Yi(),iL={...AA.symbols,upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:AA.symbols.check,leftAngle:"\u2039",mark:"\u203B",minus:"\u2212",multiplication:"\xD7",obelus:"\xF7",percent:"%",pilcrow:"\xB6",pilcrow2:"\u2761",pencilUpRight:"\u2710",pencilDownRight:"\u270E",pencilRight:"\u270F",plus:"+",plusMinus:"\xB1",pointRight:"\u261E",rightAngle:"\u203A",section:"\xA7",hexagon:{off:"\u2B21",on:"\u2B22",disabled:"\u2B22"},ballot:{on:"\u2611",off:"\u2610",disabled:"\u2612"},stars:{on:"\u2605",off:"\u2606",disabled:"\u2606"},folder:{on:"\u25BC",off:"\u25B6",disabled:"\u25B6"},prefix:{pending:AA.symbols.question,submitted:AA.symbols.check,cancelled:AA.symbols.cross},separator:{pending:AA.symbols.pointerSmall,submitted:AA.symbols.middot,cancelled:AA.symbols.middot},radio:{off:rL?"( )":"\u25EF",on:rL?"(*)":"\u25C9",disabled:rL?"(|)":"\u24BE"},numbers:["\u24EA","\u2460","\u2461","\u2462","\u2463","\u2464","\u2465","\u2466","\u2467","\u2468","\u2469","\u246A","\u246B","\u246C","\u246D","\u246E","\u246F","\u2470","\u2471","\u2472","\u2473","\u3251","\u3252","\u3253","\u3254","\u3255","\u3256","\u3257","\u3258","\u3259","\u325A","\u325B","\u325C","\u325D","\u325E","\u325F","\u32B1","\u32B2","\u32B3","\u32B4","\u32B5","\u32B6","\u32B7","\u32B8","\u32B9","\u32BA","\u32BB","\u32BC","\u32BD","\u32BE","\u32BF"]};iL.merge=r=>{let e=bYe.merge({},AA.symbols,iL,r.symbols);return delete e.merge,e};dne.exports=iL});var Ene=I((jgt,mne)=>{"use strict";var QYe=pne(),SYe=Cne(),vYe=Yi();mne.exports=r=>{r.options=vYe.merge({},r.options.theme,r.options),r.symbols=SYe.merge(r.options),r.styles=QYe.merge(r.options)}});var bne=I((wne,Bne)=>{"use strict";var Ine=process.env.TERM_PROGRAM==="Apple_Terminal",PYe=uo(),nL=Yi(),go=Bne.exports=wne,xr="\x1B[",yne="\x07",sL=!1,pl=go.code={bell:yne,beep:yne,beginning:`${xr}G`,down:`${xr}J`,esc:xr,getPosition:`${xr}6n`,hide:`${xr}?25l`,line:`${xr}2K`,lineEnd:`${xr}K`,lineStart:`${xr}1K`,restorePosition:xr+(Ine?"8":"u"),savePosition:xr+(Ine?"7":"s"),screen:`${xr}2J`,show:`${xr}?25h`,up:`${xr}1J`},au=go.cursor={get hidden(){return sL},hide(){return sL=!0,pl.hide},show(){return sL=!1,pl.show},forward:(r=1)=>`${xr}${r}C`,backward:(r=1)=>`${xr}${r}D`,nextLine:(r=1)=>`${xr}E`.repeat(r),prevLine:(r=1)=>`${xr}F`.repeat(r),up:(r=1)=>r?`${xr}${r}A`:"",down:(r=1)=>r?`${xr}${r}B`:"",right:(r=1)=>r?`${xr}${r}C`:"",left:(r=1)=>r?`${xr}${r}D`:"",to(r,e){return e?`${xr}${e+1};${r+1}H`:`${xr}${r+1}G`},move(r=0,e=0){let t="";return t+=r<0?au.left(-r):r>0?au.right(r):"",t+=e<0?au.up(-e):e>0?au.down(e):"",t},restore(r={}){let{after:e,cursor:t,initial:i,input:n,prompt:s,size:o,value:a}=r;if(i=nL.isPrimitive(i)?String(i):"",n=nL.isPrimitive(n)?String(n):"",a=nL.isPrimitive(a)?String(a):"",o){let l=go.cursor.up(o)+go.cursor.to(s.length),c=n.length-t;return c>0&&(l+=go.cursor.left(c)),l}if(a||e){let l=!n&&!!i?-i.length:-n.length+t;return e&&(l-=e.length),n===""&&i&&!s.includes(i)&&(l+=i.length),go.cursor.move(l)}}},oL=go.erase={screen:pl.screen,up:pl.up,down:pl.down,line:pl.line,lineEnd:pl.lineEnd,lineStart:pl.lineStart,lines(r){let e="";for(let t=0;t<r;t++)e+=go.erase.line+(t<r-1?go.cursor.up(1):"");return r&&(e+=go.code.beginning),e}};go.clear=(r="",e=process.stdout.columns)=>{if(!e)return oL.line+au.to(0);let t=s=>[...PYe.unstyle(s)].length,i=r.split(/\r?\n/),n=0;for(let s of i)n+=1+Math.floor(Math.max(t(s)-1,0)/e);return(oL.line+au.prevLine()).repeat(n-1)+oL.line+au.to(0)}});var Gh=I((Ggt,Sne)=>{"use strict";var xYe=J("events"),Qne=uo(),aL=lne(),kYe=une(),DYe=fne(),RYe=Ene(),Dn=Yi(),Au=bne(),Om=class extends xYe{constructor(e={}){super(),this.name=e.name,this.type=e.type,this.options=e,RYe(this),kYe(this),this.state=new DYe(this),this.initial=[e.initial,e.default].find(t=>t!=null),this.stdout=e.stdout||process.stdout,this.stdin=e.stdin||process.stdin,this.scale=e.scale||1,this.term=this.options.term||process.env.TERM_PROGRAM,this.margin=NYe(this.options.margin),this.setMaxListeners(0),FYe(this)}async keypress(e,t={}){this.keypressed=!0;let i=aL.action(e,aL(e,t),this.options.actions);this.state.keypress=i,this.emit("keypress",e,i),this.emit("state",this.state.clone());let n=this.options[i.action]||this[i.action]||this.dispatch;if(typeof n=="function")return await n.call(this,e,i);this.alert()}alert(){delete this.state.alert,this.options.show===!1?this.emit("alert"):this.stdout.write(Au.code.beep)}cursorHide(){this.stdout.write(Au.cursor.hide()),Dn.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(Au.cursor.show())}write(e){!e||(this.stdout&&this.state.show!==!1&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let t=this.state.buffer;this.state.buffer="",!(!t&&!e||this.options.show===!1)&&this.stdout.write(Au.cursor.down(e)+Au.clear(t,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:t,rest:i}=this.sections(),{cursor:n,initial:s="",input:o="",value:a=""}=this,l=this.state.size=i.length,c={after:t,cursor:n,initial:s,input:o,prompt:e,size:l,value:a},u=Au.cursor.restore(c);u&&this.stdout.write(u)}sections(){let{buffer:e,input:t,prompt:i}=this.state;i=Qne.unstyle(i);let n=Qne.unstyle(e),s=n.indexOf(i),o=n.slice(0,s),l=n.slice(s).split(` +`),c=l[0],u=l[l.length-1],h=(i+(t?" "+t:"")).length,p=h<c.length?c.slice(h+1):"";return{header:o,prompt:c,after:p,rest:l.slice(1),last:u}}async submit(){this.state.submitted=!0,this.state.validating=!0,this.options.onSubmit&&await this.options.onSubmit.call(this,this.name,this.value,this);let e=this.state.error||await this.validate(this.value,this.state);if(e!==!0){let t=` +`+this.symbols.pointer+" ";typeof e=="string"?t+=e.trim():t+="Invalid input",this.state.error=` +`+this.styles.danger(t),this.state.submitted=!1,await this.render(),await this.alert(),this.state.validating=!1,this.state.error=void 0;return}this.state.validating=!1,await this.render(),await this.close(),this.value=await this.result(this.value),this.emit("submit",this.value)}async cancel(e){this.state.cancelled=this.state.submitted=!0,await this.render(),await this.close(),typeof this.options.onCancel=="function"&&await this.options.onCancel.call(this,this.name,this.value,this),this.emit("cancel",await this.error(e))}async close(){this.state.closed=!0;try{let e=this.sections(),t=Math.ceil(e.prompt.length/this.width);e.rest&&this.write(Au.cursor.down(e.rest.length)),this.write(` +`.repeat(t))}catch{}this.emit("close")}start(){!this.stop&&this.options.show!==!1&&(this.stop=aL.listen(this,this.keypress.bind(this)),this.once("close",this.stop))}async skip(){return this.skipped=this.options.skip===!0,typeof this.options.skip=="function"&&(this.skipped=await this.options.skip.call(this,this.name,this.value)),this.skipped}async initialize(){let{format:e,options:t,result:i}=this;if(this.format=()=>e.call(this,this.value),this.result=()=>i.call(this,this.value),typeof t.initial=="function"&&(this.initial=await t.initial.call(this,this)),typeof t.onRun=="function"&&await t.onRun.call(this,this),typeof t.onSubmit=="function"){let n=t.onSubmit.bind(this),s=this.submit.bind(this);delete this.options.onSubmit,this.submit=async()=>(await n(this.name,this.value,this),s())}await this.start(),await this.render()}render(){throw new Error("expected prompt to have a custom render method")}run(){return new Promise(async(e,t)=>{if(this.once("submit",e),this.once("cancel",t),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,t,i){let{options:n,state:s,symbols:o,timers:a}=this,l=a&&a[e];s.timer=l;let c=n[e]||s[e]||o[e],u=t&&t[e]!=null?t[e]:await c;if(u==="")return u;let g=await this.resolve(u,s,t,i);return!g&&t&&t[e]?this.resolve(c,s,t,i):g}async prefix(){let e=await this.element("prefix")||this.symbols,t=this.timers&&this.timers.prefix,i=this.state;return i.timer=t,Dn.isObject(e)&&(e=e[i.status]||e.pending),Dn.hasColor(e)?e:(this.styles[i.status]||this.styles.pending)(e)}async message(){let e=await this.element("message");return Dn.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,t=this.timers&&this.timers.separator,i=this.state;i.timer=t;let n=e[i.status]||e.pending||i.separator,s=await this.resolve(n,i);return Dn.isObject(s)&&(s=s[i.status]||s.pending),Dn.hasColor(s)?s:this.styles.muted(s)}async pointer(e,t){let i=await this.element("pointer",e,t);if(typeof i=="string"&&Dn.hasColor(i))return i;if(i){let n=this.styles,s=this.index===t,o=s?n.primary:c=>c,a=await this.resolve(i[s?"on":"off"]||i,this.state),l=Dn.hasColor(a)?a:o(a);return s?l:" ".repeat(a.length)}}async indicator(e,t){let i=await this.element("indicator",e,t);if(typeof i=="string"&&Dn.hasColor(i))return i;if(i){let n=this.styles,s=e.enabled===!0,o=s?n.success:n.dark,a=i[s?"on":"off"]||i;return Dn.hasColor(a)?a:o(a)}return""}body(){return null}footer(){if(this.state.status==="pending")return this.element("footer")}header(){if(this.state.status==="pending")return this.element("header")}async hint(){if(this.state.status==="pending"&&!this.isValue(this.state.input)){let e=await this.element("hint");return Dn.hasColor(e)?e:this.styles.muted(e)}}error(e){return this.state.submitted?"":e||this.state.error}format(e){return e}result(e){return e}validate(e){return this.options.required===!0?this.isValue(e):!0}isValue(e){return e!=null&&e!==""}resolve(e,...t){return Dn.resolve(this,e,...t)}get base(){return Om.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||Dn.height(this.stdout,25)}get width(){return this.options.columns||Dn.width(this.stdout,80)}get size(){return{width:this.width,height:this.height}}set cursor(e){this.state.cursor=e}get cursor(){return this.state.cursor}set input(e){this.state.input=e}get input(){return this.state.input}set value(e){this.state.value=e}get value(){let{input:e,value:t}=this.state,i=[t,e].find(this.isValue.bind(this));return this.isValue(i)?i:this.initial}static get prompt(){return e=>new this(e).run()}};function FYe(r){let e=n=>r[n]===void 0||typeof r[n]=="function",t=["actions","choices","initial","margin","roles","styles","symbols","theme","timers","value"],i=["body","footer","error","header","hint","indicator","message","prefix","separator","skip"];for(let n of Object.keys(r.options)){if(t.includes(n)||/^on[A-Z]/.test(n))continue;let s=r.options[n];typeof s=="function"&&e(n)?i.includes(n)||(r[n]=s.bind(r)):typeof r[n]!="function"&&(r[n]=s)}}function NYe(r){typeof r=="number"&&(r=[r,r,r,r]);let e=[].concat(r||[]),t=n=>n%2===0?` +`:" ",i=[];for(let n=0;n<4;n++){let s=t(n);e[n]?i.push(s.repeat(e[n])):i.push("")}return i}Sne.exports=Om});var xne=I((Ygt,Pne)=>{"use strict";var TYe=Yi(),vne={default(r,e){return e},checkbox(r,e){throw new Error("checkbox role is not implemented yet")},editable(r,e){throw new Error("editable role is not implemented yet")},expandable(r,e){throw new Error("expandable role is not implemented yet")},heading(r,e){return e.disabled="",e.indicator=[e.indicator," "].find(t=>t!=null),e.message=e.message||"",e},input(r,e){throw new Error("input role is not implemented yet")},option(r,e){return vne.default(r,e)},radio(r,e){throw new Error("radio role is not implemented yet")},separator(r,e){return e.disabled="",e.indicator=[e.indicator," "].find(t=>t!=null),e.message=e.message||r.symbols.line.repeat(5),e},spacer(r,e){return e}};Pne.exports=(r,e={})=>{let t=TYe.merge({},vne,e.roles);return t[r]||t.default}});var Mm=I((qgt,Rne)=>{"use strict";var LYe=uo(),OYe=Gh(),MYe=xne(),Qb=Yi(),{reorder:AL,scrollUp:KYe,scrollDown:UYe,isObject:kne,swap:HYe}=Qb,lL=class extends OYe{constructor(e){super(e),this.cursorHide(),this.maxSelected=e.maxSelected||1/0,this.multiple=e.multiple||!1,this.initial=e.initial||0,this.delay=e.delay||0,this.longest=0,this.num=""}async initialize(){typeof this.options.initial=="function"&&(this.initial=await this.options.initial.call(this)),await this.reset(!0),await super.initialize()}async reset(){let{choices:e,initial:t,autofocus:i,suggest:n}=this.options;if(this.state._choices=[],this.state.choices=[],this.choices=await Promise.all(await this.toChoices(e)),this.choices.forEach(s=>s.enabled=!1),typeof n!="function"&&this.selectable.length===0)throw new Error("At least one choice must be selectable");kne(t)&&(t=Object.keys(t)),Array.isArray(t)?(i!=null&&(this.index=this.findIndex(i)),t.forEach(s=>this.enable(this.find(s))),await this.render()):(i!=null&&(t=i),typeof t=="string"&&(t=this.findIndex(t)),typeof t=="number"&&t>-1&&(this.index=Math.max(0,Math.min(t,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,t){this.state.loadingChoices=!0;let i=[],n=0,s=async(o,a)=>{typeof o=="function"&&(o=await o.call(this)),o instanceof Promise&&(o=await o);for(let l=0;l<o.length;l++){let c=o[l]=await this.toChoice(o[l],n++,a);i.push(c),c.choices&&await s(c.choices,c)}return i};return s(e,t).then(o=>(this.state.loadingChoices=!1,o))}async toChoice(e,t,i){if(typeof e=="function"&&(e=await e.call(this,this)),e instanceof Promise&&(e=await e),typeof e=="string"&&(e={name:e}),e.normalized)return e;e.normalized=!0;let n=e.value;if(e=MYe(e.role,this.options)(this,e),typeof e.disabled=="string"&&!e.hint&&(e.hint=e.disabled,e.disabled=!0),e.disabled===!0&&e.hint==null&&(e.hint="(disabled)"),e.index!=null)return e;e.name=e.name||e.key||e.title||e.value||e.message,e.message=e.message||e.name||"",e.value=[e.value,e.name].find(this.isValue.bind(this)),e.input="",e.index=t,e.cursor=0,Qb.define(e,"parent",i),e.level=i?i.level+1:1,e.indent==null&&(e.indent=i?i.indent+" ":e.indent||""),e.path=i?i.path+"."+e.name:e.name,e.enabled=!!(this.multiple&&!this.isDisabled(e)&&(e.enabled||this.isSelected(e))),this.isDisabled(e)||(this.longest=Math.max(this.longest,LYe.unstyle(e.message).length));let o={...e};return e.reset=(a=o.input,l=o.value)=>{for(let c of Object.keys(o))e[c]=o[c];e.input=a,e.value=l},n==null&&typeof e.initial=="function"&&(e.input=await e.initial.call(this,this.state,e,t)),e}async onChoice(e,t){this.emit("choice",e,t,this),typeof e.onChoice=="function"&&await e.onChoice.call(this,this.state,e,t)}async addChoice(e,t,i){let n=await this.toChoice(e,t,i);return this.choices.push(n),this.index=this.choices.length-1,this.limit=this.choices.length,n}async newItem(e,t,i){let n={name:"New choice name?",editable:!0,newChoice:!0,...e},s=await this.addChoice(n,t,i);return s.updateChoice=()=>{delete s.newChoice,s.name=s.message=s.input,s.input="",s.cursor=0},this.render()}indent(e){return e.indent==null?e.level>1?" ".repeat(e.level-1):"":e.indent}dispatch(e,t){if(this.multiple&&this[t.name])return this[t.name]();this.alert()}focus(e,t){return typeof t!="boolean"&&(t=e.enabled),t&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=t&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelected<this.choices.length)return this.alert();let e=this.selectable.every(t=>t.enabled);return this.choices.forEach(t=>t.enabled=!e),this.render()}i(){return this.choices.length-this.selected.length>this.maxSelected?this.alert():(this.choices.forEach(e=>e.enabled=!e.enabled),this.render())}g(e=this.focused){return this.choices.some(t=>!!t.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,t){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();typeof t!="boolean"&&(t=!e.enabled),e.enabled=t,e.choices&&e.choices.forEach(n=>this.toggle(n,t));let i=e.parent;for(;i;){let n=i.choices.filter(s=>this.isDisabled(s));i.enabled=n.every(s=>s.enabled===!0),i=i.parent}return Dne(this,this.choices),this.emit("toggle",e,this),e}enable(e){return this.selected.length>=this.maxSelected?this.alert():(e.enabled=!this.isDisabled(e),e.choices&&e.choices.forEach(this.enable.bind(this)),e)}disable(e){return e.enabled=!1,e.choices&&e.choices.forEach(this.disable.bind(this)),e}number(e){this.num+=e;let t=i=>{let n=Number(i);if(n>this.choices.length-1)return this.alert();let s=this.focused,o=this.choices.find(a=>n===a.index);if(!o.enabled&&this.selected.length>=this.maxSelected)return this.alert();if(this.visible.indexOf(o)===-1){let a=AL(this.choices),l=a.indexOf(o);if(s.index>l){let c=a.slice(l,l+this.limit),u=a.filter(g=>!c.includes(g));this.choices=c.concat(u)}else{let c=l-this.limit+1;this.choices=a.slice(c).concat(a.slice(0,c))}}return this.index=this.choices.indexOf(o),this.toggle(this.focused),this.render()};return clearTimeout(this.numberTimeout),new Promise(i=>{let n=this.choices.length,s=this.num,o=(a=!1,l)=>{clearTimeout(this.numberTimeout),a&&(l=t(s)),this.num="",i(l)};if(s==="0"||s.length===1&&Number(s+"0")>n)return o(!0);if(Number(s)>n)return o(!1,this.alert());this.numberTimeout=setTimeout(()=>o(!0),this.delay)})}home(){return this.choices=AL(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,t=AL(this.choices);return this.choices=t.slice(e).concat(t.slice(0,e)),this.index=this.limit-1,this.render()}first(){return this.index=0,this.render()}last(){return this.index=this.visible.length-1,this.render()}prev(){return this.visible.length<=1?this.alert():this.up()}next(){return this.visible.length<=1?this.alert():this.down()}right(){return this.cursor>=this.input.length?this.alert():(this.cursor++,this.render())}left(){return this.cursor<=0?this.alert():(this.cursor--,this.render())}up(){let e=this.choices.length,t=this.visible.length,i=this.index;return this.options.scroll===!1&&i===0?this.alert():e>t&&i===0?this.scrollUp():(this.index=(i-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,t=this.visible.length,i=this.index;return this.options.scroll===!1&&i===t-1?this.alert():e>t&&i===t-1?this.scrollDown():(this.index=(i+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=KYe(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=UYe(this.choices),this.index=e,this.isDisabled()?this.down():this.render()}async shiftUp(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index-1),await this.up(),this.sorting=!1;return}return this.scrollUp(this.index)}async shiftDown(){if(this.options.sort===!0){this.sorting=!0,this.swap(this.index+1),await this.down(),this.sorting=!1;return}return this.scrollDown(this.index)}pageUp(){return this.visible.length<=1?this.alert():(this.limit=Math.max(this.limit-1,0),this.index=Math.min(this.limit-1,this.index),this._limit=this.limit,this.isDisabled()?this.up():this.render())}pageDown(){return this.visible.length>=this.choices.length?this.alert():(this.index=Math.max(0,this.index),this.limit=Math.min(this.limit+1,this.choices.length),this._limit=this.limit,this.isDisabled()?this.down():this.render())}swap(e){HYe(this.choices,this.index,e)}isDisabled(e=this.focused){return e&&["disabled","collapsed","hidden","completing","readonly"].some(i=>e[i]===!0)?!0:e&&e.role==="heading"}isEnabled(e=this.focused){if(Array.isArray(e))return e.every(t=>this.isEnabled(t));if(e.choices){let t=e.choices.filter(i=>!this.isDisabled(i));return e.enabled&&t.every(i=>this.isEnabled(i))}return e.enabled&&!this.isDisabled(e)}isChoice(e,t){return e.name===t||e.index===Number(t)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(t=>this.isChoice(e,t)):this.isChoice(e,this.initial)}map(e=[],t="value"){return[].concat(e||[]).reduce((i,n)=>(i[n]=this.find(n,t),i),{})}filter(e,t){let n=typeof e=="function"?e:(a,l)=>[a.name,l].includes(e),o=(this.options.multiple?this.state._choices:this.choices).filter(n);return t?o.map(a=>a[t]):o}find(e,t){if(kne(e))return t?e[t]:e;let n=typeof e=="function"?e:(o,a)=>[o.name,a].includes(e),s=this.choices.find(n);if(s)return t?s[t]:s}findIndex(e){return this.choices.indexOf(this.find(e))}async submit(){let e=this.focused;if(!e)return this.alert();if(e.newChoice)return e.input?(e.updateChoice(),this.render()):this.alert();if(this.choices.some(o=>o.newChoice))return this.alert();let{reorder:t,sort:i}=this.options,n=this.multiple===!0,s=this.selected;return s===void 0?this.alert():(Array.isArray(s)&&t!==!1&&i!==!0&&(s=Qb.reorder(s)),this.value=n?s.map(o=>o.name):s.name,super.submit())}set choices(e=[]){this.state._choices=this.state._choices||[],this.state.choices=e;for(let t of e)this.state._choices.some(i=>i.name===t.name)||this.state._choices.push(t);if(!this._initial&&this.options.initial){this._initial=!0;let t=this.initial;if(typeof t=="string"||typeof t=="number"){let i=this.find(t);i&&(this.initial=i.index,this.focus(i,!0))}}}get choices(){return Dne(this,this.state.choices||[])}set visible(e){this.state.visible=e}get visible(){return(this.state.visible||this.choices).slice(0,this.limit)}set limit(e){this.state.limit=e}get limit(){let{state:e,options:t,choices:i}=this,n=e.limit||this._limit||t.limit||i.length;return Math.min(n,this.height)}set value(e){super.value=e}get value(){return typeof super.value!="string"&&super.value===this.initial?this.input:super.value}set index(e){this.state.index=e}get index(){return Math.max(0,this.state?this.state.index:0)}get enabled(){return this.filter(this.isEnabled.bind(this))}get focused(){let e=this.choices[this.index];return e&&this.state.submitted&&this.multiple!==!0&&(e.enabled=!0),e}get selectable(){return this.choices.filter(e=>!this.isDisabled(e))}get selected(){return this.multiple?this.enabled:this.focused}};function Dne(r,e){if(e instanceof Promise)return e;if(typeof e=="function"){if(Qb.isAsyncFn(e))return e;e=e.call(r,r)}for(let t of e){if(Array.isArray(t.choices)){let i=t.choices.filter(n=>!r.isDisabled(n));t.enabled=i.every(n=>n.enabled===!0)}r.isDisabled(t)===!0&&delete t.enabled}return e}Rne.exports=lL});var dl=I((Jgt,Fne)=>{"use strict";var jYe=Mm(),cL=Yi(),uL=class extends jYe{constructor(e){super(e),this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}separator(){if(this.options.separator)return super.separator();let e=this.styles.muted(this.symbols.ellipsis);return this.state.submitted?super.separator():e}pointer(e,t){return!this.multiple||this.options.pointer?super.pointer(e,t):""}indicator(e,t){return this.multiple?super.indicator(e,t):""}choiceMessage(e,t){let i=this.resolve(e.message,this.state,e,t);return e.role==="heading"&&!cL.hasColor(i)&&(i=this.styles.strong(i)),this.resolve(i,this.state,e,t)}choiceSeparator(){return":"}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=await this.pointer(e,t),s=await this.indicator(e,t)+(e.pad||""),o=await this.resolve(e.hint,this.state,e,t);o&&!cL.hasColor(o)&&(o=this.styles.muted(o));let a=this.indent(e),l=await this.choiceMessage(e,t),c=()=>[this.margin[3],a+n+s,l,this.margin[1],o].filter(Boolean).join(" ");return e.role==="heading"?c():e.disabled?(cL.hasColor(l)||(l=this.styles.disabled(l)),c()):(i&&(l=this.styles.em(l)),c())}async renderChoices(){if(this.state.loading==="choices")return this.styles.warning("Loading choices");if(this.state.submitted)return"";let e=this.visible.map(async(s,o)=>await this.renderChoice(s,o)),t=await Promise.all(e);t.length||t.push(this.styles.danger("No matching choices"));let i=this.margin[0]+t.join(` +`),n;return this.options.choicesHeader&&(n=await this.resolve(this.options.choicesHeader,this.state)),[n,i].filter(Boolean).join(` +`)}format(){return!this.state.submitted||this.state.cancelled?"":Array.isArray(this.selected)?this.selected.map(e=>this.styles.primary(e.name)).join(", "):this.styles.primary(this.selected.name)}async render(){let{submitted:e,size:t}=this.state,i="",n=await this.header(),s=await this.prefix(),o=await this.separator(),a=await this.message();this.options.promptLine!==!1&&(i=[s,a,o,""].join(" "),this.state.prompt=i);let l=await this.format(),c=await this.error()||await this.hint(),u=await this.renderChoices(),g=await this.footer();l&&(i+=l),c&&!i.includes(c)&&(i+=" "+c),e&&!l&&!u.trim()&&this.multiple&&this.emptyError!=null&&(i+=this.styles.danger(this.emptyError)),this.clear(t),this.write([n,i,u,g].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};Fne.exports=uL});var Tne=I((Wgt,Nne)=>{"use strict";var GYe=dl(),YYe=(r,e)=>{let t=r.toLowerCase();return i=>{let s=i.toLowerCase().indexOf(t),o=e(i.slice(s,s+t.length));return s>=0?i.slice(0,s)+o+i.slice(s+t.length):i}},gL=class extends GYe{constructor(e){super(e),this.cursorShow()}moveCursor(e){this.state.cursor+=e}dispatch(e){return this.append(e)}space(e){return this.options.multiple?super.space(e):this.append(e)}append(e){let{cursor:t,input:i}=this.state;return this.input=i.slice(0,t)+e+i.slice(t),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:t}=this.state;return t?(this.input=t.slice(0,e-1)+t.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:t}=this.state;return t[e]===void 0?this.alert():(this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.complete())}number(e){return this.append(e)}async complete(){this.completing=!0,this.choices=await this.suggest(this.input,this.state._choices),this.state.limit=void 0,this.index=Math.min(Math.max(this.visible.length-1,0),this.index),await this.render(),this.completing=!1}suggest(e=this.input,t=this.state._choices){if(typeof this.options.suggest=="function")return this.options.suggest.call(this,e,t);let i=e.toLowerCase();return t.filter(n=>n.message.toLowerCase().includes(i))}pointer(){return""}format(){if(!this.focused)return this.input;if(this.options.multiple&&this.state.submitted)return this.selected.map(e=>this.styles.primary(e.message)).join(", ");if(this.state.submitted){let e=this.value=this.input=this.focused.value;return this.styles.primary(e)}return this.input}async render(){if(this.state.status!=="pending")return super.render();let e=this.options.highlight?this.options.highlight.bind(this):this.styles.placeholder,t=YYe(this.input,e),i=this.choices;this.choices=i.map(n=>({...n,message:t(n.message)})),await super.render(),this.choices=i}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}};Nne.exports=gL});var hL=I((zgt,Lne)=>{"use strict";var fL=Yi();Lne.exports=(r,e={})=>{r.cursorHide();let{input:t="",initial:i="",pos:n,showCursor:s=!0,color:o}=e,a=o||r.styles.placeholder,l=fL.inverse(r.styles.primary),c=m=>l(r.styles.black(m)),u=t,g=" ",h=c(g);if(r.blink&&r.blink.off===!0&&(c=m=>m,h=""),s&&n===0&&i===""&&t==="")return c(g);if(s&&n===0&&(t===i||t===""))return c(i[0])+a(i.slice(1));i=fL.isPrimitive(i)?`${i}`:"",t=fL.isPrimitive(t)?`${t}`:"";let p=i&&i.startsWith(t)&&i!==t,d=p?c(i[t.length]):h;if(n!==t.length&&s===!0&&(u=t.slice(0,n)+c(t[n])+t.slice(n+1),d=""),s===!1&&(d=""),p){let m=r.styles.unstyle(u+d);return u+d+a(i.slice(m.length))}return u+d}});var Sb=I((Vgt,One)=>{"use strict";var qYe=uo(),JYe=dl(),WYe=hL(),pL=class extends JYe{constructor(e){super({...e,multiple:!0}),this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(t=>t!=null),this.emptyError="",this.values={}}async reset(e){return await super.reset(),e===!0&&(this._index=this.index),this.index=this._index,this.values={},this.choices.forEach(t=>t.reset&&t.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let t=this.focused;if(!t)return this.alert();let{cursor:i,input:n}=t;return t.value=t.input=n.slice(0,i)+e+n.slice(i),t.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:t,input:i}=e;return e.value=e.input=i.slice(0,t-1)+i.slice(t),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:t,input:i}=e;if(i[t]===void 0)return this.alert();let n=`${i}`.slice(0,t)+`${i}`.slice(t+1);return e.value=e.input=n,this.render()}right(){let e=this.focused;return e?e.cursor>=e.input.length?this.alert():(e.cursor++,this.render()):this.alert()}left(){let e=this.focused;return e?e.cursor<=0?this.alert():(e.cursor--,this.render()):this.alert()}space(e,t){return this.dispatch(e,t)}number(e,t){return this.dispatch(e,t)}next(){let e=this.focused;if(!e)return this.alert();let{initial:t,input:i}=e;return t&&t.startsWith(i)&&i!==t?(e.value=e.input=t,e.cursor=e.value.length,this.render()):super.next()}prev(){let e=this.focused;return e?e.cursor===0?super.prev():(e.value=e.input="",e.cursor=0,this.render()):this.alert()}separator(){return""}format(e){return this.state.submitted?"":super.format(e)}pointer(){return""}indicator(e){return e.input?"\u29BF":"\u2299"}async choiceSeparator(e,t){let i=await this.resolve(e.separator,this.state,e,t)||":";return i?" "+this.styles.disabled(i):""}async renderChoice(e,t){await this.onChoice(e,t);let{state:i,styles:n}=this,{cursor:s,initial:o="",name:a,hint:l,input:c=""}=e,{muted:u,submitted:g,primary:h,danger:p}=n,d=l,m=this.index===t,y=e.validate||(()=>!0),B=await this.choiceSeparator(e,t),S=e.message;this.align==="right"&&(S=S.padStart(this.longest+1," ")),this.align==="left"&&(S=S.padEnd(this.longest+1," "));let x=this.values[a]=c||o,F=c?"success":"dark";await y.call(e,x,this.state)!==!0&&(F="danger");let H=n[F],q=H(await this.indicator(e,t))+(e.pad||""),_=this.indent(e),X=()=>[_,q,S+B,c,d].filter(Boolean).join(" ");if(i.submitted)return S=qYe.unstyle(S),c=g(c),d="",X();if(e.format)c=await e.format.call(this,c,e,t);else{let W=this.styles.muted;c=WYe(this,{input:c,initial:o,pos:s,showCursor:m,color:W})}return this.isValue(c)||(c=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[a]=await e.result.call(this,x,e,t)),m&&(S=h(S)),e.error?c+=(c?" ":"")+p(e.error.trim()):e.hint&&(c+=(c?" ":"")+u(e.hint.trim())),X()}async submit(){return this.value=this.values,super.base.submit.call(this)}};One.exports=pL});var dL=I((Xgt,Kne)=>{"use strict";var zYe=Sb(),VYe=()=>{throw new Error("expected prompt to have a custom authenticate method")},Mne=(r=VYe)=>{class e extends zYe{constructor(i){super(i)}async submit(){this.value=await r.call(this,this.values,this.state),super.base.submit.call(this)}static create(i){return Mne(i)}}return e};Kne.exports=Mne()});var jne=I((Zgt,Hne)=>{"use strict";var XYe=dL();function ZYe(r,e){return r.username===this.options.username&&r.password===this.options.password}var Une=(r=ZYe)=>{let e=[{name:"username",message:"username"},{name:"password",message:"password",format(i){return this.options.showPassword?i:(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(i.length))}}];class t extends XYe.create(r){constructor(n){super({...n,choices:e})}static create(n){return Une(n)}}return t};Hne.exports=Une()});var vb=I((_gt,Gne)=>{"use strict";var _Ye=Gh(),{isPrimitive:$Ye,hasColor:eqe}=Yi(),CL=class extends _Ye{constructor(e){super(e),this.cursorHide()}async initialize(){let e=await this.resolve(this.initial,this.state);this.input=await this.cast(e),await super.initialize()}dispatch(e){return this.isValue(e)?(this.input=e,this.submit()):this.alert()}format(e){let{styles:t,state:i}=this;return i.submitted?t.success(e):t.primary(e)}cast(e){return this.isTrue(e)}isTrue(e){return/^[ty1]/i.test(e)}isFalse(e){return/^[fn0]/i.test(e)}isValue(e){return $Ye(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");return eqe(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:t}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o=this.styles.muted(this.default),a=[i,s,o,n].filter(Boolean).join(" ");this.state.prompt=a;let l=await this.header(),c=this.value=this.cast(e),u=await this.format(c),g=await this.error()||await this.hint(),h=await this.footer();g&&!a.includes(g)&&(u+=" "+g),a+=" "+u,this.clear(t),this.write([l,a,h].filter(Boolean).join(` +`)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}};Gne.exports=CL});var qne=I(($gt,Yne)=>{"use strict";var tqe=vb(),mL=class extends tqe{constructor(e){super(e),this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}};Yne.exports=mL});var Wne=I((eft,Jne)=>{"use strict";var rqe=dl(),iqe=Sb(),Yh=iqe.prototype,EL=class extends rqe{constructor(e){super({...e,multiple:!0}),this.align=[this.options.align,"left"].find(t=>t!=null),this.emptyError="",this.values={}}dispatch(e,t){let i=this.focused,n=i.parent||{};return!i.editable&&!n.editable&&(e==="a"||e==="i")?super[e]():Yh.dispatch.call(this,e,t)}append(e,t){return Yh.append.call(this,e,t)}delete(e,t){return Yh.delete.call(this,e,t)}space(e){return this.focused.editable?this.append(e):super.space()}number(e){return this.focused.editable?this.append(e):super.number(e)}next(){return this.focused.editable?Yh.next.call(this):super.next()}prev(){return this.focused.editable?Yh.prev.call(this):super.prev()}async indicator(e,t){let i=e.indicator||"",n=e.editable?i:super.indicator(e,t);return await this.resolve(n,this.state,e,t)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,t){return e.indent="",e.editable?Yh.renderChoice.call(this,e,t):super.renderChoice(e,t)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let t of this.choices){if(typeof t.validate!="function"||t.role==="heading")continue;let i=t.parent?this.value[t.parent.name]:this.value;if(t.editable?i=t.value===t.name?t.initial||"":t.value:this.isDisabled(t)||(i=t.enabled===!0),e=await t.validate(i,this.state),e!==!0)break}return e!==!0&&(this.state.error=typeof e=="string"?e:"Invalid Input"),e}submit(){if(this.focused.newChoice===!0)return super.submit();if(this.choices.some(e=>e.newChoice))return this.alert();this.value={};for(let e of this.choices){let t=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}e.editable?t[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(t[e.name]=e.enabled===!0)}return this.base.submit.call(this)}};Jne.exports=EL});var lu=I((tft,zne)=>{"use strict";var nqe=Gh(),sqe=hL(),{isPrimitive:oqe}=Yi(),IL=class extends nqe{constructor(e){super(e),this.initial=oqe(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,t={}){let i=this.state.prevKeypress;return this.state.prevKeypress=t,this.options.multiline===!0&&t.name==="return"&&(!i||i.name!=="return")?this.append(` +`,t):super.keypress(e,t)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,t){if(!e||t.ctrl||t.code)return this.alert();this.append(e)}append(e){let{cursor:t,input:i}=this.state;this.input=`${i}`.slice(0,t)+e+`${i}`.slice(t),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:t}=this.state;if(e<=0)return this.alert();this.input=`${t}`.slice(0,e-1)+`${t}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();this.input=`${t}`.slice(0,e)+`${t}`.slice(e+1),this.render()}cutForward(){let e=this.cursor;if(this.input.length<=e)return this.alert();this.state.clipboard.push(this.input.slice(e)),this.input=this.input.slice(0,e),this.render()}cutLeft(){let e=this.cursor;if(e===0)return this.alert();let t=this.input.slice(0,e),i=this.input.slice(e),n=t.split(" ");this.state.clipboard.push(n.pop()),this.input=n.join(" "),this.cursor=this.input.length,this.input+=i,this.render()}paste(){if(!this.state.clipboard.length)return this.alert();this.insert(this.state.clipboard.pop()),this.render()}toggleCursor(){this.state.prevCursor?(this.cursor=this.state.prevCursor,this.state.prevCursor=0):(this.state.prevCursor=this.cursor,this.cursor=0),this.render()}first(){this.cursor=0,this.render()}last(){this.cursor=this.input.length-1,this.render()}next(){let e=this.initial!=null?String(this.initial):"";if(!e||!e.startsWith(this.input))return this.alert();this.input=this.initial,this.cursor=this.initial.length,this.render()}prev(){if(!this.input)return this.alert();this.reset()}backward(){return this.left()}forward(){return this.right()}right(){return this.cursor>=this.input.length?this.alert():(this.moveCursor(1),this.render())}left(){return this.cursor<=0?this.alert():(this.moveCursor(-1),this.render())}isValue(e){return!!e}async format(e=this.value){let t=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||t):sqe(this,{input:e,initial:t,pos:this.cursor})}async render(){let e=this.state.size,t=await this.prefix(),i=await this.separator(),n=await this.message(),s=[t,n,i].filter(Boolean).join(" ");this.state.prompt=s;let o=await this.header(),a=await this.format(),l=await this.error()||await this.hint(),c=await this.footer();l&&!a.includes(l)&&(a+=" "+l),s+=" "+a,this.clear(e),this.write([o,s,c].filter(Boolean).join(` +`)),this.restore()}};zne.exports=IL});var Xne=I((rft,Vne)=>{"use strict";var aqe=r=>r.filter((e,t)=>r.lastIndexOf(e)===t),Pb=r=>aqe(r).filter(Boolean);Vne.exports=(r,e={},t="")=>{let{past:i=[],present:n=""}=e,s,o;switch(r){case"prev":case"undo":return s=i.slice(0,i.length-1),o=i[i.length-1]||"",{past:Pb([t,...s]),present:o};case"next":case"redo":return s=i.slice(1),o=i[0]||"",{past:Pb([...s,t]),present:o};case"save":return{past:Pb([...i,t]),present:""};case"remove":return o=Pb(i.filter(a=>a!==t)),n="",o.length&&(n=o.pop()),{past:o,present:n};default:throw new Error(`Invalid action: "${r}"`)}}});var wL=I((ift,_ne)=>{"use strict";var Aqe=lu(),Zne=Xne(),yL=class extends Aqe{constructor(e){super(e);let t=this.options.history;if(t&&t.store){let i=t.values||this.initial;this.autosave=!!t.autosave,this.store=t.store,this.data=this.store.get("values")||{past:[],present:i},this.initial=this.data.present||this.data.past[this.data.past.length-1]}}completion(e){return this.store?(this.data=Zne(e,this.data,this.input),this.data.present?(this.input=this.data.present,this.cursor=this.input.length,this.render()):this.alert()):this.alert()}altUp(){return this.completion("prev")}altDown(){return this.completion("next")}prev(){return this.save(),super.prev()}save(){!this.store||(this.data=Zne("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&this.autosave===!0&&this.save(),super.submit()}};_ne.exports=yL});var ese=I((nft,$ne)=>{"use strict";var lqe=lu(),BL=class extends lqe{format(){return""}};$ne.exports=BL});var rse=I((sft,tse)=>{"use strict";var cqe=lu(),bL=class extends cqe{constructor(e={}){super(e),this.sep=this.options.separator||/, */,this.initial=e.initial||""}split(e=this.value){return e?String(e).split(this.sep):[]}format(){let e=this.state.submitted?this.styles.primary:t=>t;return this.list.map(e).join(", ")}async submit(e){let t=this.state.error||await this.validate(this.list,this.state);return t!==!0?(this.state.error=t,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}};tse.exports=bL});var nse=I((oft,ise)=>{"use strict";var uqe=dl(),QL=class extends uqe{constructor(e){super({...e,multiple:!0})}};ise.exports=QL});var vL=I((aft,sse)=>{"use strict";var gqe=lu(),SL=class extends gqe{constructor(e={}){super({style:"number",...e}),this.min=this.isValue(e.min)?this.toNumber(e.min):-1/0,this.max=this.isValue(e.max)?this.toNumber(e.max):1/0,this.delay=e.delay!=null?e.delay:1e3,this.float=e.float!==!1,this.round=e.round===!0||e.float===!1,this.major=e.major||10,this.minor=e.minor||1,this.initial=e.initial!=null?e.initial:"",this.input=String(this.initial),this.cursor=this.input.length,this.cursorShow()}append(e){return!/[-+.]/.test(e)||e==="."&&this.input.includes(".")?this.alert("invalid number"):super.append(e)}number(e){return super.append(e)}next(){return this.input&&this.input!==this.initial?this.alert():this.isValue(this.initial)?(this.input=this.initial,this.cursor=String(this.initial).length,this.render()):this.alert()}up(e){let t=e||this.minor,i=this.toNumber(this.input);return i>this.max+t?this.alert():(this.input=`${i+t}`,this.render())}down(e){let t=e||this.minor,i=this.toNumber(this.input);return i<this.min-t?this.alert():(this.input=`${i-t}`,this.render())}shiftDown(){return this.down(this.major)}shiftUp(){return this.up(this.major)}format(e=this.input){return typeof this.options.format=="function"?this.options.format.call(this,e):this.styles.info(e)}toNumber(e=""){return this.float?+e:Math.round(+e)}isValue(e){return/^[-+]?[0-9]+((\.)|(\.[0-9]+))?$/.test(e)}submit(){let e=[this.input,this.initial].find(t=>this.isValue(t));return this.value=this.toNumber(e||0),super.submit()}};sse.exports=SL});var ase=I((Aft,ose)=>{ose.exports=vL()});var lse=I((lft,Ase)=>{"use strict";var fqe=lu(),PL=class extends fqe{constructor(e){super(e),this.cursorShow()}format(e=this.input){return this.keypressed?(this.state.submitted?this.styles.primary:this.styles.muted)(this.symbols.asterisk.repeat(e.length)):""}};Ase.exports=PL});var gse=I((cft,use)=>{"use strict";var hqe=uo(),pqe=Mm(),cse=Yi(),xL=class extends pqe{constructor(e={}){super(e),this.widths=[].concat(e.messageWidth||50),this.align=[].concat(e.align||"left"),this.linebreak=e.linebreak||!1,this.edgeLength=e.edgeLength||3,this.newline=e.newline||` + `;let t=e.startNumber||1;typeof this.scale=="number"&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((i,n)=>({name:n+t})))}async reset(){return this.tableized=!1,await super.reset(),this.render()}tableize(){if(this.tableized===!0)return;this.tableized=!0;let e=0;for(let t of this.choices){e=Math.max(e,t.message.length),t.scaleIndex=t.initial||2,t.scale=[];for(let i=0;i<this.scale.length;i++)t.scale.push({index:i})}this.widths[0]=Math.min(this.widths[0],e+3)}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);this.alert()}heading(e,t,i){return this.styles.strong(e)}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIndex>=this.scale.length-1?this.alert():(e.scaleIndex++,this.render())}left(){let e=this.focused;return e.scaleIndex<=0?this.alert():(e.scaleIndex--,this.render())}indent(){return""}format(){return this.state.submitted?this.choices.map(t=>this.styles.info(t.index)).join(", "):""}pointer(){return""}renderScaleKey(){return this.scaleKey===!1||this.state.submitted?"":["",...this.scale.map(i=>` ${i.name} - ${i.message}`)].map(i=>this.styles.muted(i)).join(` +`)}renderScaleHeading(e){let t=this.scale.map(l=>l.name);typeof this.options.renderScaleHeading=="function"&&(t=this.options.renderScaleHeading.call(this,e));let i=this.scaleLength-t.join("").length,n=Math.round(i/(t.length-1)),o=t.map(l=>this.styles.strong(l)).join(" ".repeat(n)),a=" ".repeat(this.widths[0]);return this.margin[3]+a+this.margin[1]+o}scaleIndicator(e,t,i){if(typeof this.options.scaleIndicator=="function")return this.options.scaleIndicator.call(this,e,t,i);let n=e.scaleIndex===t.index;return t.disabled?this.styles.hint(this.symbols.radio.disabled):n?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,t){let i=e.scale.map(s=>this.scaleIndicator(e,s,t)),n=this.term==="Hyper"?"":" ";return i.join(n+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=await this.pointer(e,t),s=await e.hint;s&&!cse.hasColor(s)&&(s=this.styles.muted(s));let o=d=>this.margin[3]+d.replace(/\s+$/,"").padEnd(this.widths[0]," "),a=this.newline,l=this.indent(e),c=await this.resolve(e.message,this.state,e,t),u=await this.renderScale(e,t),g=this.margin[1]+this.margin[3];this.scaleLength=hqe.unstyle(u).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-g.length);let p=cse.wordWrap(c,{width:this.widths[0],newline:a}).split(` +`).map(d=>o(d)+this.margin[1]);return i&&(u=this.styles.info(u),p=p.map(d=>this.styles.info(d))),p[0]+=u,this.linebreak&&p.push(""),[l+n,p.join(` +`)].filter(Boolean)}async renderChoices(){if(this.state.submitted)return"";this.tableize();let e=this.visible.map(async(n,s)=>await this.renderChoice(n,s)),t=await Promise.all(e),i=await this.renderScaleHeading();return this.margin[0]+[i,...t.map(n=>n.join(" "))].join(` +`)}async render(){let{submitted:e,size:t}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o="";this.options.promptLine!==!1&&(o=[i,s,n,""].join(" "),this.state.prompt=o);let a=await this.header(),l=await this.format(),c=await this.renderScaleKey(),u=await this.error()||await this.hint(),g=await this.renderChoices(),h=await this.footer(),p=this.emptyError;l&&(o+=l),u&&!o.includes(u)&&(o+=" "+u),e&&!l&&!g.trim()&&this.multiple&&p!=null&&(o+=this.styles.danger(p)),this.clear(t),this.write([a,o,c,g,h].filter(Boolean).join(` +`)),this.state.submitted||this.write(this.margin[2]),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIndex;return this.base.submit.call(this)}};use.exports=xL});var pse=I((uft,hse)=>{"use strict";var fse=uo(),dqe=(r="")=>typeof r=="string"?r.replace(/^['"]|['"]$/g,""):"",DL=class{constructor(e){this.name=e.key,this.field=e.field||{},this.value=dqe(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}},Cqe=async(r={},e={},t=i=>i)=>{let i=new Set,n=r.fields||[],s=r.template,o=[],a=[],l=[],c=1;typeof s=="function"&&(s=await s());let u=-1,g=()=>s[++u],h=()=>s[u+1],p=d=>{d.line=c,o.push(d)};for(p({type:"bos",value:""});u<s.length-1;){let d=g();if(/^[^\S\n ]$/.test(d)){p({type:"text",value:d});continue}if(d===` +`){p({type:"newline",value:d}),c++;continue}if(d==="\\"){d+=g(),p({type:"text",value:d});continue}if((d==="$"||d==="#"||d==="{")&&h()==="{"){let y=g();d+=y;let B={type:"template",open:d,inner:"",close:"",value:d},S;for(;S=g();){if(S==="}"){h()==="}"&&(S+=g()),B.value+=S,B.close=S;break}S===":"?(B.initial="",B.key=B.inner):B.initial!==void 0&&(B.initial+=S),B.value+=S,B.inner+=S}B.template=B.open+(B.initial||B.inner)+B.close,B.key=B.key||B.inner,e.hasOwnProperty(B.key)&&(B.initial=e[B.key]),B=t(B),p(B),l.push(B.key),i.add(B.key);let x=a.find(F=>F.name===B.key);B.field=n.find(F=>F.name===B.key),x||(x=new DL(B),a.push(x)),x.lines.push(B.line-1);continue}let m=o[o.length-1];m.type==="text"&&m.line===c?m.value+=d:p({type:"text",value:d})}return p({type:"eos",value:""}),{input:s,tabstops:o,unique:i,keys:l,items:a}};hse.exports=async r=>{let e=r.options,t=new Set(e.required===!0?[]:e.required||[]),i={...e.values,...e.initial},{tabstops:n,items:s,keys:o}=await Cqe(e,i),a=kL("result",r,e),l=kL("format",r,e),c=kL("validate",r,e,!0),u=r.isValue.bind(r);return async(g={},h=!1)=>{let p=0;g.required=t,g.items=s,g.keys=o,g.output="";let d=async(S,x,F,H)=>{let q=await c(S,x,F,H);return q===!1?"Invalid field "+F.name:q};for(let S of n){let x=S.value,F=S.key;if(S.type!=="template"){x&&(g.output+=x);continue}if(S.type==="template"){let H=s.find(Z=>Z.name===F);e.required===!0&&g.required.add(H.name);let q=[H.input,g.values[H.value],H.value,x].find(u),X=(H.field||{}).message||S.inner;if(h){let Z=await d(g.values[F],g,H,p);if(Z&&typeof Z=="string"||Z===!1){g.invalid.set(F,Z);continue}g.invalid.delete(F);let A=await a(g.values[F],g,H,p);g.output+=fse.unstyle(A);continue}H.placeholder=!1;let W=x;x=await l(x,g,H,p),q!==x?(g.values[F]=q,x=r.styles.typing(q),g.missing.delete(X)):(g.values[F]=void 0,q=`<${X}>`,x=r.styles.primary(q),H.placeholder=!0,g.required.has(F)&&g.missing.add(X)),g.missing.has(X)&&g.validating&&(x=r.styles.warning(q)),g.invalid.has(F)&&g.validating&&(x=r.styles.danger(q)),p===g.index&&(W!==x?x=r.styles.underline(x):x=r.styles.heading(fse.unstyle(x))),p++}x&&(g.output+=x)}let m=g.output.split(` +`).map(S=>" "+S),y=s.length,B=0;for(let S of s)g.invalid.has(S.name)&&S.lines.forEach(x=>{m[x][0]===" "&&(m[x]=g.styles.danger(g.symbols.bullet)+m[x].slice(1))}),r.isValue(g.values[S.name])&&B++;return g.completed=(B/y*100).toFixed(0),g.output=m.join(` +`),g.output}};function kL(r,e,t,i){return(n,s,o,a)=>typeof o.field[r]=="function"?o.field[r].call(e,n,s,o,a):[i,n].find(l=>e.isValue(l))}});var Cse=I((gft,dse)=>{"use strict";var mqe=uo(),Eqe=pse(),Iqe=Gh(),RL=class extends Iqe{constructor(e){super(e),this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await Eqe(this),await super.initialize()}async reset(e){this.state.keys=[],this.state.invalid=new Map,this.state.missing=new Set,this.state.completed=0,this.state.values={},e!==!0&&(await this.initialize(),await this.render())}moveCursor(e){let t=this.getItem();this.cursor+=e,t.cursor+=e}dispatch(e,t){if(!t.code&&!t.ctrl&&e!=null&&this.getItem()){this.append(e,t);return}this.alert()}append(e,t){let i=this.getItem(),n=i.input.slice(0,this.cursor),s=i.input.slice(this.cursor);this.input=i.input=`${n}${e}${s}`,this.moveCursor(1),this.render()}delete(){let e=this.getItem();if(this.cursor<=0||!e.input)return this.alert();let t=e.input.slice(this.cursor),i=e.input.slice(0,this.cursor-1);this.input=e.input=`${i}${t}`,this.moveCursor(-1),this.render()}increment(e){return e>=this.state.keys.length-1?0:e+1}decrement(e){return e<=0?this.state.keys.length-1:e-1}first(){this.state.index=0,this.render()}last(){this.state.index=this.state.keys.length-1,this.render()}right(){if(this.cursor>=this.input.length)return this.alert();this.moveCursor(1),this.render()}left(){if(this.cursor<=0)return this.alert();this.moveCursor(-1),this.render()}prev(){this.state.index=this.decrement(this.state.index),this.getItem(),this.render()}next(){this.state.index=this.increment(this.state.index),this.getItem(),this.render()}up(){this.prev()}down(){this.next()}format(e){let t=this.state.completed<100?this.styles.warning:this.styles.success;return this.state.submitted===!0&&this.state.completed!==100&&(t=this.styles.danger),t(`${this.state.completed}% completed`)}async render(){let{index:e,keys:t=[],submitted:i,size:n}=this.state,s=[this.options.newline,` +`].find(S=>S!=null),o=await this.prefix(),a=await this.separator(),l=await this.message(),c=[o,l,a].filter(Boolean).join(" ");this.state.prompt=c;let u=await this.header(),g=await this.error()||"",h=await this.hint()||"",p=i?"":await this.interpolate(this.state),d=this.state.key=t[e]||"",m=await this.format(d),y=await this.footer();m&&(c+=" "+m),h&&!m&&this.state.completed===0&&(c+=" "+h),this.clear(n);let B=[u,c,p,y,g.trim()];this.write(B.filter(Boolean).join(s)),this.restore()}getItem(e){let{items:t,keys:i,index:n}=this.state,s=t.find(o=>o.name===i[n]);return s&&s.input!=null&&(this.input=s.input,this.cursor=s.cursor),s}async submit(){typeof this.interpolate!="function"&&await this.initialize(),await this.interpolate(this.state,!0);let{invalid:e,missing:t,output:i,values:n}=this.state;if(e.size){let a="";for(let[l,c]of e)a+=`Invalid ${l}: ${c} +`;return this.state.error=a,super.submit()}if(t.size)return this.state.error="Required: "+[...t.keys()].join(", "),super.submit();let o=mqe.unstyle(i).split(` +`).map(a=>a.slice(1)).join(` +`);return this.value={values:n,result:o},super.submit()}};dse.exports=RL});var Ese=I((fft,mse)=>{"use strict";var yqe="(Use <shift>+<up/down> to sort)",wqe=dl(),FL=class extends wqe{constructor(e){super({...e,reorder:!1,sort:!0,multiple:!0}),this.state.hint=[this.options.hint,yqe].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,t){let i=await super.renderChoice(e,t),n=this.symbols.identicalTo+" ",s=this.index===t&&this.sorting?this.styles.muted(n):" ";return this.options.drag===!1&&(s=""),this.options.numbered===!0?s+`${t+1} - `+i:s+i}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}};mse.exports=FL});var yse=I((hft,Ise)=>{"use strict";var Bqe=Mm(),NL=class extends Bqe{constructor(e={}){if(super(e),this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let t=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];t=t.map(i=>this.styles.muted(i)),this.state.header=t.join(` + `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let t=await super.toChoices(...e);for(let i of t)i.scale=bqe(5,this.options),i.scaleIdx=2;return t}dispatch(){this.alert()}space(){let e=this.focused,t=e.scale[e.scaleIdx],i=t.selected;return e.scale.forEach(n=>n.selected=!1),t.selected=!i,this.render()}indicator(){return""}pointer(){return""}separator(){return this.styles.muted(this.symbols.ellipsis)}right(){let e=this.focused;return e.scaleIdx>=e.scale.length-1?this.alert():(e.scaleIdx++,this.render())}left(){let e=this.focused;return e.scaleIdx<=0?this.alert():(e.scaleIdx--,this.render())}indent(){return" "}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=this.term==="Hyper",s=n?9:8,o=n?"":" ",a=this.symbols.line.repeat(s),l=" ".repeat(s+(n?0:1)),c=x=>(x?this.styles.success("\u25C9"):"\u25EF")+o,u=t+1+".",g=i?this.styles.heading:this.styles.noop,h=await this.resolve(e.message,this.state,e,t),p=this.indent(e),d=p+e.scale.map((x,F)=>c(F===e.scaleIdx)).join(a),m=x=>x===e.scaleIdx?g(x):x,y=p+e.scale.map((x,F)=>m(F)).join(l),B=()=>[u,h].filter(Boolean).join(" "),S=()=>[B(),d,y," "].filter(Boolean).join(` +`);return i&&(d=this.styles.cyan(d),y=this.styles.cyan(y)),S()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(i,n)=>await this.renderChoice(i,n)),t=await Promise.all(e);return t.length||t.push(this.styles.danger("No matching choices")),t.join(` +`)}format(){return this.state.submitted?this.choices.map(t=>this.styles.info(t.scaleIdx)).join(", "):""}async render(){let{submitted:e,size:t}=this.state,i=await this.prefix(),n=await this.separator(),s=await this.message(),o=[i,s,n].filter(Boolean).join(" ");this.state.prompt=o;let a=await this.header(),l=await this.format(),c=await this.error()||await this.hint(),u=await this.renderChoices(),g=await this.footer();(l||!c)&&(o+=" "+l),c&&!o.includes(c)&&(o+=" "+c),e&&!l&&!u&&this.multiple&&this.type!=="form"&&(o+=this.styles.danger(this.emptyError)),this.clear(t),this.write([o,a,u,g].filter(Boolean).join(` +`)),this.restore()}submit(){this.value={};for(let e of this.choices)this.value[e.name]=e.scaleIdx;return this.base.submit.call(this)}};function bqe(r,e={}){if(Array.isArray(e.scale))return e.scale.map(i=>({...i}));let t=[];for(let i=1;i<r+1;i++)t.push({i,selected:!1});return t}Ise.exports=NL});var Bse=I((pft,wse)=>{wse.exports=wL()});var Qse=I((dft,bse)=>{"use strict";var Qqe=vb(),TL=class extends Qqe{async initialize(){await super.initialize(),this.value=this.initial=!!this.options.initial,this.disabled=this.options.disabled||"no",this.enabled=this.options.enabled||"yes",await this.render()}reset(){this.value=this.initial,this.render()}delete(){this.alert()}toggle(){this.value=!this.value,this.render()}enable(){if(this.value===!0)return this.alert();this.value=!0,this.render()}disable(){if(this.value===!1)return this.alert();this.value=!1,this.render()}up(){this.toggle()}down(){this.toggle()}right(){this.toggle()}left(){this.toggle()}next(){this.toggle()}prev(){this.toggle()}dispatch(e="",t){switch(e.toLowerCase()){case" ":return this.toggle();case"1":case"y":case"t":return this.enable();case"0":case"n":case"f":return this.disable();default:return this.alert()}}format(){let e=i=>this.styles.primary.underline(i);return[this.value?this.disabled:e(this.disabled),this.value?e(this.enabled):this.enabled].join(this.styles.muted(" / "))}async render(){let{size:e}=this.state,t=await this.header(),i=await this.prefix(),n=await this.separator(),s=await this.message(),o=await this.format(),a=await this.error()||await this.hint(),l=await this.footer(),c=[i,s,n,o].join(" ");this.state.prompt=c,a&&!c.includes(a)&&(c+=" "+a),this.clear(e),this.write([t,c,l].filter(Boolean).join(` +`)),this.write(this.margin[2]),this.restore()}};bse.exports=TL});var vse=I((Cft,Sse)=>{"use strict";var Sqe=dl(),LL=class extends Sqe{constructor(e){if(super(e),typeof this.options.correctChoice!="number"||this.options.correctChoice<0)throw new Error("Please specify the index of the correct answer from the list of choices")}async toChoices(e,t){let i=await super.toChoices(e,t);if(i.length<2)throw new Error("Please give at least two choices to the user");if(this.options.correctChoice>i.length)throw new Error("Please specify the index of the correct answer from the list of choices");return i}check(e){return e.index===this.options.correctChoice}async result(e){return{selectedAnswer:e,correctAnswer:this.options.choices[this.options.correctChoice].value,correct:await this.check(this.state)}}};Sse.exports=LL});var xse=I(OL=>{"use strict";var Pse=Yi(),ci=(r,e)=>{Pse.defineExport(OL,r,e),Pse.defineExport(OL,r.toLowerCase(),e)};ci("AutoComplete",()=>Tne());ci("BasicAuth",()=>jne());ci("Confirm",()=>qne());ci("Editable",()=>Wne());ci("Form",()=>Sb());ci("Input",()=>wL());ci("Invisible",()=>ese());ci("List",()=>rse());ci("MultiSelect",()=>nse());ci("Numeral",()=>ase());ci("Password",()=>lse());ci("Scale",()=>gse());ci("Select",()=>dl());ci("Snippet",()=>Cse());ci("Sort",()=>Ese());ci("Survey",()=>yse());ci("Text",()=>Bse());ci("Toggle",()=>Qse());ci("Quiz",()=>vse())});var Dse=I((Eft,kse)=>{kse.exports={ArrayPrompt:Mm(),AuthPrompt:dL(),BooleanPrompt:vb(),NumberPrompt:vL(),StringPrompt:lu()}});var Um=I((Ift,Fse)=>{"use strict";var Rse=J("assert"),KL=J("events"),Cl=Yi(),fo=class extends KL{constructor(e,t){super(),this.options=Cl.merge({},e),this.answers={...t}}register(e,t){if(Cl.isObject(e)){for(let n of Object.keys(e))this.register(n,e[n]);return this}Rse.equal(typeof t,"function","expected a function");let i=e.toLowerCase();return t.prototype instanceof this.Prompt?this.prompts[i]=t:this.prompts[i]=t(this.Prompt,this),this}async prompt(e=[]){for(let t of[].concat(e))try{typeof t=="function"&&(t=await t.call(this)),await this.ask(Cl.merge({},this.options,t))}catch(i){return Promise.reject(i)}return this.answers}async ask(e){typeof e=="function"&&(e=await e.call(this));let t=Cl.merge({},this.options,e),{type:i,name:n}=e,{set:s,get:o}=Cl;if(typeof i=="function"&&(i=await i.call(this,e,this.answers)),!i)return this.answers[n];Rse(this.prompts[i],`Prompt "${i}" is not registered`);let a=new this.prompts[i](t),l=o(this.answers,n);a.state.answers=this.answers,a.enquirer=this,n&&a.on("submit",u=>{this.emit("answer",n,u,a),s(this.answers,n,u)});let c=a.emit.bind(a);return a.emit=(...u)=>(this.emit.call(this,...u),c(...u)),this.emit("prompt",a,this),t.autofill&&l!=null?(a.value=a.input=l,t.autofill==="show"&&await a.submit()):l=a.value=await a.run(),l}use(e){return e.call(this,this),this}set Prompt(e){this._Prompt=e}get Prompt(){return this._Prompt||this.constructor.Prompt}get prompts(){return this.constructor.prompts}static set Prompt(e){this._Prompt=e}static get Prompt(){return this._Prompt||Gh()}static get prompts(){return xse()}static get types(){return Dse()}static get prompt(){let e=(t,...i)=>{let n=new this(...i),s=n.emit.bind(n);return n.emit=(...o)=>(e.emit(...o),s(...o)),n.prompt(t)};return Cl.mixinEmitter(e,new KL),e}};Cl.mixinEmitter(fo,new KL);var ML=fo.prompts;for(let r of Object.keys(ML)){let e=r.toLowerCase(),t=i=>new ML[r](i).run();fo.prompt[e]=t,fo[e]=t,fo[r]||Reflect.defineProperty(fo,r,{get:()=>ML[r]})}var Km=r=>{Cl.defineExport(fo,r,()=>fo.types[r])};Km("ArrayPrompt");Km("AuthPrompt");Km("BooleanPrompt");Km("NumberPrompt");Km("StringPrompt");Fse.exports=fo});var Gse=I((aht,jse)=>{function Dqe(r,e){for(var t=-1,i=r==null?0:r.length;++t<i&&e(r[t],t,r)!==!1;);return r}jse.exports=Dqe});var Jh=I((Aht,Yse)=>{var Rqe=j0(),Fqe=bh();function Nqe(r,e,t,i){var n=!t;t||(t={});for(var s=-1,o=e.length;++s<o;){var a=e[s],l=i?i(t[a],r[a],a,t,r):void 0;l===void 0&&(l=r[a]),n?Fqe(t,a,l):Rqe(t,a,l)}return t}Yse.exports=Nqe});var Jse=I((lht,qse)=>{var Tqe=Jh(),Lqe=Rh();function Oqe(r,e){return r&&Tqe(e,Lqe(e),r)}qse.exports=Oqe});var zse=I((cht,Wse)=>{function Mqe(r){var e=[];if(r!=null)for(var t in Object(r))e.push(t);return e}Wse.exports=Mqe});var Xse=I((uht,Vse)=>{var Kqe=vn(),Uqe=ob(),Hqe=zse(),jqe=Object.prototype,Gqe=jqe.hasOwnProperty;function Yqe(r){if(!Kqe(r))return Hqe(r);var e=Uqe(r),t=[];for(var i in r)i=="constructor"&&(e||!Gqe.call(r,i))||t.push(i);return t}Vse.exports=Yqe});var Wh=I((ght,Zse)=>{var qqe=lT(),Jqe=Xse(),Wqe=fm();function zqe(r){return Wqe(r)?qqe(r,!0):Jqe(r)}Zse.exports=zqe});var $se=I((fht,_se)=>{var Vqe=Jh(),Xqe=Wh();function Zqe(r,e){return r&&Vqe(e,Xqe(e),r)}_se.exports=Zqe});var qL=I((Ym,zh)=>{var _qe=Is(),ioe=typeof Ym=="object"&&Ym&&!Ym.nodeType&&Ym,eoe=ioe&&typeof zh=="object"&&zh&&!zh.nodeType&&zh,$qe=eoe&&eoe.exports===ioe,toe=$qe?_qe.Buffer:void 0,roe=toe?toe.allocUnsafe:void 0;function eJe(r,e){if(e)return r.slice();var t=r.length,i=roe?roe(t):new r.constructor(t);return r.copy(i),i}zh.exports=eJe});var JL=I((hht,noe)=>{function tJe(r,e){var t=-1,i=r.length;for(e||(e=Array(i));++t<i;)e[t]=r[t];return e}noe.exports=tJe});var ooe=I((pht,soe)=>{var rJe=Jh(),iJe=Ab();function nJe(r,e){return rJe(r,iJe(r),e)}soe.exports=nJe});var kb=I((dht,aoe)=>{var sJe=cT(),oJe=sJe(Object.getPrototypeOf,Object);aoe.exports=oJe});var WL=I((Cht,Aoe)=>{var aJe=Y0(),AJe=kb(),lJe=Ab(),cJe=dT(),uJe=Object.getOwnPropertySymbols,gJe=uJe?function(r){for(var e=[];r;)aJe(e,lJe(r)),r=AJe(r);return e}:cJe;Aoe.exports=gJe});var coe=I((mht,loe)=>{var fJe=Jh(),hJe=WL();function pJe(r,e){return fJe(r,hJe(r),e)}loe.exports=pJe});var goe=I((Eht,uoe)=>{var dJe=pT(),CJe=WL(),mJe=Wh();function EJe(r){return dJe(r,mJe,CJe)}uoe.exports=EJe});var hoe=I((Iht,foe)=>{var IJe=Object.prototype,yJe=IJe.hasOwnProperty;function wJe(r){var e=r.length,t=new r.constructor(e);return e&&typeof r[0]=="string"&&yJe.call(r,"index")&&(t.index=r.index,t.input=r.input),t}foe.exports=wJe});var Db=I((yht,doe)=>{var poe=fT();function BJe(r){var e=new r.constructor(r.byteLength);return new poe(e).set(new poe(r)),e}doe.exports=BJe});var moe=I((wht,Coe)=>{var bJe=Db();function QJe(r,e){var t=e?bJe(r.buffer):r.buffer;return new r.constructor(t,r.byteOffset,r.byteLength)}Coe.exports=QJe});var Ioe=I((Bht,Eoe)=>{var SJe=/\w*$/;function vJe(r){var e=new r.constructor(r.source,SJe.exec(r));return e.lastIndex=r.lastIndex,e}Eoe.exports=vJe});var Qoe=I((bht,boe)=>{var yoe=Nc(),woe=yoe?yoe.prototype:void 0,Boe=woe?woe.valueOf:void 0;function PJe(r){return Boe?Object(Boe.call(r)):{}}boe.exports=PJe});var zL=I((Qht,Soe)=>{var xJe=Db();function kJe(r,e){var t=e?xJe(r.buffer):r.buffer;return new r.constructor(t,r.byteOffset,r.length)}Soe.exports=kJe});var Poe=I((Sht,voe)=>{var DJe=Db(),RJe=moe(),FJe=Ioe(),NJe=Qoe(),TJe=zL(),LJe="[object Boolean]",OJe="[object Date]",MJe="[object Map]",KJe="[object Number]",UJe="[object RegExp]",HJe="[object Set]",jJe="[object String]",GJe="[object Symbol]",YJe="[object ArrayBuffer]",qJe="[object DataView]",JJe="[object Float32Array]",WJe="[object Float64Array]",zJe="[object Int8Array]",VJe="[object Int16Array]",XJe="[object Int32Array]",ZJe="[object Uint8Array]",_Je="[object Uint8ClampedArray]",$Je="[object Uint16Array]",e3e="[object Uint32Array]";function t3e(r,e,t){var i=r.constructor;switch(e){case YJe:return DJe(r);case LJe:case OJe:return new i(+r);case qJe:return RJe(r,t);case JJe:case WJe:case zJe:case VJe:case XJe:case ZJe:case _Je:case $Je:case e3e:return TJe(r,t);case MJe:return new i;case KJe:case jJe:return new i(r);case UJe:return FJe(r);case HJe:return new i;case GJe:return NJe(r)}}voe.exports=t3e});var Doe=I((vht,koe)=>{var r3e=vn(),xoe=Object.create,i3e=function(){function r(){}return function(e){if(!r3e(e))return{};if(xoe)return xoe(e);r.prototype=e;var t=new r;return r.prototype=void 0,t}}();koe.exports=i3e});var VL=I((Pht,Roe)=>{var n3e=Doe(),s3e=kb(),o3e=ob();function a3e(r){return typeof r.constructor=="function"&&!o3e(r)?n3e(s3e(r)):{}}Roe.exports=a3e});var Noe=I((xht,Foe)=>{var A3e=pm(),l3e=Jo(),c3e="[object Map]";function u3e(r){return l3e(r)&&A3e(r)==c3e}Foe.exports=u3e});var Moe=I((kht,Ooe)=>{var g3e=Noe(),f3e=ib(),Toe=nb(),Loe=Toe&&Toe.isMap,h3e=Loe?f3e(Loe):g3e;Ooe.exports=h3e});var Uoe=I((Dht,Koe)=>{var p3e=pm(),d3e=Jo(),C3e="[object Set]";function m3e(r){return d3e(r)&&p3e(r)==C3e}Koe.exports=m3e});var Yoe=I((Rht,Goe)=>{var E3e=Uoe(),I3e=ib(),Hoe=nb(),joe=Hoe&&Hoe.isSet,y3e=joe?I3e(joe):E3e;Goe.exports=y3e});var Voe=I((Fht,zoe)=>{var w3e=hm(),B3e=Gse(),b3e=j0(),Q3e=Jse(),S3e=$se(),v3e=qL(),P3e=JL(),x3e=ooe(),k3e=coe(),D3e=CT(),R3e=goe(),F3e=pm(),N3e=hoe(),T3e=Poe(),L3e=VL(),O3e=Ss(),M3e=cm(),K3e=Moe(),U3e=vn(),H3e=Yoe(),j3e=Rh(),G3e=Wh(),Y3e=1,q3e=2,J3e=4,qoe="[object Arguments]",W3e="[object Array]",z3e="[object Boolean]",V3e="[object Date]",X3e="[object Error]",Joe="[object Function]",Z3e="[object GeneratorFunction]",_3e="[object Map]",$3e="[object Number]",Woe="[object Object]",eWe="[object RegExp]",tWe="[object Set]",rWe="[object String]",iWe="[object Symbol]",nWe="[object WeakMap]",sWe="[object ArrayBuffer]",oWe="[object DataView]",aWe="[object Float32Array]",AWe="[object Float64Array]",lWe="[object Int8Array]",cWe="[object Int16Array]",uWe="[object Int32Array]",gWe="[object Uint8Array]",fWe="[object Uint8ClampedArray]",hWe="[object Uint16Array]",pWe="[object Uint32Array]",lr={};lr[qoe]=lr[W3e]=lr[sWe]=lr[oWe]=lr[z3e]=lr[V3e]=lr[aWe]=lr[AWe]=lr[lWe]=lr[cWe]=lr[uWe]=lr[_3e]=lr[$3e]=lr[Woe]=lr[eWe]=lr[tWe]=lr[rWe]=lr[iWe]=lr[gWe]=lr[fWe]=lr[hWe]=lr[pWe]=!0;lr[X3e]=lr[Joe]=lr[nWe]=!1;function Rb(r,e,t,i,n,s){var o,a=e&Y3e,l=e&q3e,c=e&J3e;if(t&&(o=n?t(r,i,n,s):t(r)),o!==void 0)return o;if(!U3e(r))return r;var u=O3e(r);if(u){if(o=N3e(r),!a)return P3e(r,o)}else{var g=F3e(r),h=g==Joe||g==Z3e;if(M3e(r))return v3e(r,a);if(g==Woe||g==qoe||h&&!n){if(o=l||h?{}:L3e(r),!a)return l?k3e(r,S3e(o,r)):x3e(r,Q3e(o,r))}else{if(!lr[g])return n?r:{};o=T3e(r,g,a)}}s||(s=new w3e);var p=s.get(r);if(p)return p;s.set(r,o),H3e(r)?r.forEach(function(y){o.add(Rb(y,e,t,y,r,s))}):K3e(r)&&r.forEach(function(y,B){o.set(B,Rb(y,e,t,B,r,s))});var d=c?l?R3e:D3e:l?G3e:j3e,m=u?void 0:d(r);return B3e(m||r,function(y,B){m&&(B=y,y=r[B]),b3e(o,B,Rb(y,e,t,B,r,s))}),o}zoe.exports=Rb});var XL=I((Nht,Xoe)=>{var dWe=Voe(),CWe=1,mWe=4;function EWe(r){return dWe(r,CWe|mWe)}Xoe.exports=EWe});var _oe=I((Tht,Zoe)=>{var IWe=HN();function yWe(r,e,t){return r==null?r:IWe(r,e,t)}Zoe.exports=yWe});var iae=I((Hht,rae)=>{function wWe(r){var e=r==null?0:r.length;return e?r[e-1]:void 0}rae.exports=wWe});var sae=I((jht,nae)=>{var BWe=im(),bWe=HR();function QWe(r,e){return e.length<2?r:BWe(r,bWe(e,0,-1))}nae.exports=QWe});var aae=I((Ght,oae)=>{var SWe=Bh(),vWe=iae(),PWe=sae(),xWe=$c();function kWe(r,e){return e=SWe(e,r),r=PWe(r,e),r==null||delete r[xWe(vWe(e))]}oae.exports=kWe});var lae=I((Yht,Aae)=>{var DWe=aae();function RWe(r,e){return r==null?!0:DWe(r,e)}Aae.exports=RWe});var hae=I((mpt,TWe)=>{TWe.exports={name:"@yarnpkg/cli",version:"3.8.1",license:"BSD-2-Clause",main:"./sources/index.ts",dependencies:{"@yarnpkg/core":"workspace:^","@yarnpkg/fslib":"workspace:^","@yarnpkg/libzip":"workspace:^","@yarnpkg/parsers":"workspace:^","@yarnpkg/plugin-compat":"workspace:^","@yarnpkg/plugin-dlx":"workspace:^","@yarnpkg/plugin-essentials":"workspace:^","@yarnpkg/plugin-file":"workspace:^","@yarnpkg/plugin-git":"workspace:^","@yarnpkg/plugin-github":"workspace:^","@yarnpkg/plugin-http":"workspace:^","@yarnpkg/plugin-init":"workspace:^","@yarnpkg/plugin-link":"workspace:^","@yarnpkg/plugin-nm":"workspace:^","@yarnpkg/plugin-npm":"workspace:^","@yarnpkg/plugin-npm-cli":"workspace:^","@yarnpkg/plugin-pack":"workspace:^","@yarnpkg/plugin-patch":"workspace:^","@yarnpkg/plugin-pnp":"workspace:^","@yarnpkg/plugin-pnpm":"workspace:^","@yarnpkg/shell":"workspace:^","ci-info":"^3.2.0",clipanion:"3.2.0-rc.4",semver:"^7.1.2",tslib:"^1.13.0",typanion:"^3.3.0",yup:"^0.32.9"},devDependencies:{"@types/semver":"^7.1.0","@types/yup":"^0","@yarnpkg/builder":"workspace:^","@yarnpkg/monorepo":"workspace:^","@yarnpkg/pnpify":"workspace:^",micromatch:"^4.0.2"},peerDependencies:{"@yarnpkg/core":"workspace:^"},scripts:{postpack:"rm -rf lib",prepack:'run build:compile "$(pwd)"',"build:cli+hook":"run build:pnp:hook && builder build bundle","build:cli":"builder build bundle","run:cli":"builder run","update-local":"run build:cli --no-git-hash && rsync -a --delete bundles/ bin/"},publishConfig:{main:"./lib/index.js",types:"./lib/index.d.ts",bin:null},files:["/lib/**/*","!/lib/pluginConfiguration.*","!/lib/cli.*"],"@yarnpkg/builder":{bundles:{standard:["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm"]}},repository:{type:"git",url:"ssh://git@github.com/yarnpkg/berry.git",directory:"packages/yarnpkg-cli"},engines:{node:">=12 <14 || 14.2 - 14.9 || >14.10.0"}}});var oO=I((Gmt,Pae)=>{"use strict";Pae.exports=function(e,t){t===!0&&(t=0);var i="";if(typeof e=="string")try{i=new URL(e).protocol}catch{}else e&&e.constructor===URL&&(i=e.protocol);var n=i.split(/\:|\+/).filter(Boolean);return typeof t=="number"?n[t]:n}});var kae=I((Ymt,xae)=>{"use strict";var e4e=oO();function t4e(r){var e={protocols:[],protocol:null,port:null,resource:"",host:"",user:"",password:"",pathname:"",hash:"",search:"",href:r,query:{},parse_failed:!1};try{var t=new URL(r);e.protocols=e4e(t),e.protocol=e.protocols[0],e.port=t.port,e.resource=t.hostname,e.host=t.host,e.user=t.username||"",e.password=t.password||"",e.pathname=t.pathname,e.hash=t.hash.slice(1),e.search=t.search.slice(1),e.href=t.href,e.query=Object.fromEntries(t.searchParams)}catch{e.protocols=["file"],e.protocol=e.protocols[0],e.port="",e.resource="",e.user="",e.pathname="",e.hash="",e.search="",e.href=r,e.query={},e.parse_failed=!0}return e}xae.exports=t4e});var Fae=I((qmt,Rae)=>{"use strict";var r4e=kae();function i4e(r){return r&&typeof r=="object"&&"default"in r?r:{default:r}}var n4e=i4e(r4e),s4e="text/plain",o4e="us-ascii",Dae=(r,e)=>e.some(t=>t instanceof RegExp?t.test(r):t===r),a4e=(r,{stripHash:e})=>{let t=/^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(r);if(!t)throw new Error(`Invalid URL: ${r}`);let{type:i,data:n,hash:s}=t.groups,o=i.split(";");s=e?"":s;let a=!1;o[o.length-1]==="base64"&&(o.pop(),a=!0);let l=(o.shift()||"").toLowerCase(),u=[...o.map(g=>{let[h,p=""]=g.split("=").map(d=>d.trim());return h==="charset"&&(p=p.toLowerCase(),p===o4e)?"":`${h}${p?`=${p}`:""}`}).filter(Boolean)];return a&&u.push("base64"),(u.length>0||l&&l!==s4e)&&u.unshift(l),`data:${u.join(";")},${a?n.trim():n}${s?`#${s}`:""}`};function A4e(r,e){if(e={defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripTextFragment:!0,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeSingleSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0,...e},r=r.trim(),/^data:/i.test(r))return a4e(r,e);if(/^view-source:/i.test(r))throw new Error("`view-source:` is not supported as it is a non-standard protocol");let t=r.startsWith("//");!t&&/^\.*\//.test(r)||(r=r.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new URL(r);if(e.forceHttp&&e.forceHttps)throw new Error("The `forceHttp` and `forceHttps` options cannot be used together");if(e.forceHttp&&n.protocol==="https:"&&(n.protocol="http:"),e.forceHttps&&n.protocol==="http:"&&(n.protocol="https:"),e.stripAuthentication&&(n.username="",n.password=""),e.stripHash?n.hash="":e.stripTextFragment&&(n.hash=n.hash.replace(/#?:~:text.*?$/i,"")),n.pathname){let o=/\b[a-z][a-z\d+\-.]{1,50}:\/\//g,a=0,l="";for(;;){let u=o.exec(n.pathname);if(!u)break;let g=u[0],h=u.index,p=n.pathname.slice(a,h);l+=p.replace(/\/{2,}/g,"/"),l+=g,a=h+g.length}let c=n.pathname.slice(a,n.pathname.length);l+=c.replace(/\/{2,}/g,"/"),n.pathname=l}if(n.pathname)try{n.pathname=decodeURI(n.pathname)}catch{}if(e.removeDirectoryIndex===!0&&(e.removeDirectoryIndex=[/^index\.[a-z]+$/]),Array.isArray(e.removeDirectoryIndex)&&e.removeDirectoryIndex.length>0){let o=n.pathname.split("/"),a=o[o.length-1];Dae(a,e.removeDirectoryIndex)&&(o=o.slice(0,-1),n.pathname=o.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let o of[...n.searchParams.keys()])Dae(o,e.removeQueryParameters)&&n.searchParams.delete(o);if(e.removeQueryParameters===!0&&(n.search=""),e.sortQueryParameters){n.searchParams.sort();try{n.search=decodeURIComponent(n.search)}catch{}}e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,""));let s=r;return r=n.toString(),!e.removeSingleSlash&&n.pathname==="/"&&!s.endsWith("/")&&n.hash===""&&(r=r.replace(/\/$/,"")),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&e.removeSingleSlash&&(r=r.replace(/\/$/,"")),t&&!e.normalizeProtocol&&(r=r.replace(/^http:\/\//,"//")),e.stripProtocol&&(r=r.replace(/^(?:https?:)?\/\//,"")),r}var aO=(r,e=!1)=>{let t=/^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/,i=s=>{let o=new Error(s);throw o.subject_url=r,o};(typeof r!="string"||!r.trim())&&i("Invalid url."),r.length>aO.MAX_INPUT_LENGTH&&i("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH."),e&&(typeof e!="object"&&(e={stripHash:!1}),r=A4e(r,e));let n=n4e.default(r);if(n.parse_failed){let s=n.href.match(t);s?(n.protocols=["ssh"],n.protocol="ssh",n.resource=s[2],n.host=s[2],n.user=s[1],n.pathname=`/${s[3]}`,n.parse_failed=!1):i("URL parsing failed.")}return n};aO.MAX_INPUT_LENGTH=2048;Rae.exports=aO});var Lae=I((Jmt,Tae)=>{"use strict";var l4e=oO();function Nae(r){if(Array.isArray(r))return r.indexOf("ssh")!==-1||r.indexOf("rsync")!==-1;if(typeof r!="string")return!1;var e=l4e(r);if(r=r.substring(r.indexOf("://")+3),Nae(e))return!0;var t=new RegExp(".([a-zA-Z\\d]+):(\\d+)/");return!r.match(t)&&r.indexOf("@")<r.indexOf(":")}Tae.exports=Nae});var Kae=I((Wmt,Mae)=>{"use strict";var c4e=Fae(),Oae=Lae();function u4e(r){var e=c4e(r);return e.token="",e.password==="x-oauth-basic"?e.token=e.user:e.user==="x-token-auth"&&(e.token=e.password),Oae(e.protocols)||e.protocols.length===0&&Oae(r)?e.protocol="ssh":e.protocols.length?e.protocol=e.protocols[0]:(e.protocol="file",e.protocols=["file"]),e.href=e.href.replace(/\/$/,""),e}Mae.exports=u4e});var Hae=I((zmt,Uae)=>{"use strict";var g4e=Kae();function AO(r){if(typeof r!="string")throw new Error("The url must be a string.");var e=/^([a-z\d-]{1,39})\/([-\.\w]{1,100})$/i;e.test(r)&&(r="https://github.com/"+r);var t=g4e(r),i=t.resource.split("."),n=null;switch(t.toString=function(y){return AO.stringify(this,y)},t.source=i.length>2?i.slice(1-i.length).join("."):t.source=t.resource,t.git_suffix=/\.git$/.test(t.pathname),t.name=decodeURIComponent((t.pathname||t.href).replace(/(^\/)|(\/$)/g,"").replace(/\.git$/,"")),t.owner=decodeURIComponent(t.user),t.source){case"git.cloudforge.com":t.owner=t.user,t.organization=i[0],t.source="cloudforge.com";break;case"visualstudio.com":if(t.resource==="vs-ssh.visualstudio.com"){n=t.name.split("/"),n.length===4&&(t.organization=n[1],t.owner=n[2],t.name=n[3],t.full_name=n[2]+"/"+n[3]);break}else{n=t.name.split("/"),n.length===2?(t.owner=n[1],t.name=n[1],t.full_name="_git/"+t.name):n.length===3?(t.name=n[2],n[0]==="DefaultCollection"?(t.owner=n[2],t.organization=n[0],t.full_name=t.organization+"/_git/"+t.name):(t.owner=n[0],t.full_name=t.owner+"/_git/"+t.name)):n.length===4&&(t.organization=n[0],t.owner=n[1],t.name=n[3],t.full_name=t.organization+"/"+t.owner+"/_git/"+t.name);break}case"dev.azure.com":case"azure.com":if(t.resource==="ssh.dev.azure.com"){n=t.name.split("/"),n.length===4&&(t.organization=n[1],t.owner=n[2],t.name=n[3]);break}else{n=t.name.split("/"),n.length===5?(t.organization=n[0],t.owner=n[1],t.name=n[4],t.full_name="_git/"+t.name):n.length===3?(t.name=n[2],n[0]==="DefaultCollection"?(t.owner=n[2],t.organization=n[0],t.full_name=t.organization+"/_git/"+t.name):(t.owner=n[0],t.full_name=t.owner+"/_git/"+t.name)):n.length===4&&(t.organization=n[0],t.owner=n[1],t.name=n[3],t.full_name=t.organization+"/"+t.owner+"/_git/"+t.name),t.query&&t.query.path&&(t.filepath=t.query.path.replace(/^\/+/g,"")),t.query&&t.query.version&&(t.ref=t.query.version.replace(/^GB/,""));break}default:n=t.name.split("/");var s=n.length-1;if(n.length>=2){var o=n.indexOf("-",2),a=n.indexOf("blob",2),l=n.indexOf("tree",2),c=n.indexOf("commit",2),u=n.indexOf("src",2),g=n.indexOf("raw",2),h=n.indexOf("edit",2);s=o>0?o-1:a>0?a-1:l>0?l-1:c>0?c-1:u>0?u-1:g>0?g-1:h>0?h-1:s,t.owner=n.slice(0,s).join("/"),t.name=n[s],c&&(t.commit=n[s+2])}t.ref="",t.filepathtype="",t.filepath="";var p=n.length>s&&n[s+1]==="-"?s+1:s;n.length>p+2&&["raw","src","blob","tree","edit"].indexOf(n[p+1])>=0&&(t.filepathtype=n[p+1],t.ref=n[p+2],n.length>p+3&&(t.filepath=n.slice(p+3).join("/"))),t.organization=t.owner;break}t.full_name||(t.full_name=t.owner,t.name&&(t.full_name&&(t.full_name+="/"),t.full_name+=t.name)),t.owner.startsWith("scm/")&&(t.source="bitbucket-server",t.owner=t.owner.replace("scm/",""),t.organization=t.owner,t.full_name=t.owner+"/"+t.name);var d=/(projects|users)\/(.*?)\/repos\/(.*?)((\/.*$)|$)/,m=d.exec(t.pathname);return m!=null&&(t.source="bitbucket-server",m[1]==="users"?t.owner="~"+m[2]:t.owner=m[2],t.organization=t.owner,t.name=m[3],n=m[4].split("/"),n.length>1&&(["raw","browse"].indexOf(n[1])>=0?(t.filepathtype=n[1],n.length>2&&(t.filepath=n.slice(2).join("/"))):n[1]==="commits"&&n.length>2&&(t.commit=n[2])),t.full_name=t.owner+"/"+t.name,t.query.at?t.ref=t.query.at:t.ref=""),t}AO.stringify=function(r,e){e=e||(r.protocols&&r.protocols.length?r.protocols.join("+"):r.protocol);var t=r.port?":"+r.port:"",i=r.user||"git",n=r.git_suffix?".git":"";switch(e){case"ssh":return t?"ssh://"+i+"@"+r.resource+t+"/"+r.full_name+n:i+"@"+r.resource+":"+r.full_name+n;case"git+ssh":case"ssh+git":case"ftp":case"ftps":return e+"://"+i+"@"+r.resource+t+"/"+r.full_name+n;case"http":case"https":var s=r.token?f4e(r):r.user&&(r.protocols.includes("http")||r.protocols.includes("https"))?r.user+"@":"";return e+"://"+s+r.resource+t+"/"+h4e(r)+n;default:return r.href}};function f4e(r){switch(r.source){case"bitbucket.org":return"x-token-auth:"+r.token+"@";default:return r.token+"@"}}function h4e(r){switch(r.source){case"bitbucket-server":return"scm/"+r.full_name;default:return""+r.full_name}}Uae.exports=AO});var kO=I((Myt,AAe)=>{var T4e=bh(),L4e=Ih();function O4e(r,e,t){(t!==void 0&&!L4e(r[e],t)||t===void 0&&!(e in r))&&T4e(r,e,t)}AAe.exports=O4e});var cAe=I((Kyt,lAe)=>{var M4e=fm(),K4e=Jo();function U4e(r){return K4e(r)&&M4e(r)}lAe.exports=U4e});var fAe=I((Uyt,gAe)=>{var H4e=Tc(),j4e=kb(),G4e=Jo(),Y4e="[object Object]",q4e=Function.prototype,J4e=Object.prototype,uAe=q4e.toString,W4e=J4e.hasOwnProperty,z4e=uAe.call(Object);function V4e(r){if(!G4e(r)||H4e(r)!=Y4e)return!1;var e=j4e(r);if(e===null)return!0;var t=W4e.call(e,"constructor")&&e.constructor;return typeof t=="function"&&t instanceof t&&uAe.call(t)==z4e}gAe.exports=V4e});var DO=I((Hyt,hAe)=>{function X4e(r,e){if(!(e==="constructor"&&typeof r[e]=="function")&&e!="__proto__")return r[e]}hAe.exports=X4e});var dAe=I((jyt,pAe)=>{var Z4e=Jh(),_4e=Wh();function $4e(r){return Z4e(r,_4e(r))}pAe.exports=$4e});var wAe=I((Gyt,yAe)=>{var CAe=kO(),e8e=qL(),t8e=zL(),r8e=JL(),i8e=VL(),mAe=sm(),EAe=Ss(),n8e=cAe(),s8e=cm(),o8e=K0(),a8e=vn(),A8e=fAe(),l8e=sb(),IAe=DO(),c8e=dAe();function u8e(r,e,t,i,n,s,o){var a=IAe(r,t),l=IAe(e,t),c=o.get(l);if(c){CAe(r,t,c);return}var u=s?s(a,l,t+"",r,e,o):void 0,g=u===void 0;if(g){var h=EAe(l),p=!h&&s8e(l),d=!h&&!p&&l8e(l);u=l,h||p||d?EAe(a)?u=a:n8e(a)?u=r8e(a):p?(g=!1,u=e8e(l,!0)):d?(g=!1,u=t8e(l,!0)):u=[]:A8e(l)||mAe(l)?(u=a,mAe(a)?u=c8e(a):(!a8e(a)||o8e(a))&&(u=i8e(l))):g=!1}g&&(o.set(l,u),n(u,l,i,s,o),o.delete(l)),CAe(r,t,u)}yAe.exports=u8e});var QAe=I((Yyt,bAe)=>{var g8e=hm(),f8e=kO(),h8e=aT(),p8e=wAe(),d8e=vn(),C8e=Wh(),m8e=DO();function BAe(r,e,t,i,n){r!==e&&h8e(e,function(s,o){if(n||(n=new g8e),d8e(s))p8e(r,e,o,t,BAe,i,n);else{var a=i?i(m8e(r,o),s,o+"",r,e,n):void 0;a===void 0&&(a=s),f8e(r,o,a)}},C8e)}bAe.exports=BAe});var vAe=I((qyt,SAe)=>{var E8e=q0(),I8e=YN(),y8e=qN();function w8e(r,e){return y8e(I8e(r,e,E8e),r+"")}SAe.exports=w8e});var xAe=I((Jyt,PAe)=>{var B8e=Ih(),b8e=fm(),Q8e=nm(),S8e=vn();function v8e(r,e,t){if(!S8e(t))return!1;var i=typeof e;return(i=="number"?b8e(t)&&Q8e(e,t.length):i=="string"&&e in t)?B8e(t[e],r):!1}PAe.exports=v8e});var DAe=I((Wyt,kAe)=>{var P8e=vAe(),x8e=xAe();function k8e(r){return P8e(function(e,t){var i=-1,n=t.length,s=n>1?t[n-1]:void 0,o=n>2?t[2]:void 0;for(s=r.length>3&&typeof s=="function"?(n--,s):void 0,o&&x8e(t[0],t[1],o)&&(s=n<3?void 0:s,n=1),e=Object(e);++i<n;){var a=t[i];a&&r(e,a,i,s)}return e})}kAe.exports=k8e});var FAe=I((zyt,RAe)=>{var D8e=QAe(),R8e=DAe(),F8e=R8e(function(r,e,t){D8e(r,e,t)});RAe.exports=F8e});var WAe=I((Wwt,JAe)=>{var HO;JAe.exports=()=>(typeof HO>"u"&&(HO=J("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),HO)});var hle=I((CBt,fle)=>{var XO=Symbol("arg flag"),Rn=class extends Error{constructor(e,t){super(e),this.name="ArgError",this.code=t,Object.setPrototypeOf(this,Rn.prototype)}};function uE(r,{argv:e=process.argv.slice(2),permissive:t=!1,stopAtPositional:i=!1}={}){if(!r)throw new Rn("argument specification object is required","ARG_CONFIG_NO_SPEC");let n={_:[]},s={},o={};for(let a of Object.keys(r)){if(!a)throw new Rn("argument key cannot be an empty string","ARG_CONFIG_EMPTY_KEY");if(a[0]!=="-")throw new Rn(`argument key must start with '-' but found: '${a}'`,"ARG_CONFIG_NONOPT_KEY");if(a.length===1)throw new Rn(`argument key must have a name; singular '-' keys are not allowed: ${a}`,"ARG_CONFIG_NONAME_KEY");if(typeof r[a]=="string"){s[a]=r[a];continue}let l=r[a],c=!1;if(Array.isArray(l)&&l.length===1&&typeof l[0]=="function"){let[u]=l;l=(g,h,p=[])=>(p.push(u(g,h,p[p.length-1])),p),c=u===Boolean||u[XO]===!0}else if(typeof l=="function")c=l===Boolean||l[XO]===!0;else throw new Rn(`type missing or not a function or valid array type: ${a}`,"ARG_CONFIG_VAD_TYPE");if(a[1]!=="-"&&a.length>2)throw new Rn(`short argument keys (with a single hyphen) must have only one character: ${a}`,"ARG_CONFIG_SHORTOPT_TOOLONG");o[a]=[l,c]}for(let a=0,l=e.length;a<l;a++){let c=e[a];if(i&&n._.length>0){n._=n._.concat(e.slice(a));break}if(c==="--"){n._=n._.concat(e.slice(a+1));break}if(c.length>1&&c[0]==="-"){let u=c[1]==="-"||c.length===2?[c]:c.slice(1).split("").map(g=>`-${g}`);for(let g=0;g<u.length;g++){let h=u[g],[p,d]=h[1]==="-"?h.split(/=(.*)/,2):[h,void 0],m=p;for(;m in s;)m=s[m];if(!(m in o))if(t){n._.push(h);continue}else throw new Rn(`unknown or unexpected option: ${p}`,"ARG_UNKNOWN_OPTION");let[y,B]=o[m];if(!B&&g+1<u.length)throw new Rn(`option requires argument (but was followed by another short argument): ${p}`,"ARG_MISSING_REQUIRED_SHORTARG");if(B)n[m]=y(!0,m,n[m]);else if(d===void 0){if(e.length<a+2||e[a+1].length>1&&e[a+1][0]==="-"&&!(e[a+1].match(/^-?\d*(\.(?=\d))?\d*$/)&&(y===Number||typeof BigInt<"u"&&y===BigInt))){let S=p===m?"":` (alias for ${m})`;throw new Rn(`option requires argument: ${p}${S}`,"ARG_MISSING_REQUIRED_LONGARG")}n[m]=y(e[a+1],m,n[m]),++a}else n[m]=y(d,m,n[m])}}else n._.push(c)}return n}uE.flag=r=>(r[XO]=!0,r);uE.COUNT=uE.flag((r,e,t)=>(t||0)+1);uE.ArgError=Rn;fle.exports=uE});var Qle=I((XBt,ble)=>{var eM;ble.exports=()=>(typeof eM>"u"&&(eM=J("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),eM)});var Rle=I((oM,aM)=>{(function(r){oM&&typeof oM=="object"&&typeof aM<"u"?aM.exports=r():typeof define=="function"&&define.amd?define([],r):typeof window<"u"?window.isWindows=r():typeof global<"u"?global.isWindows=r():typeof self<"u"?self.isWindows=r():this.isWindows=r()})(function(){"use strict";return function(){return process&&(process.platform==="win32"||/^(msys|cygwin)$/.test(process.env.OSTYPE))}})});var Lle=I((V0t,Tle)=>{"use strict";AM.ifExists=Dze;var np=J("util"),Ns=J("path"),Fle=Rle(),Pze=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,xze={createPwshFile:!0,createCmdFile:Fle(),fs:J("fs")},kze=new Map([[".js","node"],[".cjs","node"],[".mjs","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function Nle(r){let e={...xze,...r},t=e.fs;return e.fs_={chmod:t.chmod?np.promisify(t.chmod):async()=>{},mkdir:np.promisify(t.mkdir),readFile:np.promisify(t.readFile),stat:np.promisify(t.stat),unlink:np.promisify(t.unlink),writeFile:np.promisify(t.writeFile)},e}async function AM(r,e,t){let i=Nle(t);await i.fs_.stat(r),await Fze(r,e,i)}function Dze(r,e,t){return AM(r,e,t).catch(()=>{})}function Rze(r,e){return e.fs_.unlink(r).catch(()=>{})}async function Fze(r,e,t){let i=await Mze(r,t);return await Nze(e,t),Tze(r,e,i,t)}function Nze(r,e){return e.fs_.mkdir(Ns.dirname(r),{recursive:!0})}function Tze(r,e,t,i){let n=Nle(i),s=[{generator:Hze,extension:""}];return n.createCmdFile&&s.push({generator:Uze,extension:".cmd"}),n.createPwshFile&&s.push({generator:jze,extension:".ps1"}),Promise.all(s.map(o=>Kze(r,e+o.extension,t,o.generator,n)))}function Lze(r,e){return Rze(r,e)}function Oze(r,e){return Gze(r,e)}async function Mze(r,e){let n=(await e.fs_.readFile(r,"utf8")).trim().split(/\r*\n/)[0].match(Pze);if(!n){let s=Ns.extname(r).toLowerCase();return{program:kze.get(s)||null,additionalArgs:""}}return{program:n[1],additionalArgs:n[2]}}async function Kze(r,e,t,i,n){let s=n.preserveSymlinks?"--preserve-symlinks":"",o=[t.additionalArgs,s].filter(a=>a).join(" ");return n=Object.assign({},n,{prog:t.program,args:o}),await Lze(e,n),await n.fs_.writeFile(e,i(r,e,n),"utf8"),Oze(e,n)}function Uze(r,e,t){let n=Ns.relative(Ns.dirname(e),r).split("/").join("\\"),s=Ns.isAbsolute(n)?`"${n}"`:`"%~dp0\\${n}"`,o,a=t.prog,l=t.args||"",c=lM(t.nodePath).win32;a?(o=`"%~dp0\\${a}.exe"`,n=s):(a=s,l="",n="");let u=t.progArgs?`${t.progArgs.join(" ")} `:"",g=c?`@SET NODE_PATH=${c}\r +`:"";return o?g+=`@IF EXIST ${o} (\r + ${o} ${l} ${n} ${u}%*\r +) ELSE (\r + @SETLOCAL\r + @SET PATHEXT=%PATHEXT:;.JS;=;%\r + ${a} ${l} ${n} ${u}%*\r +)\r +`:g+=`@${a} ${l} ${n} ${u}%*\r +`,g}function Hze(r,e,t){let i=Ns.relative(Ns.dirname(e),r),n=t.prog&&t.prog.split("\\").join("/"),s;i=i.split("\\").join("/");let o=Ns.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,a=t.args||"",l=lM(t.nodePath).posix;n?(s=`"$basedir/${t.prog}"`,i=o):(n=o,a="",i="");let c=t.progArgs?`${t.progArgs.join(" ")} `:"",u=`#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") + +case \`uname\` in + *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;; +esac + +`,g=t.nodePath?`export NODE_PATH="${l}" +`:"";return s?u+=`${g}if [ -x ${s} ]; then + exec ${s} ${a} ${i} ${c}"$@" +else + exec ${n} ${a} ${i} ${c}"$@" +fi +`:u+=`${g}${n} ${a} ${i} ${c}"$@" +exit $? +`,u}function jze(r,e,t){let i=Ns.relative(Ns.dirname(e),r),n=t.prog&&t.prog.split("\\").join("/"),s=n&&`"${n}$exe"`,o;i=i.split("\\").join("/");let a=Ns.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,l=t.args||"",c=lM(t.nodePath),u=c.win32,g=c.posix;s?(o=`"$basedir/${t.prog}$exe"`,i=a):(s=a,l="",i="");let h=t.progArgs?`${t.progArgs.join(" ")} `:"",p=`#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +${t.nodePath?`$env_node_path=$env:NODE_PATH +$env:NODE_PATH="${u}" +`:""}if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +}`;return t.nodePath&&(p+=` else { + $env:NODE_PATH="${g}" +}`),o?p+=` +$ret=0 +if (Test-Path ${o}) { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${o} ${l} ${i} ${h}$args + } else { + & ${o} ${l} ${i} ${h}$args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & ${s} ${l} ${i} ${h}$args + } else { + & ${s} ${l} ${i} ${h}$args + } + $ret=$LASTEXITCODE +} +${t.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $ret +`:p+=` +# Support pipeline input +if ($MyInvocation.ExpectingInput) { + $input | & ${s} ${l} ${i} ${h}$args +} else { + & ${s} ${l} ${i} ${h}$args +} +${t.nodePath?`$env:NODE_PATH=$env_node_path +`:""}exit $LASTEXITCODE +`,p}function Gze(r,e){return e.fs_.chmod(r,493)}function lM(r){if(!r)return{win32:"",posix:""};let e=typeof r=="string"?r.split(Ns.delimiter):Array.from(r),t={};for(let i=0;i<e.length;i++){let n=e[i].split("/").join("\\"),s=Fle()?e[i].split("\\").join("/").replace(/^([^:\\/]*):/,(o,a)=>`/mnt/${a.toLowerCase()}`):e[i];t.win32=t.win32?`${t.win32};${n}`:n,t.posix=t.posix?`${t.posix}:${s}`:s,t[i]={win32:n,posix:s}}return t}Tle.exports=AM});var yM=I((fQt,rce)=>{rce.exports=J("stream")});var oce=I((hQt,sce)=>{"use strict";function ice(r,e){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable})),t.push.apply(t,i)}return t}function l5e(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?arguments[e]:{};e%2?ice(Object(t),!0).forEach(function(i){c5e(r,i,t[i])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(t)):ice(Object(t)).forEach(function(i){Object.defineProperty(r,i,Object.getOwnPropertyDescriptor(t,i))})}return r}function c5e(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}function u5e(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}function nce(r,e){for(var t=0;t<e.length;t++){var i=e[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(r,i.key,i)}}function g5e(r,e,t){return e&&nce(r.prototype,e),t&&nce(r,t),r}var f5e=J("buffer"),pQ=f5e.Buffer,h5e=J("util"),wM=h5e.inspect,p5e=wM&&wM.custom||"inspect";function d5e(r,e,t){pQ.prototype.copy.call(r,e,t)}sce.exports=function(){function r(){u5e(this,r),this.head=null,this.tail=null,this.length=0}return g5e(r,[{key:"push",value:function(t){var i={data:t,next:null};this.length>0?this.tail.next=i:this.head=i,this.tail=i,++this.length}},{key:"unshift",value:function(t){var i={data:t,next:this.head};this.length===0&&(this.tail=i),this.head=i,++this.length}},{key:"shift",value:function(){if(this.length!==0){var t=this.head.data;return this.length===1?this.head=this.tail=null:this.head=this.head.next,--this.length,t}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(t){if(this.length===0)return"";for(var i=this.head,n=""+i.data;i=i.next;)n+=t+i.data;return n}},{key:"concat",value:function(t){if(this.length===0)return pQ.alloc(0);for(var i=pQ.allocUnsafe(t>>>0),n=this.head,s=0;n;)d5e(n.data,i,s),s+=n.data.length,n=n.next;return i}},{key:"consume",value:function(t,i){var n;return t<this.head.data.length?(n=this.head.data.slice(0,t),this.head.data=this.head.data.slice(t)):t===this.head.data.length?n=this.shift():n=i?this._getString(t):this._getBuffer(t),n}},{key:"first",value:function(){return this.head.data}},{key:"_getString",value:function(t){var i=this.head,n=1,s=i.data;for(t-=s.length;i=i.next;){var o=i.data,a=t>o.length?o.length:t;if(a===o.length?s+=o:s+=o.slice(0,t),t-=a,t===0){a===o.length?(++n,i.next?this.head=i.next:this.head=this.tail=null):(this.head=i,i.data=o.slice(a));break}++n}return this.length-=n,s}},{key:"_getBuffer",value:function(t){var i=pQ.allocUnsafe(t),n=this.head,s=1;for(n.data.copy(i),t-=n.data.length;n=n.next;){var o=n.data,a=t>o.length?o.length:t;if(o.copy(i,i.length-t,0,a),t-=a,t===0){a===o.length?(++s,n.next?this.head=n.next:this.head=this.tail=null):(this.head=n,n.data=o.slice(a));break}++s}return this.length-=s,i}},{key:p5e,value:function(t,i){return wM(this,l5e({},i,{depth:0,customInspect:!1}))}}]),r}()});var bM=I((pQt,Ace)=>{"use strict";function C5e(r,e){var t=this,i=this._readableState&&this._readableState.destroyed,n=this._writableState&&this._writableState.destroyed;return i||n?(e?e(r):r&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(BM,this,r)):process.nextTick(BM,this,r)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(r||null,function(s){!e&&s?t._writableState?t._writableState.errorEmitted?process.nextTick(dQ,t):(t._writableState.errorEmitted=!0,process.nextTick(ace,t,s)):process.nextTick(ace,t,s):e?(process.nextTick(dQ,t),e(s)):process.nextTick(dQ,t)}),this)}function ace(r,e){BM(r,e),dQ(r)}function dQ(r){r._writableState&&!r._writableState.emitClose||r._readableState&&!r._readableState.emitClose||r.emit("close")}function m5e(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}function BM(r,e){r.emit("error",e)}function E5e(r,e){var t=r._readableState,i=r._writableState;t&&t.autoDestroy||i&&i.autoDestroy?r.destroy(e):r.emit("error",e)}Ace.exports={destroy:C5e,undestroy:m5e,errorOrDestroy:E5e}});var Ql=I((dQt,uce)=>{"use strict";var cce={};function Ls(r,e,t){t||(t=Error);function i(s,o,a){return typeof e=="string"?e:e(s,o,a)}class n extends t{constructor(o,a,l){super(i(o,a,l))}}n.prototype.name=t.name,n.prototype.code=r,cce[r]=n}function lce(r,e){if(Array.isArray(r)){let t=r.length;return r=r.map(i=>String(i)),t>2?`one of ${e} ${r.slice(0,t-1).join(", ")}, or `+r[t-1]:t===2?`one of ${e} ${r[0]} or ${r[1]}`:`of ${e} ${r[0]}`}else return`of ${e} ${String(r)}`}function I5e(r,e,t){return r.substr(!t||t<0?0:+t,e.length)===e}function y5e(r,e,t){return(t===void 0||t>r.length)&&(t=r.length),r.substring(t-e.length,t)===e}function w5e(r,e,t){return typeof t!="number"&&(t=0),t+e.length>r.length?!1:r.indexOf(e,t)!==-1}Ls("ERR_INVALID_OPT_VALUE",function(r,e){return'The value "'+e+'" is invalid for option "'+r+'"'},TypeError);Ls("ERR_INVALID_ARG_TYPE",function(r,e,t){let i;typeof e=="string"&&I5e(e,"not ")?(i="must not be",e=e.replace(/^not /,"")):i="must be";let n;if(y5e(r," argument"))n=`The ${r} ${i} ${lce(e,"type")}`;else{let s=w5e(r,".")?"property":"argument";n=`The "${r}" ${s} ${i} ${lce(e,"type")}`}return n+=`. Received type ${typeof t}`,n},TypeError);Ls("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");Ls("ERR_METHOD_NOT_IMPLEMENTED",function(r){return"The "+r+" method is not implemented"});Ls("ERR_STREAM_PREMATURE_CLOSE","Premature close");Ls("ERR_STREAM_DESTROYED",function(r){return"Cannot call "+r+" after a stream was destroyed"});Ls("ERR_MULTIPLE_CALLBACK","Callback called multiple times");Ls("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");Ls("ERR_STREAM_WRITE_AFTER_END","write after end");Ls("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);Ls("ERR_UNKNOWN_ENCODING",function(r){return"Unknown encoding: "+r},TypeError);Ls("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");uce.exports.codes=cce});var QM=I((CQt,gce)=>{"use strict";var B5e=Ql().codes.ERR_INVALID_OPT_VALUE;function b5e(r,e,t){return r.highWaterMark!=null?r.highWaterMark:e?r[t]:null}function Q5e(r,e,t,i){var n=b5e(e,i,t);if(n!=null){if(!(isFinite(n)&&Math.floor(n)===n)||n<0){var s=i?t:"highWaterMark";throw new B5e(s,n)}return Math.floor(n)}return r.objectMode?16:16*1024}gce.exports={getHighWaterMark:Q5e}});var fce=I((mQt,SM)=>{typeof Object.create=="function"?SM.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:SM.exports=function(e,t){if(t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}}});var Sl=I((EQt,PM)=>{try{if(vM=J("util"),typeof vM.inherits!="function")throw"";PM.exports=vM.inherits}catch{PM.exports=fce()}var vM});var pce=I((IQt,hce)=>{hce.exports=J("util").deprecate});var DM=I((yQt,yce)=>{"use strict";yce.exports=Nr;function Cce(r){var e=this;this.next=null,this.entry=null,this.finish=function(){_5e(e,r)}}var ap;Nr.WritableState=dE;var S5e={deprecate:pce()},mce=yM(),mQ=J("buffer").Buffer,v5e=global.Uint8Array||function(){};function P5e(r){return mQ.from(r)}function x5e(r){return mQ.isBuffer(r)||r instanceof v5e}var kM=bM(),k5e=QM(),D5e=k5e.getHighWaterMark,vl=Ql().codes,R5e=vl.ERR_INVALID_ARG_TYPE,F5e=vl.ERR_METHOD_NOT_IMPLEMENTED,N5e=vl.ERR_MULTIPLE_CALLBACK,T5e=vl.ERR_STREAM_CANNOT_PIPE,L5e=vl.ERR_STREAM_DESTROYED,O5e=vl.ERR_STREAM_NULL_VALUES,M5e=vl.ERR_STREAM_WRITE_AFTER_END,K5e=vl.ERR_UNKNOWN_ENCODING,Ap=kM.errorOrDestroy;Sl()(Nr,mce);function U5e(){}function dE(r,e,t){ap=ap||Wu(),r=r||{},typeof t!="boolean"&&(t=e instanceof ap),this.objectMode=!!r.objectMode,t&&(this.objectMode=this.objectMode||!!r.writableObjectMode),this.highWaterMark=D5e(this,r,"writableHighWaterMark",t),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var i=r.decodeStrings===!1;this.decodeStrings=!i,this.defaultEncoding=r.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(n){W5e(e,n)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=r.emitClose!==!1,this.autoDestroy=!!r.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new Cce(this)}dE.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t};(function(){try{Object.defineProperty(dE.prototype,"buffer",{get:S5e.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch{}})();var CQ;typeof Symbol=="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]=="function"?(CQ=Function.prototype[Symbol.hasInstance],Object.defineProperty(Nr,Symbol.hasInstance,{value:function(e){return CQ.call(this,e)?!0:this!==Nr?!1:e&&e._writableState instanceof dE}})):CQ=function(e){return e instanceof this};function Nr(r){ap=ap||Wu();var e=this instanceof ap;if(!e&&!CQ.call(Nr,this))return new Nr(r);this._writableState=new dE(r,this,e),this.writable=!0,r&&(typeof r.write=="function"&&(this._write=r.write),typeof r.writev=="function"&&(this._writev=r.writev),typeof r.destroy=="function"&&(this._destroy=r.destroy),typeof r.final=="function"&&(this._final=r.final)),mce.call(this)}Nr.prototype.pipe=function(){Ap(this,new T5e)};function H5e(r,e){var t=new M5e;Ap(r,t),process.nextTick(e,t)}function j5e(r,e,t,i){var n;return t===null?n=new O5e:typeof t!="string"&&!e.objectMode&&(n=new R5e("chunk",["string","Buffer"],t)),n?(Ap(r,n),process.nextTick(i,n),!1):!0}Nr.prototype.write=function(r,e,t){var i=this._writableState,n=!1,s=!i.objectMode&&x5e(r);return s&&!mQ.isBuffer(r)&&(r=P5e(r)),typeof e=="function"&&(t=e,e=null),s?e="buffer":e||(e=i.defaultEncoding),typeof t!="function"&&(t=U5e),i.ending?H5e(this,t):(s||j5e(this,i,r,t))&&(i.pendingcb++,n=Y5e(this,i,s,r,e,t)),n};Nr.prototype.cork=function(){this._writableState.corked++};Nr.prototype.uncork=function(){var r=this._writableState;r.corked&&(r.corked--,!r.writing&&!r.corked&&!r.bufferProcessing&&r.bufferedRequest&&Ece(this,r))};Nr.prototype.setDefaultEncoding=function(e){if(typeof e=="string"&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new K5e(e);return this._writableState.defaultEncoding=e,this};Object.defineProperty(Nr.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function G5e(r,e,t){return!r.objectMode&&r.decodeStrings!==!1&&typeof e=="string"&&(e=mQ.from(e,t)),e}Object.defineProperty(Nr.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function Y5e(r,e,t,i,n,s){if(!t){var o=G5e(e,i,n);i!==o&&(t=!0,n="buffer",i=o)}var a=e.objectMode?1:i.length;e.length+=a;var l=e.length<e.highWaterMark;if(l||(e.needDrain=!0),e.writing||e.corked){var c=e.lastBufferedRequest;e.lastBufferedRequest={chunk:i,encoding:n,isBuf:t,callback:s,next:null},c?c.next=e.lastBufferedRequest:e.bufferedRequest=e.lastBufferedRequest,e.bufferedRequestCount+=1}else xM(r,e,!1,a,i,n,s);return l}function xM(r,e,t,i,n,s,o){e.writelen=i,e.writecb=o,e.writing=!0,e.sync=!0,e.destroyed?e.onwrite(new L5e("write")):t?r._writev(n,e.onwrite):r._write(n,s,e.onwrite),e.sync=!1}function q5e(r,e,t,i,n){--e.pendingcb,t?(process.nextTick(n,i),process.nextTick(pE,r,e),r._writableState.errorEmitted=!0,Ap(r,i)):(n(i),r._writableState.errorEmitted=!0,Ap(r,i),pE(r,e))}function J5e(r){r.writing=!1,r.writecb=null,r.length-=r.writelen,r.writelen=0}function W5e(r,e){var t=r._writableState,i=t.sync,n=t.writecb;if(typeof n!="function")throw new N5e;if(J5e(t),e)q5e(r,t,i,e,n);else{var s=Ice(t)||r.destroyed;!s&&!t.corked&&!t.bufferProcessing&&t.bufferedRequest&&Ece(r,t),i?process.nextTick(dce,r,t,s,n):dce(r,t,s,n)}}function dce(r,e,t,i){t||z5e(r,e),e.pendingcb--,i(),pE(r,e)}function z5e(r,e){e.length===0&&e.needDrain&&(e.needDrain=!1,r.emit("drain"))}function Ece(r,e){e.bufferProcessing=!0;var t=e.bufferedRequest;if(r._writev&&t&&t.next){var i=e.bufferedRequestCount,n=new Array(i),s=e.corkedRequestsFree;s.entry=t;for(var o=0,a=!0;t;)n[o]=t,t.isBuf||(a=!1),t=t.next,o+=1;n.allBuffers=a,xM(r,e,!0,e.length,n,"",s.finish),e.pendingcb++,e.lastBufferedRequest=null,s.next?(e.corkedRequestsFree=s.next,s.next=null):e.corkedRequestsFree=new Cce(e),e.bufferedRequestCount=0}else{for(;t;){var l=t.chunk,c=t.encoding,u=t.callback,g=e.objectMode?1:l.length;if(xM(r,e,!1,g,l,c,u),t=t.next,e.bufferedRequestCount--,e.writing)break}t===null&&(e.lastBufferedRequest=null)}e.bufferedRequest=t,e.bufferProcessing=!1}Nr.prototype._write=function(r,e,t){t(new F5e("_write()"))};Nr.prototype._writev=null;Nr.prototype.end=function(r,e,t){var i=this._writableState;return typeof r=="function"?(t=r,r=null,e=null):typeof e=="function"&&(t=e,e=null),r!=null&&this.write(r,e),i.corked&&(i.corked=1,this.uncork()),i.ending||Z5e(this,i,t),this};Object.defineProperty(Nr.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}});function Ice(r){return r.ending&&r.length===0&&r.bufferedRequest===null&&!r.finished&&!r.writing}function V5e(r,e){r._final(function(t){e.pendingcb--,t&&Ap(r,t),e.prefinished=!0,r.emit("prefinish"),pE(r,e)})}function X5e(r,e){!e.prefinished&&!e.finalCalled&&(typeof r._final=="function"&&!e.destroyed?(e.pendingcb++,e.finalCalled=!0,process.nextTick(V5e,r,e)):(e.prefinished=!0,r.emit("prefinish")))}function pE(r,e){var t=Ice(e);if(t&&(X5e(r,e),e.pendingcb===0&&(e.finished=!0,r.emit("finish"),e.autoDestroy))){var i=r._readableState;(!i||i.autoDestroy&&i.endEmitted)&&r.destroy()}return t}function Z5e(r,e,t){e.ending=!0,pE(r,e),t&&(e.finished?process.nextTick(t):r.once("finish",t)),e.ended=!0,r.writable=!1}function _5e(r,e,t){var i=r.entry;for(r.entry=null;i;){var n=i.callback;e.pendingcb--,n(t),i=i.next}e.corkedRequestsFree.next=r}Object.defineProperty(Nr.prototype,"destroyed",{enumerable:!1,get:function(){return this._writableState===void 0?!1:this._writableState.destroyed},set:function(e){!this._writableState||(this._writableState.destroyed=e)}});Nr.prototype.destroy=kM.destroy;Nr.prototype._undestroy=kM.undestroy;Nr.prototype._destroy=function(r,e){e(r)}});var Wu=I((wQt,Bce)=>{"use strict";var $5e=Object.keys||function(r){var e=[];for(var t in r)e.push(t);return e};Bce.exports=oa;var wce=NM(),FM=DM();Sl()(oa,wce);for(RM=$5e(FM.prototype),EQ=0;EQ<RM.length;EQ++)IQ=RM[EQ],oa.prototype[IQ]||(oa.prototype[IQ]=FM.prototype[IQ]);var RM,IQ,EQ;function oa(r){if(!(this instanceof oa))return new oa(r);wce.call(this,r),FM.call(this,r),this.allowHalfOpen=!0,r&&(r.readable===!1&&(this.readable=!1),r.writable===!1&&(this.writable=!1),r.allowHalfOpen===!1&&(this.allowHalfOpen=!1,this.once("end",e6e)))}Object.defineProperty(oa.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});Object.defineProperty(oa.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});Object.defineProperty(oa.prototype,"writableLength",{enumerable:!1,get:function(){return this._writableState.length}});function e6e(){this._writableState.ended||process.nextTick(t6e,this)}function t6e(r){r.end()}Object.defineProperty(oa.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0||this._writableState===void 0?!1:this._readableState.destroyed&&this._writableState.destroyed},set:function(e){this._readableState===void 0||this._writableState===void 0||(this._readableState.destroyed=e,this._writableState.destroyed=e)}})});var Sce=I((TM,Qce)=>{var yQ=J("buffer"),hA=yQ.Buffer;function bce(r,e){for(var t in r)e[t]=r[t]}hA.from&&hA.alloc&&hA.allocUnsafe&&hA.allocUnsafeSlow?Qce.exports=yQ:(bce(yQ,TM),TM.Buffer=lp);function lp(r,e,t){return hA(r,e,t)}bce(hA,lp);lp.from=function(r,e,t){if(typeof r=="number")throw new TypeError("Argument must not be a number");return hA(r,e,t)};lp.alloc=function(r,e,t){if(typeof r!="number")throw new TypeError("Argument must be a number");var i=hA(r);return e!==void 0?typeof t=="string"?i.fill(e,t):i.fill(e):i.fill(0),i};lp.allocUnsafe=function(r){if(typeof r!="number")throw new TypeError("Argument must be a number");return hA(r)};lp.allocUnsafeSlow=function(r){if(typeof r!="number")throw new TypeError("Argument must be a number");return yQ.SlowBuffer(r)}});var MM=I(Pce=>{"use strict";var OM=Sce().Buffer,vce=OM.isEncoding||function(r){switch(r=""+r,r&&r.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function r6e(r){if(!r)return"utf8";for(var e;;)switch(r){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return r;default:if(e)return;r=(""+r).toLowerCase(),e=!0}}function i6e(r){var e=r6e(r);if(typeof e!="string"&&(OM.isEncoding===vce||!vce(r)))throw new Error("Unknown encoding: "+r);return e||r}Pce.StringDecoder=CE;function CE(r){this.encoding=i6e(r);var e;switch(this.encoding){case"utf16le":this.text=l6e,this.end=c6e,e=4;break;case"utf8":this.fillLast=o6e,e=4;break;case"base64":this.text=u6e,this.end=g6e,e=3;break;default:this.write=f6e,this.end=h6e;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=OM.allocUnsafe(e)}CE.prototype.write=function(r){if(r.length===0)return"";var e,t;if(this.lastNeed){if(e=this.fillLast(r),e===void 0)return"";t=this.lastNeed,this.lastNeed=0}else t=0;return t<r.length?e?e+this.text(r,t):this.text(r,t):e||""};CE.prototype.end=A6e;CE.prototype.text=a6e;CE.prototype.fillLast=function(r){if(this.lastNeed<=r.length)return r.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);r.copy(this.lastChar,this.lastTotal-this.lastNeed,0,r.length),this.lastNeed-=r.length};function LM(r){return r<=127?0:r>>5===6?2:r>>4===14?3:r>>3===30?4:r>>6===2?-1:-2}function n6e(r,e,t){var i=e.length-1;if(i<t)return 0;var n=LM(e[i]);return n>=0?(n>0&&(r.lastNeed=n-1),n):--i<t||n===-2?0:(n=LM(e[i]),n>=0?(n>0&&(r.lastNeed=n-2),n):--i<t||n===-2?0:(n=LM(e[i]),n>=0?(n>0&&(n===2?n=0:r.lastNeed=n-3),n):0))}function s6e(r,e,t){if((e[0]&192)!==128)return r.lastNeed=0,"\uFFFD";if(r.lastNeed>1&&e.length>1){if((e[1]&192)!==128)return r.lastNeed=1,"\uFFFD";if(r.lastNeed>2&&e.length>2&&(e[2]&192)!==128)return r.lastNeed=2,"\uFFFD"}}function o6e(r){var e=this.lastTotal-this.lastNeed,t=s6e(this,r,e);if(t!==void 0)return t;if(this.lastNeed<=r.length)return r.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);r.copy(this.lastChar,e,0,r.length),this.lastNeed-=r.length}function a6e(r,e){var t=n6e(this,r,e);if(!this.lastNeed)return r.toString("utf8",e);this.lastTotal=t;var i=r.length-(t-this.lastNeed);return r.copy(this.lastChar,0,i),r.toString("utf8",e,i)}function A6e(r){var e=r&&r.length?this.write(r):"";return this.lastNeed?e+"\uFFFD":e}function l6e(r,e){if((r.length-e)%2===0){var t=r.toString("utf16le",e);if(t){var i=t.charCodeAt(t.length-1);if(i>=55296&&i<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=r[r.length-2],this.lastChar[1]=r[r.length-1],t.slice(0,-1)}return t}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=r[r.length-1],r.toString("utf16le",e,r.length-1)}function c6e(r){var e=r&&r.length?this.write(r):"";if(this.lastNeed){var t=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,t)}return e}function u6e(r,e){var t=(r.length-e)%3;return t===0?r.toString("base64",e):(this.lastNeed=3-t,this.lastTotal=3,t===1?this.lastChar[0]=r[r.length-1]:(this.lastChar[0]=r[r.length-2],this.lastChar[1]=r[r.length-1]),r.toString("base64",e,r.length-t))}function g6e(r){var e=r&&r.length?this.write(r):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function f6e(r){return r.toString(this.encoding)}function h6e(r){return r&&r.length?this.write(r):""}});var wQ=I((bQt,Dce)=>{"use strict";var xce=Ql().codes.ERR_STREAM_PREMATURE_CLOSE;function p6e(r){var e=!1;return function(){if(!e){e=!0;for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];r.apply(this,i)}}}function d6e(){}function C6e(r){return r.setHeader&&typeof r.abort=="function"}function kce(r,e,t){if(typeof e=="function")return kce(r,null,e);e||(e={}),t=p6e(t||d6e);var i=e.readable||e.readable!==!1&&r.readable,n=e.writable||e.writable!==!1&&r.writable,s=function(){r.writable||a()},o=r._writableState&&r._writableState.finished,a=function(){n=!1,o=!0,i||t.call(r)},l=r._readableState&&r._readableState.endEmitted,c=function(){i=!1,l=!0,n||t.call(r)},u=function(d){t.call(r,d)},g=function(){var d;if(i&&!l)return(!r._readableState||!r._readableState.ended)&&(d=new xce),t.call(r,d);if(n&&!o)return(!r._writableState||!r._writableState.ended)&&(d=new xce),t.call(r,d)},h=function(){r.req.on("finish",a)};return C6e(r)?(r.on("complete",a),r.on("abort",g),r.req?h():r.on("request",h)):n&&!r._writableState&&(r.on("end",s),r.on("close",s)),r.on("end",c),r.on("finish",a),e.error!==!1&&r.on("error",u),r.on("close",g),function(){r.removeListener("complete",a),r.removeListener("abort",g),r.removeListener("request",h),r.req&&r.req.removeListener("finish",a),r.removeListener("end",s),r.removeListener("close",s),r.removeListener("finish",a),r.removeListener("end",c),r.removeListener("error",u),r.removeListener("close",g)}}Dce.exports=kce});var Fce=I((QQt,Rce)=>{"use strict";var BQ;function Pl(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var m6e=wQ(),xl=Symbol("lastResolve"),zu=Symbol("lastReject"),mE=Symbol("error"),bQ=Symbol("ended"),Vu=Symbol("lastPromise"),KM=Symbol("handlePromise"),Xu=Symbol("stream");function kl(r,e){return{value:r,done:e}}function E6e(r){var e=r[xl];if(e!==null){var t=r[Xu].read();t!==null&&(r[Vu]=null,r[xl]=null,r[zu]=null,e(kl(t,!1)))}}function I6e(r){process.nextTick(E6e,r)}function y6e(r,e){return function(t,i){r.then(function(){if(e[bQ]){t(kl(void 0,!0));return}e[KM](t,i)},i)}}var w6e=Object.getPrototypeOf(function(){}),B6e=Object.setPrototypeOf((BQ={get stream(){return this[Xu]},next:function(){var e=this,t=this[mE];if(t!==null)return Promise.reject(t);if(this[bQ])return Promise.resolve(kl(void 0,!0));if(this[Xu].destroyed)return new Promise(function(o,a){process.nextTick(function(){e[mE]?a(e[mE]):o(kl(void 0,!0))})});var i=this[Vu],n;if(i)n=new Promise(y6e(i,this));else{var s=this[Xu].read();if(s!==null)return Promise.resolve(kl(s,!1));n=new Promise(this[KM])}return this[Vu]=n,n}},Pl(BQ,Symbol.asyncIterator,function(){return this}),Pl(BQ,"return",function(){var e=this;return new Promise(function(t,i){e[Xu].destroy(null,function(n){if(n){i(n);return}t(kl(void 0,!0))})})}),BQ),w6e),b6e=function(e){var t,i=Object.create(B6e,(t={},Pl(t,Xu,{value:e,writable:!0}),Pl(t,xl,{value:null,writable:!0}),Pl(t,zu,{value:null,writable:!0}),Pl(t,mE,{value:null,writable:!0}),Pl(t,bQ,{value:e._readableState.endEmitted,writable:!0}),Pl(t,KM,{value:function(s,o){var a=i[Xu].read();a?(i[Vu]=null,i[xl]=null,i[zu]=null,s(kl(a,!1))):(i[xl]=s,i[zu]=o)},writable:!0}),t));return i[Vu]=null,m6e(e,function(n){if(n&&n.code!=="ERR_STREAM_PREMATURE_CLOSE"){var s=i[zu];s!==null&&(i[Vu]=null,i[xl]=null,i[zu]=null,s(n)),i[mE]=n;return}var o=i[xl];o!==null&&(i[Vu]=null,i[xl]=null,i[zu]=null,o(kl(void 0,!0))),i[bQ]=!0}),e.on("readable",I6e.bind(null,i)),i};Rce.exports=b6e});var Oce=I((SQt,Lce)=>{"use strict";function Nce(r,e,t,i,n,s,o){try{var a=r[s](o),l=a.value}catch(c){t(c);return}a.done?e(l):Promise.resolve(l).then(i,n)}function Q6e(r){return function(){var e=this,t=arguments;return new Promise(function(i,n){var s=r.apply(e,t);function o(l){Nce(s,i,n,o,a,"next",l)}function a(l){Nce(s,i,n,o,a,"throw",l)}o(void 0)})}}function Tce(r,e){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable})),t.push.apply(t,i)}return t}function S6e(r){for(var e=1;e<arguments.length;e++){var t=arguments[e]!=null?arguments[e]:{};e%2?Tce(Object(t),!0).forEach(function(i){v6e(r,i,t[i])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(t)):Tce(Object(t)).forEach(function(i){Object.defineProperty(r,i,Object.getOwnPropertyDescriptor(t,i))})}return r}function v6e(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var P6e=Ql().codes.ERR_INVALID_ARG_TYPE;function x6e(r,e,t){var i;if(e&&typeof e.next=="function")i=e;else if(e&&e[Symbol.asyncIterator])i=e[Symbol.asyncIterator]();else if(e&&e[Symbol.iterator])i=e[Symbol.iterator]();else throw new P6e("iterable",["Iterable"],e);var n=new r(S6e({objectMode:!0},t)),s=!1;n._read=function(){s||(s=!0,o())};function o(){return a.apply(this,arguments)}function a(){return a=Q6e(function*(){try{var l=yield i.next(),c=l.value,u=l.done;u?n.push(null):n.push(yield c)?o():s=!1}catch(g){n.destroy(g)}}),a.apply(this,arguments)}return n}Lce.exports=x6e});var NM=I((PQt,Wce)=>{"use strict";Wce.exports=Ot;var cp;Ot.ReadableState=Hce;var vQt=J("events").EventEmitter,Uce=function(e,t){return e.listeners(t).length},IE=yM(),QQ=J("buffer").Buffer,k6e=global.Uint8Array||function(){};function D6e(r){return QQ.from(r)}function R6e(r){return QQ.isBuffer(r)||r instanceof k6e}var UM=J("util"),xt;UM&&UM.debuglog?xt=UM.debuglog("stream"):xt=function(){};var F6e=oce(),WM=bM(),N6e=QM(),T6e=N6e.getHighWaterMark,SQ=Ql().codes,L6e=SQ.ERR_INVALID_ARG_TYPE,O6e=SQ.ERR_STREAM_PUSH_AFTER_EOF,M6e=SQ.ERR_METHOD_NOT_IMPLEMENTED,K6e=SQ.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,up,HM,jM;Sl()(Ot,IE);var EE=WM.errorOrDestroy,GM=["error","close","destroy","pause","resume"];function U6e(r,e,t){if(typeof r.prependListener=="function")return r.prependListener(e,t);!r._events||!r._events[e]?r.on(e,t):Array.isArray(r._events[e])?r._events[e].unshift(t):r._events[e]=[t,r._events[e]]}function Hce(r,e,t){cp=cp||Wu(),r=r||{},typeof t!="boolean"&&(t=e instanceof cp),this.objectMode=!!r.objectMode,t&&(this.objectMode=this.objectMode||!!r.readableObjectMode),this.highWaterMark=T6e(this,r,"readableHighWaterMark",t),this.buffer=new F6e,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.paused=!0,this.emitClose=r.emitClose!==!1,this.autoDestroy=!!r.autoDestroy,this.destroyed=!1,this.defaultEncoding=r.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,r.encoding&&(up||(up=MM().StringDecoder),this.decoder=new up(r.encoding),this.encoding=r.encoding)}function Ot(r){if(cp=cp||Wu(),!(this instanceof Ot))return new Ot(r);var e=this instanceof cp;this._readableState=new Hce(r,this,e),this.readable=!0,r&&(typeof r.read=="function"&&(this._read=r.read),typeof r.destroy=="function"&&(this._destroy=r.destroy)),IE.call(this)}Object.defineProperty(Ot.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0?!1:this._readableState.destroyed},set:function(e){!this._readableState||(this._readableState.destroyed=e)}});Ot.prototype.destroy=WM.destroy;Ot.prototype._undestroy=WM.undestroy;Ot.prototype._destroy=function(r,e){e(r)};Ot.prototype.push=function(r,e){var t=this._readableState,i;return t.objectMode?i=!0:typeof r=="string"&&(e=e||t.defaultEncoding,e!==t.encoding&&(r=QQ.from(r,e),e=""),i=!0),jce(this,r,e,!1,i)};Ot.prototype.unshift=function(r){return jce(this,r,null,!0,!1)};function jce(r,e,t,i,n){xt("readableAddChunk",e);var s=r._readableState;if(e===null)s.reading=!1,G6e(r,s);else{var o;if(n||(o=H6e(s,e)),o)EE(r,o);else if(s.objectMode||e&&e.length>0)if(typeof e!="string"&&!s.objectMode&&Object.getPrototypeOf(e)!==QQ.prototype&&(e=D6e(e)),i)s.endEmitted?EE(r,new K6e):YM(r,s,e,!0);else if(s.ended)EE(r,new O6e);else{if(s.destroyed)return!1;s.reading=!1,s.decoder&&!t?(e=s.decoder.write(e),s.objectMode||e.length!==0?YM(r,s,e,!1):JM(r,s)):YM(r,s,e,!1)}else i||(s.reading=!1,JM(r,s))}return!s.ended&&(s.length<s.highWaterMark||s.length===0)}function YM(r,e,t,i){e.flowing&&e.length===0&&!e.sync?(e.awaitDrain=0,r.emit("data",t)):(e.length+=e.objectMode?1:t.length,i?e.buffer.unshift(t):e.buffer.push(t),e.needReadable&&vQ(r)),JM(r,e)}function H6e(r,e){var t;return!R6e(e)&&typeof e!="string"&&e!==void 0&&!r.objectMode&&(t=new L6e("chunk",["string","Buffer","Uint8Array"],e)),t}Ot.prototype.isPaused=function(){return this._readableState.flowing===!1};Ot.prototype.setEncoding=function(r){up||(up=MM().StringDecoder);var e=new up(r);this._readableState.decoder=e,this._readableState.encoding=this._readableState.decoder.encoding;for(var t=this._readableState.buffer.head,i="";t!==null;)i+=e.write(t.data),t=t.next;return this._readableState.buffer.clear(),i!==""&&this._readableState.buffer.push(i),this._readableState.length=i.length,this};var Mce=1073741824;function j6e(r){return r>=Mce?r=Mce:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r}function Kce(r,e){return r<=0||e.length===0&&e.ended?0:e.objectMode?1:r!==r?e.flowing&&e.length?e.buffer.head.data.length:e.length:(r>e.highWaterMark&&(e.highWaterMark=j6e(r)),r<=e.length?r:e.ended?e.length:(e.needReadable=!0,0))}Ot.prototype.read=function(r){xt("read",r),r=parseInt(r,10);var e=this._readableState,t=r;if(r!==0&&(e.emittedReadable=!1),r===0&&e.needReadable&&((e.highWaterMark!==0?e.length>=e.highWaterMark:e.length>0)||e.ended))return xt("read: emitReadable",e.length,e.ended),e.length===0&&e.ended?qM(this):vQ(this),null;if(r=Kce(r,e),r===0&&e.ended)return e.length===0&&qM(this),null;var i=e.needReadable;xt("need readable",i),(e.length===0||e.length-r<e.highWaterMark)&&(i=!0,xt("length less than watermark",i)),e.ended||e.reading?(i=!1,xt("reading or ended",i)):i&&(xt("do read"),e.reading=!0,e.sync=!0,e.length===0&&(e.needReadable=!0),this._read(e.highWaterMark),e.sync=!1,e.reading||(r=Kce(t,e)));var n;return r>0?n=qce(r,e):n=null,n===null?(e.needReadable=e.length<=e.highWaterMark,r=0):(e.length-=r,e.awaitDrain=0),e.length===0&&(e.ended||(e.needReadable=!0),t!==r&&e.ended&&qM(this)),n!==null&&this.emit("data",n),n};function G6e(r,e){if(xt("onEofChunk"),!e.ended){if(e.decoder){var t=e.decoder.end();t&&t.length&&(e.buffer.push(t),e.length+=e.objectMode?1:t.length)}e.ended=!0,e.sync?vQ(r):(e.needReadable=!1,e.emittedReadable||(e.emittedReadable=!0,Gce(r)))}}function vQ(r){var e=r._readableState;xt("emitReadable",e.needReadable,e.emittedReadable),e.needReadable=!1,e.emittedReadable||(xt("emitReadable",e.flowing),e.emittedReadable=!0,process.nextTick(Gce,r))}function Gce(r){var e=r._readableState;xt("emitReadable_",e.destroyed,e.length,e.ended),!e.destroyed&&(e.length||e.ended)&&(r.emit("readable"),e.emittedReadable=!1),e.needReadable=!e.flowing&&!e.ended&&e.length<=e.highWaterMark,zM(r)}function JM(r,e){e.readingMore||(e.readingMore=!0,process.nextTick(Y6e,r,e))}function Y6e(r,e){for(;!e.reading&&!e.ended&&(e.length<e.highWaterMark||e.flowing&&e.length===0);){var t=e.length;if(xt("maybeReadMore read 0"),r.read(0),t===e.length)break}e.readingMore=!1}Ot.prototype._read=function(r){EE(this,new M6e("_read()"))};Ot.prototype.pipe=function(r,e){var t=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=r;break;case 1:i.pipes=[i.pipes,r];break;default:i.pipes.push(r);break}i.pipesCount+=1,xt("pipe count=%d opts=%j",i.pipesCount,e);var n=(!e||e.end!==!1)&&r!==process.stdout&&r!==process.stderr,s=n?a:m;i.endEmitted?process.nextTick(s):t.once("end",s),r.on("unpipe",o);function o(y,B){xt("onunpipe"),y===t&&B&&B.hasUnpiped===!1&&(B.hasUnpiped=!0,u())}function a(){xt("onend"),r.end()}var l=q6e(t);r.on("drain",l);var c=!1;function u(){xt("cleanup"),r.removeListener("close",p),r.removeListener("finish",d),r.removeListener("drain",l),r.removeListener("error",h),r.removeListener("unpipe",o),t.removeListener("end",a),t.removeListener("end",m),t.removeListener("data",g),c=!0,i.awaitDrain&&(!r._writableState||r._writableState.needDrain)&&l()}t.on("data",g);function g(y){xt("ondata");var B=r.write(y);xt("dest.write",B),B===!1&&((i.pipesCount===1&&i.pipes===r||i.pipesCount>1&&Jce(i.pipes,r)!==-1)&&!c&&(xt("false write response, pause",i.awaitDrain),i.awaitDrain++),t.pause())}function h(y){xt("onerror",y),m(),r.removeListener("error",h),Uce(r,"error")===0&&EE(r,y)}U6e(r,"error",h);function p(){r.removeListener("finish",d),m()}r.once("close",p);function d(){xt("onfinish"),r.removeListener("close",p),m()}r.once("finish",d);function m(){xt("unpipe"),t.unpipe(r)}return r.emit("pipe",t),i.flowing||(xt("pipe resume"),t.resume()),r};function q6e(r){return function(){var t=r._readableState;xt("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,t.awaitDrain===0&&Uce(r,"data")&&(t.flowing=!0,zM(r))}}Ot.prototype.unpipe=function(r){var e=this._readableState,t={hasUnpiped:!1};if(e.pipesCount===0)return this;if(e.pipesCount===1)return r&&r!==e.pipes?this:(r||(r=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,r&&r.emit("unpipe",this,t),this);if(!r){var i=e.pipes,n=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var s=0;s<n;s++)i[s].emit("unpipe",this,{hasUnpiped:!1});return this}var o=Jce(e.pipes,r);return o===-1?this:(e.pipes.splice(o,1),e.pipesCount-=1,e.pipesCount===1&&(e.pipes=e.pipes[0]),r.emit("unpipe",this,t),this)};Ot.prototype.on=function(r,e){var t=IE.prototype.on.call(this,r,e),i=this._readableState;return r==="data"?(i.readableListening=this.listenerCount("readable")>0,i.flowing!==!1&&this.resume()):r==="readable"&&!i.endEmitted&&!i.readableListening&&(i.readableListening=i.needReadable=!0,i.flowing=!1,i.emittedReadable=!1,xt("on readable",i.length,i.reading),i.length?vQ(this):i.reading||process.nextTick(J6e,this)),t};Ot.prototype.addListener=Ot.prototype.on;Ot.prototype.removeListener=function(r,e){var t=IE.prototype.removeListener.call(this,r,e);return r==="readable"&&process.nextTick(Yce,this),t};Ot.prototype.removeAllListeners=function(r){var e=IE.prototype.removeAllListeners.apply(this,arguments);return(r==="readable"||r===void 0)&&process.nextTick(Yce,this),e};function Yce(r){var e=r._readableState;e.readableListening=r.listenerCount("readable")>0,e.resumeScheduled&&!e.paused?e.flowing=!0:r.listenerCount("data")>0&&r.resume()}function J6e(r){xt("readable nexttick read 0"),r.read(0)}Ot.prototype.resume=function(){var r=this._readableState;return r.flowing||(xt("resume"),r.flowing=!r.readableListening,W6e(this,r)),r.paused=!1,this};function W6e(r,e){e.resumeScheduled||(e.resumeScheduled=!0,process.nextTick(z6e,r,e))}function z6e(r,e){xt("resume",e.reading),e.reading||r.read(0),e.resumeScheduled=!1,r.emit("resume"),zM(r),e.flowing&&!e.reading&&r.read(0)}Ot.prototype.pause=function(){return xt("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1&&(xt("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this};function zM(r){var e=r._readableState;for(xt("flow",e.flowing);e.flowing&&r.read()!==null;);}Ot.prototype.wrap=function(r){var e=this,t=this._readableState,i=!1;r.on("end",function(){if(xt("wrapped end"),t.decoder&&!t.ended){var o=t.decoder.end();o&&o.length&&e.push(o)}e.push(null)}),r.on("data",function(o){if(xt("wrapped data"),t.decoder&&(o=t.decoder.write(o)),!(t.objectMode&&o==null)&&!(!t.objectMode&&(!o||!o.length))){var a=e.push(o);a||(i=!0,r.pause())}});for(var n in r)this[n]===void 0&&typeof r[n]=="function"&&(this[n]=function(a){return function(){return r[a].apply(r,arguments)}}(n));for(var s=0;s<GM.length;s++)r.on(GM[s],this.emit.bind(this,GM[s]));return this._read=function(o){xt("wrapped _read",o),i&&(i=!1,r.resume())},this};typeof Symbol=="function"&&(Ot.prototype[Symbol.asyncIterator]=function(){return HM===void 0&&(HM=Fce()),HM(this)});Object.defineProperty(Ot.prototype,"readableHighWaterMark",{enumerable:!1,get:function(){return this._readableState.highWaterMark}});Object.defineProperty(Ot.prototype,"readableBuffer",{enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}});Object.defineProperty(Ot.prototype,"readableFlowing",{enumerable:!1,get:function(){return this._readableState.flowing},set:function(e){this._readableState&&(this._readableState.flowing=e)}});Ot._fromList=qce;Object.defineProperty(Ot.prototype,"readableLength",{enumerable:!1,get:function(){return this._readableState.length}});function qce(r,e){if(e.length===0)return null;var t;return e.objectMode?t=e.buffer.shift():!r||r>=e.length?(e.decoder?t=e.buffer.join(""):e.buffer.length===1?t=e.buffer.first():t=e.buffer.concat(e.length),e.buffer.clear()):t=e.buffer.consume(r,e.decoder),t}function qM(r){var e=r._readableState;xt("endReadable",e.endEmitted),e.endEmitted||(e.ended=!0,process.nextTick(V6e,e,r))}function V6e(r,e){if(xt("endReadableNT",r.endEmitted,r.length),!r.endEmitted&&r.length===0&&(r.endEmitted=!0,e.readable=!1,e.emit("end"),r.autoDestroy)){var t=e._writableState;(!t||t.autoDestroy&&t.finished)&&e.destroy()}}typeof Symbol=="function"&&(Ot.from=function(r,e){return jM===void 0&&(jM=Oce()),jM(Ot,r,e)});function Jce(r,e){for(var t=0,i=r.length;t<i;t++)if(r[t]===e)return t;return-1}});var VM=I((xQt,Vce)=>{"use strict";Vce.exports=pA;var PQ=Ql().codes,X6e=PQ.ERR_METHOD_NOT_IMPLEMENTED,Z6e=PQ.ERR_MULTIPLE_CALLBACK,_6e=PQ.ERR_TRANSFORM_ALREADY_TRANSFORMING,$6e=PQ.ERR_TRANSFORM_WITH_LENGTH_0,xQ=Wu();Sl()(pA,xQ);function e9e(r,e){var t=this._transformState;t.transforming=!1;var i=t.writecb;if(i===null)return this.emit("error",new Z6e);t.writechunk=null,t.writecb=null,e!=null&&this.push(e),i(r);var n=this._readableState;n.reading=!1,(n.needReadable||n.length<n.highWaterMark)&&this._read(n.highWaterMark)}function pA(r){if(!(this instanceof pA))return new pA(r);xQ.call(this,r),this._transformState={afterTransform:e9e.bind(this),needTransform:!1,transforming:!1,writecb:null,writechunk:null,writeencoding:null},this._readableState.needReadable=!0,this._readableState.sync=!1,r&&(typeof r.transform=="function"&&(this._transform=r.transform),typeof r.flush=="function"&&(this._flush=r.flush)),this.on("prefinish",t9e)}function t9e(){var r=this;typeof this._flush=="function"&&!this._readableState.destroyed?this._flush(function(e,t){zce(r,e,t)}):zce(this,null,null)}pA.prototype.push=function(r,e){return this._transformState.needTransform=!1,xQ.prototype.push.call(this,r,e)};pA.prototype._transform=function(r,e,t){t(new X6e("_transform()"))};pA.prototype._write=function(r,e,t){var i=this._transformState;if(i.writecb=t,i.writechunk=r,i.writeencoding=e,!i.transforming){var n=this._readableState;(i.needTransform||n.needReadable||n.length<n.highWaterMark)&&this._read(n.highWaterMark)}};pA.prototype._read=function(r){var e=this._transformState;e.writechunk!==null&&!e.transforming?(e.transforming=!0,this._transform(e.writechunk,e.writeencoding,e.afterTransform)):e.needTransform=!0};pA.prototype._destroy=function(r,e){xQ.prototype._destroy.call(this,r,function(t){e(t)})};function zce(r,e,t){if(e)return r.emit("error",e);if(t!=null&&r.push(t),r._writableState.length)throw new $6e;if(r._transformState.transforming)throw new _6e;return r.push(null)}});var _ce=I((kQt,Zce)=>{"use strict";Zce.exports=yE;var Xce=VM();Sl()(yE,Xce);function yE(r){if(!(this instanceof yE))return new yE(r);Xce.call(this,r)}yE.prototype._transform=function(r,e,t){t(null,r)}});var iue=I((DQt,rue)=>{"use strict";var XM;function r9e(r){var e=!1;return function(){e||(e=!0,r.apply(void 0,arguments))}}var tue=Ql().codes,i9e=tue.ERR_MISSING_ARGS,n9e=tue.ERR_STREAM_DESTROYED;function $ce(r){if(r)throw r}function s9e(r){return r.setHeader&&typeof r.abort=="function"}function o9e(r,e,t,i){i=r9e(i);var n=!1;r.on("close",function(){n=!0}),XM===void 0&&(XM=wQ()),XM(r,{readable:e,writable:t},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,s9e(r))return r.abort();if(typeof r.destroy=="function")return r.destroy();i(o||new n9e("pipe"))}}}function eue(r){r()}function a9e(r,e){return r.pipe(e)}function A9e(r){return!r.length||typeof r[r.length-1]!="function"?$ce:r.pop()}function l9e(){for(var r=arguments.length,e=new Array(r),t=0;t<r;t++)e[t]=arguments[t];var i=A9e(e);if(Array.isArray(e[0])&&(e=e[0]),e.length<2)throw new i9e("streams");var n,s=e.map(function(o,a){var l=a<e.length-1,c=a>0;return o9e(o,l,c,function(u){n||(n=u),u&&s.forEach(eue),!l&&(s.forEach(eue),i(n))})});return e.reduce(a9e)}rue.exports=l9e});var gp=I((Os,BE)=>{var wE=J("stream");process.env.READABLE_STREAM==="disable"&&wE?(BE.exports=wE.Readable,Object.assign(BE.exports,wE),BE.exports.Stream=wE):(Os=BE.exports=NM(),Os.Stream=wE||Os,Os.Readable=Os,Os.Writable=DM(),Os.Duplex=Wu(),Os.Transform=VM(),Os.PassThrough=_ce(),Os.finished=wQ(),Os.pipeline=iue())});var oue=I((RQt,sue)=>{"use strict";var{Buffer:Eo}=J("buffer"),nue=Symbol.for("BufferList");function ur(r){if(!(this instanceof ur))return new ur(r);ur._init.call(this,r)}ur._init=function(e){Object.defineProperty(this,nue,{value:!0}),this._bufs=[],this.length=0,e&&this.append(e)};ur.prototype._new=function(e){return new ur(e)};ur.prototype._offset=function(e){if(e===0)return[0,0];let t=0;for(let i=0;i<this._bufs.length;i++){let n=t+this._bufs[i].length;if(e<n||i===this._bufs.length-1)return[i,e-t];t=n}};ur.prototype._reverseOffset=function(r){let e=r[0],t=r[1];for(let i=0;i<e;i++)t+=this._bufs[i].length;return t};ur.prototype.get=function(e){if(e>this.length||e<0)return;let t=this._offset(e);return this._bufs[t[0]][t[1]]};ur.prototype.slice=function(e,t){return typeof e=="number"&&e<0&&(e+=this.length),typeof t=="number"&&t<0&&(t+=this.length),this.copy(null,0,e,t)};ur.prototype.copy=function(e,t,i,n){if((typeof i!="number"||i<0)&&(i=0),(typeof n!="number"||n>this.length)&&(n=this.length),i>=this.length||n<=0)return e||Eo.alloc(0);let s=!!e,o=this._offset(i),a=n-i,l=a,c=s&&t||0,u=o[1];if(i===0&&n===this.length){if(!s)return this._bufs.length===1?this._bufs[0]:Eo.concat(this._bufs,this.length);for(let g=0;g<this._bufs.length;g++)this._bufs[g].copy(e,c),c+=this._bufs[g].length;return e}if(l<=this._bufs[o[0]].length-u)return s?this._bufs[o[0]].copy(e,t,u,u+l):this._bufs[o[0]].slice(u,u+l);s||(e=Eo.allocUnsafe(a));for(let g=o[0];g<this._bufs.length;g++){let h=this._bufs[g].length-u;if(l>h)this._bufs[g].copy(e,c,u),c+=h;else{this._bufs[g].copy(e,c,u,u+l),c+=h;break}l-=h,u&&(u=0)}return e.length>c?e.slice(0,c):e};ur.prototype.shallowSlice=function(e,t){if(e=e||0,t=typeof t!="number"?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return this._new();let i=this._offset(e),n=this._offset(t),s=this._bufs.slice(i[0],n[0]+1);return n[1]===0?s.pop():s[s.length-1]=s[s.length-1].slice(0,n[1]),i[1]!==0&&(s[0]=s[0].slice(i[1])),this._new(s)};ur.prototype.toString=function(e,t,i){return this.slice(t,i).toString(e)};ur.prototype.consume=function(e){if(e=Math.trunc(e),Number.isNaN(e)||e<=0)return this;for(;this._bufs.length;)if(e>=this._bufs[0].length)e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift();else{this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}return this};ur.prototype.duplicate=function(){let e=this._new();for(let t=0;t<this._bufs.length;t++)e.append(this._bufs[t]);return e};ur.prototype.append=function(e){if(e==null)return this;if(e.buffer)this._appendBuffer(Eo.from(e.buffer,e.byteOffset,e.byteLength));else if(Array.isArray(e))for(let t=0;t<e.length;t++)this.append(e[t]);else if(this._isBufferList(e))for(let t=0;t<e._bufs.length;t++)this.append(e._bufs[t]);else typeof e=="number"&&(e=e.toString()),this._appendBuffer(Eo.from(e));return this};ur.prototype._appendBuffer=function(e){this._bufs.push(e),this.length+=e.length};ur.prototype.indexOf=function(r,e,t){if(t===void 0&&typeof e=="string"&&(t=e,e=void 0),typeof r=="function"||Array.isArray(r))throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.');if(typeof r=="number"?r=Eo.from([r]):typeof r=="string"?r=Eo.from(r,t):this._isBufferList(r)?r=r.slice():Array.isArray(r.buffer)?r=Eo.from(r.buffer,r.byteOffset,r.byteLength):Eo.isBuffer(r)||(r=Eo.from(r)),e=Number(e||0),isNaN(e)&&(e=0),e<0&&(e=this.length+e),e<0&&(e=0),r.length===0)return e>this.length?this.length:e;let i=this._offset(e),n=i[0],s=i[1];for(;n<this._bufs.length;n++){let o=this._bufs[n];for(;s<o.length;)if(o.length-s>=r.length){let l=o.indexOf(r,s);if(l!==-1)return this._reverseOffset([n,l]);s=o.length-r.length+1}else{let l=this._reverseOffset([n,s]);if(this._match(l,r))return l;s++}s=0}return-1};ur.prototype._match=function(r,e){if(this.length-r<e.length)return!1;for(let t=0;t<e.length;t++)if(this.get(r+t)!==e[t])return!1;return!0};(function(){let r={readDoubleBE:8,readDoubleLE:8,readFloatBE:4,readFloatLE:4,readInt32BE:4,readInt32LE:4,readUInt32BE:4,readUInt32LE:4,readInt16BE:2,readInt16LE:2,readUInt16BE:2,readUInt16LE:2,readInt8:1,readUInt8:1,readIntBE:null,readIntLE:null,readUIntBE:null,readUIntLE:null};for(let e in r)(function(t){r[t]===null?ur.prototype[t]=function(i,n){return this.slice(i,i+n)[t](0,n)}:ur.prototype[t]=function(i=0){return this.slice(i,i+r[t])[t](0)}})(e)})();ur.prototype._isBufferList=function(e){return e instanceof ur||ur.isBufferList(e)};ur.isBufferList=function(e){return e!=null&&e[nue]};sue.exports=ur});var aue=I((FQt,kQ)=>{"use strict";var ZM=gp().Duplex,c9e=Sl(),bE=oue();function Ji(r){if(!(this instanceof Ji))return new Ji(r);if(typeof r=="function"){this._callback=r;let e=function(i){this._callback&&(this._callback(i),this._callback=null)}.bind(this);this.on("pipe",function(i){i.on("error",e)}),this.on("unpipe",function(i){i.removeListener("error",e)}),r=null}bE._init.call(this,r),ZM.call(this)}c9e(Ji,ZM);Object.assign(Ji.prototype,bE.prototype);Ji.prototype._new=function(e){return new Ji(e)};Ji.prototype._write=function(e,t,i){this._appendBuffer(e),typeof i=="function"&&i()};Ji.prototype._read=function(e){if(!this.length)return this.push(null);e=Math.min(e,this.length),this.push(this.slice(0,e)),this.consume(e)};Ji.prototype.end=function(e){ZM.prototype.end.call(this,e),this._callback&&(this._callback(null,this.slice()),this._callback=null)};Ji.prototype._destroy=function(e,t){this._bufs.length=0,this.length=0,t(e)};Ji.prototype._isBufferList=function(e){return e instanceof Ji||e instanceof bE||Ji.isBufferList(e)};Ji.isBufferList=bE.isBufferList;kQ.exports=Ji;kQ.exports.BufferListStream=Ji;kQ.exports.BufferList=bE});var e1=I(hp=>{var u9e=Buffer.alloc,g9e="0000000000000000000",f9e="7777777777777777777",Aue="0".charCodeAt(0),lue=Buffer.from("ustar\0","binary"),h9e=Buffer.from("00","binary"),p9e=Buffer.from("ustar ","binary"),d9e=Buffer.from(" \0","binary"),C9e=parseInt("7777",8),QE=257,$M=263,m9e=function(r,e,t){return typeof r!="number"?t:(r=~~r,r>=e?e:r>=0||(r+=e,r>=0)?r:0)},E9e=function(r){switch(r){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null},I9e=function(r){switch(r){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0},cue=function(r,e,t,i){for(;t<i;t++)if(r[t]===e)return t;return i},uue=function(r){for(var e=256,t=0;t<148;t++)e+=r[t];for(var i=156;i<512;i++)e+=r[i];return e},Dl=function(r,e){return r=r.toString(8),r.length>e?f9e.slice(0,e)+" ":g9e.slice(0,e-r.length)+r+" "};function y9e(r){var e;if(r[0]===128)e=!0;else if(r[0]===255)e=!1;else return null;for(var t=[],i=r.length-1;i>0;i--){var n=r[i];e?t.push(n):t.push(255-n)}var s=0,o=t.length;for(i=0;i<o;i++)s+=t[i]*Math.pow(256,i);return e?s:-1*s}var Rl=function(r,e,t){if(r=r.slice(e,e+t),e=0,r[e]&128)return y9e(r);for(;e<r.length&&r[e]===32;)e++;for(var i=m9e(cue(r,32,e,r.length),r.length,r.length);e<i&&r[e]===0;)e++;return i===e?0:parseInt(r.slice(e,i).toString(),8)},fp=function(r,e,t,i){return r.slice(e,cue(r,0,e,e+t)).toString(i)},_M=function(r){var e=Buffer.byteLength(r),t=Math.floor(Math.log(e)/Math.log(10))+1;return e+t>=Math.pow(10,t)&&t++,e+t+r};hp.decodeLongPath=function(r,e){return fp(r,0,r.length,e)};hp.encodePax=function(r){var e="";r.name&&(e+=_M(" path="+r.name+` +`)),r.linkname&&(e+=_M(" linkpath="+r.linkname+` +`));var t=r.pax;if(t)for(var i in t)e+=_M(" "+i+"="+t[i]+` +`);return Buffer.from(e)};hp.decodePax=function(r){for(var e={};r.length;){for(var t=0;t<r.length&&r[t]!==32;)t++;var i=parseInt(r.slice(0,t).toString(),10);if(!i)return e;var n=r.slice(t+1,i-1).toString(),s=n.indexOf("=");if(s===-1)return e;e[n.slice(0,s)]=n.slice(s+1),r=r.slice(i)}return e};hp.encode=function(r){var e=u9e(512),t=r.name,i="";if(r.typeflag===5&&t[t.length-1]!=="/"&&(t+="/"),Buffer.byteLength(t)!==t.length)return null;for(;Buffer.byteLength(t)>100;){var n=t.indexOf("/");if(n===-1)return null;i+=i?"/"+t.slice(0,n):t.slice(0,n),t=t.slice(n+1)}return Buffer.byteLength(t)>100||Buffer.byteLength(i)>155||r.linkname&&Buffer.byteLength(r.linkname)>100?null:(e.write(t),e.write(Dl(r.mode&C9e,6),100),e.write(Dl(r.uid,6),108),e.write(Dl(r.gid,6),116),e.write(Dl(r.size,11),124),e.write(Dl(r.mtime.getTime()/1e3|0,11),136),e[156]=Aue+I9e(r.type),r.linkname&&e.write(r.linkname,157),lue.copy(e,QE),h9e.copy(e,$M),r.uname&&e.write(r.uname,265),r.gname&&e.write(r.gname,297),e.write(Dl(r.devmajor||0,6),329),e.write(Dl(r.devminor||0,6),337),i&&e.write(i,345),e.write(Dl(uue(e),6),148),e)};hp.decode=function(r,e,t){var i=r[156]===0?0:r[156]-Aue,n=fp(r,0,100,e),s=Rl(r,100,8),o=Rl(r,108,8),a=Rl(r,116,8),l=Rl(r,124,12),c=Rl(r,136,12),u=E9e(i),g=r[157]===0?null:fp(r,157,100,e),h=fp(r,265,32),p=fp(r,297,32),d=Rl(r,329,8),m=Rl(r,337,8),y=uue(r);if(y===8*32)return null;if(y!==Rl(r,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(lue.compare(r,QE,QE+6)===0)r[345]&&(n=fp(r,345,155,e)+"/"+n);else if(!(p9e.compare(r,QE,QE+6)===0&&d9e.compare(r,$M,$M+2)===0)){if(!t)throw new Error("Invalid tar header: unknown format.")}return i===0&&n&&n[n.length-1]==="/"&&(i=5),{name:n,mode:s,uid:o,gid:a,size:l,mtime:new Date(1e3*c),type:u,linkname:g,uname:h,gname:p,devmajor:d,devminor:m}}});var mue=I((TQt,Cue)=>{var fue=J("util"),w9e=aue(),SE=e1(),hue=gp().Writable,pue=gp().PassThrough,due=function(){},gue=function(r){return r&=511,r&&512-r},B9e=function(r,e){var t=new DQ(r,e);return t.end(),t},b9e=function(r,e){return e.path&&(r.name=e.path),e.linkpath&&(r.linkname=e.linkpath),e.size&&(r.size=parseInt(e.size,10)),r.pax=e,r},DQ=function(r,e){this._parent=r,this.offset=e,pue.call(this,{autoDestroy:!1})};fue.inherits(DQ,pue);DQ.prototype.destroy=function(r){this._parent.destroy(r)};var dA=function(r){if(!(this instanceof dA))return new dA(r);hue.call(this,r),r=r||{},this._offset=0,this._buffer=w9e(),this._missing=0,this._partial=!1,this._onparse=due,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var e=this,t=e._buffer,i=function(){e._continue()},n=function(h){if(e._locked=!1,h)return e.destroy(h);e._stream||i()},s=function(){e._stream=null;var h=gue(e._header.size);h?e._parse(h,o):e._parse(512,g),e._locked||i()},o=function(){e._buffer.consume(gue(e._header.size)),e._parse(512,g),i()},a=function(){var h=e._header.size;e._paxGlobal=SE.decodePax(t.slice(0,h)),t.consume(h),s()},l=function(){var h=e._header.size;e._pax=SE.decodePax(t.slice(0,h)),e._paxGlobal&&(e._pax=Object.assign({},e._paxGlobal,e._pax)),t.consume(h),s()},c=function(){var h=e._header.size;this._gnuLongPath=SE.decodeLongPath(t.slice(0,h),r.filenameEncoding),t.consume(h),s()},u=function(){var h=e._header.size;this._gnuLongLinkPath=SE.decodeLongPath(t.slice(0,h),r.filenameEncoding),t.consume(h),s()},g=function(){var h=e._offset,p;try{p=e._header=SE.decode(t.slice(0,512),r.filenameEncoding,r.allowUnknownFormat)}catch(d){e.emit("error",d)}if(t.consume(512),!p){e._parse(512,g),i();return}if(p.type==="gnu-long-path"){e._parse(p.size,c),i();return}if(p.type==="gnu-long-link-path"){e._parse(p.size,u),i();return}if(p.type==="pax-global-header"){e._parse(p.size,a),i();return}if(p.type==="pax-header"){e._parse(p.size,l),i();return}if(e._gnuLongPath&&(p.name=e._gnuLongPath,e._gnuLongPath=null),e._gnuLongLinkPath&&(p.linkname=e._gnuLongLinkPath,e._gnuLongLinkPath=null),e._pax&&(e._header=p=b9e(p,e._pax),e._pax=null),e._locked=!0,!p.size||p.type==="directory"){e._parse(512,g),e.emit("entry",p,B9e(e,h),n);return}e._stream=new DQ(e,h),e.emit("entry",p,e._stream,n),e._parse(p.size,s),i()};this._onheader=g,this._parse(512,g)};fue.inherits(dA,hue);dA.prototype.destroy=function(r){this._destroyed||(this._destroyed=!0,r&&this.emit("error",r),this.emit("close"),this._stream&&this._stream.emit("close"))};dA.prototype._parse=function(r,e){this._destroyed||(this._offset+=r,this._missing=r,e===this._onheader&&(this._partial=!1),this._onparse=e)};dA.prototype._continue=function(){if(!this._destroyed){var r=this._cb;this._cb=due,this._overflow?this._write(this._overflow,void 0,r):r()}};dA.prototype._write=function(r,e,t){if(!this._destroyed){var i=this._stream,n=this._buffer,s=this._missing;if(r.length&&(this._partial=!0),r.length<s)return this._missing-=r.length,this._overflow=null,i?i.write(r,t):(n.append(r),t());this._cb=t,this._missing=0;var o=null;r.length>s&&(o=r.slice(s),r=r.slice(0,s)),i?i.end(r):n.append(r),this._overflow=o,this._onparse()}};dA.prototype._final=function(r){if(this._partial)return this.destroy(new Error("Unexpected end of data"));r()};Cue.exports=dA});var Iue=I((LQt,Eue)=>{Eue.exports=J("fs").constants||J("constants")});var Que=I((OQt,bue)=>{var pp=Iue(),yue=xD(),FQ=Sl(),Q9e=Buffer.alloc,wue=gp().Readable,dp=gp().Writable,S9e=J("string_decoder").StringDecoder,RQ=e1(),v9e=parseInt("755",8),P9e=parseInt("644",8),Bue=Q9e(1024),r1=function(){},t1=function(r,e){e&=511,e&&r.push(Bue.slice(0,512-e))};function x9e(r){switch(r&pp.S_IFMT){case pp.S_IFBLK:return"block-device";case pp.S_IFCHR:return"character-device";case pp.S_IFDIR:return"directory";case pp.S_IFIFO:return"fifo";case pp.S_IFLNK:return"symlink"}return"file"}var NQ=function(r){dp.call(this),this.written=0,this._to=r,this._destroyed=!1};FQ(NQ,dp);NQ.prototype._write=function(r,e,t){if(this.written+=r.length,this._to.push(r))return t();this._to._drain=t};NQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var TQ=function(){dp.call(this),this.linkname="",this._decoder=new S9e("utf-8"),this._destroyed=!1};FQ(TQ,dp);TQ.prototype._write=function(r,e,t){this.linkname+=this._decoder.write(r),t()};TQ.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var vE=function(){dp.call(this),this._destroyed=!1};FQ(vE,dp);vE.prototype._write=function(r,e,t){t(new Error("No body allowed for this entry"))};vE.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var aa=function(r){if(!(this instanceof aa))return new aa(r);wue.call(this,r),this._drain=r1,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};FQ(aa,wue);aa.prototype.entry=function(r,e,t){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof e=="function"&&(t=e,e=null),t||(t=r1);var i=this;if((!r.size||r.type==="symlink")&&(r.size=0),r.type||(r.type=x9e(r.mode)),r.mode||(r.mode=r.type==="directory"?v9e:P9e),r.uid||(r.uid=0),r.gid||(r.gid=0),r.mtime||(r.mtime=new Date),typeof e=="string"&&(e=Buffer.from(e)),Buffer.isBuffer(e)){r.size=e.length,this._encode(r);var n=this.push(e);return t1(i,r.size),n?process.nextTick(t):this._drain=t,new vE}if(r.type==="symlink"&&!r.linkname){var s=new TQ;return yue(s,function(a){if(a)return i.destroy(),t(a);r.linkname=s.linkname,i._encode(r),t()}),s}if(this._encode(r),r.type!=="file"&&r.type!=="contiguous-file")return process.nextTick(t),new vE;var o=new NQ(this);return this._stream=o,yue(o,function(a){if(i._stream=null,a)return i.destroy(),t(a);if(o.written!==r.size)return i.destroy(),t(new Error("size mismatch"));t1(i,r.size),i._finalizing&&i.finalize(),t()}),o}};aa.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push(Bue),this.push(null))};aa.prototype.destroy=function(r){this._destroyed||(this._destroyed=!0,r&&this.emit("error",r),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};aa.prototype._encode=function(r){if(!r.pax){var e=RQ.encode(r);if(e){this.push(e);return}}this._encodePax(r)};aa.prototype._encodePax=function(r){var e=RQ.encodePax({name:r.name,linkname:r.linkname,pax:r.pax}),t={name:"PaxHeader",mode:r.mode,uid:r.uid,gid:r.gid,size:e.length,mtime:r.mtime,type:"pax-header",linkname:r.linkname&&"PaxHeader",uname:r.uname,gname:r.gname,devmajor:r.devmajor,devminor:r.devminor};this.push(RQ.encode(t)),this.push(e),t1(this,e.length),t.size=r.size,t.type=r.type,this.push(RQ.encode(t))};aa.prototype._read=function(r){var e=this._drain;this._drain=r1,e()};bue.exports=aa});var Sue=I(i1=>{i1.extract=mue();i1.pack=Que()});var Mue=I((sSt,Oue)=>{"use strict";var _u=class{constructor(e,t,i){this.__specs=e||{},Object.keys(this.__specs).forEach(n=>{if(typeof this.__specs[n]=="string"){let s=this.__specs[n],o=this.__specs[s];if(o){let a=o.aliases||[];a.push(n,s),o.aliases=[...new Set(a)],this.__specs[n]=o}else throw new Error(`Alias refers to invalid key: ${s} -> ${n}`)}}),this.__opts=t||{},this.__providers=Tue(i.filter(n=>n!=null&&typeof n=="object")),this.__isFiggyPudding=!0}get(e){return l1(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,t=this){for(let[i,n]of this.entries())e.call(t,n,i,this)}toJSON(){let e={};return this.forEach((t,i)=>{e[i]=t}),e}*entries(e){for(let i of Object.keys(this.__specs))yield[i,this.get(i)];let t=e||this.__opts.other;if(t){let i=new Set;for(let n of this.__providers){let s=n.entries?n.entries(t):Y9e(n);for(let[o,a]of s)t(o)&&!i.has(o)&&(i.add(o),yield[o,a])}}}*[Symbol.iterator](){for(let[e,t]of this.entries())yield[e,t]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new _u(this.__specs,this.__opts,Tue(this.__providers).concat(e)),Lue)}};try{let r=J("util");_u.prototype[r.inspect.custom]=function(e,t){return this[Symbol.toStringTag]+" "+r.inspect(this.toJSON(),t)}}catch{}function j9e(r){throw Object.assign(new Error(`invalid config key requested: ${r}`),{code:"EBADKEY"})}function l1(r,e,t){let i=r.__specs[e];if(t&&!i&&(!r.__opts.other||!r.__opts.other(e)))j9e(e);else{i||(i={});let n;for(let s of r.__providers){if(n=Nue(e,s),n===void 0&&i.aliases&&i.aliases.length){for(let o of i.aliases)if(o!==e&&(n=Nue(o,s),n!==void 0))break}if(n!==void 0)break}return n===void 0&&i.default!==void 0?typeof i.default=="function"?i.default(r):i.default:n}}function Nue(r,e){let t;return e.__isFiggyPudding?t=l1(e,r,!1):typeof e.get=="function"?t=e.get(r):t=e[r],t}var Lue={has(r,e){return e in r.__specs&&l1(r,e,!1)!==void 0},ownKeys(r){return Object.keys(r.__specs)},get(r,e){return typeof e=="symbol"||e.slice(0,2)==="__"||e in _u.prototype?r[e]:r.get(e)},set(r,e,t){if(typeof e=="symbol"||e.slice(0,2)==="__")return r[e]=t,!0;throw new Error("figgyPudding options cannot be modified. Use .concat() instead.")},deleteProperty(){throw new Error("figgyPudding options cannot be deleted. Use .concat() and shadow them instead.")}};Oue.exports=G9e;function G9e(r,e){function t(...i){return new Proxy(new _u(r,e,i),Lue)}return t}function Tue(r){let e=[];return r.forEach(t=>e.unshift(t)),e}function Y9e(r){return Object.keys(r).map(e=>[e,r[e]])}});var Hue=I((oSt,ca)=>{"use strict";var xE=J("crypto"),q9e=Mue(),J9e=J("stream").Transform,Kue=["sha256","sha384","sha512"],W9e=/^[a-z0-9+/]+(?:=?=?)$/i,z9e=/^([^-]+)-([^?]+)([?\S*]*)$/,V9e=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,X9e=/^[\x21-\x7E]+$/,an=q9e({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>nVe},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}}),Fl=class{get isHash(){return!0}constructor(e,t){t=an(t);let i=!!t.strict;this.source=e.trim();let n=this.source.match(i?V9e:z9e);if(!n||i&&!Kue.some(o=>o===n[1]))return;this.algorithm=n[1],this.digest=n[2];let s=n[3];this.options=s?s.slice(1).split("?"):[]}hexDigest(){return this.digest&&Buffer.from(this.digest,"base64").toString("hex")}toJSON(){return this.toString()}toString(e){if(e=an(e),e.strict&&!(Kue.some(i=>i===this.algorithm)&&this.digest.match(W9e)&&(this.options||[]).every(i=>i.match(X9e))))return"";let t=this.options&&this.options.length?`?${this.options.join("?")}`:"";return`${this.algorithm}-${this.digest}${t}`}},$u=class{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){e=an(e);let t=e.sep||" ";return e.strict&&(t=t.replace(/\S+/g," ")),Object.keys(this).map(i=>this[i].map(n=>Fl.prototype.toString.call(n,e)).filter(n=>n.length).join(t)).filter(i=>i.length).join(t)}concat(e,t){t=an(t);let i=typeof e=="string"?e:PE(e,t);return la(`${this.toString(t)} ${i}`,t)}hexDigest(){return la(this,{single:!0}).hexDigest()}match(e,t){t=an(t);let i=la(e,t),n=i.pickAlgorithm(t);return this[n]&&i[n]&&this[n].find(s=>i[n].find(o=>s.digest===o.digest))||!1}pickAlgorithm(e){e=an(e);let t=e.pickAlgorithm,i=Object.keys(this);if(!i.length)throw new Error(`No algorithms available for ${JSON.stringify(this.toString())}`);return i.reduce((n,s)=>t(n,s)||n)}};ca.exports.parse=la;function la(r,e){if(e=an(e),typeof r=="string")return c1(r,e);if(r.algorithm&&r.digest){let t=new $u;return t[r.algorithm]=[r],c1(PE(t,e),e)}else return c1(PE(r,e),e)}function c1(r,e){return e.single?new Fl(r,e):r.trim().split(/\s+/).reduce((t,i)=>{let n=new Fl(i,e);if(n.algorithm&&n.digest){let s=n.algorithm;t[s]||(t[s]=[]),t[s].push(n)}return t},new $u)}ca.exports.stringify=PE;function PE(r,e){return e=an(e),r.algorithm&&r.digest?Fl.prototype.toString.call(r,e):typeof r=="string"?PE(la(r,e),e):$u.prototype.toString.call(r,e)}ca.exports.fromHex=Z9e;function Z9e(r,e,t){t=an(t);let i=t.options&&t.options.length?`?${t.options.join("?")}`:"";return la(`${e}-${Buffer.from(r,"hex").toString("base64")}${i}`,t)}ca.exports.fromData=_9e;function _9e(r,e){e=an(e);let t=e.algorithms,i=e.options&&e.options.length?`?${e.options.join("?")}`:"";return t.reduce((n,s)=>{let o=xE.createHash(s).update(r).digest("base64"),a=new Fl(`${s}-${o}${i}`,e);if(a.algorithm&&a.digest){let l=a.algorithm;n[l]||(n[l]=[]),n[l].push(a)}return n},new $u)}ca.exports.fromStream=$9e;function $9e(r,e){e=an(e);let t=e.Promise||Promise,i=u1(e);return new t((n,s)=>{r.pipe(i),r.on("error",s),i.on("error",s);let o;i.on("integrity",a=>{o=a}),i.on("end",()=>n(o)),i.on("data",()=>{})})}ca.exports.checkData=eVe;function eVe(r,e,t){if(t=an(t),e=la(e,t),!Object.keys(e).length){if(t.error)throw Object.assign(new Error("No valid integrity hashes to check against"),{code:"EINTEGRITY"});return!1}let i=e.pickAlgorithm(t),n=xE.createHash(i).update(r).digest("base64"),s=la({algorithm:i,digest:n}),o=s.match(e,t);if(o||!t.error)return o;if(typeof t.size=="number"&&r.length!==t.size){let a=new Error(`data size mismatch when checking ${e}. + Wanted: ${t.size} + Found: ${r.length}`);throw a.code="EBADSIZE",a.found=r.length,a.expected=t.size,a.sri=e,a}else{let a=new Error(`Integrity checksum failed when using ${i}: Wanted ${e}, but got ${s}. (${r.length} bytes)`);throw a.code="EINTEGRITY",a.found=s,a.expected=e,a.algorithm=i,a.sri=e,a}}ca.exports.checkStream=tVe;function tVe(r,e,t){t=an(t);let i=t.Promise||Promise,n=u1(t.concat({integrity:e}));return new i((s,o)=>{r.pipe(n),r.on("error",o),n.on("error",o);let a;n.on("verified",l=>{a=l}),n.on("end",()=>s(a)),n.on("data",()=>{})})}ca.exports.integrityStream=u1;function u1(r){r=an(r);let e=r.integrity&&la(r.integrity,r),t=e&&Object.keys(e).length,i=t&&e.pickAlgorithm(r),n=t&&e[i],s=Array.from(new Set(r.algorithms.concat(i?[i]:[]))),o=s.map(xE.createHash),a=0,l=new J9e({transform(c,u,g){a+=c.length,o.forEach(h=>h.update(c,u)),g(null,c,u)}}).on("end",()=>{let c=r.options&&r.options.length?`?${r.options.join("?")}`:"",u=la(o.map((h,p)=>`${s[p]}-${h.digest("base64")}${c}`).join(" "),r),g=t&&u.match(e,r);if(typeof r.size=="number"&&a!==r.size){let h=new Error(`stream size mismatch when checking ${e}. + Wanted: ${r.size} + Found: ${a}`);h.code="EBADSIZE",h.found=a,h.expected=r.size,h.sri=e,l.emit("error",h)}else if(r.integrity&&!g){let h=new Error(`${e} integrity checksum failed when using ${i}: wanted ${n} but got ${u}. (${a} bytes)`);h.code="EINTEGRITY",h.found=u,h.expected=n,h.algorithm=i,h.sri=e,l.emit("error",h)}else l.emit("size",a),l.emit("integrity",u),g&&l.emit("verified",g)});return l}ca.exports.create=rVe;function rVe(r){r=an(r);let e=r.algorithms,t=r.options.length?`?${r.options.join("?")}`:"",i=e.map(xE.createHash);return{update:function(n,s){return i.forEach(o=>o.update(n,s)),this},digest:function(n){return e.reduce((o,a)=>{let l=i.shift().digest("base64"),c=new Fl(`${a}-${l}${t}`,r);if(c.algorithm&&c.digest){let u=c.algorithm;o[u]||(o[u]=[]),o[u].push(c)}return o},new $u)}}}var iVe=new Set(xE.getHashes()),Uue=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(r=>iVe.has(r));function nVe(r,e){return Uue.indexOf(r.toLowerCase())>=Uue.indexOf(e.toLowerCase())?r:e}});var om={};ct(om,{BuildType:()=>L0,Cache:()=>Dt,Configuration:()=>Ee,DEFAULT_LOCK_FILENAME:()=>oD,DEFAULT_RC_FILENAME:()=>sD,FormatType:()=>Bz,InstallMode:()=>ts,LightReport:()=>ta,LinkType:()=>Ef,Manifest:()=>ot,MessageName:()=>dt,MultiFetcher:()=>kf,PackageExtensionStatus:()=>XP,PackageExtensionType:()=>VP,Project:()=>Ge,ProjectLookup:()=>cD,Report:()=>Pi,ReportError:()=>rt,SettingsType:()=>aD,StreamReport:()=>He,TAG_REGEXP:()=>Rf,TelemetryManager:()=>Sh,ThrowReport:()=>$r,VirtualFetcher:()=>Ff,Workspace:()=>Qh,WorkspaceFetcher:()=>Tf,WorkspaceResolver:()=>Ur,YarnVersion:()=>Fr,execUtils:()=>pr,folderUtils:()=>Nw,formatUtils:()=>$,hashUtils:()=>Ai,httpUtils:()=>Vt,miscUtils:()=>me,nodeUtils:()=>ys,parseMessageName:()=>TI,scriptUtils:()=>Yt,semverUtils:()=>Qt,stringifyMessageName:()=>RA,structUtils:()=>P,tgzUtils:()=>Ci,treeUtils:()=>es});var pr={};ct(pr,{EndStrategy:()=>hD,ExecError:()=>jw,PipeError:()=>CC,execvp:()=>tD,pipevp:()=>so});var zp={};ct(zp,{AliasFS:()=>Qo,CustomDir:()=>jp,CwdFS:()=>jt,DEFAULT_COMPRESSION_LEVEL:()=>_l,FakeFS:()=>wa,Filename:()=>St,JailFS:()=>So,LazyFS:()=>Sg,LinkStrategy:()=>CS,NoFS:()=>qp,NodeFS:()=>Zt,PortablePath:()=>Te,PosixFS:()=>vg,ProxiedFS:()=>hi,VirtualFS:()=>yr,ZipFS:()=>qr,ZipOpenFS:()=>Kn,constants:()=>vr,extendFs:()=>aI,normalizeLineEndings:()=>Zl,npath:()=>K,opendir:()=>eI,patchFs:()=>bS,ppath:()=>v,statUtils:()=>Mp,toFilename:()=>Yr,xfs:()=>M});var vr={};ct(vr,{SAFE_TIME:()=>oK,S_IFDIR:()=>zl,S_IFLNK:()=>Xl,S_IFMT:()=>Ys,S_IFREG:()=>Vl});var Ys=61440,zl=16384,Vl=32768,Xl=40960,oK=456789e3;var Mp={};ct(Mp,{BigIntStatsEntry:()=>Bg,DEFAULT_MODE:()=>Lp,DirEntry:()=>cS,StatEntry:()=>ya,areStatsEqual:()=>gS,clearStats:()=>JE,convertToBigIntStats:()=>WE,makeDefaultStats:()=>Op,makeEmptyStats:()=>Gge});var uS=ve(J("util"));var Lp=33188,cS=class{constructor(){this.name="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},ya=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=Lp;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},Bg=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(Lp);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(61440))===BigInt(16384)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(61440))===BigInt(32768)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(61440))===BigInt(40960)}};function Op(){return new ya}function Gge(){return JE(Op())}function JE(r){for(let e in r)if(Object.prototype.hasOwnProperty.call(r,e)){let t=r[e];typeof t=="number"?r[e]=0:typeof t=="bigint"?r[e]=BigInt(0):uS.types.isDate(t)&&(r[e]=new Date(0))}return r}function WE(r){let e=new Bg;for(let t in r)if(Object.prototype.hasOwnProperty.call(r,t)){let i=r[t];typeof i=="number"?e[t]=BigInt(i):uS.types.isDate(i)&&(e[t]=new Date(i))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function gS(r,e){if(r.atimeMs!==e.atimeMs||r.birthtimeMs!==e.birthtimeMs||r.blksize!==e.blksize||r.blocks!==e.blocks||r.ctimeMs!==e.ctimeMs||r.dev!==e.dev||r.gid!==e.gid||r.ino!==e.ino||r.isBlockDevice()!==e.isBlockDevice()||r.isCharacterDevice()!==e.isCharacterDevice()||r.isDirectory()!==e.isDirectory()||r.isFIFO()!==e.isFIFO()||r.isFile()!==e.isFile()||r.isSocket()!==e.isSocket()||r.isSymbolicLink()!==e.isSymbolicLink()||r.mode!==e.mode||r.mtimeMs!==e.mtimeMs||r.nlink!==e.nlink||r.rdev!==e.rdev||r.size!==e.size||r.uid!==e.uid)return!1;let t=r,i=e;return!(t.atimeNs!==i.atimeNs||t.mtimeNs!==i.mtimeNs||t.ctimeNs!==i.ctimeNs||t.birthtimeNs!==i.birthtimeNs)}var VE=ve(J("fs"));var Kp=ve(J("path"));var Te={root:"/",dot:".",parent:".."},St={nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",rc:".yarnrc.yml"},K=Object.create(Kp.default),v=Object.create(Kp.default.posix);K.cwd=()=>process.cwd();v.cwd=()=>fS(process.cwd());v.resolve=(...r)=>r.length>0&&v.isAbsolute(r[0])?Kp.default.posix.resolve(...r):Kp.default.posix.resolve(v.cwd(),...r);var aK=function(r,e,t){return e=r.normalize(e),t=r.normalize(t),e===t?".":(e.endsWith(r.sep)||(e=e+r.sep),t.startsWith(e)?t.slice(e.length):null)};K.fromPortablePath=AK;K.toPortablePath=fS;K.contains=(r,e)=>aK(K,r,e);v.contains=(r,e)=>aK(v,r,e);var Yge=/^([a-zA-Z]:.*)$/,qge=/^\/\/(\.\/)?(.*)$/,Jge=/^\/([a-zA-Z]:.*)$/,Wge=/^\/unc\/(\.dot\/)?(.*)$/;function AK(r){if(process.platform!=="win32")return r;let e,t;if(e=r.match(Jge))r=e[1];else if(t=r.match(Wge))r=`\\\\${t[1]?".\\":""}${t[2]}`;else return r;return r.replace(/\//g,"\\")}function fS(r){if(process.platform!=="win32")return r;r=r.replace(/\\/g,"/");let e,t;return(e=r.match(Yge))?r=`/${e[1]}`:(t=r.match(qge))&&(r=`/unc/${t[1]?".dot/":""}${t[2]}`),r}function zE(r,e){return r===K?AK(e):fS(e)}function Yr(r){if(K.parse(r).dir!==""||v.parse(r).dir!=="")throw new Error(`Invalid filename: "${r}"`);return r}var XE=new Date(456789e3*1e3),CS=(t=>(t.Allow="allow",t.ReadOnly="readOnly",t))(CS||{});async function lK(r,e,t,i,n){let s=r.pathUtils.normalize(e),o=t.pathUtils.normalize(i),a=[],l=[],{atime:c,mtime:u}=n.stableTime?{atime:XE,mtime:XE}:await t.lstatPromise(o);await r.mkdirpPromise(r.pathUtils.dirname(e),{utimes:[c,u]});let g=typeof r.lutimesPromise=="function"?r.lutimesPromise.bind(r):r.utimesPromise.bind(r);await pS(a,l,g,r,s,t,o,{...n,didParentExist:!0});for(let h of a)await h();await Promise.all(l.map(h=>h()))}async function pS(r,e,t,i,n,s,o,a){var p,d;let l=a.didParentExist?await zge(i,n):null,c=await s.lstatPromise(o),{atime:u,mtime:g}=a.stableTime?{atime:XE,mtime:XE}:c,h;switch(!0){case c.isDirectory():h=await Vge(r,e,t,i,n,l,s,o,c,a);break;case c.isFile():h=await Zge(r,e,t,i,n,l,s,o,c,a);break;case c.isSymbolicLink():h=await _ge(r,e,t,i,n,l,s,o,c,a);break;default:throw new Error(`Unsupported file type (${c.mode})`)}return(h||((p=l==null?void 0:l.mtime)==null?void 0:p.getTime())!==g.getTime()||((d=l==null?void 0:l.atime)==null?void 0:d.getTime())!==u.getTime())&&(e.push(()=>t(n,u,g)),h=!0),(l===null||(l.mode&511)!==(c.mode&511))&&(e.push(()=>i.chmodPromise(n,c.mode&511)),h=!0),h}async function zge(r,e){try{return await r.lstatPromise(e)}catch{return null}}async function Vge(r,e,t,i,n,s,o,a,l,c){if(s!==null&&!s.isDirectory())if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;let u=!1;s===null&&(r.push(async()=>{try{await i.mkdirPromise(n,{mode:l.mode})}catch(p){if(p.code!=="EEXIST")throw p}}),u=!0);let g=await o.readdirPromise(a),h=c.didParentExist&&!s?{...c,didParentExist:!1}:c;if(c.stableSort)for(let p of g.sort())await pS(r,e,t,i,i.pathUtils.join(n,p),o,o.pathUtils.join(a,p),h)&&(u=!0);else(await Promise.all(g.map(async d=>{await pS(r,e,t,i,i.pathUtils.join(n,d),o,o.pathUtils.join(a,d),h)}))).some(d=>d)&&(u=!0);return u}var hS=new WeakMap;function dS(r,e,t,i,n){return async()=>{await r.linkPromise(t,e),n==="readOnly"&&(i.mode&=-147,await r.chmodPromise(e,i.mode))}}function Xge(r,e,t,i,n){let s=hS.get(r);return typeof s>"u"?async()=>{try{await r.copyFilePromise(t,e,VE.default.constants.COPYFILE_FICLONE_FORCE),hS.set(r,!0)}catch(o){if(o.code==="ENOSYS"||o.code==="ENOTSUP")hS.set(r,!1),await dS(r,e,t,i,n)();else throw o}}:s?async()=>r.copyFilePromise(t,e,VE.default.constants.COPYFILE_FICLONE_FORCE):dS(r,e,t,i,n)}async function Zge(r,e,t,i,n,s,o,a,l,c){var h;if(s!==null)if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;let u=(h=c.linkStrategy)!=null?h:null,g=i===o?u!==null?Xge(i,n,a,l,u):async()=>i.copyFilePromise(a,n,VE.default.constants.COPYFILE_FICLONE):u!==null?dS(i,n,a,l,u):async()=>i.writeFilePromise(n,await o.readFilePromise(a));return r.push(async()=>g()),!0}async function _ge(r,e,t,i,n,s,o,a,l,c){if(s!==null)if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;return r.push(async()=>{await i.symlinkPromise(zE(i.pathUtils,await o.readlinkPromise(a)),n)}),!0}function as(r,e){return Object.assign(new Error(`${r}: ${e}`),{code:r})}function _E(r){return as("EBUSY",r)}function Up(r,e){return as("ENOSYS",`${r}, ${e}`)}function SA(r){return as("EINVAL",`invalid argument, ${r}`)}function Or(r){return as("EBADF",`bad file descriptor, ${r}`)}function qs(r){return as("ENOENT",`no such file or directory, ${r}`)}function bo(r){return as("ENOTDIR",`not a directory, ${r}`)}function Hp(r){return as("EISDIR",`illegal operation on a directory, ${r}`)}function $E(r){return as("EEXIST",`file already exists, ${r}`)}function un(r){return as("EROFS",`read-only filesystem, ${r}`)}function cK(r){return as("ENOTEMPTY",`directory not empty, ${r}`)}function uK(r){return as("EOPNOTSUPP",`operation not supported, ${r}`)}function gK(){return as("ERR_DIR_CLOSED","Directory handle was closed")}var ZE=class extends Error{constructor(t,i){super(t);this.name="Libzip Error",this.code=i}};var jp=class{constructor(e,t,i={}){this.path=e;this.nextDirent=t;this.opts=i;this.closed=!1}throwIfClosed(){if(this.closed)throw gK()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let t=this.readSync();return typeof e<"u"?e(null,t):Promise.resolve(t)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e<"u"?e(null):Promise.resolve()}closeSync(){var e,t;this.throwIfClosed(),(t=(e=this.opts).onClose)==null||t.call(e),this.closed=!0}};function eI(r,e,t,i){let n=()=>{let s=t.shift();return typeof s>"u"?null:Object.assign(r.statSync(r.pathUtils.join(e,s)),{name:s})};return new jp(e,n,i)}var fK=J("os");var wa=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:t=!1}={}){let i=[e];for(;i.length>0;){let n=i.shift();if((await this.lstatPromise(n)).isDirectory()){let o=await this.readdirPromise(n);if(t)for(let a of o.sort())i.push(this.pathUtils.join(n,a));else throw new Error("Not supported")}else yield n}}async removePromise(e,{recursive:t=!0,maxRetries:i=5}={}){let n;try{n=await this.lstatPromise(e)}catch(s){if(s.code==="ENOENT")return;throw s}if(n.isDirectory()){if(t){let s=await this.readdirPromise(e);await Promise.all(s.map(o=>this.removePromise(this.pathUtils.resolve(e,o))))}for(let s=0;s<=i;s++)try{await this.rmdirPromise(e);break}catch(o){if(o.code!=="EBUSY"&&o.code!=="ENOTEMPTY")throw o;s<i&&await new Promise(a=>setTimeout(a,s*100))}}else await this.unlinkPromise(e)}removeSync(e,{recursive:t=!0}={}){let i;try{i=this.lstatSync(e)}catch(n){if(n.code==="ENOENT")return;throw n}if(i.isDirectory()){if(t)for(let n of this.readdirSync(e))this.removeSync(this.pathUtils.resolve(e,n));this.rmdirSync(e)}else this.unlinkSync(e)}async mkdirpPromise(e,{chmod:t,utimes:i}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let n=e.split(this.pathUtils.sep),s;for(let o=2;o<=n.length;++o){let a=n.slice(0,o).join(this.pathUtils.sep);if(!this.existsSync(a)){try{await this.mkdirPromise(a)}catch(l){if(l.code==="EEXIST")continue;throw l}if(s!=null||(s=a),t!=null&&await this.chmodPromise(a,t),i!=null)await this.utimesPromise(a,i[0],i[1]);else{let l=await this.statPromise(this.pathUtils.dirname(a));await this.utimesPromise(a,l.atime,l.mtime)}}}return s}mkdirpSync(e,{chmod:t,utimes:i}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let n=e.split(this.pathUtils.sep),s;for(let o=2;o<=n.length;++o){let a=n.slice(0,o).join(this.pathUtils.sep);if(!this.existsSync(a)){try{this.mkdirSync(a)}catch(l){if(l.code==="EEXIST")continue;throw l}if(s!=null||(s=a),t!=null&&this.chmodSync(a,t),i!=null)this.utimesSync(a,i[0],i[1]);else{let l=this.statSync(this.pathUtils.dirname(a));this.utimesSync(a,l.atime,l.mtime)}}}return s}async copyPromise(e,t,{baseFs:i=this,overwrite:n=!0,stableSort:s=!1,stableTime:o=!1,linkStrategy:a=null}={}){return await lK(this,e,i,t,{overwrite:n,stableSort:s,stableTime:o,linkStrategy:a})}copySync(e,t,{baseFs:i=this,overwrite:n=!0}={}){let s=i.lstatSync(t),o=this.existsSync(e);if(s.isDirectory()){this.mkdirpSync(e);let l=i.readdirSync(t);for(let c of l)this.copySync(this.pathUtils.join(e,c),i.pathUtils.join(t,c),{baseFs:i,overwrite:n})}else if(s.isFile()){if(!o||n){o&&this.removeSync(e);let l=i.readFileSync(t);this.writeFileSync(e,l)}}else if(s.isSymbolicLink()){if(!o||n){o&&this.removeSync(e);let l=i.readlinkSync(t);this.symlinkSync(zE(this.pathUtils,l),e)}}else throw new Error(`Unsupported file type (file: ${t}, mode: 0o${s.mode.toString(8).padStart(6,"0")})`);let a=s.mode&511;this.chmodSync(e,a)}async changeFilePromise(e,t,i={}){return Buffer.isBuffer(t)?this.changeFileBufferPromise(e,t,i):this.changeFileTextPromise(e,t,i)}async changeFileBufferPromise(e,t,{mode:i}={}){let n=Buffer.alloc(0);try{n=await this.readFilePromise(e)}catch{}Buffer.compare(n,t)!==0&&await this.writeFilePromise(e,t,{mode:i})}async changeFileTextPromise(e,t,{automaticNewlines:i,mode:n}={}){let s="";try{s=await this.readFilePromise(e,"utf8")}catch{}let o=i?Zl(s,t):t;s!==o&&await this.writeFilePromise(e,o,{mode:n})}changeFileSync(e,t,i={}){return Buffer.isBuffer(t)?this.changeFileBufferSync(e,t,i):this.changeFileTextSync(e,t,i)}changeFileBufferSync(e,t,{mode:i}={}){let n=Buffer.alloc(0);try{n=this.readFileSync(e)}catch{}Buffer.compare(n,t)!==0&&this.writeFileSync(e,t,{mode:i})}changeFileTextSync(e,t,{automaticNewlines:i=!1,mode:n}={}){let s="";try{s=this.readFileSync(e,"utf8")}catch{}let o=i?Zl(s,t):t;s!==o&&this.writeFileSync(e,o,{mode:n})}async movePromise(e,t){try{await this.renamePromise(e,t)}catch(i){if(i.code==="EXDEV")await this.copyPromise(t,e),await this.removePromise(e);else throw i}}moveSync(e,t){try{this.renameSync(e,t)}catch(i){if(i.code==="EXDEV")this.copySync(t,e),this.removeSync(e);else throw i}}async lockPromise(e,t){let i=`${e}.flock`,n=1e3/60,s=Date.now(),o=null,a=async()=>{let l;try{[l]=await this.readJsonPromise(i)}catch{return Date.now()-s<500}try{return process.kill(l,0),!0}catch{return!1}};for(;o===null;)try{o=await this.openPromise(i,"wx")}catch(l){if(l.code==="EEXIST"){if(!await a())try{await this.unlinkPromise(i);continue}catch{}if(Date.now()-s<60*1e3)await new Promise(c=>setTimeout(c,n));else throw new Error(`Couldn't acquire a lock in a reasonable time (via ${i})`)}else throw l}await this.writePromise(o,JSON.stringify([process.pid]));try{return await t()}finally{try{await this.closePromise(o),await this.unlinkPromise(i)}catch{}}}async readJsonPromise(e){let t=await this.readFilePromise(e,"utf8");try{return JSON.parse(t)}catch(i){throw i.message+=` (in ${e})`,i}}readJsonSync(e){let t=this.readFileSync(e,"utf8");try{return JSON.parse(t)}catch(i){throw i.message+=` (in ${e})`,i}}async writeJsonPromise(e,t){return await this.writeFilePromise(e,`${JSON.stringify(t,null,2)} +`)}writeJsonSync(e,t){return this.writeFileSync(e,`${JSON.stringify(t,null,2)} +`)}async preserveTimePromise(e,t){let i=await this.lstatPromise(e),n=await t();typeof n<"u"&&(e=n),this.lutimesPromise?await this.lutimesPromise(e,i.atime,i.mtime):i.isSymbolicLink()||await this.utimesPromise(e,i.atime,i.mtime)}async preserveTimeSync(e,t){let i=this.lstatSync(e),n=t();typeof n<"u"&&(e=n),this.lutimesSync?this.lutimesSync(e,i.atime,i.mtime):i.isSymbolicLink()||this.utimesSync(e,i.atime,i.mtime)}},vA=class extends wa{constructor(){super(v)}};function $ge(r){let e=r.match(/\r?\n/g);if(e===null)return fK.EOL;let t=e.filter(n=>n===`\r +`).length,i=e.length-t;return t>i?`\r +`:` +`}function Zl(r,e){return e.replace(/\r?\n/g,$ge(r))}var Qg=J("fs"),IS=J("stream"),CK=J("util"),yS=ve(J("zlib"));var hK=ve(J("fs"));var Zt=class extends vA{constructor(t=hK.default){super();this.realFs=t,typeof this.realFs.lutimes<"u"&&(this.lutimesPromise=this.lutimesPromiseImpl,this.lutimesSync=this.lutimesSyncImpl)}getExtractHint(){return!1}getRealPath(){return Te.root}resolve(t){return v.resolve(t)}async openPromise(t,i,n){return await new Promise((s,o)=>{this.realFs.open(K.fromPortablePath(t),i,n,this.makeCallback(s,o))})}openSync(t,i,n){return this.realFs.openSync(K.fromPortablePath(t),i,n)}async opendirPromise(t,i){return await new Promise((n,s)=>{typeof i<"u"?this.realFs.opendir(K.fromPortablePath(t),i,this.makeCallback(n,s)):this.realFs.opendir(K.fromPortablePath(t),this.makeCallback(n,s))}).then(n=>Object.defineProperty(n,"path",{value:t,configurable:!0,writable:!0}))}opendirSync(t,i){let n=typeof i<"u"?this.realFs.opendirSync(K.fromPortablePath(t),i):this.realFs.opendirSync(K.fromPortablePath(t));return Object.defineProperty(n,"path",{value:t,configurable:!0,writable:!0})}async readPromise(t,i,n=0,s=0,o=-1){return await new Promise((a,l)=>{this.realFs.read(t,i,n,s,o,(c,u)=>{c?l(c):a(u)})})}readSync(t,i,n,s,o){return this.realFs.readSync(t,i,n,s,o)}async writePromise(t,i,n,s,o){return await new Promise((a,l)=>typeof i=="string"?this.realFs.write(t,i,n,this.makeCallback(a,l)):this.realFs.write(t,i,n,s,o,this.makeCallback(a,l)))}writeSync(t,i,n,s,o){return typeof i=="string"?this.realFs.writeSync(t,i,n):this.realFs.writeSync(t,i,n,s,o)}async closePromise(t){await new Promise((i,n)=>{this.realFs.close(t,this.makeCallback(i,n))})}closeSync(t){this.realFs.closeSync(t)}createReadStream(t,i){let n=t!==null?K.fromPortablePath(t):t;return this.realFs.createReadStream(n,i)}createWriteStream(t,i){let n=t!==null?K.fromPortablePath(t):t;return this.realFs.createWriteStream(n,i)}async realpathPromise(t){return await new Promise((i,n)=>{this.realFs.realpath(K.fromPortablePath(t),{},this.makeCallback(i,n))}).then(i=>K.toPortablePath(i))}realpathSync(t){return K.toPortablePath(this.realFs.realpathSync(K.fromPortablePath(t),{}))}async existsPromise(t){return await new Promise(i=>{this.realFs.exists(K.fromPortablePath(t),i)})}accessSync(t,i){return this.realFs.accessSync(K.fromPortablePath(t),i)}async accessPromise(t,i){return await new Promise((n,s)=>{this.realFs.access(K.fromPortablePath(t),i,this.makeCallback(n,s))})}existsSync(t){return this.realFs.existsSync(K.fromPortablePath(t))}async statPromise(t,i){return await new Promise((n,s)=>{i?this.realFs.stat(K.fromPortablePath(t),i,this.makeCallback(n,s)):this.realFs.stat(K.fromPortablePath(t),this.makeCallback(n,s))})}statSync(t,i){return i?this.realFs.statSync(K.fromPortablePath(t),i):this.realFs.statSync(K.fromPortablePath(t))}async fstatPromise(t,i){return await new Promise((n,s)=>{i?this.realFs.fstat(t,i,this.makeCallback(n,s)):this.realFs.fstat(t,this.makeCallback(n,s))})}fstatSync(t,i){return i?this.realFs.fstatSync(t,i):this.realFs.fstatSync(t)}async lstatPromise(t,i){return await new Promise((n,s)=>{i?this.realFs.lstat(K.fromPortablePath(t),i,this.makeCallback(n,s)):this.realFs.lstat(K.fromPortablePath(t),this.makeCallback(n,s))})}lstatSync(t,i){return i?this.realFs.lstatSync(K.fromPortablePath(t),i):this.realFs.lstatSync(K.fromPortablePath(t))}async fchmodPromise(t,i){return await new Promise((n,s)=>{this.realFs.fchmod(t,i,this.makeCallback(n,s))})}fchmodSync(t,i){return this.realFs.fchmodSync(t,i)}async chmodPromise(t,i){return await new Promise((n,s)=>{this.realFs.chmod(K.fromPortablePath(t),i,this.makeCallback(n,s))})}chmodSync(t,i){return this.realFs.chmodSync(K.fromPortablePath(t),i)}async fchownPromise(t,i,n){return await new Promise((s,o)=>{this.realFs.fchown(t,i,n,this.makeCallback(s,o))})}fchownSync(t,i,n){return this.realFs.fchownSync(t,i,n)}async chownPromise(t,i,n){return await new Promise((s,o)=>{this.realFs.chown(K.fromPortablePath(t),i,n,this.makeCallback(s,o))})}chownSync(t,i,n){return this.realFs.chownSync(K.fromPortablePath(t),i,n)}async renamePromise(t,i){return await new Promise((n,s)=>{this.realFs.rename(K.fromPortablePath(t),K.fromPortablePath(i),this.makeCallback(n,s))})}renameSync(t,i){return this.realFs.renameSync(K.fromPortablePath(t),K.fromPortablePath(i))}async copyFilePromise(t,i,n=0){return await new Promise((s,o)=>{this.realFs.copyFile(K.fromPortablePath(t),K.fromPortablePath(i),n,this.makeCallback(s,o))})}copyFileSync(t,i,n=0){return this.realFs.copyFileSync(K.fromPortablePath(t),K.fromPortablePath(i),n)}async appendFilePromise(t,i,n){return await new Promise((s,o)=>{let a=typeof t=="string"?K.fromPortablePath(t):t;n?this.realFs.appendFile(a,i,n,this.makeCallback(s,o)):this.realFs.appendFile(a,i,this.makeCallback(s,o))})}appendFileSync(t,i,n){let s=typeof t=="string"?K.fromPortablePath(t):t;n?this.realFs.appendFileSync(s,i,n):this.realFs.appendFileSync(s,i)}async writeFilePromise(t,i,n){return await new Promise((s,o)=>{let a=typeof t=="string"?K.fromPortablePath(t):t;n?this.realFs.writeFile(a,i,n,this.makeCallback(s,o)):this.realFs.writeFile(a,i,this.makeCallback(s,o))})}writeFileSync(t,i,n){let s=typeof t=="string"?K.fromPortablePath(t):t;n?this.realFs.writeFileSync(s,i,n):this.realFs.writeFileSync(s,i)}async unlinkPromise(t){return await new Promise((i,n)=>{this.realFs.unlink(K.fromPortablePath(t),this.makeCallback(i,n))})}unlinkSync(t){return this.realFs.unlinkSync(K.fromPortablePath(t))}async utimesPromise(t,i,n){return await new Promise((s,o)=>{this.realFs.utimes(K.fromPortablePath(t),i,n,this.makeCallback(s,o))})}utimesSync(t,i,n){this.realFs.utimesSync(K.fromPortablePath(t),i,n)}async lutimesPromiseImpl(t,i,n){let s=this.realFs.lutimes;if(typeof s>"u")throw Up("unavailable Node binding",`lutimes '${t}'`);return await new Promise((o,a)=>{s.call(this.realFs,K.fromPortablePath(t),i,n,this.makeCallback(o,a))})}lutimesSyncImpl(t,i,n){let s=this.realFs.lutimesSync;if(typeof s>"u")throw Up("unavailable Node binding",`lutimes '${t}'`);s.call(this.realFs,K.fromPortablePath(t),i,n)}async mkdirPromise(t,i){return await new Promise((n,s)=>{this.realFs.mkdir(K.fromPortablePath(t),i,this.makeCallback(n,s))})}mkdirSync(t,i){return this.realFs.mkdirSync(K.fromPortablePath(t),i)}async rmdirPromise(t,i){return await new Promise((n,s)=>{i?this.realFs.rmdir(K.fromPortablePath(t),i,this.makeCallback(n,s)):this.realFs.rmdir(K.fromPortablePath(t),this.makeCallback(n,s))})}rmdirSync(t,i){return this.realFs.rmdirSync(K.fromPortablePath(t),i)}async linkPromise(t,i){return await new Promise((n,s)=>{this.realFs.link(K.fromPortablePath(t),K.fromPortablePath(i),this.makeCallback(n,s))})}linkSync(t,i){return this.realFs.linkSync(K.fromPortablePath(t),K.fromPortablePath(i))}async symlinkPromise(t,i,n){return await new Promise((s,o)=>{this.realFs.symlink(K.fromPortablePath(t.replace(/\/+$/,"")),K.fromPortablePath(i),n,this.makeCallback(s,o))})}symlinkSync(t,i,n){return this.realFs.symlinkSync(K.fromPortablePath(t.replace(/\/+$/,"")),K.fromPortablePath(i),n)}async readFilePromise(t,i){return await new Promise((n,s)=>{let o=typeof t=="string"?K.fromPortablePath(t):t;this.realFs.readFile(o,i,this.makeCallback(n,s))})}readFileSync(t,i){let n=typeof t=="string"?K.fromPortablePath(t):t;return this.realFs.readFileSync(n,i)}async readdirPromise(t,i){return await new Promise((n,s)=>{i!=null&&i.withFileTypes?this.realFs.readdir(K.fromPortablePath(t),{withFileTypes:!0},this.makeCallback(n,s)):this.realFs.readdir(K.fromPortablePath(t),this.makeCallback(o=>n(o),s))})}readdirSync(t,i){return i!=null&&i.withFileTypes?this.realFs.readdirSync(K.fromPortablePath(t),{withFileTypes:!0}):this.realFs.readdirSync(K.fromPortablePath(t))}async readlinkPromise(t){return await new Promise((i,n)=>{this.realFs.readlink(K.fromPortablePath(t),this.makeCallback(i,n))}).then(i=>K.toPortablePath(i))}readlinkSync(t){return K.toPortablePath(this.realFs.readlinkSync(K.fromPortablePath(t)))}async truncatePromise(t,i){return await new Promise((n,s)=>{this.realFs.truncate(K.fromPortablePath(t),i,this.makeCallback(n,s))})}truncateSync(t,i){return this.realFs.truncateSync(K.fromPortablePath(t),i)}async ftruncatePromise(t,i){return await new Promise((n,s)=>{this.realFs.ftruncate(t,i,this.makeCallback(n,s))})}ftruncateSync(t,i){return this.realFs.ftruncateSync(t,i)}watch(t,i,n){return this.realFs.watch(K.fromPortablePath(t),i,n)}watchFile(t,i,n){return this.realFs.watchFile(K.fromPortablePath(t),i,n)}unwatchFile(t,i){return this.realFs.unwatchFile(K.fromPortablePath(t),i)}makeCallback(t,i){return(n,s)=>{n?i(n):t(s)}}};var dK=J("events");function pK(r,e){if(r!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${r}'`)}var bg=class extends dK.EventEmitter{constructor(t,i,{bigint:n=!1}={}){super();this.status="ready";this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=t,this.path=i,this.bigint=n,this.lastStats=this.stat()}static create(t,i,n){let s=new bg(t,i,n);return s.start(),s}start(){pK(this.status,"ready"),this.status="running",this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit("change",this.lastStats,this.lastStats)},3)}stop(){pK(this.status,"running"),this.status="stopped",this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit("stop")}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch{let i=this.bigint?new Bg:new ya;return JE(i)}}makeInterval(t){let i=setInterval(()=>{let n=this.stat(),s=this.lastStats;gS(n,s)||(this.lastStats=n,this.emit("change",n,s))},t.interval);return t.persistent?i:i.unref()}registerChangeListener(t,i){this.addListener("change",t),this.changeListeners.set(t,this.makeInterval(i))}unregisterChangeListener(t){this.removeListener("change",t);let i=this.changeListeners.get(t);typeof i<"u"&&clearInterval(i),this.changeListeners.delete(t)}unregisterAllChangeListeners(){for(let t of this.changeListeners.keys())this.unregisterChangeListener(t)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let t of this.changeListeners.values())t.ref();return this}unref(){for(let t of this.changeListeners.values())t.unref();return this}};var tI=new WeakMap;function rI(r,e,t,i){let n,s,o,a;switch(typeof t){case"function":n=!1,s=!0,o=5007,a=t;break;default:({bigint:n=!1,persistent:s=!0,interval:o=5007}=t),a=i;break}let l=tI.get(r);typeof l>"u"&&tI.set(r,l=new Map);let c=l.get(e);return typeof c>"u"&&(c=bg.create(r,e,{bigint:n}),l.set(e,c)),c.registerChangeListener(a,{persistent:s,interval:o}),c}function Gp(r,e,t){let i=tI.get(r);if(typeof i>"u")return;let n=i.get(e);typeof n>"u"||(typeof t>"u"?n.unregisterAllChangeListeners():n.unregisterChangeListener(t),n.hasChangeListeners()||(n.stop(),i.delete(e)))}function Yp(r){let e=tI.get(r);if(!(typeof e>"u"))for(let t of e.keys())Gp(r,t)}var _l="mixed";function efe(r){if(typeof r=="string"&&String(+r)===r)return+r;if(typeof r=="number"&&Number.isFinite(r))return r<0?Date.now()/1e3:r;if(CK.types.isDate(r))return r.getTime()/1e3;throw new Error("Invalid time")}function ES(){return Buffer.from([80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])}var qr=class extends vA{constructor(t,i){super();this.lzSource=null;this.listings=new Map;this.entries=new Map;this.fileSources=new Map;this.fds=new Map;this.nextFd=0;this.ready=!1;this.readOnly=!1;this.libzip=i.libzip;let n=i;if(this.level=typeof n.level<"u"?n.level:_l,t!=null||(t=ES()),typeof t=="string"){let{baseFs:a=new Zt}=n;this.baseFs=a,this.path=t}else this.path=null,this.baseFs=null;if(i.stats)this.stats=i.stats;else if(typeof t=="string")try{this.stats=this.baseFs.statSync(t)}catch(a){if(a.code==="ENOENT"&&n.create)this.stats=Op();else throw a}else this.stats=Op();let s=this.libzip.malloc(4);try{let a=0;if(typeof t=="string"&&n.create&&(a|=this.libzip.ZIP_CREATE|this.libzip.ZIP_TRUNCATE),i.readOnly&&(a|=this.libzip.ZIP_RDONLY,this.readOnly=!0),typeof t=="string")this.zip=this.libzip.open(K.fromPortablePath(t),a,s);else{let l=this.allocateUnattachedSource(t);try{this.zip=this.libzip.openFromSource(l,a,s),this.lzSource=l}catch(c){throw this.libzip.source.free(l),c}}if(this.zip===0){let l=this.libzip.struct.errorS();throw this.libzip.error.initWithCode(l,this.libzip.getValue(s,"i32")),this.makeLibzipError(l)}}finally{this.libzip.free(s)}this.listings.set(Te.root,new Set);let o=this.libzip.getNumEntries(this.zip,0);for(let a=0;a<o;++a){let l=this.libzip.getName(this.zip,a,0);if(v.isAbsolute(l))continue;let c=v.resolve(Te.root,l);this.registerEntry(c,a),l.endsWith("/")&&this.registerListing(c)}if(this.symlinkCount=this.libzip.ext.countSymlinks(this.zip),this.symlinkCount===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.ready=!0}makeLibzipError(t){let i=this.libzip.struct.errorCodeZip(t),n=this.libzip.error.strerror(t),s=new ZE(n,this.libzip.errors[i]);if(i===this.libzip.errors.ZIP_ER_CHANGED)throw new Error(`Assertion failed: Unexpected libzip error: ${s.message}`);return s}getExtractHint(t){for(let i of this.entries.keys()){let n=this.pathUtils.extname(i);if(t.relevantExtensions.has(n))return!0}return!1}getAllFiles(){return Array.from(this.entries.keys())}getRealPath(){if(!this.path)throw new Error("ZipFS don't have real paths when loaded from a buffer");return this.path}getBufferAndClose(){if(this.prepareClose(),!this.lzSource)throw new Error("ZipFS was not created from a Buffer");if(this.entries.size===0)return this.discardAndClose(),ES();try{if(this.libzip.source.keep(this.lzSource),this.libzip.close(this.zip)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.libzip.source.open(this.lzSource)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(this.libzip.source.seek(this.lzSource,0,0,this.libzip.SEEK_END)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));let t=this.libzip.source.tell(this.lzSource);if(t===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(this.libzip.source.seek(this.lzSource,0,0,this.libzip.SEEK_SET)===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));let i=this.libzip.malloc(t);if(!i)throw new Error("Couldn't allocate enough memory");try{let n=this.libzip.source.read(this.lzSource,i,t);if(n===-1)throw this.makeLibzipError(this.libzip.source.error(this.lzSource));if(n<t)throw new Error("Incomplete read");if(n>t)throw new Error("Overread");let s=this.libzip.HEAPU8.subarray(i,i+t);return Buffer.from(s)}finally{this.libzip.free(i)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}prepareClose(){if(!this.ready)throw _E("archive closed, close");Yp(this)}saveAndClose(){if(!this.path||!this.baseFs)throw new Error("ZipFS cannot be saved and must be discarded when loaded from a buffer");if(this.prepareClose(),this.readOnly){this.discardAndClose();return}let t=this.baseFs.existsSync(this.path)||this.stats.mode===Lp?void 0:this.stats.mode;if(this.entries.size===0)this.discardAndClose(),this.baseFs.writeFileSync(this.path,ES(),{mode:t});else{if(this.libzip.close(this.zip)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));typeof t<"u"&&this.baseFs.chmodSync(this.path,t)}this.ready=!1}discardAndClose(){this.prepareClose(),this.libzip.discard(this.zip),this.ready=!1}resolve(t){return v.resolve(Te.root,t)}async openPromise(t,i,n){return this.openSync(t,i,n)}openSync(t,i,n){let s=this.nextFd++;return this.fds.set(s,{cursor:0,p:t}),s}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(t,i){return this.opendirSync(t,i)}opendirSync(t,i={}){let n=this.resolveFilename(`opendir '${t}'`,t);if(!this.entries.has(n)&&!this.listings.has(n))throw qs(`opendir '${t}'`);let s=this.listings.get(n);if(!s)throw bo(`opendir '${t}'`);let o=[...s],a=this.openSync(n,"r");return eI(this,n,o,{onClose:()=>{this.closeSync(a)}})}async readPromise(t,i,n,s,o){return this.readSync(t,i,n,s,o)}readSync(t,i,n=0,s=i.byteLength,o=-1){let a=this.fds.get(t);if(typeof a>"u")throw Or("read");let l=o===-1||o===null?a.cursor:o,c=this.readFileSync(a.p);c.copy(i,n,l,l+s);let u=Math.max(0,Math.min(c.length-l,s));return(o===-1||o===null)&&(a.cursor+=u),u}async writePromise(t,i,n,s,o){return typeof i=="string"?this.writeSync(t,i,o):this.writeSync(t,i,n,s,o)}writeSync(t,i,n,s,o){throw typeof this.fds.get(t)>"u"?Or("read"):new Error("Unimplemented")}async closePromise(t){return this.closeSync(t)}closeSync(t){if(typeof this.fds.get(t)>"u")throw Or("read");this.fds.delete(t)}createReadStream(t,{encoding:i}={}){if(t===null)throw new Error("Unimplemented");let n=this.openSync(t,"r"),s=Object.assign(new IS.PassThrough({emitClose:!0,autoDestroy:!0,destroy:(a,l)=>{clearImmediate(o),this.closeSync(n),l(a)}}),{close(){s.destroy()},bytesRead:0,path:t,pending:!1}),o=setImmediate(async()=>{try{let a=await this.readFilePromise(t,i);s.bytesRead=a.length,s.end(a)}catch(a){s.destroy(a)}});return s}createWriteStream(t,{encoding:i}={}){if(this.readOnly)throw un(`open '${t}'`);if(t===null)throw new Error("Unimplemented");let n=[],s=this.openSync(t,"w"),o=Object.assign(new IS.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(a,l)=>{try{a?l(a):(this.writeFileSync(t,Buffer.concat(n),i),l(null))}catch(c){l(c)}finally{this.closeSync(s)}}}),{close(){o.destroy()},bytesWritten:0,path:t,pending:!1});return o.on("data",a=>{let l=Buffer.from(a);o.bytesWritten+=l.length,n.push(l)}),o}async realpathPromise(t){return this.realpathSync(t)}realpathSync(t){let i=this.resolveFilename(`lstat '${t}'`,t);if(!this.entries.has(i)&&!this.listings.has(i))throw qs(`lstat '${t}'`);return i}async existsPromise(t){return this.existsSync(t)}existsSync(t){if(!this.ready)throw _E(`archive closed, existsSync '${t}'`);if(this.symlinkCount===0){let n=v.resolve(Te.root,t);return this.entries.has(n)||this.listings.has(n)}let i;try{i=this.resolveFilename(`stat '${t}'`,t,void 0,!1)}catch{return!1}return i===void 0?!1:this.entries.has(i)||this.listings.has(i)}async accessPromise(t,i){return this.accessSync(t,i)}accessSync(t,i=Qg.constants.F_OK){let n=this.resolveFilename(`access '${t}'`,t);if(!this.entries.has(n)&&!this.listings.has(n))throw qs(`access '${t}'`);if(this.readOnly&&i&Qg.constants.W_OK)throw un(`access '${t}'`)}async statPromise(t,i={bigint:!1}){return i.bigint?this.statSync(t,{bigint:!0}):this.statSync(t)}statSync(t,i={bigint:!1,throwIfNoEntry:!0}){let n=this.resolveFilename(`stat '${t}'`,t,void 0,i.throwIfNoEntry);if(n!==void 0){if(!this.entries.has(n)&&!this.listings.has(n)){if(i.throwIfNoEntry===!1)return;throw qs(`stat '${t}'`)}if(t[t.length-1]==="/"&&!this.listings.has(n))throw bo(`stat '${t}'`);return this.statImpl(`stat '${t}'`,n,i)}}async fstatPromise(t,i){return this.fstatSync(t,i)}fstatSync(t,i){let n=this.fds.get(t);if(typeof n>"u")throw Or("fstatSync");let{p:s}=n,o=this.resolveFilename(`stat '${s}'`,s);if(!this.entries.has(o)&&!this.listings.has(o))throw qs(`stat '${s}'`);if(s[s.length-1]==="/"&&!this.listings.has(o))throw bo(`stat '${s}'`);return this.statImpl(`fstat '${s}'`,o,i)}async lstatPromise(t,i={bigint:!1}){return i.bigint?this.lstatSync(t,{bigint:!0}):this.lstatSync(t)}lstatSync(t,i={bigint:!1,throwIfNoEntry:!0}){let n=this.resolveFilename(`lstat '${t}'`,t,!1,i.throwIfNoEntry);if(n!==void 0){if(!this.entries.has(n)&&!this.listings.has(n)){if(i.throwIfNoEntry===!1)return;throw qs(`lstat '${t}'`)}if(t[t.length-1]==="/"&&!this.listings.has(n))throw bo(`lstat '${t}'`);return this.statImpl(`lstat '${t}'`,n,i)}}statImpl(t,i,n={}){let s=this.entries.get(i);if(typeof s<"u"){let o=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,s,0,0,o)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let l=this.stats.uid,c=this.stats.gid,u=this.libzip.struct.statSize(o)>>>0,g=512,h=Math.ceil(u/g),p=(this.libzip.struct.statMtime(o)>>>0)*1e3,d=p,m=p,y=p,B=new Date(d),S=new Date(m),x=new Date(y),F=new Date(p),H=this.listings.has(i)?16384:this.isSymbolicLink(s)?40960:32768,q=H===16384?493:420,_=H|this.getUnixMode(s,q)&511,X=this.libzip.struct.statCrc(o),W=Object.assign(new ya,{uid:l,gid:c,size:u,blksize:g,blocks:h,atime:B,birthtime:S,ctime:x,mtime:F,atimeMs:d,birthtimeMs:m,ctimeMs:y,mtimeMs:p,mode:_,crc:X});return n.bigint===!0?WE(W):W}if(this.listings.has(i)){let o=this.stats.uid,a=this.stats.gid,l=0,c=512,u=0,g=this.stats.mtimeMs,h=this.stats.mtimeMs,p=this.stats.mtimeMs,d=this.stats.mtimeMs,m=new Date(g),y=new Date(h),B=new Date(p),S=new Date(d),x=16877,F=0,H=Object.assign(new ya,{uid:o,gid:a,size:l,blksize:c,blocks:u,atime:m,birthtime:y,ctime:B,mtime:S,atimeMs:g,birthtimeMs:h,ctimeMs:p,mtimeMs:d,mode:x,crc:F});return n.bigint===!0?WE(H):H}throw new Error("Unreachable")}getUnixMode(t,i){if(this.libzip.file.getExternalAttributes(this.zip,t,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?i:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(t){let i=this.listings.get(t);if(i)return i;this.registerListing(v.dirname(t)).add(v.basename(t));let s=new Set;return this.listings.set(t,s),s}registerEntry(t,i){this.registerListing(v.dirname(t)).add(v.basename(t)),this.entries.set(t,i)}unregisterListing(t){this.listings.delete(t);let i=this.listings.get(v.dirname(t));i==null||i.delete(v.basename(t))}unregisterEntry(t){this.unregisterListing(t);let i=this.entries.get(t);this.entries.delete(t),!(typeof i>"u")&&(this.fileSources.delete(i),this.isSymbolicLink(i)&&this.symlinkCount--)}deleteEntry(t,i){if(this.unregisterEntry(t),this.libzip.delete(this.zip,i)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(t,i,n=!0,s=!0){if(!this.ready)throw _E(`archive closed, ${t}`);let o=v.resolve(Te.root,i);if(o==="/")return Te.root;let a=this.entries.get(o);if(n&&a!==void 0)if(this.symlinkCount!==0&&this.isSymbolicLink(a)){let l=this.getFileSource(a).toString();return this.resolveFilename(t,v.resolve(v.dirname(o),l),!0,s)}else return o;for(;;){let l=this.resolveFilename(t,v.dirname(o),!0,s);if(l===void 0)return l;let c=this.listings.has(l),u=this.entries.has(l);if(!c&&!u){if(s===!1)return;throw qs(t)}if(!c)throw bo(t);if(o=v.resolve(l,v.basename(o)),!n||this.symlinkCount===0)break;let g=this.libzip.name.locate(this.zip,o.slice(1),0);if(g===-1)break;if(this.isSymbolicLink(g)){let h=this.getFileSource(g).toString();o=v.resolve(v.dirname(o),h)}else break}return o}allocateBuffer(t){Buffer.isBuffer(t)||(t=Buffer.from(t));let i=this.libzip.malloc(t.byteLength);if(!i)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,i,t.byteLength).set(t),{buffer:i,byteLength:t.byteLength}}allocateUnattachedSource(t){let i=this.libzip.struct.errorS(),{buffer:n,byteLength:s}=this.allocateBuffer(t),o=this.libzip.source.fromUnattachedBuffer(n,s,0,1,i);if(o===0)throw this.libzip.free(i),this.makeLibzipError(i);return o}allocateSource(t){let{buffer:i,byteLength:n}=this.allocateBuffer(t),s=this.libzip.source.fromBuffer(this.zip,i,n,0,1);if(s===0)throw this.libzip.free(i),this.makeLibzipError(this.libzip.getError(this.zip));return s}setFileSource(t,i){let n=Buffer.isBuffer(i)?i:Buffer.from(i),s=v.relative(Te.root,t),o=this.allocateSource(i);try{let a=this.libzip.file.add(this.zip,s,o,this.libzip.ZIP_FL_OVERWRITE);if(a===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));if(this.level!=="mixed"){let l=this.level===0?this.libzip.ZIP_CM_STORE:this.libzip.ZIP_CM_DEFLATE;if(this.libzip.file.setCompression(this.zip,a,0,l,this.level)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}return this.fileSources.set(a,n),a}catch(a){throw this.libzip.source.free(o),a}}isSymbolicLink(t){if(this.symlinkCount===0)return!1;if(this.libzip.file.getExternalAttributes(this.zip,t,0,0,this.libzip.uint08S,this.libzip.uint32S)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.libzip.getValue(this.libzip.uint08S,"i8")>>>0!==this.libzip.ZIP_OPSYS_UNIX?!1:(this.libzip.getValue(this.libzip.uint32S,"i32")>>>16&61440)===40960}getFileSource(t,i={asyncDecompress:!1}){let n=this.fileSources.get(t);if(typeof n<"u")return n;let s=this.libzip.struct.statS();if(this.libzip.statIndex(this.zip,t,0,0,s)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));let a=this.libzip.struct.statCompSize(s),l=this.libzip.struct.statCompMethod(s),c=this.libzip.malloc(a);try{let u=this.libzip.fopenIndex(this.zip,t,0,this.libzip.ZIP_FL_COMPRESSED);if(u===0)throw this.makeLibzipError(this.libzip.getError(this.zip));try{let g=this.libzip.fread(u,c,a,0);if(g===-1)throw this.makeLibzipError(this.libzip.file.getError(u));if(g<a)throw new Error("Incomplete read");if(g>a)throw new Error("Overread");let h=this.libzip.HEAPU8.subarray(c,c+a),p=Buffer.from(h);if(l===0)return this.fileSources.set(t,p),p;if(i.asyncDecompress)return new Promise((d,m)=>{yS.default.inflateRaw(p,(y,B)=>{y?m(y):(this.fileSources.set(t,B),d(B))})});{let d=yS.default.inflateRawSync(p);return this.fileSources.set(t,d),d}}finally{this.libzip.fclose(u)}}finally{this.libzip.free(c)}}async fchmodPromise(t,i){return this.chmodPromise(this.fdToPath(t,"fchmod"),i)}fchmodSync(t,i){return this.chmodSync(this.fdToPath(t,"fchmodSync"),i)}async chmodPromise(t,i){return this.chmodSync(t,i)}chmodSync(t,i){if(this.readOnly)throw un(`chmod '${t}'`);i&=493;let n=this.resolveFilename(`chmod '${t}'`,t,!1),s=this.entries.get(n);if(typeof s>"u")throw new Error(`Assertion failed: The entry should have been registered (${n})`);let a=this.getUnixMode(s,32768)&-512|i;if(this.libzip.file.setExternalAttributes(this.zip,s,0,0,this.libzip.ZIP_OPSYS_UNIX,a<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async fchownPromise(t,i,n){return this.chownPromise(this.fdToPath(t,"fchown"),i,n)}fchownSync(t,i,n){return this.chownSync(this.fdToPath(t,"fchownSync"),i,n)}async chownPromise(t,i,n){return this.chownSync(t,i,n)}chownSync(t,i,n){throw new Error("Unimplemented")}async renamePromise(t,i){return this.renameSync(t,i)}renameSync(t,i){throw new Error("Unimplemented")}async copyFilePromise(t,i,n){let{indexSource:s,indexDest:o,resolvedDestP:a}=this.prepareCopyFile(t,i,n),l=await this.getFileSource(s,{asyncDecompress:!0}),c=this.setFileSource(a,l);c!==o&&this.registerEntry(a,c)}copyFileSync(t,i,n=0){let{indexSource:s,indexDest:o,resolvedDestP:a}=this.prepareCopyFile(t,i,n),l=this.getFileSource(s),c=this.setFileSource(a,l);c!==o&&this.registerEntry(a,c)}prepareCopyFile(t,i,n=0){if(this.readOnly)throw un(`copyfile '${t} -> '${i}'`);if((n&Qg.constants.COPYFILE_FICLONE_FORCE)!==0)throw Up("unsupported clone operation",`copyfile '${t}' -> ${i}'`);let s=this.resolveFilename(`copyfile '${t} -> ${i}'`,t),o=this.entries.get(s);if(typeof o>"u")throw SA(`copyfile '${t}' -> '${i}'`);let a=this.resolveFilename(`copyfile '${t}' -> ${i}'`,i),l=this.entries.get(a);if((n&(Qg.constants.COPYFILE_EXCL|Qg.constants.COPYFILE_FICLONE_FORCE))!==0&&typeof l<"u")throw $E(`copyfile '${t}' -> '${i}'`);return{indexSource:o,resolvedDestP:a,indexDest:l}}async appendFilePromise(t,i,n){if(this.readOnly)throw un(`open '${t}'`);return typeof n>"u"?n={flag:"a"}:typeof n=="string"?n={flag:"a",encoding:n}:typeof n.flag>"u"&&(n={flag:"a",...n}),this.writeFilePromise(t,i,n)}appendFileSync(t,i,n={}){if(this.readOnly)throw un(`open '${t}'`);return typeof n>"u"?n={flag:"a"}:typeof n=="string"?n={flag:"a",encoding:n}:typeof n.flag>"u"&&(n={flag:"a",...n}),this.writeFileSync(t,i,n)}fdToPath(t,i){var s;let n=(s=this.fds.get(t))==null?void 0:s.p;if(typeof n>"u")throw Or(i);return n}async writeFilePromise(t,i,n){let{encoding:s,mode:o,index:a,resolvedP:l}=this.prepareWriteFile(t,n);a!==void 0&&typeof n=="object"&&n.flag&&n.flag.includes("a")&&(i=Buffer.concat([await this.getFileSource(a,{asyncDecompress:!0}),Buffer.from(i)])),s!==null&&(i=i.toString(s));let c=this.setFileSource(l,i);c!==a&&this.registerEntry(l,c),o!==null&&await this.chmodPromise(l,o)}writeFileSync(t,i,n){let{encoding:s,mode:o,index:a,resolvedP:l}=this.prepareWriteFile(t,n);a!==void 0&&typeof n=="object"&&n.flag&&n.flag.includes("a")&&(i=Buffer.concat([this.getFileSource(a),Buffer.from(i)])),s!==null&&(i=i.toString(s));let c=this.setFileSource(l,i);c!==a&&this.registerEntry(l,c),o!==null&&this.chmodSync(l,o)}prepareWriteFile(t,i){if(typeof t=="number"&&(t=this.fdToPath(t,"read")),this.readOnly)throw un(`open '${t}'`);let n=this.resolveFilename(`open '${t}'`,t);if(this.listings.has(n))throw Hp(`open '${t}'`);let s=null,o=null;typeof i=="string"?s=i:typeof i=="object"&&({encoding:s=null,mode:o=null}=i);let a=this.entries.get(n);return{encoding:s,mode:o,resolvedP:n,index:a}}async unlinkPromise(t){return this.unlinkSync(t)}unlinkSync(t){if(this.readOnly)throw un(`unlink '${t}'`);let i=this.resolveFilename(`unlink '${t}'`,t);if(this.listings.has(i))throw Hp(`unlink '${t}'`);let n=this.entries.get(i);if(typeof n>"u")throw SA(`unlink '${t}'`);this.deleteEntry(i,n)}async utimesPromise(t,i,n){return this.utimesSync(t,i,n)}utimesSync(t,i,n){if(this.readOnly)throw un(`utimes '${t}'`);let s=this.resolveFilename(`utimes '${t}'`,t);this.utimesImpl(s,n)}async lutimesPromise(t,i,n){return this.lutimesSync(t,i,n)}lutimesSync(t,i,n){if(this.readOnly)throw un(`lutimes '${t}'`);let s=this.resolveFilename(`utimes '${t}'`,t,!1);this.utimesImpl(s,n)}utimesImpl(t,i){this.listings.has(t)&&(this.entries.has(t)||this.hydrateDirectory(t));let n=this.entries.get(t);if(n===void 0)throw new Error("Unreachable");if(this.libzip.file.setMtime(this.zip,n,0,efe(i),0)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(t,i){return this.mkdirSync(t,i)}mkdirSync(t,{mode:i=493,recursive:n=!1}={}){if(n)return this.mkdirpSync(t,{chmod:i});if(this.readOnly)throw un(`mkdir '${t}'`);let s=this.resolveFilename(`mkdir '${t}'`,t);if(this.entries.has(s)||this.listings.has(s))throw $E(`mkdir '${t}'`);this.hydrateDirectory(s),this.chmodSync(s,i)}async rmdirPromise(t,i){return this.rmdirSync(t,i)}rmdirSync(t,{recursive:i=!1}={}){if(this.readOnly)throw un(`rmdir '${t}'`);if(i){this.removeSync(t);return}let n=this.resolveFilename(`rmdir '${t}'`,t),s=this.listings.get(n);if(!s)throw bo(`rmdir '${t}'`);if(s.size>0)throw cK(`rmdir '${t}'`);let o=this.entries.get(n);if(typeof o>"u")throw SA(`rmdir '${t}'`);this.deleteEntry(t,o)}hydrateDirectory(t){let i=this.libzip.dir.add(this.zip,v.relative(Te.root,t));if(i===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(t),this.registerEntry(t,i),i}async linkPromise(t,i){return this.linkSync(t,i)}linkSync(t,i){throw uK(`link '${t}' -> '${i}'`)}async symlinkPromise(t,i){return this.symlinkSync(t,i)}symlinkSync(t,i){if(this.readOnly)throw un(`symlink '${t}' -> '${i}'`);let n=this.resolveFilename(`symlink '${t}' -> '${i}'`,i);if(this.listings.has(n))throw Hp(`symlink '${t}' -> '${i}'`);if(this.entries.has(n))throw $E(`symlink '${t}' -> '${i}'`);let s=this.setFileSource(n,t);if(this.registerEntry(n,s),this.libzip.file.setExternalAttributes(this.zip,s,0,0,this.libzip.ZIP_OPSYS_UNIX,41471<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(t,i){typeof i=="object"&&(i=i?i.encoding:void 0);let n=await this.readFileBuffer(t,{asyncDecompress:!0});return i?n.toString(i):n}readFileSync(t,i){typeof i=="object"&&(i=i?i.encoding:void 0);let n=this.readFileBuffer(t);return i?n.toString(i):n}readFileBuffer(t,i={asyncDecompress:!1}){typeof t=="number"&&(t=this.fdToPath(t,"read"));let n=this.resolveFilename(`open '${t}'`,t);if(!this.entries.has(n)&&!this.listings.has(n))throw qs(`open '${t}'`);if(t[t.length-1]==="/"&&!this.listings.has(n))throw bo(`open '${t}'`);if(this.listings.has(n))throw Hp("read");let s=this.entries.get(n);if(s===void 0)throw new Error("Unreachable");return this.getFileSource(s,i)}async readdirPromise(t,i){return this.readdirSync(t,i)}readdirSync(t,i){let n=this.resolveFilename(`scandir '${t}'`,t);if(!this.entries.has(n)&&!this.listings.has(n))throw qs(`scandir '${t}'`);let s=this.listings.get(n);if(!s)throw bo(`scandir '${t}'`);let o=[...s];return i!=null&&i.withFileTypes?o.map(a=>Object.assign(this.statImpl("lstat",v.join(t,a)),{name:a})):o}async readlinkPromise(t){let i=this.prepareReadlink(t);return(await this.getFileSource(i,{asyncDecompress:!0})).toString()}readlinkSync(t){let i=this.prepareReadlink(t);return this.getFileSource(i).toString()}prepareReadlink(t){let i=this.resolveFilename(`readlink '${t}'`,t,!1);if(!this.entries.has(i)&&!this.listings.has(i))throw qs(`readlink '${t}'`);if(t[t.length-1]==="/"&&!this.listings.has(i))throw bo(`open '${t}'`);if(this.listings.has(i))throw SA(`readlink '${t}'`);let n=this.entries.get(i);if(n===void 0)throw new Error("Unreachable");if(!this.isSymbolicLink(n))throw SA(`readlink '${t}'`);return n}async truncatePromise(t,i=0){let n=this.resolveFilename(`open '${t}'`,t),s=this.entries.get(n);if(typeof s>"u")throw SA(`open '${t}'`);let o=await this.getFileSource(s,{asyncDecompress:!0}),a=Buffer.alloc(i,0);return o.copy(a),await this.writeFilePromise(t,a)}truncateSync(t,i=0){let n=this.resolveFilename(`open '${t}'`,t),s=this.entries.get(n);if(typeof s>"u")throw SA(`open '${t}'`);let o=this.getFileSource(s),a=Buffer.alloc(i,0);return o.copy(a),this.writeFileSync(t,a)}async ftruncatePromise(t,i){return this.truncatePromise(this.fdToPath(t,"ftruncate"),i)}ftruncateSync(t,i){return this.truncateSync(this.fdToPath(t,"ftruncateSync"),i)}watch(t,i,n){let s;switch(typeof i){case"function":case"string":case"undefined":s=!0;break;default:({persistent:s=!0}=i);break}if(!s)return{on:()=>{},close:()=>{}};let o=setInterval(()=>{},24*60*60*1e3);return{on:()=>{},close:()=>{clearInterval(o)}}}watchFile(t,i,n){let s=v.resolve(Te.root,t);return rI(this,s,i,n)}unwatchFile(t,i){let n=v.resolve(Te.root,t);return Gp(this,n,i)}};var hi=class extends wa{getExtractHint(e){return this.baseFs.getExtractHint(e)}resolve(e){return this.mapFromBase(this.baseFs.resolve(this.mapToBase(e)))}getRealPath(){return this.mapFromBase(this.baseFs.getRealPath())}async openPromise(e,t,i){return this.baseFs.openPromise(this.mapToBase(e),t,i)}openSync(e,t,i){return this.baseFs.openSync(this.mapToBase(e),t,i)}async opendirPromise(e,t){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),t),{path:e})}opendirSync(e,t){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),t),{path:e})}async readPromise(e,t,i,n,s){return await this.baseFs.readPromise(e,t,i,n,s)}readSync(e,t,i,n,s){return this.baseFs.readSync(e,t,i,n,s)}async writePromise(e,t,i,n,s){return typeof t=="string"?await this.baseFs.writePromise(e,t,i):await this.baseFs.writePromise(e,t,i,n,s)}writeSync(e,t,i,n,s){return typeof t=="string"?this.baseFs.writeSync(e,t,i):this.baseFs.writeSync(e,t,i,n,s)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,t){return this.baseFs.createReadStream(e!==null?this.mapToBase(e):e,t)}createWriteStream(e,t){return this.baseFs.createWriteStream(e!==null?this.mapToBase(e):e,t)}async realpathPromise(e){return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(e)))}realpathSync(e){return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(e)))}async existsPromise(e){return this.baseFs.existsPromise(this.mapToBase(e))}existsSync(e){return this.baseFs.existsSync(this.mapToBase(e))}accessSync(e,t){return this.baseFs.accessSync(this.mapToBase(e),t)}async accessPromise(e,t){return this.baseFs.accessPromise(this.mapToBase(e),t)}async statPromise(e,t){return this.baseFs.statPromise(this.mapToBase(e),t)}statSync(e,t){return this.baseFs.statSync(this.mapToBase(e),t)}async fstatPromise(e,t){return this.baseFs.fstatPromise(e,t)}fstatSync(e,t){return this.baseFs.fstatSync(e,t)}lstatPromise(e,t){return this.baseFs.lstatPromise(this.mapToBase(e),t)}lstatSync(e,t){return this.baseFs.lstatSync(this.mapToBase(e),t)}async fchmodPromise(e,t){return this.baseFs.fchmodPromise(e,t)}fchmodSync(e,t){return this.baseFs.fchmodSync(e,t)}async chmodPromise(e,t){return this.baseFs.chmodPromise(this.mapToBase(e),t)}chmodSync(e,t){return this.baseFs.chmodSync(this.mapToBase(e),t)}async fchownPromise(e,t,i){return this.baseFs.fchownPromise(e,t,i)}fchownSync(e,t,i){return this.baseFs.fchownSync(e,t,i)}async chownPromise(e,t,i){return this.baseFs.chownPromise(this.mapToBase(e),t,i)}chownSync(e,t,i){return this.baseFs.chownSync(this.mapToBase(e),t,i)}async renamePromise(e,t){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(t))}renameSync(e,t){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(t))}async copyFilePromise(e,t,i=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(t),i)}copyFileSync(e,t,i=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(t),i)}async appendFilePromise(e,t,i){return this.baseFs.appendFilePromise(this.fsMapToBase(e),t,i)}appendFileSync(e,t,i){return this.baseFs.appendFileSync(this.fsMapToBase(e),t,i)}async writeFilePromise(e,t,i){return this.baseFs.writeFilePromise(this.fsMapToBase(e),t,i)}writeFileSync(e,t,i){return this.baseFs.writeFileSync(this.fsMapToBase(e),t,i)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,t,i){return this.baseFs.utimesPromise(this.mapToBase(e),t,i)}utimesSync(e,t,i){return this.baseFs.utimesSync(this.mapToBase(e),t,i)}async mkdirPromise(e,t){return this.baseFs.mkdirPromise(this.mapToBase(e),t)}mkdirSync(e,t){return this.baseFs.mkdirSync(this.mapToBase(e),t)}async rmdirPromise(e,t){return this.baseFs.rmdirPromise(this.mapToBase(e),t)}rmdirSync(e,t){return this.baseFs.rmdirSync(this.mapToBase(e),t)}async linkPromise(e,t){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(t))}linkSync(e,t){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(t))}async symlinkPromise(e,t,i){let n=this.mapToBase(t);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkPromise(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(t),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkPromise(o,n,i)}symlinkSync(e,t,i){let n=this.mapToBase(t);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkSync(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(t),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkSync(o,n,i)}async readFilePromise(e,t){return this.baseFs.readFilePromise(this.fsMapToBase(e),t)}readFileSync(e,t){return this.baseFs.readFileSync(this.fsMapToBase(e),t)}async readdirPromise(e,t){return this.baseFs.readdirPromise(this.mapToBase(e),t)}readdirSync(e,t){return this.baseFs.readdirSync(this.mapToBase(e),t)}async readlinkPromise(e){return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(e)))}readlinkSync(e){return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(e)))}async truncatePromise(e,t){return this.baseFs.truncatePromise(this.mapToBase(e),t)}truncateSync(e,t){return this.baseFs.truncateSync(this.mapToBase(e),t)}async ftruncatePromise(e,t){return this.baseFs.ftruncatePromise(e,t)}ftruncateSync(e,t){return this.baseFs.ftruncateSync(e,t)}watch(e,t,i){return this.baseFs.watch(this.mapToBase(e),t,i)}watchFile(e,t,i){return this.baseFs.watchFile(this.mapToBase(e),t,i)}unwatchFile(e,t){return this.baseFs.unwatchFile(this.mapToBase(e),t)}fsMapToBase(e){return typeof e=="number"?e:this.mapToBase(e)}};var Qo=class extends hi{constructor(t,{baseFs:i,pathUtils:n}){super(n);this.target=t,this.baseFs=i}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(t){return t}mapToBase(t){return t}};var jt=class extends hi{constructor(t,{baseFs:i=new Zt}={}){super(v);this.target=this.pathUtils.normalize(t),this.baseFs=i}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(t){return this.pathUtils.isAbsolute(t)?v.normalize(t):this.baseFs.resolve(v.join(this.target,t))}mapFromBase(t){return t}mapToBase(t){return this.pathUtils.isAbsolute(t)?t:this.pathUtils.join(this.target,t)}};var mK=Te.root,So=class extends hi{constructor(t,{baseFs:i=new Zt}={}){super(v);this.target=this.pathUtils.resolve(Te.root,t),this.baseFs=i}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(Te.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(t){let i=this.pathUtils.normalize(t);if(this.pathUtils.isAbsolute(t))return this.pathUtils.resolve(this.target,this.pathUtils.relative(mK,t));if(i.match(/^\.\.\/?/))throw new Error(`Resolving this path (${t}) would escape the jail`);return this.pathUtils.resolve(this.target,t)}mapFromBase(t){return this.pathUtils.resolve(mK,this.pathUtils.relative(this.target,t))}};var Sg=class extends hi{constructor(t,i){super(i);this.instance=null;this.factory=t}get baseFs(){return this.instance||(this.instance=this.factory()),this.instance}set baseFs(t){this.instance=t}mapFromBase(t){return t}mapToBase(t){return t}};var Xe=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"}),wS=class extends wa{constructor(){super(v)}getExtractHint(){throw Xe()}getRealPath(){throw Xe()}resolve(){throw Xe()}async openPromise(){throw Xe()}openSync(){throw Xe()}async opendirPromise(){throw Xe()}opendirSync(){throw Xe()}async readPromise(){throw Xe()}readSync(){throw Xe()}async writePromise(){throw Xe()}writeSync(){throw Xe()}async closePromise(){throw Xe()}closeSync(){throw Xe()}createWriteStream(){throw Xe()}createReadStream(){throw Xe()}async realpathPromise(){throw Xe()}realpathSync(){throw Xe()}async readdirPromise(){throw Xe()}readdirSync(){throw Xe()}async existsPromise(e){throw Xe()}existsSync(e){throw Xe()}async accessPromise(){throw Xe()}accessSync(){throw Xe()}async statPromise(){throw Xe()}statSync(){throw Xe()}async fstatPromise(e){throw Xe()}fstatSync(e){throw Xe()}async lstatPromise(e){throw Xe()}lstatSync(e){throw Xe()}async fchmodPromise(){throw Xe()}fchmodSync(){throw Xe()}async chmodPromise(){throw Xe()}chmodSync(){throw Xe()}async fchownPromise(){throw Xe()}fchownSync(){throw Xe()}async chownPromise(){throw Xe()}chownSync(){throw Xe()}async mkdirPromise(){throw Xe()}mkdirSync(){throw Xe()}async rmdirPromise(){throw Xe()}rmdirSync(){throw Xe()}async linkPromise(){throw Xe()}linkSync(){throw Xe()}async symlinkPromise(){throw Xe()}symlinkSync(){throw Xe()}async renamePromise(){throw Xe()}renameSync(){throw Xe()}async copyFilePromise(){throw Xe()}copyFileSync(){throw Xe()}async appendFilePromise(){throw Xe()}appendFileSync(){throw Xe()}async writeFilePromise(){throw Xe()}writeFileSync(){throw Xe()}async unlinkPromise(){throw Xe()}unlinkSync(){throw Xe()}async utimesPromise(){throw Xe()}utimesSync(){throw Xe()}async readFilePromise(){throw Xe()}readFileSync(){throw Xe()}async readlinkPromise(){throw Xe()}readlinkSync(){throw Xe()}async truncatePromise(){throw Xe()}truncateSync(){throw Xe()}async ftruncatePromise(e,t){throw Xe()}ftruncateSync(e,t){throw Xe()}watch(){throw Xe()}watchFile(){throw Xe()}unwatchFile(){throw Xe()}},qp=wS;qp.instance=new wS;var vg=class extends hi{constructor(t){super(K);this.baseFs=t}mapFromBase(t){return K.fromPortablePath(t)}mapToBase(t){return K.toPortablePath(t)}};var tfe=/^[0-9]+$/,BS=/^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,rfe=/^([^/]+-)?[a-f0-9]+$/,yr=class extends hi{constructor({baseFs:t=new Zt}={}){super(v);this.baseFs=t}static makeVirtualPath(t,i,n){if(v.basename(t)!=="__virtual__")throw new Error('Assertion failed: Virtual folders must be named "__virtual__"');if(!v.basename(i).match(rfe))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");let o=v.relative(v.dirname(t),n).split("/"),a=0;for(;a<o.length&&o[a]==="..";)a+=1;let l=o.slice(a);return v.join(t,i,String(a),...l)}static resolveVirtual(t){let i=t.match(BS);if(!i||!i[3]&&i[5])return t;let n=v.dirname(i[1]);if(!i[3]||!i[4])return n;if(!tfe.test(i[4]))return t;let o=Number(i[4]),a="../".repeat(o),l=i[5]||".";return yr.resolveVirtual(v.join(n,a,l))}getExtractHint(t){return this.baseFs.getExtractHint(t)}getRealPath(){return this.baseFs.getRealPath()}realpathSync(t){let i=t.match(BS);if(!i)return this.baseFs.realpathSync(t);if(!i[5])return t;let n=this.baseFs.realpathSync(this.mapToBase(t));return yr.makeVirtualPath(i[1],i[3],n)}async realpathPromise(t){let i=t.match(BS);if(!i)return await this.baseFs.realpathPromise(t);if(!i[5])return t;let n=await this.baseFs.realpathPromise(this.mapToBase(t));return yr.makeVirtualPath(i[1],i[3],n)}mapToBase(t){if(t==="")return t;if(this.pathUtils.isAbsolute(t))return yr.resolveVirtual(t);let i=yr.resolveVirtual(this.baseFs.resolve(Te.dot)),n=yr.resolveVirtual(this.baseFs.resolve(t));return v.relative(i,n)||Te.dot}mapFromBase(t){return t}};var Jp=J("fs");var gn=4278190080,zi=704643072,EK=(r,e)=>{let t=r.indexOf(e);if(t<=0)return null;let i=t;for(;t>=0&&(i=t+e.length,r[i]!==v.sep);){if(r[t-1]===v.sep)return null;t=r.indexOf(e,i)}return r.length>i&&r[i]!==v.sep?null:r.slice(0,i)},Kn=class extends vA{constructor({libzip:t,baseFs:i=new Zt,filter:n=null,maxOpenFiles:s=1/0,readOnlyArchives:o=!1,useCache:a=!0,maxAge:l=5e3,fileExtensions:c=null}){super();this.fdMap=new Map;this.nextFd=3;this.isZip=new Set;this.notZip=new Set;this.realPaths=new Map;this.limitOpenFilesTimeout=null;this.libzipFactory=typeof t!="function"?()=>t:t,this.baseFs=i,this.zipInstances=a?new Map:null,this.filter=n,this.maxOpenFiles=s,this.readOnlyArchives=o,this.maxAge=l,this.fileExtensions=c}static async openPromise(t,i){let n=new Kn(i);try{return await t(n)}finally{n.saveAndClose()}}get libzip(){return typeof this.libzipInstance>"u"&&(this.libzipInstance=this.libzipFactory()),this.libzipInstance}getExtractHint(t){return this.baseFs.getExtractHint(t)}getRealPath(){return this.baseFs.getRealPath()}saveAndClose(){if(Yp(this),this.zipInstances)for(let[t,{zipFs:i}]of this.zipInstances.entries())i.saveAndClose(),this.zipInstances.delete(t)}discardAndClose(){if(Yp(this),this.zipInstances)for(let[t,{zipFs:i}]of this.zipInstances.entries())i.discardAndClose(),this.zipInstances.delete(t)}resolve(t){return this.baseFs.resolve(t)}remapFd(t,i){let n=this.nextFd++|zi;return this.fdMap.set(n,[t,i]),n}async openPromise(t,i,n){return await this.makeCallPromise(t,async()=>await this.baseFs.openPromise(t,i,n),async(s,{subPath:o})=>this.remapFd(s,await s.openPromise(o,i,n)))}openSync(t,i,n){return this.makeCallSync(t,()=>this.baseFs.openSync(t,i,n),(s,{subPath:o})=>this.remapFd(s,s.openSync(o,i,n)))}async opendirPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.opendirPromise(t,i),async(n,{subPath:s})=>await n.opendirPromise(s,i),{requireSubpath:!1})}opendirSync(t,i){return this.makeCallSync(t,()=>this.baseFs.opendirSync(t,i),(n,{subPath:s})=>n.opendirSync(s,i),{requireSubpath:!1})}async readPromise(t,i,n,s,o){if((t&gn)!==zi)return await this.baseFs.readPromise(t,i,n,s,o);let a=this.fdMap.get(t);if(typeof a>"u")throw Or("read");let[l,c]=a;return await l.readPromise(c,i,n,s,o)}readSync(t,i,n,s,o){if((t&gn)!==zi)return this.baseFs.readSync(t,i,n,s,o);let a=this.fdMap.get(t);if(typeof a>"u")throw Or("readSync");let[l,c]=a;return l.readSync(c,i,n,s,o)}async writePromise(t,i,n,s,o){if((t&gn)!==zi)return typeof i=="string"?await this.baseFs.writePromise(t,i,n):await this.baseFs.writePromise(t,i,n,s,o);let a=this.fdMap.get(t);if(typeof a>"u")throw Or("write");let[l,c]=a;return typeof i=="string"?await l.writePromise(c,i,n):await l.writePromise(c,i,n,s,o)}writeSync(t,i,n,s,o){if((t&gn)!==zi)return typeof i=="string"?this.baseFs.writeSync(t,i,n):this.baseFs.writeSync(t,i,n,s,o);let a=this.fdMap.get(t);if(typeof a>"u")throw Or("writeSync");let[l,c]=a;return typeof i=="string"?l.writeSync(c,i,n):l.writeSync(c,i,n,s,o)}async closePromise(t){if((t&gn)!==zi)return await this.baseFs.closePromise(t);let i=this.fdMap.get(t);if(typeof i>"u")throw Or("close");this.fdMap.delete(t);let[n,s]=i;return await n.closePromise(s)}closeSync(t){if((t&gn)!==zi)return this.baseFs.closeSync(t);let i=this.fdMap.get(t);if(typeof i>"u")throw Or("closeSync");this.fdMap.delete(t);let[n,s]=i;return n.closeSync(s)}createReadStream(t,i){return t===null?this.baseFs.createReadStream(t,i):this.makeCallSync(t,()=>this.baseFs.createReadStream(t,i),(n,{archivePath:s,subPath:o})=>{let a=n.createReadStream(o,i);return a.path=K.fromPortablePath(this.pathUtils.join(s,o)),a})}createWriteStream(t,i){return t===null?this.baseFs.createWriteStream(t,i):this.makeCallSync(t,()=>this.baseFs.createWriteStream(t,i),(n,{subPath:s})=>n.createWriteStream(s,i))}async realpathPromise(t){return await this.makeCallPromise(t,async()=>await this.baseFs.realpathPromise(t),async(i,{archivePath:n,subPath:s})=>{let o=this.realPaths.get(n);return typeof o>"u"&&(o=await this.baseFs.realpathPromise(n),this.realPaths.set(n,o)),this.pathUtils.join(o,this.pathUtils.relative(Te.root,await i.realpathPromise(s)))})}realpathSync(t){return this.makeCallSync(t,()=>this.baseFs.realpathSync(t),(i,{archivePath:n,subPath:s})=>{let o=this.realPaths.get(n);return typeof o>"u"&&(o=this.baseFs.realpathSync(n),this.realPaths.set(n,o)),this.pathUtils.join(o,this.pathUtils.relative(Te.root,i.realpathSync(s)))})}async existsPromise(t){return await this.makeCallPromise(t,async()=>await this.baseFs.existsPromise(t),async(i,{subPath:n})=>await i.existsPromise(n))}existsSync(t){return this.makeCallSync(t,()=>this.baseFs.existsSync(t),(i,{subPath:n})=>i.existsSync(n))}async accessPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.accessPromise(t,i),async(n,{subPath:s})=>await n.accessPromise(s,i))}accessSync(t,i){return this.makeCallSync(t,()=>this.baseFs.accessSync(t,i),(n,{subPath:s})=>n.accessSync(s,i))}async statPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.statPromise(t,i),async(n,{subPath:s})=>await n.statPromise(s,i))}statSync(t,i){return this.makeCallSync(t,()=>this.baseFs.statSync(t,i),(n,{subPath:s})=>n.statSync(s,i))}async fstatPromise(t,i){if((t&gn)!==zi)return this.baseFs.fstatPromise(t,i);let n=this.fdMap.get(t);if(typeof n>"u")throw Or("fstat");let[s,o]=n;return s.fstatPromise(o,i)}fstatSync(t,i){if((t&gn)!==zi)return this.baseFs.fstatSync(t,i);let n=this.fdMap.get(t);if(typeof n>"u")throw Or("fstatSync");let[s,o]=n;return s.fstatSync(o,i)}async lstatPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.lstatPromise(t,i),async(n,{subPath:s})=>await n.lstatPromise(s,i))}lstatSync(t,i){return this.makeCallSync(t,()=>this.baseFs.lstatSync(t,i),(n,{subPath:s})=>n.lstatSync(s,i))}async fchmodPromise(t,i){if((t&gn)!==zi)return this.baseFs.fchmodPromise(t,i);let n=this.fdMap.get(t);if(typeof n>"u")throw Or("fchmod");let[s,o]=n;return s.fchmodPromise(o,i)}fchmodSync(t,i){if((t&gn)!==zi)return this.baseFs.fchmodSync(t,i);let n=this.fdMap.get(t);if(typeof n>"u")throw Or("fchmodSync");let[s,o]=n;return s.fchmodSync(o,i)}async chmodPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.chmodPromise(t,i),async(n,{subPath:s})=>await n.chmodPromise(s,i))}chmodSync(t,i){return this.makeCallSync(t,()=>this.baseFs.chmodSync(t,i),(n,{subPath:s})=>n.chmodSync(s,i))}async fchownPromise(t,i,n){if((t&gn)!==zi)return this.baseFs.fchownPromise(t,i,n);let s=this.fdMap.get(t);if(typeof s>"u")throw Or("fchown");let[o,a]=s;return o.fchownPromise(a,i,n)}fchownSync(t,i,n){if((t&gn)!==zi)return this.baseFs.fchownSync(t,i,n);let s=this.fdMap.get(t);if(typeof s>"u")throw Or("fchownSync");let[o,a]=s;return o.fchownSync(a,i,n)}async chownPromise(t,i,n){return await this.makeCallPromise(t,async()=>await this.baseFs.chownPromise(t,i,n),async(s,{subPath:o})=>await s.chownPromise(o,i,n))}chownSync(t,i,n){return this.makeCallSync(t,()=>this.baseFs.chownSync(t,i,n),(s,{subPath:o})=>s.chownSync(o,i,n))}async renamePromise(t,i){return await this.makeCallPromise(t,async()=>await this.makeCallPromise(i,async()=>await this.baseFs.renamePromise(t,i),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(n,{subPath:s})=>await this.makeCallPromise(i,async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},async(o,{subPath:a})=>{if(n!==o)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return await n.renamePromise(s,a)}))}renameSync(t,i){return this.makeCallSync(t,()=>this.makeCallSync(i,()=>this.baseFs.renameSync(t,i),()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(n,{subPath:s})=>this.makeCallSync(i,()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})},(o,{subPath:a})=>{if(n!==o)throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"});return n.renameSync(s,a)}))}async copyFilePromise(t,i,n=0){let s=async(o,a,l,c)=>{if((n&Jp.constants.COPYFILE_FICLONE_FORCE)!==0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${a}' -> ${c}'`),{code:"EXDEV"});if(n&Jp.constants.COPYFILE_EXCL&&await this.existsPromise(a))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${a}' -> '${c}'`),{code:"EEXIST"});let u;try{u=await o.readFilePromise(a)}catch{throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${a}' -> '${c}'`),{code:"EINVAL"})}await l.writeFilePromise(c,u)};return await this.makeCallPromise(t,async()=>await this.makeCallPromise(i,async()=>await this.baseFs.copyFilePromise(t,i,n),async(o,{subPath:a})=>await s(this.baseFs,t,o,a)),async(o,{subPath:a})=>await this.makeCallPromise(i,async()=>await s(o,a,this.baseFs,i),async(l,{subPath:c})=>o!==l?await s(o,a,l,c):await o.copyFilePromise(a,c,n)))}copyFileSync(t,i,n=0){let s=(o,a,l,c)=>{if((n&Jp.constants.COPYFILE_FICLONE_FORCE)!==0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${a}' -> ${c}'`),{code:"EXDEV"});if(n&Jp.constants.COPYFILE_EXCL&&this.existsSync(a))throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${a}' -> '${c}'`),{code:"EEXIST"});let u;try{u=o.readFileSync(a)}catch{throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${a}' -> '${c}'`),{code:"EINVAL"})}l.writeFileSync(c,u)};return this.makeCallSync(t,()=>this.makeCallSync(i,()=>this.baseFs.copyFileSync(t,i,n),(o,{subPath:a})=>s(this.baseFs,t,o,a)),(o,{subPath:a})=>this.makeCallSync(i,()=>s(o,a,this.baseFs,i),(l,{subPath:c})=>o!==l?s(o,a,l,c):o.copyFileSync(a,c,n)))}async appendFilePromise(t,i,n){return await this.makeCallPromise(t,async()=>await this.baseFs.appendFilePromise(t,i,n),async(s,{subPath:o})=>await s.appendFilePromise(o,i,n))}appendFileSync(t,i,n){return this.makeCallSync(t,()=>this.baseFs.appendFileSync(t,i,n),(s,{subPath:o})=>s.appendFileSync(o,i,n))}async writeFilePromise(t,i,n){return await this.makeCallPromise(t,async()=>await this.baseFs.writeFilePromise(t,i,n),async(s,{subPath:o})=>await s.writeFilePromise(o,i,n))}writeFileSync(t,i,n){return this.makeCallSync(t,()=>this.baseFs.writeFileSync(t,i,n),(s,{subPath:o})=>s.writeFileSync(o,i,n))}async unlinkPromise(t){return await this.makeCallPromise(t,async()=>await this.baseFs.unlinkPromise(t),async(i,{subPath:n})=>await i.unlinkPromise(n))}unlinkSync(t){return this.makeCallSync(t,()=>this.baseFs.unlinkSync(t),(i,{subPath:n})=>i.unlinkSync(n))}async utimesPromise(t,i,n){return await this.makeCallPromise(t,async()=>await this.baseFs.utimesPromise(t,i,n),async(s,{subPath:o})=>await s.utimesPromise(o,i,n))}utimesSync(t,i,n){return this.makeCallSync(t,()=>this.baseFs.utimesSync(t,i,n),(s,{subPath:o})=>s.utimesSync(o,i,n))}async mkdirPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.mkdirPromise(t,i),async(n,{subPath:s})=>await n.mkdirPromise(s,i))}mkdirSync(t,i){return this.makeCallSync(t,()=>this.baseFs.mkdirSync(t,i),(n,{subPath:s})=>n.mkdirSync(s,i))}async rmdirPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.rmdirPromise(t,i),async(n,{subPath:s})=>await n.rmdirPromise(s,i))}rmdirSync(t,i){return this.makeCallSync(t,()=>this.baseFs.rmdirSync(t,i),(n,{subPath:s})=>n.rmdirSync(s,i))}async linkPromise(t,i){return await this.makeCallPromise(i,async()=>await this.baseFs.linkPromise(t,i),async(n,{subPath:s})=>await n.linkPromise(t,s))}linkSync(t,i){return this.makeCallSync(i,()=>this.baseFs.linkSync(t,i),(n,{subPath:s})=>n.linkSync(t,s))}async symlinkPromise(t,i,n){return await this.makeCallPromise(i,async()=>await this.baseFs.symlinkPromise(t,i,n),async(s,{subPath:o})=>await s.symlinkPromise(t,o))}symlinkSync(t,i,n){return this.makeCallSync(i,()=>this.baseFs.symlinkSync(t,i,n),(s,{subPath:o})=>s.symlinkSync(t,o))}async readFilePromise(t,i){return this.makeCallPromise(t,async()=>await this.baseFs.readFilePromise(t,i),async(n,{subPath:s})=>await n.readFilePromise(s,i))}readFileSync(t,i){return this.makeCallSync(t,()=>this.baseFs.readFileSync(t,i),(n,{subPath:s})=>n.readFileSync(s,i))}async readdirPromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.readdirPromise(t,i),async(n,{subPath:s})=>await n.readdirPromise(s,i),{requireSubpath:!1})}readdirSync(t,i){return this.makeCallSync(t,()=>this.baseFs.readdirSync(t,i),(n,{subPath:s})=>n.readdirSync(s,i),{requireSubpath:!1})}async readlinkPromise(t){return await this.makeCallPromise(t,async()=>await this.baseFs.readlinkPromise(t),async(i,{subPath:n})=>await i.readlinkPromise(n))}readlinkSync(t){return this.makeCallSync(t,()=>this.baseFs.readlinkSync(t),(i,{subPath:n})=>i.readlinkSync(n))}async truncatePromise(t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.truncatePromise(t,i),async(n,{subPath:s})=>await n.truncatePromise(s,i))}truncateSync(t,i){return this.makeCallSync(t,()=>this.baseFs.truncateSync(t,i),(n,{subPath:s})=>n.truncateSync(s,i))}async ftruncatePromise(t,i){if((t&gn)!==zi)return this.baseFs.ftruncatePromise(t,i);let n=this.fdMap.get(t);if(typeof n>"u")throw Or("ftruncate");let[s,o]=n;return s.ftruncatePromise(o,i)}ftruncateSync(t,i){if((t&gn)!==zi)return this.baseFs.ftruncateSync(t,i);let n=this.fdMap.get(t);if(typeof n>"u")throw Or("ftruncateSync");let[s,o]=n;return s.ftruncateSync(o,i)}watch(t,i,n){return this.makeCallSync(t,()=>this.baseFs.watch(t,i,n),(s,{subPath:o})=>s.watch(o,i,n))}watchFile(t,i,n){return this.makeCallSync(t,()=>this.baseFs.watchFile(t,i,n),()=>rI(this,t,i,n))}unwatchFile(t,i){return this.makeCallSync(t,()=>this.baseFs.unwatchFile(t,i),()=>Gp(this,t,i))}async makeCallPromise(t,i,n,{requireSubpath:s=!0}={}){if(typeof t!="string")return await i();let o=this.resolve(t),a=this.findZip(o);return a?s&&a.subPath==="/"?await i():await this.getZipPromise(a.archivePath,async l=>await n(l,a)):await i()}makeCallSync(t,i,n,{requireSubpath:s=!0}={}){if(typeof t!="string")return i();let o=this.resolve(t),a=this.findZip(o);return!a||s&&a.subPath==="/"?i():this.getZipSync(a.archivePath,l=>n(l,a))}findZip(t){if(this.filter&&!this.filter.test(t))return null;let i="";for(;;){let n=t.substring(i.length),s;if(!this.fileExtensions)s=EK(n,".zip");else for(let o of this.fileExtensions)if(s=EK(n,o),s)break;if(!s)return null;if(i=this.pathUtils.join(i,s),this.isZip.has(i)===!1){if(this.notZip.has(i))continue;try{if(!this.baseFs.lstatSync(i).isFile()){this.notZip.add(i);continue}}catch{return null}this.isZip.add(i)}return{archivePath:i,subPath:this.pathUtils.join(Te.root,t.substring(i.length))}}}limitOpenFiles(t){if(this.zipInstances===null)return;let i=Date.now(),n=i+this.maxAge,s=t===null?0:this.zipInstances.size-t;for(let[o,{zipFs:a,expiresAt:l,refCount:c}]of this.zipInstances.entries())if(!(c!==0||a.hasOpenFileHandles())){if(i>=l){a.saveAndClose(),this.zipInstances.delete(o),s-=1;continue}else if(t===null||s<=0){n=l;break}a.saveAndClose(),this.zipInstances.delete(o),s-=1}this.limitOpenFilesTimeout===null&&(t===null&&this.zipInstances.size>0||t!==null)&&(this.limitOpenFilesTimeout=setTimeout(()=>{this.limitOpenFilesTimeout=null,this.limitOpenFiles(null)},n-i).unref())}async getZipPromise(t,i){let n=async()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:await this.baseFs.statPromise(t)});if(this.zipInstances){let s=this.zipInstances.get(t);if(!s){let o=await n();s=this.zipInstances.get(t),s||(s={zipFs:new qr(t,o),expiresAt:0,refCount:0})}this.zipInstances.delete(t),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(t,s),s.expiresAt=Date.now()+this.maxAge,s.refCount+=1;try{return await i(s.zipFs)}finally{s.refCount-=1}}else{let s=new qr(t,await n());try{return await i(s)}finally{s.saveAndClose()}}}getZipSync(t,i){let n=()=>({baseFs:this.baseFs,libzip:this.libzip,readOnly:this.readOnlyArchives,stats:this.baseFs.statSync(t)});if(this.zipInstances){let s=this.zipInstances.get(t);return s||(s={zipFs:new qr(t,n()),expiresAt:0,refCount:0}),this.zipInstances.delete(t),this.limitOpenFiles(this.maxOpenFiles-1),this.zipInstances.set(t,s),s.expiresAt=Date.now()+this.maxAge,i(s.zipFs)}else{let s=new qr(t,n());try{return i(s)}finally{s.saveAndClose()}}}};var xg=J("util");var nI=J("url"),IK=J("util");var iI=class extends hi{constructor(t){super(K);this.baseFs=t}mapFromBase(t){return t}mapToBase(t){if(typeof t=="string")return t;if(t instanceof nI.URL)return(0,nI.fileURLToPath)(t);if(Buffer.isBuffer(t)){let i=t.toString();if(Buffer.byteLength(i)!==t.byteLength)throw new Error("Non-utf8 buffers are not supported at the moment. Please upvote the following issue if you encounter this error: https://github.com/yarnpkg/berry/issues/4942");return i}throw new Error(`Unsupported path type: ${(0,IK.inspect)(t)}`)}};var yK=J("readline"),Fi=Symbol("kBaseFs"),Ba=Symbol("kFd"),PA=Symbol("kClosePromise"),sI=Symbol("kCloseResolve"),oI=Symbol("kCloseReject"),Pg=Symbol("kRefs"),Js=Symbol("kRef"),Ws=Symbol("kUnref"),ife,nfe,sfe,ofe,Wp=class{constructor(e,t){this[ife]=1;this[nfe]=void 0;this[sfe]=void 0;this[ofe]=void 0;this[Fi]=t,this[Ba]=e}get fd(){return this[Ba]}async appendFile(e,t){var i;try{this[Js](this.appendFile);let n=(i=typeof t=="string"?t:t==null?void 0:t.encoding)!=null?i:void 0;return await this[Fi].appendFilePromise(this.fd,e,n?{encoding:n}:void 0)}finally{this[Ws]()}}async chown(e,t){try{return this[Js](this.chown),await this[Fi].fchownPromise(this.fd,e,t)}finally{this[Ws]()}}async chmod(e){try{return this[Js](this.chmod),await this[Fi].fchmodPromise(this.fd,e)}finally{this[Ws]()}}createReadStream(e){return this[Fi].createReadStream(null,{...e,fd:this.fd})}createWriteStream(e){return this[Fi].createWriteStream(null,{...e,fd:this.fd})}datasync(){throw new Error("Method not implemented.")}sync(){throw new Error("Method not implemented.")}async read(e,t,i,n){var s,o,a;try{this[Js](this.read);let l;return Buffer.isBuffer(e)?l=e:(e!=null||(e={}),l=(s=e.buffer)!=null?s:Buffer.alloc(16384),t=e.offset||0,i=(o=e.length)!=null?o:l.byteLength,n=(a=e.position)!=null?a:null),t!=null||(t=0),i!=null||(i=0),i===0?{bytesRead:i,buffer:l}:{bytesRead:await this[Fi].readPromise(this.fd,l,t,i,n),buffer:l}}finally{this[Ws]()}}async readFile(e){var t;try{this[Js](this.readFile);let i=(t=typeof e=="string"?e:e==null?void 0:e.encoding)!=null?t:void 0;return await this[Fi].readFilePromise(this.fd,i)}finally{this[Ws]()}}readLines(e){return(0,yK.createInterface)({input:this.createReadStream(e),crlfDelay:1/0})}async stat(e){try{return this[Js](this.stat),await this[Fi].fstatPromise(this.fd,e)}finally{this[Ws]()}}async truncate(e){try{return this[Js](this.truncate),await this[Fi].ftruncatePromise(this.fd,e)}finally{this[Ws]()}}utimes(e,t){throw new Error("Method not implemented.")}async writeFile(e,t){var i;try{this[Js](this.writeFile);let n=(i=typeof t=="string"?t:t==null?void 0:t.encoding)!=null?i:void 0;await this[Fi].writeFilePromise(this.fd,e,n)}finally{this[Ws]()}}async write(...e){try{if(this[Js](this.write),ArrayBuffer.isView(e[0])){let[t,i,n,s]=e;return{bytesWritten:await this[Fi].writePromise(this.fd,t,i!=null?i:void 0,n!=null?n:void 0,s!=null?s:void 0),buffer:t}}else{let[t,i,n]=e;return{bytesWritten:await this[Fi].writePromise(this.fd,t,i,n),buffer:t}}}finally{this[Ws]()}}async writev(e,t){try{this[Js](this.writev);let i=0;if(typeof t<"u")for(let n of e){let s=await this.write(n,void 0,void 0,t);i+=s.bytesWritten,t+=s.bytesWritten}else for(let n of e){let s=await this.write(n);i+=s.bytesWritten}return{buffers:e,bytesWritten:i}}finally{this[Ws]()}}readv(e,t){throw new Error("Method not implemented.")}close(){if(this[Ba]===-1)return Promise.resolve();if(this[PA])return this[PA];if(this[Pg]--,this[Pg]===0){let e=this[Ba];this[Ba]=-1,this[PA]=this[Fi].closePromise(e).finally(()=>{this[PA]=void 0})}else this[PA]=new Promise((e,t)=>{this[sI]=e,this[oI]=t}).finally(()=>{this[PA]=void 0,this[oI]=void 0,this[sI]=void 0});return this[PA]}[(Fi,Ba,ife=Pg,nfe=PA,sfe=sI,ofe=oI,Js)](e){if(this[Ba]===-1){let t=new Error("file closed");throw t.code="EBADF",t.syscall=e.name,t}this[Pg]++}[Ws](){if(this[Pg]--,this[Pg]===0){let e=this[Ba];this[Ba]=-1,this[Fi].closePromise(e).then(this[sI],this[oI])}}};var afe=new Set(["accessSync","appendFileSync","createReadStream","createWriteStream","chmodSync","fchmodSync","chownSync","fchownSync","closeSync","copyFileSync","linkSync","lstatSync","fstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","statSync","symlinkSync","truncateSync","ftruncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),wK=new Set(["accessPromise","appendFilePromise","fchmodPromise","chmodPromise","fchownPromise","chownPromise","closePromise","copyFilePromise","linkPromise","fstatPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","statPromise","symlinkPromise","truncatePromise","ftruncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"]);function bS(r,e){e=new iI(e);let t=(i,n,s)=>{let o=i[n];i[n]=s,typeof(o==null?void 0:o[xg.promisify.custom])<"u"&&(s[xg.promisify.custom]=o[xg.promisify.custom])};{t(r,"exists",(i,...n)=>{let o=typeof n[n.length-1]=="function"?n.pop():()=>{};process.nextTick(()=>{e.existsPromise(i).then(a=>{o(a)},()=>{o(!1)})})}),t(r,"read",(...i)=>{let[n,s,o,a,l,c]=i;if(i.length<=3){let u={};i.length<3?c=i[1]:(u=i[1],c=i[2]),{buffer:s=Buffer.alloc(16384),offset:o=0,length:a=s.byteLength,position:l}=u}if(o==null&&(o=0),a|=0,a===0){process.nextTick(()=>{c(null,0,s)});return}l==null&&(l=-1),process.nextTick(()=>{e.readPromise(n,s,o,a,l).then(u=>{c(null,u,s)},u=>{c(u,0,s)})})});for(let i of wK){let n=i.replace(/Promise$/,"");if(typeof r[n]>"u")continue;let s=e[i];if(typeof s>"u")continue;t(r,n,(...a)=>{let c=typeof a[a.length-1]=="function"?a.pop():()=>{};process.nextTick(()=>{s.apply(e,a).then(u=>{c(null,u)},u=>{c(u)})})})}r.realpath.native=r.realpath}{t(r,"existsSync",i=>{try{return e.existsSync(i)}catch{return!1}}),t(r,"readSync",(...i)=>{let[n,s,o,a,l]=i;return i.length<=3&&({offset:o=0,length:a=s.byteLength,position:l}=i[2]||{}),o==null&&(o=0),a|=0,a===0?0:(l==null&&(l=-1),e.readSync(n,s,o,a,l))});for(let i of afe){let n=i;if(typeof r[n]>"u")continue;let s=e[i];typeof s>"u"||t(r,n,s.bind(e))}r.realpathSync.native=r.realpathSync}{let i=r.promises;for(let n of wK){let s=n.replace(/Promise$/,"");if(typeof i[s]>"u")continue;let o=e[n];typeof o>"u"||n!=="open"&&t(i,s,(a,...l)=>a instanceof Wp?a[s].apply(a,l):o.call(e,a,...l))}t(i,"open",async(...n)=>{let s=await e.openPromise(...n);return new Wp(s,e)})}r.read[xg.promisify.custom]=async(i,n,...s)=>({bytesRead:await e.readPromise(i,n,...s),buffer:n}),r.write[xg.promisify.custom]=async(i,n,...s)=>({bytesWritten:await e.writePromise(i,n,...s),buffer:n})}function aI(r,e){let t=Object.create(r);return bS(t,e),t}var QK=ve(J("os"));function BK(r){let e=Math.ceil(Math.random()*4294967296).toString(16).padStart(8,"0");return`${r}${e}`}var zs=new Set,QS=null;function bK(){if(QS)return QS;let r=K.toPortablePath(QK.default.tmpdir()),e=M.realpathSync(r);return process.once("exit",()=>{M.rmtempSync()}),QS={tmpdir:r,realTmpdir:e}}var M=Object.assign(new Zt,{detachTemp(r){zs.delete(r)},mktempSync(r){let{tmpdir:e,realTmpdir:t}=bK();for(;;){let i=BK("xfs-");try{this.mkdirSync(v.join(e,i))}catch(s){if(s.code==="EEXIST")continue;throw s}let n=v.join(t,i);if(zs.add(n),typeof r>"u")return n;try{return r(n)}finally{if(zs.has(n)){zs.delete(n);try{this.removeSync(n)}catch{}}}}},async mktempPromise(r){let{tmpdir:e,realTmpdir:t}=bK();for(;;){let i=BK("xfs-");try{await this.mkdirPromise(v.join(e,i))}catch(s){if(s.code==="EEXIST")continue;throw s}let n=v.join(t,i);if(zs.add(n),typeof r>"u")return n;try{return await r(n)}finally{if(zs.has(n)){zs.delete(n);try{await this.removePromise(n)}catch{}}}}},async rmtempPromise(){await Promise.all(Array.from(zs.values()).map(async r=>{try{await M.removePromise(r,{maxRetries:0}),zs.delete(r)}catch{}}))},rmtempSync(){for(let r of zs)try{M.removeSync(r),zs.delete(r)}catch{}}});var fD=ve(TS());var rd={};ct(rd,{parseResolution:()=>fI,parseShell:()=>cI,parseSyml:()=>wi,stringifyArgument:()=>KS,stringifyArgumentSegment:()=>US,stringifyArithmeticExpression:()=>gI,stringifyCommand:()=>MS,stringifyCommandChain:()=>Fg,stringifyCommandChainThen:()=>OS,stringifyCommandLine:()=>uI,stringifyCommandLineThen:()=>LS,stringifyEnvSegment:()=>lI,stringifyRedirectArgument:()=>Vp,stringifyResolution:()=>hI,stringifyShell:()=>Rg,stringifyShellLine:()=>Rg,stringifySyml:()=>Qa,stringifyValueArgument:()=>ec});var pU=ve(hU());function cI(r,e={isGlobPattern:()=>!1}){try{return(0,pU.parse)(r,e)}catch(t){throw t.location&&(t.message=t.message.replace(/(\.)?$/,` (line ${t.location.start.line}, column ${t.location.start.column})$1`)),t}}function Rg(r,{endSemicolon:e=!1}={}){return r.map(({command:t,type:i},n)=>`${uI(t)}${i===";"?n!==r.length-1||e?";":"":" &"}`).join(" ")}function uI(r){return`${Fg(r.chain)}${r.then?` ${LS(r.then)}`:""}`}function LS(r){return`${r.type} ${uI(r.line)}`}function Fg(r){return`${MS(r)}${r.then?` ${OS(r.then)}`:""}`}function OS(r){return`${r.type} ${Fg(r.chain)}`}function MS(r){switch(r.type){case"command":return`${r.envs.length>0?`${r.envs.map(e=>lI(e)).join(" ")} `:""}${r.args.map(e=>KS(e)).join(" ")}`;case"subshell":return`(${Rg(r.subshell)})${r.args.length>0?` ${r.args.map(e=>Vp(e)).join(" ")}`:""}`;case"group":return`{ ${Rg(r.group,{endSemicolon:!0})} }${r.args.length>0?` ${r.args.map(e=>Vp(e)).join(" ")}`:""}`;case"envs":return r.envs.map(e=>lI(e)).join(" ");default:throw new Error(`Unsupported command type: "${r.type}"`)}}function lI(r){return`${r.name}=${r.args[0]?ec(r.args[0]):""}`}function KS(r){switch(r.type){case"redirection":return Vp(r);case"argument":return ec(r);default:throw new Error(`Unsupported argument type: "${r.type}"`)}}function Vp(r){return`${r.subtype} ${r.args.map(e=>ec(e)).join(" ")}`}function ec(r){return r.segments.map(e=>US(e)).join("")}var dU=new Map([["\f","\\f"],[` +`,"\\n"],["\r","\\r"],[" ","\\t"],["\v","\\v"],["\0","\\0"]]),Lfe=new Map([["\\","\\\\"],["$","\\$"],['"','\\"'],...Array.from(dU,([r,e])=>[r,`"$'${e}'"`])]),CU=r=>{var e;return(e=dU.get(r))!=null?e:`\\x${r.charCodeAt(0).toString(16).padStart(2,"0")}`},Ofe=r=>{var e;return(e=Lfe.get(r))!=null?e:`"$'${CU(r)}'"`};function US(r){let e=(i,n)=>n?`"${i}"`:i,t=i=>i===""?"''":i.match(/[()}<>$|&;"'\n\t ]/)?i.match(/['\t\p{C}]/u)?i.match(/'/)?`"${i.replace(/["$\t\p{C}]/u,Ofe)}"`:`$'${i.replace(/[\t\p{C}]/u,CU)}'`:`'${i}'`:i;switch(r.type){case"text":return t(r.text);case"glob":return r.pattern;case"shell":return e(`\${${Rg(r.shell)}}`,r.quoted);case"variable":return e(typeof r.defaultValue>"u"?typeof r.alternativeValue>"u"?`\${${r.name}}`:r.alternativeValue.length===0?`\${${r.name}:+}`:`\${${r.name}:+${r.alternativeValue.map(i=>ec(i)).join(" ")}}`:r.defaultValue.length===0?`\${${r.name}:-}`:`\${${r.name}:-${r.defaultValue.map(i=>ec(i)).join(" ")}}`,r.quoted);case"arithmetic":return`$(( ${gI(r.arithmetic)} ))`;default:throw new Error(`Unsupported argument segment type: "${r.type}"`)}}function gI(r){let e=n=>{switch(n){case"addition":return"+";case"subtraction":return"-";case"multiplication":return"*";case"division":return"/";default:throw new Error(`Can't extract operator from arithmetic expression of type "${n}"`)}},t=(n,s)=>s?`( ${n} )`:n,i=n=>t(gI(n),!["number","variable"].includes(n.type));switch(r.type){case"number":return String(r.value);case"variable":return r.name;default:return`${i(r.left)} ${e(r.type)} ${i(r.right)}`}}var IU=ve(EU());function fI(r){let e=r.match(/^\*{1,2}\/(.*)/);if(e)throw new Error(`The override for '${r}' includes a glob pattern. Glob patterns have been removed since their behaviours don't match what you'd expect. Set the override to '${e[1]}' instead.`);try{return(0,IU.parse)(r)}catch(t){throw t.location&&(t.message=t.message.replace(/(\.)?$/,` (line ${t.location.start.line}, column ${t.location.start.column})$1`)),t}}function hI(r){let e="";return r.from&&(e+=r.from.fullName,r.from.description&&(e+=`@${r.from.description}`),e+="/"),e+=r.descriptor.fullName,r.descriptor.description&&(e+=`@${r.descriptor.description}`),e}var SI=ve(cH()),pH=ve(gH()),mde=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,fH=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"],QI=class{constructor(e){this.data=e}};function hH(r){return r.match(mde)?r:JSON.stringify(r)}function dH(r){return typeof r>"u"?!0:typeof r=="object"&&r!==null?Object.keys(r).every(e=>dH(r[e])):!1}function $S(r,e,t){if(r===null)return`null +`;if(typeof r=="number"||typeof r=="boolean")return`${r.toString()} +`;if(typeof r=="string")return`${hH(r)} +`;if(Array.isArray(r)){if(r.length===0)return`[] +`;let i=" ".repeat(e);return` +${r.map(s=>`${i}- ${$S(s,e+1,!1)}`).join("")}`}if(typeof r=="object"&&r){let[i,n]=r instanceof QI?[r.data,!1]:[r,!0],s=" ".repeat(e),o=Object.keys(i);n&&o.sort((l,c)=>{let u=fH.indexOf(l),g=fH.indexOf(c);return u===-1&&g===-1?l<c?-1:l>c?1:0:u!==-1&&g===-1?-1:u===-1&&g!==-1?1:u-g});let a=o.filter(l=>!dH(i[l])).map((l,c)=>{let u=i[l],g=hH(l),h=$S(u,e+1,!0),p=c>0||t?s:"",d=g.length>1024?`? ${g} +${p}:`:`${g}:`,m=h.startsWith(` +`)?h:` ${h}`;return`${p}${d}${m}`}).join(e===0?` +`:"")||` +`;return t?` +${a}`:`${a}`}throw new Error(`Unsupported value type (${r})`)}function Qa(r){try{let e=$S(r,0,!1);return e!==` +`?e:""}catch(e){throw e.location&&(e.message=e.message.replace(/(\.)?$/,` (line ${e.location.start.line}, column ${e.location.start.column})$1`)),e}}Qa.PreserveOrdering=QI;function Ede(r){return r.endsWith(` +`)||(r+=` +`),(0,pH.parse)(r)}var Ide=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i;function yde(r){if(Ide.test(r))return Ede(r);let e=(0,SI.safeLoad)(r,{schema:SI.FAILSAFE_SCHEMA,json:!0});if(e==null)return{};if(typeof e!="object")throw new Error(`Expected an indexed object, got a ${typeof e} instead. Does your file follow Yaml's rules?`);if(Array.isArray(e))throw new Error("Expected an indexed object, got an array instead. Does your file follow Yaml's rules?");return e}function wi(r){return yde(r)}var yz=ve(mH()),Mw=ve(cc());var gd={};ct(gd,{Builtins:()=>hv,Cli:()=>jn,Command:()=>Qe,Option:()=>z,UsageError:()=>we,formatMarkdownish:()=>Ti});var tv="",Bi="\0";var rv=/^(-h|--help)(?:=([0-9]+))?$/,vI=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,wH=/^-[a-zA-Z]{2,}$/,iv=/^([^=]+)=([\s\S]*)$/,nv=process.env.DEBUG_CLI==="1";var we=class extends Error{constructor(e){super(e),this.clipanion={type:"usage"},this.name="UsageError"}},Hg=class extends Error{constructor(e,t){if(super(),this.input=e,this.candidates=t,this.clipanion={type:"none"},this.name="UnknownSyntaxError",this.candidates.length===0)this.message="Command not found, but we're not sure what's the alternative.";else if(this.candidates.every(i=>i.reason!==null&&i.reason===t[0].reason)){let[{reason:i}]=this.candidates;this.message=`${i} + +${this.candidates.map(({usage:n})=>`$ ${n}`).join(` +`)}`}else if(this.candidates.length===1){let[{usage:i}]=this.candidates;this.message=`Command not found; did you mean: + +$ ${i} +${sv(e)}`}else this.message=`Command not found; did you mean one of: + +${this.candidates.map(({usage:i},n)=>`${`${n}.`.padStart(4)} ${i}`).join(` +`)} + +${sv(e)}`}},PI=class extends Error{constructor(e,t){super(),this.input=e,this.usages=t,this.clipanion={type:"none"},this.name="AmbiguousSyntaxError",this.message=`Cannot find which to pick amongst the following alternatives: + +${this.usages.map((i,n)=>`${`${n}.`.padStart(4)} ${i}`).join(` +`)} + +${sv(e)}`}},sv=r=>`While running ${r.filter(e=>e!==Bi).map(e=>{let t=JSON.stringify(e);return e.match(/\s/)||e.length===0||t!==`"${e}"`?t:e}).join(" ")}`;var id=Symbol("clipanion/isOption");function Vi(r){return{...r,[id]:!0}}function xo(r,e){return typeof r>"u"?[r,e]:typeof r=="object"&&r!==null&&!Array.isArray(r)?[void 0,r]:[r,e]}function xI(r,e=!1){let t=r.replace(/^\.: /,"");return e&&(t=t[0].toLowerCase()+t.slice(1)),t}function nd(r,e){return e.length===1?new we(`${r}: ${xI(e[0],!0)}`):new we(`${r}: +${e.map(t=>` +- ${xI(t)}`).join("")}`)}function sd(r,e,t){if(typeof t>"u")return e;let i=[],n=[],s=a=>{let l=e;return e=a,s.bind(null,l)};if(!t(e,{errors:i,coercions:n,coercion:s}))throw nd(`Invalid value for ${r}`,i);for(let[,a]of n)a();return e}var Qe=class{constructor(){this.help=!1}static Usage(e){return e}async catch(e){throw e}async validateAndExecute(){let t=this.constructor.schema;if(Array.isArray(t)){let{isDict:n,isUnknown:s,applyCascade:o}=await Promise.resolve().then(()=>(As(),hn)),a=o(n(s()),t),l=[],c=[];if(!a(this,{errors:l,coercions:c}))throw nd("Invalid option schema",l);for(let[,g]of c)g()}else if(t!=null)throw new Error("Invalid command schema");let i=await this.execute();return typeof i<"u"?i:0}};Qe.isOption=id;Qe.Default=[];var Av=Array(80).fill("\u2501");for(let r=0;r<=24;++r)Av[Av.length-r]=`\x1B[38;5;${232+r}m\u2501`;var lv={header:r=>`\x1B[1m\u2501\u2501\u2501 ${r}${r.length<80-5?` ${Av.slice(r.length+5).join("")}`:":"}\x1B[0m`,bold:r=>`\x1B[1m${r}\x1B[22m`,error:r=>`\x1B[31m\x1B[1m${r}\x1B[22m\x1B[39m`,code:r=>`\x1B[36m${r}\x1B[39m`},RH={header:r=>r,bold:r=>r,error:r=>r,code:r=>r};function nCe(r){let e=r.split(` +`),t=e.filter(n=>n.match(/\S/)),i=t.length>0?t.reduce((n,s)=>Math.min(n,s.length-s.trimStart().length),Number.MAX_VALUE):0;return e.map(n=>n.slice(i).trimRight()).join(` +`)}function Ti(r,{format:e,paragraphs:t}){return r=r.replace(/\r\n?/g,` +`),r=nCe(r),r=r.replace(/^\n+|\n+$/g,""),r=r.replace(/^(\s*)-([^\n]*?)\n+/gm,`$1-$2 + +`),r=r.replace(/\n(\n)?\n*/g,"$1"),t&&(r=r.split(/\n/).map(i=>{let n=i.match(/^\s*[*-][\t ]+(.*)/);if(!n)return i.match(/(.{1,80})(?: |$)/g).join(` +`);let s=i.length-i.trimStart().length;return n[1].match(new RegExp(`(.{1,${78-s}})(?: |$)`,"g")).map((o,a)=>" ".repeat(s)+(a===0?"- ":" ")+o).join(` +`)}).join(` + +`)),r=r.replace(/(`+)((?:.|[\n])*?)\1/g,(i,n,s)=>e.code(n+s+n)),r=r.replace(/(\*\*)((?:.|[\n])*?)\1/g,(i,n,s)=>e.bold(n+s+n)),r?`${r} +`:""}var fv=ve(J("tty"),1);function pn(r){nv&&console.log(r)}var FH={candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:-1};function NH(){return{nodes:[Zi(),Zi(),Zi()]}}function sCe(r){let e=NH(),t=[],i=e.nodes.length;for(let n of r){t.push(i);for(let s=0;s<n.nodes.length;++s)OH(s)||e.nodes.push(hCe(n.nodes[s],i));i+=n.nodes.length-2}for(let n of t)jg(e,0,n);return e}function Vs(r,e){return r.nodes.push(e),r.nodes.length-1}function oCe(r){let e=new Set,t=i=>{if(e.has(i))return;e.add(i);let n=r.nodes[i];for(let o of Object.values(n.statics))for(let{to:a}of o)t(a);for(let[,{to:o}]of n.dynamics)t(o);for(let{to:o}of n.shortcuts)t(o);let s=new Set(n.shortcuts.map(({to:o})=>o));for(;n.shortcuts.length>0;){let{to:o}=n.shortcuts.shift(),a=r.nodes[o];for(let[l,c]of Object.entries(a.statics)){let u=Object.prototype.hasOwnProperty.call(n.statics,l)?n.statics[l]:n.statics[l]=[];for(let g of c)u.some(({to:h})=>g.to===h)||u.push(g)}for(let[l,c]of a.dynamics)n.dynamics.some(([u,{to:g}])=>l===u&&c.to===g)||n.dynamics.push([l,c]);for(let l of a.shortcuts)s.has(l.to)||(n.shortcuts.push(l),s.add(l.to))}};t(0)}function aCe(r,{prefix:e=""}={}){if(nv){pn(`${e}Nodes are:`);for(let t=0;t<r.nodes.length;++t)pn(`${e} ${t}: ${JSON.stringify(r.nodes[t])}`)}}function TH(r,e,t=!1){pn(`Running a vm on ${JSON.stringify(e)}`);let i=[{node:0,state:{candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,options:[],path:[],positionals:[],remainder:null,selectedIndex:null}}];aCe(r,{prefix:" "});let n=[tv,...e];for(let s=0;s<n.length;++s){let o=n[s];pn(` Processing ${JSON.stringify(o)}`);let a=[];for(let{node:l,state:c}of i){pn(` Current node is ${l}`);let u=r.nodes[l];if(l===2){a.push({node:l,state:c});continue}console.assert(u.shortcuts.length===0,"Shortcuts should have been eliminated by now");let g=Object.prototype.hasOwnProperty.call(u.statics,o);if(!t||s<n.length-1||g)if(g){let h=u.statics[o];for(let{to:p,reducer:d}of h)a.push({node:p,state:typeof d<"u"?DI(uv,d,c,o):c}),pn(` Static transition to ${p} found`)}else pn(" No static transition found");else{let h=!1;for(let p of Object.keys(u.statics))if(!!p.startsWith(o)){if(o===p)for(let{to:d,reducer:m}of u.statics[p])a.push({node:d,state:typeof m<"u"?DI(uv,m,c,o):c}),pn(` Static transition to ${d} found`);else for(let{to:d}of u.statics[p])a.push({node:d,state:{...c,remainder:p.slice(o.length)}}),pn(` Static transition to ${d} found (partial match)`);h=!0}h||pn(" No partial static transition found")}if(o!==Bi)for(let[h,{to:p,reducer:d}]of u.dynamics)DI(FI,h,c,o)&&(a.push({node:p,state:typeof d<"u"?DI(uv,d,c,o):c}),pn(` Dynamic transition to ${p} found (via ${h})`))}if(a.length===0&&o===Bi&&e.length===1)return[{node:0,state:FH}];if(a.length===0)throw new Hg(e,i.filter(({node:l})=>l!==2).map(({state:l})=>({usage:l.candidateUsage,reason:null})));if(a.every(({node:l})=>l===2))throw new Hg(e,a.map(({state:l})=>({usage:l.candidateUsage,reason:l.errorMessage})));i=uCe(a)}if(i.length>0){pn(" Results:");for(let s of i)pn(` - ${s.node} -> ${JSON.stringify(s.state)}`)}else pn(" No results");return i}function ACe(r,e){if(e.selectedIndex!==null)return!0;if(Object.prototype.hasOwnProperty.call(r.statics,Bi)){for(let{to:t}of r.statics[Bi])if(t===1)return!0}return!1}function lCe(r,e,t){let i=t&&e.length>0?[""]:[],n=TH(r,e,t),s=[],o=new Set,a=(l,c,u=!0)=>{let g=[c];for(;g.length>0;){let p=g;g=[];for(let d of p){let m=r.nodes[d],y=Object.keys(m.statics);for(let B of Object.keys(m.statics)){let S=y[0];for(let{to:x,reducer:F}of m.statics[S])F==="pushPath"&&(u||l.push(S),g.push(x))}}u=!1}let h=JSON.stringify(l);o.has(h)||(s.push(l),o.add(h))};for(let{node:l,state:c}of n){if(c.remainder!==null){a([c.remainder],l);continue}let u=r.nodes[l],g=ACe(u,c);for(let[h,p]of Object.entries(u.statics))(g&&h!==Bi||!h.startsWith("-")&&p.some(({reducer:d})=>d==="pushPath"))&&a([...i,h],l);if(!!g)for(let[h,{to:p}]of u.dynamics){if(p===2)continue;let d=pCe(h,c);if(d!==null)for(let m of d)a([...i,m],l)}}return[...s].sort()}function cCe(r,e){let t=TH(r,[...e,Bi]);return gCe(e,t.map(({state:i})=>i))}function uCe(r){let e=0;for(let{state:t}of r)t.path.length>e&&(e=t.path.length);return r.filter(({state:t})=>t.path.length===e)}function gCe(r,e){let t=e.filter(g=>g.selectedIndex!==null);if(t.length===0)throw new Error;let i=t.filter(g=>g.requiredOptions.every(h=>h.some(p=>g.options.find(d=>d.name===p))));if(i.length===0)throw new Hg(r,t.map(g=>({usage:g.candidateUsage,reason:null})));let n=0;for(let g of i)g.path.length>n&&(n=g.path.length);let s=i.filter(g=>g.path.length===n),o=g=>g.positionals.filter(({extra:h})=>!h).length+g.options.length,a=s.map(g=>({state:g,positionalCount:o(g)})),l=0;for(let{positionalCount:g}of a)g>l&&(l=g);let c=a.filter(({positionalCount:g})=>g===l).map(({state:g})=>g),u=fCe(c);if(u.length>1)throw new PI(r,u.map(g=>g.candidateUsage));return u[0]}function fCe(r){let e=[],t=[];for(let i of r)i.selectedIndex===-1?t.push(i):e.push(i);return t.length>0&&e.push({...FH,path:LH(...t.map(i=>i.path)),options:t.reduce((i,n)=>i.concat(n.options),[])}),e}function LH(r,e,...t){return e===void 0?Array.from(r):LH(r.filter((i,n)=>i===e[n]),...t)}function Zi(){return{dynamics:[],shortcuts:[],statics:{}}}function OH(r){return r===1||r===2}function cv(r,e=0){return{to:OH(r.to)?r.to:r.to>2?r.to+e-2:r.to+e,reducer:r.reducer}}function hCe(r,e=0){let t=Zi();for(let[i,n]of r.dynamics)t.dynamics.push([i,cv(n,e)]);for(let i of r.shortcuts)t.shortcuts.push(cv(i,e));for(let[i,n]of Object.entries(r.statics))t.statics[i]=n.map(s=>cv(s,e));return t}function bi(r,e,t,i,n){r.nodes[e].dynamics.push([t,{to:i,reducer:n}])}function jg(r,e,t,i){r.nodes[e].shortcuts.push({to:t,reducer:i})}function Sa(r,e,t,i,n){(Object.prototype.hasOwnProperty.call(r.nodes[e].statics,t)?r.nodes[e].statics[t]:r.nodes[e].statics[t]=[]).push({to:i,reducer:n})}function DI(r,e,t,i){if(Array.isArray(e)){let[n,...s]=e;return r[n](t,i,...s)}else return r[e](t,i)}function pCe(r,e){let t=Array.isArray(r)?FI[r[0]]:FI[r];if(typeof t.suggest>"u")return null;let i=Array.isArray(r)?r.slice(1):[];return t.suggest(e,...i)}var FI={always:()=>!0,isOptionLike:(r,e)=>!r.ignoreOptions&&e!=="-"&&e.startsWith("-"),isNotOptionLike:(r,e)=>r.ignoreOptions||e==="-"||!e.startsWith("-"),isOption:(r,e,t,i)=>!r.ignoreOptions&&e===t,isBatchOption:(r,e,t)=>!r.ignoreOptions&&wH.test(e)&&[...e.slice(1)].every(i=>t.includes(`-${i}`)),isBoundOption:(r,e,t,i)=>{let n=e.match(iv);return!r.ignoreOptions&&!!n&&vI.test(n[1])&&t.includes(n[1])&&i.filter(s=>s.names.includes(n[1])).every(s=>s.allowBinding)},isNegatedOption:(r,e,t)=>!r.ignoreOptions&&e===`--no-${t.slice(2)}`,isHelp:(r,e)=>!r.ignoreOptions&&rv.test(e),isUnsupportedOption:(r,e,t)=>!r.ignoreOptions&&e.startsWith("-")&&vI.test(e)&&!t.includes(e),isInvalidOption:(r,e)=>!r.ignoreOptions&&e.startsWith("-")&&!vI.test(e)};FI.isOption.suggest=(r,e,t=!0)=>t?null:[e];var uv={setCandidateState:(r,e,t)=>({...r,...t}),setSelectedIndex:(r,e,t)=>({...r,selectedIndex:t}),pushBatch:(r,e)=>({...r,options:r.options.concat([...e.slice(1)].map(t=>({name:`-${t}`,value:!0})))}),pushBound:(r,e)=>{let[,t,i]=e.match(iv);return{...r,options:r.options.concat({name:t,value:i})}},pushPath:(r,e)=>({...r,path:r.path.concat(e)}),pushPositional:(r,e)=>({...r,positionals:r.positionals.concat({value:e,extra:!1})}),pushExtra:(r,e)=>({...r,positionals:r.positionals.concat({value:e,extra:!0})}),pushExtraNoLimits:(r,e)=>({...r,positionals:r.positionals.concat({value:e,extra:Hn})}),pushTrue:(r,e,t=e)=>({...r,options:r.options.concat({name:e,value:!0})}),pushFalse:(r,e,t=e)=>({...r,options:r.options.concat({name:t,value:!1})}),pushUndefined:(r,e)=>({...r,options:r.options.concat({name:e,value:void 0})}),pushStringValue:(r,e)=>{var t;let i={...r,options:[...r.options]},n=r.options[r.options.length-1];return n.value=((t=n.value)!==null&&t!==void 0?t:[]).concat([e]),i},setStringValue:(r,e)=>{let t={...r,options:[...r.options]},i=r.options[r.options.length-1];return i.value=e,t},inhibateOptions:r=>({...r,ignoreOptions:!0}),useHelp:(r,e,t)=>{let[,,i]=e.match(rv);return typeof i<"u"?{...r,options:[{name:"-c",value:String(t)},{name:"-i",value:i}]}:{...r,options:[{name:"-c",value:String(t)}]}},setError:(r,e,t)=>e===Bi?{...r,errorMessage:`${t}.`}:{...r,errorMessage:`${t} ("${e}").`},setOptionArityError:(r,e)=>{let t=r.options[r.options.length-1];return{...r,errorMessage:`Not enough arguments to option ${t.name}.`}}},Hn=Symbol(),gv=class{constructor(e,t){this.allOptionNames=[],this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=t}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:t=this.arity.trailing,extra:i=this.arity.extra,proxy:n=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:t,extra:i,proxy:n})}addPositional({name:e="arg",required:t=!0}={}){if(!t&&this.arity.extra===Hn)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!t&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");!t&&this.arity.extra!==Hn?this.arity.extra.push(e):this.arity.extra!==Hn&&this.arity.extra.length===0?this.arity.leading.push(e):this.arity.trailing.push(e)}addRest({name:e="arg",required:t=0}={}){if(this.arity.extra===Hn)throw new Error("Infinite lists cannot be declared multiple times in the same command");if(this.arity.trailing.length>0)throw new Error("Infinite lists cannot be declared after the required trailing positional arguments");for(let i=0;i<t;++i)this.addPositional({name:e});this.arity.extra=Hn}addProxy({required:e=0}={}){this.addRest({required:e}),this.arity.proxy=!0}addOption({names:e,description:t,arity:i=0,hidden:n=!1,required:s=!1,allowBinding:o=!0}){if(!o&&i>1)throw new Error("The arity cannot be higher than 1 when the option only supports the --arg=value syntax");if(!Number.isInteger(i))throw new Error(`The arity must be an integer, got ${i}`);if(i<0)throw new Error(`The arity must be positive, got ${i}`);this.allOptionNames.push(...e),this.options.push({names:e,description:t,arity:i,hidden:n,required:s,allowBinding:o})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:t=!0}={}){let i=[this.cliOpts.binaryName],n=[];if(this.paths.length>0&&i.push(...this.paths[0]),e){for(let{names:o,arity:a,hidden:l,description:c,required:u}of this.options){if(l)continue;let g=[];for(let p=0;p<a;++p)g.push(` #${p}`);let h=`${o.join(",")}${g.join("")}`;!t&&c?n.push({definition:h,description:c,required:u}):i.push(u?`<${h}>`:`[${h}]`)}i.push(...this.arity.leading.map(o=>`<${o}>`)),this.arity.extra===Hn?i.push("..."):i.push(...this.arity.extra.map(o=>`[${o}]`)),i.push(...this.arity.trailing.map(o=>`<${o}>`))}return{usage:i.join(" "),options:n}}compile(){if(typeof this.context>"u")throw new Error("Assertion failed: No context attached");let e=NH(),t=0,i=this.usage().usage,n=this.options.filter(a=>a.required).map(a=>a.names);t=Vs(e,Zi()),Sa(e,0,tv,t,["setCandidateState",{candidateUsage:i,requiredOptions:n}]);let s=this.arity.proxy?"always":"isNotOptionLike",o=this.paths.length>0?this.paths:[[]];for(let a of o){let l=t;if(a.length>0){let h=Vs(e,Zi());jg(e,l,h),this.registerOptions(e,h),l=h}for(let h=0;h<a.length;++h){let p=Vs(e,Zi());Sa(e,l,a[h],p,"pushPath"),l=p}if(this.arity.leading.length>0||!this.arity.proxy){let h=Vs(e,Zi());bi(e,l,"isHelp",h,["useHelp",this.cliIndex]),Sa(e,h,Bi,1,["setSelectedIndex",-1]),this.registerOptions(e,l)}this.arity.leading.length>0&&Sa(e,l,Bi,2,["setError","Not enough positional arguments"]);let c=l;for(let h=0;h<this.arity.leading.length;++h){let p=Vs(e,Zi());this.arity.proxy||this.registerOptions(e,p),(this.arity.trailing.length>0||h+1!==this.arity.leading.length)&&Sa(e,p,Bi,2,["setError","Not enough positional arguments"]),bi(e,c,"isNotOptionLike",p,"pushPositional"),c=p}let u=c;if(this.arity.extra===Hn||this.arity.extra.length>0){let h=Vs(e,Zi());if(jg(e,c,h),this.arity.extra===Hn){let p=Vs(e,Zi());this.arity.proxy||this.registerOptions(e,p),bi(e,c,s,p,"pushExtraNoLimits"),bi(e,p,s,p,"pushExtraNoLimits"),jg(e,p,h)}else for(let p=0;p<this.arity.extra.length;++p){let d=Vs(e,Zi());this.arity.proxy||this.registerOptions(e,d),bi(e,u,s,d,"pushExtra"),jg(e,d,h),u=d}u=h}this.arity.trailing.length>0&&Sa(e,u,Bi,2,["setError","Not enough positional arguments"]);let g=u;for(let h=0;h<this.arity.trailing.length;++h){let p=Vs(e,Zi());this.arity.proxy||this.registerOptions(e,p),h+1<this.arity.trailing.length&&Sa(e,p,Bi,2,["setError","Not enough positional arguments"]),bi(e,g,"isNotOptionLike",p,"pushPositional"),g=p}bi(e,g,s,2,["setError","Extraneous positional argument"]),Sa(e,g,Bi,1,["setSelectedIndex",this.cliIndex])}return{machine:e,context:this.context}}registerOptions(e,t){bi(e,t,["isOption","--"],t,"inhibateOptions"),bi(e,t,["isBatchOption",this.allOptionNames],t,"pushBatch"),bi(e,t,["isBoundOption",this.allOptionNames,this.options],t,"pushBound"),bi(e,t,["isUnsupportedOption",this.allOptionNames],2,["setError","Unsupported option name"]),bi(e,t,["isInvalidOption"],2,["setError","Invalid option name"]);for(let i of this.options){let n=i.names.reduce((s,o)=>o.length>s.length?o:s,"");if(i.arity===0)for(let s of i.names)bi(e,t,["isOption",s,i.hidden||s!==n],t,"pushTrue"),s.startsWith("--")&&!s.startsWith("--no-")&&bi(e,t,["isNegatedOption",s],t,["pushFalse",s]);else{let s=Vs(e,Zi());for(let o of i.names)bi(e,t,["isOption",o,i.hidden||o!==n],s,"pushUndefined");for(let o=0;o<i.arity;++o){let a=Vs(e,Zi());Sa(e,s,Bi,2,"setOptionArityError"),bi(e,s,"isOptionLike",2,"setOptionArityError");let l=i.arity===1?"setStringValue":"pushStringValue";bi(e,s,"isNotOptionLike",a,l),s=a}jg(e,s,t)}}}},Yg=class{constructor({binaryName:e="..."}={}){this.builders=[],this.opts={binaryName:e}}static build(e,t={}){return new Yg(t).commands(e).compile()}getBuilderByIndex(e){if(!(e>=0&&e<this.builders.length))throw new Error(`Assertion failed: Out-of-bound command index (${e})`);return this.builders[e]}commands(e){for(let t of e)t(this.command());return this}command(){let e=new gv(this.builders.length,this.opts);return this.builders.push(e),e}compile(){let e=[],t=[];for(let n of this.builders){let{machine:s,context:o}=n.compile();e.push(s),t.push(o)}let i=sCe(e);return oCe(i),{machine:i,contexts:t,process:n=>cCe(i,n),suggest:(n,s)=>lCe(i,n,s)}}};var qg=class extends Qe{constructor(e){super(),this.contexts=e,this.commands=[]}static from(e,t){let i=new qg(t);i.path=e.path;for(let n of e.options)switch(n.name){case"-c":i.commands.push(Number(n.value));break;case"-i":i.index=Number(n.value);break}return i}async execute(){let e=this.commands;if(typeof this.index<"u"&&this.index>=0&&this.index<e.length&&(e=[e[this.index]]),e.length===0)this.context.stdout.write(this.cli.usage());else if(e.length===1)this.context.stdout.write(this.cli.usage(this.contexts[e[0]].commandClass,{detailed:!0}));else if(e.length>1){this.context.stdout.write(`Multiple commands match your selection: +`),this.context.stdout.write(` +`);let t=0;for(let i of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[i].commandClass,{prefix:`${t++}. `.padStart(5)}));this.context.stdout.write(` +`),this.context.stdout.write(`Run again with -h=<index> to see the longer details of any of those commands. +`)}}};var MH=Symbol("clipanion/errorCommand");function dCe(){return process.env.FORCE_COLOR==="0"?1:process.env.FORCE_COLOR==="1"||typeof process.stdout<"u"&&process.stdout.isTTY?8:1}var jn=class{constructor({binaryLabel:e,binaryName:t="...",binaryVersion:i,enableCapture:n=!1,enableColors:s}={}){this.registrations=new Map,this.builder=new Yg({binaryName:t}),this.binaryLabel=e,this.binaryName=t,this.binaryVersion=i,this.enableCapture=n,this.enableColors=s}static from(e,t={}){let i=new jn(t);for(let n of e)i.register(n);return i}register(e){var t;let i=new Map,n=new e;for(let l in n){let c=n[l];typeof c=="object"&&c!==null&&c[Qe.isOption]&&i.set(l,c)}let s=this.builder.command(),o=s.cliIndex,a=(t=e.paths)!==null&&t!==void 0?t:n.paths;if(typeof a<"u")for(let l of a)s.addPath(l);this.registrations.set(e,{specs:i,builder:s,index:o});for(let[l,{definition:c}]of i.entries())c(s,l);s.setContext({commandClass:e})}process(e){let{contexts:t,process:i}=this.builder.compile(),n=i(e);switch(n.selectedIndex){case-1:return qg.from(n,t);default:{let{commandClass:s}=t[n.selectedIndex],o=this.registrations.get(s);if(typeof o>"u")throw new Error("Assertion failed: Expected the command class to have been registered.");let a=new s;a.path=n.path;try{for(let[l,{transformer:c}]of o.specs.entries())a[l]=c(o.builder,l,n);return a}catch(l){throw l[MH]=a,l}}break}}async run(e,t){var i;let n,s={...jn.defaultContext,...t},o=(i=this.enableColors)!==null&&i!==void 0?i:s.colorDepth>1;if(!Array.isArray(e))n=e;else try{n=this.process(e)}catch(c){return s.stdout.write(this.error(c,{colored:o})),1}if(n.help)return s.stdout.write(this.usage(n,{colored:o,detailed:!0})),0;n.context=s,n.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableCapture:this.enableCapture,enableColors:this.enableColors,definitions:()=>this.definitions(),error:(c,u)=>this.error(c,u),format:c=>this.format(c),process:c=>this.process(c),run:(c,u)=>this.run(c,{...s,...u}),usage:(c,u)=>this.usage(c,u)};let a=this.enableCapture?CCe(s):UH,l;try{l=await a(()=>n.validateAndExecute().catch(c=>n.catch(c).then(()=>0)))}catch(c){return s.stdout.write(this.error(c,{colored:o,command:n})),1}return l}async runExit(e,t){process.exitCode=await this.run(e,t)}suggest(e,t){let{suggest:i}=this.builder.compile();return i(e,t)}definitions({colored:e=!1}={}){let t=[];for(let[i,{index:n}]of this.registrations){if(typeof i.usage>"u")continue;let{usage:s}=this.getUsageByIndex(n,{detailed:!1}),{usage:o,options:a}=this.getUsageByIndex(n,{detailed:!0,inlineOptions:!1}),l=typeof i.usage.category<"u"?Ti(i.usage.category,{format:this.format(e),paragraphs:!1}):void 0,c=typeof i.usage.description<"u"?Ti(i.usage.description,{format:this.format(e),paragraphs:!1}):void 0,u=typeof i.usage.details<"u"?Ti(i.usage.details,{format:this.format(e),paragraphs:!0}):void 0,g=typeof i.usage.examples<"u"?i.usage.examples.map(([h,p])=>[Ti(h,{format:this.format(e),paragraphs:!1}),p.replace(/\$0/g,this.binaryName)]):void 0;t.push({path:s,usage:o,category:l,description:c,details:u,examples:g,options:a})}return t}usage(e=null,{colored:t,detailed:i=!1,prefix:n="$ "}={}){var s;if(e===null){for(let l of this.registrations.keys()){let c=l.paths,u=typeof l.usage<"u";if(!c||c.length===0||c.length===1&&c[0].length===0||((s=c==null?void 0:c.some(p=>p.length===0))!==null&&s!==void 0?s:!1))if(e){e=null;break}else e=l;else if(u){e=null;continue}}e&&(i=!0)}let o=e!==null&&e instanceof Qe?e.constructor:e,a="";if(o)if(i){let{description:l="",details:c="",examples:u=[]}=o.usage||{};l!==""&&(a+=Ti(l,{format:this.format(t),paragraphs:!1}).replace(/^./,p=>p.toUpperCase()),a+=` +`),(c!==""||u.length>0)&&(a+=`${this.format(t).header("Usage")} +`,a+=` +`);let{usage:g,options:h}=this.getUsageByRegistration(o,{inlineOptions:!1});if(a+=`${this.format(t).bold(n)}${g} +`,h.length>0){a+=` +`,a+=`${lv.header("Options")} +`;let p=h.reduce((d,m)=>Math.max(d,m.definition.length),0);a+=` +`;for(let{definition:d,description:m}of h)a+=` ${this.format(t).bold(d.padEnd(p))} ${Ti(m,{format:this.format(t),paragraphs:!1})}`}if(c!==""&&(a+=` +`,a+=`${this.format(t).header("Details")} +`,a+=` +`,a+=Ti(c,{format:this.format(t),paragraphs:!0})),u.length>0){a+=` +`,a+=`${this.format(t).header("Examples")} +`;for(let[p,d]of u)a+=` +`,a+=Ti(p,{format:this.format(t),paragraphs:!1}),a+=`${d.replace(/^/m,` ${this.format(t).bold(n)}`).replace(/\$0/g,this.binaryName)} +`}}else{let{usage:l}=this.getUsageByRegistration(o);a+=`${this.format(t).bold(n)}${l} +`}else{let l=new Map;for(let[h,{index:p}]of this.registrations.entries()){if(typeof h.usage>"u")continue;let d=typeof h.usage.category<"u"?Ti(h.usage.category,{format:this.format(t),paragraphs:!1}):null,m=l.get(d);typeof m>"u"&&l.set(d,m=[]);let{usage:y}=this.getUsageByIndex(p);m.push({commandClass:h,usage:y})}let c=Array.from(l.keys()).sort((h,p)=>h===null?-1:p===null?1:h.localeCompare(p,"en",{usage:"sort",caseFirst:"upper"})),u=typeof this.binaryLabel<"u",g=typeof this.binaryVersion<"u";u||g?(u&&g?a+=`${this.format(t).header(`${this.binaryLabel} - ${this.binaryVersion}`)} + +`:u?a+=`${this.format(t).header(`${this.binaryLabel}`)} +`:a+=`${this.format(t).header(`${this.binaryVersion}`)} +`,a+=` ${this.format(t).bold(n)}${this.binaryName} <command> +`):a+=`${this.format(t).bold(n)}${this.binaryName} <command> +`;for(let h of c){let p=l.get(h).slice().sort((m,y)=>m.usage.localeCompare(y.usage,"en",{usage:"sort",caseFirst:"upper"})),d=h!==null?h.trim():"General commands";a+=` +`,a+=`${this.format(t).header(`${d}`)} +`;for(let{commandClass:m,usage:y}of p){let B=m.usage.description||"undocumented";a+=` +`,a+=` ${this.format(t).bold(y)} +`,a+=` ${Ti(B,{format:this.format(t),paragraphs:!1})}`}}a+=` +`,a+=Ti("You can also print more details about any of these commands by calling them with the `-h,--help` flag right after the command name.",{format:this.format(t),paragraphs:!0})}return a}error(e,t){var i,{colored:n,command:s=(i=e[MH])!==null&&i!==void 0?i:null}=t===void 0?{}:t;e instanceof Error||(e=new Error(`Execution failed with a non-error rejection (rejected value: ${JSON.stringify(e)})`));let o="",a=e.name.replace(/([a-z])([A-Z])/g,"$1 $2");a==="Error"&&(a="Internal Error"),o+=`${this.format(n).error(a)}: ${e.message} +`;let l=e.clipanion;return typeof l<"u"?l.type==="usage"&&(o+=` +`,o+=this.usage(s)):e.stack&&(o+=`${e.stack.replace(/^.*\n/,"")} +`),o}format(e){var t;return((t=e!=null?e:this.enableColors)!==null&&t!==void 0?t:jn.defaultContext.colorDepth>1)?lv:RH}getUsageByRegistration(e,t){let i=this.registrations.get(e);if(typeof i>"u")throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(i.index,t)}getUsageByIndex(e,t){return this.builder.getBuilderByIndex(e).usage(t)}};jn.defaultContext={stdin:process.stdin,stdout:process.stdout,stderr:process.stderr,colorDepth:"getColorDepth"in fv.default.WriteStream.prototype?fv.default.WriteStream.prototype.getColorDepth():dCe()};var KH;function CCe(r){let e=KH;if(typeof e>"u"){if(r.stdout===process.stdout&&r.stderr===process.stderr)return UH;let{AsyncLocalStorage:t}=J("async_hooks");e=KH=new t;let i=process.stdout._write;process.stdout._write=function(s,o,a){let l=e.getStore();return typeof l>"u"?i.call(this,s,o,a):l.stdout.write(s,o,a)};let n=process.stderr._write;process.stderr._write=function(s,o,a){let l=e.getStore();return typeof l>"u"?n.call(this,s,o,a):l.stderr.write(s,o,a)}}return t=>e.run(r,t)}function UH(r){return r()}var hv={};ct(hv,{DefinitionsCommand:()=>ld,HelpCommand:()=>cd,VersionCommand:()=>ud});var ld=class extends Qe{async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.definitions(),null,2)} +`)}};ld.paths=[["--clipanion=definitions"]];var cd=class extends Qe{async execute(){this.context.stdout.write(this.cli.usage())}};cd.paths=[["-h"],["--help"]];var ud=class extends Qe{async execute(){var e;this.context.stdout.write(`${(e=this.cli.binaryVersion)!==null&&e!==void 0?e:"<unknown>"} +`)}};ud.paths=[["-v"],["--version"]];var z={};ct(z,{Array:()=>HH,Boolean:()=>jH,Counter:()=>GH,Proxy:()=>YH,Rest:()=>qH,String:()=>JH,applyValidator:()=>sd,cleanValidationError:()=>xI,formatError:()=>nd,isOptionSymbol:()=>id,makeCommandOption:()=>Vi,rerouteArguments:()=>xo});function HH(r,e,t){let[i,n]=xo(e,t!=null?t:{}),{arity:s=1}=n,o=r.split(","),a=new Set(o);return Vi({definition(l){l.addOption({names:o,arity:s,hidden:n==null?void 0:n.hidden,description:n==null?void 0:n.description,required:n.required})},transformer(l,c,u){let g=typeof i<"u"?[...i]:void 0;for(let{name:h,value:p}of u.options)!a.has(h)||(g=g!=null?g:[],g.push(p));return g}})}function jH(r,e,t){let[i,n]=xo(e,t!=null?t:{}),s=r.split(","),o=new Set(s);return Vi({definition(a){a.addOption({names:s,allowBinding:!1,arity:0,hidden:n.hidden,description:n.description,required:n.required})},transformer(a,l,c){let u=i;for(let{name:g,value:h}of c.options)!o.has(g)||(u=h);return u}})}function GH(r,e,t){let[i,n]=xo(e,t!=null?t:{}),s=r.split(","),o=new Set(s);return Vi({definition(a){a.addOption({names:s,allowBinding:!1,arity:0,hidden:n.hidden,description:n.description,required:n.required})},transformer(a,l,c){let u=i;for(let{name:g,value:h}of c.options)!o.has(g)||(u!=null||(u=0),h?u+=1:u=0);return u}})}function YH(r={}){return Vi({definition(e,t){var i;e.addProxy({name:(i=r.name)!==null&&i!==void 0?i:t,required:r.required})},transformer(e,t,i){return i.positionals.map(({value:n})=>n)}})}function qH(r={}){return Vi({definition(e,t){var i;e.addRest({name:(i=r.name)!==null&&i!==void 0?i:t,required:r.required})},transformer(e,t,i){let n=o=>{let a=i.positionals[o];return a.extra===Hn||a.extra===!1&&o<e.arity.leading.length},s=0;for(;s<i.positionals.length&&n(s);)s+=1;return i.positionals.splice(0,s).map(({value:o})=>o)}})}function mCe(r,e,t){let[i,n]=xo(e,t!=null?t:{}),{arity:s=1}=n,o=r.split(","),a=new Set(o);return Vi({definition(l){l.addOption({names:o,arity:n.tolerateBoolean?0:s,hidden:n.hidden,description:n.description,required:n.required})},transformer(l,c,u){let g,h=i;for(let{name:p,value:d}of u.options)!a.has(p)||(g=p,h=d);return typeof h=="string"?sd(g!=null?g:c,h,n.validator):h}})}function ECe(r={}){let{required:e=!0}=r;return Vi({definition(t,i){var n;t.addPositional({name:(n=r.name)!==null&&n!==void 0?n:i,required:r.required})},transformer(t,i,n){var s;for(let o=0;o<n.positionals.length;++o){if(n.positionals[o].extra===Hn||e&&n.positionals[o].extra===!0||!e&&n.positionals[o].extra===!1)continue;let[a]=n.positionals.splice(o,1);return sd((s=r.name)!==null&&s!==void 0?s:i,a.value,r.validator)}}})}function JH(r,...e){return typeof r=="string"?mCe(r,...e):ECe(r)}var wz=ve(Jg()),nD=J("stream");var dt=(ae=>(ae[ae.UNNAMED=0]="UNNAMED",ae[ae.EXCEPTION=1]="EXCEPTION",ae[ae.MISSING_PEER_DEPENDENCY=2]="MISSING_PEER_DEPENDENCY",ae[ae.CYCLIC_DEPENDENCIES=3]="CYCLIC_DEPENDENCIES",ae[ae.DISABLED_BUILD_SCRIPTS=4]="DISABLED_BUILD_SCRIPTS",ae[ae.BUILD_DISABLED=5]="BUILD_DISABLED",ae[ae.SOFT_LINK_BUILD=6]="SOFT_LINK_BUILD",ae[ae.MUST_BUILD=7]="MUST_BUILD",ae[ae.MUST_REBUILD=8]="MUST_REBUILD",ae[ae.BUILD_FAILED=9]="BUILD_FAILED",ae[ae.RESOLVER_NOT_FOUND=10]="RESOLVER_NOT_FOUND",ae[ae.FETCHER_NOT_FOUND=11]="FETCHER_NOT_FOUND",ae[ae.LINKER_NOT_FOUND=12]="LINKER_NOT_FOUND",ae[ae.FETCH_NOT_CACHED=13]="FETCH_NOT_CACHED",ae[ae.YARN_IMPORT_FAILED=14]="YARN_IMPORT_FAILED",ae[ae.REMOTE_INVALID=15]="REMOTE_INVALID",ae[ae.REMOTE_NOT_FOUND=16]="REMOTE_NOT_FOUND",ae[ae.RESOLUTION_PACK=17]="RESOLUTION_PACK",ae[ae.CACHE_CHECKSUM_MISMATCH=18]="CACHE_CHECKSUM_MISMATCH",ae[ae.UNUSED_CACHE_ENTRY=19]="UNUSED_CACHE_ENTRY",ae[ae.MISSING_LOCKFILE_ENTRY=20]="MISSING_LOCKFILE_ENTRY",ae[ae.WORKSPACE_NOT_FOUND=21]="WORKSPACE_NOT_FOUND",ae[ae.TOO_MANY_MATCHING_WORKSPACES=22]="TOO_MANY_MATCHING_WORKSPACES",ae[ae.CONSTRAINTS_MISSING_DEPENDENCY=23]="CONSTRAINTS_MISSING_DEPENDENCY",ae[ae.CONSTRAINTS_INCOMPATIBLE_DEPENDENCY=24]="CONSTRAINTS_INCOMPATIBLE_DEPENDENCY",ae[ae.CONSTRAINTS_EXTRANEOUS_DEPENDENCY=25]="CONSTRAINTS_EXTRANEOUS_DEPENDENCY",ae[ae.CONSTRAINTS_INVALID_DEPENDENCY=26]="CONSTRAINTS_INVALID_DEPENDENCY",ae[ae.CANT_SUGGEST_RESOLUTIONS=27]="CANT_SUGGEST_RESOLUTIONS",ae[ae.FROZEN_LOCKFILE_EXCEPTION=28]="FROZEN_LOCKFILE_EXCEPTION",ae[ae.CROSS_DRIVE_VIRTUAL_LOCAL=29]="CROSS_DRIVE_VIRTUAL_LOCAL",ae[ae.FETCH_FAILED=30]="FETCH_FAILED",ae[ae.DANGEROUS_NODE_MODULES=31]="DANGEROUS_NODE_MODULES",ae[ae.NODE_GYP_INJECTED=32]="NODE_GYP_INJECTED",ae[ae.AUTHENTICATION_NOT_FOUND=33]="AUTHENTICATION_NOT_FOUND",ae[ae.INVALID_CONFIGURATION_KEY=34]="INVALID_CONFIGURATION_KEY",ae[ae.NETWORK_ERROR=35]="NETWORK_ERROR",ae[ae.LIFECYCLE_SCRIPT=36]="LIFECYCLE_SCRIPT",ae[ae.CONSTRAINTS_MISSING_FIELD=37]="CONSTRAINTS_MISSING_FIELD",ae[ae.CONSTRAINTS_INCOMPATIBLE_FIELD=38]="CONSTRAINTS_INCOMPATIBLE_FIELD",ae[ae.CONSTRAINTS_EXTRANEOUS_FIELD=39]="CONSTRAINTS_EXTRANEOUS_FIELD",ae[ae.CONSTRAINTS_INVALID_FIELD=40]="CONSTRAINTS_INVALID_FIELD",ae[ae.AUTHENTICATION_INVALID=41]="AUTHENTICATION_INVALID",ae[ae.PROLOG_UNKNOWN_ERROR=42]="PROLOG_UNKNOWN_ERROR",ae[ae.PROLOG_SYNTAX_ERROR=43]="PROLOG_SYNTAX_ERROR",ae[ae.PROLOG_EXISTENCE_ERROR=44]="PROLOG_EXISTENCE_ERROR",ae[ae.STACK_OVERFLOW_RESOLUTION=45]="STACK_OVERFLOW_RESOLUTION",ae[ae.AUTOMERGE_FAILED_TO_PARSE=46]="AUTOMERGE_FAILED_TO_PARSE",ae[ae.AUTOMERGE_IMMUTABLE=47]="AUTOMERGE_IMMUTABLE",ae[ae.AUTOMERGE_SUCCESS=48]="AUTOMERGE_SUCCESS",ae[ae.AUTOMERGE_REQUIRED=49]="AUTOMERGE_REQUIRED",ae[ae.DEPRECATED_CLI_SETTINGS=50]="DEPRECATED_CLI_SETTINGS",ae[ae.PLUGIN_NAME_NOT_FOUND=51]="PLUGIN_NAME_NOT_FOUND",ae[ae.INVALID_PLUGIN_REFERENCE=52]="INVALID_PLUGIN_REFERENCE",ae[ae.CONSTRAINTS_AMBIGUITY=53]="CONSTRAINTS_AMBIGUITY",ae[ae.CACHE_OUTSIDE_PROJECT=54]="CACHE_OUTSIDE_PROJECT",ae[ae.IMMUTABLE_INSTALL=55]="IMMUTABLE_INSTALL",ae[ae.IMMUTABLE_CACHE=56]="IMMUTABLE_CACHE",ae[ae.INVALID_MANIFEST=57]="INVALID_MANIFEST",ae[ae.PACKAGE_PREPARATION_FAILED=58]="PACKAGE_PREPARATION_FAILED",ae[ae.INVALID_RANGE_PEER_DEPENDENCY=59]="INVALID_RANGE_PEER_DEPENDENCY",ae[ae.INCOMPATIBLE_PEER_DEPENDENCY=60]="INCOMPATIBLE_PEER_DEPENDENCY",ae[ae.DEPRECATED_PACKAGE=61]="DEPRECATED_PACKAGE",ae[ae.INCOMPATIBLE_OS=62]="INCOMPATIBLE_OS",ae[ae.INCOMPATIBLE_CPU=63]="INCOMPATIBLE_CPU",ae[ae.FROZEN_ARTIFACT_EXCEPTION=64]="FROZEN_ARTIFACT_EXCEPTION",ae[ae.TELEMETRY_NOTICE=65]="TELEMETRY_NOTICE",ae[ae.PATCH_HUNK_FAILED=66]="PATCH_HUNK_FAILED",ae[ae.INVALID_CONFIGURATION_VALUE=67]="INVALID_CONFIGURATION_VALUE",ae[ae.UNUSED_PACKAGE_EXTENSION=68]="UNUSED_PACKAGE_EXTENSION",ae[ae.REDUNDANT_PACKAGE_EXTENSION=69]="REDUNDANT_PACKAGE_EXTENSION",ae[ae.AUTO_NM_SUCCESS=70]="AUTO_NM_SUCCESS",ae[ae.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK=71]="NM_CANT_INSTALL_EXTERNAL_SOFT_LINK",ae[ae.NM_PRESERVE_SYMLINKS_REQUIRED=72]="NM_PRESERVE_SYMLINKS_REQUIRED",ae[ae.UPDATE_LOCKFILE_ONLY_SKIP_LINK=73]="UPDATE_LOCKFILE_ONLY_SKIP_LINK",ae[ae.NM_HARDLINKS_MODE_DOWNGRADED=74]="NM_HARDLINKS_MODE_DOWNGRADED",ae[ae.PROLOG_INSTANTIATION_ERROR=75]="PROLOG_INSTANTIATION_ERROR",ae[ae.INCOMPATIBLE_ARCHITECTURE=76]="INCOMPATIBLE_ARCHITECTURE",ae[ae.GHOST_ARCHITECTURE=77]="GHOST_ARCHITECTURE",ae[ae.PROLOG_LIMIT_EXCEEDED=79]="PROLOG_LIMIT_EXCEEDED",ae[ae.NETWORK_DISABLED=80]="NETWORK_DISABLED",ae[ae.NETWORK_UNSAFE_HTTP=81]="NETWORK_UNSAFE_HTTP",ae[ae.RESOLUTION_FAILED=82]="RESOLUTION_FAILED",ae))(dt||{});function RA(r){return`YN${r.toString(10).padStart(4,"0")}`}function TI(r){let e=Number(r.slice(2));if(typeof dt[e]>"u")throw new Error(`Unknown message name: "${r}"`);return e}var P={};ct(P,{areDescriptorsEqual:()=>x8,areIdentsEqual:()=>oC,areLocatorsEqual:()=>aC,areVirtualPackagesEquivalent:()=>YSe,bindDescriptor:()=>jSe,bindLocator:()=>GSe,convertDescriptorToLocator:()=>Qw,convertLocatorToDescriptor:()=>Hk,convertPackageToLocator:()=>HSe,convertToIdent:()=>USe,convertToManifestRange:()=>WSe,copyPackage:()=>iC,devirtualizeDescriptor:()=>nC,devirtualizeLocator:()=>sC,getIdentVendorPath:()=>qk,isPackageCompatible:()=>kw,isVirtualDescriptor:()=>qA,isVirtualLocator:()=>Yo,makeDescriptor:()=>zt,makeIdent:()=>qo,makeLocator:()=>rn,makeRange:()=>vw,parseDescriptor:()=>JA,parseFileStyleRange:()=>qSe,parseIdent:()=>en,parseLocator:()=>Rc,parseRange:()=>vf,prettyDependent:()=>nx,prettyDescriptor:()=>$t,prettyIdent:()=>ai,prettyLocator:()=>Ct,prettyLocatorNoColors:()=>Yk,prettyRange:()=>xw,prettyReference:()=>lC,prettyResolution:()=>ix,prettyWorkspace:()=>cC,renamePackage:()=>rC,slugifyIdent:()=>Uk,slugifyLocator:()=>Pf,sortDescriptors:()=>xf,stringifyDescriptor:()=>Sn,stringifyIdent:()=>Tt,stringifyLocator:()=>ms,tryParseDescriptor:()=>AC,tryParseIdent:()=>k8,tryParseLocator:()=>Sw,virtualizeDescriptor:()=>jk,virtualizePackage:()=>Gk});var Sf=ve(J("querystring")),S8=ve(zr()),v8=ve(yJ());var $={};ct($,{LogLevel:()=>Vy,Style:()=>_P,Type:()=>Ke,addLogFilterSupport:()=>Zd,applyColor:()=>Qn,applyHyperlink:()=>If,applyStyle:()=>zy,json:()=>Qc,jsonOrPretty:()=>w0e,mark:()=>rx,pretty:()=>_e,prettyField:()=>Ho,prettyList:()=>tx,supportsColor:()=>Wy,supportsHyperlinks:()=>ex,tuple:()=>io});var Xd=ve(wP()),Vd=ve(cc());var mW=ve(Bn()),EW=ve(aW());var me={};ct(me,{AsyncActions:()=>jP,BufferStream:()=>HP,CachingStrategy:()=>dW,DefaultStream:()=>GP,allSettledSafe:()=>ro,assertNever:()=>qP,bufferStream:()=>Cf,buildIgnorePattern:()=>m0e,convertMapsToIndexableObjects:()=>qy,dynamicRequire:()=>mf,escapeRegExp:()=>g0e,getArrayWithDefault:()=>hf,getFactoryWithDefault:()=>La,getMapWithDefault:()=>pf,getSetWithDefault:()=>bc,isIndexableObject:()=>UP,isPathLike:()=>E0e,isTaggedYarnVersion:()=>u0e,mapAndFilter:()=>Uo,mapAndFind:()=>Wd,overrideType:()=>f0e,parseBoolean:()=>zd,parseOptionalBoolean:()=>CW,prettifyAsyncErrors:()=>df,prettifySyncErrors:()=>JP,releaseAfterUseAsync:()=>p0e,replaceEnvVariables:()=>WP,sortMap:()=>bn,tryParseOptionalBoolean:()=>zP,validateEnum:()=>h0e});var lW=ve(Bn()),cW=ve(Jg()),uW=ve(zr()),YP=J("stream");function u0e(r){return!!(uW.default.valid(r)&&r.match(/^[^-]+(-rc\.[0-9]+)?$/))}function g0e(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function f0e(r){}function qP(r){throw new Error(`Assertion failed: Unexpected object '${r}'`)}function h0e(r,e){let t=Object.values(r);if(!t.includes(e))throw new we(`Invalid value for enumeration: ${JSON.stringify(e)} (expected one of ${t.map(i=>JSON.stringify(i)).join(", ")})`);return e}function Uo(r,e){let t=[];for(let i of r){let n=e(i);n!==gW&&t.push(n)}return t}var gW=Symbol();Uo.skip=gW;function Wd(r,e){for(let t of r){let i=e(t);if(i!==fW)return i}}var fW=Symbol();Wd.skip=fW;function UP(r){return typeof r=="object"&&r!==null}async function ro(r){let e=await Promise.allSettled(r),t=[];for(let i of e){if(i.status==="rejected")throw i.reason;t.push(i.value)}return t}function qy(r){if(r instanceof Map&&(r=Object.fromEntries(r)),UP(r))for(let e of Object.keys(r)){let t=r[e];UP(t)&&(r[e]=qy(t))}return r}function La(r,e,t){let i=r.get(e);return typeof i>"u"&&r.set(e,i=t()),i}function hf(r,e){let t=r.get(e);return typeof t>"u"&&r.set(e,t=[]),t}function bc(r,e){let t=r.get(e);return typeof t>"u"&&r.set(e,t=new Set),t}function pf(r,e){let t=r.get(e);return typeof t>"u"&&r.set(e,t=new Map),t}async function p0e(r,e){if(e==null)return await r();try{return await r()}finally{await e()}}async function df(r,e){try{return await r()}catch(t){throw t.message=e(t.message),t}}function JP(r,e){try{return r()}catch(t){throw t.message=e(t.message),t}}async function Cf(r){return await new Promise((e,t)=>{let i=[];r.on("error",n=>{t(n)}),r.on("data",n=>{i.push(n)}),r.on("end",()=>{e(Buffer.concat(i))})})}var HP=class extends YP.Transform{constructor(){super(...arguments);this.chunks=[]}_transform(t,i,n){if(i!=="buffer"||!Buffer.isBuffer(t))throw new Error("Assertion failed: BufferStream only accept buffers");this.chunks.push(t),n(null,null)}_flush(t){t(null,Buffer.concat(this.chunks))}};function d0e(){let r,e;return{promise:new Promise((i,n)=>{r=i,e=n}),resolve:r,reject:e}}var jP=class{constructor(e){this.deferred=new Map;this.promises=new Map;this.limit=(0,cW.default)(e)}set(e,t){let i=this.deferred.get(e);typeof i>"u"&&this.deferred.set(e,i=d0e());let n=this.limit(()=>t());return this.promises.set(e,n),n.then(()=>{this.promises.get(e)===n&&i.resolve()},s=>{this.promises.get(e)===n&&i.reject(s)}),i.promise}reduce(e,t){var n;let i=(n=this.promises.get(e))!=null?n:Promise.resolve();this.set(e,()=>t(i))}async wait(){await Promise.all(this.promises.values())}},GP=class extends YP.Transform{constructor(t=Buffer.alloc(0)){super();this.active=!0;this.ifEmpty=t}_transform(t,i,n){if(i!=="buffer"||!Buffer.isBuffer(t))throw new Error("Assertion failed: DefaultStream only accept buffers");this.active=!1,n(null,t)}_flush(t){this.active&&this.ifEmpty.length>0?t(null,this.ifEmpty):t(null)}},Jd=eval("require");function hW(r){return Jd(K.fromPortablePath(r))}function pW(path){let physicalPath=K.fromPortablePath(path),currentCacheEntry=Jd.cache[physicalPath];delete Jd.cache[physicalPath];let result;try{result=hW(physicalPath);let freshCacheEntry=Jd.cache[physicalPath],dynamicModule=eval("module"),freshCacheIndex=dynamicModule.children.indexOf(freshCacheEntry);freshCacheIndex!==-1&&dynamicModule.children.splice(freshCacheIndex,1)}finally{Jd.cache[physicalPath]=currentCacheEntry}return result}var AW=new Map;function C0e(r){let e=AW.get(r),t=M.statSync(r);if((e==null?void 0:e.mtime)===t.mtimeMs)return e.instance;let i=pW(r);return AW.set(r,{mtime:t.mtimeMs,instance:i}),i}var dW=(i=>(i[i.NoCache=0]="NoCache",i[i.FsTime=1]="FsTime",i[i.Node=2]="Node",i))(dW||{});function mf(r,{cachingStrategy:e=2}={}){switch(e){case 0:return pW(r);case 1:return C0e(r);case 2:return hW(r);default:throw new Error("Unsupported caching strategy")}}function bn(r,e){let t=Array.from(r);Array.isArray(e)||(e=[e]);let i=[];for(let s of e)i.push(t.map(o=>s(o)));let n=t.map((s,o)=>o);return n.sort((s,o)=>{for(let a of i){let l=a[s]<a[o]?-1:a[s]>a[o]?1:0;if(l!==0)return l}return 0}),n.map(s=>t[s])}function m0e(r){return r.length===0?null:r.map(e=>`(${lW.default.makeRe(e,{windows:!1,dot:!0}).source})`).join("|")}function WP(r,{env:e}){let t=/\${(?<variableName>[\d\w_]+)(?<colon>:)?(?:-(?<fallback>[^}]*))?}/g;return r.replace(t,(...i)=>{let{variableName:n,colon:s,fallback:o}=i[i.length-1],a=Object.prototype.hasOwnProperty.call(e,n),l=e[n];if(l||a&&!s)return l;if(o!=null)return o;throw new we(`Environment variable not found (${n})`)})}function zd(r){switch(r){case"true":case"1":case 1:case!0:return!0;case"false":case"0":case 0:case!1:return!1;default:throw new Error(`Couldn't parse "${r}" as a boolean`)}}function CW(r){return typeof r>"u"?r:zd(r)}function zP(r){try{return CW(r)}catch{return null}}function E0e(r){return!!(K.isAbsolute(r)||r.match(/^(\.{1,2}|~)\//))}var Ef=(t=>(t.HARD="HARD",t.SOFT="SOFT",t))(Ef||{}),VP=(i=>(i.Dependency="Dependency",i.PeerDependency="PeerDependency",i.PeerDependencyMeta="PeerDependencyMeta",i))(VP||{}),XP=(i=>(i.Inactive="inactive",i.Redundant="redundant",i.Active="active",i))(XP||{});var Ke={NO_HINT:"NO_HINT",NULL:"NULL",SCOPE:"SCOPE",NAME:"NAME",RANGE:"RANGE",REFERENCE:"REFERENCE",NUMBER:"NUMBER",PATH:"PATH",URL:"URL",ADDED:"ADDED",REMOVED:"REMOVED",CODE:"CODE",DURATION:"DURATION",SIZE:"SIZE",IDENT:"IDENT",DESCRIPTOR:"DESCRIPTOR",LOCATOR:"LOCATOR",RESOLUTION:"RESOLUTION",DEPENDENT:"DEPENDENT",PACKAGE_EXTENSION:"PACKAGE_EXTENSION",SETTING:"SETTING",MARKDOWN:"MARKDOWN"},_P=(e=>(e[e.BOLD=2]="BOLD",e))(_P||{}),$P=Vd.default.GITHUB_ACTIONS?{level:2}:Xd.default.supportsColor?{level:Xd.default.supportsColor.level}:{level:0},Wy=$P.level!==0,ex=Wy&&!Vd.default.GITHUB_ACTIONS&&!Vd.default.CIRCLE&&!Vd.default.GITLAB,ZP=new Xd.default.Instance($P),I0e=new Map([[Ke.NO_HINT,null],[Ke.NULL,["#a853b5",129]],[Ke.SCOPE,["#d75f00",166]],[Ke.NAME,["#d7875f",173]],[Ke.RANGE,["#00afaf",37]],[Ke.REFERENCE,["#87afff",111]],[Ke.NUMBER,["#ffd700",220]],[Ke.PATH,["#d75fd7",170]],[Ke.URL,["#d75fd7",170]],[Ke.ADDED,["#5faf00",70]],[Ke.REMOVED,["#d70000",160]],[Ke.CODE,["#87afff",111]],[Ke.SIZE,["#ffd700",220]]]),Cs=r=>r,Jy={[Ke.NUMBER]:Cs({pretty:(r,e)=>Qn(r,`${e}`,Ke.NUMBER),json:r=>r}),[Ke.IDENT]:Cs({pretty:(r,e)=>ai(r,e),json:r=>Tt(r)}),[Ke.LOCATOR]:Cs({pretty:(r,e)=>Ct(r,e),json:r=>ms(r)}),[Ke.DESCRIPTOR]:Cs({pretty:(r,e)=>$t(r,e),json:r=>Sn(r)}),[Ke.RESOLUTION]:Cs({pretty:(r,{descriptor:e,locator:t})=>ix(r,e,t),json:({descriptor:r,locator:e})=>({descriptor:Sn(r),locator:e!==null?ms(e):null})}),[Ke.DEPENDENT]:Cs({pretty:(r,{locator:e,descriptor:t})=>nx(r,e,t),json:({locator:r,descriptor:e})=>({locator:ms(r),descriptor:Sn(e)})}),[Ke.PACKAGE_EXTENSION]:Cs({pretty:(r,e)=>{switch(e.type){case"Dependency":return`${ai(r,e.parentDescriptor)} \u27A4 ${Qn(r,"dependencies",Ke.CODE)} \u27A4 ${ai(r,e.descriptor)}`;case"PeerDependency":return`${ai(r,e.parentDescriptor)} \u27A4 ${Qn(r,"peerDependencies",Ke.CODE)} \u27A4 ${ai(r,e.descriptor)}`;case"PeerDependencyMeta":return`${ai(r,e.parentDescriptor)} \u27A4 ${Qn(r,"peerDependenciesMeta",Ke.CODE)} \u27A4 ${ai(r,en(e.selector))} \u27A4 ${Qn(r,e.key,Ke.CODE)}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${e.type}`)}},json:r=>{switch(r.type){case"Dependency":return`${Tt(r.parentDescriptor)} > ${Tt(r.descriptor)}`;case"PeerDependency":return`${Tt(r.parentDescriptor)} >> ${Tt(r.descriptor)}`;case"PeerDependencyMeta":return`${Tt(r.parentDescriptor)} >> ${r.selector} / ${r.key}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${r.type}`)}}}),[Ke.SETTING]:Cs({pretty:(r,e)=>(r.get(e),If(r,Qn(r,e,Ke.CODE),`https://yarnpkg.com/configuration/yarnrc#${e}`)),json:r=>r}),[Ke.DURATION]:Cs({pretty:(r,e)=>{if(e>1e3*60){let t=Math.floor(e/1e3/60),i=Math.ceil((e-t*60*1e3)/1e3);return i===0?`${t}m`:`${t}m ${i}s`}else{let t=Math.floor(e/1e3),i=e-t*1e3;return i===0?`${t}s`:`${t}s ${i}ms`}},json:r=>r}),[Ke.SIZE]:Cs({pretty:(r,e)=>{let t=["KB","MB","GB","TB"],i=t.length;for(;i>1&&e<1024**i;)i-=1;let n=1024**i,s=Math.floor(e*100/n)/100;return Qn(r,`${s} ${t[i-1]}`,Ke.NUMBER)},json:r=>r}),[Ke.PATH]:Cs({pretty:(r,e)=>Qn(r,K.fromPortablePath(e),Ke.PATH),json:r=>K.fromPortablePath(r)}),[Ke.MARKDOWN]:Cs({pretty:(r,{text:e,format:t,paragraphs:i})=>Ti(e,{format:t,paragraphs:i}),json:({text:r})=>r})};function io(r,e){return[e,r]}function zy(r,e,t){return r.get("enableColors")&&t&2&&(e=Xd.default.bold(e)),e}function Qn(r,e,t){if(!r.get("enableColors"))return e;let i=I0e.get(t);if(i===null)return e;let n=typeof i>"u"?t:$P.level>=3?i[0]:i[1],s=typeof n=="number"?ZP.ansi256(n):n.startsWith("#")?ZP.hex(n):ZP[n];if(typeof s!="function")throw new Error(`Invalid format type ${n}`);return s(e)}var y0e=!!process.env.KONSOLE_VERSION;function If(r,e,t){return r.get("enableHyperlinks")?y0e?`\x1B]8;;${t}\x1B\\${e}\x1B]8;;\x1B\\`:`\x1B]8;;${t}\x07${e}\x1B]8;;\x07`:e}function _e(r,e,t){if(e===null)return Qn(r,"null",Ke.NULL);if(Object.prototype.hasOwnProperty.call(Jy,t))return Jy[t].pretty(r,e);if(typeof e!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof e}`);return Qn(r,e,t)}function tx(r,e,t,{separator:i=", "}={}){return[...e].map(n=>_e(r,n,t)).join(i)}function Qc(r,e){if(r===null)return null;if(Object.prototype.hasOwnProperty.call(Jy,e))return Jy[e].json(r);if(typeof r!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof r}`);return r}function w0e(r,e,[t,i]){return r?Qc(t,i):_e(e,t,i)}function rx(r){return{Check:Qn(r,"\u2713","green"),Cross:Qn(r,"\u2718","red"),Question:Qn(r,"?","cyan")}}function Ho(r,{label:e,value:[t,i]}){return`${_e(r,e,Ke.CODE)}: ${_e(r,t,i)}`}var Vy=(n=>(n.Error="error",n.Warning="warning",n.Info="info",n.Discard="discard",n))(Vy||{});function Zd(r,{configuration:e}){let t=e.get("logFilters"),i=new Map,n=new Map,s=[];for(let g of t){let h=g.get("level");if(typeof h>"u")continue;let p=g.get("code");typeof p<"u"&&i.set(p,h);let d=g.get("text");typeof d<"u"&&n.set(d,h);let m=g.get("pattern");typeof m<"u"&&s.push([mW.default.matcher(m,{contains:!0}),h])}s.reverse();let o=(g,h,p)=>{if(g===null||g===0)return p;let d=n.size>0||s.length>0?(0,EW.default)(h):h;if(n.size>0){let m=n.get(d);if(typeof m<"u")return m!=null?m:p}if(s.length>0){for(let[m,y]of s)if(m(d))return y!=null?y:p}if(i.size>0){let m=i.get(RA(g));if(typeof m<"u")return m!=null?m:p}return p},a=r.reportInfo,l=r.reportWarning,c=r.reportError,u=function(g,h,p,d){switch(o(h,p,d)){case"info":a.call(g,h,p);break;case"warning":l.call(g,h!=null?h:0,p);break;case"error":c.call(g,h!=null?h:0,p);break}};r.reportInfo=function(...g){return u(this,...g,"info")},r.reportWarning=function(...g){return u(this,...g,"warning")},r.reportError=function(...g){return u(this,...g,"error")}}var Ai={};ct(Ai,{checksumFile:()=>Bw,checksumPattern:()=>bw,makeHash:()=>tn});var ww=J("crypto"),Kk=ve(Mk());function tn(...r){let e=(0,ww.createHash)("sha512"),t="";for(let i of r)typeof i=="string"?t+=i:i&&(t&&(e.update(t),t=""),e.update(i));return t&&e.update(t),e.digest("hex")}async function Bw(r,{baseFs:e,algorithm:t}={baseFs:M,algorithm:"sha512"}){let i=await e.openPromise(r,"r");try{let s=Buffer.allocUnsafeSlow(65536),o=(0,ww.createHash)(t),a=0;for(;(a=await e.readPromise(i,s,0,65536))!==0;)o.update(a===65536?s:s.slice(0,a));return o.digest("hex")}finally{await e.closePromise(i)}}async function bw(r,{cwd:e}){let i=(await(0,Kk.default)(r,{cwd:K.fromPortablePath(e),expandDirectories:!1,onlyDirectories:!0,unique:!0})).map(a=>`${a}/**/*`),n=await(0,Kk.default)([r,...i],{cwd:K.fromPortablePath(e),expandDirectories:!1,onlyFiles:!1,unique:!0});n.sort();let s=await Promise.all(n.map(async a=>{let l=[Buffer.from(a)],c=K.toPortablePath(a),u=await M.lstatPromise(c);return u.isSymbolicLink()?l.push(Buffer.from(await M.readlinkPromise(c))):u.isFile()&&l.push(await M.readFilePromise(c)),l.join("\0")})),o=(0,ww.createHash)("sha512");for(let a of s)o.update(a);return o.digest("hex")}var tC="virtual:",MSe=5,P8=/(os|cpu|libc)=([a-z0-9_-]+)/,KSe=(0,v8.makeParser)(P8);function qo(r,e){if(r!=null&&r.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:tn(r,e),scope:r,name:e}}function zt(r,e){return{identHash:r.identHash,scope:r.scope,name:r.name,descriptorHash:tn(r.identHash,e),range:e}}function rn(r,e){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:tn(r.identHash,e),reference:e}}function USe(r){return{identHash:r.identHash,scope:r.scope,name:r.name}}function Qw(r){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:r.descriptorHash,reference:r.range}}function Hk(r){return{identHash:r.identHash,scope:r.scope,name:r.name,descriptorHash:r.locatorHash,range:r.reference}}function HSe(r){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:r.locatorHash,reference:r.reference}}function rC(r,e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference,version:r.version,languageName:r.languageName,linkType:r.linkType,conditions:r.conditions,dependencies:new Map(r.dependencies),peerDependencies:new Map(r.peerDependencies),dependenciesMeta:new Map(r.dependenciesMeta),peerDependenciesMeta:new Map(r.peerDependenciesMeta),bin:new Map(r.bin)}}function iC(r){return rC(r,r)}function jk(r,e){if(e.includes("#"))throw new Error("Invalid entropy");return zt(r,`virtual:${e}#${r.range}`)}function Gk(r,e){if(e.includes("#"))throw new Error("Invalid entropy");return rC(r,rn(r,`virtual:${e}#${r.reference}`))}function qA(r){return r.range.startsWith(tC)}function Yo(r){return r.reference.startsWith(tC)}function nC(r){if(!qA(r))throw new Error("Not a virtual descriptor");return zt(r,r.range.replace(/^[^#]*#/,""))}function sC(r){if(!Yo(r))throw new Error("Not a virtual descriptor");return rn(r,r.reference.replace(/^[^#]*#/,""))}function jSe(r,e){return r.range.includes("::")?r:zt(r,`${r.range}::${Sf.default.stringify(e)}`)}function GSe(r,e){return r.reference.includes("::")?r:rn(r,`${r.reference}::${Sf.default.stringify(e)}`)}function oC(r,e){return r.identHash===e.identHash}function x8(r,e){return r.descriptorHash===e.descriptorHash}function aC(r,e){return r.locatorHash===e.locatorHash}function YSe(r,e){if(!Yo(r))throw new Error("Invalid package type");if(!Yo(e))throw new Error("Invalid package type");if(!oC(r,e)||r.dependencies.size!==e.dependencies.size)return!1;for(let t of r.dependencies.values()){let i=e.dependencies.get(t.identHash);if(!i||!x8(t,i))return!1}return!0}function en(r){let e=k8(r);if(!e)throw new Error(`Invalid ident (${r})`);return e}function k8(r){let e=r.match(/^(?:@([^/]+?)\/)?([^/]+)$/);if(!e)return null;let[,t,i]=e;return qo(typeof t<"u"?t:null,i)}function JA(r,e=!1){let t=AC(r,e);if(!t)throw new Error(`Invalid descriptor (${r})`);return t}function AC(r,e=!1){let t=e?r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!t)return null;let[,i,n,s]=t;if(s==="unknown")throw new Error(`Invalid range (${r})`);let o=typeof i<"u"?i:null,a=typeof s<"u"?s:"unknown";return zt(qo(o,n),a)}function Rc(r,e=!1){let t=Sw(r,e);if(!t)throw new Error(`Invalid locator (${r})`);return t}function Sw(r,e=!1){let t=e?r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!t)return null;let[,i,n,s]=t;if(s==="unknown")throw new Error(`Invalid reference (${r})`);let o=typeof i<"u"?i:null,a=typeof s<"u"?s:"unknown";return rn(qo(o,n),a)}function vf(r,e){let t=r.match(/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/);if(t===null)throw new Error(`Invalid range (${r})`);let i=typeof t[1]<"u"?t[1]:null;if(typeof(e==null?void 0:e.requireProtocol)=="string"&&i!==e.requireProtocol)throw new Error(`Invalid protocol (${i})`);if((e==null?void 0:e.requireProtocol)&&i===null)throw new Error(`Missing protocol (${i})`);let n=typeof t[3]<"u"?decodeURIComponent(t[2]):null;if((e==null?void 0:e.requireSource)&&n===null)throw new Error(`Missing source (${r})`);let s=typeof t[3]<"u"?decodeURIComponent(t[3]):decodeURIComponent(t[2]),o=e!=null&&e.parseSelector?Sf.default.parse(s):s,a=typeof t[4]<"u"?Sf.default.parse(t[4]):null;return{protocol:i,source:n,selector:o,params:a}}function qSe(r,{protocol:e}){let{selector:t,params:i}=vf(r,{requireProtocol:e,requireBindings:!0});if(typeof i.locator!="string")throw new Error(`Assertion failed: Invalid bindings for ${r}`);return{parentLocator:Rc(i.locator,!0),path:t}}function Q8(r){return r=r.replace(/%/g,"%25"),r=r.replace(/:/g,"%3A"),r=r.replace(/#/g,"%23"),r}function JSe(r){return r===null?!1:Object.entries(r).length>0}function vw({protocol:r,source:e,selector:t,params:i}){let n="";return r!==null&&(n+=`${r}`),e!==null&&(n+=`${Q8(e)}#`),n+=Q8(t),JSe(i)&&(n+=`::${Sf.default.stringify(i)}`),n}function WSe(r){let{params:e,protocol:t,source:i,selector:n}=vf(r);for(let s in e)s.startsWith("__")&&delete e[s];return vw({protocol:t,source:i,params:e,selector:n})}function Tt(r){return r.scope?`@${r.scope}/${r.name}`:`${r.name}`}function Sn(r){return r.scope?`@${r.scope}/${r.name}@${r.range}`:`${r.name}@${r.range}`}function ms(r){return r.scope?`@${r.scope}/${r.name}@${r.reference}`:`${r.name}@${r.reference}`}function Uk(r){return r.scope!==null?`@${r.scope}-${r.name}`:r.name}function Pf(r){let{protocol:e,selector:t}=vf(r.reference),i=e!==null?e.replace(/:$/,""):"exotic",n=S8.default.valid(t),s=n!==null?`${i}-${n}`:`${i}`,o=10,a=r.scope?`${Uk(r)}-${s}-${r.locatorHash.slice(0,o)}`:`${Uk(r)}-${s}-${r.locatorHash.slice(0,o)}`;return Yr(a)}function ai(r,e){return e.scope?`${_e(r,`@${e.scope}/`,Ke.SCOPE)}${_e(r,e.name,Ke.NAME)}`:`${_e(r,e.name,Ke.NAME)}`}function Pw(r){if(r.startsWith(tC)){let e=Pw(r.substring(r.indexOf("#")+1)),t=r.substring(tC.length,tC.length+MSe);return`${e} [${t}]`}else return r.replace(/\?.*/,"?[...]")}function xw(r,e){return`${_e(r,Pw(e),Ke.RANGE)}`}function $t(r,e){return`${ai(r,e)}${_e(r,"@",Ke.RANGE)}${xw(r,e.range)}`}function lC(r,e){return`${_e(r,Pw(e),Ke.REFERENCE)}`}function Ct(r,e){return`${ai(r,e)}${_e(r,"@",Ke.REFERENCE)}${lC(r,e.reference)}`}function Yk(r){return`${Tt(r)}@${Pw(r.reference)}`}function xf(r){return bn(r,[e=>Tt(e),e=>e.range])}function cC(r,e){return ai(r,e.locator)}function ix(r,e,t){let i=qA(e)?nC(e):e;return t===null?`${$t(r,i)} \u2192 ${rx(r).Cross}`:i.identHash===t.identHash?`${$t(r,i)} \u2192 ${lC(r,t.reference)}`:`${$t(r,i)} \u2192 ${Ct(r,t)}`}function nx(r,e,t){return t===null?`${Ct(r,e)}`:`${Ct(r,e)} (via ${xw(r,t.range)})`}function qk(r){return`node_modules/${Tt(r)}`}function kw(r,e){return r.conditions?KSe(r.conditions,t=>{let[,i,n]=t.match(P8),s=e[i];return s?s.includes(n):!0}):!0}var D8={hooks:{reduceDependency:(r,e,t,i,{resolver:n,resolveOptions:s})=>{for(let{pattern:o,reference:a}of e.topLevelWorkspace.manifest.resolutions){if(o.from&&o.from.fullName!==Tt(t)||o.from&&o.from.description&&o.from.description!==t.reference||o.descriptor.fullName!==Tt(r)||o.descriptor.description&&o.descriptor.description!==r.range)continue;return n.bindDescriptor(zt(r,a),e.topLevelWorkspace.anchoredLocator,s)}return r},validateProject:async(r,e)=>{for(let t of r.workspaces){let i=cC(r.configuration,t);await r.configuration.triggerHook(n=>n.validateWorkspace,t,{reportWarning:(n,s)=>e.reportWarning(n,`${i}: ${s}`),reportError:(n,s)=>e.reportError(n,`${i}: ${s}`)})}},validateWorkspace:async(r,e)=>{let{manifest:t}=r;t.resolutions.length&&r.cwd!==r.project.cwd&&t.errors.push(new Error("Resolutions field will be ignored"));for(let i of t.errors)e.reportWarning(57,i.message)}}};var M8=ve(zr());var uC=class{supportsDescriptor(e,t){return!!(e.range.startsWith(uC.protocol)||t.project.tryWorkspaceByDescriptor(e)!==null)}supportsLocator(e,t){return!!e.reference.startsWith(uC.protocol)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){return[i.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,t,i){return null}async resolve(e,t){let i=t.project.getWorkspaceByCwd(e.reference.slice(uC.protocol.length));return{...e,version:i.manifest.version||"0.0.0",languageName:"unknown",linkType:"SOFT",conditions:null,dependencies:new Map([...i.manifest.dependencies,...i.manifest.devDependencies]),peerDependencies:new Map([...i.manifest.peerDependencies]),dependenciesMeta:i.manifest.dependenciesMeta,peerDependenciesMeta:i.manifest.peerDependenciesMeta,bin:i.manifest.bin}}},Ur=uC;Ur.protocol="workspace:";var Qt={};ct(Qt,{SemVer:()=>N8.SemVer,clean:()=>VSe,satisfiesWithPrereleases:()=>Fc,validRange:()=>no});var Dw=ve(zr()),N8=ve(zr()),R8=new Map;function Fc(r,e,t=!1){if(!r)return!1;let i=`${e}${t}`,n=R8.get(i);if(typeof n>"u")try{n=new Dw.default.Range(e,{includePrerelease:!0,loose:t})}catch{return!1}finally{R8.set(i,n||null)}else if(n===null)return!1;let s;try{s=new Dw.default.SemVer(r,n)}catch{return!1}return n.test(s)?!0:(s.prerelease&&(s.prerelease=[]),n.set.some(o=>{for(let a of o)a.semver.prerelease&&(a.semver.prerelease=[]);return o.every(a=>a.test(s))}))}var F8=new Map;function no(r){if(r.indexOf(":")!==-1)return null;let e=F8.get(r);if(typeof e<"u")return e;try{e=new Dw.default.Range(r)}catch{e=null}return F8.set(r,e),e}var zSe=/^(?:[\sv=]*?)((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\s*)$/;function VSe(r){let e=zSe.exec(r);return e?e[1]:null}var WA=class{constructor(){this.indent=" ";this.name=null;this.version=null;this.os=null;this.cpu=null;this.libc=null;this.type=null;this.packageManager=null;this.private=!1;this.license=null;this.main=null;this.module=null;this.browser=null;this.languageName=null;this.bin=new Map;this.scripts=new Map;this.dependencies=new Map;this.devDependencies=new Map;this.peerDependencies=new Map;this.workspaceDefinitions=[];this.dependenciesMeta=new Map;this.peerDependenciesMeta=new Map;this.resolutions=[];this.files=null;this.publishConfig=null;this.installConfig=null;this.preferUnplugged=null;this.raw={};this.errors=[]}static async tryFind(e,{baseFs:t=new Zt}={}){let i=v.join(e,"package.json");try{return await WA.fromFile(i,{baseFs:t})}catch(n){if(n.code==="ENOENT")return null;throw n}}static async find(e,{baseFs:t}={}){let i=await WA.tryFind(e,{baseFs:t});if(i===null)throw new Error("Manifest not found");return i}static async fromFile(e,{baseFs:t=new Zt}={}){let i=new WA;return await i.loadFile(e,{baseFs:t}),i}static fromText(e){let t=new WA;return t.loadFromText(e),t}static isManifestFieldCompatible(e,t){if(e===null)return!0;let i=!0,n=!1;for(let s of e)if(s[0]==="!"){if(n=!0,t===s.slice(1))return!1}else if(i=!1,s===t)return!0;return n&&i}loadFromText(e){let t;try{t=JSON.parse(L8(e)||"{}")}catch(i){throw i.message+=` (when parsing ${e})`,i}this.load(t),this.indent=T8(e)}async loadFile(e,{baseFs:t=new Zt}){let i=await t.readFilePromise(e,"utf8"),n;try{n=JSON.parse(L8(i)||"{}")}catch(s){throw s.message+=` (when parsing ${e})`,s}this.load(n),this.indent=T8(i)}load(e,{yamlCompatibilityMode:t=!1}={}){if(typeof e!="object"||e===null)throw new Error(`Utterly invalid manifest data (${e})`);this.raw=e;let i=[];if(this.name=null,typeof e.name=="string")try{this.name=en(e.name)}catch{i.push(new Error("Parsing failed for the 'name' field"))}if(typeof e.version=="string"?this.version=e.version:this.version=null,Array.isArray(e.os)){let s=[];this.os=s;for(let o of e.os)typeof o!="string"?i.push(new Error("Parsing failed for the 'os' field")):s.push(o)}else this.os=null;if(Array.isArray(e.cpu)){let s=[];this.cpu=s;for(let o of e.cpu)typeof o!="string"?i.push(new Error("Parsing failed for the 'cpu' field")):s.push(o)}else this.cpu=null;if(Array.isArray(e.libc)){let s=[];this.libc=s;for(let o of e.libc)typeof o!="string"?i.push(new Error("Parsing failed for the 'libc' field")):s.push(o)}else this.libc=null;if(typeof e.type=="string"?this.type=e.type:this.type=null,typeof e.packageManager=="string"?this.packageManager=e.packageManager:this.packageManager=null,typeof e.private=="boolean"?this.private=e.private:this.private=!1,typeof e.license=="string"?this.license=e.license:this.license=null,typeof e.languageName=="string"?this.languageName=e.languageName:this.languageName=null,typeof e.main=="string"?this.main=nn(e.main):this.main=null,typeof e.module=="string"?this.module=nn(e.module):this.module=null,e.browser!=null)if(typeof e.browser=="string")this.browser=nn(e.browser);else{this.browser=new Map;for(let[s,o]of Object.entries(e.browser))this.browser.set(nn(s),typeof o=="string"?nn(o):o)}else this.browser=null;if(this.bin=new Map,typeof e.bin=="string")e.bin.trim()===""?i.push(new Error("Invalid bin field")):this.name!==null?this.bin.set(this.name.name,nn(e.bin)):i.push(new Error("String bin field, but no attached package name"));else if(typeof e.bin=="object"&&e.bin!==null)for(let[s,o]of Object.entries(e.bin)){if(typeof o!="string"||o.trim()===""){i.push(new Error(`Invalid bin definition for '${s}'`));continue}let a=en(s);this.bin.set(a.name,nn(o))}if(this.scripts=new Map,typeof e.scripts=="object"&&e.scripts!==null)for(let[s,o]of Object.entries(e.scripts)){if(typeof o!="string"){i.push(new Error(`Invalid script definition for '${s}'`));continue}this.scripts.set(s,o)}if(this.dependencies=new Map,typeof e.dependencies=="object"&&e.dependencies!==null)for(let[s,o]of Object.entries(e.dependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=en(s)}catch{i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=zt(a,o);this.dependencies.set(l.identHash,l)}if(this.devDependencies=new Map,typeof e.devDependencies=="object"&&e.devDependencies!==null)for(let[s,o]of Object.entries(e.devDependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=en(s)}catch{i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=zt(a,o);this.devDependencies.set(l.identHash,l)}if(this.peerDependencies=new Map,typeof e.peerDependencies=="object"&&e.peerDependencies!==null)for(let[s,o]of Object.entries(e.peerDependencies)){let a;try{a=en(s)}catch{i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}(typeof o!="string"||!o.startsWith(Ur.protocol)&&!no(o))&&(i.push(new Error(`Invalid dependency range for '${s}'`)),o="*");let l=zt(a,o);this.peerDependencies.set(l.identHash,l)}typeof e.workspaces=="object"&&e.workspaces!==null&&e.workspaces.nohoist&&i.push(new Error("'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead"));let n=Array.isArray(e.workspaces)?e.workspaces:typeof e.workspaces=="object"&&e.workspaces!==null&&Array.isArray(e.workspaces.packages)?e.workspaces.packages:[];this.workspaceDefinitions=[];for(let s of n){if(typeof s!="string"){i.push(new Error(`Invalid workspace definition for '${s}'`));continue}this.workspaceDefinitions.push({pattern:s})}if(this.dependenciesMeta=new Map,typeof e.dependenciesMeta=="object"&&e.dependenciesMeta!==null)for(let[s,o]of Object.entries(e.dependenciesMeta)){if(typeof o!="object"||o===null){i.push(new Error(`Invalid meta field for '${s}`));continue}let a=JA(s),l=this.ensureDependencyMeta(a),c=Rw(o.built,{yamlCompatibilityMode:t});if(c===null){i.push(new Error(`Invalid built meta field for '${s}'`));continue}let u=Rw(o.optional,{yamlCompatibilityMode:t});if(u===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}let g=Rw(o.unplugged,{yamlCompatibilityMode:t});if(g===null){i.push(new Error(`Invalid unplugged meta field for '${s}'`));continue}Object.assign(l,{built:c,optional:u,unplugged:g})}if(this.peerDependenciesMeta=new Map,typeof e.peerDependenciesMeta=="object"&&e.peerDependenciesMeta!==null)for(let[s,o]of Object.entries(e.peerDependenciesMeta)){if(typeof o!="object"||o===null){i.push(new Error(`Invalid meta field for '${s}'`));continue}let a=JA(s),l=this.ensurePeerDependencyMeta(a),c=Rw(o.optional,{yamlCompatibilityMode:t});if(c===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}Object.assign(l,{optional:c})}if(this.resolutions=[],typeof e.resolutions=="object"&&e.resolutions!==null)for(let[s,o]of Object.entries(e.resolutions)){if(typeof o!="string"){i.push(new Error(`Invalid resolution entry for '${s}'`));continue}try{this.resolutions.push({pattern:fI(s),reference:o})}catch(a){i.push(a);continue}}if(Array.isArray(e.files)){this.files=new Set;for(let s of e.files){if(typeof s!="string"){i.push(new Error(`Invalid files entry for '${s}'`));continue}this.files.add(s)}}else this.files=null;if(typeof e.publishConfig=="object"&&e.publishConfig!==null){if(this.publishConfig={},typeof e.publishConfig.access=="string"&&(this.publishConfig.access=e.publishConfig.access),typeof e.publishConfig.main=="string"&&(this.publishConfig.main=nn(e.publishConfig.main)),typeof e.publishConfig.module=="string"&&(this.publishConfig.module=nn(e.publishConfig.module)),e.publishConfig.browser!=null)if(typeof e.publishConfig.browser=="string")this.publishConfig.browser=nn(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(let[s,o]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set(nn(s),typeof o=="string"?nn(o):o)}if(typeof e.publishConfig.registry=="string"&&(this.publishConfig.registry=e.publishConfig.registry),typeof e.publishConfig.bin=="string")this.name!==null?this.publishConfig.bin=new Map([[this.name.name,nn(e.publishConfig.bin)]]):i.push(new Error("String bin field, but no attached package name"));else if(typeof e.publishConfig.bin=="object"&&e.publishConfig.bin!==null){this.publishConfig.bin=new Map;for(let[s,o]of Object.entries(e.publishConfig.bin)){if(typeof o!="string"){i.push(new Error(`Invalid bin definition for '${s}'`));continue}this.publishConfig.bin.set(s,nn(o))}}if(Array.isArray(e.publishConfig.executableFiles)){this.publishConfig.executableFiles=new Set;for(let s of e.publishConfig.executableFiles){if(typeof s!="string"){i.push(new Error("Invalid executable file definition"));continue}this.publishConfig.executableFiles.add(nn(s))}}}else this.publishConfig=null;if(typeof e.installConfig=="object"&&e.installConfig!==null){this.installConfig={};for(let s of Object.keys(e.installConfig))s==="hoistingLimits"?typeof e.installConfig.hoistingLimits=="string"?this.installConfig.hoistingLimits=e.installConfig.hoistingLimits:i.push(new Error("Invalid hoisting limits definition")):s=="selfReferences"?typeof e.installConfig.selfReferences=="boolean"?this.installConfig.selfReferences=e.installConfig.selfReferences:i.push(new Error("Invalid selfReferences definition, must be a boolean value")):i.push(new Error(`Unrecognized installConfig key: ${s}`))}else this.installConfig=null;if(typeof e.optionalDependencies=="object"&&e.optionalDependencies!==null)for(let[s,o]of Object.entries(e.optionalDependencies)){if(typeof o!="string"){i.push(new Error(`Invalid dependency range for '${s}'`));continue}let a;try{a=en(s)}catch{i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=zt(a,o);this.dependencies.set(l.identHash,l);let c=zt(a,"unknown"),u=this.ensureDependencyMeta(c);Object.assign(u,{optional:!0})}typeof e.preferUnplugged=="boolean"?this.preferUnplugged=e.preferUnplugged:this.preferUnplugged=null,this.errors=i}getForScope(e){switch(e){case"dependencies":return this.dependencies;case"devDependencies":return this.devDependencies;case"peerDependencies":return this.peerDependencies;default:throw new Error(`Unsupported value ("${e}")`)}}hasConsumerDependency(e){return!!(this.dependencies.has(e.identHash)||this.peerDependencies.has(e.identHash))}hasHardDependency(e){return!!(this.dependencies.has(e.identHash)||this.devDependencies.has(e.identHash))}hasSoftDependency(e){return!!this.peerDependencies.has(e.identHash)}hasDependency(e){return!!(this.hasHardDependency(e)||this.hasSoftDependency(e))}getConditions(){let e=[];return this.os&&this.os.length>0&&e.push(Jk("os",this.os)),this.cpu&&this.cpu.length>0&&e.push(Jk("cpu",this.cpu)),this.libc&&this.libc.length>0&&e.push(Jk("libc",this.libc)),e.length>0?e.join(" & "):null}isCompatibleWithOS(e){return WA.isManifestFieldCompatible(this.os,e)}isCompatibleWithCPU(e){return WA.isManifestFieldCompatible(this.cpu,e)}ensureDependencyMeta(e){if(e.range!=="unknown"&&!M8.default.valid(e.range))throw new Error(`Invalid meta field range for '${Sn(e)}'`);let t=Tt(e),i=e.range!=="unknown"?e.range:null,n=this.dependenciesMeta.get(t);n||this.dependenciesMeta.set(t,n=new Map);let s=n.get(i);return s||n.set(i,s={}),s}ensurePeerDependencyMeta(e){if(e.range!=="unknown")throw new Error(`Invalid meta field range for '${Sn(e)}'`);let t=Tt(e),i=this.peerDependenciesMeta.get(t);return i||this.peerDependenciesMeta.set(t,i={}),i}setRawField(e,t,{after:i=[]}={}){let n=new Set(i.filter(s=>Object.prototype.hasOwnProperty.call(this.raw,s)));if(n.size===0||Object.prototype.hasOwnProperty.call(this.raw,e))this.raw[e]=t;else{let s=this.raw,o=this.raw={},a=!1;for(let l of Object.keys(s))o[l]=s[l],a||(n.delete(l),n.size===0&&(o[e]=t,a=!0))}}exportTo(e,{compatibilityMode:t=!0}={}){var s;if(Object.assign(e,this.raw),this.name!==null?e.name=Tt(this.name):delete e.name,this.version!==null?e.version=this.version:delete e.version,this.os!==null?e.os=this.os:delete e.os,this.cpu!==null?e.cpu=this.cpu:delete e.cpu,this.type!==null?e.type=this.type:delete e.type,this.packageManager!==null?e.packageManager=this.packageManager:delete e.packageManager,this.private?e.private=!0:delete e.private,this.license!==null?e.license=this.license:delete e.license,this.languageName!==null?e.languageName=this.languageName:delete e.languageName,this.main!==null?e.main=this.main:delete e.main,this.module!==null?e.module=this.module:delete e.module,this.browser!==null){let o=this.browser;typeof o=="string"?e.browser=o:o instanceof Map&&(e.browser=Object.assign({},...Array.from(o.keys()).sort().map(a=>({[a]:o.get(a)}))))}else delete e.browser;this.bin.size===1&&this.name!==null&&this.bin.has(this.name.name)?e.bin=this.bin.get(this.name.name):this.bin.size>0?e.bin=Object.assign({},...Array.from(this.bin.keys()).sort().map(o=>({[o]:this.bin.get(o)}))):delete e.bin,this.workspaceDefinitions.length>0?this.raw.workspaces&&!Array.isArray(this.raw.workspaces)?e.workspaces={...this.raw.workspaces,packages:this.workspaceDefinitions.map(({pattern:o})=>o)}:e.workspaces=this.workspaceDefinitions.map(({pattern:o})=>o):this.raw.workspaces&&!Array.isArray(this.raw.workspaces)&&Object.keys(this.raw.workspaces).length>0?e.workspaces=this.raw.workspaces:delete e.workspaces;let i=[],n=[];for(let o of this.dependencies.values()){let a=this.dependenciesMeta.get(Tt(o)),l=!1;if(t&&a){let c=a.get(null);c&&c.optional&&(l=!0)}l?n.push(o):i.push(o)}i.length>0?e.dependencies=Object.assign({},...xf(i).map(o=>({[Tt(o)]:o.range}))):delete e.dependencies,n.length>0?e.optionalDependencies=Object.assign({},...xf(n).map(o=>({[Tt(o)]:o.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...xf(this.devDependencies.values()).map(o=>({[Tt(o)]:o.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...xf(this.peerDependencies.values()).map(o=>({[Tt(o)]:o.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(let[o,a]of bn(this.dependenciesMeta.entries(),([l,c])=>l))for(let[l,c]of bn(a.entries(),([u,g])=>u!==null?`0${u}`:"1")){let u=l!==null?Sn(zt(en(o),l)):o,g={...c};t&&l===null&&delete g.optional,Object.keys(g).length!==0&&(e.dependenciesMeta[u]=g)}if(Object.keys(e.dependenciesMeta).length===0&&delete e.dependenciesMeta,this.peerDependenciesMeta.size>0?e.peerDependenciesMeta=Object.assign({},...bn(this.peerDependenciesMeta.entries(),([o,a])=>o).map(([o,a])=>({[o]:a}))):delete e.peerDependenciesMeta,this.resolutions.length>0?e.resolutions=Object.assign({},...this.resolutions.map(({pattern:o,reference:a})=>({[hI(o)]:a}))):delete e.resolutions,this.files!==null?e.files=Array.from(this.files):delete e.files,this.preferUnplugged!==null?e.preferUnplugged=this.preferUnplugged:delete e.preferUnplugged,this.scripts!==null&&this.scripts.size>0){(s=e.scripts)!=null||(e.scripts={});for(let o of Object.keys(e.scripts))this.scripts.has(o)||delete e.scripts[o];for(let[o,a]of this.scripts.entries())e.scripts[o]=a}else delete e.scripts;return e}},ot=WA;ot.fileName="package.json",ot.allDependencies=["dependencies","devDependencies","peerDependencies"],ot.hardDependencies=["dependencies","devDependencies"];function T8(r){let e=r.match(/^[ \t]+/m);return e?e[0]:" "}function L8(r){return r.charCodeAt(0)===65279?r.slice(1):r}function nn(r){return r.replace(/\\/g,"/")}function Rw(r,{yamlCompatibilityMode:e}){return e?zP(r):typeof r>"u"||typeof r=="boolean"?r:null}function O8(r,e){let t=e.search(/[^!]/);if(t===-1)return"invalid";let i=t%2===0?"":"!",n=e.slice(t);return`${i}${r}=${n}`}function Jk(r,e){return e.length===1?O8(r,e[0]):`(${e.map(t=>O8(r,t)).join(" | ")})`}var pz=ve(hz()),dz=J("stream"),Cz=J("string_decoder");var jve=15,rt=class extends Error{constructor(t,i,n){super(i);this.reportExtra=n;this.reportCode=t}};function Gve(r){return typeof r.reportCode<"u"}var Pi=class{constructor(){this.reportedInfos=new Set;this.reportedWarnings=new Set;this.reportedErrors=new Set}static progressViaCounter(e){let t=0,i,n=new Promise(l=>{i=l}),s=l=>{let c=i;n=new Promise(u=>{i=u}),t=l,c()},o=(l=0)=>{s(t+1)},a=async function*(){for(;t<e;)await n,yield{progress:t/e}}();return{[Symbol.asyncIterator](){return a},hasProgress:!0,hasTitle:!1,set:s,tick:o}}static progressViaTitle(){let e,t,i=new Promise(o=>{t=o}),n=(0,pz.default)(o=>{let a=t;i=new Promise(l=>{t=l}),e=o,a()},1e3/jve),s=async function*(){for(;;)await i,yield{title:e}}();return{[Symbol.asyncIterator](){return s},hasProgress:!1,hasTitle:!0,setTitle:n}}async startProgressPromise(e,t){let i=this.reportProgress(e);try{return await t(e)}finally{i.stop()}}startProgressSync(e,t){let i=this.reportProgress(e);try{return t(e)}finally{i.stop()}}reportInfoOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedInfos.has(n)||(this.reportedInfos.add(n),this.reportInfo(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportWarningOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedWarnings.has(n)||(this.reportedWarnings.add(n),this.reportWarning(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportErrorOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedErrors.has(n)||(this.reportedErrors.add(n),this.reportError(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportExceptionOnce(e){Gve(e)?this.reportErrorOnce(e.reportCode,e.message,{key:e,reportExtra:e.reportExtra}):this.reportErrorOnce(1,e.stack||e.message,{key:e})}createStreamReporter(e=null){let t=new dz.PassThrough,i=new Cz.StringDecoder,n="";return t.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` +`),a!==-1){let l=n+o.substring(0,a);o=o.substring(a+1),n="",e!==null?this.reportInfo(null,`${e} ${l}`):this.reportInfo(null,l)}while(a!==-1);n+=o}),t.on("end",()=>{let s=i.end();s!==""&&(e!==null?this.reportInfo(null,`${e} ${s}`):this.reportInfo(null,s))}),t}};var kf=class{constructor(e){this.fetchers=e}supports(e,t){return!!this.tryFetcher(e,t)}getLocalPath(e,t){return this.getFetcher(e,t).getLocalPath(e,t)}async fetch(e,t){return await this.getFetcher(e,t).fetch(e,t)}tryFetcher(e,t){let i=this.fetchers.find(n=>n.supports(e,t));return i||null}getFetcher(e,t){let i=this.fetchers.find(n=>n.supports(e,t));if(!i)throw new rt(11,`${Ct(t.project.configuration,e)} isn't supported by any available fetcher`);return i}};var Df=class{constructor(e){this.resolvers=e.filter(t=>t)}supportsDescriptor(e,t){return!!this.tryResolverByDescriptor(e,t)}supportsLocator(e,t){return!!this.tryResolverByLocator(e,t)}shouldPersistResolution(e,t){return this.getResolverByLocator(e,t).shouldPersistResolution(e,t)}bindDescriptor(e,t,i){return this.getResolverByDescriptor(e,i).bindDescriptor(e,t,i)}getResolutionDependencies(e,t){return this.getResolverByDescriptor(e,t).getResolutionDependencies(e,t)}async getCandidates(e,t,i){return await this.getResolverByDescriptor(e,i).getCandidates(e,t,i)}async getSatisfying(e,t,i){return this.getResolverByDescriptor(e,i).getSatisfying(e,t,i)}async resolve(e,t){return await this.getResolverByLocator(e,t).resolve(e,t)}tryResolverByDescriptor(e,t){let i=this.resolvers.find(n=>n.supportsDescriptor(e,t));return i||null}getResolverByDescriptor(e,t){let i=this.resolvers.find(n=>n.supportsDescriptor(e,t));if(!i)throw new Error(`${$t(t.project.configuration,e)} isn't supported by any available resolver`);return i}tryResolverByLocator(e,t){let i=this.resolvers.find(n=>n.supportsLocator(e,t));return i||null}getResolverByLocator(e,t){let i=this.resolvers.find(n=>n.supportsLocator(e,t));if(!i)throw new Error(`${Ct(t.project.configuration,e)} isn't supported by any available resolver`);return i}};var mz=ve(zr());var Rf=/^(?!v)[a-z0-9._-]+$/i,Fw=class{supportsDescriptor(e,t){return!!(no(e.range)||Rf.test(e.range))}supportsLocator(e,t){return!!(mz.default.valid(e.reference)||Rf.test(e.reference))}shouldPersistResolution(e,t){return t.resolver.shouldPersistResolution(this.forwardLocator(e,t),t)}bindDescriptor(e,t,i){return i.resolver.bindDescriptor(this.forwardDescriptor(e,i),t,i)}getResolutionDependencies(e,t){return t.resolver.getResolutionDependencies(this.forwardDescriptor(e,t),t)}async getCandidates(e,t,i){return await i.resolver.getCandidates(this.forwardDescriptor(e,i),t,i)}async getSatisfying(e,t,i){return await i.resolver.getSatisfying(this.forwardDescriptor(e,i),t,i)}async resolve(e,t){let i=await t.resolver.resolve(this.forwardLocator(e,t),t);return rC(i,e)}forwardDescriptor(e,t){return zt(e,`${t.project.configuration.get("defaultProtocol")}${e.range}`)}forwardLocator(e,t){return rn(e,`${t.project.configuration.get("defaultProtocol")}${e.reference}`)}};var Ff=class{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,t){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=rn(e,n);return t.fetcher.getLocalPath(s,t)}async fetch(e,t){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=rn(e,n),o=await t.fetcher.fetch(s,t);return await this.ensureVirtualLink(e,o,t)}getLocatorFilename(e){return Pf(e)}async ensureVirtualLink(e,t,i){let n=t.packageFs.getRealPath(),s=i.project.configuration.get("virtualFolder"),o=this.getLocatorFilename(e),a=yr.makeVirtualPath(s,o,n),l=new Qo(a,{baseFs:t.packageFs,pathUtils:v});return{...t,packageFs:l}}};var Nf=class{static isVirtualDescriptor(e){return!!e.range.startsWith(Nf.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(Nf.protocol)}supportsDescriptor(e,t){return Nf.isVirtualDescriptor(e)}supportsLocator(e,t){return Nf.isVirtualLocator(e)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,t){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,t,i){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,t,i){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,t){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}},hC=Nf;hC.protocol="virtual:";var Tf=class{supports(e){return!!e.reference.startsWith(Ur.protocol)}getLocalPath(e,t){return this.getWorkspace(e,t).cwd}async fetch(e,t){let i=this.getWorkspace(e,t).cwd;return{packageFs:new jt(i),prefixPath:Te.dot,localPath:i}}getWorkspace(e,t){return t.project.getWorkspaceByCwd(e.reference.slice(Ur.protocol.length))}};var Nw={};ct(Nw,{getDefaultGlobalFolder:()=>Xk,getHomeFolder:()=>pC,isFolderInside:()=>Zk});var Vk=J("os");function Xk(){if(process.platform==="win32"){let r=K.toPortablePath(process.env.LOCALAPPDATA||K.join((0,Vk.homedir)(),"AppData","Local"));return v.resolve(r,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){let r=K.toPortablePath(process.env.XDG_DATA_HOME);return v.resolve(r,"yarn/berry")}return v.resolve(pC(),".yarn/berry")}function pC(){return K.toPortablePath((0,Vk.homedir)()||"/usr/local/share")}function Zk(r,e){let t=v.relative(e,r);return t&&!t.startsWith("..")&&!v.isAbsolute(t)}var ys={};ct(ys,{availableParallelism:()=>eD,builtinModules:()=>_k,getArchitecture:()=>dC,getArchitectureName:()=>Wve,getArchitectureSet:()=>$k,openUrl:()=>Yve});var Iz=ve(J("module")),Ow=ve(J("os"));var Ez=new Map([["darwin","open"],["linux","xdg-open"],["win32","explorer.exe"]]).get(process.platform),Yve=typeof Ez<"u"?async r=>{try{return await tD(Ez,[r],{cwd:v.cwd()}),!0}catch{return!1}}:void 0;function _k(){return new Set(Iz.default.builtinModules||Object.keys(process.binding("natives")))}var qve="/usr/bin/ldd";function Jve(){var n,s,o,a;if(process.platform==="win32")return null;let r;try{r=M.readFileSync(qve)}catch{}if(typeof r<"u"){if(r&&r.includes("GLIBC"))return"glibc";if(r&&r.includes("musl"))return"musl"}let t=(o=((s=(n=process.report)==null?void 0:n.getReport())!=null?s:{}).sharedObjects)!=null?o:[],i=/\/(?:(ld-linux-|[^/]+-linux-gnu\/)|(libc.musl-|ld-musl-))/;return(a=Wd(t,l=>{let c=l.match(i);if(!c)return Wd.skip;if(c[1])return"glibc";if(c[2])return"musl";throw new Error("Assertion failed: Expected the libc variant to have been detected")}))!=null?a:null}var Tw,Lw;function dC(){return Tw=Tw!=null?Tw:{os:process.platform,cpu:process.arch,libc:Jve()}}function Wve(r=dC()){return r.libc?`${r.os}-${r.cpu}-${r.libc}`:`${r.os}-${r.cpu}`}function $k(){let r=dC();return Lw=Lw!=null?Lw:{os:[r.os],cpu:[r.cpu],libc:r.libc?[r.libc]:[]}}function eD(){return"availableParallelism"in Ow.default?Ow.default.availableParallelism():Math.max(1,Ow.default.cpus().length)}var zve=new Set(["isTestEnv","injectNpmUser","injectNpmPassword","injectNpm2FaToken","binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput","home","confDir","registry"]),Hw="yarn_",sD=".yarnrc.yml",oD="yarn.lock",Vve="********",aD=(u=>(u.ANY="ANY",u.BOOLEAN="BOOLEAN",u.ABSOLUTE_PATH="ABSOLUTE_PATH",u.LOCATOR="LOCATOR",u.LOCATOR_LOOSE="LOCATOR_LOOSE",u.NUMBER="NUMBER",u.STRING="STRING",u.SECRET="SECRET",u.SHAPE="SHAPE",u.MAP="MAP",u))(aD||{}),Bz=Ke,rD={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:"STRING",default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:"ABSOLUTE_PATH",default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:"BOOLEAN",default:!1},ignoreCwd:{description:"If true, the `--cwd` flag will be ignored",type:"BOOLEAN",default:!1},cacheKeyOverride:{description:"A global cache key override; used only for test purposes",type:"STRING",default:null},globalFolder:{description:"Folder where all system-global files are stored",type:"ABSOLUTE_PATH",default:Xk()},cacheFolder:{description:"Folder where the cache files must be written",type:"ABSOLUTE_PATH",default:"./.yarn/cache"},compressionLevel:{description:"Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)",type:"NUMBER",values:["mixed",0,1,2,3,4,5,6,7,8,9],default:_l},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named __virtual__)",type:"ABSOLUTE_PATH",default:"./.yarn/__virtual__"},lockfileFilename:{description:"Name of the files where the Yarn dependency tree entries must be stored",type:"STRING",default:oD},installStatePath:{description:"Path of the file where the install state will be persisted",type:"ABSOLUTE_PATH",default:"./.yarn/install-state.gz"},immutablePatterns:{description:"Array of glob patterns; files matching them won't be allowed to change during immutable installs",type:"STRING",default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:"STRING",default:Uw()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:"BOOLEAN",default:!1},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:"BOOLEAN",default:Wy,defaultText:"<dynamic>"},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:"BOOLEAN",default:ex,defaultText:"<dynamic>"},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:"BOOLEAN",default:Mw.isCI,defaultText:"<dynamic>"},enableMessageNames:{description:"If true, the CLI will prefix most messages with codes suitable for search engines",type:"BOOLEAN",default:!0},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:"BOOLEAN",default:!Mw.isCI,defaultText:"<dynamic>"},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:"BOOLEAN",default:!0},preferAggregateCacheInfo:{description:"If true, the CLI will only print a one-line report of any cache changes",type:"BOOLEAN",default:Mw.isCI},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:"BOOLEAN",default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:"BOOLEAN",default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:"STRING",default:void 0,defaultText:"<dynamic>"},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:"STRING",default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:"STRING",default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:"BOOLEAN",default:!0},supportedArchitectures:{description:"Architectures that Yarn will fetch and inject into the resolver",type:"SHAPE",properties:{os:{description:"Array of supported process.platform strings, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]},cpu:{description:"Array of supported process.arch strings, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]},libc:{description:"Array of supported libc libraries, or null to target them all",type:"STRING",isArray:!0,isNullable:!0,default:["current"]}}},enableMirror:{description:"If true, the downloaded packages will be retrieved and stored in both the local and global folders",type:"BOOLEAN",default:!0},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:"BOOLEAN",default:!0},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:"STRING",default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:"STRING",default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:"STRING",default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:"NUMBER",default:6e4},httpRetry:{description:"Retry times on http failure",type:"NUMBER",default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:"NUMBER",default:50},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:"MAP",valueDefinition:{description:"",type:"SHAPE",properties:{caFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:"ABSOLUTE_PATH",default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:"BOOLEAN",default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:"STRING",default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:"STRING",default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:"ABSOLUTE_PATH",default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:"ABSOLUTE_PATH",default:null}}}},caFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:"ABSOLUTE_PATH",default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:"ABSOLUTE_PATH",default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:"ABSOLUTE_PATH",default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:"BOOLEAN",default:!0},logFilters:{description:"Overrides for log levels",type:"SHAPE",isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:"STRING",default:void 0},text:{description:"Code of the texts covered by this override",type:"STRING",default:void 0},pattern:{description:"Code of the patterns covered by this override",type:"STRING",default:void 0},level:{description:"Log level override, set to null to remove override",type:"STRING",values:Object.values(Vy),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:"BOOLEAN",default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:"NUMBER",default:7},telemetryUserId:{description:"If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.",type:"STRING",default:null},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:"BOOLEAN",default:!0},enableStrictSettings:{description:"If true, unknown settings will cause Yarn to abort",type:"BOOLEAN",default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:"BOOLEAN",default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:"STRING",default:"throw"},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:"MAP",valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:"SHAPE",properties:{dependencies:{description:"The set of dependencies that must be made available to the current package in order for it to work properly",type:"MAP",valueDefinition:{description:"A range",type:"STRING"}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:"MAP",valueDefinition:{description:"A semver range",type:"STRING"}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:"MAP",valueDefinition:{description:"The peerDependency meta",type:"SHAPE",properties:{optional:{description:"If true, the selected peer dependency will be marked as optional by the package manager and the consumer omitting it won't be reported as an error",type:"BOOLEAN",default:!1}}}}}}}};function AD(r,e,t,i,n){if(i.isArray||i.type==="ANY"&&Array.isArray(t))return Array.isArray(t)?t.map((s,o)=>iD(r,`${e}[${o}]`,s,i,n)):String(t).split(/,/).map(s=>iD(r,e,s,i,n));if(Array.isArray(t))throw new Error(`Non-array configuration settings "${e}" cannot be an array`);return iD(r,e,t,i,n)}function iD(r,e,t,i,n){var a;switch(i.type){case"ANY":return t;case"SHAPE":return Xve(r,e,t,i,n);case"MAP":return Zve(r,e,t,i,n)}if(t===null&&!i.isNullable&&i.default!==null)throw new Error(`Non-nullable configuration settings "${e}" cannot be set to null`);if((a=i.values)!=null&&a.includes(t))return t;let o=(()=>{if(i.type==="BOOLEAN"&&typeof t!="string")return zd(t);if(typeof t!="string")throw new Error(`Expected configuration setting "${e}" to be a string, got ${typeof t}`);let l=WP(t,{env:process.env});switch(i.type){case"ABSOLUTE_PATH":return v.resolve(n,K.toPortablePath(l));case"LOCATOR_LOOSE":return Rc(l,!1);case"NUMBER":return parseInt(l);case"LOCATOR":return Rc(l);case"BOOLEAN":return zd(l);default:return l}})();if(i.values&&!i.values.includes(o))throw new Error(`Invalid value, expected one of ${i.values.join(", ")}`);return o}function Xve(r,e,t,i,n){if(typeof t!="object"||Array.isArray(t))throw new we(`Object configuration settings "${e}" must be an object`);let s=lD(r,i,{ignoreArrays:!0});if(t===null)return s;for(let[o,a]of Object.entries(t)){let l=`${e}.${o}`;if(!i.properties[o])throw new we(`Unrecognized configuration settings found: ${e}.${o} - run "yarn config -v" to see the list of settings supported in Yarn`);s.set(o,AD(r,l,a,i.properties[o],n))}return s}function Zve(r,e,t,i,n){let s=new Map;if(typeof t!="object"||Array.isArray(t))throw new we(`Map configuration settings "${e}" must be an object`);if(t===null)return s;for(let[o,a]of Object.entries(t)){let l=i.normalizeKeys?i.normalizeKeys(o):o,c=`${e}['${l}']`,u=i.valueDefinition;s.set(l,AD(r,c,a,u,n))}return s}function lD(r,e,{ignoreArrays:t=!1}={}){switch(e.type){case"SHAPE":{if(e.isArray&&!t)return[];let i=new Map;for(let[n,s]of Object.entries(e.properties))i.set(n,lD(r,s));return i}break;case"MAP":return e.isArray&&!t?[]:new Map;case"ABSOLUTE_PATH":return e.default===null?null:r.projectCwd===null?v.isAbsolute(e.default)?v.normalize(e.default):e.isNullable?null:void 0:Array.isArray(e.default)?e.default.map(i=>v.resolve(r.projectCwd,i)):v.resolve(r.projectCwd,e.default);default:return e.default}}function Kw(r,e,t){if(e.type==="SECRET"&&typeof r=="string"&&t.hideSecrets)return Vve;if(e.type==="ABSOLUTE_PATH"&&typeof r=="string"&&t.getNativePaths)return K.fromPortablePath(r);if(e.isArray&&Array.isArray(r)){let i=[];for(let n of r)i.push(Kw(n,e,t));return i}if(e.type==="MAP"&&r instanceof Map){let i=new Map;for(let[n,s]of r.entries())i.set(n,Kw(s,e.valueDefinition,t));return i}if(e.type==="SHAPE"&&r instanceof Map){let i=new Map;for(let[n,s]of r.entries()){let o=e.properties[n];i.set(n,Kw(s,o,t))}return i}return r}function _ve(){let r={};for(let[e,t]of Object.entries(process.env))e=e.toLowerCase(),e.startsWith(Hw)&&(e=(0,yz.default)(e.slice(Hw.length)),r[e]=t);return r}function Uw(){let r=`${Hw}rc_filename`;for(let[e,t]of Object.entries(process.env))if(e.toLowerCase()===r&&typeof t=="string")return t;return sD}var cD=(i=>(i[i.LOCKFILE=0]="LOCKFILE",i[i.MANIFEST=1]="MANIFEST",i[i.NONE=2]="NONE",i))(cD||{}),ja=class{constructor(e){this.projectCwd=null;this.plugins=new Map;this.settings=new Map;this.values=new Map;this.sources=new Map;this.invalid=new Map;this.packageExtensions=new Map;this.limits=new Map;this.startingCwd=e}static create(e,t,i){let n=new ja(e);typeof t<"u"&&!(t instanceof Map)&&(n.projectCwd=t),n.importSettings(rD);let s=typeof i<"u"?i:t instanceof Map?t:new Map;for(let[o,a]of s)n.activatePlugin(o,a);return n}static async find(e,t,{lookup:i=0,strict:n=!0,usePath:s=!1,useRc:o=!0}={}){let a=_ve();delete a.rcFilename;let l=await ja.findRcFiles(e),c=await ja.findHomeRcFile();if(c){let B=l.find(S=>S.path===c.path);B?B.strict=!1:l.push({...c,strict:!1})}let u=({ignoreCwd:B,yarnPath:S,ignorePath:x,lockfileFilename:F})=>({ignoreCwd:B,yarnPath:S,ignorePath:x,lockfileFilename:F}),g=({ignoreCwd:B,yarnPath:S,ignorePath:x,lockfileFilename:F,...H})=>H,h=new ja(e);h.importSettings(u(rD)),h.useWithSource("<environment>",u(a),e,{strict:!1});for(let{path:B,cwd:S,data:x}of l)h.useWithSource(B,u(x),S,{strict:!1});if(s){let B=h.get("yarnPath"),S=h.get("ignorePath");if(B!==null&&!S)return h}let p=h.get("lockfileFilename"),d;switch(i){case 0:d=await ja.findProjectCwd(e,p);break;case 1:d=await ja.findProjectCwd(e,null);break;case 2:M.existsSync(v.join(e,"package.json"))?d=v.resolve(e):d=null;break}h.startingCwd=e,h.projectCwd=d,h.importSettings(g(rD));let m=new Map([["@@core",D8]]),y=B=>"default"in B?B.default:B;if(t!==null){for(let F of t.plugins.keys())m.set(F,y(t.modules.get(F)));let B=new Map;for(let F of _k())B.set(F,()=>mf(F));for(let[F,H]of t.modules)B.set(F,()=>H);let S=new Set,x=async(F,H)=>{let{factory:q,name:_}=mf(F);if(S.has(_))return;let X=new Map(B),W=A=>{if(X.has(A))return X.get(A)();throw new we(`This plugin cannot access the package referenced via ${A} which is neither a builtin, nor an exposed entry`)},Z=await df(async()=>y(await q(W)),A=>`${A} (when initializing ${_}, defined in ${H})`);B.set(_,()=>Z),S.add(_),m.set(_,Z)};if(a.plugins)for(let F of a.plugins.split(";")){let H=v.resolve(e,K.toPortablePath(F));await x(H,"<environment>")}for(let{path:F,cwd:H,data:q}of l)if(!!o&&!!Array.isArray(q.plugins))for(let _ of q.plugins){let X=typeof _!="string"?_.path:_,W=v.resolve(H,K.toPortablePath(X));await x(W,F)}}for(let[B,S]of m)h.activatePlugin(B,S);h.useWithSource("<environment>",g(a),e,{strict:n});for(let{path:B,cwd:S,data:x,strict:F}of l)h.useWithSource(B,g(x),S,{strict:F!=null?F:n});return h.get("enableGlobalCache")&&(h.values.set("cacheFolder",`${h.get("globalFolder")}/cache`),h.sources.set("cacheFolder","<internal>")),await h.refreshPackageExtensions(),h}static async findRcFiles(e){let t=Uw(),i=[],n=e,s=null;for(;n!==s;){s=n;let o=v.join(s,t);if(M.existsSync(o)){let a=await M.readFilePromise(o,"utf8"),l;try{l=wi(a)}catch{let u="";throw a.match(/^\s+(?!-)[^:]+\s+\S+/m)&&(u=" (in particular, make sure you list the colons after each key name)"),new we(`Parse error when loading ${o}; please check it's proper Yaml${u}`)}i.push({path:o,cwd:s,data:l})}n=v.dirname(s)}return i}static async findHomeRcFile(){let e=Uw(),t=pC(),i=v.join(t,e);if(M.existsSync(i)){let n=await M.readFilePromise(i,"utf8"),s=wi(n);return{path:i,cwd:t,data:s}}return null}static async findProjectCwd(e,t){let i=null,n=e,s=null;for(;n!==s;){if(s=n,M.existsSync(v.join(s,"package.json"))&&(i=s),t!==null){if(M.existsSync(v.join(s,t))){i=s;break}}else if(i!==null)break;n=v.dirname(s)}return i}static async updateConfiguration(e,t){let i=Uw(),n=v.join(e,i),s=M.existsSync(n)?wi(await M.readFilePromise(n,"utf8")):{},o=!1,a;if(typeof t=="function"){try{a=t(s)}catch{a=t({})}if(a===s)return}else{a=s;for(let l of Object.keys(t)){let c=s[l],u=t[l],g;if(typeof u=="function")try{g=u(c)}catch{g=u(void 0)}else g=u;c!==g&&(a[l]=g,o=!0)}if(!o)return}await M.changeFilePromise(n,Qa(a),{automaticNewlines:!0})}static async updateHomeConfiguration(e){let t=pC();return await ja.updateConfiguration(t,e)}activatePlugin(e,t){this.plugins.set(e,t),typeof t.configuration<"u"&&this.importSettings(t.configuration)}importSettings(e){for(let[t,i]of Object.entries(e))if(i!=null){if(this.settings.has(t))throw new Error(`Cannot redefine settings "${t}"`);this.settings.set(t,i),this.values.set(t,lD(this,i))}}useWithSource(e,t,i,n){try{this.use(e,t,i,n)}catch(s){throw s.message+=` (in ${_e(this,e,Ke.PATH)})`,s}}use(e,t,i,{strict:n=!0,overwrite:s=!1}={}){n=n&&this.get("enableStrictSettings");for(let o of["enableStrictSettings",...Object.keys(t)]){if(typeof t[o]>"u"||o==="plugins"||e==="<environment>"&&zve.has(o))continue;if(o==="rcFilename")throw new we(`The rcFilename settings can only be set via ${`${Hw}RC_FILENAME`.toUpperCase()}, not via a rc file`);let l=this.settings.get(o);if(!l){if(n)throw new we(`Unrecognized or legacy configuration settings found: ${o} - run "yarn config -v" to see the list of settings supported in Yarn`);this.invalid.set(o,e);continue}if(this.sources.has(o)&&!(s||l.type==="MAP"||l.isArray&&l.concatenateValues))continue;let c;try{c=AD(this,o,t[o],l,i)}catch(u){throw u.message+=` in ${_e(this,e,Ke.PATH)}`,u}if(o==="enableStrictSettings"&&e!=="<environment>"){n=c;continue}if(l.type==="MAP"){let u=this.values.get(o);this.values.set(o,new Map(s?[...u,...c]:[...c,...u])),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else if(l.isArray&&l.concatenateValues){let u=this.values.get(o);this.values.set(o,s?[...u,...c]:[...c,...u]),this.sources.set(o,`${this.sources.get(o)}, ${e}`)}else this.values.set(o,c),this.sources.set(o,e)}}get(e){if(!this.values.has(e))throw new Error(`Invalid configuration key "${e}"`);return this.values.get(e)}getSpecial(e,{hideSecrets:t=!1,getNativePaths:i=!1}){let n=this.get(e),s=this.settings.get(e);if(typeof s>"u")throw new we(`Couldn't find a configuration settings named "${e}"`);return Kw(n,s,{hideSecrets:t,getNativePaths:i})}getSubprocessStreams(e,{header:t,prefix:i,report:n}){let s,o,a=M.createWriteStream(e);if(this.get("enableInlineBuilds")){let l=n.createStreamReporter(`${i} ${_e(this,"STDOUT","green")}`),c=n.createStreamReporter(`${i} ${_e(this,"STDERR","red")}`);s=new nD.PassThrough,s.pipe(l),s.pipe(a),o=new nD.PassThrough,o.pipe(c),o.pipe(a)}else s=a,o=a,typeof t<"u"&&s.write(`${t} +`);return{stdout:s,stderr:o}}makeResolver(){let e=[];for(let t of this.plugins.values())for(let i of t.resolvers||[])e.push(new i);return new Df([new hC,new Ur,new Fw,...e])}makeFetcher(){let e=[];for(let t of this.plugins.values())for(let i of t.fetchers||[])e.push(new i);return new kf([new Ff,new Tf,...e])}getLinkers(){let e=[];for(let t of this.plugins.values())for(let i of t.linkers||[])e.push(new i);return e}getSupportedArchitectures(){let e=dC(),t=this.get("supportedArchitectures"),i=t.get("os");i!==null&&(i=i.map(o=>o==="current"?e.os:o));let n=t.get("cpu");n!==null&&(n=n.map(o=>o==="current"?e.cpu:o));let s=t.get("libc");return s!==null&&(s=Uo(s,o=>{var a;return o==="current"?(a=e.libc)!=null?a:Uo.skip:o})),{os:i,cpu:n,libc:s}}async refreshPackageExtensions(){this.packageExtensions=new Map;let e=this.packageExtensions,t=(i,n,{userProvided:s=!1}={})=>{if(!no(i.range))throw new Error("Only semver ranges are allowed as keys for the packageExtensions setting");let o=new ot;o.load(n,{yamlCompatibilityMode:!0});let a=hf(e,i.identHash),l=[];a.push([i.range,l]);let c={status:"inactive",userProvided:s,parentDescriptor:i};for(let u of o.dependencies.values())l.push({...c,type:"Dependency",descriptor:u});for(let u of o.peerDependencies.values())l.push({...c,type:"PeerDependency",descriptor:u});for(let[u,g]of o.peerDependenciesMeta)for(let[h,p]of Object.entries(g))l.push({...c,type:"PeerDependencyMeta",selector:u,key:h,value:p})};await this.triggerHook(i=>i.registerPackageExtensions,this,t);for(let[i,n]of this.get("packageExtensions"))t(JA(i,!0),qy(n),{userProvided:!0})}normalizePackage(e){let t=iC(e);if(this.packageExtensions==null)throw new Error("refreshPackageExtensions has to be called before normalizing packages");let i=this.packageExtensions.get(e.identHash);if(typeof i<"u"){let s=e.version;if(s!==null){for(let[o,a]of i)if(!!Fc(s,o))for(let l of a)switch(l.status==="inactive"&&(l.status="redundant"),l.type){case"Dependency":typeof t.dependencies.get(l.descriptor.identHash)>"u"&&(l.status="active",t.dependencies.set(l.descriptor.identHash,l.descriptor));break;case"PeerDependency":typeof t.peerDependencies.get(l.descriptor.identHash)>"u"&&(l.status="active",t.peerDependencies.set(l.descriptor.identHash,l.descriptor));break;case"PeerDependencyMeta":{let c=t.peerDependenciesMeta.get(l.selector);(typeof c>"u"||!Object.prototype.hasOwnProperty.call(c,l.key)||c[l.key]!==l.value)&&(l.status="active",La(t.peerDependenciesMeta,l.selector,()=>({}))[l.key]=l.value)}break;default:qP(l);break}}}let n=s=>s.scope?`${s.scope}__${s.name}`:`${s.name}`;for(let s of t.peerDependenciesMeta.keys()){let o=en(s);t.peerDependencies.has(o.identHash)||t.peerDependencies.set(o.identHash,zt(o,"*"))}for(let s of t.peerDependencies.values()){if(s.scope==="types")continue;let o=n(s),a=qo("types",o),l=Tt(a);t.peerDependencies.has(a.identHash)||t.peerDependenciesMeta.has(l)||(t.peerDependencies.set(a.identHash,zt(a,"*")),t.peerDependenciesMeta.set(l,{optional:!0}))}return t.dependencies=new Map(bn(t.dependencies,([,s])=>Sn(s))),t.peerDependencies=new Map(bn(t.peerDependencies,([,s])=>Sn(s))),t}getLimit(e){return La(this.limits,e,()=>(0,wz.default)(this.get(e)))}async triggerHook(e,...t){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);!s||await s(...t)}}async triggerMultipleHooks(e,t){for(let i of t)await this.triggerHook(e,...i)}async reduceHook(e,t,...i){let n=t;for(let s of this.plugins.values()){let o=s.hooks;if(!o)continue;let a=e(o);!a||(n=await a(n,...i))}return n}async firstHook(e,...t){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);if(!s)continue;let o=await s(...t);if(typeof o<"u")return o}return null}},Ee=ja;Ee.telemetry=null;var hD=(i=>(i[i.Never=0]="Never",i[i.ErrorCode=1]="ErrorCode",i[i.Always=2]="Always",i))(hD||{}),CC=class extends rt{constructor({fileName:t,code:i,signal:n}){let s=Ee.create(v.cwd()),o=_e(s,t,Ke.PATH);super(1,`Child ${o} reported an error`,a=>{ePe(i,n,{configuration:s,report:a})});this.code=pD(i,n)}},jw=class extends CC{constructor({fileName:t,code:i,signal:n,stdout:s,stderr:o}){super({fileName:t,code:i,signal:n});this.stdout=s,this.stderr=o}};function Lc(r){return r!==null&&typeof r.fd=="number"}var Oc=new Set;function uD(){}function gD(){for(let r of Oc)r.kill()}async function so(r,e,{cwd:t,env:i=process.env,strict:n=!1,stdin:s=null,stdout:o,stderr:a,end:l=2}){let c=["pipe","pipe","pipe"];s===null?c[0]="ignore":Lc(s)&&(c[0]=s),Lc(o)&&(c[1]=o),Lc(a)&&(c[2]=a);let u=(0,fD.default)(r,e,{cwd:K.fromPortablePath(t),env:{...i,PWD:K.fromPortablePath(t)},stdio:c});Oc.add(u),Oc.size===1&&(process.on("SIGINT",uD),process.on("SIGTERM",gD)),!Lc(s)&&s!==null&&s.pipe(u.stdin),Lc(o)||u.stdout.pipe(o,{end:!1}),Lc(a)||u.stderr.pipe(a,{end:!1});let g=()=>{for(let h of new Set([o,a]))Lc(h)||h.end()};return new Promise((h,p)=>{u.on("error",d=>{Oc.delete(u),Oc.size===0&&(process.off("SIGINT",uD),process.off("SIGTERM",gD)),(l===2||l===1)&&g(),p(d)}),u.on("close",(d,m)=>{Oc.delete(u),Oc.size===0&&(process.off("SIGINT",uD),process.off("SIGTERM",gD)),(l===2||l===1&&d!==0)&&g(),d===0||!n?h({code:pD(d,m)}):p(new CC({fileName:r,code:d,signal:m}))})})}async function tD(r,e,{cwd:t,env:i=process.env,encoding:n="utf8",strict:s=!1}){let o=["ignore","pipe","pipe"],a=[],l=[],c=K.fromPortablePath(t);typeof i.PWD<"u"&&(i={...i,PWD:c});let u=(0,fD.default)(r,e,{cwd:c,env:i,stdio:o});return u.stdout.on("data",g=>{a.push(g)}),u.stderr.on("data",g=>{l.push(g)}),await new Promise((g,h)=>{u.on("error",p=>{let d=Ee.create(t),m=_e(d,r,Ke.PATH);h(new rt(1,`Process ${m} failed to spawn`,y=>{y.reportError(1,` ${Ho(d,{label:"Thrown Error",value:io(Ke.NO_HINT,p.message)})}`)}))}),u.on("close",(p,d)=>{let m=n==="buffer"?Buffer.concat(a):Buffer.concat(a).toString(n),y=n==="buffer"?Buffer.concat(l):Buffer.concat(l).toString(n);p===0||!s?g({code:pD(p,d),stdout:m,stderr:y}):h(new jw({fileName:r,code:p,signal:d,stdout:m,stderr:y}))})})}var $ve=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]]);function pD(r,e){let t=$ve.get(e);return typeof t<"u"?128+t:r!=null?r:1}function ePe(r,e,{configuration:t,report:i}){i.reportError(1,` ${Ho(t,r!==null?{label:"Exit Code",value:io(Ke.NUMBER,r)}:{label:"Exit Signal",value:io(Ke.CODE,e)})}`)}var Vt={};ct(Vt,{Method:()=>n9,RequestError:()=>s9.RequestError,del:()=>fDe,get:()=>uDe,getNetworkSettings:()=>i9,post:()=>DR,put:()=>gDe,request:()=>PC});var e9=ve(dB()),t9=J("https"),r9=J("http"),kR=ve(Bn()),xR=ve(X6()),CB=J("url");var s9=ve(dB()),Z6=new Map,_6=new Map,ADe=new r9.Agent({keepAlive:!0}),lDe=new t9.Agent({keepAlive:!0});function $6(r){let e=new CB.URL(r),t={host:e.hostname,headers:{}};return e.port&&(t.port=Number(e.port)),e.username&&e.password&&(t.proxyAuth=`${e.username}:${e.password}`),{proxy:t}}async function PR(r){return La(_6,r,()=>M.readFilePromise(r).then(e=>(_6.set(r,e),e)))}function cDe({statusCode:r,statusMessage:e},t){let i=_e(t,r,Ke.NUMBER),n=`https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${r}`;return If(t,`${i}${e?` (${e})`:""}`,n)}async function mB(r,{configuration:e,customErrorMessage:t}){var i,n;try{return await r}catch(s){if(s.name!=="HTTPError")throw s;let o=(n=t==null?void 0:t(s))!=null?n:(i=s.response.body)==null?void 0:i.error;o==null&&(s.message.startsWith("Response code")?o="The remote server failed to provide the requested resource":o=s.message),s instanceof e9.TimeoutError&&s.event==="socket"&&(o+=`(can be increased via ${_e(e,"httpTimeout",Ke.SETTING)})`);let a=new rt(35,o,l=>{s.response&&l.reportError(35,` ${Ho(e,{label:"Response Code",value:io(Ke.NO_HINT,cDe(s.response,e))})}`),s.request&&(l.reportError(35,` ${Ho(e,{label:"Request Method",value:io(Ke.NO_HINT,s.request.options.method)})}`),l.reportError(35,` ${Ho(e,{label:"Request URL",value:io(Ke.URL,s.request.requestUrl)})}`)),s.request.redirects.length>0&&l.reportError(35,` ${Ho(e,{label:"Request Redirects",value:io(Ke.NO_HINT,tx(e,s.request.redirects,Ke.URL))})}`),s.request.retryCount===s.request.options.retry.limit&&l.reportError(35,` ${Ho(e,{label:"Request Retry Count",value:io(Ke.NO_HINT,`${_e(e,s.request.retryCount,Ke.NUMBER)} (can be increased via ${_e(e,"httpRetry",Ke.SETTING)})`)})}`)});throw a.originalError=s,a}}function i9(r,e){let t=[...e.configuration.get("networkSettings")].sort(([o],[a])=>a.length-o.length),i={enableNetwork:void 0,caFilePath:void 0,httpProxy:void 0,httpsProxy:void 0,httpsKeyFilePath:void 0,httpsCertFilePath:void 0},n=Object.keys(i),s=typeof r=="string"?new CB.URL(r):r;for(let[o,a]of t)if(kR.default.isMatch(s.hostname,o))for(let l of n){let c=a.get(l);c!==null&&typeof i[l]>"u"&&(i[l]=c)}for(let o of n)typeof i[o]>"u"&&(i[o]=e.configuration.get(o));return i}var n9=(n=>(n.GET="GET",n.PUT="PUT",n.POST="POST",n.DELETE="DELETE",n))(n9||{});async function PC(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o="GET"}){let a=async()=>await hDe(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o});return await(await t.reduceHook(c=>c.wrapNetworkRequest,a,{target:r,body:e,configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o}))()}async function uDe(r,{configuration:e,jsonResponse:t,...i}){let n=La(Z6,r,()=>mB(PC(r,null,{configuration:e,...i}),{configuration:e}).then(s=>(Z6.set(r,s.body),s.body)));return Buffer.isBuffer(n)===!1&&(n=await n),t?JSON.parse(n.toString()):n}async function gDe(r,e,{customErrorMessage:t,...i}){return(await mB(PC(r,e,{...i,method:"PUT"}),i)).body}async function DR(r,e,{customErrorMessage:t,...i}){return(await mB(PC(r,e,{...i,method:"POST"}),i)).body}async function fDe(r,{customErrorMessage:e,...t}){return(await mB(PC(r,null,{...t,method:"DELETE"}),t)).body}async function hDe(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o="GET"}){let a=typeof r=="string"?new CB.URL(r):r,l=i9(a,{configuration:t});if(l.enableNetwork===!1)throw new rt(80,`Request to '${a.href}' has been blocked because of your configuration settings`);if(a.protocol==="http:"&&!kR.default.isMatch(a.hostname,t.get("unsafeHttpWhitelist")))throw new rt(81,`Unsafe http requests must be explicitly whitelisted in your configuration (${a.hostname})`);let u={agent:{http:l.httpProxy?xR.default.httpOverHttp($6(l.httpProxy)):ADe,https:l.httpsProxy?xR.default.httpsOverHttp($6(l.httpsProxy)):lDe},headers:i,method:o};u.responseType=s?"json":"buffer",e!==null&&(Buffer.isBuffer(e)||!n&&typeof e=="string"?u.body=e:u.json=e);let g=t.get("httpTimeout"),h=t.get("httpRetry"),p=t.get("enableStrictSsl"),d=l.caFilePath,m=l.httpsCertFilePath,y=l.httpsKeyFilePath,{default:B}=await Promise.resolve().then(()=>ve(dB())),S=d?await PR(d):void 0,x=m?await PR(m):void 0,F=y?await PR(y):void 0,H=B.extend({timeout:{socket:g},retry:h,https:{rejectUnauthorized:p,certificateAuthority:S,certificate:x,key:F},...u});return t.getLimit("networkConcurrency")(()=>H(a))}var Yt={};ct(Yt,{PackageManager:()=>CV,detectPackageManager:()=>mV,executePackageAccessibleBinary:()=>BV,executePackageScript:()=>NB,executePackageShellcode:()=>JR,executeWorkspaceAccessibleBinary:()=>FRe,executeWorkspaceLifecycleScript:()=>yV,executeWorkspaceScript:()=>IV,getPackageAccessibleBinaries:()=>TB,getWorkspaceAccessibleBinaries:()=>wV,hasPackageScript:()=>kRe,hasWorkspaceScript:()=>WR,isNodeScript:()=>zR,makeScriptEnv:()=>NC,maybeExecuteWorkspaceLifecycleScript:()=>RRe,prepareExternalProject:()=>xRe});var xC={};ct(xC,{getLibzipPromise:()=>on,getLibzipSync:()=>u9});var c9=ve(a9());var Wa=["number","number"],A9=(N=>(N[N.ZIP_ER_OK=0]="ZIP_ER_OK",N[N.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",N[N.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",N[N.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",N[N.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",N[N.ZIP_ER_READ=5]="ZIP_ER_READ",N[N.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",N[N.ZIP_ER_CRC=7]="ZIP_ER_CRC",N[N.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",N[N.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",N[N.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",N[N.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",N[N.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",N[N.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",N[N.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",N[N.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",N[N.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",N[N.ZIP_ER_EOF=17]="ZIP_ER_EOF",N[N.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",N[N.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",N[N.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",N[N.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",N[N.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",N[N.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",N[N.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",N[N.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",N[N.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",N[N.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",N[N.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",N[N.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",N[N.ZIP_ER_TELL=30]="ZIP_ER_TELL",N[N.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA",N))(A9||{}),l9=r=>({get HEAP8(){return r.HEAP8},get HEAPU8(){return r.HEAPU8},errors:A9,SEEK_SET:0,SEEK_CUR:1,SEEK_END:2,ZIP_CHECKCONS:4,ZIP_CREATE:1,ZIP_EXCL:2,ZIP_TRUNCATE:8,ZIP_RDONLY:16,ZIP_FL_OVERWRITE:8192,ZIP_FL_COMPRESSED:4,ZIP_OPSYS_DOS:0,ZIP_OPSYS_AMIGA:1,ZIP_OPSYS_OPENVMS:2,ZIP_OPSYS_UNIX:3,ZIP_OPSYS_VM_CMS:4,ZIP_OPSYS_ATARI_ST:5,ZIP_OPSYS_OS_2:6,ZIP_OPSYS_MACINTOSH:7,ZIP_OPSYS_Z_SYSTEM:8,ZIP_OPSYS_CPM:9,ZIP_OPSYS_WINDOWS_NTFS:10,ZIP_OPSYS_MVS:11,ZIP_OPSYS_VSE:12,ZIP_OPSYS_ACORN_RISC:13,ZIP_OPSYS_VFAT:14,ZIP_OPSYS_ALTERNATE_MVS:15,ZIP_OPSYS_BEOS:16,ZIP_OPSYS_TANDEM:17,ZIP_OPSYS_OS_400:18,ZIP_OPSYS_OS_X:19,ZIP_CM_DEFAULT:-1,ZIP_CM_STORE:0,ZIP_CM_DEFLATE:8,uint08S:r._malloc(1),uint16S:r._malloc(2),uint32S:r._malloc(4),uint64S:r._malloc(8),malloc:r._malloc,free:r._free,getValue:r.getValue,open:r.cwrap("zip_open","number",["string","number","number"]),openFromSource:r.cwrap("zip_open_from_source","number",["number","number","number"]),close:r.cwrap("zip_close","number",["number"]),discard:r.cwrap("zip_discard",null,["number"]),getError:r.cwrap("zip_get_error","number",["number"]),getName:r.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:r.cwrap("zip_get_num_entries","number",["number","number"]),delete:r.cwrap("zip_delete","number",["number","number"]),stat:r.cwrap("zip_stat","number",["number","string","number","number"]),statIndex:r.cwrap("zip_stat_index","number",["number",...Wa,"number","number"]),fopen:r.cwrap("zip_fopen","number",["number","string","number"]),fopenIndex:r.cwrap("zip_fopen_index","number",["number",...Wa,"number"]),fread:r.cwrap("zip_fread","number",["number","number","number","number"]),fclose:r.cwrap("zip_fclose","number",["number"]),dir:{add:r.cwrap("zip_dir_add","number",["number","string"])},file:{add:r.cwrap("zip_file_add","number",["number","string","number","number"]),getError:r.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:r.cwrap("zip_file_get_external_attributes","number",["number",...Wa,"number","number","number"]),setExternalAttributes:r.cwrap("zip_file_set_external_attributes","number",["number",...Wa,"number","number","number"]),setMtime:r.cwrap("zip_file_set_mtime","number",["number",...Wa,"number","number"]),setCompression:r.cwrap("zip_set_file_compression","number",["number",...Wa,"number","number"])},ext:{countSymlinks:r.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:r.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:r.cwrap("zip_error_strerror","string",["number"])},name:{locate:r.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:r.cwrap("zip_source_buffer_create","number",["number",...Wa,"number","number"]),fromBuffer:r.cwrap("zip_source_buffer","number",["number","number",...Wa,"number"]),free:r.cwrap("zip_source_free",null,["number"]),keep:r.cwrap("zip_source_keep",null,["number"]),open:r.cwrap("zip_source_open","number",["number"]),close:r.cwrap("zip_source_close","number",["number"]),seek:r.cwrap("zip_source_seek","number",["number",...Wa,"number"]),tell:r.cwrap("zip_source_tell","number",["number"]),read:r.cwrap("zip_source_read","number",["number","number","number"]),error:r.cwrap("zip_source_error","number",["number"]),setMtime:r.cwrap("zip_source_set_mtime","number",["number","number"])},struct:{stat:r.cwrap("zipstruct_stat","number",[]),statS:r.cwrap("zipstruct_statS","number",[]),statName:r.cwrap("zipstruct_stat_name","string",["number"]),statIndex:r.cwrap("zipstruct_stat_index","number",["number"]),statSize:r.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:r.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:r.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:r.cwrap("zipstruct_stat_mtime","number",["number"]),statCrc:r.cwrap("zipstruct_stat_crc","number",["number"]),error:r.cwrap("zipstruct_error","number",[]),errorS:r.cwrap("zipstruct_errorS","number",[]),errorCodeZip:r.cwrap("zipstruct_error_code_zip","number",["number"])}});var NR=null;function u9(){return NR===null&&(NR=l9((0,c9.default)())),NR}async function on(){return u9()}var FC={};ct(FC,{ShellError:()=>zn,execute:()=>vB,globUtils:()=>wB});var Q9=ve(wP()),S9=J("os"),Vn=J("stream"),v9=J("util");var zn=class extends Error{constructor(e){super(e),this.name="ShellError"}};var wB={};ct(wB,{fastGlobOptions:()=>h9,isBraceExpansion:()=>TR,isGlobPattern:()=>pDe,match:()=>dDe,micromatchOptions:()=>yB});var g9=ve(pw()),f9=ve(J("fs")),IB=ve(Bn()),yB={strictBrackets:!0},h9={onlyDirectories:!1,onlyFiles:!1};function pDe(r){if(!IB.default.scan(r,yB).isGlob)return!1;try{IB.default.parse(r,yB)}catch{return!1}return!0}function dDe(r,{cwd:e,baseFs:t}){return(0,g9.default)(r,{...h9,cwd:K.fromPortablePath(e),fs:aI(f9.default,new vg(t))})}function TR(r){return IB.default.scan(r,yB).isBrace}var d9=ve(TS()),zo=J("stream"),C9=J("string_decoder");var Uc=new Set;function LR(){}function OR(){for(let r of Uc)r.kill()}function m9(r,e,t,i){return n=>{let s=n[0]instanceof zo.Transform?"pipe":n[0],o=n[1]instanceof zo.Transform?"pipe":n[1],a=n[2]instanceof zo.Transform?"pipe":n[2],l=(0,d9.default)(r,e,{...i,stdio:[s,o,a]});return Uc.add(l),Uc.size===1&&(process.on("SIGINT",LR),process.on("SIGTERM",OR)),n[0]instanceof zo.Transform&&n[0].pipe(l.stdin),n[1]instanceof zo.Transform&&l.stdout.pipe(n[1],{end:!1}),n[2]instanceof zo.Transform&&l.stderr.pipe(n[2],{end:!1}),{stdin:l.stdin,promise:new Promise(c=>{l.on("error",u=>{switch(Uc.delete(l),Uc.size===0&&(process.off("SIGINT",LR),process.off("SIGTERM",OR)),u.code){case"ENOENT":n[2].write(`command not found: ${r} +`),c(127);break;case"EACCES":n[2].write(`permission denied: ${r} +`),c(128);break;default:n[2].write(`uncaught error: ${u.message} +`),c(1);break}}),l.on("close",u=>{Uc.delete(l),Uc.size===0&&(process.off("SIGINT",LR),process.off("SIGTERM",OR)),c(u!==null?u:129)})})}}}function E9(r){return e=>{let t=e[0]==="pipe"?new zo.PassThrough:e[0];return{stdin:t,promise:Promise.resolve().then(()=>r({stdin:t,stdout:e[1],stderr:e[2]}))}}}var Qs=class{constructor(e){this.stream=e}close(){}get(){return this.stream}},MR=class{constructor(){this.stream=null}close(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");this.stream.end()}attach(e){this.stream=e}get(){if(this.stream===null)throw new Error("Assertion failed: No stream attached");return this.stream}},zf=class{constructor(e,t){this.stdin=null;this.stdout=null;this.stderr=null;this.pipe=null;this.ancestor=e,this.implementation=t}static start(e,{stdin:t,stdout:i,stderr:n}){let s=new zf(null,e);return s.stdin=t,s.stdout=i,s.stderr=n,s}pipeTo(e,t=1){let i=new zf(this,e),n=new MR;return i.pipe=n,i.stdout=this.stdout,i.stderr=this.stderr,(t&1)===1?this.stdout=n:this.ancestor!==null&&(this.stderr=this.ancestor.stdout),(t&2)===2?this.stderr=n:this.ancestor!==null&&(this.stderr=this.ancestor.stderr),i}async exec(){let e=["ignore","ignore","ignore"];if(this.pipe)e[0]="pipe";else{if(this.stdin===null)throw new Error("Assertion failed: No input stream registered");e[0]=this.stdin.get()}let t;if(this.stdout===null)throw new Error("Assertion failed: No output stream registered");t=this.stdout,e[1]=t.get();let i;if(this.stderr===null)throw new Error("Assertion failed: No error stream registered");i=this.stderr,e[2]=i.get();let n=this.implementation(e);return this.pipe&&this.pipe.attach(n.stdin),await n.promise.then(s=>(t.close(),i.close(),s))}async run(){let e=[];for(let i=this;i;i=i.ancestor)e.push(i.exec());return(await Promise.all(e))[0]}};function BB(r,e){return zf.start(r,e)}function p9(r,e=null){let t=new zo.PassThrough,i=new C9.StringDecoder,n="";return t.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` +`),a!==-1){let l=n+o.substring(0,a);o=o.substring(a+1),n="",r(e!==null?`${e} ${l}`:l)}while(a!==-1);n+=o}),t.on("end",()=>{let s=i.end();s!==""&&r(e!==null?`${e} ${s}`:s)}),t}function I9(r,{prefix:e}){return{stdout:p9(t=>r.stdout.write(`${t} +`),r.stdout.isTTY?e:null),stderr:p9(t=>r.stderr.write(`${t} +`),r.stderr.isTTY?e:null)}}var CDe=(0,v9.promisify)(setTimeout);function y9(r,e,t){let i=new Vn.PassThrough({autoDestroy:!0});switch(r){case 0:(e&1)===1&&t.stdin.pipe(i,{end:!1}),(e&2)===2&&t.stdin instanceof Vn.Writable&&i.pipe(t.stdin,{end:!1});break;case 1:(e&1)===1&&t.stdout.pipe(i,{end:!1}),(e&2)===2&&i.pipe(t.stdout,{end:!1});break;case 2:(e&1)===1&&t.stderr.pipe(i,{end:!1}),(e&2)===2&&i.pipe(t.stderr,{end:!1});break;default:throw new zn(`Bad file descriptor: "${r}"`)}return i}function QB(r,e={}){let t={...r,...e};return t.environment={...r.environment,...e.environment},t.variables={...r.variables,...e.variables},t}var mDe=new Map([["cd",async([r=(0,S9.homedir)(),...e],t,i)=>{let n=v.resolve(i.cwd,K.toPortablePath(r));if(!(await t.baseFs.statPromise(n).catch(o=>{throw o.code==="ENOENT"?new zn(`cd: no such file or directory: ${r}`):o})).isDirectory())throw new zn(`cd: not a directory: ${r}`);return i.cwd=n,0}],["pwd",async(r,e,t)=>(t.stdout.write(`${K.fromPortablePath(t.cwd)} +`),0)],[":",async(r,e,t)=>0],["true",async(r,e,t)=>0],["false",async(r,e,t)=>1],["exit",async([r,...e],t,i)=>i.exitCode=parseInt(r!=null?r:i.variables["?"],10)],["echo",async(r,e,t)=>(t.stdout.write(`${r.join(" ")} +`),0)],["sleep",async([r],e,t)=>{if(typeof r>"u")throw new zn("sleep: missing operand");let i=Number(r);if(Number.isNaN(i))throw new zn(`sleep: invalid time interval '${r}'`);return await CDe(1e3*i,0)}],["__ysh_run_procedure",async(r,e,t)=>{let i=t.procedures[r[0]];return await BB(i,{stdin:new Qs(t.stdin),stdout:new Qs(t.stdout),stderr:new Qs(t.stderr)}).run()}],["__ysh_set_redirects",async(r,e,t)=>{let i=t.stdin,n=t.stdout,s=t.stderr,o=[],a=[],l=[],c=0;for(;r[c]!=="--";){let g=r[c++],{type:h,fd:p}=JSON.parse(g),d=S=>{switch(p){case null:case 0:o.push(S);break;default:throw new Error(`Unsupported file descriptor: "${p}"`)}},m=S=>{switch(p){case null:case 1:a.push(S);break;case 2:l.push(S);break;default:throw new Error(`Unsupported file descriptor: "${p}"`)}},y=Number(r[c++]),B=c+y;for(let S=c;S<B;++c,++S)switch(h){case"<":d(()=>e.baseFs.createReadStream(v.resolve(t.cwd,K.toPortablePath(r[S]))));break;case"<<<":d(()=>{let x=new Vn.PassThrough;return process.nextTick(()=>{x.write(`${r[S]} +`),x.end()}),x});break;case"<&":d(()=>y9(Number(r[S]),1,t));break;case">":case">>":{let x=v.resolve(t.cwd,K.toPortablePath(r[S]));m(x==="/dev/null"?new Vn.Writable({autoDestroy:!0,emitClose:!0,write(F,H,q){setImmediate(q)}}):e.baseFs.createWriteStream(x,h===">>"?{flags:"a"}:void 0))}break;case">&":m(y9(Number(r[S]),2,t));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${h}"`)}}if(o.length>0){let g=new Vn.PassThrough;i=g;let h=p=>{if(p===o.length)g.end();else{let d=o[p]();d.pipe(g,{end:!1}),d.on("end",()=>{h(p+1)})}};h(0)}if(a.length>0){let g=new Vn.PassThrough;n=g;for(let h of a)g.pipe(h)}if(l.length>0){let g=new Vn.PassThrough;s=g;for(let h of l)g.pipe(h)}let u=await BB(DC(r.slice(c+1),e,t),{stdin:new Qs(i),stdout:new Qs(n),stderr:new Qs(s)}).run();return await Promise.all(a.map(g=>new Promise((h,p)=>{g.on("error",d=>{p(d)}),g.on("close",()=>{h()}),g.end()}))),await Promise.all(l.map(g=>new Promise((h,p)=>{g.on("error",d=>{p(d)}),g.on("close",()=>{h()}),g.end()}))),u}]]);async function EDe(r,e,t){let i=[],n=new Vn.PassThrough;return n.on("data",s=>i.push(s)),await SB(r,e,QB(t,{stdout:n})),Buffer.concat(i).toString().replace(/[\r\n]+$/,"")}async function w9(r,e,t){let i=r.map(async s=>{let o=await Hc(s.args,e,t);return{name:s.name,value:o.join(" ")}});return(await Promise.all(i)).reduce((s,o)=>(s[o.name]=o.value,s),{})}function bB(r){return r.match(/[^ \r\n\t]+/g)||[]}async function P9(r,e,t,i,n=i){switch(r.name){case"$":i(String(process.pid));break;case"#":i(String(e.args.length));break;case"@":if(r.quoted)for(let s of e.args)n(s);else for(let s of e.args){let o=bB(s);for(let a=0;a<o.length-1;++a)n(o[a]);i(o[o.length-1])}break;case"*":{let s=e.args.join(" ");if(r.quoted)i(s);else for(let o of bB(s))n(o)}break;case"PPID":i(String(process.ppid));break;case"RANDOM":i(String(Math.floor(Math.random()*32768)));break;default:{let s=parseInt(r.name,10),o,a=Number.isFinite(s);if(a?s>=0&&s<e.args.length&&(o=e.args[s]):Object.prototype.hasOwnProperty.call(t.variables,r.name)?o=t.variables[r.name]:Object.prototype.hasOwnProperty.call(t.environment,r.name)&&(o=t.environment[r.name]),typeof o<"u"&&r.alternativeValue?o=(await Hc(r.alternativeValue,e,t)).join(" "):typeof o>"u"&&(r.defaultValue?o=(await Hc(r.defaultValue,e,t)).join(" "):r.alternativeValue&&(o="")),typeof o>"u")throw a?new zn(`Unbound argument #${s}`):new zn(`Unbound variable "${r.name}"`);if(r.quoted)i(o);else{let l=bB(o);for(let u=0;u<l.length-1;++u)n(l[u]);let c=l[l.length-1];typeof c<"u"&&i(c)}}break}}var IDe={addition:(r,e)=>r+e,subtraction:(r,e)=>r-e,multiplication:(r,e)=>r*e,division:(r,e)=>Math.trunc(r/e)};async function kC(r,e,t){if(r.type==="number"){if(Number.isInteger(r.value))return r.value;throw new Error(`Invalid number: "${r.value}", only integers are allowed`)}else if(r.type==="variable"){let i=[];await P9({...r,quoted:!0},e,t,s=>i.push(s));let n=Number(i.join(" "));return Number.isNaN(n)?kC({type:"variable",name:i.join(" ")},e,t):kC({type:"number",value:n},e,t)}else return IDe[r.type](await kC(r.left,e,t),await kC(r.right,e,t))}async function Hc(r,e,t){let i=new Map,n=[],s=[],o=u=>{s.push(u)},a=()=>{s.length>0&&n.push(s.join("")),s=[]},l=u=>{o(u),a()},c=(u,g,h)=>{let p=JSON.stringify({type:u,fd:g}),d=i.get(p);typeof d>"u"&&i.set(p,d=[]),d.push(h)};for(let u of r){let g=!1;switch(u.type){case"redirection":{let h=await Hc(u.args,e,t);for(let p of h)c(u.subtype,u.fd,p)}break;case"argument":for(let h of u.segments)switch(h.type){case"text":o(h.text);break;case"glob":o(h.pattern),g=!0;break;case"shell":{let p=await EDe(h.shell,e,t);if(h.quoted)o(p);else{let d=bB(p);for(let m=0;m<d.length-1;++m)l(d[m]);o(d[d.length-1])}}break;case"variable":await P9(h,e,t,o,l);break;case"arithmetic":o(String(await kC(h.arithmetic,e,t)));break}break}if(a(),g){let h=n.pop();if(typeof h>"u")throw new Error("Assertion failed: Expected a glob pattern to have been set");let p=await e.glob.match(h,{cwd:t.cwd,baseFs:e.baseFs});if(p.length===0){let d=TR(h)?". Note: Brace expansion of arbitrary strings isn't currently supported. For more details, please read this issue: https://github.com/yarnpkg/berry/issues/22":"";throw new zn(`No matches found: "${h}"${d}`)}for(let d of p.sort())l(d)}}if(i.size>0){let u=[];for(let[g,h]of i.entries())u.splice(u.length,0,g,String(h.length),...h);n.splice(0,0,"__ysh_set_redirects",...u,"--")}return n}function DC(r,e,t){e.builtins.has(r[0])||(r=["command",...r]);let i=K.fromPortablePath(t.cwd),n=t.environment;typeof n.PWD<"u"&&(n={...n,PWD:i});let[s,...o]=r;if(s==="command")return m9(o[0],o.slice(1),e,{cwd:i,env:n});let a=e.builtins.get(s);if(typeof a>"u")throw new Error(`Assertion failed: A builtin should exist for "${s}"`);return E9(async({stdin:l,stdout:c,stderr:u})=>{let{stdin:g,stdout:h,stderr:p}=t;t.stdin=l,t.stdout=c,t.stderr=u;try{return await a(o,e,t)}finally{t.stdin=g,t.stdout=h,t.stderr=p}})}function yDe(r,e,t){return i=>{let n=new Vn.PassThrough,s=SB(r,e,QB(t,{stdin:n}));return{stdin:n,promise:s}}}function wDe(r,e,t){return i=>{let n=new Vn.PassThrough,s=SB(r,e,t);return{stdin:n,promise:s}}}function B9(r,e,t,i){if(e.length===0)return r;{let n;do n=String(Math.random());while(Object.prototype.hasOwnProperty.call(i.procedures,n));return i.procedures={...i.procedures},i.procedures[n]=r,DC([...e,"__ysh_run_procedure",n],t,i)}}async function b9(r,e,t){let i=r,n=null,s=null;for(;i;){let o=i.then?{...t}:t,a;switch(i.type){case"command":{let l=await Hc(i.args,e,t),c=await w9(i.envs,e,t);a=i.envs.length?DC(l,e,QB(o,{environment:c})):DC(l,e,o)}break;case"subshell":{let l=await Hc(i.args,e,t),c=yDe(i.subshell,e,o);a=B9(c,l,e,o)}break;case"group":{let l=await Hc(i.args,e,t),c=wDe(i.group,e,o);a=B9(c,l,e,o)}break;case"envs":{let l=await w9(i.envs,e,t);o.environment={...o.environment,...l},a=DC(["true"],e,o)}break}if(typeof a>"u")throw new Error("Assertion failed: An action should have been generated");if(n===null)s=BB(a,{stdin:new Qs(o.stdin),stdout:new Qs(o.stdout),stderr:new Qs(o.stderr)});else{if(s===null)throw new Error("Assertion failed: The execution pipeline should have been setup");switch(n){case"|":s=s.pipeTo(a,1);break;case"|&":s=s.pipeTo(a,3);break}}i.then?(n=i.then.type,i=i.then.chain):i=null}if(s===null)throw new Error("Assertion failed: The execution pipeline should have been setup");return await s.run()}async function BDe(r,e,t,{background:i=!1}={}){function n(s){let o=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],a=o[s%o.length];return Q9.default.hex(a)}if(i){let s=t.nextBackgroundJobIndex++,o=n(s),a=`[${s}]`,l=o(a),{stdout:c,stderr:u}=I9(t,{prefix:l});return t.backgroundJobs.push(b9(r,e,QB(t,{stdout:c,stderr:u})).catch(g=>u.write(`${g.message} +`)).finally(()=>{t.stdout.isTTY&&t.stdout.write(`Job ${l}, '${o(Fg(r))}' has ended +`)})),0}return await b9(r,e,t)}async function bDe(r,e,t,{background:i=!1}={}){let n,s=a=>{n=a,t.variables["?"]=String(a)},o=async a=>{try{return await BDe(a.chain,e,t,{background:i&&typeof a.then>"u"})}catch(l){if(!(l instanceof zn))throw l;return t.stderr.write(`${l.message} +`),1}};for(s(await o(r));r.then;){if(t.exitCode!==null)return t.exitCode;switch(r.then.type){case"&&":n===0&&s(await o(r.then.line));break;case"||":n!==0&&s(await o(r.then.line));break;default:throw new Error(`Assertion failed: Unsupported command type: "${r.then.type}"`)}r=r.then.line}return n}async function SB(r,e,t){let i=t.backgroundJobs;t.backgroundJobs=[];let n=0;for(let{command:s,type:o}of r){if(n=await bDe(s,e,t,{background:o==="&"}),t.exitCode!==null)return t.exitCode;t.variables["?"]=String(n)}return await Promise.all(t.backgroundJobs),t.backgroundJobs=i,n}function x9(r){switch(r.type){case"variable":return r.name==="@"||r.name==="#"||r.name==="*"||Number.isFinite(parseInt(r.name,10))||"defaultValue"in r&&!!r.defaultValue&&r.defaultValue.some(e=>RC(e))||"alternativeValue"in r&&!!r.alternativeValue&&r.alternativeValue.some(e=>RC(e));case"arithmetic":return KR(r.arithmetic);case"shell":return UR(r.shell);default:return!1}}function RC(r){switch(r.type){case"redirection":return r.args.some(e=>RC(e));case"argument":return r.segments.some(e=>x9(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${r.type}"`)}}function KR(r){switch(r.type){case"variable":return x9(r);case"number":return!1;default:return KR(r.left)||KR(r.right)}}function UR(r){return r.some(({command:e})=>{for(;e;){let t=e.chain;for(;t;){let i;switch(t.type){case"subshell":i=UR(t.subshell);break;case"command":i=t.envs.some(n=>n.args.some(s=>RC(s)))||t.args.some(n=>RC(n));break}if(i)return!0;if(!t.then)break;t=t.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function vB(r,e=[],{baseFs:t=new Zt,builtins:i={},cwd:n=K.toPortablePath(process.cwd()),env:s=process.env,stdin:o=process.stdin,stdout:a=process.stdout,stderr:l=process.stderr,variables:c={},glob:u=wB}={}){let g={};for(let[d,m]of Object.entries(s))typeof m<"u"&&(g[d]=m);let h=new Map(mDe);for(let[d,m]of Object.entries(i))h.set(d,m);o===null&&(o=new Vn.PassThrough,o.end());let p=cI(r,u);if(!UR(p)&&p.length>0&&e.length>0){let{command:d}=p[p.length-1];for(;d.then;)d=d.then.line;let m=d.chain;for(;m.then;)m=m.then.chain;m.type==="command"&&(m.args=m.args.concat(e.map(y=>({type:"argument",segments:[{type:"text",text:y}]}))))}return await SB(p,{args:e,baseFs:t,builtins:h,initialStdin:o,initialStdout:a,initialStderr:l,glob:u},{cwd:n,environment:g,exitCode:null,procedures:{},stdin:o,stdout:a,stderr:l,variables:Object.assign({},c,{["?"]:0}),nextBackgroundJobIndex:1,backgroundJobs:[]})}var pV=ve(PB()),dV=ve(Jg()),el=J("stream");var fV=ve(lV()),RB=ve(cc());var cV=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],uV=80,wRe=new Set([13,19]),BRe=5,DB=RB.default.GITHUB_ACTIONS?{start:r=>`::group::${r} +`,end:r=>`::endgroup:: +`}:RB.default.TRAVIS?{start:r=>`travis_fold:start:${r} +`,end:r=>`travis_fold:end:${r} +`}:RB.default.GITLAB?{start:r=>`section_start:${Math.floor(Date.now()/1e3)}:${r.toLowerCase().replace(/\W+/g,"_")}[collapsed=true]\r\x1B[0K${r} +`,end:r=>`section_end:${Math.floor(Date.now()/1e3)}:${r.toLowerCase().replace(/\W+/g,"_")}\r\x1B[0K`}:null,gV=new Date,bRe=["iTerm.app","Apple_Terminal","WarpTerminal","vscode"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,QRe=r=>r,FB=QRe({patrick:{date:[17,3],chars:["\u{1F340}","\u{1F331}"],size:40},simba:{date:[19,7],chars:["\u{1F981}","\u{1F334}"],size:40},jack:{date:[31,10],chars:["\u{1F383}","\u{1F987}"],size:40},hogsfather:{date:[31,12],chars:["\u{1F389}","\u{1F384}"],size:40},default:{chars:["=","-"],size:80}}),SRe=bRe&&Object.keys(FB).find(r=>{let e=FB[r];return!(e.date&&(e.date[0]!==gV.getDate()||e.date[1]!==gV.getMonth()+1))})||"default";function hV(r,{configuration:e,json:t}){if(!e.get("enableMessageNames"))return"";let n=RA(r===null?0:r);return!t&&r===null?_e(e,n,"grey"):n}function qR(r,{configuration:e,json:t}){let i=hV(r,{configuration:e,json:t});if(!i||r===null||r===0)return i;let n=dt[r],s=`https://yarnpkg.com/advanced/error-codes#${i}---${n}`.toLowerCase();return If(e,i,s)}var He=class extends Pi{constructor({configuration:t,stdout:i,json:n=!1,includePrefix:s=!0,includeFooter:o=!0,includeLogs:a=!n,includeInfos:l=a,includeWarnings:c=a,forgettableBufferSize:u=BRe,forgettableNames:g=new Set}){super();this.uncommitted=new Set;this.cacheHitCount=0;this.cacheMissCount=0;this.lastCacheMiss=null;this.warningCount=0;this.errors=[];this.startTime=Date.now();this.indent=0;this.progress=new Map;this.progressTime=0;this.progressFrame=0;this.progressTimeout=null;this.progressStyle=null;this.progressMaxScaledSize=null;this.forgettableLines=[];if(Zd(this,{configuration:t}),this.configuration=t,this.forgettableBufferSize=u,this.forgettableNames=new Set([...g,...wRe]),this.includePrefix=s,this.includeFooter=o,this.includeInfos=l,this.includeWarnings=c,this.json=n,this.stdout=i,t.get("enableProgressBars")&&!n&&i.isTTY&&i.columns>22){let h=t.get("progressBarStyle")||SRe;if(!Object.prototype.hasOwnProperty.call(FB,h))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=FB[h];let p=12,d=Math.max(0,Math.min(i.columns-p,80));this.progressMaxScaledSize=Math.floor(this.progressStyle.size*d/80)}}static async start(t,i){let n=new this(t),s=process.emitWarning;process.emitWarning=(o,a)=>{if(typeof o!="string"){let c=o;o=c.message,a=a!=null?a:c.name}let l=typeof a<"u"?`${a}: ${o}`:o;n.reportWarning(0,l)};try{await i(n)}catch(o){n.reportExceptionOnce(o)}finally{await n.finalize(),process.emitWarning=s}return n}hasErrors(){return this.errors.length>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(t){this.cacheHitCount+=1}reportCacheMiss(t,i){this.lastCacheMiss=t,this.cacheMissCount+=1,typeof i<"u"&&!this.configuration.get("preferAggregateCacheInfo")&&this.reportInfo(13,i)}startSectionSync({reportHeader:t,reportFooter:i,skipIfEmpty:n},s){let o={committed:!1,action:()=>{t==null||t()}};n?this.uncommitted.add(o):(o.action(),o.committed=!0);let a=Date.now();try{return s()}catch(l){throw this.reportExceptionOnce(l),l}finally{let l=Date.now();this.uncommitted.delete(o),o.committed&&(i==null||i(l-a))}}async startSectionPromise({reportHeader:t,reportFooter:i,skipIfEmpty:n},s){let o={committed:!1,action:()=>{t==null||t()}};n?this.uncommitted.add(o):(o.action(),o.committed=!0);let a=Date.now();try{return await s()}catch(l){throw this.reportExceptionOnce(l),l}finally{let l=Date.now();this.uncommitted.delete(o),o.committed&&(i==null||i(l-a))}}startTimerImpl(t,i,n){return{cb:typeof i=="function"?i:n,reportHeader:()=>{this.reportInfo(null,`\u250C ${t}`),this.indent+=1,DB!==null&&!this.json&&this.includeInfos&&this.stdout.write(DB.start(t))},reportFooter:a=>{if(this.indent-=1,DB!==null&&!this.json&&this.includeInfos){this.stdout.write(DB.end(t));for(let[l,c]of this.errors)this.reportErrorImpl(l,c)}this.configuration.get("enableTimers")&&a>200?this.reportInfo(null,`\u2514 Completed in ${_e(this.configuration,a,Ke.DURATION)}`):this.reportInfo(null,"\u2514 Completed")},skipIfEmpty:(typeof i=="function"?{}:i).skipIfEmpty}}startTimerSync(t,i,n){let{cb:s,...o}=this.startTimerImpl(t,i,n);return this.startSectionSync(o,s)}async startTimerPromise(t,i,n){let{cb:s,...o}=this.startTimerImpl(t,i,n);return this.startSectionPromise(o,s)}async startCacheReport(t){let i=this.configuration.get("preferAggregateCacheInfo")?{cacheHitCount:this.cacheHitCount,cacheMissCount:this.cacheMissCount}:null;try{return await t()}catch(n){throw this.reportExceptionOnce(n),n}finally{i!==null&&this.reportCacheChanges(i)}}reportSeparator(){this.indent===0?this.writeLineWithForgettableReset(""):this.reportInfo(null,"")}reportInfo(t,i){if(!this.includeInfos)return;this.commit();let n=this.formatNameWithHyperlink(t),s=n?`${n}: `:"",o=`${this.formatPrefix(s,"blueBright")}${i}`;if(this.json)this.reportJson({type:"info",name:t,displayName:this.formatName(t),indent:this.formatIndent(),data:i});else if(this.forgettableNames.has(t))if(this.forgettableLines.push(o),this.forgettableLines.length>this.forgettableBufferSize){for(;this.forgettableLines.length>this.forgettableBufferSize;)this.forgettableLines.shift();this.writeLines(this.forgettableLines,{truncate:!0})}else this.writeLine(o,{truncate:!0});else this.writeLineWithForgettableReset(o)}reportWarning(t,i){if(this.warningCount+=1,!this.includeWarnings)return;this.commit();let n=this.formatNameWithHyperlink(t),s=n?`${n}: `:"";this.json?this.reportJson({type:"warning",name:t,displayName:this.formatName(t),indent:this.formatIndent(),data:i}):this.writeLineWithForgettableReset(`${this.formatPrefix(s,"yellowBright")}${i}`)}reportError(t,i){this.errors.push([t,i]),this.reportErrorImpl(t,i)}reportErrorImpl(t,i){this.commit();let n=this.formatNameWithHyperlink(t),s=n?`${n}: `:"";this.json?this.reportJson({type:"error",name:t,displayName:this.formatName(t),indent:this.formatIndent(),data:i}):this.writeLineWithForgettableReset(`${this.formatPrefix(s,"redBright")}${i}`,{truncate:!1})}reportProgress(t){if(this.progressStyle===null)return{...Promise.resolve(),stop:()=>{}};if(t.hasProgress&&t.hasTitle)throw new Error("Unimplemented: Progress bars can't have both progress and titles.");let i=!1,n=Promise.resolve().then(async()=>{let o={progress:t.hasProgress?0:void 0,title:t.hasTitle?"":void 0};this.progress.set(t,{definition:o,lastScaledSize:t.hasProgress?-1:void 0,lastTitle:void 0}),this.refreshProgress({delta:-1});for await(let{progress:a,title:l}of t)i||o.progress===a&&o.title===l||(o.progress=a,o.title=l,this.refreshProgress());s()}),s=()=>{i||(i=!0,this.progress.delete(t),this.refreshProgress({delta:1}))};return{...n,stop:s}}reportJson(t){this.json&&this.writeLineWithForgettableReset(`${JSON.stringify(t)}`)}async finalize(){if(!this.includeFooter)return;let t="";this.errors.length>0?t="Failed with errors":this.warningCount>0?t="Done with warnings":t="Done";let i=_e(this.configuration,Date.now()-this.startTime,Ke.DURATION),n=this.configuration.get("enableTimers")?`${t} in ${i}`:t;this.errors.length>0?this.reportError(0,n):this.warningCount>0?this.reportWarning(0,n):this.reportInfo(0,n)}writeLine(t,{truncate:i}={}){this.clearProgress({clear:!0}),this.stdout.write(`${this.truncate(t,{truncate:i})} +`),this.writeProgress()}writeLineWithForgettableReset(t,{truncate:i}={}){this.forgettableLines=[],this.writeLine(t,{truncate:i})}writeLines(t,{truncate:i}={}){this.clearProgress({delta:t.length});for(let n of t)this.stdout.write(`${this.truncate(n,{truncate:i})} +`);this.writeProgress()}reportCacheChanges({cacheHitCount:t,cacheMissCount:i}){let n=this.cacheHitCount-t,s=this.cacheMissCount-i;if(n===0&&s===0)return;let o="";this.cacheHitCount>1?o+=`${this.cacheHitCount} packages were already cached`:this.cacheHitCount===1?o+=" - one package was already cached":o+="No packages were cached",this.cacheHitCount>0?this.cacheMissCount>1?o+=`, ${this.cacheMissCount} had to be fetched`:this.cacheMissCount===1&&(o+=`, one had to be fetched (${Ct(this.configuration,this.lastCacheMiss)})`):this.cacheMissCount>1?o+=` - ${this.cacheMissCount} packages had to be fetched`:this.cacheMissCount===1&&(o+=` - one package had to be fetched (${Ct(this.configuration,this.lastCacheMiss)})`),this.reportInfo(13,o)}commit(){let t=this.uncommitted;this.uncommitted=new Set;for(let i of t)i.committed=!0,i.action()}clearProgress({delta:t=0,clear:i=!1}){this.progressStyle!==null&&this.progress.size+t>0&&(this.stdout.write(`\x1B[${this.progress.size+t}A`),(t>0||i)&&this.stdout.write("\x1B[0J"))}writeProgress(){if(this.progressStyle===null||(this.progressTimeout!==null&&clearTimeout(this.progressTimeout),this.progressTimeout=null,this.progress.size===0))return;let t=Date.now();t-this.progressTime>uV&&(this.progressFrame=(this.progressFrame+1)%cV.length,this.progressTime=t);let i=cV[this.progressFrame];for(let n of this.progress.values()){let s="";if(typeof n.lastScaledSize<"u"){let c=this.progressStyle.chars[0].repeat(n.lastScaledSize),u=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-n.lastScaledSize);s=` ${c}${u}`}let o=this.formatName(null),a=o?`${o}: `:"",l=n.definition.title?` ${n.definition.title}`:"";this.stdout.write(`${_e(this.configuration,"\u27A4","blueBright")} ${a}${i}${s}${l} +`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress({force:!0})},uV)}refreshProgress({delta:t=0,force:i=!1}={}){let n=!1,s=!1;if(i||this.progress.size===0)n=!0;else for(let o of this.progress.values()){let a=typeof o.definition.progress<"u"?Math.trunc(this.progressMaxScaledSize*o.definition.progress):void 0,l=o.lastScaledSize;o.lastScaledSize=a;let c=o.lastTitle;if(o.lastTitle=o.definition.title,a!==l||(s=c!==o.definition.title)){n=!0;break}}n&&(this.clearProgress({delta:t,clear:s}),this.writeProgress())}truncate(t,{truncate:i}={}){return this.progressStyle===null&&(i=!1),typeof i>"u"&&(i=this.configuration.get("preferTruncatedLines")),i&&(t=(0,fV.default)(t,0,this.stdout.columns-1)),t}formatName(t){return hV(t,{configuration:this.configuration,json:this.json})}formatPrefix(t,i){return this.includePrefix?`${_e(this.configuration,"\u27A4",i)} ${t}${this.formatIndent()}`:""}formatNameWithHyperlink(t){return qR(t,{configuration:this.configuration,json:this.json})}formatIndent(){return"\u2502 ".repeat(this.indent)}};var Fr="3.8.1";var CV=(n=>(n.Yarn1="Yarn Classic",n.Yarn2="Yarn",n.Npm="npm",n.Pnpm="pnpm",n))(CV||{});async function $A(r,e,t,i=[]){if(process.platform==="win32"){let n=`@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"${t}" ${i.map(s=>`"${s.replace('"','""')}"`).join(" ")} %*`;await M.writeFilePromise(v.format({dir:r,name:e,ext:".cmd"}),n)}await M.writeFilePromise(v.join(r,e),`#!/bin/sh +exec "${t}" ${i.map(n=>`'${n.replace(/'/g,`'"'"'`)}'`).join(" ")} "$@" +`,{mode:493})}async function mV(r){let e=await ot.tryFind(r);if(e!=null&&e.packageManager){let i=Sw(e.packageManager);if(i!=null&&i.name){let n=`found ${JSON.stringify({packageManager:e.packageManager})} in manifest`,[s]=i.reference.split(".");switch(i.name){case"yarn":return{packageManagerField:!0,packageManager:Number(s)===1?"Yarn Classic":"Yarn",reason:n};case"npm":return{packageManagerField:!0,packageManager:"npm",reason:n};case"pnpm":return{packageManagerField:!0,packageManager:"pnpm",reason:n}}}}let t;try{t=await M.readFilePromise(v.join(r,St.lockfile),"utf8")}catch{}return t!==void 0?t.match(/^__metadata:$/m)?{packageManager:"Yarn",reason:'"__metadata" key found in yarn.lock'}:{packageManager:"Yarn Classic",reason:'"__metadata" key not found in yarn.lock, must be a Yarn classic lockfile'}:M.existsSync(v.join(r,"package-lock.json"))?{packageManager:"npm",reason:`found npm's "package-lock.json" lockfile`}:M.existsSync(v.join(r,"pnpm-lock.yaml"))?{packageManager:"pnpm",reason:`found pnpm's "pnpm-lock.yaml" lockfile`}:null}async function NC({project:r,locator:e,binFolder:t,ignoreCorepack:i,lifecycleScript:n}){var c,u;let s={};for(let[g,h]of Object.entries(process.env))typeof h<"u"&&(s[g.toLowerCase()!=="path"?g:"PATH"]=h);let o=K.fromPortablePath(t);s.BERRY_BIN_FOLDER=K.fromPortablePath(o);let a=process.env.COREPACK_ROOT&&!i?K.join(process.env.COREPACK_ROOT,"dist/yarn.js"):process.argv[1];if(await Promise.all([$A(t,"node",process.execPath),...Fr!==null?[$A(t,"run",process.execPath,[a,"run"]),$A(t,"yarn",process.execPath,[a]),$A(t,"yarnpkg",process.execPath,[a]),$A(t,"node-gyp",process.execPath,[a,"run","--top-level","node-gyp"])]:[]]),r&&(s.INIT_CWD=K.fromPortablePath(r.configuration.startingCwd),s.PROJECT_CWD=K.fromPortablePath(r.cwd)),s.PATH=s.PATH?`${o}${K.delimiter}${s.PATH}`:`${o}`,s.npm_execpath=`${o}${K.sep}yarn`,s.npm_node_execpath=`${o}${K.sep}node`,e){if(!r)throw new Error("Assertion failed: Missing project");let g=r.tryWorkspaceByLocator(e),h=g?(c=g.manifest.version)!=null?c:"":(u=r.storedPackages.get(e.locatorHash).version)!=null?u:"";s.npm_package_name=Tt(e),s.npm_package_version=h;let p;if(g)p=g.cwd;else{let d=r.storedPackages.get(e.locatorHash);if(!d)throw new Error(`Package for ${Ct(r.configuration,e)} not found in the project`);let m=r.configuration.getLinkers(),y={project:r,report:new He({stdout:new el.PassThrough,configuration:r.configuration})},B=m.find(S=>S.supportsPackage(d,y));if(!B)throw new Error(`The package ${Ct(r.configuration,d)} isn't supported by any of the available linkers`);p=await B.findPackageLocation(d,y)}s.npm_package_json=K.fromPortablePath(v.join(p,St.manifest))}let l=Fr!==null?`yarn/${Fr}`:`yarn/${mf("@yarnpkg/core").version}-core`;return s.npm_config_user_agent=`${l} npm/? node/${process.version} ${process.platform} ${process.arch}`,n&&(s.npm_lifecycle_event=n),r&&await r.configuration.triggerHook(g=>g.setupScriptEnvironment,r,s,async(g,h,p)=>await $A(t,Yr(g),h,p)),s}var vRe=2,PRe=(0,dV.default)(vRe);async function xRe(r,e,{configuration:t,report:i,workspace:n=null,locator:s=null}){await PRe(async()=>{await M.mktempPromise(async o=>{let a=v.join(o,"pack.log"),l=null,{stdout:c,stderr:u}=t.getSubprocessStreams(a,{prefix:K.fromPortablePath(r),report:i}),g=s&&Yo(s)?sC(s):s,h=g?ms(g):"an external project";c.write(`Packing ${h} from sources +`);let p=await mV(r),d;p!==null?(c.write(`Using ${p.packageManager} for bootstrap. Reason: ${p.reason} + +`),d=p.packageManager):(c.write(`No package manager configuration detected; defaulting to Yarn + +`),d="Yarn");let m=d==="Yarn"&&!(p!=null&&p.packageManagerField);await M.mktempPromise(async y=>{let B=await NC({binFolder:y,ignoreCorepack:m}),x=new Map([["Yarn Classic",async()=>{let H=n!==null?["workspace",n]:[],q=v.join(r,St.manifest),_=await M.readFilePromise(q),X=await so(process.execPath,[process.argv[1],"set","version","classic","--only-if-needed"],{cwd:r,env:B,stdin:l,stdout:c,stderr:u,end:1});if(X.code!==0)return X.code;await M.writeFilePromise(q,_),await M.appendFilePromise(v.join(r,".npmignore"),`/.yarn +`),c.write(` +`),delete B.NODE_ENV;let W=await so("yarn",["install"],{cwd:r,env:B,stdin:l,stdout:c,stderr:u,end:1});if(W.code!==0)return W.code;c.write(` +`);let Z=await so("yarn",[...H,"pack","--filename",K.fromPortablePath(e)],{cwd:r,env:B,stdin:l,stdout:c,stderr:u});return Z.code!==0?Z.code:0}],["Yarn",async()=>{let H=n!==null?["workspace",n]:[];B.YARN_ENABLE_INLINE_BUILDS="1";let q=v.join(r,St.lockfile);await M.existsPromise(q)||await M.writeFilePromise(q,"");let _=await so("yarn",[...H,"pack","--install-if-needed","--filename",K.fromPortablePath(e)],{cwd:r,env:B,stdin:l,stdout:c,stderr:u});return _.code!==0?_.code:0}],["npm",async()=>{if(n!==null){let ne=new el.PassThrough,ue=Cf(ne);ne.pipe(c,{end:!1});let te=await so("npm",["--version"],{cwd:r,env:B,stdin:l,stdout:ne,stderr:u,end:0});if(ne.end(),te.code!==0)return c.end(),u.end(),te.code;let O=(await ue).toString().trim();if(!Fc(O,">=7.x")){let N=qo(null,"npm"),ce=zt(N,O),he=zt(N,">=7.x");throw new Error(`Workspaces aren't supported by ${$t(t,ce)}; please upgrade to ${$t(t,he)} (npm has been detected as the primary package manager for ${_e(t,r,Ke.PATH)})`)}}let H=n!==null?["--workspace",n]:[];delete B.npm_config_user_agent,delete B.npm_config_production,delete B.NPM_CONFIG_PRODUCTION,delete B.NODE_ENV;let q=await so("npm",["install"],{cwd:r,env:B,stdin:l,stdout:c,stderr:u,end:1});if(q.code!==0)return q.code;let _=new el.PassThrough,X=Cf(_);_.pipe(c);let W=await so("npm",["pack","--silent",...H],{cwd:r,env:B,stdin:l,stdout:_,stderr:u});if(W.code!==0)return W.code;let Z=(await X).toString().trim().replace(/^.*\n/s,""),A=v.resolve(r,K.toPortablePath(Z));return await M.renamePromise(A,e),0}]]).get(d);if(typeof x>"u")throw new Error("Assertion failed: Unsupported workflow");let F=await x();if(!(F===0||typeof F>"u"))throw M.detachTemp(o),new rt(58,`Packing the package failed (exit code ${F}, logs can be found here: ${_e(t,a,Ke.PATH)})`)})})})}async function kRe(r,e,{project:t}){let i=t.tryWorkspaceByLocator(r);if(i!==null)return WR(i,e);let n=t.storedPackages.get(r.locatorHash);if(!n)throw new Error(`Package for ${Ct(t.configuration,r)} not found in the project`);return await Kn.openPromise(async s=>{let o=t.configuration,a=t.configuration.getLinkers(),l={project:t,report:new He({stdout:new el.PassThrough,configuration:o})},c=a.find(p=>p.supportsPackage(n,l));if(!c)throw new Error(`The package ${Ct(t.configuration,n)} isn't supported by any of the available linkers`);let u=await c.findPackageLocation(n,l),g=new jt(u,{baseFs:s});return(await ot.find(Te.dot,{baseFs:g})).scripts.has(e)},{libzip:await on()})}async function NB(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await M.mktempPromise(async l=>{let{manifest:c,env:u,cwd:g}=await EV(r,{project:n,binFolder:l,cwd:i,lifecycleScript:e}),h=c.scripts.get(e);if(typeof h>"u")return 1;let p=async()=>await vB(h,t,{cwd:g,env:u,stdin:s,stdout:o,stderr:a});return await(await n.configuration.reduceHook(m=>m.wrapScriptExecution,p,n,r,e,{script:h,args:t,cwd:g,env:u,stdin:s,stdout:o,stderr:a}))()})}async function JR(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await M.mktempPromise(async l=>{let{env:c,cwd:u}=await EV(r,{project:n,binFolder:l,cwd:i});return await vB(e,t,{cwd:u,env:c,stdin:s,stdout:o,stderr:a})})}async function DRe(r,{binFolder:e,cwd:t,lifecycleScript:i}){let n=await NC({project:r.project,locator:r.anchoredLocator,binFolder:e,lifecycleScript:i});return await VR(e,await wV(r)),typeof t>"u"&&(t=v.dirname(await M.realpathPromise(v.join(r.cwd,"package.json")))),{manifest:r.manifest,binFolder:e,env:n,cwd:t}}async function EV(r,{project:e,binFolder:t,cwd:i,lifecycleScript:n}){let s=e.tryWorkspaceByLocator(r);if(s!==null)return DRe(s,{binFolder:t,cwd:i,lifecycleScript:n});let o=e.storedPackages.get(r.locatorHash);if(!o)throw new Error(`Package for ${Ct(e.configuration,r)} not found in the project`);return await Kn.openPromise(async a=>{let l=e.configuration,c=e.configuration.getLinkers(),u={project:e,report:new He({stdout:new el.PassThrough,configuration:l})},g=c.find(y=>y.supportsPackage(o,u));if(!g)throw new Error(`The package ${Ct(e.configuration,o)} isn't supported by any of the available linkers`);let h=await NC({project:e,locator:r,binFolder:t,lifecycleScript:n});await VR(t,await TB(r,{project:e}));let p=await g.findPackageLocation(o,u),d=new jt(p,{baseFs:a}),m=await ot.find(Te.dot,{baseFs:d});return typeof i>"u"&&(i=p),{manifest:m,binFolder:t,env:h,cwd:i}},{libzip:await on()})}async function IV(r,e,t,{cwd:i,stdin:n,stdout:s,stderr:o}){return await NB(r.anchoredLocator,e,t,{cwd:i,project:r.project,stdin:n,stdout:s,stderr:o})}function WR(r,e){return r.manifest.scripts.has(e)}async function yV(r,e,{cwd:t,report:i}){let{configuration:n}=r.project,s=null;await M.mktempPromise(async o=>{let a=v.join(o,`${e}.log`),l=`# This file contains the result of Yarn calling the "${e}" lifecycle script inside a workspace ("${K.fromPortablePath(r.cwd)}") +`,{stdout:c,stderr:u}=n.getSubprocessStreams(a,{report:i,prefix:Ct(n,r.anchoredLocator),header:l});i.reportInfo(36,`Calling the "${e}" lifecycle script`);let g=await IV(r,e,[],{cwd:t,stdin:s,stdout:c,stderr:u});if(c.end(),u.end(),g!==0)throw M.detachTemp(o),new rt(36,`${(0,pV.default)(e)} script failed (exit code ${_e(n,g,Ke.NUMBER)}, logs can be found here: ${_e(n,a,Ke.PATH)}); run ${_e(n,`yarn ${e}`,Ke.CODE)} to investigate`)})}async function RRe(r,e,t){WR(r,e)&&await yV(r,e,t)}function zR(r){let e=v.extname(r);if(e.match(/\.[cm]?[jt]sx?$/))return!0;if(e===".exe"||e===".bin")return!1;let t=Buffer.alloc(4),i;try{i=M.openSync(r,"r")}catch{return!0}try{M.readSync(i,t,0,t.length,0)}finally{M.closeSync(i)}let n=t.readUint32BE();return!(n===3405691582||n===3489328638||n===2135247942||(n&4294901760)===1297743872)}async function TB(r,{project:e}){let t=e.configuration,i=new Map,n=e.storedPackages.get(r.locatorHash);if(!n)throw new Error(`Package for ${Ct(t,r)} not found in the project`);let s=new el.Writable,o=t.getLinkers(),a={project:e,report:new He({configuration:t,stdout:s})},l=new Set([r.locatorHash]);for(let u of n.dependencies.values()){let g=e.storedResolutions.get(u.descriptorHash);if(!g)throw new Error(`Assertion failed: The resolution (${$t(t,u)}) should have been registered`);l.add(g)}let c=await Promise.all(Array.from(l,async u=>{let g=e.storedPackages.get(u);if(!g)throw new Error(`Assertion failed: The package (${u}) should have been registered`);if(g.bin.size===0)return Uo.skip;let h=o.find(d=>d.supportsPackage(g,a));if(!h)return Uo.skip;let p=null;try{p=await h.findPackageLocation(g,a)}catch(d){if(d.code==="LOCATOR_NOT_INSTALLED")return Uo.skip;throw d}return{dependency:g,packageLocation:p}}));for(let u of c){if(u===Uo.skip)continue;let{dependency:g,packageLocation:h}=u;for(let[p,d]of g.bin){let m=v.resolve(h,d);i.set(p,[g,K.fromPortablePath(m),zR(m)])}}return i}async function wV(r){return await TB(r.anchoredLocator,{project:r.project})}async function VR(r,e){await Promise.all(Array.from(e,([t,[,i,n]])=>n?$A(r,Yr(t),process.execPath,[i]):$A(r,Yr(t),i,[])))}async function BV(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a,nodeArgs:l=[],packageAccessibleBinaries:c}){c!=null||(c=await TB(r,{project:n}));let u=c.get(e);if(!u)throw new Error(`Binary not found (${e}) for ${Ct(n.configuration,r)}`);return await M.mktempPromise(async g=>{let[,h]=u,p=await NC({project:n,locator:r,binFolder:g});await VR(p.BERRY_BIN_FOLDER,c);let d=zR(K.toPortablePath(h))?so(process.execPath,[...l,h,...t],{cwd:i,env:p,stdin:s,stdout:o,stderr:a}):so(h,t,{cwd:i,env:p,stdin:s,stdout:o,stderr:a}),m;try{m=await d}finally{await M.removePromise(p.BERRY_BIN_FOLDER)}return m.code})}async function FRe(r,e,t,{cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a}){return await BV(r.anchoredLocator,e,t,{project:r.project,cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a})}var Ci={};ct(Ci,{convertToZip:()=>oTe,extractArchiveTo:()=>ATe,makeArchiveFromDirectory:()=>sTe});var fZ=J("stream"),hZ=ve(aZ());var AZ=ve(Jg()),lZ=J("worker_threads");var fl=Symbol("kTaskInfo"),T0=class{constructor(e){this.source=e;this.workers=[];this.limit=(0,AZ.default)(eD());this.cleanupInterval=setInterval(()=>{if(this.limit.pendingCount===0&&this.limit.activeCount===0){let t=this.workers.pop();t?t.terminate():clearInterval(this.cleanupInterval)}},5e3).unref()}createWorker(){this.cleanupInterval.refresh();let e=new lZ.Worker(this.source,{eval:!0,execArgv:[...process.execArgv,"--unhandled-rejections=strict"]});return e.on("message",t=>{if(!e[fl])throw new Error("Assertion failed: Worker sent a result without having a task assigned");e[fl].resolve(t),e[fl]=null,e.unref(),this.workers.push(e)}),e.on("error",t=>{var i;(i=e[fl])==null||i.reject(t),e[fl]=null}),e.on("exit",t=>{var i;t!==0&&((i=e[fl])==null||i.reject(new Error(`Worker exited with code ${t}`))),e[fl]=null}),e}run(e){return this.limit(()=>{var i;let t=(i=this.workers.pop())!=null?i:this.createWorker();return t.ref(),new Promise((n,s)=>{t[fl]={resolve:n,reject:s},t.postMessage(e)})})}};var pZ=ve(uZ());async function sTe(r,{baseFs:e=new Zt,prefixPath:t=Te.root,compressionLevel:i,inMemory:n=!1}={}){let s=await on(),o;if(n)o=new qr(null,{libzip:s,level:i});else{let l=await M.mktempPromise(),c=v.join(l,"archive.zip");o=new qr(c,{create:!0,libzip:s,level:i})}let a=v.resolve(Te.root,t);return await o.copyPromise(a,r,{baseFs:e,stableTime:!0,stableSort:!0}),o}var gZ;async function oTe(r,e){let t=await M.mktempPromise(),i=v.join(t,"archive.zip");return gZ||(gZ=new T0((0,pZ.getContent)())),await gZ.run({tmpFile:i,tgz:r,opts:e}),new qr(i,{libzip:await on(),level:e.compressionLevel})}async function*aTe(r){let e=new hZ.default.Parse,t=new fZ.PassThrough({objectMode:!0,autoDestroy:!0,emitClose:!0});e.on("entry",i=>{t.write(i)}),e.on("error",i=>{t.destroy(i)}),e.on("close",()=>{t.destroyed||t.end()}),e.end(r);for await(let i of t){let n=i;yield n,n.resume()}}async function ATe(r,e,{stripComponents:t=0,prefixPath:i=Te.dot}={}){var s,o;function n(a){if(a.path[0]==="/")return!0;let l=a.path.split(/\//g);return!!(l.some(c=>c==="..")||l.length<=t)}for await(let a of aTe(r)){if(n(a))continue;let l=v.normalize(K.toPortablePath(a.path)).replace(/\/$/,"").split(/\//g);if(l.length<=t)continue;let c=l.slice(t).join("/"),u=v.join(i,c),g=420;switch((a.type==="Directory"||(((s=a.mode)!=null?s:0)&73)!==0)&&(g|=73),a.type){case"Directory":e.mkdirpSync(v.dirname(u),{chmod:493,utimes:[vr.SAFE_TIME,vr.SAFE_TIME]}),e.mkdirSync(u,{mode:g}),e.utimesSync(u,vr.SAFE_TIME,vr.SAFE_TIME);break;case"OldFile":case"File":e.mkdirpSync(v.dirname(u),{chmod:493,utimes:[vr.SAFE_TIME,vr.SAFE_TIME]}),e.writeFileSync(u,await Cf(a),{mode:g}),e.utimesSync(u,vr.SAFE_TIME,vr.SAFE_TIME);break;case"SymbolicLink":e.mkdirpSync(v.dirname(u),{chmod:493,utimes:[vr.SAFE_TIME,vr.SAFE_TIME]}),e.symlinkSync(a.linkpath,u),(o=e.lutimesSync)==null||o.call(e,u,vr.SAFE_TIME,vr.SAFE_TIME);break}}return e}var es={};ct(es,{emitList:()=>lTe,emitTree:()=>yZ,treeNodeToJson:()=>IZ,treeNodeToTreeify:()=>EZ});var mZ=ve(CZ());function EZ(r,{configuration:e}){let t={},i=(n,s)=>{let o=Array.isArray(n)?n.entries():Object.entries(n);for(let[a,{label:l,value:c,children:u}]of o){let g=[];typeof l<"u"&&g.push(zy(e,l,2)),typeof c<"u"&&g.push(_e(e,c[0],c[1])),g.length===0&&g.push(zy(e,`${a}`,2));let h=g.join(": "),p=s[h]={};typeof u<"u"&&i(u,p)}};if(typeof r.children>"u")throw new Error("The root node must only contain children");return i(r.children,t),t}function IZ(r){let e=t=>{var s;if(typeof t.children>"u"){if(typeof t.value>"u")throw new Error("Assertion failed: Expected a value to be set if the children are missing");return Qc(t.value[0],t.value[1])}let i=Array.isArray(t.children)?t.children.entries():Object.entries((s=t.children)!=null?s:{}),n=Array.isArray(t.children)?[]:{};for(let[o,a]of i)n[o]=e(a);return typeof t.value>"u"?n:{value:Qc(t.value[0],t.value[1]),children:n}};return e(r)}function lTe(r,{configuration:e,stdout:t,json:i}){let n=r.map(s=>({value:s}));yZ({children:n},{configuration:e,stdout:t,json:i})}function yZ(r,{configuration:e,stdout:t,json:i,separators:n=0}){var o;if(i){let a=Array.isArray(r.children)?r.children.values():Object.values((o=r.children)!=null?o:{});for(let l of a)t.write(`${JSON.stringify(IZ(l))} +`);return}let s=(0,mZ.asTree)(EZ(r,{configuration:e}),!1,!1);if(n>=1&&(s=s.replace(/^([├└]─)/gm,`\u2502 +$1`).replace(/^│\n/,"")),n>=2)for(let a=0;a<2;++a)s=s.replace(/^([│ ].{2}[├│ ].{2}[^\n]+\n)(([│ ]).{2}[├└].{2}[^\n]*\n[│ ].{2}[│ ].{2}[├└]─)/gm,`$1$3 \u2502 +$2`).replace(/^│\n/,"");if(n>=3)throw new Error("Only the first two levels are accepted by treeUtils.emitTree");t.write(s)}var wZ=J("crypto"),DN=ve(J("fs"));var cTe=8,Dt=class{constructor(e,{configuration:t,immutable:i=t.get("enableImmutableCache"),check:n=!1}){this.markedFiles=new Set;this.mutexes=new Map;this.cacheId=`-${(0,wZ.randomBytes)(8).toString("hex")}.tmp`;this.configuration=t,this.cwd=e,this.immutable=i,this.check=n;let s=t.get("cacheKeyOverride");if(s!==null)this.cacheKey=`${s}`;else{let o=t.get("compressionLevel"),a=o!==_l?`c${o}`:"";this.cacheKey=[cTe,a].join("")}}static async find(e,{immutable:t,check:i}={}){let n=new Dt(e.get("cacheFolder"),{configuration:e,immutable:t,check:i});return await n.setup(),n}get mirrorCwd(){if(!this.configuration.get("enableMirror"))return null;let e=`${this.configuration.get("globalFolder")}/cache`;return e!==this.cwd?e:null}getVersionFilename(e){return`${Pf(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,t){let n=uTe(t).slice(0,10);return`${Pf(e)}-${n}.zip`}getLocatorPath(e,t,i={}){var s;return this.mirrorCwd===null||((s=i.unstablePackages)==null?void 0:s.has(e.locatorHash))?v.resolve(this.cwd,this.getVersionFilename(e)):t===null||kN(t)!==this.cacheKey?null:v.resolve(this.cwd,this.getChecksumFilename(e,t))}getLocatorMirrorPath(e){let t=this.mirrorCwd;return t!==null?v.resolve(t,this.getVersionFilename(e)):null}async setup(){if(!this.configuration.get("enableGlobalCache"))if(this.immutable){if(!await M.existsPromise(this.cwd))throw new rt(56,"Cache path does not exist.")}else{await M.mkdirPromise(this.cwd,{recursive:!0});let e=v.resolve(this.cwd,".gitignore");await M.changeFilePromise(e,`/.gitignore +*.flock +*.tmp +`)}(this.mirrorCwd||!this.immutable)&&await M.mkdirPromise(this.mirrorCwd||this.cwd,{recursive:!0})}async fetchPackageFromCache(e,t,{onHit:i,onMiss:n,loader:s,...o}){var W;let a=this.getLocatorMirrorPath(e),l=new Zt,c=()=>{let Z=new qr(null,{libzip:x}),A=v.join(Te.root,qk(e));return Z.mkdirSync(A,{recursive:!0}),Z.writeJsonSync(v.join(A,St.manifest),{name:Tt(e),mocked:!0}),Z},u=async(Z,A=null)=>{var ue;if(A===null&&((ue=o.unstablePackages)==null?void 0:ue.has(e.locatorHash)))return{isValid:!0,hash:null};let ne=!o.skipIntegrityCheck||!t?`${this.cacheKey}/${await Bw(Z)}`:t;if(A!==null){let te=!o.skipIntegrityCheck||!t?`${this.cacheKey}/${await Bw(A)}`:t;if(ne!==te)throw new rt(18,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}if(t!==null&&ne!==t){let te;switch(this.check?te="throw":kN(t)!==kN(ne)?te="update":te=this.configuration.get("checksumBehavior"),te){case"ignore":return{isValid:!0,hash:t};case"update":return{isValid:!0,hash:ne};case"reset":return{isValid:!1,hash:t};default:case"throw":throw new rt(18,"The remote archive doesn't match the expected checksum")}}return{isValid:!0,hash:ne}},g=async Z=>{if(!s)throw new Error(`Cache check required but no loader configured for ${Ct(this.configuration,e)}`);let A=await s(),ne=A.getRealPath();A.saveAndClose(),await M.chmodPromise(ne,420);let ue=await u(Z,ne);if(!ue.isValid)throw new Error("Assertion failed: Expected a valid checksum");return ue.hash},h=async()=>{if(a===null||!await M.existsPromise(a)){let Z=await s(),A=Z.getRealPath();return Z.saveAndClose(),{source:"loader",path:A}}return{source:"mirror",path:a}},p=async()=>{if(!s)throw new Error(`Cache entry required but missing for ${Ct(this.configuration,e)}`);if(this.immutable)throw new rt(56,`Cache entry required but missing for ${Ct(this.configuration,e)}`);let{path:Z,source:A}=await h(),ne=(await u(Z)).hash,ue=this.getLocatorPath(e,ne,o);if(!ue)throw new Error("Assertion failed: Expected the cache path to be available");let te=[];A!=="mirror"&&a!==null&&te.push(async()=>{let N=`${a}${this.cacheId}`;await M.copyFilePromise(Z,N,DN.default.constants.COPYFILE_FICLONE),await M.chmodPromise(N,420),await M.renamePromise(N,a)}),(!o.mirrorWriteOnly||a===null)&&te.push(async()=>{let N=`${ue}${this.cacheId}`;await M.copyFilePromise(Z,N,DN.default.constants.COPYFILE_FICLONE),await M.chmodPromise(N,420),await M.renamePromise(N,ue)});let O=o.mirrorWriteOnly&&a!=null?a:ue;return await Promise.all(te.map(N=>N())),[!1,O,ne]},d=async()=>{let A=(async()=>{var ce;let ne=this.getLocatorPath(e,t,o),ue=ne!==null?this.markedFiles.has(ne)||await l.existsPromise(ne):!1,te=!!((ce=o.mockedPackages)!=null&&ce.has(e.locatorHash))&&(!this.check||!ue),O=te||ue,N=O?i:n;if(N&&N(),O){let he=null,xe=ne;if(!te)if(this.check)he=await g(xe);else{let De=await u(xe);if(De.isValid)he=De.hash;else return p()}return[te,xe,he]}else return p()})();this.mutexes.set(e.locatorHash,A);try{return await A}finally{this.mutexes.delete(e.locatorHash)}};for(let Z;Z=this.mutexes.get(e.locatorHash);)await Z;let[m,y,B]=await d();m||this.markedFiles.add(y);let S,x=await on(),F=m?()=>c():()=>new qr(y,{baseFs:l,libzip:x,readOnly:!0}),H=new Sg(()=>JP(()=>S=F(),Z=>`Failed to open the cache entry for ${Ct(this.configuration,e)}: ${Z}`),v),q=new Qo(y,{baseFs:H,pathUtils:v}),_=()=>{S==null||S.discardAndClose()},X=(W=o.unstablePackages)!=null&&W.has(e.locatorHash)?null:B;return[q,_,X]}};function kN(r){let e=r.indexOf("/");return e!==-1?r.slice(0,e):null}function uTe(r){let e=r.indexOf("/");return e!==-1?r.slice(e+1):r}var L0=(t=>(t[t.SCRIPT=0]="SCRIPT",t[t.SHELLCODE=1]="SHELLCODE",t))(L0||{});var ta=class extends Pi{constructor({configuration:t,stdout:i,suggestInstall:n=!0}){super();this.errorCount=0;Zd(this,{configuration:t}),this.configuration=t,this.stdout=i,this.suggestInstall=n}static async start(t,i){let n=new this(t);try{await i(n)}catch(s){n.reportExceptionOnce(s)}finally{await n.finalize()}return n}hasErrors(){return this.errorCount>0}exitCode(){return this.hasErrors()?1:0}reportCacheHit(t){}reportCacheMiss(t){}startSectionSync(t,i){return i()}async startSectionPromise(t,i){return await i()}startTimerSync(t,i,n){return(typeof i=="function"?i:n)()}async startTimerPromise(t,i,n){return await(typeof i=="function"?i:n)()}async startCacheReport(t){return await t()}reportSeparator(){}reportInfo(t,i){}reportWarning(t,i){}reportError(t,i){this.errorCount+=1,this.stdout.write(`${_e(this.configuration,"\u27A4","redBright")} ${this.formatNameWithHyperlink(t)}: ${i} +`)}reportProgress(t){return{...Promise.resolve().then(async()=>{for await(let{}of t);}),stop:()=>{}}}reportJson(t){}async finalize(){this.errorCount>0&&(this.stdout.write(` +`),this.stdout.write(`${_e(this.configuration,"\u27A4","redBright")} Errors happened when preparing the environment required to run this command. +`),this.suggestInstall&&this.stdout.write(`${_e(this.configuration,"\u27A4","redBright")} This might be caused by packages being missing from the lockfile, in which case running "yarn install" might help. +`))}formatNameWithHyperlink(t){return qR(t,{configuration:this.configuration,json:!1})}};var V0=J("crypto");function iA(){}iA.prototype={diff:function(e,t){var i=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},n=i.callback;typeof i=="function"&&(n=i,i={}),this.options=i;var s=this;function o(m){return n?(setTimeout(function(){n(void 0,m)},0),!0):m}e=this.castInput(e),t=this.castInput(t),e=this.removeEmpty(this.tokenize(e)),t=this.removeEmpty(this.tokenize(t));var a=t.length,l=e.length,c=1,u=a+l;i.maxEditLength&&(u=Math.min(u,i.maxEditLength));var g=[{newPos:-1,components:[]}],h=this.extractCommon(g[0],t,e,0);if(g[0].newPos+1>=a&&h+1>=l)return o([{value:this.join(t),count:t.length}]);function p(){for(var m=-1*c;m<=c;m+=2){var y=void 0,B=g[m-1],S=g[m+1],x=(S?S.newPos:0)-m;B&&(g[m-1]=void 0);var F=B&&B.newPos+1<a,H=S&&0<=x&&x<l;if(!F&&!H){g[m]=void 0;continue}if(!F||H&&B.newPos<S.newPos?(y=fTe(S),s.pushComponent(y.components,void 0,!0)):(y=B,y.newPos++,s.pushComponent(y.components,!0,void 0)),x=s.extractCommon(y,t,e,m),y.newPos+1>=a&&x+1>=l)return o(gTe(s,y.components,t,e,s.useLongestToken));g[m]=y}c++}if(n)(function m(){setTimeout(function(){if(c>u)return n();p()||m()},0)})();else for(;c<=u;){var d=p();if(d)return d}},pushComponent:function(e,t,i){var n=e[e.length-1];n&&n.added===t&&n.removed===i?e[e.length-1]={count:n.count+1,added:t,removed:i}:e.push({count:1,added:t,removed:i})},extractCommon:function(e,t,i,n){for(var s=t.length,o=i.length,a=e.newPos,l=a-n,c=0;a+1<s&&l+1<o&&this.equals(t[a+1],i[l+1]);)a++,l++,c++;return c&&e.components.push({count:c}),e.newPos=a,l},equals:function(e,t){return this.options.comparator?this.options.comparator(e,t):e===t||this.options.ignoreCase&&e.toLowerCase()===t.toLowerCase()},removeEmpty:function(e){for(var t=[],i=0;i<e.length;i++)e[i]&&t.push(e[i]);return t},castInput:function(e){return e},tokenize:function(e){return e.split("")},join:function(e){return e.join("")}};function gTe(r,e,t,i,n){for(var s=0,o=e.length,a=0,l=0;s<o;s++){var c=e[s];if(c.removed){if(c.value=r.join(i.slice(l,l+c.count)),l+=c.count,s&&e[s-1].added){var g=e[s-1];e[s-1]=e[s],e[s]=g}}else{if(!c.added&&n){var u=t.slice(a,a+c.count);u=u.map(function(p,d){var m=i[l+d];return m.length>p.length?m:p}),c.value=r.join(u)}else c.value=r.join(t.slice(a,a+c.count));a+=c.count,c.added||(l+=c.count)}}var h=e[o-1];return o>1&&typeof h.value=="string"&&(h.added||h.removed)&&r.equals("",h.value)&&(e[o-2].value+=h.value,e.pop()),e}function fTe(r){return{newPos:r.newPos,components:r.components.slice(0)}}var Xat=new iA;var BZ=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,bZ=/\S/,QZ=new iA;QZ.equals=function(r,e){return this.options.ignoreCase&&(r=r.toLowerCase(),e=e.toLowerCase()),r===e||this.options.ignoreWhitespace&&!bZ.test(r)&&!bZ.test(e)};QZ.tokenize=function(r){for(var e=r.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),t=0;t<e.length-1;t++)!e[t+1]&&e[t+2]&&BZ.test(e[t])&&BZ.test(e[t+2])&&(e[t]+=e[t+2],e.splice(t+1,2),t--);return e};var LN=new iA;LN.tokenize=function(r){var e=[],t=r.split(/(\n|\r\n)/);t[t.length-1]||t.pop();for(var i=0;i<t.length;i++){var n=t[i];i%2&&!this.options.newlineIsToken?e[e.length-1]+=n:(this.options.ignoreWhitespace&&(n=n.trim()),e.push(n))}return e};function hTe(r,e,t){return LN.diff(r,e,t)}var pTe=new iA;pTe.tokenize=function(r){return r.split(/(\S.+?[.!?])(?=\s+|$)/)};var dTe=new iA;dTe.tokenize=function(r){return r.split(/([{}:;,]|\s+)/)};function O0(r){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O0=function(e){return typeof e}:O0=function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},O0(r)}function RN(r){return CTe(r)||mTe(r)||ETe(r)||ITe()}function CTe(r){if(Array.isArray(r))return FN(r)}function mTe(r){if(typeof Symbol<"u"&&Symbol.iterator in Object(r))return Array.from(r)}function ETe(r,e){if(!!r){if(typeof r=="string")return FN(r,e);var t=Object.prototype.toString.call(r).slice(8,-1);if(t==="Object"&&r.constructor&&(t=r.constructor.name),t==="Map"||t==="Set")return Array.from(r);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return FN(r,e)}}function FN(r,e){(e==null||e>r.length)&&(e=r.length);for(var t=0,i=new Array(e);t<e;t++)i[t]=r[t];return i}function ITe(){throw new TypeError(`Invalid attempt to spread non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var yTe=Object.prototype.toString,_C=new iA;_C.useLongestToken=!0;_C.tokenize=LN.tokenize;_C.castInput=function(r){var e=this.options,t=e.undefinedReplacement,i=e.stringifyReplacer,n=i===void 0?function(s,o){return typeof o>"u"?t:o}:i;return typeof r=="string"?r:JSON.stringify(NN(r,null,null,n),n," ")};_C.equals=function(r,e){return iA.prototype.equals.call(_C,r.replace(/,([\r\n])/g,"$1"),e.replace(/,([\r\n])/g,"$1"))};function NN(r,e,t,i,n){e=e||[],t=t||[],i&&(r=i(n,r));var s;for(s=0;s<e.length;s+=1)if(e[s]===r)return t[s];var o;if(yTe.call(r)==="[object Array]"){for(e.push(r),o=new Array(r.length),t.push(o),s=0;s<r.length;s+=1)o[s]=NN(r[s],e,t,i,n);return e.pop(),t.pop(),o}if(r&&r.toJSON&&(r=r.toJSON()),O0(r)==="object"&&r!==null){e.push(r),o={},t.push(o);var a=[],l;for(l in r)r.hasOwnProperty(l)&&a.push(l);for(a.sort(),s=0;s<a.length;s+=1)l=a[s],o[l]=NN(r[l],e,t,i,l);e.pop(),t.pop()}else o=r;return o}var TN=new iA;TN.tokenize=function(r){return r.slice()};TN.join=TN.removeEmpty=function(r){return r};function SZ(r,e,t,i,n,s,o){o||(o={}),typeof o.context>"u"&&(o.context=4);var a=hTe(t,i,o);if(!a)return;a.push({value:"",lines:[]});function l(B){return B.map(function(S){return" "+S})}for(var c=[],u=0,g=0,h=[],p=1,d=1,m=function(S){var x=a[S],F=x.lines||x.value.replace(/\n$/,"").split(` +`);if(x.lines=F,x.added||x.removed){var H;if(!u){var q=a[S-1];u=p,g=d,q&&(h=o.context>0?l(q.lines.slice(-o.context)):[],u-=h.length,g-=h.length)}(H=h).push.apply(H,RN(F.map(function(te){return(x.added?"+":"-")+te}))),x.added?d+=F.length:p+=F.length}else{if(u)if(F.length<=o.context*2&&S<a.length-2){var _;(_=h).push.apply(_,RN(l(F)))}else{var X,W=Math.min(F.length,o.context);(X=h).push.apply(X,RN(l(F.slice(0,W))));var Z={oldStart:u,oldLines:p-u+W,newStart:g,newLines:d-g+W,lines:h};if(S>=a.length-2&&F.length<=o.context){var A=/\n$/.test(t),ne=/\n$/.test(i),ue=F.length==0&&h.length>Z.oldLines;!A&&ue&&t.length>0&&h.splice(Z.oldLines,0,"\\ No newline at end of file"),(!A&&!ue||!ne)&&h.push("\\ No newline at end of file")}c.push(Z),u=0,g=0,h=[]}p+=F.length,d+=F.length}},y=0;y<a.length;y++)m(y);return{oldFileName:r,newFileName:e,oldHeader:n,newHeader:s,hunks:c}}var X0=ve(R$()),Z0=ve(Jg()),O$=ve(zr()),zN=J("util"),WN=ve(J("v8")),VN=ve(J("zlib"));var VMe=[[/^(git(?:\+(?:https|ssh))?:\/\/.*(?:\.git)?)#(.*)$/,(r,e,t,i)=>`${t}#commit=${i}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(r,e,t="",i,n)=>`https://${t}github.com/${i}.git#commit=${n}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(r,e,t="",i,n)=>`https://${t}github.com/${i}.git#commit=${n}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@.+(?:\/|(?:%2f)))?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,r=>`npm:${r}`],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)(?:#|$)/,r=>`npm:${r}`],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,r=>`npm:${r}`],[/^https?:\/\/[^/]+\/.*\/(@[^/]+)\/([^/]+)\/-\/\1\/\2-(?:[.\d\w-]+)\.tgz(?:#|$)/,(r,e)=>vw({protocol:"npm:",source:null,selector:r,params:{__archiveUrl:e}})],[/^[^/]+\.tgz#[0-9a-f]+$/,r=>`npm:${r}`]],J0=class{constructor(e){this.resolver=e;this.resolutions=null}async setup(e,{report:t}){let i=v.join(e.cwd,e.configuration.get("lockfileFilename"));if(!M.existsSync(i))return;let n=await M.readFilePromise(i,"utf8"),s=wi(n);if(Object.prototype.hasOwnProperty.call(s,"__metadata"))return;let o=this.resolutions=new Map;for(let a of Object.keys(s)){let l=AC(a);if(!l){t.reportWarning(14,`Failed to parse the string "${a}" into a proper descriptor`);continue}let c=no(l.range)?zt(l,`npm:${l.range}`):l,{version:u,resolved:g}=s[a];if(!g)continue;let h;for(let[d,m]of VMe){let y=g.match(d);if(y){h=m(u,...y);break}}if(!h){t.reportWarning(14,`${$t(e.configuration,c)}: Only some patterns can be imported from legacy lockfiles (not "${g}")`);continue}let p=c;try{let d=vf(c.range),m=AC(d.selector,!0);m&&(p=m)}catch{}o.set(c.descriptorHash,rn(p,h))}}supportsDescriptor(e,t){return this.resolutions?this.resolutions.has(e.descriptorHash):!1}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){if(!this.resolutions)throw new Error("Assertion failed: The resolution store should have been setup");let n=this.resolutions.get(e.descriptorHash);if(!n)throw new Error("Assertion failed: The resolution should have been registered");return await this.resolver.getCandidates(Hk(n),t,i)}async getSatisfying(e,t,i){return null}async resolve(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}};var W0=class{constructor(e){this.resolver=e}supportsDescriptor(e,t){return!!(t.project.storedResolutions.get(e.descriptorHash)||t.project.originalPackages.has(Qw(e).locatorHash))}supportsLocator(e,t){return!!(t.project.originalPackages.has(e.locatorHash)&&!t.project.lockfileNeedsRefresh)}shouldPersistResolution(e,t){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,i){let n=i.project.originalPackages.get(Qw(e).locatorHash);if(n)return[n];let s=i.project.storedResolutions.get(e.descriptorHash);if(!s)throw new Error("Expected the resolution to have been successful - resolution not found");let o=i.project.originalPackages.get(s);if(!o)throw new Error("Expected the resolution to have been successful - package not found");return[o]}async getSatisfying(e,t,i){return null}async resolve(e,t){let i=t.project.originalPackages.get(e.locatorHash);if(!i)throw new Error("The lockfile resolver isn't meant to resolve packages - they should already have been stored into a cache");return i}};var z0=class{constructor(e){this.resolver=e}supportsDescriptor(e,t){return this.resolver.supportsDescriptor(e,t)}supportsLocator(e,t){return this.resolver.supportsLocator(e,t)}shouldPersistResolution(e,t){return this.resolver.shouldPersistResolution(e,t)}bindDescriptor(e,t,i){return this.resolver.bindDescriptor(e,t,i)}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,i){throw new rt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async getSatisfying(e,t,i){throw new rt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async resolve(e,t){throw new rt(20,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}};var $r=class extends Pi{reportCacheHit(e){}reportCacheMiss(e){}startSectionSync(e,t){return t()}async startSectionPromise(e,t){return await t()}startTimerSync(e,t,i){return(typeof t=="function"?t:i)()}async startTimerPromise(e,t,i){return await(typeof t=="function"?t:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){}reportProgress(e){return{...Promise.resolve().then(async()=>{for await(let{}of e);}),stop:()=>{}}}reportJson(e){}async finalize(){}};var F$=ve(Mk());var Qh=class{constructor(e,{project:t}){this.workspacesCwds=new Set;this.dependencies=new Map;this.project=t,this.cwd=e}async setup(){var s;this.manifest=(s=await ot.tryFind(this.cwd))!=null?s:new ot,this.relativeCwd=v.relative(this.project.cwd,this.cwd)||Te.dot;let e=this.manifest.name?this.manifest.name:qo(null,`${this.computeCandidateName()}-${tn(this.relativeCwd).substring(0,6)}`),t=this.manifest.version?this.manifest.version:"0.0.0";this.locator=rn(e,t),this.anchoredDescriptor=zt(this.locator,`${Ur.protocol}${this.relativeCwd}`),this.anchoredLocator=rn(this.locator,`${Ur.protocol}${this.relativeCwd}`);let i=this.manifest.workspaceDefinitions.map(({pattern:o})=>o);if(i.length===0)return;let n=await(0,F$.default)(i,{cwd:K.fromPortablePath(this.cwd),expandDirectories:!1,onlyDirectories:!0,onlyFiles:!1,ignore:["**/node_modules","**/.git","**/.yarn"]});n.sort(),await n.reduce(async(o,a)=>{let l=v.resolve(this.cwd,K.toPortablePath(a)),c=await M.existsPromise(v.join(l,"package.json"));await o,c&&this.workspacesCwds.add(l)},Promise.resolve())}accepts(e){var o;let t=e.indexOf(":"),i=t!==-1?e.slice(0,t+1):null,n=t!==-1?e.slice(t+1):e;if(i===Ur.protocol&&v.normalize(n)===this.relativeCwd||i===Ur.protocol&&(n==="*"||n==="^"||n==="~"))return!0;let s=no(n);return s?i===Ur.protocol?s.test((o=this.manifest.version)!=null?o:"0.0.0"):this.project.configuration.get("enableTransparentWorkspaces")&&this.manifest.version!==null?s.test(this.manifest.version):!1:!1}computeCandidateName(){return this.cwd===this.project.cwd?"root-workspace":`${v.basename(this.cwd)}`||"unnamed-workspace"}getRecursiveWorkspaceDependencies({dependencies:e=ot.hardDependencies}={}){let t=new Set,i=n=>{for(let s of e)for(let o of n.manifest[s].values()){let a=this.project.tryWorkspaceByDescriptor(o);a===null||t.has(a)||(t.add(a),i(a))}};return i(this),t}getRecursiveWorkspaceDependents({dependencies:e=ot.hardDependencies}={}){let t=new Set,i=n=>{for(let s of this.project.workspaces)e.some(a=>[...s.manifest[a].values()].some(l=>{let c=this.project.tryWorkspaceByDescriptor(l);return c!==null&&aC(c.anchoredLocator,n.anchoredLocator)}))&&!t.has(s)&&(t.add(s),i(s))};return i(this),t}getRecursiveWorkspaceChildren(){let e=new Set([this]);for(let t of e)for(let i of t.workspacesCwds){let n=this.project.workspacesByCwd.get(i);n&&e.add(n)}return e.delete(this),Array.from(e)}async persistManifest(){let e={};this.manifest.exportTo(e);let t=v.join(this.cwd,ot.fileName),i=`${JSON.stringify(e,null,this.manifest.indent)} +`;await M.changeFilePromise(t,i,{automaticNewlines:!0}),this.manifest.raw=e}};var N$=6,XMe=1,ZMe=/ *, */g,T$=/\/$/,_Me=32,$Me=(0,zN.promisify)(VN.default.gzip),e1e=(0,zN.promisify)(VN.default.gunzip),ts=(t=>(t.UpdateLockfile="update-lockfile",t.SkipBuild="skip-build",t))(ts||{}),JN={restoreInstallersCustomData:["installersCustomData"],restoreResolutions:["accessibleLocators","conditionalLocators","disabledLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"],restoreBuildState:["storedBuildState"]},L$=r=>tn(`${XMe}`,r),Ge=class{constructor(e,{configuration:t}){this.resolutionAliases=new Map;this.workspaces=[];this.workspacesByCwd=new Map;this.workspacesByIdent=new Map;this.storedResolutions=new Map;this.storedDescriptors=new Map;this.storedPackages=new Map;this.storedChecksums=new Map;this.storedBuildState=new Map;this.accessibleLocators=new Set;this.conditionalLocators=new Set;this.disabledLocators=new Set;this.originalPackages=new Map;this.optionalBuilds=new Set;this.lockfileNeedsRefresh=!1;this.peerRequirements=new Map;this.installersCustomData=new Map;this.lockFileChecksum=null;this.installStateChecksum=null;this.configuration=t,this.cwd=e}static async find(e,t){var d,m,y;if(!e.projectCwd)throw new we(`No project found in ${t}`);let i=e.projectCwd,n=t,s=null;for(;s!==e.projectCwd;){if(s=n,M.existsSync(v.join(s,St.manifest))){i=s;break}n=v.dirname(s)}let o=new Ge(e.projectCwd,{configuration:e});(d=Ee.telemetry)==null||d.reportProject(o.cwd),await o.setupResolutions(),await o.setupWorkspaces(),(m=Ee.telemetry)==null||m.reportWorkspaceCount(o.workspaces.length),(y=Ee.telemetry)==null||y.reportDependencyCount(o.workspaces.reduce((B,S)=>B+S.manifest.dependencies.size+S.manifest.devDependencies.size,0));let a=o.tryWorkspaceByCwd(i);if(a)return{project:o,workspace:a,locator:a.anchoredLocator};let l=await o.findLocatorForLocation(`${i}/`,{strict:!0});if(l)return{project:o,locator:l,workspace:null};let c=_e(e,o.cwd,Ke.PATH),u=_e(e,v.relative(o.cwd,i),Ke.PATH),g=`- If ${c} isn't intended to be a project, remove any yarn.lock and/or package.json file there.`,h=`- If ${c} is intended to be a project, it might be that you forgot to list ${u} in its workspace configuration.`,p=`- Finally, if ${c} is fine and you intend ${u} to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.`;throw new we(`The nearest package directory (${_e(e,i,Ke.PATH)}) doesn't seem to be part of the project declared in ${_e(e,o.cwd,Ke.PATH)}. + +${[g,h,p].join(` +`)}`)}async setupResolutions(){var i;this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;let e=v.join(this.cwd,this.configuration.get("lockfileFilename")),t=this.configuration.get("defaultLanguageName");if(M.existsSync(e)){let n=await M.readFilePromise(e,"utf8");this.lockFileChecksum=L$(n);let s=wi(n);if(s.__metadata){let o=s.__metadata.version,a=s.__metadata.cacheKey;this.lockfileNeedsRefresh=o<N$;for(let l of Object.keys(s)){if(l==="__metadata")continue;let c=s[l];if(typeof c.resolution>"u")throw new Error(`Assertion failed: Expected the lockfile entry to have a resolution field (${l})`);let u=Rc(c.resolution,!0),g=new ot;g.load(c,{yamlCompatibilityMode:!0});let h=g.version,p=g.languageName||t,d=c.linkType.toUpperCase(),m=(i=c.conditions)!=null?i:null,y=g.dependencies,B=g.peerDependencies,S=g.dependenciesMeta,x=g.peerDependenciesMeta,F=g.bin;if(c.checksum!=null){let q=typeof a<"u"&&!c.checksum.includes("/")?`${a}/${c.checksum}`:c.checksum;this.storedChecksums.set(u.locatorHash,q)}let H={...u,version:h,languageName:p,linkType:d,conditions:m,dependencies:y,peerDependencies:B,dependenciesMeta:S,peerDependenciesMeta:x,bin:F};this.originalPackages.set(H.locatorHash,H);for(let q of l.split(ZMe)){let _=JA(q);this.storedDescriptors.set(_.descriptorHash,_),this.storedResolutions.set(_.descriptorHash,u.locatorHash)}}}}}async setupWorkspaces(){this.workspaces=[],this.workspacesByCwd=new Map,this.workspacesByIdent=new Map;let e=new Set,t=(0,Z0.default)(4),i=async(n,s)=>{if(e.has(s))return n;e.add(s);let o=new Qh(s,{project:this});await t(()=>o.setup());let a=n.then(()=>{this.addWorkspace(o);let l=this.storedPackages.get(o.anchoredLocator.locatorHash);l&&(o.dependencies=l.dependencies)});return Array.from(o.workspacesCwds).reduce(i,a)};await i(Promise.resolve(),this.cwd)}addWorkspace(e){let t=this.workspacesByIdent.get(e.locator.identHash);if(typeof t<"u")throw new Error(`Duplicate workspace name ${ai(this.configuration,e.locator)}: ${K.fromPortablePath(e.cwd)} conflicts with ${K.fromPortablePath(t.cwd)}`);this.workspaces.push(e),this.workspacesByCwd.set(e.cwd,e),this.workspacesByIdent.set(e.locator.identHash,e)}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){v.isAbsolute(e)||(e=v.resolve(this.cwd,e)),e=v.normalize(e).replace(/\/+$/,"");let t=this.workspacesByCwd.get(e);return t||null}getWorkspaceByCwd(e){let t=this.tryWorkspaceByCwd(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByFilePath(e){let t=null;for(let i of this.workspaces)v.relative(i.cwd,e).startsWith("../")||t&&t.cwd.length>=i.cwd.length||(t=i);return t||null}getWorkspaceByFilePath(e){let t=this.tryWorkspaceByFilePath(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByIdent(e){let t=this.workspacesByIdent.get(e.identHash);return typeof t>"u"?null:t}getWorkspaceByIdent(e){let t=this.tryWorkspaceByIdent(e);if(!t)throw new Error(`Workspace not found (${ai(this.configuration,e)})`);return t}tryWorkspaceByDescriptor(e){let t=this.tryWorkspaceByIdent(e);return t===null||(qA(e)&&(e=nC(e)),!t.accepts(e.range))?null:t}getWorkspaceByDescriptor(e){let t=this.tryWorkspaceByDescriptor(e);if(t===null)throw new Error(`Workspace not found (${$t(this.configuration,e)})`);return t}tryWorkspaceByLocator(e){let t=this.tryWorkspaceByIdent(e);return t===null||(Yo(e)&&(e=sC(e)),t.locator.locatorHash!==e.locatorHash&&t.anchoredLocator.locatorHash!==e.locatorHash)?null:t}getWorkspaceByLocator(e){let t=this.tryWorkspaceByLocator(e);if(!t)throw new Error(`Workspace not found (${Ct(this.configuration,e)})`);return t}refreshWorkspaceDependencies(){for(let e of this.workspaces){let t=this.storedPackages.get(e.anchoredLocator.locatorHash);if(!t)throw new Error(`Assertion failed: Expected workspace ${cC(this.configuration,e)} (${_e(this.configuration,v.join(e.cwd,St.manifest),Ke.PATH)}) to have been resolved. Run "yarn install" to update the lockfile`);e.dependencies=new Map(t.dependencies)}}deleteDescriptor(e){this.storedResolutions.delete(e),this.storedDescriptors.delete(e)}deleteLocator(e){this.originalPackages.delete(e),this.storedPackages.delete(e),this.accessibleLocators.delete(e)}forgetResolution(e){if("descriptorHash"in e){let t=this.storedResolutions.get(e.descriptorHash);this.deleteDescriptor(e.descriptorHash);let i=new Set(this.storedResolutions.values());typeof t<"u"&&!i.has(t)&&this.deleteLocator(t)}if("locatorHash"in e){this.deleteLocator(e.locatorHash);for(let[t,i]of this.storedResolutions)i===e.locatorHash&&this.deleteDescriptor(t)}}forgetTransientResolutions(){let e=this.configuration.makeResolver(),t=new Map;for(let[i,n]of this.storedResolutions.entries()){let s=t.get(n);s||t.set(n,s=new Set),s.add(i)}for(let i of this.originalPackages.values()){let n;try{n=e.shouldPersistResolution(i,{project:this,resolver:e})}catch{n=!1}if(!n){this.deleteLocator(i.locatorHash);let s=t.get(i.locatorHash);if(s){t.delete(i.locatorHash);for(let o of s)this.deleteDescriptor(o)}}}}forgetVirtualResolutions(){for(let e of this.storedPackages.values())for(let[t,i]of e.dependencies)qA(i)&&e.dependencies.set(t,nC(i))}getDependencyMeta(e,t){let i={},s=this.topLevelWorkspace.manifest.dependenciesMeta.get(Tt(e));if(!s)return i;let o=s.get(null);if(o&&Object.assign(i,o),t===null||!O$.default.valid(t))return i;for(let[a,l]of s)a!==null&&a===t&&Object.assign(i,l);return i}async findLocatorForLocation(e,{strict:t=!1}={}){let i=new $r,n=this.configuration.getLinkers(),s={project:this,report:i};for(let o of n){let a=await o.findPackageLocator(e,s);if(a){if(t&&(await o.findPackageLocation(a,s)).replace(T$,"")!==e.replace(T$,""))continue;return a}}return null}async resolveEverything(e){if(!this.workspacesByCwd||!this.workspacesByIdent)throw new Error("Workspaces must have been setup before calling this function");this.forgetVirtualResolutions(),e.lockfileOnly||this.forgetTransientResolutions();let t=e.resolver||this.configuration.makeResolver(),i=new J0(t);await i.setup(this,{report:e.report});let n=e.lockfileOnly?[new z0(t)]:[i,t],s=new Df([new W0(t),...n]),o=this.configuration.makeFetcher(),a=e.lockfileOnly?{project:this,report:e.report,resolver:s}:{project:this,report:e.report,resolver:s,fetchOptions:{project:this,cache:e.cache,checksums:this.storedChecksums,report:e.report,fetcher:o,cacheOptions:{mirrorWriteOnly:!0}}},l=new Map,c=new Map,u=new Map,g=new Map,h=new Map,p=new Map,d=this.topLevelWorkspace.anchoredLocator,m=new Set,y=[],B=$k(),S=this.configuration.getSupportedArchitectures();await e.report.startProgressPromise(Pi.progressViaTitle(),async W=>{let Z=async O=>{let N=await df(async()=>await s.resolve(O,a),xe=>`${Ct(this.configuration,O)}: ${xe}`);if(!aC(O,N))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${Ct(this.configuration,O)} to ${Ct(this.configuration,N)})`);g.set(N.locatorHash,N);let ce=this.configuration.normalizePackage(N);for(let[xe,De]of ce.dependencies){let Re=await this.configuration.reduceHook(Ae=>Ae.reduceDependency,De,this,ce,De,{resolver:s,resolveOptions:a});if(!oC(De,Re))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");let se=s.bindDescriptor(Re,O,a);ce.dependencies.set(xe,se)}let he=ro([...ce.dependencies.values()].map(xe=>te(xe)));return y.push(he),he.catch(()=>{}),c.set(ce.locatorHash,ce),ce},A=async O=>{let N=h.get(O.locatorHash);if(typeof N<"u")return N;let ce=Promise.resolve().then(()=>Z(O));return h.set(O.locatorHash,ce),ce},ne=async(O,N)=>{let ce=await te(N);return l.set(O.descriptorHash,O),u.set(O.descriptorHash,ce.locatorHash),ce},ue=async O=>{W.setTitle($t(this.configuration,O));let N=this.resolutionAliases.get(O.descriptorHash);if(typeof N<"u")return ne(O,this.storedDescriptors.get(N));let ce=s.getResolutionDependencies(O,a),he=new Map(await ro(ce.map(async Re=>{let se=s.bindDescriptor(Re,d,a),Ae=await te(se);return m.add(Ae.locatorHash),[Re.descriptorHash,Ae]}))),De=(await df(async()=>await s.getCandidates(O,he,a),Re=>`${$t(this.configuration,O)}: ${Re}`))[0];if(typeof De>"u")throw new rt(82,`${$t(this.configuration,O)}: No candidates found`);return l.set(O.descriptorHash,O),u.set(O.descriptorHash,De.locatorHash),A(De)},te=O=>{let N=p.get(O.descriptorHash);if(typeof N<"u")return N;l.set(O.descriptorHash,O);let ce=Promise.resolve().then(()=>ue(O));return p.set(O.descriptorHash,ce),ce};for(let O of this.workspaces){let N=O.anchoredDescriptor;y.push(te(N))}for(;y.length>0;){let O=[...y];y.length=0,await ro(O)}});let x=new Set(this.resolutionAliases.values()),F=new Set(c.keys()),H=new Set,q=new Map;t1e({project:this,report:e.report,accessibleLocators:H,volatileDescriptors:x,optionalBuilds:F,peerRequirements:q,allDescriptors:l,allResolutions:u,allPackages:c});for(let W of m)F.delete(W);for(let W of x)l.delete(W),u.delete(W);let _=new Set,X=new Set;for(let W of c.values())W.conditions!=null&&(!F.has(W.locatorHash)||(kw(W,S)||(kw(W,B)&&e.report.reportWarningOnce(77,`${Ct(this.configuration,W)}: Your current architecture (${process.platform}-${process.arch}) is supported by this package, but is missing from the ${_e(this.configuration,"supportedArchitectures",Ke.SETTING)} setting`),X.add(W.locatorHash)),_.add(W.locatorHash)));this.storedResolutions=u,this.storedDescriptors=l,this.storedPackages=c,this.accessibleLocators=H,this.conditionalLocators=_,this.disabledLocators=X,this.originalPackages=g,this.optionalBuilds=F,this.peerRequirements=q,this.refreshWorkspaceDependencies()}async fetchEverything({cache:e,report:t,fetcher:i,mode:n}){let s={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators},o=i||this.configuration.makeFetcher(),a={checksums:this.storedChecksums,project:this,cache:e,fetcher:o,report:t,cacheOptions:s},l=Array.from(new Set(bn(this.storedResolutions.values(),[h=>{let p=this.storedPackages.get(h);if(!p)throw new Error("Assertion failed: The locator should have been registered");return ms(p)}])));n==="update-lockfile"&&(l=l.filter(h=>!this.storedChecksums.has(h)));let c=!1,u=Pi.progressViaCounter(l.length);await t.reportProgress(u);let g=(0,Z0.default)(_Me);if(await t.startCacheReport(async()=>{await ro(l.map(h=>g(async()=>{let p=this.storedPackages.get(h);if(!p)throw new Error("Assertion failed: The locator should have been registered");if(Yo(p))return;let d;try{d=await o.fetch(p,a)}catch(m){m.message=`${Ct(this.configuration,p)}: ${m.message}`,t.reportExceptionOnce(m),c=m;return}d.checksum!=null?this.storedChecksums.set(p.locatorHash,d.checksum):this.storedChecksums.delete(p.locatorHash),d.releaseFs&&d.releaseFs()}).finally(()=>{u.tick()})))}),c)throw c}async linkEverything({cache:e,report:t,fetcher:i,mode:n}){var ne,ue,te;let s={mockedPackages:this.disabledLocators,unstablePackages:this.conditionalLocators,skipIntegrityCheck:!0},o=i||this.configuration.makeFetcher(),a={checksums:this.storedChecksums,project:this,cache:e,fetcher:o,report:t,skipIntegrityCheck:!0,cacheOptions:s},l=this.configuration.getLinkers(),c={project:this,report:t},u=new Map(l.map(O=>{let N=O.makeInstaller(c),ce=N.getCustomDataKey(),he=this.installersCustomData.get(ce);return typeof he<"u"&&N.attachCustomData(he),[O,N]})),g=new Map,h=new Map,p=new Map,d=new Map(await ro([...this.accessibleLocators].map(async O=>{let N=this.storedPackages.get(O);if(!N)throw new Error("Assertion failed: The locator should have been registered");return[O,await o.fetch(N,a)]}))),m=[];for(let O of this.accessibleLocators){let N=this.storedPackages.get(O);if(typeof N>"u")throw new Error("Assertion failed: The locator should have been registered");let ce=d.get(N.locatorHash);if(typeof ce>"u")throw new Error("Assertion failed: The fetch result should have been registered");let he=[],xe=Re=>{he.push(Re)},De=this.tryWorkspaceByLocator(N);if(De!==null){let Re=[],{scripts:se}=De.manifest;for(let ye of["preinstall","install","postinstall"])se.has(ye)&&Re.push([0,ye]);try{for(let[ye,ge]of u)if(ye.supportsPackage(N,c)&&(await ge.installPackage(N,ce,{holdFetchResult:xe})).buildDirective!==null)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}finally{he.length===0?(ne=ce.releaseFs)==null||ne.call(ce):m.push(ro(he).catch(()=>{}).then(()=>{var ye;(ye=ce.releaseFs)==null||ye.call(ce)}))}let Ae=v.join(ce.packageFs.getRealPath(),ce.prefixPath);h.set(N.locatorHash,Ae),!Yo(N)&&Re.length>0&&p.set(N.locatorHash,{directives:Re,buildLocations:[Ae]})}else{let Re=l.find(ye=>ye.supportsPackage(N,c));if(!Re)throw new rt(12,`${Ct(this.configuration,N)} isn't supported by any available linker`);let se=u.get(Re);if(!se)throw new Error("Assertion failed: The installer should have been registered");let Ae;try{Ae=await se.installPackage(N,ce,{holdFetchResult:xe})}finally{he.length===0?(ue=ce.releaseFs)==null||ue.call(ce):m.push(ro(he).then(()=>{}).then(()=>{var ye;(ye=ce.releaseFs)==null||ye.call(ce)}))}g.set(N.locatorHash,Re),h.set(N.locatorHash,Ae.packageLocation),Ae.buildDirective&&Ae.buildDirective.length>0&&Ae.packageLocation&&p.set(N.locatorHash,{directives:Ae.buildDirective,buildLocations:[Ae.packageLocation]})}}let y=new Map;for(let O of this.accessibleLocators){let N=this.storedPackages.get(O);if(!N)throw new Error("Assertion failed: The locator should have been registered");let ce=this.tryWorkspaceByLocator(N)!==null,he=async(xe,De)=>{let Re=h.get(N.locatorHash);if(typeof Re>"u")throw new Error(`Assertion failed: The package (${Ct(this.configuration,N)}) should have been registered`);let se=[];for(let Ae of N.dependencies.values()){let ye=this.storedResolutions.get(Ae.descriptorHash);if(typeof ye>"u")throw new Error(`Assertion failed: The resolution (${$t(this.configuration,Ae)}, from ${Ct(this.configuration,N)})should have been registered`);let ge=this.storedPackages.get(ye);if(typeof ge>"u")throw new Error(`Assertion failed: The package (${ye}, resolved from ${$t(this.configuration,Ae)}) should have been registered`);let oe=this.tryWorkspaceByLocator(ge)===null?g.get(ye):null;if(typeof oe>"u")throw new Error(`Assertion failed: The package (${ye}, resolved from ${$t(this.configuration,Ae)}) should have been registered`);oe===xe||oe===null?h.get(ge.locatorHash)!==null&&se.push([Ae,ge]):!ce&&Re!==null&&hf(y,ye).push(Re)}Re!==null&&await De.attachInternalDependencies(N,se)};if(ce)for(let[xe,De]of u)xe.supportsPackage(N,c)&&await he(xe,De);else{let xe=g.get(N.locatorHash);if(!xe)throw new Error("Assertion failed: The linker should have been found");let De=u.get(xe);if(!De)throw new Error("Assertion failed: The installer should have been registered");await he(xe,De)}}for(let[O,N]of y){let ce=this.storedPackages.get(O);if(!ce)throw new Error("Assertion failed: The package should have been registered");let he=g.get(ce.locatorHash);if(!he)throw new Error("Assertion failed: The linker should have been found");let xe=u.get(he);if(!xe)throw new Error("Assertion failed: The installer should have been registered");await xe.attachExternalDependents(ce,N)}let B=new Map;for(let O of u.values()){let N=await O.finalizeInstall();for(let ce of(te=N==null?void 0:N.records)!=null?te:[])p.set(ce.locatorHash,{directives:ce.buildDirective,buildLocations:ce.buildLocations});typeof(N==null?void 0:N.customData)<"u"&&B.set(O.getCustomDataKey(),N.customData)}if(this.installersCustomData=B,await ro(m),n==="skip-build")return;let S=new Set(this.storedPackages.keys()),x=new Set(p.keys());for(let O of x)S.delete(O);let F=(0,V0.createHash)("sha512");F.update(process.versions.node),await this.configuration.triggerHook(O=>O.globalHashGeneration,this,O=>{F.update("\0"),F.update(O)});let H=F.digest("hex"),q=new Map,_=O=>{let N=q.get(O.locatorHash);if(typeof N<"u")return N;let ce=this.storedPackages.get(O.locatorHash);if(typeof ce>"u")throw new Error("Assertion failed: The package should have been registered");let he=(0,V0.createHash)("sha512");he.update(O.locatorHash),q.set(O.locatorHash,"<recursive>");for(let xe of ce.dependencies.values()){let De=this.storedResolutions.get(xe.descriptorHash);if(typeof De>"u")throw new Error(`Assertion failed: The resolution (${$t(this.configuration,xe)}) should have been registered`);let Re=this.storedPackages.get(De);if(typeof Re>"u")throw new Error("Assertion failed: The package should have been registered");he.update(_(Re))}return N=he.digest("hex"),q.set(O.locatorHash,N),N},X=(O,N)=>{let ce=(0,V0.createHash)("sha512");ce.update(H),ce.update(_(O));for(let he of N)ce.update(he);return ce.digest("hex")},W=new Map,Z=!1,A=O=>{let N=new Set([O.locatorHash]);for(let ce of N){let he=this.storedPackages.get(ce);if(!he)throw new Error("Assertion failed: The package should have been registered");for(let xe of he.dependencies.values()){let De=this.storedResolutions.get(xe.descriptorHash);if(!De)throw new Error(`Assertion failed: The resolution (${$t(this.configuration,xe)}) should have been registered`);if(De!==O.locatorHash&&x.has(De))return!1;let Re=this.storedPackages.get(De);if(!Re)throw new Error("Assertion failed: The package should have been registered");let se=this.tryWorkspaceByLocator(Re);if(se){if(se.anchoredLocator.locatorHash!==O.locatorHash&&x.has(se.anchoredLocator.locatorHash))return!1;N.add(se.anchoredLocator.locatorHash)}N.add(De)}}return!0};for(;x.size>0;){let O=x.size,N=[];for(let ce of x){let he=this.storedPackages.get(ce);if(!he)throw new Error("Assertion failed: The package should have been registered");if(!A(he))continue;let xe=p.get(he.locatorHash);if(!xe)throw new Error("Assertion failed: The build directive should have been registered");let De=X(he,xe.buildLocations);if(this.storedBuildState.get(he.locatorHash)===De){W.set(he.locatorHash,De),x.delete(ce);continue}Z||(await this.persistInstallStateFile(),Z=!0),this.storedBuildState.has(he.locatorHash)?t.reportInfo(8,`${Ct(this.configuration,he)} must be rebuilt because its dependency tree changed`):t.reportInfo(7,`${Ct(this.configuration,he)} must be built because it never has been before or the last one failed`);let Re=xe.buildLocations.map(async se=>{if(!v.isAbsolute(se))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${se})`);for(let[Ae,ye]of xe.directives){let ge=`# This file contains the result of Yarn building a package (${ms(he)}) +`;switch(Ae){case 0:ge+=`# Script name: ${ye} +`;break;case 1:ge+=`# Script code: ${ye} +`;break}let oe=null;if(!await M.mktempPromise(async ie=>{let G=v.join(ie,"build.log"),{stdout:fe,stderr:re}=this.configuration.getSubprocessStreams(G,{header:ge,prefix:Ct(this.configuration,he),report:t}),de;try{switch(Ae){case 0:de=await NB(he,ye,[],{cwd:se,project:this,stdin:oe,stdout:fe,stderr:re});break;case 1:de=await JR(he,ye,[],{cwd:se,project:this,stdin:oe,stdout:fe,stderr:re});break}}catch(vt){re.write(vt.stack),de=1}if(fe.end(),re.end(),de===0)return!0;M.detachTemp(ie);let Ze=`${Ct(this.configuration,he)} couldn't be built successfully (exit code ${_e(this.configuration,de,Ke.NUMBER)}, logs can be found here: ${_e(this.configuration,G,Ke.PATH)})`;return this.optionalBuilds.has(he.locatorHash)?(t.reportInfo(9,Ze),!0):(t.reportError(9,Ze),!1)}))return!1}return!0});N.push(...Re,Promise.allSettled(Re).then(se=>{x.delete(ce),se.every(Ae=>Ae.status==="fulfilled"&&Ae.value===!0)&&W.set(he.locatorHash,De)}))}if(await ro(N),O===x.size){let ce=Array.from(x).map(he=>{let xe=this.storedPackages.get(he);if(!xe)throw new Error("Assertion failed: The package should have been registered");return Ct(this.configuration,xe)}).join(", ");t.reportError(3,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${ce})`);break}}this.storedBuildState=W}async install(e){var a,l;let t=this.configuration.get("nodeLinker");(a=Ee.telemetry)==null||a.reportInstall(t),await e.report.startTimerPromise("Project validation",{skipIfEmpty:!0},async()=>{await this.configuration.triggerHook(c=>c.validateProject,this,{reportWarning:e.report.reportWarning.bind(e.report),reportError:e.report.reportError.bind(e.report)})});for(let c of this.configuration.packageExtensions.values())for(let[,u]of c)for(let g of u)g.status="inactive";let i=v.join(this.cwd,this.configuration.get("lockfileFilename")),n=null;if(e.immutable)try{n=await M.readFilePromise(i,"utf8")}catch(c){throw c.code==="ENOENT"?new rt(28,"The lockfile would have been created by this install, which is explicitly forbidden."):c}await e.report.startTimerPromise("Resolution step",async()=>{await this.resolveEverything(e)}),await e.report.startTimerPromise("Post-resolution validation",{skipIfEmpty:!0},async()=>{for(let[,c]of this.configuration.packageExtensions)for(let[,u]of c)for(let g of u)if(g.userProvided){let h=_e(this.configuration,g,Ke.PACKAGE_EXTENSION);switch(g.status){case"inactive":e.report.reportWarning(68,`${h}: No matching package in the dependency tree; you may not need this rule anymore.`);break;case"redundant":e.report.reportWarning(69,`${h}: This rule seems redundant when applied on the original package; the extension may have been applied upstream.`);break}}if(n!==null){let c=Zl(n,this.generateLockfile());if(c!==n){let u=SZ(i,i,n,c,void 0,void 0,{maxEditLength:100});if(u){e.report.reportSeparator();for(let g of u.hunks){e.report.reportInfo(null,`@@ -${g.oldStart},${g.oldLines} +${g.newStart},${g.newLines} @@`);for(let h of g.lines)h.startsWith("+")?e.report.reportError(28,_e(this.configuration,h,Ke.ADDED)):h.startsWith("-")?e.report.reportError(28,_e(this.configuration,h,Ke.REMOVED)):e.report.reportInfo(null,_e(this.configuration,h,"grey"))}e.report.reportSeparator()}throw new rt(28,"The lockfile would have been modified by this install, which is explicitly forbidden.")}}});for(let c of this.configuration.packageExtensions.values())for(let[,u]of c)for(let g of u)g.userProvided&&g.status==="active"&&((l=Ee.telemetry)==null||l.reportPackageExtension(Qc(g,Ke.PACKAGE_EXTENSION)));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e),(typeof e.persistProject>"u"||e.persistProject)&&e.mode!=="update-lockfile"&&await this.cacheCleanup(e)});let s=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],o=await Promise.all(s.map(async c=>bw(c,{cwd:this.cwd})));(typeof e.persistProject>"u"||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{if(e.mode==="update-lockfile"){e.report.reportWarning(73,`Skipped due to ${_e(this.configuration,"mode=update-lockfile",Ke.CODE)}`);return}await this.linkEverything(e);let c=await Promise.all(s.map(async u=>bw(u,{cwd:this.cwd})));for(let u=0;u<s.length;++u)o[u]!==c[u]&&e.report.reportError(64,`The checksum for ${s[u]} has been modified by this install, which is explicitly forbidden.`)}),await this.persistInstallStateFile(),await this.configuration.triggerHook(c=>c.afterAllInstalled,this,e)}generateLockfile(){let e=new Map;for(let[n,s]of this.storedResolutions.entries()){let o=e.get(s);o||e.set(s,o=new Set),o.add(n)}let t={};t.__metadata={version:N$,cacheKey:void 0};for(let[n,s]of e.entries()){let o=this.originalPackages.get(n);if(!o)continue;let a=[];for(let h of s){let p=this.storedDescriptors.get(h);if(!p)throw new Error("Assertion failed: The descriptor should have been registered");a.push(p)}let l=a.map(h=>Sn(h)).sort().join(", "),c=new ot;c.version=o.linkType==="HARD"?o.version:"0.0.0-use.local",c.languageName=o.languageName,c.dependencies=new Map(o.dependencies),c.peerDependencies=new Map(o.peerDependencies),c.dependenciesMeta=new Map(o.dependenciesMeta),c.peerDependenciesMeta=new Map(o.peerDependenciesMeta),c.bin=new Map(o.bin);let u,g=this.storedChecksums.get(o.locatorHash);if(typeof g<"u"){let h=g.indexOf("/");if(h===-1)throw new Error("Assertion failed: Expected the checksum to reference its cache key");let p=g.slice(0,h),d=g.slice(h+1);typeof t.__metadata.cacheKey>"u"&&(t.__metadata.cacheKey=p),p===t.__metadata.cacheKey?u=d:u=g}t[l]={...c.exportTo({},{compatibilityMode:!1}),linkType:o.linkType.toLowerCase(),resolution:ms(o),checksum:u,conditions:o.conditions||void 0}}return`${[`# This file is generated by running "yarn install" inside your project. +`,`# Manual changes might be lost - proceed with caution! +`].join("")} +`+Qa(t)}async persistLockfile(){let e=v.join(this.cwd,this.configuration.get("lockfileFilename")),t="";try{t=await M.readFilePromise(e,"utf8")}catch{}let i=this.generateLockfile(),n=Zl(t,i);n!==t&&(await M.writeFilePromise(e,n),this.lockFileChecksum=L$(n),this.lockfileNeedsRefresh=!1)}async persistInstallStateFile(){let e=[];for(let o of Object.values(JN))e.push(...o);let t=(0,X0.default)(this,e),i=WN.default.serialize(t),n=tn(i);if(this.installStateChecksum===n)return;let s=this.configuration.get("installStatePath");await M.mkdirPromise(v.dirname(s),{recursive:!0}),await M.writeFilePromise(s,await $Me(i)),this.installStateChecksum=n}async restoreInstallState({restoreInstallersCustomData:e=!0,restoreResolutions:t=!0,restoreBuildState:i=!0}={}){let n=this.configuration.get("installStatePath"),s;try{let o=await e1e(await M.readFilePromise(n));s=WN.default.deserialize(o),this.installStateChecksum=tn(o)}catch{t&&await this.applyLightResolution();return}e&&typeof s.installersCustomData<"u"&&(this.installersCustomData=s.installersCustomData),i&&Object.assign(this,(0,X0.default)(s,JN.restoreBuildState)),t&&(s.lockFileChecksum===this.lockFileChecksum?(Object.assign(this,(0,X0.default)(s,JN.restoreResolutions)),this.refreshWorkspaceDependencies()):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new $r}),await this.persistInstallStateFile()}async persist(){let e=(0,Z0.default)(4);await Promise.all([this.persistLockfile(),...this.workspaces.map(t=>e(()=>t.persistManifest()))])}async cacheCleanup({cache:e,report:t}){if(this.configuration.get("enableGlobalCache"))return;let i=new Set([".gitignore"]);if(!Zk(e.cwd,this.cwd)||!await M.existsPromise(e.cwd))return;let n=this.configuration.get("preferAggregateCacheInfo"),s=0,o=null;for(let a of await M.readdirPromise(e.cwd)){if(i.has(a))continue;let l=v.resolve(e.cwd,a);e.markedFiles.has(l)||(o=a,e.immutable?t.reportError(56,`${_e(this.configuration,v.basename(l),"magenta")} appears to be unused and would be marked for deletion, but the cache is immutable`):(n?s+=1:t.reportInfo(19,`${_e(this.configuration,v.basename(l),"magenta")} appears to be unused - removing`),await M.removePromise(l)))}n&&s!==0&&t.reportInfo(19,s>1?`${s} packages appeared to be unused and were removed`:`${o} appeared to be unused and was removed`)}};function t1e({project:r,allDescriptors:e,allResolutions:t,allPackages:i,accessibleLocators:n=new Set,optionalBuilds:s=new Set,peerRequirements:o=new Map,volatileDescriptors:a=new Set,report:l}){var X;let c=new Map,u=[],g=new Map,h=new Map,p=new Map,d=new Map,m=new Map,y=new Map(r.workspaces.map(W=>{let Z=W.anchoredLocator.locatorHash,A=i.get(Z);if(typeof A>"u")throw new Error("Assertion failed: The workspace should have an associated package");return[Z,iC(A)]})),B=()=>{let W=M.mktempSync(),Z=v.join(W,"stacktrace.log"),A=String(u.length+1).length,ne=u.map((ue,te)=>`${`${te+1}.`.padStart(A," ")} ${ms(ue)} +`).join("");throw M.writeFileSync(Z,ne),M.detachTemp(W),new rt(45,`Encountered a stack overflow when resolving peer dependencies; cf ${K.fromPortablePath(Z)}`)},S=W=>{let Z=t.get(W.descriptorHash);if(typeof Z>"u")throw new Error("Assertion failed: The resolution should have been registered");let A=i.get(Z);if(!A)throw new Error("Assertion failed: The package could not be found");return A},x=(W,Z,A,{top:ne,optional:ue})=>{u.length>1e3&&B(),u.push(Z);let te=F(W,Z,A,{top:ne,optional:ue});return u.pop(),te},F=(W,Z,A,{top:ne,optional:ue})=>{if(ue||s.delete(Z.locatorHash),n.has(Z.locatorHash))return;n.add(Z.locatorHash);let te=i.get(Z.locatorHash);if(!te)throw new Error(`Assertion failed: The package (${Ct(r.configuration,Z)}) should have been registered`);let O=[],N=[],ce=[],he=[],xe=[];for(let Re of Array.from(te.dependencies.values())){if(te.peerDependencies.has(Re.identHash)&&te.locatorHash!==ne)continue;if(qA(Re))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");a.delete(Re.descriptorHash);let se=ue;if(!se){let G=te.dependenciesMeta.get(Tt(Re));if(typeof G<"u"){let fe=G.get(null);typeof fe<"u"&&fe.optional&&(se=!0)}}let Ae=t.get(Re.descriptorHash);if(!Ae)throw new Error(`Assertion failed: The resolution (${$t(r.configuration,Re)}) should have been registered`);let ye=y.get(Ae)||i.get(Ae);if(!ye)throw new Error(`Assertion failed: The package (${Ae}, resolved from ${$t(r.configuration,Re)}) should have been registered`);if(ye.peerDependencies.size===0){x(Re,ye,new Map,{top:ne,optional:se});continue}let ge,oe,Ye=new Set,ie;N.push(()=>{ge=jk(Re,Z.locatorHash),oe=Gk(ye,Z.locatorHash),te.dependencies.delete(Re.identHash),te.dependencies.set(ge.identHash,ge),t.set(ge.descriptorHash,oe.locatorHash),e.set(ge.descriptorHash,ge),i.set(oe.locatorHash,oe),O.push([ye,ge,oe])}),ce.push(()=>{var G;ie=new Map;for(let fe of oe.peerDependencies.values()){let re=te.dependencies.get(fe.identHash);if(!re&&oC(Z,fe)&&(W.identHash===Z.identHash?re=W:(re=zt(Z,W.range),e.set(re.descriptorHash,re),t.set(re.descriptorHash,Z.locatorHash),a.delete(re.descriptorHash))),(!re||re.range==="missing:")&&oe.dependencies.has(fe.identHash)){oe.peerDependencies.delete(fe.identHash);continue}re||(re=zt(fe,"missing:")),oe.dependencies.set(re.identHash,re),qA(re)&&bc(p,re.descriptorHash).add(oe.locatorHash),g.set(re.identHash,re),re.range==="missing:"&&Ye.add(re.identHash),ie.set(fe.identHash,(G=A.get(fe.identHash))!=null?G:oe.locatorHash)}oe.dependencies=new Map(bn(oe.dependencies,([fe,re])=>Tt(re)))}),he.push(()=>{if(!i.has(oe.locatorHash))return;let G=c.get(ye.locatorHash);typeof G=="number"&&G>=2&&B();let fe=c.get(ye.locatorHash),re=typeof fe<"u"?fe+1:1;c.set(ye.locatorHash,re),x(ge,oe,ie,{top:ne,optional:se}),c.set(ye.locatorHash,re-1)}),xe.push(()=>{let G=te.dependencies.get(Re.identHash);if(typeof G>"u")throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");let fe=t.get(G.descriptorHash);if(typeof fe>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");if(bc(m,fe).add(Z.locatorHash),!!i.has(oe.locatorHash)){for(let re of oe.peerDependencies.values()){let de=ie.get(re.identHash);if(typeof de>"u")throw new Error("Assertion failed: Expected the peer dependency ident to be registered");hf(pf(d,de),Tt(re)).push(oe.locatorHash)}for(let re of Ye)oe.dependencies.delete(re)}})}for(let Re of[...N,...ce])Re();let De;do{De=!0;for(let[Re,se,Ae]of O){let ye=pf(h,Re.locatorHash),ge=tn(...[...Ae.dependencies.values()].map(G=>{let fe=G.range!=="missing:"?t.get(G.descriptorHash):"missing:";if(typeof fe>"u")throw new Error(`Assertion failed: Expected the resolution for ${$t(r.configuration,G)} to have been registered`);return fe===ne?`${fe} (top)`:fe}),se.identHash),oe=ye.get(ge);if(typeof oe>"u"){ye.set(ge,se);continue}if(oe===se)continue;i.delete(Ae.locatorHash),e.delete(se.descriptorHash),t.delete(se.descriptorHash),n.delete(Ae.locatorHash);let Ye=p.get(se.descriptorHash)||[],ie=[te.locatorHash,...Ye];p.delete(se.descriptorHash);for(let G of ie){let fe=i.get(G);typeof fe>"u"||(fe.dependencies.get(se.identHash).descriptorHash!==oe.descriptorHash&&(De=!1),fe.dependencies.set(se.identHash,oe))}}}while(!De);for(let Re of[...he,...xe])Re()};for(let W of r.workspaces){let Z=W.anchoredLocator;a.delete(W.anchoredDescriptor.descriptorHash),x(W.anchoredDescriptor,Z,new Map,{top:Z.locatorHash,optional:!1})}let H;(A=>(A[A.NotProvided=0]="NotProvided",A[A.NotCompatible=1]="NotCompatible"))(H||(H={}));let q=[];for(let[W,Z]of m){let A=i.get(W);if(typeof A>"u")throw new Error("Assertion failed: Expected the root to be registered");let ne=d.get(W);if(!(typeof ne>"u"))for(let ue of Z){let te=i.get(ue);if(!(typeof te>"u"))for(let[O,N]of ne){let ce=en(O);if(te.peerDependencies.has(ce.identHash))continue;let he=`p${tn(ue,O,W).slice(0,5)}`;o.set(he,{subject:ue,requested:ce,rootRequester:W,allRequesters:N});let xe=A.dependencies.get(ce.identHash);if(typeof xe<"u"){let De=S(xe),Re=(X=De.version)!=null?X:"0.0.0",se=new Set;for(let ye of N){let ge=i.get(ye);if(typeof ge>"u")throw new Error("Assertion failed: Expected the link to be registered");let oe=ge.peerDependencies.get(ce.identHash);if(typeof oe>"u")throw new Error("Assertion failed: Expected the ident to be registered");se.add(oe.range)}[...se].every(ye=>{if(ye.startsWith(Ur.protocol)){if(!r.tryWorkspaceByLocator(De))return!1;ye=ye.slice(Ur.protocol.length),(ye==="^"||ye==="~")&&(ye="*")}return Fc(Re,ye)})||q.push({type:1,subject:te,requested:ce,requester:A,version:Re,hash:he,requirementCount:N.length})}else{let De=A.peerDependenciesMeta.get(O);De!=null&&De.optional||q.push({type:0,subject:te,requested:ce,requester:A,hash:he})}}}}let _=[W=>Yk(W.subject),W=>Tt(W.requested),W=>`${W.type}`];l==null||l.startSectionSync({reportFooter:()=>{l.reportWarning(0,`Some peer dependencies are incorrectly met; run ${_e(r.configuration,"yarn explain peer-requirements <hash>",Ke.CODE)} for details, where ${_e(r.configuration,"<hash>",Ke.CODE)} is the six-letter p-prefixed code`)},skipIfEmpty:!0},()=>{for(let W of bn(q,_))switch(W.type){case 0:l.reportWarning(2,`${Ct(r.configuration,W.subject)} doesn't provide ${ai(r.configuration,W.requested)} (${_e(r.configuration,W.hash,Ke.CODE)}), requested by ${ai(r.configuration,W.requester)}`);break;case 1:{let Z=W.requirementCount>1?"and some of its descendants request":"requests";l.reportWarning(60,`${Ct(r.configuration,W.subject)} provides ${ai(r.configuration,W.requested)} (${_e(r.configuration,W.hash,Ke.CODE)}) with version ${lC(r.configuration,W.version)}, which doesn't satisfy what ${ai(r.configuration,W.requester)} ${Z}`)}break}})}var Sh=class{constructor(e,t){this.values=new Map;this.hits=new Map;this.enumerators=new Map;this.configuration=e;let i=this.getRegistryPath();this.isNew=!M.existsSync(i),this.sendReport(t),this.startBuffer()}reportVersion(e){this.reportValue("version",e.replace(/-git\..*/,"-git"))}reportCommandName(e){this.reportValue("commandName",e||"<none>")}reportPluginName(e){this.reportValue("pluginName",e)}reportProject(e){this.reportEnumerator("projectCount",e)}reportInstall(e){this.reportHit("installCount",e)}reportPackageExtension(e){this.reportValue("packageExtension",e)}reportWorkspaceCount(e){this.reportValue("workspaceCount",String(e))}reportDependencyCount(e){this.reportValue("dependencyCount",String(e))}reportValue(e,t){bc(this.values,e).add(t)}reportEnumerator(e,t){bc(this.enumerators,e).add(tn(t))}reportHit(e,t="*"){let i=pf(this.hits,e),n=La(i,t,()=>0);i.set(t,n+1)}getRegistryPath(){let e=this.configuration.get("globalFolder");return v.join(e,"telemetry.json")}sendReport(e){var u,g,h;let t=this.getRegistryPath(),i;try{i=M.readJsonSync(t)}catch{i={}}let n=Date.now(),s=this.configuration.get("telemetryInterval")*24*60*60*1e3,a=((u=i.lastUpdate)!=null?u:n+s+Math.floor(s*Math.random()))+s;if(a>n&&i.lastUpdate!=null)return;try{M.mkdirSync(v.dirname(t),{recursive:!0}),M.writeJsonSync(t,{lastUpdate:n})}catch{return}if(a>n||!i.blocks)return;let l=`https://browser-http-intake.logs.datadoghq.eu/v1/input/${e}?ddsource=yarn`,c=p=>DR(l,p,{configuration:this.configuration}).catch(()=>{});for(let[p,d]of Object.entries((g=i.blocks)!=null?g:{})){if(Object.keys(d).length===0)continue;let m=d;m.userId=p,m.reportType="primary";for(let S of Object.keys((h=m.enumerators)!=null?h:{}))m.enumerators[S]=m.enumerators[S].length;c(m);let y=new Map,B=20;for(let[S,x]of Object.entries(m.values))x.length>0&&y.set(S,x.slice(0,B));for(;y.size>0;){let S={};S.userId=p,S.reportType="secondary",S.metrics={};for(let[x,F]of y)S.metrics[x]=F.shift(),F.length===0&&y.delete(x);c(S)}}}applyChanges(){var o,a,l,c,u,g,h,p,d;let e=this.getRegistryPath(),t;try{t=M.readJsonSync(e)}catch{t={}}let i=(o=this.configuration.get("telemetryUserId"))!=null?o:"*",n=t.blocks=(a=t.blocks)!=null?a:{},s=n[i]=(l=n[i])!=null?l:{};for(let m of this.hits.keys()){let y=s.hits=(c=s.hits)!=null?c:{},B=y[m]=(u=y[m])!=null?u:{};for(let[S,x]of this.hits.get(m))B[S]=((g=B[S])!=null?g:0)+x}for(let m of["values","enumerators"])for(let y of this[m].keys()){let B=s[m]=(h=s[m])!=null?h:{};B[y]=[...new Set([...(p=B[y])!=null?p:[],...(d=this[m].get(y))!=null?d:[]])]}M.mkdirSync(v.dirname(e),{recursive:!0}),M.writeJsonSync(e,t)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch{}})}};var XN=J("child_process"),M$=ve(cc());var ZN=J("fs");var vh=new Map([["constraints",[["constraints","query"],["constraints","source"],["constraints"]]],["exec",[]],["interactive-tools",[["search"],["upgrade-interactive"]]],["stage",[["stage"]]],["typescript",[]],["version",[["version","apply"],["version","check"],["version"]]],["workspace-tools",[["workspaces","focus"],["workspaces","foreach"]]]]);function r1e(r){let e=K.fromPortablePath(r);process.on("SIGINT",()=>{}),e?(0,XN.execFileSync)(process.execPath,[e,...process.argv.slice(2)],{stdio:"inherit",env:{...process.env,YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"}}):(0,XN.execFileSync)(e,process.argv.slice(2),{stdio:"inherit",env:{...process.env,YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"}})}async function _0({binaryVersion:r,pluginConfiguration:e}){async function t(){let n=new jn({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:r});try{await i(n)}catch(s){process.stdout.write(n.error(s)),process.exitCode=1}}async function i(n){var m,y,B,S,x;let s=process.versions.node,o=">=12 <14 || 14.2 - 14.9 || >14.10.0";if(!me.parseOptionalBoolean(process.env.YARN_IGNORE_NODE)&&!Qt.satisfiesWithPrereleases(s,o))throw new we(`This tool requires a Node version compatible with ${o} (got ${s}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);let l=await Ee.find(K.toPortablePath(process.cwd()),e,{usePath:!0,strict:!1}),c=l.get("yarnPath"),u=l.get("ignorePath"),g=l.get("ignoreCwd"),h=K.toPortablePath(K.resolve(process.argv[1])),p=F=>M.readFilePromise(F).catch(()=>Buffer.of());if(!u&&!g&&await(async()=>c===h||Buffer.compare(...await Promise.all([p(c),p(h)]))===0)()){process.env.YARN_IGNORE_PATH="1",process.env.YARN_IGNORE_CWD="1",await i(n);return}else if(c!==null&&!u)if(!M.existsSync(c))process.stdout.write(n.error(new Error(`The "yarn-path" option has been set (in ${l.sources.get("yarnPath")}), but the specified location doesn't exist (${c}).`))),process.exitCode=1;else try{r1e(c)}catch(F){process.exitCode=F.code||1}else{u&&delete process.env.YARN_IGNORE_PATH,l.get("enableTelemetry")&&!M$.isCI&&process.stdout.isTTY&&(Ee.telemetry=new Sh(l,"puba9cdc10ec5790a2cf4969dd413a47270")),(m=Ee.telemetry)==null||m.reportVersion(r);for(let[_,X]of l.plugins.entries()){vh.has((B=(y=_.match(/^@yarnpkg\/plugin-(.*)$/))==null?void 0:y[1])!=null?B:"")&&((S=Ee.telemetry)==null||S.reportPluginName(_));for(let W of X.commands||[])n.register(W)}let H=n.process(process.argv.slice(2));H.help||(x=Ee.telemetry)==null||x.reportCommandName(H.path.join(" "));let q=H.cwd;if(typeof q<"u"&&!g){let _=(0,ZN.realpathSync)(process.cwd()),X=(0,ZN.realpathSync)(q);if(_!==X){process.chdir(q),await t();return}}await n.runExit(H,{cwd:K.toPortablePath(process.cwd()),plugins:e,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr})}}return t().catch(n=>{process.stdout.write(n.stack||n.message),process.exitCode=1}).finally(()=>M.rmtempPromise())}function K$(r){r.Command.Path=(...e)=>t=>{t.paths=t.paths||[],t.paths.push(e)};for(let e of["Array","Boolean","String","Proxy","Rest","Counter"])r.Command[e]=(...t)=>(i,n)=>{let s=r.Option[e](...t);Object.defineProperty(i,`__${n}`,{configurable:!1,enumerable:!0,get(){return s},set(o){this[n]=o}})};return r}var Tm={};ct(Tm,{BaseCommand:()=>Pe,WorkspaceRequiredError:()=>lt,getDynamicLibs:()=>_ie,getPluginConfiguration:()=>wb,main:()=>_0,openWorkspace:()=>Hh,pluginCommands:()=>vh});var Pe=class extends Qe{constructor(){super(...arguments);this.cwd=z.String("--cwd",{hidden:!0})}};var lt=class extends we{constructor(e,t){let i=v.relative(e,t),n=v.join(e,ot.fileName);super(`This command can only be run from within a workspace of your project (${i} isn't a workspace of ${n}).`)}};var AYe=ve(zr());As();var lYe=ve(VT()),_ie=()=>new Map([["@yarnpkg/cli",Tm],["@yarnpkg/core",om],["@yarnpkg/fslib",zp],["@yarnpkg/libzip",xC],["@yarnpkg/parsers",rd],["@yarnpkg/shell",FC],["clipanion",gd],["semver",AYe],["typanion",hn],["yup",lYe]]);async function Hh(r,e){let{project:t,workspace:i}=await Ge.find(r,e);if(!i)throw new lt(t.cwd,e);return i}var KVe=ve(zr());As();var UVe=ve(VT());var CO={};ct(CO,{dedupeUtils:()=>Fb,default:()=>y4e,suggestUtils:()=>qh});var _ae=ve(cc());var Use=ve(Um());As();var qh={};ct(qh,{Modifier:()=>HL,Strategy:()=>xb,Target:()=>Hm,WorkspaceModifier:()=>Nse,applyModifier:()=>Lse,extractDescriptorFromPath:()=>jL,extractRangeModifier:()=>Tse,fetchDescriptorFrom:()=>GL,findProjectDescriptors:()=>Kse,getModifier:()=>jm,getSuggestedDescriptors:()=>Gm,makeWorkspaceDescriptor:()=>Mse,toWorkspaceModifier:()=>Ose});var UL=ve(zr()),vqe="workspace:",Hm=(i=>(i.REGULAR="dependencies",i.DEVELOPMENT="devDependencies",i.PEER="peerDependencies",i))(Hm||{}),HL=(i=>(i.CARET="^",i.TILDE="~",i.EXACT="",i))(HL||{}),Nse=(i=>(i.CARET="^",i.TILDE="~",i.EXACT="*",i))(Nse||{}),xb=(s=>(s.KEEP="keep",s.REUSE="reuse",s.PROJECT="project",s.LATEST="latest",s.CACHE="cache",s))(xb||{});function jm(r,e){return r.exact?"":r.caret?"^":r.tilde?"~":e.configuration.get("defaultSemverRangePrefix")}var Pqe=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function Tse(r,{project:e}){let t=r.match(Pqe);return t?t[1]:e.configuration.get("defaultSemverRangePrefix")}function Lse(r,e){let{protocol:t,source:i,params:n,selector:s}=P.parseRange(r.range);return UL.default.valid(s)&&(s=`${e}${r.range}`),P.makeDescriptor(r,P.makeRange({protocol:t,source:i,params:n,selector:s}))}function Ose(r){switch(r){case"^":return"^";case"~":return"~";case"":return"*";default:throw new Error(`Assertion failed: Unknown modifier: "${r}"`)}}function Mse(r,e){return P.makeDescriptor(r.anchoredDescriptor,`${vqe}${Ose(e)}`)}async function Kse(r,{project:e,target:t}){let i=new Map,n=s=>{let o=i.get(s.descriptorHash);return o||i.set(s.descriptorHash,o={descriptor:s,locators:[]}),o};for(let s of e.workspaces)if(t==="peerDependencies"){let o=s.manifest.peerDependencies.get(r.identHash);o!==void 0&&n(o).locators.push(s.anchoredLocator)}else{let o=s.manifest.dependencies.get(r.identHash),a=s.manifest.devDependencies.get(r.identHash);t==="devDependencies"?a!==void 0?n(a).locators.push(s.anchoredLocator):o!==void 0&&n(o).locators.push(s.anchoredLocator):o!==void 0?n(o).locators.push(s.anchoredLocator):a!==void 0&&n(a).locators.push(s.anchoredLocator)}return i}async function jL(r,{cwd:e,workspace:t}){return await xqe(async i=>{v.isAbsolute(r)||(r=v.relative(t.cwd,v.resolve(e,r)),r.match(/^\.{0,2}\//)||(r=`./${r}`));let{project:n}=t,s=await GL(P.makeIdent(null,"archive"),r,{project:t.project,cache:i,workspace:t});if(!s)throw new Error("Assertion failed: The descriptor should have been found");let o=new $r,a=n.configuration.makeResolver(),l=n.configuration.makeFetcher(),c={checksums:n.storedChecksums,project:n,cache:i,fetcher:l,report:o,resolver:a},u=a.bindDescriptor(s,t.anchoredLocator,c),g=P.convertDescriptorToLocator(u),h=await l.fetch(g,c),p=await ot.find(h.prefixPath,{baseFs:h.packageFs});if(!p.name)throw new Error("Target path doesn't have a name");return P.makeDescriptor(p.name,r)})}async function Gm(r,{project:e,workspace:t,cache:i,target:n,modifier:s,strategies:o,maxResults:a=1/0}){if(!(a>=0))throw new Error(`Invalid maxResults (${a})`);if(r.range!=="unknown")return{suggestions:[{descriptor:r,name:`Use ${P.prettyDescriptor(e.configuration,r)}`,reason:"(unambiguous explicit request)"}],rejections:[]};let l=typeof t<"u"&&t!==null&&t.manifest[n].get(r.identHash)||null,c=[],u=[],g=async h=>{try{await h()}catch(p){u.push(p)}};for(let h of o){if(c.length>=a)break;switch(h){case"keep":await g(async()=>{l&&c.push({descriptor:l,name:`Keep ${P.prettyDescriptor(e.configuration,l)}`,reason:"(no changes)"})});break;case"reuse":await g(async()=>{for(let{descriptor:p,locators:d}of(await Kse(r,{project:e,target:n})).values()){if(d.length===1&&d[0].locatorHash===t.anchoredLocator.locatorHash&&o.includes("keep"))continue;let m=`(originally used by ${P.prettyLocator(e.configuration,d[0])}`;m+=d.length>1?` and ${d.length-1} other${d.length>2?"s":""})`:")",c.push({descriptor:p,name:`Reuse ${P.prettyDescriptor(e.configuration,p)}`,reason:m})}});break;case"cache":await g(async()=>{for(let p of e.storedDescriptors.values())p.identHash===r.identHash&&c.push({descriptor:p,name:`Reuse ${P.prettyDescriptor(e.configuration,p)}`,reason:"(already used somewhere in the lockfile)"})});break;case"project":await g(async()=>{if(t.manifest.name!==null&&r.identHash===t.manifest.name.identHash)return;let p=e.tryWorkspaceByIdent(r);if(p===null)return;let d=Mse(p,s);c.push({descriptor:d,name:`Attach ${P.prettyDescriptor(e.configuration,d)}`,reason:`(local workspace at ${$.pretty(e.configuration,p.relativeCwd,$.Type.PATH)})`})});break;case"latest":await g(async()=>{if(r.range!=="unknown")c.push({descriptor:r,name:`Use ${P.prettyRange(e.configuration,r.range)}`,reason:"(explicit range requested)"});else if(n==="peerDependencies")c.push({descriptor:P.makeDescriptor(r,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(!e.configuration.get("enableNetwork"))c.push({descriptor:null,name:"Resolve from latest",reason:$.pretty(e.configuration,"(unavailable because enableNetwork is toggled off)","grey")});else{let p=await GL(r,"latest",{project:e,cache:i,workspace:t,preserveModifier:!1});p&&(p=Lse(p,s),c.push({descriptor:p,name:`Use ${P.prettyDescriptor(e.configuration,p)}`,reason:"(resolved from latest)"}))}});break}}return{suggestions:c.slice(0,a),rejections:u.slice(0,a)}}async function GL(r,e,{project:t,cache:i,workspace:n,preserveModifier:s=!0}){let o=P.makeDescriptor(r,e),a=new $r,l=t.configuration.makeFetcher(),c=t.configuration.makeResolver(),u={project:t,fetcher:l,cache:i,checksums:t.storedChecksums,report:a,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},g={...u,resolver:c,fetchOptions:u},h=c.bindDescriptor(o,n.anchoredLocator,g),p=await c.getCandidates(h,new Map,g);if(p.length===0)return null;let d=p[0],{protocol:m,source:y,params:B,selector:S}=P.parseRange(P.convertToManifestRange(d.reference));if(m===t.configuration.get("defaultProtocol")&&(m=null),UL.default.valid(S)&&s!==!1){let x=typeof s=="string"?s:o.range;S=Tse(x,{project:t})+S}return P.makeDescriptor(d,P.makeRange({protocol:m,source:y,params:B,selector:S}))}async function xqe(r){return await M.mktempPromise(async e=>{let t=Ee.create(e);return t.useWithSource(e,{enableMirror:!1,compressionLevel:0},e,{overwrite:!0}),await r(new Dt(e,{configuration:t,check:!1,immutable:!1}))})}var cu=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.exact=z.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=z.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=z.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.dev=z.Boolean("-D,--dev",!1,{description:"Add a package as a dev dependency"});this.peer=z.Boolean("-P,--peer",!1,{description:"Add a package as a peer dependency"});this.optional=z.Boolean("-O,--optional",!1,{description:"Add / upgrade a package to an optional regular / peer dependency"});this.preferDev=z.Boolean("--prefer-dev",!1,{description:"Add / upgrade a package to a dev dependency"});this.interactive=z.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"});this.cached=z.Boolean("--cached",!1,{description:"Reuse the highest version already used somewhere within the project"});this.mode=z.String("--mode",{description:"Change what artifacts installs generate",validator:Xi(ts)});this.silent=z.Boolean("--silent",{hidden:!0});this.packages=z.Rest()}async execute(){var B;let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState({restoreResolutions:!1});let o=(B=this.interactive)!=null?B:t.get("preferInteractive"),a=o||t.get("preferReuse"),l=jm(this,i),c=[a?"reuse":void 0,"project",this.cached?"cache":void 0,"latest"].filter(S=>typeof S<"u"),u=o?1/0:1,g=await Promise.all(this.packages.map(async S=>{let x=S.match(/^\.{0,2}\//)?await jL(S,{cwd:this.context.cwd,workspace:n}):P.tryParseDescriptor(S),F=S.match(/^(https?:|git@github)/);if(F)throw new we(`It seems you are trying to add a package using a ${$.pretty(t,`${F[0]}...`,$.Type.RANGE)} url; we now require package names to be explicitly specified. +Try running the command again with the package name prefixed: ${$.pretty(t,"yarn add",$.Type.CODE)} ${$.pretty(t,P.makeDescriptor(P.makeIdent(null,"my-package"),`${F[0]}...`),$.Type.DESCRIPTOR)}`);if(!x)throw new we(`The ${$.pretty(t,S,$.Type.CODE)} string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?`);let H=kqe(n,x,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional});return await Promise.all(H.map(async _=>{let X=await Gm(x,{project:i,workspace:n,cache:s,target:_,modifier:l,strategies:c,maxResults:u});return{request:x,suggestedDescriptors:X,target:_}}))})).then(S=>S.flat()),h=await ta.start({configuration:t,stdout:this.context.stdout,suggestInstall:!1},async S=>{for(let{request:x,suggestedDescriptors:{suggestions:F,rejections:H}}of g)if(F.filter(_=>_.descriptor!==null).length===0){let[_]=H;if(typeof _>"u")throw new Error("Assertion failed: Expected an error to have been set");i.configuration.get("enableNetwork")?S.reportError(27,`${P.prettyDescriptor(t,x)} can't be resolved to a satisfying range`):S.reportError(27,`${P.prettyDescriptor(t,x)} can't be resolved to a satisfying range (note: network resolution has been disabled)`),S.reportSeparator(),S.reportExceptionOnce(_)}});if(h.hasErrors())return h.exitCode();let p=!1,d=[],m=[];for(let{suggestedDescriptors:{suggestions:S},target:x}of g){let F,H=S.filter(W=>W.descriptor!==null),q=H[0].descriptor,_=H.every(W=>P.areDescriptorsEqual(W.descriptor,q));H.length===1||_?F=q:(p=!0,{answer:F}=await(0,Use.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:S.map(({descriptor:W,name:Z,reason:A})=>W?{name:Z,hint:A,descriptor:W}:{name:Z,hint:A,disabled:!0}),onCancel:()=>process.exit(130),result(W){return this.find(W,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let X=n.manifest[x].get(F.identHash);(typeof X>"u"||X.descriptorHash!==F.descriptorHash)&&(n.manifest[x].set(F.identHash,F),this.optional&&(x==="dependencies"?n.manifest.ensureDependencyMeta({...F,range:"unknown"}).optional=!0:x==="peerDependencies"&&(n.manifest.ensurePeerDependencyMeta({...F,range:"unknown"}).optional=!0)),typeof X>"u"?d.push([n,x,F,c]):m.push([n,x,X,F]))}return await t.triggerMultipleHooks(S=>S.afterWorkspaceDependencyAddition,d),await t.triggerMultipleHooks(S=>S.afterWorkspaceDependencyReplacement,m),p&&this.context.stdout.write(` +`),(await He.start({configuration:t,json:this.json,stdout:this.context.stdout,includeLogs:!this.context.quiet},async S=>{await i.install({cache:s,report:S,mode:this.mode})})).exitCode()}};cu.paths=[["add"]],cu.usage=Qe.Usage({description:"add dependencies to the project",details:"\n This command adds a package to the package.json for the nearest workspace.\n\n - If it didn't exist before, the package will by default be added to the regular `dependencies` field, but this behavior can be overriden thanks to the `-D,--dev` flag (which will cause the dependency to be added to the `devDependencies` field instead) and the `-P,--peer` flag (which will do the same but for `peerDependencies`).\n\n - If the package was already listed in your dependencies, it will by default be upgraded whether it's part of your `dependencies` or `devDependencies` (it won't ever update `peerDependencies`, though).\n\n - If set, the `--prefer-dev` flag will operate as a more flexible `-D,--dev` in that it will add the package to your `devDependencies` if it isn't already listed in either `dependencies` or `devDependencies`, but it will also happily upgrade your `dependencies` if that's what you already use (whereas `-D,--dev` would throw an exception).\n\n - If set, the `-O,--optional` flag will add the package to the `optionalDependencies` field and, in combination with the `-P,--peer` flag, it will add the package as an optional peer dependency. If the package was already listed in your `dependencies`, it will be upgraded to `optionalDependencies`. If the package was already listed in your `peerDependencies`, in combination with the `-P,--peer` flag, it will be upgraded to an optional peer dependency: `\"peerDependenciesMeta\": { \"<package>\": { \"optional\": true } }`\n\n - If the added package doesn't specify a range at all its `latest` tag will be resolved and the returned version will be used to generate a new semver range (using the `^` modifier by default unless otherwise configured via the `defaultSemverRangePrefix` configuration, or the `~` modifier if `-T,--tilde` is specified, or no modifier at all if `-E,--exact` is specified). Two exceptions to this rule: the first one is that if the package is a workspace then its local version will be used, and the second one is that if you use `-P,--peer` the default range will be `*` and won't be resolved at all.\n\n - If the added package specifies a range (such as `^1.0.0`, `latest`, or `rc`), Yarn will add this range as-is in the resulting package.json entry (in particular, tags such as `rc` will be encoded as-is rather than being converted into a semver range).\n\n If the `--cached` option is used, Yarn will preferably reuse the highest version already used somewhere within the project, even if through a transitive dependency.\n\n If the `-i,--interactive` option is used (or if the `preferInteractive` settings is toggled on) the command will first try to check whether other workspaces in the project use the specified package and, if so, will offer to reuse them.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n For a compilation of all the supported protocols, please consult the dedicated page from our website: https://yarnpkg.com/features/protocols.\n ",examples:[["Add a regular package to the current workspace","$0 add lodash"],["Add a specific version for a package to the current workspace","$0 add lodash@1.2.3"],["Add a package from a GitHub repository (the master branch) to the current workspace using a URL","$0 add lodash@https://github.com/lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol","$0 add lodash@github:lodash/lodash"],["Add a package from a GitHub repository (the master branch) to the current workspace using the GitHub protocol (shorthand)","$0 add lodash@lodash/lodash"],["Add a package from a specific branch of a GitHub repository to the current workspace using the GitHub protocol (shorthand)","$0 add lodash-es@lodash/lodash#es"]]});function kqe(r,e,{dev:t,peer:i,preferDev:n,optional:s}){let o=r.manifest["dependencies"].has(e.identHash),a=r.manifest["devDependencies"].has(e.identHash),l=r.manifest["peerDependencies"].has(e.identHash);if((t||i)&&o)throw new we(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!t&&!i&&l)throw new we(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a peer dependency - use either of -D or -P, or remove it from your peer dependencies first`);if(s&&a)throw new we(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a dev dependency - remove the -O flag or remove it from your dev dependencies first`);if(s&&!i&&l)throw new we(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a peer dependency - remove the -O flag or add the -P flag or remove it from your peer dependencies first`);if((t||n)&&s)throw new we(`Package "${P.prettyIdent(r.project.configuration,e)}" cannot simultaneously be a dev dependency and an optional dependency`);let c=[];return i&&c.push("peerDependencies"),(t||n)&&c.push("devDependencies"),s&&c.push("dependencies"),c.length>0?c:a?["devDependencies"]:l?["peerDependencies"]:["dependencies"]}var uu=class extends Pe{constructor(){super(...arguments);this.verbose=z.Boolean("-v,--verbose",!1,{description:"Print both the binary name and the locator of the package that provides the binary"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.name=z.String({required:!1})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,locator:n}=await Ge.find(t,this.context.cwd);if(await i.restoreInstallState(),this.name){let a=(await Yt.getPackageAccessibleBinaries(n,{project:i})).get(this.name);if(!a)throw new we(`Couldn't find a binary named "${this.name}" for package "${P.prettyLocator(t,n)}"`);let[,l]=a;return this.context.stdout.write(`${l} +`),0}return(await He.start({configuration:t,json:this.json,stdout:this.context.stdout},async o=>{let a=await Yt.getPackageAccessibleBinaries(n,{project:i}),c=Array.from(a.keys()).reduce((u,g)=>Math.max(u,g.length),0);for(let[u,[g,h]]of a)o.reportJson({name:u,source:P.stringifyIdent(g),path:h});if(this.verbose)for(let[u,[g]]of a)o.reportInfo(null,`${u.padEnd(c," ")} ${P.prettyLocator(t,g)}`);else for(let u of a.keys())o.reportInfo(null,u)})).exitCode()}};uu.paths=[["bin"]],uu.usage=Qe.Usage({description:"get the path to a binary script",details:` + When used without arguments, this command will print the list of all the binaries available in the current workspace. Adding the \`-v,--verbose\` flag will cause the output to contain both the binary name and the locator of the package that provides the binary. + + When an argument is specified, this command will just print the path to the binary on the standard output and exit. Note that the reported path may be stored within a zip archive. + `,examples:[["List all the available binaries","$0 bin"],["Print the path to a specific binary","$0 bin eslint"]]});var gu=class extends Pe{constructor(){super(...arguments);this.mirror=z.Boolean("--mirror",!1,{description:"Remove the global cache files instead of the local cache files"});this.all=z.Boolean("--all",!1,{description:"Remove both the global cache files and the local cache files of the current project"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=await Dt.find(t);return(await He.start({configuration:t,stdout:this.context.stdout},async()=>{let s=(this.all||this.mirror)&&i.mirrorCwd!==null,o=!this.mirror;s&&(await M.removePromise(i.mirrorCwd),await t.triggerHook(a=>a.cleanGlobalArtifacts,t)),o&&await M.removePromise(i.cwd)})).exitCode()}};gu.paths=[["cache","clean"],["cache","clear"]],gu.usage=Qe.Usage({description:"remove the shared cache files",details:` + This command will remove all the files from the cache. + `,examples:[["Remove all the local archives","$0 cache clean"],["Remove all the archives stored in the ~/.yarn directory","$0 cache clean --mirror"]]});var Hse=ve(cb()),YL=J("util"),fu=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.unsafe=z.Boolean("--no-redacted",!1,{description:"Don't redact secrets (such as tokens) from the output"});this.name=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=this.name.replace(/[.[].*$/,""),n=this.name.replace(/^[^.[]*/,"");if(typeof t.settings.get(i)>"u")throw new we(`Couldn't find a configuration settings named "${i}"`);let o=t.getSpecial(i,{hideSecrets:!this.unsafe,getNativePaths:!0}),a=me.convertMapsToIndexableObjects(o),l=n?(0,Hse.default)(a,n):a,c=await He.start({configuration:t,includeFooter:!1,json:this.json,stdout:this.context.stdout},async u=>{u.reportJson(l)});if(!this.json){if(typeof l=="string")return this.context.stdout.write(`${l} +`),c.exitCode();YL.inspect.styles.name="cyan",this.context.stdout.write(`${(0,YL.inspect)(l,{depth:1/0,colors:t.get("enableColors"),compact:!1})} +`)}return c.exitCode()}};fu.paths=[["config","get"]],fu.usage=Qe.Usage({description:"read a configuration settings",details:` + This command will print a configuration setting. + + Secrets (such as tokens) will be redacted from the output by default. If this behavior isn't desired, set the \`--no-redacted\` to get the untransformed value. + `,examples:[["Print a simple configuration setting","yarn config get yarnPath"],["Print a complex configuration setting","yarn config get packageExtensions"],["Print a nested field from the configuration",`yarn config get 'npmScopes["my-company"].npmRegistryServer'`],["Print a token from the configuration","yarn config get npmAuthToken --no-redacted"],["Print a configuration setting as JSON","yarn config get packageExtensions --json"]]});var $oe=ve(XL()),eae=ve(cb()),tae=ve(_oe()),ZL=J("util"),hu=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Set complex configuration settings to JSON values"});this.home=z.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=z.String();this.value=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=()=>{if(!t.projectCwd)throw new we("This command must be run from within a project folder");return t.projectCwd},n=this.name.replace(/[.[].*$/,""),s=this.name.replace(/^[^.[]*\.?/,"");if(typeof t.settings.get(n)>"u")throw new we(`Couldn't find a configuration settings named "${n}"`);if(n==="enableStrictSettings")throw new we("This setting only affects the file it's in, and thus cannot be set from the CLI");let a=this.json?JSON.parse(this.value):this.value;await(this.home?d=>Ee.updateHomeConfiguration(d):d=>Ee.updateConfiguration(i(),d))(d=>{if(s){let m=(0,$oe.default)(d);return(0,tae.default)(m,this.name,a),m}else return{...d,[n]:a}});let u=(await Ee.find(this.context.cwd,this.context.plugins)).getSpecial(n,{hideSecrets:!0,getNativePaths:!0}),g=me.convertMapsToIndexableObjects(u),h=s?(0,eae.default)(g,s):g;return(await He.start({configuration:t,includeFooter:!1,stdout:this.context.stdout},async d=>{ZL.inspect.styles.name="cyan",d.reportInfo(0,`Successfully set ${this.name} to ${(0,ZL.inspect)(h,{depth:1/0,colors:t.get("enableColors"),compact:!1})}`)})).exitCode()}};hu.paths=[["config","set"]],hu.usage=Qe.Usage({description:"change a configuration settings",details:` + This command will set a configuration setting. + + When used without the \`--json\` flag, it can only set a simple configuration setting (a string, a number, or a boolean). + + When used with the \`--json\` flag, it can set both simple and complex configuration settings, including Arrays and Objects. + `,examples:[["Set a simple configuration setting (a string, a number, or a boolean)","yarn config set initScope myScope"],["Set a simple configuration setting (a string, a number, or a boolean) using the `--json` flag",'yarn config set initScope --json \\"myScope\\"'],["Set a complex configuration setting (an Array) using the `--json` flag",`yarn config set unsafeHttpWhitelist --json '["*.example.com", "example.com"]'`],["Set a complex configuration setting (an Object) using the `--json` flag",`yarn config set packageExtensions --json '{ "@babel/parser@*": { "dependencies": { "@babel/types": "*" } } }'`],["Set a nested configuration setting",'yarn config set npmScopes.company.npmRegistryServer "https://npm.example.com"'],["Set a nested configuration setting using indexed access for non-simple keys",`yarn config set 'npmRegistries["//npm.example.com"].npmAuthToken' "ffffffff-ffff-ffff-ffff-ffffffffffff"`]]});var cae=ve(XL()),uae=ve(Am()),gae=ve(lae()),pu=class extends Pe{constructor(){super(...arguments);this.home=z.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=()=>{if(!t.projectCwd)throw new we("This command must be run from within a project folder");return t.projectCwd},n=this.name.replace(/[.[].*$/,""),s=this.name.replace(/^[^.[]*\.?/,"");if(typeof t.settings.get(n)>"u")throw new we(`Couldn't find a configuration settings named "${n}"`);let a=this.home?c=>Ee.updateHomeConfiguration(c):c=>Ee.updateConfiguration(i(),c);return(await He.start({configuration:t,includeFooter:!1,stdout:this.context.stdout},async c=>{let u=!1;await a(g=>{if(!(0,uae.default)(g,this.name))return c.reportWarning(0,`Configuration doesn't contain setting ${this.name}; there is nothing to unset`),u=!0,g;let h=s?(0,cae.default)(g):{...g};return(0,gae.default)(h,this.name),h}),u||c.reportInfo(0,`Successfully unset ${this.name}`)})).exitCode()}};pu.paths=[["config","unset"]],pu.usage=Qe.Usage({description:"unset a configuration setting",details:` + This command will unset a configuration setting. + `,examples:[["Unset a simple configuration setting","yarn config unset initScope"],["Unset a complex configuration setting","yarn config unset packageExtensions"],["Unset a nested configuration setting","yarn config unset npmScopes.company.npmRegistryServer"]]});var _L=J("util"),du=class extends Pe{constructor(){super(...arguments);this.verbose=z.Boolean("-v,--verbose",!1,{description:"Print the setting description on top of the regular key/value information"});this.why=z.Boolean("--why",!1,{description:"Print the reason why a setting is set a particular way"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins,{strict:!1});return(await He.start({configuration:t,json:this.json,stdout:this.context.stdout},async n=>{if(t.invalid.size>0&&!this.json){for(let[s,o]of t.invalid)n.reportError(34,`Invalid configuration key "${s}" in ${o}`);n.reportSeparator()}if(this.json){let s=me.sortMap(t.settings.keys(),o=>o);for(let o of s){let a=t.settings.get(o),l=t.getSpecial(o,{hideSecrets:!0,getNativePaths:!0}),c=t.sources.get(o);this.verbose?n.reportJson({key:o,effective:l,source:c}):n.reportJson({key:o,effective:l,source:c,...a})}}else{let s=me.sortMap(t.settings.keys(),l=>l),o=s.reduce((l,c)=>Math.max(l,c.length),0),a={breakLength:1/0,colors:t.get("enableColors"),maxArrayLength:2};if(this.why||this.verbose){let l=s.map(u=>{let g=t.settings.get(u);if(!g)throw new Error(`Assertion failed: This settings ("${u}") should have been registered`);let h=this.why?t.sources.get(u)||"<default>":g.description;return[u,h]}),c=l.reduce((u,[,g])=>Math.max(u,g.length),0);for(let[u,g]of l)n.reportInfo(null,`${u.padEnd(o," ")} ${g.padEnd(c," ")} ${(0,_L.inspect)(t.getSpecial(u,{hideSecrets:!0,getNativePaths:!0}),a)}`)}else for(let l of s)n.reportInfo(null,`${l.padEnd(o," ")} ${(0,_L.inspect)(t.getSpecial(l,{hideSecrets:!0,getNativePaths:!0}),a)}`)}})).exitCode()}};du.paths=[["config"]],du.usage=Qe.Usage({description:"display the current configuration",details:` + This command prints the current active configuration settings. + `,examples:[["Print the active configuration settings","$0 config"]]});As();var Fb={};ct(Fb,{Strategy:()=>qm,acceptedStrategies:()=>FWe,dedupe:()=>$L});var fae=ve(Bn()),qm=(e=>(e.HIGHEST="highest",e))(qm||{}),FWe=new Set(Object.values(qm)),NWe={highest:async(r,e,{resolver:t,fetcher:i,resolveOptions:n,fetchOptions:s})=>{let o=new Map;for(let[a,l]of r.storedResolutions){let c=r.storedDescriptors.get(a);if(typeof c>"u")throw new Error(`Assertion failed: The descriptor (${a}) should have been registered`);me.getSetWithDefault(o,c.identHash).add(l)}return Array.from(r.storedDescriptors.values(),async a=>{if(e.length&&!fae.default.isMatch(P.stringifyIdent(a),e))return null;let l=r.storedResolutions.get(a.descriptorHash);if(typeof l>"u")throw new Error(`Assertion failed: The resolution (${a.descriptorHash}) should have been registered`);let c=r.originalPackages.get(l);if(typeof c>"u"||!t.shouldPersistResolution(c,n))return null;let u=o.get(a.identHash);if(typeof u>"u")throw new Error(`Assertion failed: The resolutions (${a.identHash}) should have been registered`);if(u.size===1)return null;let g=[...u].map(y=>{let B=r.originalPackages.get(y);if(typeof B>"u")throw new Error(`Assertion failed: The package (${y}) should have been registered`);return B.reference}),h=await t.getSatisfying(a,g,n),p=h==null?void 0:h[0];if(typeof p>"u")return null;let d=p.locatorHash,m=r.originalPackages.get(d);if(typeof m>"u")throw new Error(`Assertion failed: The package (${d}) should have been registered`);return d===l?null:{descriptor:a,currentPackage:c,updatedPackage:m}})}};async function $L(r,{strategy:e,patterns:t,cache:i,report:n}){let{configuration:s}=r,o=new $r,a=s.makeResolver(),l=s.makeFetcher(),c={cache:i,checksums:r.storedChecksums,fetcher:l,project:r,report:o,skipIntegrityCheck:!0,cacheOptions:{skipIntegrityCheck:!0}},u={project:r,resolver:a,report:o,fetchOptions:c};return await n.startTimerPromise("Deduplication step",async()=>{let g=NWe[e],h=await g(r,t,{resolver:a,resolveOptions:u,fetcher:l,fetchOptions:c}),p=Pi.progressViaCounter(h.length);await n.reportProgress(p);let d=0;await Promise.all(h.map(B=>B.then(S=>{if(S===null)return;d++;let{descriptor:x,currentPackage:F,updatedPackage:H}=S;n.reportInfo(0,`${P.prettyDescriptor(s,x)} can be deduped from ${P.prettyLocator(s,F)} to ${P.prettyLocator(s,H)}`),n.reportJson({descriptor:P.stringifyDescriptor(x),currentResolution:P.stringifyLocator(F),updatedResolution:P.stringifyLocator(H)}),r.storedResolutions.set(x.descriptorHash,H.locatorHash)}).finally(()=>p.tick())));let m;switch(d){case 0:m="No packages";break;case 1:m="One package";break;default:m=`${d} packages`}let y=$.pretty(s,e,$.Type.CODE);return n.reportInfo(0,`${m} can be deduped using the ${y} strategy`),d})}var Cu=class extends Pe{constructor(){super(...arguments);this.strategy=z.String("-s,--strategy","highest",{description:"The strategy to use when deduping dependencies",validator:Xi(qm)});this.check=z.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.mode=z.String("--mode",{description:"Change what artifacts installs generate",validator:Xi(ts)});this.patterns=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i}=await Ge.find(t,this.context.cwd),n=await Dt.find(t);await i.restoreInstallState({restoreResolutions:!1});let s=0,o=await He.start({configuration:t,includeFooter:!1,stdout:this.context.stdout,json:this.json},async a=>{s=await $L(i,{strategy:this.strategy,patterns:this.patterns,cache:n,report:a})});return o.hasErrors()?o.exitCode():this.check?s?1:0:(await He.start({configuration:t,stdout:this.context.stdout,json:this.json},async l=>{await i.install({cache:n,report:l,mode:this.mode})})).exitCode()}};Cu.paths=[["dedupe"]],Cu.usage=Qe.Usage({description:"deduplicate dependencies with overlapping ranges",details:"\n Duplicates are defined as descriptors with overlapping ranges being resolved and locked to different locators. They are a natural consequence of Yarn's deterministic installs, but they can sometimes pile up and unnecessarily increase the size of your project.\n\n This command dedupes dependencies in the current project using different strategies (only one is implemented at the moment):\n\n - `highest`: Reuses (where possible) the locators with the highest versions. This means that dependencies can only be upgraded, never downgraded. It's also guaranteed that it never takes more than a single pass to dedupe the entire dependency tree.\n\n **Note:** Even though it never produces a wrong dependency tree, this command should be used with caution, as it modifies the dependency tree, which can sometimes cause problems when packages don't strictly follow semver recommendations. Because of this, it is recommended to also review the changes manually.\n\n If set, the `-c,--check` flag will only report the found duplicates, without persisting the modified dependency tree. If changes are found, the command will exit with a non-zero exit code, making it suitable for CI purposes.\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n ### In-depth explanation:\n\n Yarn doesn't deduplicate dependencies by default, otherwise installs wouldn't be deterministic and the lockfile would be useless. What it actually does is that it tries to not duplicate dependencies in the first place.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@*`will cause Yarn to reuse `foo@2.3.4`, even if the latest `foo` is actually `foo@2.10.14`, thus preventing unnecessary duplication.\n\n Duplication happens when Yarn can't unlock dependencies that have already been locked inside the lockfile.\n\n **Example:** If `foo@^2.3.4` (a dependency of a dependency) has already been resolved to `foo@2.3.4`, running `yarn add foo@2.10.14` will cause Yarn to install `foo@2.10.14` because the existing resolution doesn't satisfy the range `2.10.14`. This behavior can lead to (sometimes) unwanted duplication, since now the lockfile contains 2 separate resolutions for the 2 `foo` descriptors, even though they have overlapping ranges, which means that the lockfile can be simplified so that both descriptors resolve to `foo@2.10.14`.\n ",examples:[["Dedupe all packages","$0 dedupe"],["Dedupe all packages using a specific strategy","$0 dedupe --strategy highest"],["Dedupe a specific package","$0 dedupe lodash"],["Dedupe all packages with the `@babel/*` scope","$0 dedupe '@babel/*'"],["Check for duplicates (can be used as a CI step)","$0 dedupe --check"]]});var Vh=class extends Pe{async execute(){let{plugins:e}=await Ee.find(this.context.cwd,this.context.plugins),t=[];for(let o of e){let{commands:a}=o[1];if(a){let c=jn.from(a).definitions();t.push([o[0],c])}}let i=this.cli.definitions(),n=(o,a)=>o.split(" ").slice(1).join()===a.split(" ").slice(1).join(),s=hae()["@yarnpkg/builder"].bundles.standard;for(let o of t){let a=o[1];for(let l of a)i.find(c=>n(c.path,l.path)).plugin={name:o[0],isDefault:s.includes(o[0])}}this.context.stdout.write(`${JSON.stringify(i,null,2)} +`)}};Vh.paths=[["--clipanion=definitions"]];var Xh=class extends Pe{async execute(){this.context.stdout.write(this.cli.usage(null))}};Xh.paths=[["help"],["--help"],["-h"]];var Jm=class extends Pe{constructor(){super(...arguments);this.leadingArgument=z.String();this.args=z.Proxy()}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!P.tryParseIdent(this.leadingArgument)){let t=v.resolve(this.context.cwd,K.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:t})}else return await this.cli.run(["run",this.leadingArgument,...this.args])}};var Zh=class extends Pe{async execute(){this.context.stdout.write(`${Fr||"<unknown>"} +`)}};Zh.paths=[["-v"],["--version"]];var mu=class extends Pe{constructor(){super(...arguments);this.commandName=z.String();this.args=z.Proxy()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,locator:n}=await Ge.find(t,this.context.cwd);return await i.restoreInstallState(),await Yt.executePackageShellcode(n,this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,project:i})}};mu.paths=[["exec"]],mu.usage=Qe.Usage({description:"execute a shell script",details:` + This command simply executes a shell script within the context of the root directory of the active workspace using the portable shell. + + It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + `,examples:[["Execute a single shell command","$0 exec echo Hello World"],["Execute a shell script",'$0 exec "tsc & babel src --out-dir lib"']]});As();var Eu=class extends Pe{constructor(){super(...arguments);this.hash=z.String({required:!1,validator:ad(od(),[Ad(/^p[0-9a-f]{5}$/)])})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i}=await Ge.find(t,this.context.cwd);return await i.restoreInstallState({restoreResolutions:!1}),await i.applyLightResolution(),typeof this.hash<"u"?await LWe(this.hash,i,{stdout:this.context.stdout}):(await He.start({configuration:t,stdout:this.context.stdout,includeFooter:!1},async s=>{var a;let o=[([,l])=>P.stringifyLocator(i.storedPackages.get(l.subject)),([,l])=>P.stringifyIdent(l.requested)];for(let[l,c]of me.sortMap(i.peerRequirements,o)){let u=i.storedPackages.get(c.subject);if(typeof u>"u")throw new Error("Assertion failed: Expected the subject package to have been registered");let g=i.storedPackages.get(c.rootRequester);if(typeof g>"u")throw new Error("Assertion failed: Expected the root package to have been registered");let h=(a=u.dependencies.get(c.requested.identHash))!=null?a:null,p=$.pretty(t,l,$.Type.CODE),d=P.prettyLocator(t,u),m=P.prettyIdent(t,c.requested),y=P.prettyIdent(t,g),B=c.allRequesters.length-1,S=`descendant${B===1?"":"s"}`,x=B>0?` and ${B} ${S}`:"",F=h!==null?"provides":"doesn't provide";s.reportInfo(null,`${p} \u2192 ${d} ${F} ${m} to ${y}${x}`)}})).exitCode()}};Eu.paths=[["explain","peer-requirements"]],Eu.usage=Qe.Usage({description:"explain a set of peer requirements",details:` + A set of peer requirements represents all peer requirements that a dependent must satisfy when providing a given peer request to a requester and its descendants. + + When the hash argument is specified, this command prints a detailed explanation of all requirements of the set corresponding to the hash and whether they're satisfied or not. + + When used without arguments, this command lists all sets of peer requirements and the corresponding hash that can be used to get detailed information about a given set. + + **Note:** A hash is a six-letter p-prefixed code that can be obtained from peer dependency warnings or from the list of all peer requirements (\`yarn explain peer-requirements\`). + `,examples:[["Explain the corresponding set of peer requirements for a hash","$0 explain peer-requirements p1a4ed"],["List all sets of peer requirements","$0 explain peer-requirements"]]});async function LWe(r,e,t){let{configuration:i}=e,n=e.peerRequirements.get(r);if(typeof n>"u")throw new Error(`No peerDependency requirements found for hash: "${r}"`);return(await He.start({configuration:i,stdout:t.stdout,includeFooter:!1},async o=>{var B,S;let a=e.storedPackages.get(n.subject);if(typeof a>"u")throw new Error("Assertion failed: Expected the subject package to have been registered");let l=e.storedPackages.get(n.rootRequester);if(typeof l>"u")throw new Error("Assertion failed: Expected the root package to have been registered");let c=(B=a.dependencies.get(n.requested.identHash))!=null?B:null,u=c!==null?e.storedResolutions.get(c.descriptorHash):null;if(typeof u>"u")throw new Error("Assertion failed: Expected the resolution to have been registered");let g=u!==null?e.storedPackages.get(u):null;if(typeof g>"u")throw new Error("Assertion failed: Expected the provided package to have been registered");let h=[...n.allRequesters.values()].map(x=>{let F=e.storedPackages.get(x);if(typeof F>"u")throw new Error("Assertion failed: Expected the package to be registered");let H=P.devirtualizeLocator(F),q=e.storedPackages.get(H.locatorHash);if(typeof q>"u")throw new Error("Assertion failed: Expected the package to be registered");let _=q.peerDependencies.get(n.requested.identHash);if(typeof _>"u")throw new Error("Assertion failed: Expected the peer dependency to be registered");return{pkg:F,peerDependency:_}});if(g!==null){let x=h.every(({peerDependency:F})=>Qt.satisfiesWithPrereleases(g.version,F.range));o.reportInfo(0,`${P.prettyLocator(i,a)} provides ${P.prettyLocator(i,g)} with version ${P.prettyReference(i,(S=g.version)!=null?S:"<missing>")}, which ${x?"satisfies":"doesn't satisfy"} the following requirements:`)}else o.reportInfo(0,`${P.prettyLocator(i,a)} doesn't provide ${P.prettyIdent(i,n.requested)}, breaking the following requirements:`);o.reportSeparator();let p=$.mark(i),d=[];for(let{pkg:x,peerDependency:F}of me.sortMap(h,H=>P.stringifyLocator(H.pkg))){let q=(g!==null?Qt.satisfiesWithPrereleases(g.version,F.range):!1)?p.Check:p.Cross;d.push({stringifiedLocator:P.stringifyLocator(x),prettyLocator:P.prettyLocator(i,x),prettyRange:P.prettyRange(i,F.range),mark:q})}let m=Math.max(...d.map(({stringifiedLocator:x})=>x.length)),y=Math.max(...d.map(({prettyRange:x})=>x.length));for(let{stringifiedLocator:x,prettyLocator:F,prettyRange:H,mark:q}of me.sortMap(d,({stringifiedLocator:_})=>_))o.reportInfo(null,`${F.padEnd(m+(F.length-x.length)," ")} \u2192 ${H.padEnd(y," ")} ${q}`);d.length>1&&(o.reportSeparator(),o.reportInfo(0,`Note: these requirements start with ${P.prettyLocator(e.configuration,l)}`))})).exitCode()}As();var pae=ve(zr()),Iu=class extends Pe{constructor(){super(...arguments);this.onlyIfNeeded=z.Boolean("--only-if-needed",!1,{description:"Only lock the Yarn version if it isn't already locked"});this.version=z.String()}async execute(){var o;let t=await Ee.find(this.context.cwd,this.context.plugins);if(this.onlyIfNeeded&&t.get("yarnPath")){let a=t.sources.get("yarnPath");if(!a)throw new Error("Assertion failed: Expected 'yarnPath' to have a source");let l=(o=t.projectCwd)!=null?o:t.startingCwd;if(v.contains(l,a))return 0}let i=()=>{if(typeof Fr>"u")throw new we("The --install flag can only be used without explicit version specifier from the Yarn CLI");return`file://${process.argv[1]}`},n;if(this.version==="self")n=i();else if(this.version==="latest"||this.version==="berry"||this.version==="stable")n=`https://repo.yarnpkg.com/${await Wm(t,"stable")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="canary")n=`https://repo.yarnpkg.com/${await Wm(t,"canary")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="classic")n="https://classic.yarnpkg.com/latest.js";else if(this.version.match(/^https?:/))n=this.version;else if(this.version.match(/^\.{0,2}[\\/]/)||K.isAbsolute(this.version))n=`file://${K.resolve(this.version)}`;else if(Qt.satisfiesWithPrereleases(this.version,">=2.0.0"))n=`https://repo.yarnpkg.com/${this.version}/packages/yarnpkg-cli/bin/yarn.js`;else if(Qt.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))n=`https://github.com/yarnpkg/yarn/releases/download/v${this.version}/yarn-${this.version}.js`;else if(Qt.validRange(this.version))n=`https://repo.yarnpkg.com/${await OWe(t,this.version)}/packages/yarnpkg-cli/bin/yarn.js`;else throw new we(`Invalid version descriptor "${this.version}"`);return(await He.start({configuration:t,stdout:this.context.stdout,includeLogs:!this.context.quiet},async a=>{let l="file://",c;n.startsWith(l)?(a.reportInfo(0,`Downloading ${$.pretty(t,n,$.Type.URL)}`),c=await M.readFilePromise(K.toPortablePath(n.slice(l.length)))):(a.reportInfo(0,`Retrieving ${$.pretty(t,n,$.Type.PATH)}`),c=await Vt.get(n,{configuration:t})),await eO(t,null,c,{report:a})})).exitCode()}};Iu.paths=[["set","version"]],Iu.usage=Qe.Usage({description:"lock the Yarn version used by the project",details:"\n This command will download a specific release of Yarn directly from the Yarn GitHub repository, will store it inside your project, and will change the `yarnPath` settings from your project `.yarnrc.yml` file to point to the new file.\n\n A very good use case for this command is to enforce the version of Yarn used by any single member of your team inside the same project - by doing this you ensure that you have control over Yarn upgrades and downgrades (including on your deployment servers), and get rid of most of the headaches related to someone using a slightly different version and getting different behavior.\n\n The version specifier can be:\n\n - a tag:\n - `latest` / `berry` / `stable` -> the most recent stable berry (`>=2.0.0`) release\n - `canary` -> the most recent canary (release candidate) berry (`>=2.0.0`) release\n - `classic` -> the most recent classic (`^0.x || ^1.x`) release\n\n - a semver range (e.g. `2.x`) -> the most recent version satisfying the range (limited to berry releases)\n\n - a semver version (e.g. `2.4.1`, `1.22.1`)\n\n - a local file referenced through either a relative or absolute path\n\n - `self` -> the version used to invoke the command\n ",examples:[["Download the latest release from the Yarn repository","$0 set version latest"],["Download the latest canary release from the Yarn repository","$0 set version canary"],["Download the latest classic release from the Yarn repository","$0 set version classic"],["Download the most recent Yarn 3 build","$0 set version 3.x"],["Download a specific Yarn 2 build","$0 set version 2.0.0-rc.30"],["Switch back to a specific Yarn 1 release","$0 set version 1.22.1"],["Use a release from the local filesystem","$0 set version ./yarn.cjs"],["Use a release from a URL","$0 set version https://repo.yarnpkg.com/3.1.0/packages/yarnpkg-cli/bin/yarn.js"],["Download the version used to invoke the command","$0 set version self"]]});async function OWe(r,e){let i=(await Vt.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0})).tags.filter(n=>Qt.satisfiesWithPrereleases(n,e));if(i.length===0)throw new we(`No matching release found for range ${$.pretty(r,e,$.Type.RANGE)}.`);return i[0]}async function Wm(r,e){let t=await Vt.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0});if(!t.latest[e])throw new we(`Tag ${$.pretty(r,e,$.Type.RANGE)} not found`);return t.latest[e]}async function eO(r,e,t,{report:i}){var p;e===null&&await M.mktempPromise(async d=>{let m=v.join(d,"yarn.cjs");await M.writeFilePromise(m,t);let{stdout:y}=await pr.execvp(process.execPath,[K.fromPortablePath(m),"--version"],{cwd:d,env:{...process.env,YARN_IGNORE_PATH:"1"}});if(e=y.trim(),!pae.default.valid(e))throw new Error(`Invalid semver version. ${$.pretty(r,"yarn --version",$.Type.CODE)} returned: +${e}`)});let n=(p=r.projectCwd)!=null?p:r.startingCwd,s=v.resolve(n,".yarn/releases"),o=v.resolve(s,`yarn-${e}.cjs`),a=v.relative(r.startingCwd,o),l=v.relative(n,o);i.reportInfo(0,`Saving the new release in ${$.pretty(r,a,"magenta")}`),await M.removePromise(v.dirname(o)),await M.mkdirPromise(v.dirname(o),{recursive:!0}),await M.writeFilePromise(o,t,{mode:493}),await Ee.updateConfiguration(n,{yarnPath:l});let c=await ot.tryFind(n)||new ot;c.packageManager=`yarn@${e&&me.isTaggedYarnVersion(e)?e:await Wm(r,"stable")}`;let u={};c.exportTo(u);let g=v.join(n,ot.fileName),h=`${JSON.stringify(u,null,c.indent)} +`;await M.changeFilePromise(g,h,{automaticNewlines:!0})}function dae(r){return dt[TI(r)]}var MWe=/## (?<code>YN[0-9]{4}) - `(?<name>[A-Z_]+)`\n\n(?<details>(?:.(?!##))+)/gs;async function KWe(r){let t=`https://repo.yarnpkg.com/${me.isTaggedYarnVersion(Fr)?Fr:await Wm(r,"canary")}/packages/gatsby/content/advanced/error-codes.md`,i=await Vt.get(t,{configuration:r});return new Map(Array.from(i.toString().matchAll(MWe),({groups:n})=>{if(!n)throw new Error("Assertion failed: Expected the match to have been successful");let s=dae(n.code);if(n.name!==s)throw new Error(`Assertion failed: Invalid error code data: Expected "${n.name}" to be named "${s}"`);return[n.code,n.details]}))}var yu=class extends Pe{constructor(){super(...arguments);this.code=z.String({required:!1,validator:ad(od(),[Ad(/^YN[0-9]{4}$/)])});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins);if(typeof this.code<"u"){let i=dae(this.code),n=$.pretty(t,i,$.Type.CODE),s=this.cli.format().header(`${this.code} - ${n}`),a=(await KWe(t)).get(this.code),l=typeof a<"u"?$.jsonOrPretty(this.json,t,$.tuple($.Type.MARKDOWN,{text:a,format:this.cli.format(),paragraphs:!0})):`This error code does not have a description. + +You can help us by editing this page on GitHub \u{1F642}: +${$.jsonOrPretty(this.json,t,$.tuple($.Type.URL,"https://github.com/yarnpkg/berry/blob/master/packages/gatsby/content/advanced/error-codes.md"))} +`;this.json?this.context.stdout.write(`${JSON.stringify({code:this.code,name:i,details:l})} +`):this.context.stdout.write(`${s} + +${l} +`)}else{let i={children:me.mapAndFilter(Object.entries(dt),([n,s])=>Number.isNaN(Number(n))?me.mapAndFilter.skip:{label:RA(Number(n)),value:$.tuple($.Type.CODE,s)})};es.emitTree(i,{configuration:t,stdout:this.context.stdout,json:this.json})}}};yu.paths=[["explain"]],yu.usage=Qe.Usage({description:"explain an error code",details:` + When the code argument is specified, this command prints its name and its details. + + When used without arguments, this command lists all error codes and their names. + `,examples:[["Explain an error code","$0 explain YN0006"],["List all error codes","$0 explain"]]});var Cae=ve(Bn()),wu=class extends Pe{constructor(){super(...arguments);this.all=z.Boolean("-A,--all",!1,{description:"Print versions of a package from the whole project"});this.recursive=z.Boolean("-R,--recursive",!1,{description:"Print information for all packages, including transitive dependencies"});this.extra=z.Array("-X,--extra",[],{description:"An array of requests of extra data provided by plugins"});this.cache=z.Boolean("--cache",!1,{description:"Print information about the cache entry of a package (path, size, checksum)"});this.dependents=z.Boolean("--dependents",!1,{description:"Print all dependents for each matching package"});this.manifest=z.Boolean("--manifest",!1,{description:"Print data obtained by looking at the package archive (license, homepage, ...)"});this.nameOnly=z.Boolean("--name-only",!1,{description:"Only print the name for the matching packages"});this.virtuals=z.Boolean("--virtuals",!1,{description:"Print each instance of the virtual packages"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n&&!this.all)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState();let o=new Set(this.extra);this.cache&&o.add("cache"),this.dependents&&o.add("dependents"),this.manifest&&o.add("manifest");let a=(F,{recursive:H})=>{let q=F.anchoredLocator.locatorHash,_=new Map,X=[q];for(;X.length>0;){let W=X.shift();if(_.has(W))continue;let Z=i.storedPackages.get(W);if(typeof Z>"u")throw new Error("Assertion failed: Expected the package to be registered");if(_.set(W,Z),P.isVirtualLocator(Z)&&X.push(P.devirtualizeLocator(Z).locatorHash),!(!H&&W!==q))for(let A of Z.dependencies.values()){let ne=i.storedResolutions.get(A.descriptorHash);if(typeof ne>"u")throw new Error("Assertion failed: Expected the resolution to be registered");X.push(ne)}}return _.values()},l=({recursive:F})=>{let H=new Map;for(let q of i.workspaces)for(let _ of a(q,{recursive:F}))H.set(_.locatorHash,_);return H.values()},c=({all:F,recursive:H})=>F&&H?i.storedPackages.values():F?l({recursive:H}):a(n,{recursive:H}),u=({all:F,recursive:H})=>{let q=c({all:F,recursive:H}),_=this.patterns.map(Z=>{let A=P.parseLocator(Z),ne=Cae.default.makeRe(P.stringifyIdent(A)),ue=P.isVirtualLocator(A),te=ue?P.devirtualizeLocator(A):A;return O=>{let N=P.stringifyIdent(O);if(!ne.test(N))return!1;if(A.reference==="unknown")return!0;let ce=P.isVirtualLocator(O),he=ce?P.devirtualizeLocator(O):O;return!(ue&&ce&&A.reference!==O.reference||te.reference!==he.reference)}}),X=me.sortMap([...q],Z=>P.stringifyLocator(Z));return{selection:X.filter(Z=>_.length===0||_.some(A=>A(Z))),sortedLookup:X}},{selection:g,sortedLookup:h}=u({all:this.all,recursive:this.recursive});if(g.length===0)throw new we("No package matched your request");let p=new Map;if(this.dependents)for(let F of h)for(let H of F.dependencies.values()){let q=i.storedResolutions.get(H.descriptorHash);if(typeof q>"u")throw new Error("Assertion failed: Expected the resolution to be registered");me.getArrayWithDefault(p,q).push(F)}let d=new Map;for(let F of h){if(!P.isVirtualLocator(F))continue;let H=P.devirtualizeLocator(F);me.getArrayWithDefault(d,H.locatorHash).push(F)}let m={},y={children:m},B=t.makeFetcher(),S={project:i,fetcher:B,cache:s,checksums:i.storedChecksums,report:new $r,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},x=[async(F,H,q)=>{var W,Z;if(!H.has("manifest"))return;let _=await B.fetch(F,S),X;try{X=await ot.find(_.prefixPath,{baseFs:_.packageFs})}finally{(W=_.releaseFs)==null||W.call(_)}q("Manifest",{License:$.tuple($.Type.NO_HINT,X.license),Homepage:$.tuple($.Type.URL,(Z=X.raw.homepage)!=null?Z:null)})},async(F,H,q)=>{var ne;if(!H.has("cache"))return;let _={mockedPackages:i.disabledLocators,unstablePackages:i.conditionalLocators},X=(ne=i.storedChecksums.get(F.locatorHash))!=null?ne:null,W=s.getLocatorPath(F,X,_),Z;if(W!==null)try{Z=M.statSync(W)}catch{}let A=typeof Z<"u"?[Z.size,$.Type.SIZE]:void 0;q("Cache",{Checksum:$.tuple($.Type.NO_HINT,X),Path:$.tuple($.Type.PATH,W),Size:A})}];for(let F of g){let H=P.isVirtualLocator(F);if(!this.virtuals&&H)continue;let q={},_={value:[F,$.Type.LOCATOR],children:q};if(m[P.stringifyLocator(F)]=_,this.nameOnly){delete _.children;continue}let X=d.get(F.locatorHash);typeof X<"u"&&(q.Instances={label:"Instances",value:$.tuple($.Type.NUMBER,X.length)}),q.Version={label:"Version",value:$.tuple($.Type.NO_HINT,F.version)};let W=(A,ne)=>{let ue={};if(q[A]=ue,Array.isArray(ne))ue.children=ne.map(te=>({value:te}));else{let te={};ue.children=te;for(let[O,N]of Object.entries(ne))typeof N>"u"||(te[O]={label:O,value:N})}};if(!H){for(let A of x)await A(F,o,W);await t.triggerHook(A=>A.fetchPackageInfo,F,o,W)}F.bin.size>0&&!H&&W("Exported Binaries",[...F.bin.keys()].map(A=>$.tuple($.Type.PATH,A)));let Z=p.get(F.locatorHash);typeof Z<"u"&&Z.length>0&&W("Dependents",Z.map(A=>$.tuple($.Type.LOCATOR,A))),F.dependencies.size>0&&!H&&W("Dependencies",[...F.dependencies.values()].map(A=>{var te;let ne=i.storedResolutions.get(A.descriptorHash),ue=typeof ne<"u"&&(te=i.storedPackages.get(ne))!=null?te:null;return $.tuple($.Type.RESOLUTION,{descriptor:A,locator:ue})})),F.peerDependencies.size>0&&H&&W("Peer dependencies",[...F.peerDependencies.values()].map(A=>{var O,N;let ne=F.dependencies.get(A.identHash),ue=typeof ne<"u"&&(O=i.storedResolutions.get(ne.descriptorHash))!=null?O:null,te=ue!==null&&(N=i.storedPackages.get(ue))!=null?N:null;return $.tuple($.Type.RESOLUTION,{descriptor:A,locator:te})}))}es.emitTree(y,{configuration:t,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}};wu.paths=[["info"]],wu.usage=Qe.Usage({description:"see information related to packages",details:"\n This command prints various information related to the specified packages, accepting glob patterns.\n\n By default, if the locator reference is missing, Yarn will default to print the information about all the matching direct dependencies of the package for the active workspace. To instead print all versions of the package that are direct dependencies of any of your workspaces, use the `-A,--all` flag. Adding the `-R,--recursive` flag will also report transitive dependencies.\n\n Some fields will be hidden by default in order to keep the output readable, but can be selectively displayed by using additional options (`--dependents`, `--manifest`, `--virtuals`, ...) described in the option descriptions.\n\n Note that this command will only print the information directly related to the selected packages - if you wish to know why the package is there in the first place, use `yarn why` which will do just that (it also provides a `-R,--recursive` flag that may be of some help).\n ",examples:[["Show information about Lodash","$0 info lodash"]]});var Nb=ve(cc());As();var Bu=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.immutable=z.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"});this.immutableCache=z.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"});this.checkCache=z.Boolean("--check-cache",!1,{description:"Always refetch the packages and ensure that their checksums are consistent"});this.inlineBuilds=z.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"});this.mode=z.String("--mode",{description:"Change what artifacts installs generate",validator:Xi(ts)});this.cacheFolder=z.String("--cache-folder",{hidden:!0});this.frozenLockfile=z.Boolean("--frozen-lockfile",{hidden:!0});this.ignoreEngines=z.Boolean("--ignore-engines",{hidden:!0});this.nonInteractive=z.Boolean("--non-interactive",{hidden:!0});this.preferOffline=z.Boolean("--prefer-offline",{hidden:!0});this.production=z.Boolean("--production",{hidden:!0});this.registry=z.String("--registry",{hidden:!0});this.silent=z.Boolean("--silent",{hidden:!0});this.networkTimeout=z.String("--network-timeout",{hidden:!0})}async execute(){var h;let t=await Ee.find(this.context.cwd,this.context.plugins);typeof this.inlineBuilds<"u"&&t.useWithSource("<cli>",{enableInlineBuilds:this.inlineBuilds},t.startingCwd,{overwrite:!0});let i=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,n=async(p,{error:d})=>{let m=await He.start({configuration:t,stdout:this.context.stdout,includeFooter:!1},async y=>{d?y.reportError(50,p):y.reportWarning(50,p)});return m.hasErrors()?m.exitCode():null};if(typeof this.ignoreEngines<"u"){let p=await n("The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",{error:!Nb.default.VERCEL});if(p!==null)return p}if(typeof this.registry<"u"){let p=await n("The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file",{error:!1});if(p!==null)return p}if(typeof this.preferOffline<"u"){let p=await n("The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",{error:!Nb.default.VERCEL});if(p!==null)return p}if(typeof this.production<"u"){let p=await n("The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",{error:!0});if(p!==null)return p}if(typeof this.nonInteractive<"u"){let p=await n("The --non-interactive option is deprecated",{error:!i});if(p!==null)return p}if(typeof this.frozenLockfile<"u"&&(await n("The --frozen-lockfile option is deprecated; use --immutable and/or --immutable-cache instead",{error:!1}),this.immutable=this.frozenLockfile),typeof this.cacheFolder<"u"){let p=await n("The cache-folder option has been deprecated; use rc settings instead",{error:!Nb.default.NETLIFY});if(p!==null)return p}let s=this.mode==="update-lockfile";if(s&&(this.immutable||this.immutableCache))throw new we(`${$.pretty(t,"--immutable",$.Type.CODE)} and ${$.pretty(t,"--immutable-cache",$.Type.CODE)} cannot be used with ${$.pretty(t,"--mode=update-lockfile",$.Type.CODE)}`);let o=((h=this.immutable)!=null?h:t.get("enableImmutableInstalls"))&&!s,a=this.immutableCache&&!s;if(t.projectCwd!==null){let p=await He.start({configuration:t,json:this.json,stdout:this.context.stdout,includeFooter:!1},async d=>{await GWe(t,o)&&(d.reportInfo(48,"Automatically fixed merge conflicts \u{1F44D}"),d.reportSeparator())});if(p.hasErrors())return p.exitCode()}if(t.projectCwd!==null&&typeof t.sources.get("nodeLinker")>"u"){let p=t.projectCwd,d;try{d=await M.readFilePromise(v.join(p,St.lockfile),"utf8")}catch{}if(d!=null&&d.includes("yarn lockfile v1")){let m=await He.start({configuration:t,json:this.json,stdout:this.context.stdout,includeFooter:!1},async y=>{y.reportInfo(70,"Migrating from Yarn 1; automatically enabling the compatibility node-modules linker \u{1F44D}"),y.reportSeparator(),t.use("<compat>",{nodeLinker:"node-modules"},p,{overwrite:!0}),await Ee.updateConfiguration(p,{nodeLinker:"node-modules"})});if(m.hasErrors())return m.exitCode()}}if(t.projectCwd!==null){let p=await He.start({configuration:t,json:this.json,stdout:this.context.stdout,includeFooter:!1},async d=>{var m;(m=Ee.telemetry)!=null&&m.isNew&&(d.reportInfo(65,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),d.reportInfo(65,`Run ${$.pretty(t,"yarn config set --home enableTelemetry 0",$.Type.CODE)} to disable`),d.reportSeparator())});if(p.hasErrors())return p.exitCode()}let{project:l,workspace:c}=await Ge.find(t,this.context.cwd),u=await Dt.find(t,{immutable:a,check:this.checkCache});if(!c)throw new lt(l.cwd,this.context.cwd);return await l.restoreInstallState({restoreResolutions:!1}),(await He.start({configuration:t,json:this.json,stdout:this.context.stdout,includeLogs:!0},async p=>{await l.install({cache:u,report:p,immutable:o,mode:this.mode})})).exitCode()}};Bu.paths=[["install"],Qe.Default],Bu.usage=Qe.Usage({description:"install the project dependencies",details:` + This command sets up your project if needed. The installation is split into four different steps that each have their own characteristics: + + - **Resolution:** First the package manager will resolve your dependencies. The exact way a dependency version is privileged over another isn't standardized outside of the regular semver guarantees. If a package doesn't resolve to what you would expect, check that all dependencies are correctly declared (also check our website for more information: ). + + - **Fetch:** Then we download all the dependencies if needed, and make sure that they're all stored within our cache (check the value of \`cacheFolder\` in \`yarn config\` to see where the cache files are stored). + + - **Link:** Then we send the dependency tree information to internal plugins tasked with writing them on the disk in some form (for example by generating the .pnp.cjs file you might know). + + - **Build:** Once the dependency tree has been written on the disk, the package manager will now be free to run the build scripts for all packages that might need it, in a topological order compatible with the way they depend on one another. See https://yarnpkg.com/advanced/lifecycle-scripts for detail. + + Note that running this command is not part of the recommended workflow. Yarn supports zero-installs, which means that as long as you store your cache and your .pnp.cjs file inside your repository, everything will work without requiring any install right after cloning your repository or switching branches. + + If the \`--immutable\` option is set (defaults to true on CI), Yarn will abort with an error exit code if the lockfile was to be modified (other paths can be added using the \`immutablePatterns\` configuration setting). For backward compatibility we offer an alias under the name of \`--frozen-lockfile\`, but it will be removed in a later release. + + If the \`--immutable-cache\` option is set, Yarn will abort with an error exit code if the cache folder was to be modified (either because files would be added, or because they'd be removed). + + If the \`--check-cache\` option is set, Yarn will always refetch the packages and will ensure that their checksum matches what's 1/ described in the lockfile 2/ inside the existing cache files (if present). This is recommended as part of your CI workflow if you're both following the Zero-Installs model and accepting PRs from third-parties, as they'd otherwise have the ability to alter the checked-in packages before submitting them. + + If the \`--inline-builds\` option is set, Yarn will verbosely print the output of the build steps of your dependencies (instead of writing them into individual files). This is likely useful mostly for debug purposes only when using Docker-like environments. + + If the \`--mode=<mode>\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: + + - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. + + - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. + `,examples:[["Install the project","$0 install"],["Validate a project when using Zero-Installs","$0 install --immutable --immutable-cache"],["Validate a project when using Zero-Installs (slightly safer if you accept external PRs)","$0 install --immutable --immutable-cache --check-cache"]]});var UWe="|||||||",HWe=">>>>>>>",jWe="=======",mae="<<<<<<<";async function GWe(r,e){if(!r.projectCwd)return!1;let t=v.join(r.projectCwd,r.get("lockfileFilename"));if(!await M.existsPromise(t))return!1;let i=await M.readFilePromise(t,"utf8");if(!i.includes(mae))return!1;if(e)throw new rt(47,"Cannot autofix a lockfile when running an immutable install");let[n,s]=YWe(i),o,a;try{o=wi(n),a=wi(s)}catch{throw new rt(46,"The individual variants of the lockfile failed to parse")}let l={...o,...a};for(let[c,u]of Object.entries(l))typeof u=="string"&&delete l[c];return await M.changeFilePromise(t,Qa(l),{automaticNewlines:!0}),!0}function YWe(r){let e=[[],[]],t=r.split(/\r?\n/g),i=!1;for(;t.length>0;){let n=t.shift();if(typeof n>"u")throw new Error("Assertion failed: Some lines should remain");if(n.startsWith(mae)){for(;t.length>0;){let s=t.shift();if(typeof s>"u")throw new Error("Assertion failed: Some lines should remain");if(s===jWe){i=!1;break}else if(i||s.startsWith(UWe)){i=!0;continue}else e[0].push(s)}for(;t.length>0;){let s=t.shift();if(typeof s>"u")throw new Error("Assertion failed: Some lines should remain");if(s.startsWith(HWe))break;e[1].push(s)}}else e[0].push(n),e[1].push(n)}return[e[0].join(` +`),e[1].join(` +`)]}var bu=class extends Pe{constructor(){super(...arguments);this.all=z.Boolean("-A,--all",!1,{description:"Link all workspaces belonging to the target projects to the current one"});this.private=z.Boolean("-p,--private",!1,{description:"Also link private workspaces belonging to the target projects to the current one"});this.relative=z.Boolean("-r,--relative",!1,{description:"Link workspaces using relative paths instead of absolute paths"});this.destinations=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState({restoreResolutions:!1});let o=i.topLevelWorkspace,a=[];for(let c of this.destinations){let u=v.resolve(this.context.cwd,K.toPortablePath(c)),g=await Ee.find(u,this.context.plugins,{useRc:!1,strict:!1}),{project:h,workspace:p}=await Ge.find(g,u);if(i.cwd===h.cwd)throw new we(`Invalid destination '${c}'; Can't link the project to itself`);if(!p)throw new lt(h.cwd,u);if(this.all){let d=!1;for(let m of h.workspaces)m.manifest.name&&(!m.manifest.private||this.private)&&(a.push(m),d=!0);if(!d)throw new we(`No workspace found to be linked in the target project: ${c}`)}else{if(!p.manifest.name)throw new we(`The target workspace at '${c}' doesn't have a name and thus cannot be linked`);if(p.manifest.private&&!this.private)throw new we(`The target workspace at '${c}' is marked private - use the --private flag to link it anyway`);a.push(p)}}for(let c of a){let u=P.stringifyIdent(c.locator),g=this.relative?v.relative(i.cwd,c.cwd):c.cwd;o.manifest.resolutions.push({pattern:{descriptor:{fullName:u}},reference:`portal:${g}`})}return(await He.start({configuration:t,stdout:this.context.stdout},async c=>{await i.install({cache:s,report:c})})).exitCode()}};bu.paths=[["link"]],bu.usage=Qe.Usage({description:"connect the local project to another one",details:"\n This command will set a new `resolutions` field in the project-level manifest and point it to the workspace at the specified location (even if part of another project).\n ",examples:[["Register one or more remote workspaces for use in the current project","$0 link ~/ts-loader ~/jest"],["Register all workspaces from a remote project for use in the current project","$0 link ~/jest --all"]]});var Qu=class extends Pe{constructor(){super(...arguments);this.args=z.Proxy()}async execute(){return this.cli.run(["exec","node",...this.args])}};Qu.paths=[["node"]],Qu.usage=Qe.Usage({description:"run node with the hook already setup",details:` + This command simply runs Node. It also makes sure to call it in a way that's compatible with the current project (for example, on PnP projects the environment will be setup in such a way that PnP will be correctly injected into the environment). + + The Node process will use the exact same version of Node as the one used to run Yarn itself, which might be a good way to ensure that your commands always use a consistent Node version. + `,examples:[["Run a Node script","$0 node ./my-script.js"]]});var bae=J("os");var Eae=J("os");var qWe="https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml";async function vu(r){let e=await Vt.get(qWe,{configuration:r});return wi(e.toString())}var Su=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins);return(await He.start({configuration:t,json:this.json,stdout:this.context.stdout},async n=>{let s=await vu(t);for(let[o,{experimental:a,...l}]of Object.entries(s)){let c=o;a&&(c+=" [experimental]"),n.reportJson({name:o,experimental:a,...l}),n.reportInfo(null,c)}})).exitCode()}};Su.paths=[["plugin","list"]],Su.usage=Qe.Usage({category:"Plugin-related commands",description:"list the available official plugins",details:"\n This command prints the plugins available directly from the Yarn repository. Only those plugins can be referenced by name in `yarn plugin import`.\n ",examples:[["List the official plugins","$0 plugin list"]]});var JWe=/^[0-9]+$/;function Iae(r){return JWe.test(r)?`pull/${r}/head`:r}var WWe=({repository:r,branch:e},t)=>[["git","init",K.fromPortablePath(t)],["git","remote","add","origin",r],["git","fetch","origin","--depth=1",Iae(e)],["git","reset","--hard","FETCH_HEAD"]],zWe=({branch:r})=>[["git","fetch","origin","--depth=1",Iae(r),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx"]],VWe=({plugins:r,noMinify:e},t)=>[["yarn","build:cli",...new Array().concat(...r.map(i=>["--plugin",v.resolve(t,i)])),...e?["--no-minify"]:[],"|"]],Pu=class extends Pe{constructor(){super(...arguments);this.installPath=z.String("--path",{description:"The path where the repository should be cloned to"});this.repository=z.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=z.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.plugins=z.Array("--plugin",[],{description:"An array of additional plugins that should be included in the bundle"});this.noMinify=z.Boolean("--no-minify",!1,{description:"Build a bundle for development (debugging) - non-minified and non-mangled"});this.force=z.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.skipPlugins=z.Boolean("--skip-plugins",!1,{description:"Skip updating the contrib plugins"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i}=await Ge.find(t,this.context.cwd),n=typeof this.installPath<"u"?v.resolve(this.context.cwd,K.toPortablePath(this.installPath)):v.resolve(K.toPortablePath((0,Eae.tmpdir)()),"yarnpkg-sources",Ai.makeHash(this.repository).slice(0,6));return(await He.start({configuration:t,stdout:this.context.stdout},async o=>{await tO(this,{configuration:t,report:o,target:n}),o.reportSeparator(),o.reportInfo(0,"Building a fresh bundle"),o.reportSeparator(),await zm(VWe(this,n),{configuration:t,context:this.context,target:n}),o.reportSeparator();let a=v.resolve(n,"packages/yarnpkg-cli/bundles/yarn.js"),l=await M.readFilePromise(a);await eO(t,"sources",l,{report:o}),this.skipPlugins||await XWe(this,{project:i,report:o,target:n})})).exitCode()}};Pu.paths=[["set","version","from","sources"]],Pu.usage=Qe.Usage({description:"build Yarn from master",details:` + This command will clone the Yarn repository into a temporary folder, then build it. The resulting bundle will then be copied into the local project. + + By default, it also updates all contrib plugins to the same commit the bundle is built from. This behavior can be disabled by using the \`--skip-plugins\` flag. + `,examples:[["Build Yarn from master","$0 set version from sources"]]});async function zm(r,{configuration:e,context:t,target:i}){for(let[n,...s]of r){let o=s[s.length-1]==="|";if(o&&s.pop(),o)await pr.pipevp(n,s,{cwd:i,stdin:t.stdin,stdout:t.stdout,stderr:t.stderr,strict:!0});else{t.stdout.write(`${$.pretty(e,` $ ${[n,...s].join(" ")}`,"grey")} +`);try{await pr.execvp(n,s,{cwd:i,strict:!0})}catch(a){throw t.stdout.write(a.stdout||a.stack),a}}}}async function tO(r,{configuration:e,report:t,target:i}){let n=!1;if(!r.force&&M.existsSync(v.join(i,".git"))){t.reportInfo(0,"Fetching the latest commits"),t.reportSeparator();try{await zm(zWe(r),{configuration:e,context:r.context,target:i}),n=!0}catch{t.reportSeparator(),t.reportWarning(0,"Repository update failed; we'll try to regenerate it")}}n||(t.reportInfo(0,"Cloning the remote repository"),t.reportSeparator(),await M.removePromise(i),await M.mkdirPromise(i,{recursive:!0}),await zm(WWe(r,i),{configuration:e,context:r.context,target:i}))}async function XWe(r,{project:e,report:t,target:i}){let n=await vu(e.configuration),s=new Set(Object.keys(n));for(let o of e.configuration.plugins.keys())!s.has(o)||await rO(o,r,{project:e,report:t,target:i})}var yae=ve(zr()),wae=J("url"),Bae=J("vm");var xu=class extends Pe{constructor(){super(...arguments);this.name=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins);return(await He.start({configuration:t,stdout:this.context.stdout},async n=>{let{project:s}=await Ge.find(t,this.context.cwd),o,a;if(this.name.match(/^\.{0,2}[\\/]/)||K.isAbsolute(this.name)){let l=v.resolve(this.context.cwd,K.toPortablePath(this.name));n.reportInfo(0,`Reading ${$.pretty(t,l,$.Type.PATH)}`),o=v.relative(s.cwd,l),a=await M.readFilePromise(l)}else{let l;if(this.name.match(/^https?:/)){try{new wae.URL(this.name)}catch{throw new rt(52,`Plugin specifier "${this.name}" is neither a plugin name nor a valid url`)}o=this.name,l=this.name}else{let c=P.parseLocator(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-"));if(c.reference!=="unknown"&&!yae.default.valid(c.reference))throw new rt(0,"Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.");let u=P.stringifyIdent(c),g=await vu(t);if(!Object.prototype.hasOwnProperty.call(g,u))throw new rt(51,`Couldn't find a plugin named "${u}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be referenced by their name; any other plugin will have to be referenced through its public url (for example https://github.com/yarnpkg/berry/raw/master/packages/plugin-typescript/bin/%40yarnpkg/plugin-typescript.js).`);o=u,l=g[u].url,c.reference!=="unknown"?l=l.replace(/\/master\//,`/${u}/${c.reference}/`):Fr!==null&&(l=l.replace(/\/master\//,`/@yarnpkg/cli/${Fr}/`))}n.reportInfo(0,`Downloading ${$.pretty(t,l,"green")}`),a=await Vt.get(l,{configuration:t})}await iO(o,a,{project:s,report:n})})).exitCode()}};xu.paths=[["plugin","import"]],xu.usage=Qe.Usage({category:"Plugin-related commands",description:"download a plugin",details:` + This command downloads the specified plugin from its remote location and updates the configuration to reference it in further CLI invocations. + + Three types of plugin references are accepted: + + - If the plugin is stored within the Yarn repository, it can be referenced by name. + - Third-party plugins can be referenced directly through their public urls. + - Local plugins can be referenced by their path on the disk. + + Plugins cannot be downloaded from the npm registry, and aren't allowed to have dependencies (they need to be bundled into a single file, possibly thanks to the \`@yarnpkg/builder\` package). + `,examples:[['Download and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import @yarnpkg/plugin-exec"],['Download and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import exec"],["Download and activate a community plugin","$0 plugin import https://example.org/path/to/plugin.js"],["Activate a local plugin","$0 plugin import ./path/to/plugin.js"]]});async function iO(r,e,{project:t,report:i}){let{configuration:n}=t,s={},o={exports:s};(0,Bae.runInNewContext)(e.toString(),{module:o,exports:s});let a=o.exports.name,l=`.yarn/plugins/${a}.cjs`,c=v.resolve(t.cwd,l);i.reportInfo(0,`Saving the new plugin in ${$.pretty(n,l,"magenta")}`),await M.mkdirPromise(v.dirname(c),{recursive:!0}),await M.writeFilePromise(c,e);let u={path:l,spec:r};await Ee.updateConfiguration(t.cwd,g=>{let h=[],p=!1;for(let d of g.plugins||[]){let m=typeof d!="string"?d.path:d,y=v.resolve(t.cwd,K.toPortablePath(m)),{name:B}=me.dynamicRequire(y);B!==a?h.push(d):(h.push(u),p=!0)}return p||h.push(u),{...g,plugins:h}})}var ZWe=({pluginName:r,noMinify:e},t)=>[["yarn",`build:${r}`,...e?["--no-minify"]:[],"|"]],ku=class extends Pe{constructor(){super(...arguments);this.installPath=z.String("--path",{description:"The path where the repository should be cloned to"});this.repository=z.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=z.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.noMinify=z.Boolean("--no-minify",!1,{description:"Build a plugin for development (debugging) - non-minified and non-mangled"});this.force=z.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.name=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=typeof this.installPath<"u"?v.resolve(this.context.cwd,K.toPortablePath(this.installPath)):v.resolve(K.toPortablePath((0,bae.tmpdir)()),"yarnpkg-sources",Ai.makeHash(this.repository).slice(0,6));return(await He.start({configuration:t,stdout:this.context.stdout},async s=>{let{project:o}=await Ge.find(t,this.context.cwd),a=P.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),l=P.stringifyIdent(a),c=await vu(t);if(!Object.prototype.hasOwnProperty.call(c,l))throw new rt(51,`Couldn't find a plugin named "${l}" on the remote registry. Note that only the plugins referenced on our website (https://github.com/yarnpkg/berry/blob/master/plugins.yml) can be built and imported from sources.`);let u=l;await tO(this,{configuration:t,report:s,target:i}),await rO(u,this,{project:o,report:s,target:i})})).exitCode()}};ku.paths=[["plugin","import","from","sources"]],ku.usage=Qe.Usage({category:"Plugin-related commands",description:"build a plugin from sources",details:` + This command clones the Yarn repository into a temporary folder, builds the specified contrib plugin and updates the configuration to reference it in further CLI invocations. + + The plugins can be referenced by their short name if sourced from the official Yarn repository. + `,examples:[['Build and activate the "@yarnpkg/plugin-exec" plugin',"$0 plugin import from sources @yarnpkg/plugin-exec"],['Build and activate the "@yarnpkg/plugin-exec" plugin (shorthand)',"$0 plugin import from sources exec"]]});async function rO(r,{context:e,noMinify:t},{project:i,report:n,target:s}){let o=r.replace(/@yarnpkg\//,""),{configuration:a}=i;n.reportSeparator(),n.reportInfo(0,`Building a fresh ${o}`),n.reportSeparator(),await zm(ZWe({pluginName:o,noMinify:t},s),{configuration:a,context:e,target:s}),n.reportSeparator();let l=v.resolve(s,`packages/${o}/bundles/${r}.js`),c=await M.readFilePromise(l);await iO(r,c,{project:i,report:n})}var Du=class extends Pe{constructor(){super(...arguments);this.name=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i}=await Ge.find(t,this.context.cwd);return(await He.start({configuration:t,stdout:this.context.stdout},async s=>{let o=this.name,a=P.parseIdent(o);if(!t.plugins.has(o))throw new we(`${P.prettyIdent(t,a)} isn't referenced by the current configuration`);let l=`.yarn/plugins/${o}.cjs`,c=v.resolve(i.cwd,l);M.existsSync(c)&&(s.reportInfo(0,`Removing ${$.pretty(t,l,$.Type.PATH)}...`),await M.removePromise(c)),s.reportInfo(0,"Updating the configuration..."),await Ee.updateConfiguration(i.cwd,u=>{if(!Array.isArray(u.plugins))return u;let g=u.plugins.filter(h=>h.path!==l);return u.plugins.length===g.length?u:{...u,plugins:g}})})).exitCode()}};Du.paths=[["plugin","remove"]],Du.usage=Qe.Usage({category:"Plugin-related commands",description:"remove a plugin",details:` + This command deletes the specified plugin from the .yarn/plugins folder and removes it from the configuration. + + **Note:** The plugins have to be referenced by their name property, which can be obtained using the \`yarn plugin runtime\` command. Shorthands are not allowed. + `,examples:[["Remove a plugin imported from the Yarn repository","$0 plugin remove @yarnpkg/plugin-typescript"],["Remove a plugin imported from a local file","$0 plugin remove my-local-plugin"]]});var Ru=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins);return(await He.start({configuration:t,json:this.json,stdout:this.context.stdout},async n=>{for(let s of t.plugins.keys()){let o=this.context.plugins.plugins.has(s),a=s;o&&(a+=" [builtin]"),n.reportJson({name:s,builtin:o}),n.reportInfo(null,`${a}`)}})).exitCode()}};Ru.paths=[["plugin","runtime"]],Ru.usage=Qe.Usage({category:"Plugin-related commands",description:"list the active plugins",details:` + This command prints the currently active plugins. Will be displayed both builtin plugins and external plugins. + `,examples:[["List the currently active plugins","$0 plugin runtime"]]});var Fu=class extends Pe{constructor(){super(...arguments);this.idents=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);let o=new Set;for(let l of this.idents)o.add(P.parseIdent(l).identHash);if(await i.restoreInstallState({restoreResolutions:!1}),await i.resolveEverything({cache:s,report:new $r}),o.size>0)for(let l of i.storedPackages.values())o.has(l.identHash)&&i.storedBuildState.delete(l.locatorHash);else i.storedBuildState.clear();return(await He.start({configuration:t,stdout:this.context.stdout,includeLogs:!this.context.quiet},async l=>{await i.install({cache:s,report:l})})).exitCode()}};Fu.paths=[["rebuild"]],Fu.usage=Qe.Usage({description:"rebuild the project's native packages",details:` + This command will automatically cause Yarn to forget about previous compilations of the given packages and to run them again. + + Note that while Yarn forgets the compilation, the previous artifacts aren't erased from the filesystem and may affect the next builds (in good or bad). To avoid this, you may remove the .yarn/unplugged folder, or any other relevant location where packages might have been stored (Yarn may offer a way to do that automatically in the future). + + By default all packages will be rebuilt, but you can filter the list by specifying the names of the packages you want to clear from memory. + `,examples:[["Rebuild all packages","$0 rebuild"],["Rebuild fsevents only","$0 rebuild fsevents"]]});var nO=ve(Bn());As();var Nu=class extends Pe{constructor(){super(...arguments);this.all=z.Boolean("-A,--all",!1,{description:"Apply the operation to all workspaces from the current project"});this.mode=z.String("--mode",{description:"Change what artifacts installs generate",validator:Xi(ts)});this.patterns=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState({restoreResolutions:!1});let o=this.all?i.workspaces:[n],a=["dependencies","devDependencies","peerDependencies"],l=[],c=!1,u=[];for(let d of this.patterns){let m=!1,y=P.parseIdent(d);for(let B of o){let S=[...B.manifest.peerDependenciesMeta.keys()];for(let x of(0,nO.default)(S,d))B.manifest.peerDependenciesMeta.delete(x),c=!0,m=!0;for(let x of a){let F=B.manifest.getForScope(x),H=[...F.values()].map(q=>P.stringifyIdent(q));for(let q of(0,nO.default)(H,P.stringifyIdent(y))){let{identHash:_}=P.parseIdent(q),X=F.get(_);if(typeof X>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");B.manifest[x].delete(_),u.push([B,x,X]),c=!0,m=!0}}}m||l.push(d)}let g=l.length>1?"Patterns":"Pattern",h=l.length>1?"don't":"doesn't",p=this.all?"any":"this";if(l.length>0)throw new we(`${g} ${$.prettyList(t,l,$.Type.CODE)} ${h} match any packages referenced by ${p} workspace`);return c?(await t.triggerMultipleHooks(m=>m.afterWorkspaceDependencyRemoval,u),(await He.start({configuration:t,stdout:this.context.stdout},async m=>{await i.install({cache:s,report:m,mode:this.mode})})).exitCode()):0}};Nu.paths=[["remove"]],Nu.usage=Qe.Usage({description:"remove dependencies from the project",details:` + This command will remove the packages matching the specified patterns from the current workspace. + + If the \`--mode=<mode>\` option is set, Yarn will change which artifacts are generated. The modes currently supported are: + + - \`skip-build\` will not run the build scripts at all. Note that this is different from setting \`enableScripts\` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run. + + - \`update-lockfile\` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost. + + This command accepts glob patterns as arguments (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them. + `,examples:[["Remove a dependency from the current project","$0 remove lodash"],["Remove a dependency from all workspaces at once","$0 remove lodash --all"],["Remove all dependencies starting with `eslint-`","$0 remove 'eslint-*'"],["Remove all dependencies with the `@babel` scope","$0 remove '@babel/*'"],["Remove all dependencies matching `react-dom` or `react-helmet`","$0 remove 'react-{dom,helmet}'"]]});var Qae=J("util"),_h=class extends Pe{async execute(){let e=await Ee.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await Ge.find(e,this.context.cwd);if(!i)throw new lt(t.cwd,this.context.cwd);return(await He.start({configuration:e,stdout:this.context.stdout},async s=>{let o=i.manifest.scripts,a=me.sortMap(o.keys(),u=>u),l={breakLength:1/0,colors:e.get("enableColors"),maxArrayLength:2},c=a.reduce((u,g)=>Math.max(u,g.length),0);for(let[u,g]of o.entries())s.reportInfo(null,`${u.padEnd(c," ")} ${(0,Qae.inspect)(g,l)}`)})).exitCode()}};_h.paths=[["run"]];var Tu=class extends Pe{constructor(){super(...arguments);this.inspect=z.String("--inspect",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.inspectBrk=z.String("--inspect-brk",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.topLevel=z.Boolean("-T,--top-level",!1,{description:"Check the root workspace for scripts and/or binaries instead of the current one"});this.binariesOnly=z.Boolean("-B,--binaries-only",!1,{description:"Ignore any user defined scripts and only check for binaries"});this.require=z.String("--require",{description:"Forwarded to the underlying Node process when executing a binary"});this.silent=z.Boolean("--silent",{hidden:!0});this.scriptName=z.String();this.args=z.Proxy()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n,locator:s}=await Ge.find(t,this.context.cwd);await i.restoreInstallState();let o=this.topLevel?i.topLevelWorkspace.anchoredLocator:s;if(!this.binariesOnly&&await Yt.hasPackageScript(o,this.scriptName,{project:i}))return await Yt.executePackageScript(o,this.scriptName,this.args,{project:i,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});let a=await Yt.getPackageAccessibleBinaries(o,{project:i});if(a.get(this.scriptName)){let c=[];return this.inspect&&(typeof this.inspect=="string"?c.push(`--inspect=${this.inspect}`):c.push("--inspect")),this.inspectBrk&&(typeof this.inspectBrk=="string"?c.push(`--inspect-brk=${this.inspectBrk}`):c.push("--inspect-brk")),this.require&&c.push(`--require=${this.require}`),await Yt.executePackageAccessibleBinary(o,this.scriptName,this.args,{cwd:this.context.cwd,project:i,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,nodeArgs:c,packageAccessibleBinaries:a})}if(!this.topLevel&&!this.binariesOnly&&n&&this.scriptName.includes(":")){let u=(await Promise.all(i.workspaces.map(async g=>g.manifest.scripts.has(this.scriptName)?g:null))).filter(g=>g!==null);if(u.length===1)return await Yt.executeWorkspaceScript(u[0],this.scriptName,this.args,{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})}if(this.topLevel)throw this.scriptName==="node-gyp"?new we(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${P.prettyLocator(t,s)}). This typically happens because some package depends on "node-gyp" to build itself, but didn't list it in their dependencies. To fix that, please run "yarn add node-gyp" into your top-level workspace. You also can open an issue on the repository of the specified package to suggest them to use an optional peer dependency.`):new we(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${P.prettyLocator(t,s)}).`);{if(this.scriptName==="global")throw new we("The 'yarn global' commands have been removed in 2.x - consider using 'yarn dlx' or a third-party plugin instead");let c=[this.scriptName].concat(this.args);for(let[u,g]of vh)for(let h of g)if(c.length>=h.length&&JSON.stringify(c.slice(0,h.length))===JSON.stringify(h))throw new we(`Couldn't find a script named "${this.scriptName}", but a matching command can be found in the ${u} plugin. You can install it with "yarn plugin import ${u}".`);throw new we(`Couldn't find a script named "${this.scriptName}".`)}}};Tu.paths=[["run"]],Tu.usage=Qe.Usage({description:"run a script defined in the package.json",details:` + This command will run a tool. The exact tool that will be executed will depend on the current state of your workspace: + + - If the \`scripts\` field from your local package.json contains a matching script name, its definition will get executed. + + - Otherwise, if one of the local workspace's dependencies exposes a binary with a matching name, this binary will get executed. + + - Otherwise, if the specified name contains a colon character and if one of the workspaces in the project contains exactly one script with a matching name, then this script will get executed. + + Whatever happens, the cwd of the spawned process will be the workspace that declares the script (which makes it possible to call commands cross-workspaces using the third syntax). + `,examples:[["Run the tests from the local workspace","$0 run test"],['Same thing, but without the "run" keyword',"$0 test"],["Inspect Webpack while running","$0 run --inspect-brk webpack"]]});var Lu=class extends Pe{constructor(){super(...arguments);this.save=z.Boolean("-s,--save",!1,{description:"Persist the resolution inside the top-level manifest"});this.descriptor=z.String();this.resolution=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(await i.restoreInstallState({restoreResolutions:!1}),!n)throw new lt(i.cwd,this.context.cwd);let o=P.parseDescriptor(this.descriptor,!0),a=P.makeDescriptor(o,this.resolution);return i.storedDescriptors.set(o.descriptorHash,o),i.storedDescriptors.set(a.descriptorHash,a),i.resolutionAliases.set(o.descriptorHash,a.descriptorHash),(await He.start({configuration:t,stdout:this.context.stdout},async c=>{await i.install({cache:s,report:c})})).exitCode()}};Lu.paths=[["set","resolution"]],Lu.usage=Qe.Usage({description:"enforce a package resolution",details:'\n This command updates the resolution table so that `descriptor` is resolved by `resolution`.\n\n Note that by default this command only affect the current resolution table - meaning that this "manual override" will disappear if you remove the lockfile, or if the package disappear from the table. If you wish to make the enforced resolution persist whatever happens, add the `-s,--save` flag which will also edit the `resolutions` field from your top-level manifest.\n\n Note that no attempt is made at validating that `resolution` is a valid resolution entry for `descriptor`.\n ',examples:[["Force all instances of lodash@npm:^1.2.3 to resolve to 1.5.0","$0 set resolution lodash@npm:^1.2.3 1.5.0"]]});var Sae=ve(Bn()),Ou=class extends Pe{constructor(){super(...arguments);this.all=z.Boolean("-A,--all",!1,{description:"Unlink all workspaces belonging to the target project from the current one"});this.leadingArguments=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);let o=i.topLevelWorkspace,a=new Set;if(this.leadingArguments.length===0&&this.all)for(let{pattern:c,reference:u}of o.manifest.resolutions)u.startsWith("portal:")&&a.add(c.descriptor.fullName);if(this.leadingArguments.length>0)for(let c of this.leadingArguments){let u=v.resolve(this.context.cwd,K.toPortablePath(c));if(me.isPathLike(c)){let g=await Ee.find(u,this.context.plugins,{useRc:!1,strict:!1}),{project:h,workspace:p}=await Ge.find(g,u);if(!p)throw new lt(h.cwd,u);if(this.all){for(let d of h.workspaces)d.manifest.name&&a.add(P.stringifyIdent(d.locator));if(a.size===0)throw new we("No workspace found to be unlinked in the target project")}else{if(!p.manifest.name)throw new we("The target workspace doesn't have a name and thus cannot be unlinked");a.add(P.stringifyIdent(p.locator))}}else{let g=[...o.manifest.resolutions.map(({pattern:h})=>h.descriptor.fullName)];for(let h of(0,Sae.default)(g,c))a.add(h)}}return o.manifest.resolutions=o.manifest.resolutions.filter(({pattern:c})=>!a.has(c.descriptor.fullName)),(await He.start({configuration:t,stdout:this.context.stdout},async c=>{await i.install({cache:s,report:c})})).exitCode()}};Ou.paths=[["unlink"]],Ou.usage=Qe.Usage({description:"disconnect the local project from another one",details:` + This command will remove any resolutions in the project-level manifest that would have been added via a yarn link with similar arguments. + `,examples:[["Unregister a remote workspace in the current project","$0 unlink ~/ts-loader"],["Unregister all workspaces from a remote project in the current project","$0 unlink ~/jest --all"],["Unregister all previously linked workspaces","$0 unlink --all"],["Unregister all workspaces matching a glob","$0 unlink '@babel/*' 'pkg-{a,b}'"]]});var vae=ve(Um()),sO=ve(Bn());As();var ml=class extends Pe{constructor(){super(...arguments);this.interactive=z.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"});this.exact=z.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=z.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=z.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.recursive=z.Boolean("-R,--recursive",!1,{description:"Resolve again ALL resolutions for those packages"});this.mode=z.String("--mode",{description:"Change what artifacts installs generate",validator:Xi(ts)});this.patterns=z.Rest()}async execute(){return this.recursive?await this.executeUpRecursive():await this.executeUpClassic()}async executeUpRecursive(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState({restoreResolutions:!1});let o=[...i.storedDescriptors.values()],a=o.map(g=>P.stringifyIdent(g)),l=new Set;for(let g of this.patterns){if(P.parseDescriptor(g).range!=="unknown")throw new we("Ranges aren't allowed when using --recursive");for(let h of(0,sO.default)(a,g)){let p=P.parseIdent(h);l.add(p.identHash)}}let c=o.filter(g=>l.has(g.identHash));for(let g of c)i.storedDescriptors.delete(g.descriptorHash),i.storedResolutions.delete(g.descriptorHash);return(await He.start({configuration:t,stdout:this.context.stdout},async g=>{await i.install({cache:s,report:g})})).exitCode()}async executeUpClassic(){var y;let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState({restoreResolutions:!1});let o=(y=this.interactive)!=null?y:t.get("preferInteractive"),a=jm(this,i),l=o?["keep","reuse","project","latest"]:["project","latest"],c=[],u=[];for(let B of this.patterns){let S=!1,x=P.parseDescriptor(B);for(let F of i.workspaces)for(let H of["dependencies","devDependencies"]){let _=[...F.manifest.getForScope(H).values()].map(X=>P.stringifyIdent(X));for(let X of(0,sO.default)(_,P.stringifyIdent(x))){let W=P.parseIdent(X),Z=F.manifest[H].get(W.identHash);if(typeof Z>"u")throw new Error("Assertion failed: Expected the descriptor to be registered");let A=P.makeDescriptor(W,x.range);c.push(Promise.resolve().then(async()=>[F,H,Z,await Gm(A,{project:i,workspace:F,cache:s,target:H,modifier:a,strategies:l})])),S=!0}}S||u.push(B)}if(u.length>1)throw new we(`Patterns ${$.prettyList(t,u,$.Type.CODE)} don't match any packages referenced by any workspace`);if(u.length>0)throw new we(`Pattern ${$.prettyList(t,u,$.Type.CODE)} doesn't match any packages referenced by any workspace`);let g=await Promise.all(c),h=await ta.start({configuration:t,stdout:this.context.stdout,suggestInstall:!1},async B=>{for(let[,,S,{suggestions:x,rejections:F}]of g){let H=x.filter(q=>q.descriptor!==null);if(H.length===0){let[q]=F;if(typeof q>"u")throw new Error("Assertion failed: Expected an error to have been set");let _=this.cli.error(q);i.configuration.get("enableNetwork")?B.reportError(27,`${P.prettyDescriptor(t,S)} can't be resolved to a satisfying range + +${_}`):B.reportError(27,`${P.prettyDescriptor(t,S)} can't be resolved to a satisfying range (note: network resolution has been disabled) + +${_}`)}else H.length>1&&!o&&B.reportError(27,`${P.prettyDescriptor(t,S)} has multiple possible upgrade strategies; use -i to disambiguate manually`)}});if(h.hasErrors())return h.exitCode();let p=!1,d=[];for(let[B,S,,{suggestions:x}]of g){let F,H=x.filter(W=>W.descriptor!==null),q=H[0].descriptor,_=H.every(W=>P.areDescriptorsEqual(W.descriptor,q));H.length===1||_?F=q:(p=!0,{answer:F}=await(0,vae.prompt)({type:"select",name:"answer",message:`Which range do you want to use in ${P.prettyWorkspace(t,B)} \u276F ${S}?`,choices:x.map(({descriptor:W,name:Z,reason:A})=>W?{name:Z,hint:A,descriptor:W}:{name:Z,hint:A,disabled:!0}),onCancel:()=>process.exit(130),result(W){return this.find(W,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let X=B.manifest[S].get(F.identHash);if(typeof X>"u")throw new Error("Assertion failed: This descriptor should have a matching entry");if(X.descriptorHash!==F.descriptorHash)B.manifest[S].set(F.identHash,F),d.push([B,S,X,F]);else{let W=t.makeResolver(),Z={project:i,resolver:W},A=W.bindDescriptor(X,B.anchoredLocator,Z);i.forgetResolution(A)}}return await t.triggerMultipleHooks(B=>B.afterWorkspaceDependencyReplacement,d),p&&this.context.stdout.write(` +`),(await He.start({configuration:t,stdout:this.context.stdout},async B=>{await i.install({cache:s,report:B,mode:this.mode})})).exitCode()}};ml.paths=[["up"]],ml.usage=Qe.Usage({description:"upgrade dependencies across the project",details:"\n This command upgrades the packages matching the list of specified patterns to their latest available version across the whole project (regardless of whether they're part of `dependencies` or `devDependencies` - `peerDependencies` won't be affected). This is a project-wide command: all workspaces will be upgraded in the process.\n\n If `-R,--recursive` is set the command will change behavior and no other switch will be allowed. When operating under this mode `yarn up` will force all ranges matching the selected packages to be resolved again (often to the highest available versions) before being stored in the lockfile. It however won't touch your manifests anymore, so depending on your needs you might want to run both `yarn up` and `yarn up -R` to cover all bases.\n\n If `-i,--interactive` is set (or if the `preferInteractive` settings is toggled on) the command will offer various choices, depending on the detected upgrade paths. Some upgrades require this flag in order to resolve ambiguities.\n\n The, `-C,--caret`, `-E,--exact` and `-T,--tilde` options have the same meaning as in the `add` command (they change the modifier used when the range is missing or a tag, and are ignored when the range is explicitly set).\n\n If the `--mode=<mode>` option is set, Yarn will change which artifacts are generated. The modes currently supported are:\n\n - `skip-build` will not run the build scripts at all. Note that this is different from setting `enableScripts` to false because the latter will disable build scripts, and thus affect the content of the artifacts generated on disk, whereas the former will just disable the build step - but not the scripts themselves, which just won't run.\n\n - `update-lockfile` will skip the link step altogether, and only fetch packages that are missing from the lockfile (or that have no associated checksums). This mode is typically used by tools like Renovate or Dependabot to keep a lockfile up-to-date without incurring the full install cost.\n\n Generally you can see `yarn up` as a counterpart to what was `yarn upgrade --latest` in Yarn 1 (ie it ignores the ranges previously listed in your manifests), but unlike `yarn upgrade` which only upgraded dependencies in the current workspace, `yarn up` will upgrade all workspaces at the same time.\n\n This command accepts glob patterns as arguments (if valid Descriptors and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.\n\n **Note:** The ranges have to be static, only the package scopes and names can contain glob patterns.\n ",examples:[["Upgrade all instances of lodash to the latest release","$0 up lodash"],["Upgrade all instances of lodash to the latest release, but ask confirmation for each","$0 up lodash -i"],["Upgrade all instances of lodash to 1.2.3","$0 up lodash@1.2.3"],["Upgrade all instances of packages with the `@babel` scope to the latest release","$0 up '@babel/*'"],["Upgrade all instances of packages containing the word `jest` to the latest release","$0 up '*jest*'"],["Upgrade all instances of packages with the `@babel` scope to 7.0.0","$0 up '@babel/*@7.0.0'"]]}),ml.schema=[av("recursive",uc.Forbids,["interactive","exact","tilde","caret"],{ignore:[void 0,!1]})];var Mu=class extends Pe{constructor(){super(...arguments);this.recursive=z.Boolean("-R,--recursive",!1,{description:"List, for each workspace, what are all the paths that lead to the dependency"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.peers=z.Boolean("--peers",!1,{description:"Also print the peer dependencies that match the specified name"});this.package=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState();let s=P.parseIdent(this.package).identHash,o=this.recursive?$We(i,s,{configuration:t,peers:this.peers}):_We(i,s,{configuration:t,peers:this.peers});es.emitTree(o,{configuration:t,stdout:this.context.stdout,json:this.json,separators:1})}};Mu.paths=[["why"]],Mu.usage=Qe.Usage({description:"display the reason why a package is needed",details:` + This command prints the exact reasons why a package appears in the dependency tree. + + If \`-R,--recursive\` is set, the listing will go in depth and will list, for each workspaces, what are all the paths that lead to the dependency. Note that the display is somewhat optimized in that it will not print the package listing twice for a single package, so if you see a leaf named "Foo" when looking for "Bar", it means that "Foo" already got printed higher in the tree. + `,examples:[["Explain why lodash is used in your project","$0 why lodash"]]});function _We(r,e,{configuration:t,peers:i}){let n=me.sortMap(r.storedPackages.values(),a=>P.stringifyLocator(a)),s={},o={children:s};for(let a of n){let l={};for(let u of a.dependencies.values()){if(!i&&a.peerDependencies.has(u.identHash))continue;let g=r.storedResolutions.get(u.descriptorHash);if(!g)throw new Error("Assertion failed: The resolution should have been registered");let h=r.storedPackages.get(g);if(!h)throw new Error("Assertion failed: The package should have been registered");if(h.identHash!==e)continue;{let d=P.stringifyLocator(a);s[d]={value:[a,$.Type.LOCATOR],children:l}}let p=P.stringifyLocator(h);l[p]={value:[{descriptor:u,locator:h},$.Type.DEPENDENT]}}}return o}function $We(r,e,{configuration:t,peers:i}){let n=me.sortMap(r.workspaces,h=>P.stringifyLocator(h.anchoredLocator)),s=new Set,o=new Set,a=h=>{if(s.has(h.locatorHash))return o.has(h.locatorHash);if(s.add(h.locatorHash),h.identHash===e)return o.add(h.locatorHash),!0;let p=!1;h.identHash===e&&(p=!0);for(let d of h.dependencies.values()){if(!i&&h.peerDependencies.has(d.identHash))continue;let m=r.storedResolutions.get(d.descriptorHash);if(!m)throw new Error("Assertion failed: The resolution should have been registered");let y=r.storedPackages.get(m);if(!y)throw new Error("Assertion failed: The package should have been registered");a(y)&&(p=!0)}return p&&o.add(h.locatorHash),p};for(let h of n){let p=r.storedPackages.get(h.anchoredLocator.locatorHash);if(!p)throw new Error("Assertion failed: The package should have been registered");a(p)}let l=new Set,c={},u={children:c},g=(h,p,d)=>{if(!o.has(h.locatorHash))return;let m=d!==null?$.tuple($.Type.DEPENDENT,{locator:h,descriptor:d}):$.tuple($.Type.LOCATOR,h),y={},B={value:m,children:y},S=P.stringifyLocator(h);if(p[S]=B,!l.has(h.locatorHash)&&(l.add(h.locatorHash),!(d!==null&&r.tryWorkspaceByLocator(h))))for(let x of h.dependencies.values()){if(!i&&h.peerDependencies.has(x.identHash))continue;let F=r.storedResolutions.get(x.descriptorHash);if(!F)throw new Error("Assertion failed: The resolution should have been registered");let H=r.storedPackages.get(F);if(!H)throw new Error("Assertion failed: The package should have been registered");g(H,y,x)}};for(let h of n){let p=r.storedPackages.get(h.anchoredLocator.locatorHash);if(!p)throw new Error("Assertion failed: The package should have been registered");g(p,c,null)}return u}var dO={};ct(dO,{default:()=>E4e,gitUtils:()=>lA});var lA={};ct(lA,{TreeishProtocols:()=>Tb,clone:()=>pO,fetchBase:()=>Xae,fetchChangedFiles:()=>Zae,fetchChangedWorkspaces:()=>C4e,fetchRoot:()=>Vae,isGitUrl:()=>ep,lsRemote:()=>zae,normalizeLocator:()=>gO,normalizeRepoUrl:()=>Lb,resolveUrl:()=>hO,splitRepoUrl:()=>Vm,validateRepoUrl:()=>fO});var qae=ve(Hae()),Jae=ve(PB()),$h=ve(J("querystring")),cO=ve(zr());var Gae=J("url");function lO(r,e,t){let i=r.indexOf(t);return r.lastIndexOf(e,i>-1?i:1/0)}function jae(r){try{return new Gae.URL(r)}catch{return}}function p4e(r){let e=lO(r,"@","#"),t=lO(r,":","#");return t>e&&(r=`${r.slice(0,t)}/${r.slice(t+1)}`),lO(r,":","#")===-1&&r.indexOf("//")===-1&&(r=`ssh://${r}`),r}function Yae(r){return jae(r)||jae(p4e(r))}function Wae(){return{...process.env,GIT_SSH_COMMAND:process.env.GIT_SSH_COMMAND||`${process.env.GIT_SSH||"ssh"} -o BatchMode=yes`}}var d4e=[/^ssh:/,/^git(?:\+[^:]+)?:/,/^(?:git\+)?https?:[^#]+\/[^#]+(?:\.git)(?:#.*)?$/,/^git@[^#]+\/[^#]+\.git(?:#.*)?$/,/^(?:github:|https:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z._0-9-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z._0-9-]+?)(?:\.git)?(?:#.*)?$/,/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/],Tb=(n=>(n.Commit="commit",n.Head="head",n.Tag="tag",n.Semver="semver",n))(Tb||{});function ep(r){return r?d4e.some(e=>!!r.match(e)):!1}function Vm(r){r=Lb(r);let e=r.indexOf("#");if(e===-1)return{repo:r,treeish:{protocol:"head",request:"HEAD"},extra:{}};let t=r.slice(0,e),i=r.slice(e+1);if(i.match(/^[a-z]+=/)){let n=$h.default.parse(i);for(let[l,c]of Object.entries(n))if(typeof c!="string")throw new Error(`Assertion failed: The ${l} parameter must be a literal string`);let s=Object.values(Tb).find(l=>Object.prototype.hasOwnProperty.call(n,l)),[o,a]=typeof s<"u"?[s,n[s]]:["head","HEAD"];for(let l of Object.values(Tb))delete n[l];return{repo:t,treeish:{protocol:o,request:a},extra:n}}else{let n=i.indexOf(":"),[s,o]=n===-1?[null,i]:[i.slice(0,n),i.slice(n+1)];return{repo:t,treeish:{protocol:s,request:o},extra:{}}}}function Lb(r,{git:e=!1}={}){if(r=r.replace(/^git\+https:/,"https:"),r=r.replace(/^(?:github:|https:\/\/github\.com\/|git:\/\/github\.com\/)?(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)(?:\.git)?(#.*)?$/,"https://github.com/$1/$2.git$3"),r=r.replace(/^https:\/\/github\.com\/(?!\.{1,2}\/)([a-zA-Z0-9._-]+)\/(?!\.{1,2}(?:#|$))([a-zA-Z0-9._-]+?)\/tarball\/(.+)?$/,"https://github.com/$1/$2.git#$3"),e){let t=Yae(r);t&&(r=t.href),r=r.replace(/^git\+([^:]+):/,"$1:")}return r}function gO(r){return P.makeLocator(r,Lb(r.reference))}function fO(r,{configuration:e}){let t=Lb(r,{git:!0});if(!Vt.getNetworkSettings(`https://${(0,qae.default)(t).resource}`,{configuration:e}).enableNetwork)throw new rt(80,`Request to '${t}' has been blocked because of your configuration settings`);return t}async function zae(r,e){let t=fO(r,{configuration:e}),i=await uO("listing refs",["ls-remote",t],{cwd:e.startingCwd,env:Wae()},{configuration:e,normalizedRepoUrl:t}),n=new Map,s=/^([a-f0-9]{40})\t([^\n]+)/gm,o;for(;(o=s.exec(i.stdout))!==null;)n.set(o[2],o[1]);return n}async function hO(r,e){let{repo:t,treeish:{protocol:i,request:n},extra:s}=Vm(r),o=await zae(t,e),a=(c,u)=>{switch(c){case"commit":{if(!u.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return $h.default.stringify({...s,commit:u})}case"head":{let g=o.get(u==="HEAD"?u:`refs/heads/${u}`);if(typeof g>"u")throw new Error(`Unknown head ("${u}")`);return $h.default.stringify({...s,commit:g})}case"tag":{let g=o.get(`refs/tags/${u}`);if(typeof g>"u")throw new Error(`Unknown tag ("${u}")`);return $h.default.stringify({...s,commit:g})}case"semver":{let g=Qt.validRange(u);if(!g)throw new Error(`Invalid range ("${u}")`);let h=new Map([...o.entries()].filter(([d])=>d.startsWith("refs/tags/")).map(([d,m])=>[cO.default.parse(d.slice(10)),m]).filter(d=>d[0]!==null)),p=cO.default.maxSatisfying([...h.keys()],g);if(p===null)throw new Error(`No matching range ("${u}")`);return $h.default.stringify({...s,commit:h.get(p)})}case null:{let g;if((g=l("commit",u))!==null||(g=l("tag",u))!==null||(g=l("head",u))!==null)return g;throw u.match(/^[a-f0-9]+$/)?new Error(`Couldn't resolve "${u}" as either a commit, a tag, or a head - if a commit, use the 40-characters commit hash`):new Error(`Couldn't resolve "${u}" as either a commit, a tag, or a head`)}default:throw new Error(`Invalid Git resolution protocol ("${c}")`)}},l=(c,u)=>{try{return a(c,u)}catch{return null}};return`${t}#${a(i,n)}`}async function pO(r,e){return await e.getLimit("cloneConcurrency")(async()=>{let{repo:t,treeish:{protocol:i,request:n}}=Vm(r);if(i!=="commit")throw new Error("Invalid treeish protocol when cloning");let s=fO(t,{configuration:e}),o=await M.mktempPromise(),a={cwd:o,env:Wae()};return await uO("cloning the repository",["clone","-c core.autocrlf=false",s,K.fromPortablePath(o)],a,{configuration:e,normalizedRepoUrl:s}),await uO("switching branch",["checkout",`${n}`],a,{configuration:e,normalizedRepoUrl:s}),o})}async function Vae(r){let e,t=r;do{if(e=t,await M.existsPromise(v.join(e,".git")))return e;t=v.dirname(e)}while(t!==e);return null}async function Xae(r,{baseRefs:e}){if(e.length===0)throw new we("Can't run this command with zero base refs specified.");let t=[];for(let a of e){let{code:l}=await pr.execvp("git",["merge-base",a,"HEAD"],{cwd:r});l===0&&t.push(a)}if(t.length===0)throw new we(`No ancestor could be found between any of HEAD and ${e.join(", ")}`);let{stdout:i}=await pr.execvp("git",["merge-base","HEAD",...t],{cwd:r,strict:!0}),n=i.trim(),{stdout:s}=await pr.execvp("git",["show","--quiet","--pretty=format:%s",n],{cwd:r,strict:!0}),o=s.trim();return{hash:n,title:o}}async function Zae(r,{base:e,project:t}){let i=me.buildIgnorePattern(t.configuration.get("changesetIgnorePatterns")),{stdout:n}=await pr.execvp("git",["diff","--name-only",`${e}`],{cwd:r,strict:!0}),s=n.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>v.resolve(r,K.toPortablePath(c))),{stdout:o}=await pr.execvp("git",["ls-files","--others","--exclude-standard"],{cwd:r,strict:!0}),a=o.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>v.resolve(r,K.toPortablePath(c))),l=[...new Set([...s,...a].sort())];return i?l.filter(c=>!v.relative(t.cwd,c).match(i)):l}async function C4e({ref:r,project:e}){if(e.configuration.projectCwd===null)throw new we("This command can only be run from within a Yarn project");let t=[v.resolve(e.cwd,e.configuration.get("cacheFolder")),v.resolve(e.cwd,e.configuration.get("installStatePath")),v.resolve(e.cwd,e.configuration.get("lockfileFilename")),v.resolve(e.cwd,e.configuration.get("virtualFolder"))];await e.configuration.triggerHook(o=>o.populateYarnPaths,e,o=>{o!=null&&t.push(o)});let i=await Vae(e.configuration.projectCwd);if(i==null)throw new we("This command can only be run on Git repositories");let n=await Xae(i,{baseRefs:typeof r=="string"?[r]:e.configuration.get("changesetBaseRefs")}),s=await Zae(i,{base:n.hash,project:e});return new Set(me.mapAndFilter(s,o=>{let a=e.tryWorkspaceByFilePath(o);return a===null?me.mapAndFilter.skip:t.some(l=>o.startsWith(l))?me.mapAndFilter.skip:a}))}async function uO(r,e,t,{configuration:i,normalizedRepoUrl:n}){try{return await pr.execvp("git",e,{...t,strict:!0})}catch(s){if(!(s instanceof pr.ExecError))throw s;let o=s.reportExtra,a=s.stderr.toString();throw new rt(1,`Failed ${r}`,l=>{l.reportError(1,` ${$.prettyField(i,{label:"Repository URL",value:$.tuple($.Type.URL,n)})}`);for(let c of a.matchAll(/^(.+?): (.*)$/gm)){let[,u,g]=c;u=u.toLowerCase();let h=u==="error"?"Error":`${(0,Jae.default)(u)} Error`;l.reportError(1,` ${$.prettyField(i,{label:h,value:$.tuple($.Type.NO_HINT,g)})}`)}o==null||o(l)})}}var Ob=class{supports(e,t){return ep(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,n=gO(e),s=new Map(t.checksums);s.set(n.locatorHash,i);let o={...t,checksums:s},a=await this.downloadHosted(n,o);if(a!==null)return a;let[l,c,u]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote repository`),loader:()=>this.cloneFromRemote(n,o),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:l,releaseFs:c,prefixPath:P.getIdentVendorPath(e),checksum:u}}async downloadHosted(e,t){return t.project.configuration.reduceHook(i=>i.fetchHostedRepository,null,e,t)}async cloneFromRemote(e,t){let i=await pO(e.reference,t.project.configuration),n=Vm(e.reference),s=v.join(i,"package.tgz");await Yt.prepareExternalProject(i,s,{configuration:t.project.configuration,report:t.report,workspace:n.extra.workspace,locator:e});let o=await M.readFilePromise(s);return await me.releaseAfterUseAsync(async()=>await Ci.convertToZip(o,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1}))}};var Mb=class{supportsDescriptor(e,t){return ep(e.range)}supportsLocator(e,t){return ep(e.reference)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=await hO(e.range,i.project.configuration);return[P.makeLocator(e,n)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await me.releaseAfterUseAsync(async()=>await ot.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return{...e,version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin}}};var m4e={configuration:{changesetBaseRefs:{description:"The base git refs that the current HEAD is compared against when detecting changes. Supports git branches, tags, and commits.",type:"STRING",isArray:!0,isNullable:!1,default:["master","origin/master","upstream/master","main","origin/main","upstream/main"]},changesetIgnorePatterns:{description:"Array of glob patterns; files matching them will be ignored when fetching the changed files",type:"STRING",default:[],isArray:!0},cloneConcurrency:{description:"Maximal number of concurrent clones",type:"NUMBER",default:2}},fetchers:[Ob],resolvers:[Mb]};var E4e=m4e;var Ku=class extends Pe{constructor(){super(...arguments);this.since=z.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.recursive=z.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.noPrivate=z.Boolean("--no-private",{description:"Exclude workspaces that have the private field set to true"});this.verbose=z.Boolean("-v,--verbose",!1,{description:"Also return the cross-dependencies between workspaces"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i}=await Ge.find(t,this.context.cwd);return(await He.start({configuration:t,json:this.json,stdout:this.context.stdout},async s=>{let o=this.since?await lA.fetchChangedWorkspaces({ref:this.since,project:i}):i.workspaces,a=new Set(o);if(this.recursive)for(let l of[...o].map(c=>c.getRecursiveWorkspaceDependents()))for(let c of l)a.add(c);for(let l of a){let{manifest:c}=l;if(c.private&&this.noPrivate)continue;let u;if(this.verbose){let g=new Set,h=new Set;for(let p of ot.hardDependencies)for(let[d,m]of c.getForScope(p)){let y=i.tryWorkspaceByDescriptor(m);y===null?i.workspacesByIdent.has(d)&&h.add(m):g.add(y)}u={workspaceDependencies:Array.from(g).map(p=>p.relativeCwd),mismatchedWorkspaceDependencies:Array.from(h).map(p=>P.stringifyDescriptor(p))}}s.reportInfo(null,`${l.relativeCwd}`),s.reportJson({location:l.relativeCwd,name:c.name?P.stringifyIdent(c.name):null,...u})}})).exitCode()}};Ku.paths=[["workspaces","list"]],Ku.usage=Qe.Usage({category:"Workspace-related commands",description:"list all available workspaces",details:"\n This command will print the list of all workspaces in the project.\n\n - If `--since` is set, Yarn will only list workspaces that have been modified since the specified ref. By default Yarn will use the refs specified by the `changesetBaseRefs` configuration option.\n\n - If `-R,--recursive` is set, Yarn will find workspaces to run the command on by recursively evaluating `dependencies` and `devDependencies` fields, instead of looking at the `workspaces` fields.\n\n - If `--no-private` is set, Yarn will not list any workspaces that have the `private` field set to `true`.\n\n - If both the `-v,--verbose` and `--json` options are set, Yarn will also return the cross-dependencies between each workspaces (useful when you wish to automatically generate Buck / Bazel rules).\n "});var Uu=class extends Pe{constructor(){super(...arguments);this.workspaceName=z.String();this.commandName=z.String();this.args=z.Proxy()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);let s=i.workspaces,o=new Map(s.map(l=>[P.stringifyIdent(l.locator),l])),a=o.get(this.workspaceName);if(a===void 0){let l=Array.from(o.keys()).sort();throw new we(`Workspace '${this.workspaceName}' not found. Did you mean any of the following: + - ${l.join(` + - `)}?`)}return this.cli.run([this.commandName,...this.args],{cwd:a.cwd})}};Uu.paths=[["workspace"]],Uu.usage=Qe.Usage({category:"Workspace-related commands",description:"run a command within the specified workspace",details:` + This command will run a given sub-command on a single workspace. + `,examples:[["Add a package to a single workspace","yarn workspace components add -D react"],["Run build script on a single workspace","yarn workspace components run build"]]});var I4e={configuration:{enableImmutableInstalls:{description:"If true (the default on CI), prevents the install command from modifying the lockfile",type:"BOOLEAN",default:_ae.isCI},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:"STRING",values:["^","~",""],default:"^"},preferReuse:{description:"If true, `yarn add` will attempt to reuse the most common dependency range in other workspaces.",type:"BOOLEAN",default:!1}},commands:[gu,fu,hu,pu,Lu,Pu,Iu,Ku,Vh,Xh,Jm,Zh,cu,uu,du,Cu,mu,Eu,yu,wu,Bu,bu,Ou,Qu,ku,xu,Du,Su,Ru,Fu,Nu,_h,Tu,ml,Mu,Uu]},y4e=I4e;var wO={};ct(wO,{default:()=>B4e});var Fe={optional:!0},mO=[["@tailwindcss/aspect-ratio@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@tailwindcss/line-clamp@<0.2.1",{peerDependencies:{tailwindcss:"^2.0.2"}}],["@fullhuman/postcss-purgecss@3.1.3 || 3.1.3-alpha.0",{peerDependencies:{postcss:"^8.0.0"}}],["@samverschueren/stream-to-observable@<0.3.1",{peerDependenciesMeta:{rxjs:Fe,zenObservable:Fe}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:Fe,zenObservable:Fe}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{["supports-color"]:Fe}}],["got@<11",{dependencies:{["@types/responselike"]:"^1.0.0",["@types/keyv"]:"^3.1.1"}}],["cacheable-lookup@<4.1.2",{dependencies:{["@types/keyv"]:"^3.1.1"}}],["http-link-dataloader@*",{peerDependencies:{graphql:"^0.13.1 || ^14.0.0"}}],["typescript-language-server@*",{dependencies:{["vscode-jsonrpc"]:"^5.0.1",["vscode-languageserver-protocol"]:"^3.15.0"}}],["postcss-syntax@*",{peerDependenciesMeta:{["postcss-html"]:Fe,["postcss-jsx"]:Fe,["postcss-less"]:Fe,["postcss-markdown"]:Fe,["postcss-scss"]:Fe}}],["jss-plugin-rule-value-function@<=10.1.1",{dependencies:{["tiny-warning"]:"^1.0.2"}}],["ink-select-input@<4.1.0",{peerDependencies:{react:"^16.8.2"}}],["license-webpack-plugin@<2.3.18",{peerDependenciesMeta:{webpack:Fe}}],["snowpack@>=3.3.0",{dependencies:{["node-gyp"]:"^7.1.0"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:Fe}}],["reactcss@*",{peerDependencies:{react:"*"}}],["react-color@<=2.19.0",{peerDependencies:{react:"*"}}],["gatsby-plugin-i18n@*",{dependencies:{ramda:"^0.24.1"}}],["useragent@^2.0.0",{dependencies:{request:"^2.88.0",yamlparser:"0.0.x",semver:"5.5.x"}}],["@apollographql/apollo-tools@<=0.5.2",{peerDependencies:{graphql:"^14.2.1 || ^15.0.0"}}],["material-table@^2.0.0",{dependencies:{"@babel/runtime":"^7.11.2"}}],["@babel/parser@*",{dependencies:{"@babel/types":"^7.8.3"}}],["fork-ts-checker-webpack-plugin@<=6.3.4",{peerDependencies:{eslint:">= 6",typescript:">= 2.7",webpack:">= 4","vue-template-compiler":"*"},peerDependenciesMeta:{eslint:Fe,"vue-template-compiler":Fe}}],["rc-animate@<=3.1.1",{peerDependencies:{react:">=16.9.0","react-dom":">=16.9.0"}}],["react-bootstrap-table2-paginator@*",{dependencies:{classnames:"^2.2.6"}}],["react-draggable@<=4.4.3",{peerDependencies:{react:">= 16.3.0","react-dom":">= 16.3.0"}}],["apollo-upload-client@<14",{peerDependencies:{graphql:"14 - 15"}}],["react-instantsearch-core@<=6.7.0",{peerDependencies:{algoliasearch:">= 3.1 < 5"}}],["react-instantsearch-dom@<=6.7.0",{dependencies:{"react-fast-compare":"^3.0.0"}}],["ws@<7.2.1",{peerDependencies:{bufferutil:"^4.0.1","utf-8-validate":"^5.0.2"},peerDependenciesMeta:{bufferutil:Fe,"utf-8-validate":Fe}}],["react-portal@<4.2.2",{peerDependencies:{"react-dom":"^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"}}],["react-scripts@<=4.0.1",{peerDependencies:{react:"*"}}],["testcafe@<=1.10.1",{dependencies:{"@babel/plugin-transform-for-of":"^7.12.1","@babel/runtime":"^7.12.5"}}],["testcafe-legacy-api@<=4.2.0",{dependencies:{"testcafe-hammerhead":"^17.0.1","read-file-relative":"^1.2.0"}}],["@google-cloud/firestore@<=4.9.3",{dependencies:{protobufjs:"^6.8.6"}}],["gatsby-source-apiserver@*",{dependencies:{["babel-polyfill"]:"^6.26.0"}}],["@webpack-cli/package-utils@<=1.0.1-alpha.4",{dependencies:{["cross-spawn"]:"^7.0.3"}}],["gatsby-remark-prismjs@<3.3.28",{dependencies:{lodash:"^4"}}],["gatsby-plugin-favicon@*",{peerDependencies:{webpack:"*"}}],["gatsby-plugin-sharp@<=4.6.0-next.3",{dependencies:{debug:"^4.3.1"}}],["gatsby-react-router-scroll@<=5.6.0-next.0",{dependencies:{["prop-types"]:"^15.7.2"}}],["@rebass/forms@*",{dependencies:{["@styled-system/should-forward-prop"]:"^5.0.0"},peerDependencies:{react:"^16.8.6"}}],["rebass@*",{peerDependencies:{react:"^16.8.6"}}],["@ant-design/react-slick@<=0.28.3",{peerDependencies:{react:">=16.0.0"}}],["mqtt@<4.2.7",{dependencies:{duplexify:"^4.1.1"}}],["vue-cli-plugin-vuetify@<=2.0.3",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":Fe,"vuetify-loader":Fe}}],["vue-cli-plugin-vuetify@<=2.0.4",{dependencies:{"null-loader":"^3.0.0"}}],["vue-cli-plugin-vuetify@>=2.4.3",{peerDependencies:{vue:"*"}}],["@vuetify/cli-plugin-utils@<=0.0.4",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":Fe}}],["@vue/cli-plugin-typescript@<=5.0.0-alpha.0",{dependencies:{"babel-loader":"^8.1.0"}}],["@vue/cli-plugin-typescript@<=5.0.0-beta.0",{dependencies:{"@babel/core":"^7.12.16"},peerDependencies:{"vue-template-compiler":"^2.0.0"},peerDependenciesMeta:{"vue-template-compiler":Fe}}],["cordova-ios@<=6.3.0",{dependencies:{underscore:"^1.9.2"}}],["cordova-lib@<=10.0.1",{dependencies:{underscore:"^1.9.2"}}],["git-node-fs@*",{peerDependencies:{"js-git":"^0.7.8"},peerDependenciesMeta:{"js-git":Fe}}],["consolidate@<0.16.0",{peerDependencies:{mustache:"^3.0.0"},peerDependenciesMeta:{mustache:Fe}}],["consolidate@<=0.16.0",{peerDependencies:{velocityjs:"^2.0.1",tinyliquid:"^0.2.34","liquid-node":"^3.0.1",jade:"^1.11.0","then-jade":"*",dust:"^0.3.0","dustjs-helpers":"^1.7.4","dustjs-linkedin":"^2.7.5",swig:"^1.4.2","swig-templates":"^2.0.3","razor-tmpl":"^1.3.1",atpl:">=0.7.6",liquor:"^0.0.5",twig:"^1.15.2",ejs:"^3.1.5",eco:"^1.1.0-rc-3",jazz:"^0.0.18",jqtpl:"~1.1.0",hamljs:"^0.6.2",hamlet:"^0.3.3",whiskers:"^0.4.0","haml-coffee":"^1.14.1","hogan.js":"^3.0.2",templayed:">=0.2.3",handlebars:"^4.7.6",underscore:"^1.11.0",lodash:"^4.17.20",pug:"^3.0.0","then-pug":"*",qejs:"^3.0.5",walrus:"^0.10.1",mustache:"^4.0.1",just:"^0.1.8",ect:"^0.5.9",mote:"^0.2.0",toffee:"^0.3.6",dot:"^1.1.3","bracket-template":"^1.1.5",ractive:"^1.3.12",nunjucks:"^3.2.2",htmling:"^0.0.8","babel-core":"^6.26.3",plates:"~0.4.11","react-dom":"^16.13.1",react:"^16.13.1","arc-templates":"^0.5.3",vash:"^0.13.0",slm:"^2.0.0",marko:"^3.14.4",teacup:"^2.0.0","coffee-script":"^1.12.7",squirrelly:"^5.1.0",twing:"^5.0.2"},peerDependenciesMeta:{velocityjs:Fe,tinyliquid:Fe,"liquid-node":Fe,jade:Fe,"then-jade":Fe,dust:Fe,"dustjs-helpers":Fe,"dustjs-linkedin":Fe,swig:Fe,"swig-templates":Fe,"razor-tmpl":Fe,atpl:Fe,liquor:Fe,twig:Fe,ejs:Fe,eco:Fe,jazz:Fe,jqtpl:Fe,hamljs:Fe,hamlet:Fe,whiskers:Fe,"haml-coffee":Fe,"hogan.js":Fe,templayed:Fe,handlebars:Fe,underscore:Fe,lodash:Fe,pug:Fe,"then-pug":Fe,qejs:Fe,walrus:Fe,mustache:Fe,just:Fe,ect:Fe,mote:Fe,toffee:Fe,dot:Fe,"bracket-template":Fe,ractive:Fe,nunjucks:Fe,htmling:Fe,"babel-core":Fe,plates:Fe,"react-dom":Fe,react:Fe,"arc-templates":Fe,vash:Fe,slm:Fe,marko:Fe,teacup:Fe,"coffee-script":Fe,squirrelly:Fe,twing:Fe}}],["vue-loader@<=16.3.3",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",webpack:"^4.1.0 || ^5.0.0-0"},peerDependenciesMeta:{"@vue/compiler-sfc":Fe}}],["vue-loader@^16.7.0",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",vue:"^3.2.13"},peerDependenciesMeta:{"@vue/compiler-sfc":Fe,vue:Fe}}],["scss-parser@<=1.0.5",{dependencies:{lodash:"^4.17.21"}}],["query-ast@<1.0.5",{dependencies:{lodash:"^4.17.21"}}],["redux-thunk@<=2.3.0",{peerDependencies:{redux:"^4.0.0"}}],["skypack@<=0.3.2",{dependencies:{tar:"^6.1.0"}}],["@npmcli/metavuln-calculator@<2.0.0",{dependencies:{"json-parse-even-better-errors":"^2.3.1"}}],["bin-links@<2.3.0",{dependencies:{"mkdirp-infer-owner":"^1.0.2"}}],["rollup-plugin-polyfill-node@<=0.8.0",{peerDependencies:{rollup:"^1.20.0 || ^2.0.0"}}],["snowpack@<3.8.6",{dependencies:{"magic-string":"^0.25.7"}}],["elm-webpack-loader@*",{dependencies:{temp:"^0.9.4"}}],["winston-transport@<=4.4.0",{dependencies:{logform:"^2.2.0"}}],["jest-vue-preprocessor@*",{dependencies:{"@babel/core":"7.8.7","@babel/template":"7.8.6"},peerDependencies:{pug:"^2.0.4"},peerDependenciesMeta:{pug:Fe}}],["redux-persist@*",{peerDependencies:{react:">=16"},peerDependenciesMeta:{react:Fe}}],["sodium@>=3",{dependencies:{"node-gyp":"^3.8.0"}}],["babel-plugin-graphql-tag@<=3.1.0",{peerDependencies:{graphql:"^14.0.0 || ^15.0.0"}}],["@playwright/test@<=1.14.1",{dependencies:{"jest-matcher-utils":"^26.4.2"}}],...["babel-plugin-remove-graphql-queries@<3.14.0-next.1","babel-preset-gatsby-package@<1.14.0-next.1","create-gatsby@<1.14.0-next.1","gatsby-admin@<0.24.0-next.1","gatsby-cli@<3.14.0-next.1","gatsby-core-utils@<2.14.0-next.1","gatsby-design-tokens@<3.14.0-next.1","gatsby-legacy-polyfills@<1.14.0-next.1","gatsby-plugin-benchmark-reporting@<1.14.0-next.1","gatsby-plugin-graphql-config@<0.23.0-next.1","gatsby-plugin-image@<1.14.0-next.1","gatsby-plugin-mdx@<2.14.0-next.1","gatsby-plugin-netlify-cms@<5.14.0-next.1","gatsby-plugin-no-sourcemaps@<3.14.0-next.1","gatsby-plugin-page-creator@<3.14.0-next.1","gatsby-plugin-preact@<5.14.0-next.1","gatsby-plugin-preload-fonts@<2.14.0-next.1","gatsby-plugin-schema-snapshot@<2.14.0-next.1","gatsby-plugin-styletron@<6.14.0-next.1","gatsby-plugin-subfont@<3.14.0-next.1","gatsby-plugin-utils@<1.14.0-next.1","gatsby-recipes@<0.25.0-next.1","gatsby-source-shopify@<5.6.0-next.1","gatsby-source-wikipedia@<3.14.0-next.1","gatsby-transformer-screenshot@<3.14.0-next.1","gatsby-worker@<0.5.0-next.1"].map(r=>[r,{dependencies:{"@babel/runtime":"^7.14.8"}}]),["gatsby-core-utils@<2.14.0-next.1",{dependencies:{got:"8.3.2"}}],["gatsby-plugin-gatsby-cloud@<=3.1.0-next.0",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["gatsby-plugin-gatsby-cloud@<=3.2.0-next.1",{peerDependencies:{webpack:"*"}}],["babel-plugin-remove-graphql-queries@<=3.14.0-next.1",{dependencies:{"gatsby-core-utils":"^2.8.0-next.1"}}],["gatsby-plugin-netlify@3.13.0-next.1",{dependencies:{"gatsby-core-utils":"^2.13.0-next.0"}}],["clipanion-v3-codemod@<=0.2.0",{peerDependencies:{jscodeshift:"^0.11.0"}}],["react-live@*",{peerDependencies:{"react-dom":"*",react:"*"}}],["webpack@<4.44.1",{peerDependenciesMeta:{"webpack-cli":Fe,"webpack-command":Fe}}],["webpack@<5.0.0-beta.23",{peerDependenciesMeta:{"webpack-cli":Fe}}],["webpack-dev-server@<3.10.2",{peerDependenciesMeta:{"webpack-cli":Fe}}],["@docusaurus/responsive-loader@<1.5.0",{peerDependenciesMeta:{sharp:Fe,jimp:Fe}}],["eslint-module-utils@*",{peerDependenciesMeta:{"eslint-import-resolver-node":Fe,"eslint-import-resolver-typescript":Fe,"eslint-import-resolver-webpack":Fe,"@typescript-eslint/parser":Fe}}],["eslint-plugin-import@*",{peerDependenciesMeta:{"@typescript-eslint/parser":Fe}}],["critters-webpack-plugin@<3.0.2",{peerDependenciesMeta:{"html-webpack-plugin":Fe}}],["terser@<=5.10.0",{dependencies:{acorn:"^8.5.0"}}],["babel-preset-react-app@10.0.x <10.0.2",{dependencies:{"@babel/plugin-proposal-private-property-in-object":"^7.16.7"}}],["eslint-config-react-app@*",{peerDependenciesMeta:{typescript:Fe}}],["@vue/eslint-config-typescript@<11.0.0",{peerDependenciesMeta:{typescript:Fe}}],["unplugin-vue2-script-setup@<0.9.1",{peerDependencies:{"@vue/composition-api":"^1.4.3","@vue/runtime-dom":"^3.2.26"}}],["@cypress/snapshot@*",{dependencies:{debug:"^3.2.7"}}],["auto-relay@<=0.14.0",{peerDependencies:{"reflect-metadata":"^0.1.13"}}],["vue-template-babel-compiler@<1.2.0",{peerDependencies:{["vue-template-compiler"]:"^2.6.0"}}],["@parcel/transformer-image@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["@parcel/transformer-js@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["parcel@*",{peerDependenciesMeta:{["@parcel/core"]:Fe}}],["react-scripts@*",{peerDependencies:{eslint:"*"}}],["focus-trap-react@^8.0.0",{dependencies:{tabbable:"^5.3.2"}}],["react-rnd@<10.3.7",{peerDependencies:{react:">=16.3.0","react-dom":">=16.3.0"}}],["connect-mongo@<5.0.0",{peerDependencies:{"express-session":"^1.17.1"}}],["vue-i18n@<9",{peerDependencies:{vue:"^2"}}],["vue-router@<4",{peerDependencies:{vue:"^2"}}],["unified@<10",{dependencies:{"@types/unist":"^2.0.0"}}],["react-github-btn@<=1.3.0",{peerDependencies:{react:">=16.3.0"}}],["react-dev-utils@*",{peerDependencies:{typescript:">=2.7",webpack:">=4"},peerDependenciesMeta:{typescript:Fe}}],["@asyncapi/react-component@<=1.0.0-next.39",{peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}}],["xo@*",{peerDependencies:{webpack:">=1.11.0"},peerDependenciesMeta:{webpack:Fe}}],["babel-plugin-remove-graphql-queries@<=4.20.0-next.0",{dependencies:{"@babel/types":"^7.15.4"}}],["gatsby-plugin-page-creator@<=4.20.0-next.1",{dependencies:{"fs-extra":"^10.1.0"}}],["gatsby-plugin-utils@<=3.14.0-next.1",{dependencies:{fastq:"^1.13.0"},peerDependencies:{graphql:"^15.0.0"}}],["gatsby-plugin-mdx@<3.1.0-next.1",{dependencies:{mkdirp:"^1.0.4"}}],["gatsby-plugin-mdx@^2",{peerDependencies:{gatsby:"^3.0.0-next"}}],["fdir@<=5.2.0",{peerDependencies:{picomatch:"2.x"},peerDependenciesMeta:{picomatch:Fe}}],["babel-plugin-transform-typescript-metadata@<=0.3.2",{peerDependencies:{"@babel/core":"^7","@babel/traverse":"^7"},peerDependenciesMeta:{"@babel/traverse":Fe}}],["graphql-compose@>=9.0.10",{peerDependencies:{graphql:"^14.2.0 || ^15.0.0 || ^16.0.0"}}],["vite-plugin-vuetify@<=1.0.2",{peerDependencies:{vue:"^3.0.0"}}],["webpack-plugin-vuetify@<=2.0.1",{peerDependencies:{vue:"^3.2.6"}}]];var EO;function $ae(){return typeof EO>"u"&&(EO=J("zlib").brotliDecompressSync(Buffer.from("G7weAByFTVk3Vs7UfHhq4yykgEM7pbW7TI43SG2S5tvGrwHBAzdz+s/npQ6tgEvobvxisrPIadkXeUAJotBn5bDZ5kAhcRqsIHe3F75Walet5hNalwgFDtxb0BiDUjiUQkjG0yW2hto9HPgiCkm316d6bC0kST72YN7D7rfkhCE9x4J0XwB0yavalxpUu2t9xszHrmtwalOxT7VslsxWcB1qpqZwERUra4psWhTV8BgwWeizurec82Caf1ABL11YMfbf8FJ9JBceZOkgmvrQPbC9DUldX/yMbmX06UQluCEjSwUoyO+EZPIjofr+/oAZUck2enraRD+oWLlnlYnj8xB+gwSo9lmmks4fXv574qSqcWA6z21uYkzMu3EWj+K23RxeQlLqiE35/rC8GcS4CGkKHKKq+zAIQwD9iRDNfiAqueLLpicFFrNsAI4zeTD/eO9MHcnRa5m8UT+M2+V+AkFST4BlKneiAQRSdST8KEAIyFlULt6wa9EBd0Ds28VmpaxquJdVt+nwdEs5xUskI13OVtFyY0UrQIRAlCuvvWivvlSKQfTO+2Q8OyUR1W5RvetaPz4jD27hdtwHFFA1Ptx6Ee/t2cY2rg2G46M1pNDRf2pWhvpy8pqMnuI3++4OF3+7OFIWXGjh+o7Nr2jNvbiYcQdQS1h903/jVFgOpA0yJ78z+x759bFA0rq+6aY5qPB4FzS3oYoLupDUhD9nDz6F6H7hpnlMf18KNKDu4IKjTWwrAnY6MFQw1W6ymOALHlFyCZmQhldg1MQHaMVVQTVgDC60TfaBqG++Y8PEoFhN/PBTZT175KNP/BlHDYGOOBmnBdzqJKplZ/ljiVG0ZBzfqeBRrrUkn6rA54462SgiliKoYVnbeptMdXNfAuaupIEi0bApF10TlgHfmEJAPUVidRVFyDupSem5po5vErPqWKhKbUIp0LozpYsIKK57dM/HKr+nguF+7924IIWMICkQ8JUigs9D+W+c4LnNoRtPPKNRUiCYmP+Jfo2lfKCKw8qpraEeWU3uiNRO6zcyKQoXPR5htmzzLznke7b4YbXW3I1lIRzmgG02Udb58U+7TpwyN7XymCgH+wuPDthZVQvRZuEP+SnLtMicz9m5zASWOBiAcLmkuFlTKuHspSIhCBD0yUPKcxu81A+4YD78rA2vtwsUEday9WNyrShyrl60rWmA+SmbYZkQOwFJWArxRYYc5jGhA5ikxYw1rx3ei4NmeX/lKiwpZ9Ln1tV2Ae7sArvxuVLbJjqJRjW1vFXAyHpvLG+8MJ6T2Ubx5M2KDa2SN6vuIGxJ9WQM9Mk3Q7aCNiZONXllhqq24DmoLbQfW2rYWsOgHWjtOmIQMyMKdiHZDjoyIq5+U700nZ6odJAoYXPQBvFNiQ78d5jaXliBqLTJEqUCwi+LiH2mx92EmNKDsJL74Z613+3lf20pxkV1+erOrjj8pW00vsPaahKUM+05ssd5uwM7K482KWEf3TCwlg/o3e5ngto7qSMz7YteIgCsF1UOcsLk7F7MxWbvrPMY473ew0G+noVL8EPbkmEMftMSeL6HFub/zy+2JQ==","base64")).toString()),EO}var IO;function eAe(){return typeof IO>"u"&&(IO=J("zlib").brotliDecompressSync(Buffer.from("G8MSIIzURnVBnObTcvb3XE6v2S9Qgc2K801Oa5otNKEtK8BINZNcaQHy+9/vf/WXBimwutXC33P2DPc64pps5rz7NGGWaOKNSPL4Y2KRE8twut2lFOIN+OXPtRmPMRhMTILib2bEQx43az2I5d3YS8Roa5UZpF/ujHb3Djd3GDvYUfvFYSUQ39vb2cmifp/rgB4J/65JK3wRBTvMBoNBmn3mbXC63/gbBkW/2IRPri0O8bcsRBsmarF328pAln04nyJFkwUAvNu934supAqLtyerZZpJ8I8suJHhf/ocMV+scKwa8NOiDKIPXw6Ex/EEZD6TEGaW8N5zvNHYF10l6Lfooj7D5W2k3dgvQSbp2Wv8TGOayS978gxlOLVjTGXs66ozewbrjwElLtyrYNnWTfzzdEutgROUFPVMhnMoy8EjJLLlWwIEoySxliim9kYW30JUHiPVyjt0iAw/ZpPmCbUCltYPnq6ZNblIKhTNhqS/oqC9iya5sGKZTOVsTEg34n92uZTf2iPpcZih8rPW8CzA+adIGmyCPcKdLMsBLShd+zuEbTrqpwuh+DLmracZcjPC5Sdf5odDAhKpFuOsQS67RT+1VgWWygSv3YwxDnylc04/PYuaMeIzhBkLrvs7e/OUzRTF56MmfY6rI63QtEjEQzq637zQqJ39nNhu3NmoRRhW/086bHGBUtx0PE0j3aEGvkdh9WJC8y8j8mqqke9/dQ5la+Q3ba4RlhvTbnfQhPDDab3tUifkjKuOsp13mXEmO00Mu88F/M67R7LXfoFDFLNtgCSWjWX+3Jn1371pJTK9xPBiMJafvDjtFyAzu8rxeQ0TKMQXNPs5xxiBOd+BRJP8KP88XPtJIbZKh/cdW8KvBUkpqKpGoiIaA32c3/JnQr4efXt85mXvidOvn/eU3Pase1typLYBalJ14mCso9h79nuMOuCa/kZAOkJHmTjP5RM2WNoPasZUAnT1TAE/NH25hUxcQv6hQWR/m1PKk4ooXMcM4SR1iYU3fUohvqk4RY2hbmTVVIXv6TvqO+0doOjgeVFAcom+RlwJQmOVH7pr1Q9LoJT6n1DeQEB+NHygsATbIwTcOKZlJsY8G4+suX1uQLjUWwLjjs0mvSvZcLTpIGAekeR7GCgl8eo3ndAqEe2XCav4huliHjdbIPBsGJuPX7lrO9HX1UbXRH5opOe1x6JsOSgHZR+EaxuXVhpLLxm6jk1LJtZfHSc6BKPun3CpYYVMJGwEUyk8MTGG0XL5MfEwaXpnc9TKnBmlGn6nHiGREc3ysn47XIBDzA+YvFdjZzVIEDcKGpS6PbUJehFRjEne8D0lVU1XuRtlgszq6pTNlQ/3MzNOEgCWPyTct22V2mEi2krizn5VDo9B19/X2DB3hCGRMM7ONbtnAcIx/OWB1u5uPbW1gsH8irXxT/IzG0PoXWYjhbMsH3KTuoOl5o17PulcgvsfTSnKFM354GWI8luqZnrswWjiXy3G+Vbyo1KMopFmmvBwNELgaS8z8dNZchx/Cl/xjddxhMcyqtzFyONb2Zdu90NkI8pAeufe7YlXrp53v8Dj/l8vWeVspRKBGXScBBPI/HinSTGmLDOGGOCIyH0JFdOZx0gWsacNlQLJMIrBhqRxXxHF/5pseWwejlAAvZ3klZSDSYY8mkToaWejXhgNomeGtx1DTLEUFMRkgF5yFB22WYdJnaWN14r1YJj81hGi45+jrADS5nYRhCiSlCJJ1nL8pYX+HDSMhdTEWyRcgHVp/IsUIZYMfT+YYncUQPgcxNGCHfZ88vDdrcUuaGIl6zhAsiaq7R5dfqrqXH/JcBhfjT8D0azayIyEz75Nxp6YkcyDxlJq3EXnJUpqDohJJOysL1t1uNiHESlvsxPb5cpbW0+ICZqJmUZus1BMW0F5IVBODLIo2zHHjA0=","base64")).toString()),IO}var yO;function tAe(){return typeof yO>"u"&&(yO=J("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),yO}var rAe=new Map([[P.makeIdent(null,"fsevents").identHash,$ae],[P.makeIdent(null,"resolve").identHash,eAe],[P.makeIdent(null,"typescript").identHash,tAe]]),w4e={hooks:{registerPackageExtensions:async(r,e)=>{for(let[t,i]of mO)e(P.parseDescriptor(t,!0),i)},getBuiltinPatch:async(r,e)=>{var s;let t="compat/";if(!e.startsWith(t))return;let i=P.parseIdent(e.slice(t.length)),n=(s=rAe.get(i.identHash))==null?void 0:s();return typeof n<"u"?n:null},reduceDependency:async(r,e,t,i)=>typeof rAe.get(r.identHash)>"u"?r:P.makeDescriptor(r,P.makeRange({protocol:"patch:",source:P.stringifyDescriptor(r),selector:`~builtin<compat/${P.stringifyIdent(r)}>`,params:null}))}},B4e=w4e;var BO={};ct(BO,{default:()=>Q4e});var tp=class extends Pe{constructor(){super(...arguments);this.pkg=z.String("-p,--package",{description:"The package to run the provided command from"});this.quiet=z.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=z.String();this.args=z.Proxy()}async execute(){let t=[];this.pkg&&t.push("--package",this.pkg),this.quiet&&t.push("--quiet");let i=P.parseDescriptor(this.command),n;i.scope?n=P.makeIdent(i.scope,`create-${i.name}`):i.name.startsWith("@")?n=P.makeIdent(i.name.substring(1),"create"):n=P.makeIdent(null,`create-${i.name}`);let s=P.stringifyIdent(n);return i.range!=="unknown"&&(s+=`@${i.range}`),this.cli.run(["dlx",...t,s,...this.args])}};tp.paths=[["create"]];var Hu=class extends Pe{constructor(){super(...arguments);this.packages=z.Array("-p,--package",{description:"The package(s) to install before running the command"});this.quiet=z.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=z.String();this.args=z.Proxy()}async execute(){return Ee.telemetry=null,await M.mktempPromise(async t=>{var m;let i=v.join(t,`dlx-${process.pid}`);await M.mkdirPromise(i),await M.writeFilePromise(v.join(i,"package.json"),`{} +`),await M.writeFilePromise(v.join(i,"yarn.lock"),"");let n=v.join(i,".yarnrc.yml"),s=await Ee.findProjectCwd(this.context.cwd,St.lockfile),o=!(await Ee.find(this.context.cwd,null,{strict:!1})).get("enableGlobalCache"),a=s!==null?v.join(s,".yarnrc.yml"):null;a!==null&&M.existsSync(a)?(await M.copyFilePromise(a,n),await Ee.updateConfiguration(i,y=>{let B={...y,enableGlobalCache:o,enableTelemetry:!1};return Array.isArray(y.plugins)&&(B.plugins=y.plugins.map(S=>{let x=typeof S=="string"?S:S.path,F=K.isAbsolute(x)?x:K.resolve(K.fromPortablePath(s),x);return typeof S=="string"?F:{path:F,spec:S.spec}})),B})):await M.writeFilePromise(n,`enableGlobalCache: ${o} +enableTelemetry: false +`);let l=(m=this.packages)!=null?m:[this.command],c=P.parseDescriptor(this.command).name,u=await this.cli.run(["add","--",...l],{cwd:i,quiet:this.quiet});if(u!==0)return u;this.quiet||this.context.stdout.write(` +`);let g=await Ee.find(i,this.context.plugins),{project:h,workspace:p}=await Ge.find(g,i);if(p===null)throw new lt(h.cwd,i);await h.restoreInstallState();let d=await Yt.getWorkspaceAccessibleBinaries(p);return d.has(c)===!1&&d.size===1&&typeof this.packages>"u"&&(c=Array.from(d)[0][0]),await Yt.executeWorkspaceAccessibleBinary(p,c,this.args,{packageAccessibleBinaries:d,cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}};Hu.paths=[["dlx"]],Hu.usage=Qe.Usage({description:"run a package in a temporary environment",details:"\n This command will install a package within a temporary environment, and run its binary script if it contains any. The binary will run within the current cwd.\n\n By default Yarn will download the package named `command`, but this can be changed through the use of the `-p,--package` flag which will instruct Yarn to still run the same command but from a different package.\n\n Using `yarn dlx` as a replacement of `yarn add` isn't recommended, as it makes your project non-deterministic (Yarn doesn't keep track of the packages installed through `dlx` - neither their name, nor their version).\n ",examples:[["Use create-react-app to create a new React app","yarn dlx create-react-app ./my-app"],["Install multiple packages for a single command",`yarn dlx -p typescript -p ts-node ts-node --transpile-only -e "console.log('hello!')"`]]});var b4e={commands:[tp,Hu]},Q4e=b4e;var vO={};ct(vO,{default:()=>P4e,fileUtils:()=>Zm});var rp=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,Xm=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/,Hr="file:";var Zm={};ct(Zm,{makeArchiveFromLocator:()=>Kb,makeBufferFromLocator:()=>SO,makeLocator:()=>QO,makeSpec:()=>iAe,parseSpec:()=>bO});function bO(r){let{params:e,selector:t}=P.parseRange(r),i=K.toPortablePath(t);return{parentLocator:e&&typeof e.locator=="string"?P.parseLocator(e.locator):null,path:i}}function iAe({parentLocator:r,path:e,folderHash:t,protocol:i}){let n=r!==null?{locator:P.stringifyLocator(r)}:{},s=typeof t<"u"?{hash:t}:{};return P.makeRange({protocol:i,source:e,selector:e,params:{...s,...n}})}function QO(r,{parentLocator:e,path:t,folderHash:i,protocol:n}){return P.makeLocator(r,iAe({parentLocator:e,path:t,folderHash:i,protocol:n}))}async function Kb(r,{protocol:e,fetchOptions:t,inMemory:i=!1}){let{parentLocator:n,path:s}=P.parseFileStyleRange(r.reference,{protocol:e}),o=v.isAbsolute(s)?{packageFs:new jt(Te.root),prefixPath:Te.dot,localPath:Te.root}:await t.fetcher.fetch(n,t),a=o.localPath?{packageFs:new jt(Te.root),prefixPath:v.relative(Te.root,o.localPath)}:o;o!==a&&o.releaseFs&&o.releaseFs();let l=a.packageFs,c=v.join(a.prefixPath,s);return await me.releaseAfterUseAsync(async()=>await Ci.makeArchiveFromDirectory(c,{baseFs:l,prefixPath:P.getIdentVendorPath(r),compressionLevel:t.project.configuration.get("compressionLevel"),inMemory:i}),a.releaseFs)}async function SO(r,{protocol:e,fetchOptions:t}){return(await Kb(r,{protocol:e,fetchOptions:t,inMemory:!0})).getBufferAndClose()}var Ub=class{supports(e,t){return!!e.reference.startsWith(Hr)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:Hr});if(v.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:v.resolve(s,n)}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async fetchFromDisk(e,t){return Kb(e,{protocol:Hr,fetchOptions:t})}};var S4e=2,Hb=class{supportsDescriptor(e,t){return e.range.match(rp)?!0:!!e.range.startsWith(Hr)}supportsLocator(e,t){return!!e.reference.startsWith(Hr)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return rp.test(e.range)&&(e=P.makeDescriptor(e,`${Hr}${e.range}`)),P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:n,parentLocator:s}=bO(e.range);if(s===null)throw new Error("Assertion failed: The descriptor should have been bound");let o=await SO(P.makeLocator(e,P.makeRange({protocol:Hr,source:n,selector:n,params:{locator:P.stringifyLocator(s)}})),{protocol:Hr,fetchOptions:i.fetchOptions}),a=Ai.makeHash(`${S4e}`,o).slice(0,6);return[QO(e,{parentLocator:s,path:n,folderHash:a,protocol:Hr})]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await me.releaseAfterUseAsync(async()=>await ot.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return{...e,version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin}}};var jb=class{supports(e,t){return Xm.test(e.reference)?!!e.reference.startsWith(Hr):!1}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromDisk(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:Hr}),s=v.isAbsolute(n)?{packageFs:new jt(Te.root),prefixPath:Te.dot,localPath:Te.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new jt(Te.root),prefixPath:v.relative(Te.root,s.localPath)}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=v.join(o.prefixPath,n),c=await a.readFilePromise(l);return await me.releaseAfterUseAsync(async()=>await Ci.convertToZip(c,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1}),o.releaseFs)}};var Gb=class{supportsDescriptor(e,t){return Xm.test(e.range)?!!(e.range.startsWith(Hr)||rp.test(e.range)):!1}supportsLocator(e,t){return Xm.test(e.reference)?!!e.reference.startsWith(Hr):!1}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return rp.test(e.range)&&(e=P.makeDescriptor(e,`${Hr}${e.range}`)),P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.startsWith(Hr)?e.range.slice(Hr.length):e.range;return[P.makeLocator(e,`${Hr}${K.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await me.releaseAfterUseAsync(async()=>await ot.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return{...e,version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin}}};var v4e={fetchers:[jb,Ub],resolvers:[Gb,Hb]},P4e=v4e;var PO={};ct(PO,{default:()=>R4e});var nAe=ve(J("querystring")),sAe=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];function oAe(r){return r?sAe.some(e=>!!r.match(e)):!1}function aAe(r){let e;for(let a of sAe)if(e=r.match(a),e)break;if(!e)throw new Error(x4e(r));let[,t,i,n,s="master"]=e,{commit:o}=nAe.default.parse(s);return s=o||s.replace(/[^:]*:/,""),{auth:t,username:i,reponame:n,treeish:s}}function x4e(r){return`Input cannot be parsed as a valid GitHub URL ('${r}').`}var Yb=class{supports(e,t){return!!oAe(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from GitHub`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i=await Vt.get(this.getLocatorUrl(e,t),{configuration:t.project.configuration});return await M.mktempPromise(async n=>{let s=new jt(n);await Ci.extractArchiveTo(i,s,{stripComponents:1});let o=lA.splitRepoUrl(e.reference),a=v.join(n,"package.tgz");await Yt.prepareExternalProject(n,a,{configuration:t.project.configuration,report:t.report,workspace:o.extra.workspace,locator:e});let l=await M.readFilePromise(a);return await Ci.convertToZip(l,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,t){let{auth:i,username:n,reponame:s,treeish:o}=aAe(e.reference);return`https://${i?`${i}@`:""}github.com/${n}/${s}/archive/${o}.tar.gz`}};var D4e={hooks:{async fetchHostedRepository(r,e,t){if(r!==null)return r;let i=new Yb;if(!i.supports(e,t))return null;try{return await i.fetch(e,t)}catch{return null}}}},R4e=D4e;var xO={};ct(xO,{default:()=>N4e});var _m=/^[^?]*\.(?:tar\.gz|tgz)(?:\?.*)?$/,$m=/^https?:/;var qb=class{supports(e,t){return _m.test(e.reference)?!!$m.test(e.reference):!1}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i=await Vt.get(e.reference,{configuration:t.project.configuration});return await Ci.convertToZip(i,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}};var Jb=class{supportsDescriptor(e,t){return _m.test(e.range)?!!$m.test(e.range):!1}supportsLocator(e,t){return _m.test(e.reference)?!!$m.test(e.reference):!1}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){return[P.convertDescriptorToLocator(e)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await me.releaseAfterUseAsync(async()=>await ot.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return{...e,version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:"HARD",conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin}}};var F4e={fetchers:[qb],resolvers:[Jb]},N4e=F4e;var FO={};ct(FO,{default:()=>T8e});var NAe=ve(FAe()),RO=J("util"),ju=class extends Pe{constructor(){super(...arguments);this.private=z.Boolean("-p,--private",!1,{description:"Initialize a private package"});this.workspace=z.Boolean("-w,--workspace",!1,{description:"Initialize a workspace root with a `packages/` directory"});this.install=z.String("-i,--install",!1,{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"});this.usev2=z.Boolean("-2",!1,{hidden:!0});this.yes=z.Boolean("-y,--yes",{hidden:!0});this.assumeFreshProject=z.Boolean("--assume-fresh-project",!1,{hidden:!0})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=typeof this.install=="string"?this.install:this.usev2||this.install===!0?"latest":null;return i!==null?await this.executeProxy(t,i):await this.executeRegular(t)}async executeProxy(t,i){if(t.projectCwd!==null&&t.projectCwd!==this.context.cwd)throw new we("Cannot use the --install flag from within a project subdirectory");M.existsSync(this.context.cwd)||await M.mkdirPromise(this.context.cwd,{recursive:!0});let n=v.join(this.context.cwd,t.get("lockfileFilename"));M.existsSync(n)||await M.writeFilePromise(n,"");let s=await this.cli.run(["set","version",i],{quiet:!0});if(s!==0)return s;let o=[];return this.private&&o.push("-p"),this.workspace&&o.push("-w"),this.yes&&o.push("-y"),await M.mktempPromise(async a=>{let{code:l}=await pr.pipevp("yarn",["init",...o],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await Yt.makeScriptEnv({binFolder:a})});return l})}async executeRegular(t){var c;let i=null;try{i=(await Ge.find(t,this.context.cwd)).project}catch{i=null}M.existsSync(this.context.cwd)||await M.mkdirPromise(this.context.cwd,{recursive:!0});let n=await ot.tryFind(this.context.cwd)||new ot,s=Object.fromEntries(t.get("initFields").entries());n.load(s),n.name=(c=n.name)!=null?c:P.makeIdent(t.get("initScope"),v.basename(this.context.cwd)),n.packageManager=Fr&&me.isTaggedYarnVersion(Fr)?`yarn@${Fr}`:null,typeof n.raw.private>"u"&&(this.private||this.workspace&&n.workspaceDefinitions.length===0)&&(n.private=!0),this.workspace&&n.workspaceDefinitions.length===0&&(await M.mkdirPromise(v.join(this.context.cwd,"packages"),{recursive:!0}),n.workspaceDefinitions=[{pattern:"packages/*"}]);let o={};n.exportTo(o),RO.inspect.styles.name="cyan",this.context.stdout.write(`${(0,RO.inspect)(o,{depth:1/0,colors:!0,compact:!1})} +`);let a=v.join(this.context.cwd,ot.fileName);await M.changeFilePromise(a,`${JSON.stringify(o,null,2)} +`,{automaticNewlines:!0});let l=v.join(this.context.cwd,"README.md");if(M.existsSync(l)||await M.writeFilePromise(l,`# ${P.stringifyIdent(n.name)} +`),!i||i.cwd===this.context.cwd){let u=v.join(this.context.cwd,St.lockfile);M.existsSync(u)||await M.writeFilePromise(u,"");let h=[".yarn/*","!.yarn/patches","!.yarn/plugins","!.yarn/releases","!.yarn/sdks","!.yarn/versions","","# Swap the comments on the following lines if you don't wish to use zero-installs","# Documentation here: https://yarnpkg.com/features/zero-installs","!.yarn/cache","#.pnp.*"].map(F=>`${F} +`).join(""),p=v.join(this.context.cwd,".gitignore");M.existsSync(p)||await M.writeFilePromise(p,h);let m=["/.yarn/** linguist-vendored","/.yarn/releases/* binary","/.yarn/plugins/**/* binary","/.pnp.* binary linguist-generated"].map(F=>`${F} +`).join(""),y=v.join(this.context.cwd,".gitattributes");M.existsSync(y)||await M.writeFilePromise(y,m);let B={["*"]:{endOfLine:"lf",insertFinalNewline:!0},["*.{js,json,yml}"]:{charset:"utf-8",indentStyle:"space",indentSize:2}};(0,NAe.default)(B,t.get("initEditorConfig"));let S=`root = true +`;for(let[F,H]of Object.entries(B)){S+=` +[${F}] +`;for(let[q,_]of Object.entries(H)){let X=q.replace(/[A-Z]/g,W=>`_${W.toLowerCase()}`);S+=`${X} = ${_} +`}}let x=v.join(this.context.cwd,".editorconfig");M.existsSync(x)||await M.writeFilePromise(x,S),M.existsSync(v.join(this.context.cwd,".git"))||await pr.execvp("git",["init"],{cwd:this.context.cwd})}}};ju.paths=[["init"]],ju.usage=Qe.Usage({description:"create a new package",details:"\n This command will setup a new package in your local directory.\n\n If the `-p,--private` or `-w,--workspace` options are set, the package will be private by default.\n\n If the `-w,--workspace` option is set, the package will be configured to accept a set of workspaces in the `packages/` directory.\n\n If the `-i,--install` option is given a value, Yarn will first download it using `yarn set version` and only then forward the init call to the newly downloaded bundle. Without arguments, the downloaded bundle will be `latest`.\n\n The initial settings of the manifest can be changed by using the `initScope` and `initFields` configuration values. Additionally, Yarn will generate an EditorConfig file whose rules can be altered via `initEditorConfig`, and will initialize a Git repository in the current directory.\n ",examples:[["Create a new package in the local directory","yarn init"],["Create a new private package in the local directory","yarn init -p"],["Create a new package and store the Yarn release inside","yarn init -i=latest"],["Create a new private package and defines it as a workspace root","yarn init -w"]]});var N8e={configuration:{initScope:{description:"Scope used when creating packages via the init command",type:"STRING",default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:"MAP",valueDefinition:{description:"",type:"ANY"}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:"MAP",valueDefinition:{description:"",type:"ANY"}}},commands:[ju]},T8e=N8e;var NO={};ct(NO,{default:()=>O8e});var cA="portal:",uA="link:";var Wb=class{supports(e,t){return!!e.reference.startsWith(cA)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:cA});if(v.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:v.resolve(s,n)}async fetch(e,t){var c;let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:cA}),s=v.isAbsolute(n)?{packageFs:new jt(Te.root),prefixPath:Te.dot,localPath:Te.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new jt(Te.root),prefixPath:v.relative(Te.root,s.localPath),localPath:Te.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=v.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new jt(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Te.dot,localPath:l}:{packageFs:new So(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Te.dot}}};var zb=class{supportsDescriptor(e,t){return!!e.range.startsWith(cA)}supportsLocator(e,t){return!!e.reference.startsWith(cA)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(cA.length);return[P.makeLocator(e,`${cA}${K.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await me.releaseAfterUseAsync(async()=>await ot.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return{...e,version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:"SOFT",conditions:n.getConditions(),dependencies:new Map([...n.dependencies]),peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin}}};var Vb=class{supports(e,t){return!!e.reference.startsWith(uA)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:uA});if(v.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:v.resolve(s,n)}async fetch(e,t){var c;let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:uA}),s=v.isAbsolute(n)?{packageFs:new jt(Te.root),prefixPath:Te.dot,localPath:Te.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new jt(Te.root),prefixPath:v.relative(Te.root,s.localPath),localPath:Te.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=v.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new jt(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Te.dot,discardFromLookup:!0,localPath:l}:{packageFs:new So(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Te.dot,discardFromLookup:!0}}};var Xb=class{supportsDescriptor(e,t){return!!e.range.startsWith(uA)}supportsLocator(e,t){return!!e.reference.startsWith(uA)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(uA.length);return[P.makeLocator(e,`${uA}${K.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){return{...e,version:"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:"SOFT",conditions:null,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map}}};var L8e={fetchers:[Vb,Wb],resolvers:[Xb,zb]},O8e=L8e;var dM={};ct(dM,{default:()=>e5e});var LO=(r,e)=>`${r}@${e}`,TAe=(r,e)=>{let t=e.indexOf("#"),i=t>=0?e.substring(t+1):e;return LO(r,i)};var MAe=(r,e={})=>{let t=e.debugLevel||Number(process.env.NM_DEBUG_LEVEL||-1),i=e.check||t>=9,n=e.hoistingLimits||new Map,s={check:i,debugLevel:t,hoistingLimits:n,fastLookupPossible:!0},o;s.debugLevel>=0&&(o=Date.now());let a=Y8e(r,s),l=!1,c=0;do l=OO(a,[a],new Set([a.locator]),new Map,s).anotherRoundNeeded,s.fastLookupPossible=!1,c++;while(l);if(s.debugLevel>=0&&console.log(`hoist time: ${Date.now()-o}ms, rounds: ${c}`),s.debugLevel>=1){let u=eE(a);if(OO(a,[a],new Set([a.locator]),new Map,s).isGraphChanged)throw new Error(`The hoisting result is not terminal, prev tree: +${u}, next tree: +${eE(a)}`);let h=KAe(a);if(h)throw new Error(`${h}, after hoisting finished: +${eE(a)}`)}return s.debugLevel>=2&&console.log(eE(a)),q8e(a)},M8e=r=>{let e=r[r.length-1],t=new Map,i=new Set,n=s=>{if(!i.has(s)){i.add(s);for(let o of s.hoistedDependencies.values())t.set(o.name,o);for(let o of s.dependencies.values())s.peerNames.has(o.name)||n(o)}};return n(e),t},K8e=r=>{let e=r[r.length-1],t=new Map,i=new Set,n=new Set,s=(o,a)=>{if(i.has(o))return;i.add(o);for(let c of o.hoistedDependencies.values())if(!a.has(c.name)){let u;for(let g of r)u=g.dependencies.get(c.name),u&&t.set(u.name,u)}let l=new Set;for(let c of o.dependencies.values())l.add(c.name);for(let c of o.dependencies.values())o.peerNames.has(c.name)||s(c,l)};return s(e,n),t},LAe=(r,e)=>{if(e.decoupled)return e;let{name:t,references:i,ident:n,locator:s,dependencies:o,originalDependencies:a,hoistedDependencies:l,peerNames:c,reasons:u,isHoistBorder:g,hoistPriority:h,dependencyKind:p,hoistedFrom:d,hoistedTo:m}=e,y={name:t,references:new Set(i),ident:n,locator:s,dependencies:new Map(o),originalDependencies:new Map(a),hoistedDependencies:new Map(l),peerNames:new Set(c),reasons:new Map(u),decoupled:!0,isHoistBorder:g,hoistPriority:h,dependencyKind:p,hoistedFrom:new Map(d),hoistedTo:new Map(m)},B=y.dependencies.get(t);return B&&B.ident==y.ident&&y.dependencies.set(t,y),r.dependencies.set(y.name,y),y},U8e=(r,e)=>{let t=new Map([[r.name,[r.ident]]]);for(let n of r.dependencies.values())r.peerNames.has(n.name)||t.set(n.name,[n.ident]);let i=Array.from(e.keys());i.sort((n,s)=>{let o=e.get(n),a=e.get(s);return a.hoistPriority!==o.hoistPriority?a.hoistPriority-o.hoistPriority:a.peerDependents.size!==o.peerDependents.size?a.peerDependents.size-o.peerDependents.size:a.dependents.size-o.dependents.size});for(let n of i){let s=n.substring(0,n.indexOf("@",1)),o=n.substring(s.length+1);if(!r.peerNames.has(s)){let a=t.get(s);a||(a=[],t.set(s,a)),a.indexOf(o)<0&&a.push(o)}}return t},TO=r=>{let e=new Set,t=(i,n=new Set)=>{if(!n.has(i)){n.add(i);for(let s of i.peerNames)if(!r.peerNames.has(s)){let o=r.dependencies.get(s);o&&!e.has(o)&&t(o,n)}e.add(i)}};for(let i of r.dependencies.values())r.peerNames.has(i.name)||t(i);return e},OO=(r,e,t,i,n,s=new Set)=>{let o=e[e.length-1];if(s.has(o))return{anotherRoundNeeded:!1,isGraphChanged:!1};s.add(o);let a=J8e(o),l=U8e(o,a),c=r==o?new Map:n.fastLookupPossible?M8e(e):K8e(e),u,g=!1,h=!1,p=new Map(Array.from(l.entries()).map(([m,y])=>[m,y[0]])),d=new Map;do{let m=G8e(r,e,t,c,p,l,i,d,n);m.isGraphChanged&&(h=!0),m.anotherRoundNeeded&&(g=!0),u=!1;for(let[y,B]of l)B.length>1&&!o.dependencies.has(y)&&(p.delete(y),B.shift(),p.set(y,B[0]),u=!0)}while(u);for(let m of o.dependencies.values())if(!o.peerNames.has(m.name)&&!t.has(m.locator)){t.add(m.locator);let y=OO(r,[...e,m],t,d,n);y.isGraphChanged&&(h=!0),y.anotherRoundNeeded&&(g=!0),t.delete(m.locator)}return{anotherRoundNeeded:g,isGraphChanged:h}},H8e=r=>{for(let[e,t]of r.dependencies)if(!r.peerNames.has(e)&&t.ident!==r.ident)return!0;return!1},j8e=(r,e,t,i,n,s,o,a,{outputReason:l,fastLookupPossible:c})=>{let u,g=null,h=new Set;l&&(u=`${Array.from(e).map(y=>Di(y)).join("\u2192")}`);let p=t[t.length-1],m=!(i.ident===p.ident);if(l&&!m&&(g="- self-reference"),m&&(m=i.dependencyKind!==1,l&&!m&&(g="- workspace")),m&&i.dependencyKind===2&&(m=!H8e(i),l&&!m&&(g="- external soft link with unhoisted dependencies")),m&&(m=p.dependencyKind!==1||p.hoistedFrom.has(i.name)||e.size===1,l&&!m&&(g=p.reasons.get(i.name))),m&&(m=!r.peerNames.has(i.name),l&&!m&&(g=`- cannot shadow peer: ${Di(r.originalDependencies.get(i.name).locator)} at ${u}`)),m){let y=!1,B=n.get(i.name);if(y=!B||B.ident===i.ident,l&&!y&&(g=`- filled by: ${Di(B.locator)} at ${u}`),y)for(let S=t.length-1;S>=1;S--){let F=t[S].dependencies.get(i.name);if(F&&F.ident!==i.ident){y=!1;let H=a.get(p);H||(H=new Set,a.set(p,H)),H.add(i.name),l&&(g=`- filled by ${Di(F.locator)} at ${t.slice(0,S).map(q=>Di(q.locator)).join("\u2192")}`);break}}m=y}if(m&&(m=s.get(i.name)===i.ident,l&&!m&&(g=`- filled by: ${Di(o.get(i.name)[0])} at ${u}`)),m){let y=!0,B=new Set(i.peerNames);for(let S=t.length-1;S>=1;S--){let x=t[S];for(let F of B){if(x.peerNames.has(F)&&x.originalDependencies.has(F))continue;let H=x.dependencies.get(F);H&&r.dependencies.get(F)!==H&&(S===t.length-1?h.add(H):(h=null,y=!1,l&&(g=`- peer dependency ${Di(H.locator)} from parent ${Di(x.locator)} was not hoisted to ${u}`))),B.delete(F)}if(!y)break}m=y}if(m&&!c)for(let y of i.hoistedDependencies.values()){let B=n.get(y.name)||r.dependencies.get(y.name);if(!B||y.ident!==B.ident){m=!1,l&&(g=`- previously hoisted dependency mismatch, needed: ${Di(y.locator)}, available: ${Di(B==null?void 0:B.locator)}`);break}}return h!==null&&h.size>0?{isHoistable:2,dependsOn:h,reason:g}:{isHoistable:m?0:1,reason:g}},Zb=r=>`${r.name}@${r.locator}`,G8e=(r,e,t,i,n,s,o,a,l)=>{let c=e[e.length-1],u=new Set,g=!1,h=!1,p=(B,S,x,F,H)=>{if(u.has(F))return;let q=[...S,Zb(F)],_=[...x,Zb(F)],X=new Map,W=new Map;for(let te of TO(F)){let O=j8e(c,t,[c,...B,F],te,i,n,s,a,{outputReason:l.debugLevel>=2,fastLookupPossible:l.fastLookupPossible});if(W.set(te,O),O.isHoistable===2)for(let N of O.dependsOn){let ce=X.get(N.name)||new Set;ce.add(te.name),X.set(N.name,ce)}}let Z=new Set,A=(te,O,N)=>{if(!Z.has(te)){Z.add(te),W.set(te,{isHoistable:1,reason:N});for(let ce of X.get(te.name)||[])A(F.dependencies.get(ce),O,l.debugLevel>=2?`- peer dependency ${Di(te.locator)} from parent ${Di(F.locator)} was not hoisted`:"")}};for(let[te,O]of W)O.isHoistable===1&&A(te,O,O.reason);let ne=!1;for(let te of W.keys())if(!Z.has(te)){h=!0;let O=o.get(F);O&&O.has(te.name)&&(g=!0),ne=!0,F.dependencies.delete(te.name),F.hoistedDependencies.set(te.name,te),F.reasons.delete(te.name);let N=c.dependencies.get(te.name);if(l.debugLevel>=2){let ce=Array.from(S).concat([F.locator]).map(xe=>Di(xe)).join("\u2192"),he=c.hoistedFrom.get(te.name);he||(he=[],c.hoistedFrom.set(te.name,he)),he.push(ce),F.hoistedTo.set(te.name,Array.from(e).map(xe=>Di(xe.locator)).join("\u2192"))}if(!N)c.ident!==te.ident&&(c.dependencies.set(te.name,te),H.add(te));else for(let ce of te.references)N.references.add(ce)}if(F.dependencyKind===2&&ne&&(g=!0),l.check){let te=KAe(r);if(te)throw new Error(`${te}, after hoisting dependencies of ${[c,...B,F].map(O=>Di(O.locator)).join("\u2192")}: +${eE(r)}`)}let ue=TO(F);for(let te of ue)if(Z.has(te)){let O=W.get(te);if((n.get(te.name)===te.ident||!F.reasons.has(te.name))&&O.isHoistable!==0&&F.reasons.set(te.name,O.reason),!te.isHoistBorder&&_.indexOf(Zb(te))<0){u.add(F);let ce=LAe(F,te);p([...B,F],q,_,ce,m),u.delete(F)}}},d,m=new Set(TO(c)),y=Array.from(e).map(B=>Zb(B));do{d=m,m=new Set;for(let B of d){if(B.locator===c.locator||B.isHoistBorder)continue;let S=LAe(c,B);p([],Array.from(t),y,S,m)}}while(m.size>0);return{anotherRoundNeeded:g,isGraphChanged:h}},KAe=r=>{let e=[],t=new Set,i=new Set,n=(s,o,a)=>{if(t.has(s)||(t.add(s),i.has(s)))return;let l=new Map(o);for(let c of s.dependencies.values())s.peerNames.has(c.name)||l.set(c.name,c);for(let c of s.originalDependencies.values()){let u=l.get(c.name),g=()=>`${Array.from(i).concat([s]).map(h=>Di(h.locator)).join("\u2192")}`;if(s.peerNames.has(c.name)){let h=o.get(c.name);(h!==u||!h||h.ident!==c.ident)&&e.push(`${g()} - broken peer promise: expected ${c.ident} but found ${h&&h.ident}`)}else{let h=a.hoistedFrom.get(s.name),p=s.hoistedTo.get(c.name),d=`${h?` hoisted from ${h.join(", ")}`:""}`,m=`${p?` hoisted to ${p}`:""}`,y=`${g()}${d}`;u?u.ident!==c.ident&&e.push(`${y} - broken require promise for ${c.name}${m}: expected ${c.ident}, but found: ${u.ident}`):e.push(`${y} - broken require promise: no required dependency ${c.name}${m} found`)}}i.add(s);for(let c of s.dependencies.values())s.peerNames.has(c.name)||n(c,l,s);i.delete(s)};return n(r,r.dependencies,r),e.join(` +`)},Y8e=(r,e)=>{let{identName:t,name:i,reference:n,peerNames:s}=r,o={name:i,references:new Set([n]),locator:LO(t,n),ident:TAe(t,n),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(s),reasons:new Map,decoupled:!0,isHoistBorder:!0,hoistPriority:0,dependencyKind:1,hoistedFrom:new Map,hoistedTo:new Map},a=new Map([[r,o]]),l=(c,u)=>{let g=a.get(c),h=!!g;if(!g){let{name:p,identName:d,reference:m,peerNames:y,hoistPriority:B,dependencyKind:S}=c,x=e.hoistingLimits.get(u.locator);g={name:p,references:new Set([m]),locator:LO(d,m),ident:TAe(d,m),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(y),reasons:new Map,decoupled:!0,isHoistBorder:x?x.has(p):!1,hoistPriority:B||0,dependencyKind:S||0,hoistedFrom:new Map,hoistedTo:new Map},a.set(c,g)}if(u.dependencies.set(c.name,g),u.originalDependencies.set(c.name,g),h){let p=new Set,d=m=>{if(!p.has(m)){p.add(m),m.decoupled=!1;for(let y of m.dependencies.values())m.peerNames.has(y.name)||d(y)}};d(g)}else for(let p of c.dependencies)l(p,g)};for(let c of r.dependencies)l(c,o);return o},MO=r=>r.substring(0,r.indexOf("@",1)),q8e=r=>{let e={name:r.name,identName:MO(r.locator),references:new Set(r.references),dependencies:new Set},t=new Set([r]),i=(n,s,o)=>{let a=t.has(n),l;if(s===n)l=o;else{let{name:c,references:u,locator:g}=n;l={name:c,identName:MO(g),references:u,dependencies:new Set}}if(o.dependencies.add(l),!a){t.add(n);for(let c of n.dependencies.values())n.peerNames.has(c.name)||i(c,n,l);t.delete(n)}};for(let n of r.dependencies.values())i(n,r,e);return e},J8e=r=>{let e=new Map,t=new Set([r]),i=o=>`${o.name}@${o.ident}`,n=o=>{let a=i(o),l=e.get(a);return l||(l={dependents:new Set,peerDependents:new Set,hoistPriority:0},e.set(a,l)),l},s=(o,a)=>{let l=!!t.has(a);if(n(a).dependents.add(o.ident),!l){t.add(a);for(let u of a.dependencies.values()){let g=n(u);g.hoistPriority=Math.max(g.hoistPriority,u.hoistPriority),a.peerNames.has(u.name)?g.peerDependents.add(a.ident):s(a,u)}}};for(let o of r.dependencies.values())r.peerNames.has(o.name)||s(r,o);return e},Di=r=>{if(!r)return"none";let e=r.indexOf("@",1),t=r.substring(0,e);t.endsWith("$wsroot$")&&(t=`wh:${t.replace("$wsroot$","")}`);let i=r.substring(e+1);if(i==="workspace:.")return".";if(i){let n=(i.indexOf("#")>0?i.split("#")[1]:i).replace("npm:","");return i.startsWith("virtual")&&(t=`v:${t}`),n.startsWith("workspace")&&(t=`w:${t}`,n=""),`${t}${n?`@${n}`:""}`}else return`${t}`},OAe=5e4,eE=r=>{let e=0,t=(n,s,o="")=>{if(e>OAe||s.has(n))return"";e++;let a=Array.from(n.dependencies.values()).sort((c,u)=>c.name===u.name?0:c.name>u.name?1:-1),l="";s.add(n);for(let c=0;c<a.length;c++){let u=a[c];if(!n.peerNames.has(u.name)&&u!==n){let g=n.reasons.get(u.name),h=MO(u.locator);l+=`${o}${c<a.length-1?"\u251C\u2500":"\u2514\u2500"}${(s.has(u)?">":"")+(h!==u.name?`a:${u.name}:`:"")+Di(u.locator)+(g?` ${g}`:"")} +`,l+=t(u,s,`${o}${c<a.length-1?"\u2502 ":" "}`)}}return s.delete(n),l};return t(r,new Set)+(e>OAe?` +Tree is too large, part of the tree has been dunped +`:"")};var tE=(i=>(i.WORKSPACES="workspaces",i.DEPENDENCIES="dependencies",i.NONE="none",i))(tE||{}),UAe="node_modules",Gu="$wsroot$";var rE=(r,e)=>{let{packageTree:t,hoistingLimits:i,errors:n,preserveSymlinksRequired:s}=z8e(r,e),o=null;if(n.length===0){let a=MAe(t,{hoistingLimits:i});o=X8e(r,a,e)}return{tree:o,errors:n,preserveSymlinksRequired:s}},na=r=>`${r.name}@${r.reference}`,UO=r=>{let e=new Map;for(let[t,i]of r.entries())if(!i.dirList){let n=e.get(i.locator);n||(n={target:i.target,linkType:i.linkType,locations:[],aliases:i.aliases},e.set(i.locator,n)),n.locations.push(t)}for(let t of e.values())t.locations=t.locations.sort((i,n)=>{let s=i.split(v.delimiter).length,o=n.split(v.delimiter).length;return n===i?0:s!==o?o-s:n>i?1:-1});return e},HAe=(r,e)=>{let t=P.isVirtualLocator(r)?P.devirtualizeLocator(r):r,i=P.isVirtualLocator(e)?P.devirtualizeLocator(e):e;return P.areLocatorsEqual(t,i)},KO=(r,e,t,i)=>{if(r.linkType!=="SOFT")return!1;let n=K.toPortablePath(t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(r.packageLocation):r.packageLocation);return v.contains(i,n)===null},W8e=r=>{let e=r.getPackageInformation(r.topLevel);if(e===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");if(r.findPackageLocator(e.packageLocation)===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let i=K.toPortablePath(e.packageLocation.slice(0,-1)),n=new Map,s={children:new Map},o=r.getDependencyTreeRoots(),a=new Map,l=new Set,c=(h,p)=>{let d=na(h);if(l.has(d))return;l.add(d);let m=r.getPackageInformation(h);if(m){let y=p?na(p):"";if(na(h)!==y&&m.linkType==="SOFT"&&!KO(m,h,r,i)){let B=jAe(m,h,r);(!a.get(B)||h.reference.startsWith("workspace:"))&&a.set(B,h)}for(let[B,S]of m.packageDependencies)S!==null&&(m.packagePeers.has(B)||c(r.getLocator(B,S),h))}};for(let h of o)c(h,null);let u=i.split(v.sep);for(let h of a.values()){let p=r.getPackageInformation(h),m=K.toPortablePath(p.packageLocation.slice(0,-1)).split(v.sep).slice(u.length),y=s;for(let B of m){let S=y.children.get(B);S||(S={children:new Map},y.children.set(B,S)),y=S}y.workspaceLocator=h}let g=(h,p)=>{if(h.workspaceLocator){let d=na(p),m=n.get(d);m||(m=new Set,n.set(d,m)),m.add(h.workspaceLocator)}for(let d of h.children.values())g(d,h.workspaceLocator||p)};for(let h of s.children.values())g(h,s.workspaceLocator);return n},z8e=(r,e)=>{let t=[],i=!1,n=new Map,s=W8e(r),o=r.getPackageInformation(r.topLevel);if(o===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");let a=r.findPackageLocator(o.packageLocation);if(a===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let l=K.toPortablePath(o.packageLocation.slice(0,-1)),c={name:a.name,identName:a.name,reference:a.reference,peerNames:o.packagePeers,dependencies:new Set,dependencyKind:1},u=new Map,g=(p,d)=>`${na(d)}:${p}`,h=(p,d,m,y,B,S,x,F)=>{var te,O;let H=g(p,m),q=u.get(H),_=!!q;!_&&m.name===a.name&&m.reference===a.reference&&(q=c,u.set(H,c));let X=KO(d,m,r,l);if(!q){let N=0;X?N=2:d.linkType==="SOFT"&&m.name.endsWith(Gu)&&(N=1),q={name:p,identName:m.name,reference:m.reference,dependencies:new Set,peerNames:N===1?new Set:d.packagePeers,dependencyKind:N},u.set(H,q)}let W;if(X?W=2:B.linkType==="SOFT"?W=1:W=0,q.hoistPriority=Math.max(q.hoistPriority||0,W),F&&!X){let N=na({name:y.identName,reference:y.reference}),ce=n.get(N)||new Set;n.set(N,ce),ce.add(q.name)}let Z=new Map(d.packageDependencies);if(e.project){let N=e.project.workspacesByCwd.get(K.toPortablePath(d.packageLocation.slice(0,-1)));if(N){let ce=new Set([...Array.from(N.manifest.peerDependencies.values(),he=>P.stringifyIdent(he)),...Array.from(N.manifest.peerDependenciesMeta.keys())]);for(let he of ce)Z.has(he)||(Z.set(he,S.get(he)||null),q.peerNames.add(he))}}let A=na({name:m.name.replace(Gu,""),reference:m.reference}),ne=s.get(A);if(ne)for(let N of ne)Z.set(`${N.name}${Gu}`,N.reference);(d!==B||d.linkType!=="SOFT"||!X&&(!e.selfReferencesByCwd||e.selfReferencesByCwd.get(x)))&&y.dependencies.add(q);let ue=m!==a&&d.linkType==="SOFT"&&!m.name.endsWith(Gu)&&!X;if(!_&&!ue){let N=new Map;for(let[ce,he]of Z)if(he!==null){let xe=r.getLocator(ce,he),De=r.getLocator(ce.replace(Gu,""),he),Re=r.getPackageInformation(De);if(Re===null)throw new Error("Assertion failed: Expected the package to have been registered");let se=KO(Re,xe,r,l);if(e.validateExternalSoftLinks&&e.project&&se){Re.packageDependencies.size>0&&(i=!0);for(let[Ye,ie]of Re.packageDependencies)if(ie!==null){let G=P.parseLocator(Array.isArray(ie)?`${ie[0]}@${ie[1]}`:`${Ye}@${ie}`);if(na(G)!==na(xe)){let fe=Z.get(Ye);if(fe){let re=P.parseLocator(Array.isArray(fe)?`${fe[0]}@${fe[1]}`:`${Ye}@${fe}`);HAe(re,G)||t.push({messageName:71,text:`Cannot link ${P.prettyIdent(e.project.configuration,P.parseIdent(xe.name))} into ${P.prettyLocator(e.project.configuration,P.parseLocator(`${m.name}@${m.reference}`))} dependency ${P.prettyLocator(e.project.configuration,G)} conflicts with parent dependency ${P.prettyLocator(e.project.configuration,re)}`})}else{let re=N.get(Ye);if(re){let de=re.target,Ze=P.parseLocator(Array.isArray(de)?`${de[0]}@${de[1]}`:`${Ye}@${de}`);HAe(Ze,G)||t.push({messageName:71,text:`Cannot link ${P.prettyIdent(e.project.configuration,P.parseIdent(xe.name))} into ${P.prettyLocator(e.project.configuration,P.parseLocator(`${m.name}@${m.reference}`))} dependency ${P.prettyLocator(e.project.configuration,G)} conflicts with dependency ${P.prettyLocator(e.project.configuration,Ze)} from sibling portal ${P.prettyIdent(e.project.configuration,P.parseIdent(re.portal.name))}`})}else N.set(Ye,{target:G.reference,portal:xe})}}}}let Ae=(te=e.hoistingLimitsByCwd)==null?void 0:te.get(x),ye=se?x:v.relative(l,K.toPortablePath(Re.packageLocation))||Te.dot,ge=(O=e.hoistingLimitsByCwd)==null?void 0:O.get(ye);h(ce,Re,xe,q,d,Z,ye,Ae==="dependencies"||ge==="dependencies"||ge==="workspaces")}}};return h(a.name,o,a,c,o,o.packageDependencies,Te.dot,!1),{packageTree:c,hoistingLimits:n,errors:t,preserveSymlinksRequired:i}};function jAe(r,e,t){let i=t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(r.packageLocation):r.packageLocation;return K.toPortablePath(i||r.packageLocation)}function V8e(r,e,t){let i=e.getLocator(r.name.replace(Gu,""),r.reference),n=e.getPackageInformation(i);if(n===null)throw new Error("Assertion failed: Expected the package to be registered");return t.pnpifyFs?{linkType:"SOFT",target:K.toPortablePath(n.packageLocation)}:{linkType:n.linkType,target:jAe(n,r,e)}}var X8e=(r,e,t)=>{let i=new Map,n=(u,g,h)=>{let{linkType:p,target:d}=V8e(u,r,t);return{locator:na(u),nodePath:g,target:d,linkType:p,aliases:h}},s=u=>{let[g,h]=u.split("/");return h?{scope:Yr(g),name:Yr(h)}:{scope:null,name:Yr(g)}},o=new Set,a=(u,g,h)=>{if(o.has(u))return;o.add(u);let p=Array.from(u.references).sort().join("#");for(let d of u.dependencies){let m=Array.from(d.references).sort().join("#");if(d.identName===u.identName&&m===p)continue;let y=Array.from(d.references).sort(),B={name:d.identName,reference:y[0]},{name:S,scope:x}=s(d.name),F=x?[x,S]:[S],H=v.join(g,UAe),q=v.join(H,...F),_=`${h}/${B.name}`,X=n(B,h,y.slice(1)),W=!1;if(X.linkType==="SOFT"&&t.project){let A=t.project.workspacesByCwd.get(X.target.slice(0,-1));W=!!(A&&!A.manifest.name)}let Z=X.linkType==="SOFT"&&q.startsWith(X.target);if(!d.name.endsWith(Gu)&&!W&&!Z){let A=i.get(q);if(A){if(A.dirList)throw new Error(`Assertion failed: ${q} cannot merge dir node with leaf node`);{let te=P.parseLocator(A.locator),O=P.parseLocator(X.locator);if(A.linkType!==X.linkType)throw new Error(`Assertion failed: ${q} cannot merge nodes with different link types ${A.nodePath}/${P.stringifyLocator(te)} and ${h}/${P.stringifyLocator(O)}`);if(te.identHash!==O.identHash)throw new Error(`Assertion failed: ${q} cannot merge nodes with different idents ${A.nodePath}/${P.stringifyLocator(te)} and ${h}/s${P.stringifyLocator(O)}`);X.aliases=[...X.aliases,...A.aliases,P.parseLocator(A.locator).reference]}}i.set(q,X);let ne=q.split("/"),ue=ne.indexOf(UAe);for(let te=ne.length-1;ue>=0&&te>ue;te--){let O=K.toPortablePath(ne.slice(0,te).join(v.sep)),N=Yr(ne[te]),ce=i.get(O);if(!ce)i.set(O,{dirList:new Set([N])});else if(ce.dirList){if(ce.dirList.has(N))break;ce.dirList.add(N)}}}a(d,X.linkType==="SOFT"?X.target:q,_)}},l=n({name:e.name,reference:Array.from(e.references)[0]},"",[]),c=l.target;return i.set(c,l),a(e,c,""),i};var sM={};ct(sM,{PnpInstaller:()=>qu,PnpLinker:()=>yl,default:()=>vze,getPnpPath:()=>wl,jsInstallUtils:()=>po,pnpUtils:()=>hE,quotePathIfNeeded:()=>Dle});var xle=ve(zr()),kle=J("url");var GAe={["DEFAULT"]:{collapsed:!1,next:{["*"]:"DEFAULT"}},["TOP_LEVEL"]:{collapsed:!1,next:{fallbackExclusionList:"FALLBACK_EXCLUSION_LIST",packageRegistryData:"PACKAGE_REGISTRY_DATA",["*"]:"DEFAULT"}},["FALLBACK_EXCLUSION_LIST"]:{collapsed:!1,next:{["*"]:"FALLBACK_EXCLUSION_ENTRIES"}},["FALLBACK_EXCLUSION_ENTRIES"]:{collapsed:!0,next:{["*"]:"FALLBACK_EXCLUSION_DATA"}},["FALLBACK_EXCLUSION_DATA"]:{collapsed:!0,next:{["*"]:"DEFAULT"}},["PACKAGE_REGISTRY_DATA"]:{collapsed:!1,next:{["*"]:"PACKAGE_REGISTRY_ENTRIES"}},["PACKAGE_REGISTRY_ENTRIES"]:{collapsed:!0,next:{["*"]:"PACKAGE_STORE_DATA"}},["PACKAGE_STORE_DATA"]:{collapsed:!1,next:{["*"]:"PACKAGE_STORE_ENTRIES"}},["PACKAGE_STORE_ENTRIES"]:{collapsed:!0,next:{["*"]:"PACKAGE_INFORMATION_DATA"}},["PACKAGE_INFORMATION_DATA"]:{collapsed:!1,next:{packageDependencies:"PACKAGE_DEPENDENCIES",["*"]:"DEFAULT"}},["PACKAGE_DEPENDENCIES"]:{collapsed:!1,next:{["*"]:"PACKAGE_DEPENDENCY"}},["PACKAGE_DEPENDENCY"]:{collapsed:!0,next:{["*"]:"DEFAULT"}}};function Z8e(r,e,t){let i="";i+="[";for(let n=0,s=r.length;n<s;++n)i+=_b(String(n),r[n],e,t).replace(/^ +/g,""),n+1<s&&(i+=", ");return i+="]",i}function _8e(r,e,t){let i=`${t} `,n="";n+=t,n+=`[ +`;for(let s=0,o=r.length;s<o;++s)n+=i+_b(String(s),r[s],e,i).replace(/^ +/,""),s+1<o&&(n+=","),n+=` +`;return n+=t,n+="]",n}function $8e(r,e,t){let i=Object.keys(r),n="";n+="{";for(let s=0,o=i.length,a=0;s<o;++s){let l=i[s],c=r[l];typeof c>"u"||(a!==0&&(n+=", "),n+=JSON.stringify(l),n+=": ",n+=_b(l,c,e,t).replace(/^ +/g,""),a+=1)}return n+="}",n}function eze(r,e,t){let i=Object.keys(r),n=`${t} `,s="";s+=t,s+=`{ +`;let o=0;for(let a=0,l=i.length;a<l;++a){let c=i[a],u=r[c];typeof u>"u"||(o!==0&&(s+=",",s+=` +`),s+=n,s+=JSON.stringify(c),s+=": ",s+=_b(c,u,e,n).replace(/^ +/g,""),o+=1)}return o!==0&&(s+=` +`),s+=t,s+="}",s}function _b(r,e,t,i){let{next:n}=GAe[t],s=n[r]||n["*"];return YAe(e,s,i)}function YAe(r,e,t){let{collapsed:i}=GAe[e];return Array.isArray(r)?i?Z8e(r,e,t):_8e(r,e,t):typeof r=="object"&&r!==null?i?$8e(r,e,t):eze(r,e,t):JSON.stringify(r)}function qAe(r){return YAe(r,"TOP_LEVEL","")}function iE(r,e){let t=Array.from(r);Array.isArray(e)||(e=[e]);let i=[];for(let s of e)i.push(t.map(o=>s(o)));let n=t.map((s,o)=>o);return n.sort((s,o)=>{for(let a of i){let l=a[s]<a[o]?-1:a[s]>a[o]?1:0;if(l!==0)return l}return 0}),n.map(s=>t[s])}function tze(r){let e=new Map,t=iE(r.fallbackExclusionList||[],[({name:i,reference:n})=>i,({name:i,reference:n})=>n]);for(let{name:i,reference:n}of t){let s=e.get(i);typeof s>"u"&&e.set(i,s=new Set),s.add(n)}return Array.from(e).map(([i,n])=>[i,Array.from(n)])}function rze(r){return iE(r.fallbackPool||[],([e])=>e)}function ize(r){let e=[];for(let[t,i]of iE(r.packageRegistry,([n])=>n===null?"0":`1${n}`)){let n=[];e.push([t,n]);for(let[s,{packageLocation:o,packageDependencies:a,packagePeers:l,linkType:c,discardFromLookup:u}]of iE(i,([g])=>g===null?"0":`1${g}`)){let g=[];t!==null&&s!==null&&!a.has(t)&&g.push([t,s]);for(let[d,m]of iE(a.entries(),([y])=>y))g.push([d,m]);let h=l&&l.size>0?Array.from(l):void 0,p=u||void 0;n.push([s,{packageLocation:o,packageDependencies:g,packagePeers:h,linkType:c,discardFromLookup:p}])}}return e}function nE(r){return{__info:["This file is automatically generated. Do not touch it, or risk","your modifications being lost. We also recommend you not to read","it either without using the @yarnpkg/pnp package, as the data layout","is entirely unspecified and WILL change from a version to another."],dependencyTreeRoots:r.dependencyTreeRoots,enableTopLevelFallback:r.enableTopLevelFallback||!1,ignorePatternData:r.ignorePattern||null,fallbackExclusionList:tze(r),fallbackPool:rze(r),packageRegistryData:ize(r)}}var zAe=ve(WAe());function VAe(r,e){return[r?`${r} +`:"",`/* eslint-disable */ +`,`"use strict"; +`,` +`,`function $$SETUP_STATE(hydrateRuntimeState, basePath) { +`,e.replace(/^/gm," "),`} +`,` +`,(0,zAe.default)()].join("")}function nze(r){return JSON.stringify(r,null,2)}function sze(r){return`'${r.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,`\\ +`)}'`}function oze(r){return[`return hydrateRuntimeState(JSON.parse(${sze(qAe(r))}), {basePath: basePath || __dirname}); +`].join("")}function aze(r){return[`var path = require('path'); +`,`var dataLocation = path.resolve(__dirname, ${JSON.stringify(r)}); +`,`return hydrateRuntimeState(require(dataLocation), {basePath: basePath || path.dirname(dataLocation)}); +`].join("")}function XAe(r){let e=nE(r),t=oze(e);return VAe(r.shebang,t)}function ZAe(r){let e=nE(r),t=aze(r.dataLocation),i=VAe(r.shebang,t);return{dataFile:nze(e),loaderFile:i}}var yle=J("fs");var wle=J("util");function jO(r,{basePath:e}){let t=K.toPortablePath(e),i=v.resolve(t),n=r.ignorePatternData!==null?new RegExp(r.ignorePatternData):null,s=new Map,o=new Map(r.packageRegistryData.map(([g,h])=>[g,new Map(h.map(([p,d])=>{var x;if(g===null!=(p===null))throw new Error("Assertion failed: The name and reference should be null, or neither should");let m=(x=d.discardFromLookup)!=null?x:!1,y={name:g,reference:p},B=s.get(d.packageLocation);B?(B.discardFromLookup=B.discardFromLookup&&m,m||(B.locator=y)):s.set(d.packageLocation,{locator:y,discardFromLookup:m});let S=null;return[p,{packageDependencies:new Map(d.packageDependencies),packagePeers:new Set(d.packagePeers),linkType:d.linkType,discardFromLookup:m,get packageLocation(){return S||(S=v.join(i,d.packageLocation))}}]}))])),a=new Map(r.fallbackExclusionList.map(([g,h])=>[g,new Set(h)])),l=new Map(r.fallbackPool),c=r.dependencyTreeRoots,u=r.enableTopLevelFallback;return{basePath:t,dependencyTreeRoots:c,enableTopLevelFallback:u,fallbackExclusionList:a,fallbackPool:l,ignorePattern:n,packageLocatorsByLocations:s,packageRegistry:o}}var gE=J("module"),gA=J("url"),_O=J("util");var qi=J("url");var tle=ve(J("assert"));var GO=Array.isArray,sE=JSON.stringify,oE=Object.getOwnPropertyNames,Yu=(r,e)=>Object.prototype.hasOwnProperty.call(r,e),YO=(r,e)=>RegExp.prototype.exec.call(r,e),qO=(r,...e)=>RegExp.prototype[Symbol.replace].apply(r,e),El=(r,...e)=>String.prototype.endsWith.apply(r,e),JO=(r,...e)=>String.prototype.includes.apply(r,e),WO=(r,...e)=>String.prototype.lastIndexOf.apply(r,e),aE=(r,...e)=>String.prototype.indexOf.apply(r,e),_Ae=(r,...e)=>String.prototype.replace.apply(r,e),Il=(r,...e)=>String.prototype.slice.apply(r,e),sa=(r,...e)=>String.prototype.startsWith.apply(r,e),$Ae=Map,ele=JSON.parse;function AE(r,e,t){return class extends t{constructor(...i){super(e(...i)),this.code=r,this.name=`${t.name} [${r}]`}}}var rle=AE("ERR_PACKAGE_IMPORT_NOT_DEFINED",(r,e,t)=>`Package import specifier "${r}" is not defined${e?` in package ${e}package.json`:""} imported from ${t}`,TypeError),zO=AE("ERR_INVALID_MODULE_SPECIFIER",(r,e,t=void 0)=>`Invalid module "${r}" ${e}${t?` imported from ${t}`:""}`,TypeError),ile=AE("ERR_INVALID_PACKAGE_TARGET",(r,e,t,i=!1,n=void 0)=>{let s=typeof t=="string"&&!i&&t.length&&!sa(t,"./");return e==="."?((0,tle.default)(i===!1),`Invalid "exports" main target ${sE(t)} defined in the package config ${r}package.json${n?` imported from ${n}`:""}${s?'; targets must start with "./"':""}`):`Invalid "${i?"imports":"exports"}" target ${sE(t)} defined for '${e}' in the package config ${r}package.json${n?` imported from ${n}`:""}${s?'; targets must start with "./"':""}`},Error),lE=AE("ERR_INVALID_PACKAGE_CONFIG",(r,e,t)=>`Invalid package config ${r}${e?` while importing ${e}`:""}${t?`. ${t}`:""}`,Error),nle=AE("ERR_PACKAGE_PATH_NOT_EXPORTED",(r,e,t=void 0)=>e==="."?`No "exports" main defined in ${r}package.json${t?` imported from ${t}`:""}`:`Package subpath '${e}' is not defined by "exports" in ${r}package.json${t?` imported from ${t}`:""}`,Error);var eQ=J("url");function sle(r,e){let t=Object.create(null);for(let i=0;i<e.length;i++){let n=e[i];Yu(r,n)&&(t[n]=r[n])}return t}var $b=new $Ae;function Aze(r,e,t,i){let n=$b.get(r);if(n!==void 0)return n;let s=i(r);if(s===void 0){let p={pjsonPath:r,exists:!1,main:void 0,name:void 0,type:"none",exports:void 0,imports:void 0};return $b.set(r,p),p}let o;try{o=ele(s)}catch(p){throw new lE(r,(t?`"${e}" from `:"")+(0,eQ.fileURLToPath)(t||e),p.message)}let{imports:a,main:l,name:c,type:u}=sle(o,["imports","main","name","type"]),g=Yu(o,"exports")?o.exports:void 0;(typeof a!="object"||a===null)&&(a=void 0),typeof l!="string"&&(l=void 0),typeof c!="string"&&(c=void 0),u!=="module"&&u!=="commonjs"&&(u="none");let h={pjsonPath:r,exists:!0,main:l,name:c,type:u,exports:g,imports:a};return $b.set(r,h),h}function ole(r,e){let t=new URL("./package.json",r);for(;;){let s=t.pathname;if(El(s,"node_modules/package.json"))break;let o=Aze((0,eQ.fileURLToPath)(t),r,void 0,e);if(o.exists)return o;let a=t;if(t=new URL("../package.json",t),t.pathname===a.pathname)break}let i=(0,eQ.fileURLToPath)(t),n={pjsonPath:i,exists:!1,main:void 0,name:void 0,type:"none",exports:void 0,imports:void 0};return $b.set(i,n),n}function lze(r,e,t){throw new rle(r,e&&(0,qi.fileURLToPath)(new URL(".",e)),(0,qi.fileURLToPath)(t))}function cze(r,e,t,i){let n=`request is not a valid subpath for the "${t?"imports":"exports"}" resolution of ${(0,qi.fileURLToPath)(e)}`;throw new zO(r,n,i&&(0,qi.fileURLToPath)(i))}function cE(r,e,t,i,n){throw typeof e=="object"&&e!==null?e=sE(e,null,""):e=`${e}`,new ile((0,qi.fileURLToPath)(new URL(".",t)),r,e,i,n&&(0,qi.fileURLToPath)(n))}var ale=/(^|\\|\/)((\.|%2e)(\.|%2e)?|(n|%6e|%4e)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(_|%5f)(m|%6d|%4d)(o|%6f|%4f)(d|%64|%44)(u|%75|%55)(l|%6c|%4c)(e|%65|%45)(s|%73|%53))(\\|\/|$)/i,Ale=/\*/g;function uze(r,e,t,i,n,s,o,a){if(e!==""&&!s&&r[r.length-1]!=="/"&&cE(t,r,i,o,n),!sa(r,"./")){if(o&&!sa(r,"../")&&!sa(r,"/")){let g=!1;try{new URL(r),g=!0}catch{}if(!g)return s?qO(Ale,r,()=>e):r+e}cE(t,r,i,o,n)}YO(ale,Il(r,2))!==null&&cE(t,r,i,o,n);let l=new URL(r,i),c=l.pathname,u=new URL(".",i).pathname;if(sa(c,u)||cE(t,r,i,o,n),e==="")return l;if(YO(ale,e)!==null){let g=s?_Ae(t,"*",()=>e):t+e;cze(g,i,o,n)}return s?new URL(qO(Ale,l.href,()=>e)):new URL(e,l)}function gze(r){let e=+r;return`${e}`!==r?!1:e>=0&&e<4294967295}function ip(r,e,t,i,n,s,o,a){if(typeof e=="string")return uze(e,t,i,r,n,s,o,a);if(GO(e)){if(e.length===0)return null;let l;for(let c=0;c<e.length;c++){let u=e[c],g;try{g=ip(r,u,t,i,n,s,o,a)}catch(h){if(l=h,h.code==="ERR_INVALID_PACKAGE_TARGET")continue;throw h}if(g!==void 0){if(g===null){l=null;continue}return g}}if(l==null)return l;throw l}else if(typeof e=="object"&&e!==null){let l=oE(e);for(let c=0;c<l.length;c++){let u=l[c];if(gze(u))throw new lE((0,qi.fileURLToPath)(r),n,'"exports" cannot contain numeric property keys.')}for(let c=0;c<l.length;c++){let u=l[c];if(u==="default"||a.has(u)){let g=e[u],h=ip(r,g,t,i,n,s,o,a);if(h===void 0)continue;return h}}return}else if(e===null)return null;cE(i,e,r,o,n)}function cle(r,e){let t=aE(r,"*"),i=aE(e,"*"),n=t===-1?r.length:t+1,s=i===-1?e.length:i+1;return n>s?-1:s>n||t===-1?1:i===-1||r.length>e.length?-1:e.length>r.length?1:0}function fze(r,e,t){if(typeof r=="string"||GO(r))return!0;if(typeof r!="object"||r===null)return!1;let i=oE(r),n=!1,s=0;for(let o=0;o<i.length;o++){let a=i[o],l=a===""||a[0]!==".";if(s++===0)n=l;else if(n!==l)throw new lE((0,qi.fileURLToPath)(e),t,`"exports" cannot contain some keys starting with '.' and some not. The exports object must either be an object of package subpath keys or an object of main entry condition name keys only.`)}return n}function VO(r,e,t){throw new nle((0,qi.fileURLToPath)(new URL(".",e)),r,t&&(0,qi.fileURLToPath)(t))}var lle=new Set;function hze(r,e,t){let i=(0,qi.fileURLToPath)(e);lle.has(i+"|"+r)||(lle.add(i+"|"+r),process.emitWarning(`Use of deprecated trailing slash pattern mapping "${r}" in the "exports" field module resolution of the package at ${i}${t?` imported from ${(0,qi.fileURLToPath)(t)}`:""}. Mapping specifiers ending in "/" is no longer supported.`,"DeprecationWarning","DEP0155"))}function ule({packageJSONUrl:r,packageSubpath:e,exports:t,base:i,conditions:n}){if(fze(t,r,i)&&(t={".":t}),Yu(t,e)&&!JO(e,"*")&&!El(e,"/")){let l=t[e],c=ip(r,l,"",e,i,!1,!1,n);return c==null&&VO(e,r,i),c}let s="",o,a=oE(t);for(let l=0;l<a.length;l++){let c=a[l],u=aE(c,"*");if(u!==-1&&sa(e,Il(c,0,u))){El(e,"/")&&hze(e,r,i);let g=Il(c,u+1);e.length>=c.length&&El(e,g)&&cle(s,c)===1&&WO(c,"*")===u&&(s=c,o=Il(e,u,e.length-g.length))}}if(s){let l=t[s],c=ip(r,l,o,s,i,!0,!1,n);return c==null&&VO(e,r,i),c}VO(e,r,i)}function gle({name:r,base:e,conditions:t,readFileSyncFn:i}){if(r==="#"||sa(r,"#/")||El(r,"/")){let o="is not a valid internal imports specifier name";throw new zO(r,o,(0,qi.fileURLToPath)(e))}let n,s=ole(e,i);if(s.exists){n=(0,qi.pathToFileURL)(s.pjsonPath);let o=s.imports;if(o)if(Yu(o,r)&&!JO(r,"*")){let a=ip(n,o[r],"",r,e,!1,!0,t);if(a!=null)return a}else{let a="",l,c=oE(o);for(let u=0;u<c.length;u++){let g=c[u],h=aE(g,"*");if(h!==-1&&sa(r,Il(g,0,h))){let p=Il(g,h+1);r.length>=g.length&&El(r,p)&&cle(a,g)===1&&WO(g,"*")===h&&(a=g,l=Il(r,h,r.length-p.length))}}if(a){let u=o[a],g=ip(n,u,l,a,e,!0,!0,t);if(g!=null)return g}}}lze(r,n,e)}var pze=new Set(["BUILTIN_NODE_RESOLUTION_FAILED","MISSING_DEPENDENCY","MISSING_PEER_DEPENDENCY","QUALIFIED_PATH_RESOLUTION_FAILED","UNDECLARED_DEPENDENCY"]);function ei(r,e,t={},i){i!=null||(i=pze.has(r)?"MODULE_NOT_FOUND":r);let n={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(e),{code:{...n,value:i},pnpCode:{...n,value:r},data:{...n,value:t}})}function ho(r){return K.normalize(K.fromPortablePath(r))}var dle=ve(hle());function Cle(r){return dze(),ZO[r]}var ZO;function dze(){ZO||(ZO={"--conditions":[],...ple(Cze()),...ple(process.execArgv)})}function ple(r){return(0,dle.default)({"--conditions":[String],"-C":"--conditions"},{argv:r,permissive:!0})}function Cze(){let r=[],e=mze(process.env.NODE_OPTIONS||"",r);return r.length,e}function mze(r,e){let t=[],i=!1,n=!0;for(let s=0;s<r.length;++s){let o=r[s];if(o==="\\"&&i){if(s+1===r.length)return e.push(`invalid value for NODE_OPTIONS (invalid escape) +`),t;o=r[++s]}else if(o===" "&&!i){n=!0;continue}else if(o==='"'){i=!i;continue}n?(t.push(o),n=!1):t[t.length-1]+=o}return i&&e.push(`invalid value for NODE_OPTIONS (unterminated string) +`),t}var Ele=J("module");var[jr,Fn]=process.versions.node.split(".").map(r=>parseInt(r,10)),EBt=jr>16||jr===16&&Fn>=12,IBt=jr>17||jr===17&&Fn>=5||jr===16&&Fn>=15,yBt=jr>17||jr===17&&Fn>=1||jr===16&&Fn>14,mle=jr>19||jr===19&&Fn>=2||jr===18&&Fn>=13,wBt=jr===20&&Fn<6||jr===19&&Fn>=3,BBt=jr>19||jr===19&&Fn>=6,bBt=jr>18||jr===18&&Fn>=1||jr===16&&Fn>=17,QBt=jr>=21||jr===20&&Fn>=10||jr===18&&Fn>=19;var Eze=new Set(Ele.Module.builtinModules||Object.keys(process.binding("natives"))),tQ=r=>r.startsWith("node:")||Eze.has(r);function Ile(r){if(process.env.WATCH_REPORT_DEPENDENCIES&&process.send)if(r=r.map(e=>K.fromPortablePath(yr.resolveVirtual(K.toPortablePath(e)))),mle)process.send({"watch:require":r});else for(let e of r)process.send({"watch:require":e})}function $O(r,e){let t=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,i=Number(process.env.PNP_DEBUG_LEVEL),n=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/,s=/^(\/|\.{1,2}(\/|$))/,o=/\/$/,a=/^\.{0,2}\//,l={name:null,reference:null},c=[],u=new Set;if(r.enableTopLevelFallback===!0&&c.push(l),e.compatibilityMode!==!1)for(let se of["react-scripts","gatsby"]){let Ae=r.packageRegistry.get(se);if(Ae)for(let ye of Ae.keys()){if(ye===null)throw new Error("Assertion failed: This reference shouldn't be null");c.push({name:se,reference:ye})}}let{ignorePattern:g,packageRegistry:h,packageLocatorsByLocations:p}=r;function d(se,Ae){return{fn:se,args:Ae,error:null,result:null}}function m(se){var Ye,ie,G,fe,re,de;let Ae=(G=(ie=(Ye=process.stderr)==null?void 0:Ye.hasColors)==null?void 0:ie.call(Ye))!=null?G:process.stdout.isTTY,ye=(Ze,vt)=>`\x1B[${Ze}m${vt}\x1B[0m`,ge=se.error;console.error(ge?ye("31;1",`\u2716 ${(fe=se.error)==null?void 0:fe.message.replace(/\n.*/s,"")}`):ye("33;1","\u203C Resolution")),se.args.length>0&&console.error();for(let Ze of se.args)console.error(` ${ye("37;1","In \u2190")} ${(0,_O.inspect)(Ze,{colors:Ae,compact:!0})}`);se.result&&(console.error(),console.error(` ${ye("37;1","Out \u2192")} ${(0,_O.inspect)(se.result,{colors:Ae,compact:!0})}`));let oe=(de=(re=new Error().stack.match(/(?<=^ +)at.*/gm))==null?void 0:re.slice(2))!=null?de:[];if(oe.length>0){console.error();for(let Ze of oe)console.error(` ${ye("38;5;244",Ze)}`)}console.error()}function y(se,Ae){if(e.allowDebug===!1)return Ae;if(Number.isFinite(i)){if(i>=2)return(...ye)=>{let ge=d(se,ye);try{return ge.result=Ae(...ye)}catch(oe){throw ge.error=oe}finally{m(ge)}};if(i>=1)return(...ye)=>{try{return Ae(...ye)}catch(ge){let oe=d(se,ye);throw oe.error=ge,m(oe),ge}}}return Ae}function B(se){let Ae=A(se);if(!Ae)throw ei("INTERNAL","Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)");return Ae}function S(se){if(se.name===null)return!0;for(let Ae of r.dependencyTreeRoots)if(Ae.name===se.name&&Ae.reference===se.reference)return!0;return!1}let x=new Set(["node","require",...Cle("--conditions")]);function F(se,Ae=x,ye){let ge=te(v.join(se,"internal.js"),{resolveIgnored:!0,includeDiscardFromLookup:!0});if(ge===null)throw ei("INTERNAL",`The locator that owns the "${se}" path can't be found inside the dependency tree (this is probably an internal error)`);let{packageLocation:oe}=B(ge),Ye=v.join(oe,St.manifest);if(!e.fakeFs.existsSync(Ye))return null;let ie=JSON.parse(e.fakeFs.readFileSync(Ye,"utf8"));if(ie.exports==null)return null;let G=v.contains(oe,se);if(G===null)throw ei("INTERNAL","unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)");G!=="."&&!a.test(G)&&(G=`./${G}`);try{let fe=ule({packageJSONUrl:(0,gA.pathToFileURL)(K.fromPortablePath(Ye)),packageSubpath:G,exports:ie.exports,base:ye?(0,gA.pathToFileURL)(K.fromPortablePath(ye)):null,conditions:Ae});return K.toPortablePath((0,gA.fileURLToPath)(fe))}catch(fe){throw ei("EXPORTS_RESOLUTION_FAILED",fe.message,{unqualifiedPath:ho(se),locator:ge,pkgJson:ie,subpath:ho(G),conditions:Ae},fe.code)}}function H(se,Ae,{extensions:ye}){let ge;try{Ae.push(se),ge=e.fakeFs.statSync(se)}catch{}if(ge&&!ge.isDirectory())return e.fakeFs.realpathSync(se);if(ge&&ge.isDirectory()){let oe;try{oe=JSON.parse(e.fakeFs.readFileSync(v.join(se,St.manifest),"utf8"))}catch{}let Ye;if(oe&&oe.main&&(Ye=v.resolve(se,oe.main)),Ye&&Ye!==se){let ie=H(Ye,Ae,{extensions:ye});if(ie!==null)return ie}}for(let oe=0,Ye=ye.length;oe<Ye;oe++){let ie=`${se}${ye[oe]}`;if(Ae.push(ie),e.fakeFs.existsSync(ie))return ie}if(ge&&ge.isDirectory())for(let oe=0,Ye=ye.length;oe<Ye;oe++){let ie=v.format({dir:se,name:"index",ext:ye[oe]});if(Ae.push(ie),e.fakeFs.existsSync(ie))return ie}return null}function q(se){let Ae=new gE.Module(se,null);return Ae.filename=se,Ae.paths=gE.Module._nodeModulePaths(se),Ae}function _(se,Ae){return Ae.endsWith("/")&&(Ae=v.join(Ae,"internal.js")),gE.Module._resolveFilename(K.fromPortablePath(se),q(K.fromPortablePath(Ae)),!1,{plugnplay:!1})}function X(se){if(g===null)return!1;let Ae=v.contains(r.basePath,se);return Ae===null?!1:!!g.test(Ae.replace(/\/$/,""))}let W={std:3,resolveVirtual:1,getAllLocators:1},Z=l;function A({name:se,reference:Ae}){let ye=h.get(se);if(!ye)return null;let ge=ye.get(Ae);return ge||null}function ne({name:se,reference:Ae}){let ye=[];for(let[ge,oe]of h)if(ge!==null)for(let[Ye,ie]of oe)Ye===null||ie.packageDependencies.get(se)!==Ae||ge===se&&Ye===Ae||ye.push({name:ge,reference:Ye});return ye}function ue(se,Ae){let ye=new Map,ge=new Set,oe=ie=>{let G=JSON.stringify(ie.name);if(ge.has(G))return;ge.add(G);let fe=ne(ie);for(let re of fe)if(B(re).packagePeers.has(se))oe(re);else{let Ze=ye.get(re.name);typeof Ze>"u"&&ye.set(re.name,Ze=new Set),Ze.add(re.reference)}};oe(Ae);let Ye=[];for(let ie of[...ye.keys()].sort())for(let G of[...ye.get(ie)].sort())Ye.push({name:ie,reference:G});return Ye}function te(se,{resolveIgnored:Ae=!1,includeDiscardFromLookup:ye=!1}={}){if(X(se)&&!Ae)return null;let ge=v.relative(r.basePath,se);ge.match(s)||(ge=`./${ge}`),ge.endsWith("/")||(ge=`${ge}/`);do{let oe=p.get(ge);if(typeof oe>"u"||oe.discardFromLookup&&!ye){ge=ge.substring(0,ge.lastIndexOf("/",ge.length-2)+1);continue}return oe.locator}while(ge!=="");return null}function O(se){try{return e.fakeFs.readFileSync(K.toPortablePath(se),"utf8")}catch(Ae){if(Ae.code==="ENOENT")return;throw Ae}}function N(se,Ae,{considerBuiltins:ye=!0}={}){if(se.startsWith("#"))throw new Error("resolveToUnqualified can not handle private import mappings");if(se==="pnpapi")return K.toPortablePath(e.pnpapiResolution);if(ye&&tQ(se))return null;let ge=ho(se),oe=Ae&&ho(Ae);if(Ae&&X(Ae)&&(!v.isAbsolute(se)||te(se)===null)){let G=_(se,Ae);if(G===!1)throw ei("BUILTIN_NODE_RESOLUTION_FAILED",`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer was explicitely ignored by the regexp) + +Require request: "${ge}" +Required by: ${oe} +`,{request:ge,issuer:oe});return K.toPortablePath(G)}let Ye,ie=se.match(n);if(ie){if(!Ae)throw ei("API_ERROR","The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:ge,issuer:oe});let[,G,fe]=ie,re=te(Ae);if(!re){let gr=_(se,Ae);if(gr===!1)throw ei("BUILTIN_NODE_RESOLUTION_FAILED",`The builtin node resolution algorithm was unable to resolve the requested module (it didn't go through the pnp resolver because the issuer doesn't seem to be part of the Yarn-managed dependency tree). + +Require path: "${ge}" +Required by: ${oe} +`,{request:ge,issuer:oe});return K.toPortablePath(gr)}let Ze=B(re).packageDependencies.get(G),vt=null;if(Ze==null&&re.name!==null){let gr=r.fallbackExclusionList.get(re.name);if(!gr||!gr.has(re.reference)){for(let ri=0,Ms=c.length;ri<Ms;++ri){let Ei=B(c[ri]).packageDependencies.get(G);if(Ei!=null){t?vt=Ei:Ze=Ei;break}}if(r.enableTopLevelFallback&&Ze==null&&vt===null){let ri=r.fallbackPool.get(G);ri!=null&&(vt=ri)}}}let mt=null;if(Ze===null)if(S(re))mt=ei("MISSING_PEER_DEPENDENCY",`Your application tried to access ${G} (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${oe} +`,{request:ge,issuer:oe,dependencyName:G});else{let gr=ue(G,re);gr.every(gi=>S(gi))?mt=ei("MISSING_PEER_DEPENDENCY",`${re.name} tried to access ${G} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${re.name}@${re.reference} (via ${oe}) +${gr.map(gi=>`Ancestor breaking the chain: ${gi.name}@${gi.reference} +`).join("")} +`,{request:ge,issuer:oe,issuerLocator:Object.assign({},re),dependencyName:G,brokenAncestors:gr}):mt=ei("MISSING_PEER_DEPENDENCY",`${re.name} tried to access ${G} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${re.name}@${re.reference} (via ${oe}) + +${gr.map(gi=>`Ancestor breaking the chain: ${gi.name}@${gi.reference} +`).join("")} +`,{request:ge,issuer:oe,issuerLocator:Object.assign({},re),dependencyName:G,brokenAncestors:gr})}else Ze===void 0&&(!ye&&tQ(se)?S(re)?mt=ei("UNDECLARED_DEPENDENCY",`Your application tried to access ${G}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${G} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${oe} +`,{request:ge,issuer:oe,dependencyName:G}):mt=ei("UNDECLARED_DEPENDENCY",`${re.name} tried to access ${G}. While this module is usually interpreted as a Node builtin, your resolver is running inside a non-Node resolution context where such builtins are ignored. Since ${G} isn't otherwise declared in ${re.name}'s dependencies, this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${oe} +`,{request:ge,issuer:oe,issuerLocator:Object.assign({},re),dependencyName:G}):S(re)?mt=ei("UNDECLARED_DEPENDENCY",`Your application tried to access ${G}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${oe} +`,{request:ge,issuer:oe,dependencyName:G}):mt=ei("UNDECLARED_DEPENDENCY",`${re.name} tried to access ${G}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. + +Required package: ${G}${G!==ge?` (via "${ge}")`:""} +Required by: ${re.name}@${re.reference} (via ${oe}) +`,{request:ge,issuer:oe,issuerLocator:Object.assign({},re),dependencyName:G}));if(Ze==null){if(vt===null||mt===null)throw mt||new Error("Assertion failed: Expected an error to have been set");Ze=vt;let gr=mt.message.replace(/\n.*/g,"");mt.message=gr,!u.has(gr)&&i!==0&&(u.add(gr),process.emitWarning(mt))}let Tr=Array.isArray(Ze)?{name:Ze[0],reference:Ze[1]}:{name:G,reference:Ze},ti=B(Tr);if(!ti.packageLocation)throw ei("MISSING_DEPENDENCY",`A dependency seems valid but didn't get installed for some reason. This might be caused by a partial install, such as dev vs prod. + +Required package: ${Tr.name}@${Tr.reference}${Tr.name!==ge?` (via "${ge}")`:""} +Required by: ${re.name}@${re.reference} (via ${oe}) +`,{request:ge,issuer:oe,dependencyLocator:Object.assign({},Tr)});let ui=ti.packageLocation;fe?Ye=v.join(ui,fe):Ye=ui}else if(v.isAbsolute(se))Ye=v.normalize(se);else{if(!Ae)throw ei("API_ERROR","The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:ge,issuer:oe});let G=v.resolve(Ae);Ae.match(o)?Ye=v.normalize(v.join(G,se)):Ye=v.normalize(v.join(v.dirname(G),se))}return v.normalize(Ye)}function ce(se,Ae,ye=x,ge){if(s.test(se))return Ae;let oe=F(Ae,ye,ge);return oe?v.normalize(oe):Ae}function he(se,{extensions:Ae=Object.keys(gE.Module._extensions)}={}){var oe,Ye;let ye=[],ge=H(se,ye,{extensions:Ae});if(ge)return v.normalize(ge);{Ile(ye.map(fe=>K.fromPortablePath(fe)));let ie=ho(se),G=te(se);if(G){let{packageLocation:fe}=B(G),re=!0;try{e.fakeFs.accessSync(fe)}catch(de){if((de==null?void 0:de.code)==="ENOENT")re=!1;else{let Ze=((Ye=(oe=de==null?void 0:de.message)!=null?oe:de)!=null?Ye:"empty exception thrown").replace(/^[A-Z]/,vt=>vt.toLowerCase());throw ei("QUALIFIED_PATH_RESOLUTION_FAILED",`Required package exists but could not be accessed (${Ze}). + +Missing package: ${G.name}@${G.reference} +Expected package location: ${ho(fe)} +`,{unqualifiedPath:ie,extensions:Ae})}}if(!re){let de=fe.includes("/unplugged/")?"Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).":"Required package missing from disk. If you keep your packages inside your repository then restarting the Node process may be enough. Otherwise, try to run an install first.";throw ei("QUALIFIED_PATH_RESOLUTION_FAILED",`${de} + +Missing package: ${G.name}@${G.reference} +Expected package location: ${ho(fe)} +`,{unqualifiedPath:ie,extensions:Ae})}}throw ei("QUALIFIED_PATH_RESOLUTION_FAILED",`Qualified path resolution failed: we looked for the following paths, but none could be accessed. + +Source path: ${ie} +${ye.map(fe=>`Not found: ${ho(fe)} +`).join("")}`,{unqualifiedPath:ie,extensions:Ae})}}function xe(se,Ae,ye){var oe;if(!Ae)throw new Error("Assertion failed: An issuer is required to resolve private import mappings");let ge=gle({name:se,base:(0,gA.pathToFileURL)(K.fromPortablePath(Ae)),conditions:(oe=ye.conditions)!=null?oe:x,readFileSyncFn:O});if(ge instanceof gA.URL)return he(K.toPortablePath((0,gA.fileURLToPath)(ge)),{extensions:ye.extensions});if(ge.startsWith("#"))throw new Error("Mapping from one private import to another isn't allowed");return De(ge,Ae,ye)}function De(se,Ae,ye={}){try{if(se.startsWith("#"))return xe(se,Ae,ye);let{considerBuiltins:ge,extensions:oe,conditions:Ye}=ye,ie=N(se,Ae,{considerBuiltins:ge});if(se==="pnpapi")return ie;if(ie===null)return null;let G=()=>Ae!==null?X(Ae):!1,fe=(!ge||!tQ(se))&&!G()?ce(se,ie,Ye,Ae):ie;return he(fe,{extensions:oe})}catch(ge){throw Object.prototype.hasOwnProperty.call(ge,"pnpCode")&&Object.assign(ge.data,{request:ho(se),issuer:Ae&&ho(Ae)}),ge}}function Re(se){let Ae=v.normalize(se),ye=yr.resolveVirtual(Ae);return ye!==Ae?ye:null}return{VERSIONS:W,topLevel:Z,getLocator:(se,Ae)=>Array.isArray(Ae)?{name:Ae[0],reference:Ae[1]}:{name:se,reference:Ae},getDependencyTreeRoots:()=>[...r.dependencyTreeRoots],getAllLocators(){let se=[];for(let[Ae,ye]of h)for(let ge of ye.keys())Ae!==null&&ge!==null&&se.push({name:Ae,reference:ge});return se},getPackageInformation:se=>{let Ae=A(se);if(Ae===null)return null;let ye=K.fromPortablePath(Ae.packageLocation);return{...Ae,packageLocation:ye}},findPackageLocator:se=>te(K.toPortablePath(se)),resolveToUnqualified:y("resolveToUnqualified",(se,Ae,ye)=>{let ge=Ae!==null?K.toPortablePath(Ae):null,oe=N(K.toPortablePath(se),ge,ye);return oe===null?null:K.fromPortablePath(oe)}),resolveUnqualified:y("resolveUnqualified",(se,Ae)=>K.fromPortablePath(he(K.toPortablePath(se),Ae))),resolveRequest:y("resolveRequest",(se,Ae,ye)=>{let ge=Ae!==null?K.toPortablePath(Ae):null,oe=De(K.toPortablePath(se),ge,ye);return oe===null?null:K.fromPortablePath(oe)}),resolveVirtual:y("resolveVirtual",se=>{let Ae=Re(K.toPortablePath(se));return Ae!==null?K.fromPortablePath(Ae):null})}}var jBt=(0,wle.promisify)(yle.readFile);var Ble=(r,e,t)=>{let i=nE(r),n=jO(i,{basePath:e}),s=K.join(e,St.pnpCjs);return $O(n,{fakeFs:t,pnpapiResolution:s})};var tM=ve(Qle());var po={};ct(po,{checkAndReportManifestCompatibility:()=>vle,checkManifestCompatibility:()=>Sle,extractBuildScripts:()=>rQ,getExtractHint:()=>rM,hasBindingGyp:()=>iM});function Sle(r){return P.isPackageCompatible(r,ys.getArchitectureSet())}function vle(r,e,{configuration:t,report:i}){return Sle(r)?!0:(i==null||i.reportWarningOnce(76,`${P.prettyLocator(t,r)} The ${ys.getArchitectureName()} architecture is incompatible with this package, ${e} skipped.`),!1)}function rQ(r,e,t,{configuration:i,report:n}){let s=[];for(let a of["preinstall","install","postinstall"])e.manifest.scripts.has(a)&&s.push([0,a]);return!e.manifest.scripts.has("install")&&e.misc.hasBindingGyp&&s.push([1,"node-gyp rebuild"]),s.length===0?[]:r.linkType!=="HARD"?(n==null||n.reportWarningOnce(6,`${P.prettyLocator(i,r)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`),[]):t&&t.built===!1?(n==null||n.reportInfoOnce(5,`${P.prettyLocator(i,r)} lists build scripts, but its build has been explicitly disabled through configuration.`),[]):!i.get("enableScripts")&&!t.built?(n==null||n.reportWarningOnce(4,`${P.prettyLocator(i,r)} lists build scripts, but all build scripts have been disabled.`),[]):vle(r,"build",{configuration:i,report:n})?s:[]}var yze=new Set([".exe",".bin",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function rM(r){return r.packageFs.getExtractHint({relevantExtensions:yze})}function iM(r){let e=v.join(r.prefixPath,"binding.gyp");return r.packageFs.existsSync(e)}var hE={};ct(hE,{getUnpluggedPath:()=>fE});function fE(r,{configuration:e}){return v.resolve(e.get("pnpUnpluggedFolder"),P.slugifyLocator(r))}var wze=new Set([P.makeIdent(null,"open").identHash,P.makeIdent(null,"opn").identHash]),yl=class{constructor(){this.mode="strict";this.pnpCache=new Map}supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the PnP linker to be enabled");let i=wl(t.project).cjs;if(!M.existsSync(i))throw new we(`The project in ${$.pretty(t.project.configuration,`${t.project.cwd}/package.json`,$.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=me.getFactoryWithDefault(this.pnpCache,i,()=>me.dynamicRequire(i,{cachingStrategy:me.CachingStrategy.FsTime})),s={name:P.stringifyIdent(e),reference:e.reference},o=n.getPackageInformation(s);if(!o)throw new we(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed PnP map - running an install might help`);return K.toPortablePath(o.packageLocation)}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=wl(t.project).cjs;if(!M.existsSync(i))return null;let s=me.getFactoryWithDefault(this.pnpCache,i,()=>me.dynamicRequire(i,{cachingStrategy:me.CachingStrategy.FsTime})).findPackageLocator(K.fromPortablePath(e));return s?P.makeLocator(P.parseIdent(s.name),s.reference):null}makeInstaller(e){return new qu(e)}isEnabled(e){return!(e.project.configuration.get("nodeLinker")!=="pnp"||e.project.configuration.get("pnpMode")!==this.mode)}},qu=class{constructor(e){this.opts=e;this.mode="strict";this.asyncActions=new me.AsyncActions(10);this.packageRegistry=new Map;this.virtualTemplates=new Map;this.isESMLoaderRequired=!1;this.customData={store:new Map};this.unpluggedPaths=new Set;this.opts=e}getCustomDataKey(){return JSON.stringify({name:"PnpInstaller",version:2})}attachCustomData(e){this.customData=e}async installPackage(e,t,i){let n=P.stringifyIdent(e),s=e.reference,o=!!this.opts.project.tryWorkspaceByLocator(e),a=P.isVirtualLocator(e),l=e.peerDependencies.size>0&&!a,c=!l&&!o,u=!l&&e.linkType!=="SOFT",g,h;if(c||u){let x=a?P.devirtualizeLocator(e):e;g=this.customData.store.get(x.locatorHash),typeof g>"u"&&(g=await Bze(t),e.linkType==="HARD"&&this.customData.store.set(x.locatorHash,g)),g.manifest.type==="module"&&(this.isESMLoaderRequired=!0),h=this.opts.project.getDependencyMeta(x,e.version)}let p=c?rQ(e,g,h,{configuration:this.opts.project.configuration,report:this.opts.report}):[],d=u?await this.unplugPackageIfNeeded(e,g,t,h,i):t.packageFs;if(v.isAbsolute(t.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${t.prefixPath}) to be relative to the parent`);let m=v.resolve(d.getRealPath(),t.prefixPath),y=nM(this.opts.project.cwd,m),B=new Map,S=new Set;if(a){for(let x of e.peerDependencies.values())B.set(P.stringifyIdent(x),null),S.add(P.stringifyIdent(x));if(!o){let x=P.devirtualizeLocator(e);this.virtualTemplates.set(x.locatorHash,{location:nM(this.opts.project.cwd,yr.resolveVirtual(m)),locator:x})}}return me.getMapWithDefault(this.packageRegistry,n).set(s,{packageLocation:y,packageDependencies:B,packagePeers:S,linkType:e.linkType,discardFromLookup:t.discardFromLookup||!1}),{packageLocation:m,buildDirective:p.length>0?p:null}}async attachInternalDependencies(e,t){let i=this.getPackageInformation(e);for(let[n,s]of t){let o=P.areIdentsEqual(n,s)?s.reference:[P.stringifyIdent(s),s.reference];i.packageDependencies.set(P.stringifyIdent(n),o)}}async attachExternalDependents(e,t){for(let i of t)this.getDiskInformation(i).packageDependencies.set(P.stringifyIdent(e),e.reference)}async finalizeInstall(){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;let e=wl(this.opts.project);if(M.existsSync(e.cjsLegacy)&&(this.opts.report.reportWarning(0,`Removing the old ${$.pretty(this.opts.project.configuration,St.pnpJs,$.Type.PATH)} file. You might need to manually update existing references to reference the new ${$.pretty(this.opts.project.configuration,St.pnpCjs,$.Type.PATH)} file. If you use Editor SDKs, you'll have to rerun ${$.pretty(this.opts.project.configuration,"yarn sdks",$.Type.CODE)}.`),await M.removePromise(e.cjsLegacy)),this.isEsmEnabled()||await M.removePromise(e.esmLoader),this.opts.project.configuration.get("nodeLinker")!=="pnp"){await M.removePromise(e.cjs),await M.removePromise(this.opts.project.configuration.get("pnpDataPath")),await M.removePromise(e.esmLoader),await M.removePromise(this.opts.project.configuration.get("pnpUnpluggedFolder"));return}for(let{locator:u,location:g}of this.virtualTemplates.values())me.getMapWithDefault(this.packageRegistry,P.stringifyIdent(u)).set(u.reference,{packageLocation:g,packageDependencies:new Map,packagePeers:new Set,linkType:"SOFT",discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));let t=this.opts.project.configuration.get("pnpFallbackMode"),i=this.opts.project.workspaces.map(({anchoredLocator:u})=>({name:P.stringifyIdent(u),reference:u.reference})),n=t!=="none",s=[],o=new Map,a=me.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),l=this.packageRegistry,c=this.opts.project.configuration.get("pnpShebang");if(t==="dependencies-only")for(let u of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(u)&&s.push({name:P.stringifyIdent(u),reference:u.reference});return await this.asyncActions.wait(),await this.finalizeInstallWithPnp({dependencyTreeRoots:i,enableTopLevelFallback:n,fallbackExclusionList:s,fallbackPool:o,ignorePattern:a,packageRegistry:l,shebang:c}),{customData:this.customData}}async transformPnpSettings(e){}isEsmEnabled(){if(this.opts.project.configuration.sources.has("pnpEnableEsmLoader"))return this.opts.project.configuration.get("pnpEnableEsmLoader");if(this.isESMLoaderRequired)return!0;for(let e of this.opts.project.workspaces)if(e.manifest.type==="module")return!0;return!1}async finalizeInstallWithPnp(e){let t=wl(this.opts.project),i=this.opts.project.configuration.get("pnpDataPath"),n=await this.locateNodeModules(e.ignorePattern);if(n.length>0){this.opts.report.reportWarning(31,"One or more node_modules have been detected and will be removed. This operation may take some time.");for(let o of n)await M.removePromise(o)}if(await this.transformPnpSettings(e),this.opts.project.configuration.get("pnpEnableInlining")){let o=XAe(e);await M.changeFilePromise(t.cjs,o,{automaticNewlines:!0,mode:493}),await M.removePromise(i)}else{let o=v.relative(v.dirname(t.cjs),i),{dataFile:a,loaderFile:l}=ZAe({...e,dataLocation:o});await M.changeFilePromise(t.cjs,l,{automaticNewlines:!0,mode:493}),await M.changeFilePromise(i,a,{automaticNewlines:!0,mode:420})}this.isEsmEnabled()&&(this.opts.report.reportWarning(0,"ESM support for PnP uses the experimental loader API and is therefore experimental"),await M.changeFilePromise(t.esmLoader,(0,tM.default)(),{automaticNewlines:!0,mode:420}));let s=this.opts.project.configuration.get("pnpUnpluggedFolder");if(this.unpluggedPaths.size===0)await M.removePromise(s);else for(let o of await M.readdirPromise(s)){let a=v.resolve(s,o);this.unpluggedPaths.has(a)||await M.removePromise(a)}}async locateNodeModules(e){let t=[],i=e?new RegExp(e):null;for(let n of this.opts.project.workspaces){let s=v.join(n.cwd,"node_modules");if(i&&i.test(v.relative(this.opts.project.cwd,n.cwd))||!M.existsSync(s))continue;let o=await M.readdirPromise(s,{withFileTypes:!0}),a=o.filter(l=>!l.isDirectory()||l.name===".bin"||!l.name.startsWith("."));if(a.length===o.length)t.push(s);else for(let l of a)t.push(v.join(s,l.name))}return t}async unplugPackageIfNeeded(e,t,i,n,s){return this.shouldBeUnplugged(e,t,n)?this.unplugPackage(e,i,s):i.packageFs}shouldBeUnplugged(e,t,i){return typeof i.unplugged<"u"?i.unplugged:wze.has(e.identHash)||e.conditions!=null?!0:t.manifest.preferUnplugged!==null?t.manifest.preferUnplugged:!!(rQ(e,t,i,{configuration:this.opts.project.configuration}).length>0||t.misc.extractHint)}async unplugPackage(e,t,i){let n=fE(e,{configuration:this.opts.project.configuration});return this.opts.project.disabledLocators.has(e.locatorHash)?new Qo(n,{baseFs:t.packageFs,pathUtils:v}):(this.unpluggedPaths.add(n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{let s=v.join(n,t.prefixPath,".ready");await M.existsPromise(s)||(this.opts.project.storedBuildState.delete(e.locatorHash),await M.mkdirPromise(n,{recursive:!0}),await M.copyPromise(n,Te.dot,{baseFs:t.packageFs,overwrite:!1}),await M.writeFilePromise(s,""))})),new jt(n))}getPackageInformation(e){let t=P.stringifyIdent(e),i=e.reference,n=this.packageRegistry.get(t);if(!n)throw new Error(`Assertion failed: The package information store should have been available (for ${P.prettyIdent(this.opts.project.configuration,e)})`);let s=n.get(i);if(!s)throw new Error(`Assertion failed: The package information should have been available (for ${P.prettyLocator(this.opts.project.configuration,e)})`);return s}getDiskInformation(e){let t=me.getMapWithDefault(this.packageRegistry,"@@disk"),i=nM(this.opts.project.cwd,e);return me.getFactoryWithDefault(t,i,()=>({packageLocation:i,packageDependencies:new Map,packagePeers:new Set,linkType:"SOFT",discardFromLookup:!1}))}};function nM(r,e){let t=v.relative(r,e);return t.match(/^\.{0,2}\//)||(t=`./${t}`),t.replace(/\/?$/,"/")}async function Bze(r){var i;let e=(i=await ot.tryFind(r.prefixPath,{baseFs:r.packageFs}))!=null?i:new ot,t=new Set(["preinstall","install","postinstall"]);for(let n of e.scripts.keys())t.has(n)||e.scripts.delete(n);return{manifest:{scripts:e.scripts,preferUnplugged:e.preferUnplugged,type:e.type},misc:{extractHint:rM(r),hasBindingGyp:iM(r)}}}var Ple=ve(Bn());var Ju=class extends Pe{constructor(){super(...arguments);this.all=z.Boolean("-A,--all",!1,{description:"Unplug direct dependencies from the entire project"});this.recursive=z.Boolean("-R,--recursive",!1,{description:"Unplug both direct and transitive dependencies"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);if(t.get("nodeLinker")!=="pnp")throw new we("This command can only be used if the `nodeLinker` option is set to `pnp`");await i.restoreInstallState();let o=new Set(this.patterns),a=this.patterns.map(p=>{let d=P.parseDescriptor(p),m=d.range!=="unknown"?d:P.makeDescriptor(d,"*");if(!Qt.validRange(m.range))throw new we(`The range of the descriptor patterns must be a valid semver range (${P.prettyDescriptor(t,m)})`);return y=>{let B=P.stringifyIdent(y);return!Ple.default.isMatch(B,P.stringifyIdent(m))||y.version&&!Qt.satisfiesWithPrereleases(y.version,m.range)?!1:(o.delete(p),!0)}}),l=()=>{let p=[];for(let d of i.storedPackages.values())!i.tryWorkspaceByLocator(d)&&!P.isVirtualLocator(d)&&a.some(m=>m(d))&&p.push(d);return p},c=p=>{let d=new Set,m=[],y=(B,S)=>{if(d.has(B.locatorHash))return;let x=!!i.tryWorkspaceByLocator(B);if(!(S>0&&!this.recursive&&x)&&(d.add(B.locatorHash),!i.tryWorkspaceByLocator(B)&&a.some(F=>F(B))&&m.push(B),!(S>0&&!this.recursive)))for(let F of B.dependencies.values()){let H=i.storedResolutions.get(F.descriptorHash);if(!H)throw new Error("Assertion failed: The resolution should have been registered");let q=i.storedPackages.get(H);if(!q)throw new Error("Assertion failed: The package should have been registered");y(q,S+1)}};for(let B of p){let S=i.storedPackages.get(B.anchoredLocator.locatorHash);if(!S)throw new Error("Assertion failed: The package should have been registered");y(S,0)}return m},u,g;if(this.all&&this.recursive?(u=l(),g="the project"):this.all?(u=c(i.workspaces),g="any workspace"):(u=c([n]),g="this workspace"),o.size>1)throw new we(`Patterns ${$.prettyList(t,o,$.Type.CODE)} don't match any packages referenced by ${g}`);if(o.size>0)throw new we(`Pattern ${$.prettyList(t,o,$.Type.CODE)} doesn't match any packages referenced by ${g}`);return u=me.sortMap(u,p=>P.stringifyLocator(p)),(await He.start({configuration:t,stdout:this.context.stdout,json:this.json},async p=>{var d;for(let m of u){let y=(d=m.version)!=null?d:"unknown",B=i.topLevelWorkspace.manifest.ensureDependencyMeta(P.makeDescriptor(m,y));B.unplugged=!0,p.reportInfo(0,`Will unpack ${P.prettyLocator(t,m)} to ${$.pretty(t,fE(m,{configuration:t}),$.Type.PATH)}`),p.reportJson({locator:P.stringifyLocator(m),version:y})}await i.topLevelWorkspace.persistManifest(),p.reportSeparator(),await i.install({cache:s,report:p})})).exitCode()}};Ju.paths=[["unplug"]],Ju.usage=Qe.Usage({description:"force the unpacking of a list of packages",details:"\n This command will add the selectors matching the specified patterns to the list of packages that must be unplugged when installed.\n\n A package being unplugged means that instead of being referenced directly through its archive, it will be unpacked at install time in the directory configured via `pnpUnpluggedFolder`. Note that unpacking packages this way is generally not recommended because it'll make it harder to store your packages within the repository. However, it's a good approach to quickly and safely debug some packages, and can even sometimes be required depending on the context (for example when the package contains shellscripts).\n\n Running the command will set a persistent flag inside your top-level `package.json`, in the `dependenciesMeta` field. As such, to undo its effects, you'll need to revert the changes made to the manifest and run `yarn install` to apply the modification.\n\n By default, only direct dependencies from the current workspace are affected. If `-A,--all` is set, direct dependencies from the entire project are affected. Using the `-R,--recursive` flag will affect transitive dependencies as well as direct ones.\n\n This command accepts glob patterns inside the scope and name components (not the range). Make sure to escape the patterns to prevent your own shell from trying to expand them.\n ",examples:[["Unplug the lodash dependency from the active workspace","yarn unplug lodash"],["Unplug all instances of lodash referenced by any workspace","yarn unplug lodash -A"],["Unplug all instances of lodash referenced by the active workspace and its dependencies","yarn unplug lodash -R"],["Unplug all instances of lodash, anywhere","yarn unplug lodash -AR"],["Unplug one specific version of lodash","yarn unplug lodash@1.2.3"],["Unplug all packages with the `@babel` scope","yarn unplug '@babel/*'"],["Unplug all packages (only for testing, not recommended)","yarn unplug -R '*'"]]});var wl=r=>({cjs:v.join(r.cwd,St.pnpCjs),cjsLegacy:v.join(r.cwd,St.pnpJs),esmLoader:v.join(r.cwd,".pnp.loader.mjs")}),Dle=r=>/\s/.test(r)?JSON.stringify(r):r;async function bze(r,e,t){let i=wl(r),n=`--require ${Dle(K.fromPortablePath(i.cjs))}`;if(M.existsSync(i.esmLoader)&&(n=`${n} --experimental-loader ${(0,kle.pathToFileURL)(K.fromPortablePath(i.esmLoader)).href}`),i.cjs.includes(" ")&&xle.default.lt(process.versions.node,"12.0.0"))throw new Error(`Expected the build location to not include spaces when using Node < 12.0.0 (${process.versions.node})`);if(M.existsSync(i.cjs)){let s=e.NODE_OPTIONS||"",o=/\s*--require\s+\S*\.pnp\.c?js\s*/g,a=/\s*--experimental-loader\s+\S*\.pnp\.loader\.mjs\s*/;s=s.replace(o," ").replace(a," ").trim(),s=s?`${n} ${s}`:n,e.NODE_OPTIONS=s}}async function Qze(r,e){let t=wl(r);e(t.cjs),e(t.esmLoader),e(r.configuration.get("pnpDataPath")),e(r.configuration.get("pnpUnpluggedFolder"))}var Sze={hooks:{populateYarnPaths:Qze,setupScriptEnvironment:bze},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "node-modules"',type:"STRING",default:"pnp"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:"STRING",default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:"STRING",default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:"STRING",default:[],isArray:!0},pnpEnableEsmLoader:{description:"If true, Yarn will generate an ESM loader (`.pnp.loader.mjs`). If this is not explicitly set Yarn tries to automatically detect whether ESM support is required.",type:"BOOLEAN",default:!1},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:"BOOLEAN",default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:"STRING",default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:"ABSOLUTE_PATH",default:"./.yarn/unplugged"},pnpDataPath:{description:"Path of the file where the PnP data (used by the loader) must be written",type:"ABSOLUTE_PATH",default:"./.pnp.data.json"}},linkers:[yl],commands:[Ju]},vze=Sze;var Kle=ve(Lle());var gM=ve(J("crypto")),Ule=ve(J("fs")),Hle=1,kr="node_modules",iQ=".bin",jle=".yarn-state.yml",Yze=1e3;var nQ=class{constructor(){this.installStateCache=new Map}supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the node-modules linker to be enabled");let i=t.project.tryWorkspaceByLocator(e);if(i)return i.cwd;let n=await me.getFactoryWithDefault(this.installStateCache,t.project.cwd,async()=>await uM(t.project,{unrollAliases:!0}));if(n===null)throw new we("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");let s=n.locatorMap.get(P.stringifyLocator(e));if(!s){let l=new we(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw l.code="LOCATOR_NOT_INSTALLED",l}let o=s.locations.sort((l,c)=>l.split(v.sep).length-c.split(v.sep).length),a=v.join(t.project.configuration.startingCwd,kr);return o.find(l=>v.contains(a,l))||s.locations[0]}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=await me.getFactoryWithDefault(this.installStateCache,t.project.cwd,async()=>await uM(t.project,{unrollAliases:!0}));if(i===null)return null;let{locationRoot:n,segments:s}=sQ(v.resolve(e),{skipPrefix:t.project.cwd}),o=i.locationTree.get(n);if(!o)return null;let a=o.locator;for(let l of s){if(o=o.children.get(l),!o)break;a=o.locator||a}return P.parseLocator(a)}makeInstaller(e){return new cM(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="node-modules"}},cM=class{constructor(e){this.opts=e;this.localStore=new Map;this.realLocatorChecksums=new Map;this.customData={store:new Map}}getCustomDataKey(){return JSON.stringify({name:"NodeModulesInstaller",version:2})}attachCustomData(e){this.customData=e}async installPackage(e,t){var u;let i=v.resolve(t.packageFs.getRealPath(),t.prefixPath),n=this.customData.store.get(e.locatorHash);if(typeof n>"u"&&(n=await qze(e,t),e.linkType==="HARD"&&this.customData.store.set(e.locatorHash,n)),!P.isPackageCompatible(e,this.opts.project.configuration.getSupportedArchitectures()))return{packageLocation:null,buildDirective:null};let s=new Map,o=new Set;s.has(P.stringifyIdent(e))||s.set(P.stringifyIdent(e),e.reference);let a=e;if(P.isVirtualLocator(e)){a=P.devirtualizeLocator(e);for(let g of e.peerDependencies.values())s.set(P.stringifyIdent(g),null),o.add(P.stringifyIdent(g))}let l={packageLocation:`${K.fromPortablePath(i)}/`,packageDependencies:s,packagePeers:o,linkType:e.linkType,discardFromLookup:(u=t.discardFromLookup)!=null?u:!1};this.localStore.set(e.locatorHash,{pkg:e,customPackageData:n,dependencyMeta:this.opts.project.getDependencyMeta(e,e.version),pnpNode:l});let c=t.checksum?t.checksum.substring(t.checksum.indexOf("/")+1):null;return this.realLocatorChecksums.set(a.locatorHash,c),{packageLocation:i,buildDirective:null}}async attachInternalDependencies(e,t){let i=this.localStore.get(e.locatorHash);if(typeof i>"u")throw new Error("Assertion failed: Expected information object to have been registered");for(let[n,s]of t){let o=P.areIdentsEqual(n,s)?s.reference:[P.stringifyIdent(s),s.reference];i.pnpNode.packageDependencies.set(P.stringifyIdent(n),o)}}async attachExternalDependents(e,t){throw new Error("External dependencies haven't been implemented for the node-modules linker")}async finalizeInstall(){if(this.opts.project.configuration.get("nodeLinker")!=="node-modules")return;let e=new yr({baseFs:new Kn({libzip:await on(),maxOpenFiles:80,readOnlyArchives:!0})}),t=await uM(this.opts.project),i=this.opts.project.configuration.get("nmMode");(t===null||i!==t.nmMode)&&(this.opts.project.storedBuildState.clear(),t={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map,nmMode:i,mtimeMs:0});let n=new Map(this.opts.project.workspaces.map(h=>{var d,m;let p=this.opts.project.configuration.get("nmHoistingLimits");try{p=me.validateEnum(tE,(m=(d=h.manifest.installConfig)==null?void 0:d.hoistingLimits)!=null?m:p)}catch{let B=P.prettyWorkspace(this.opts.project.configuration,h);this.opts.report.reportWarning(57,`${B}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(tE).join(", ")}, using default: "${p}"`)}return[h.relativeCwd,p]})),s=new Map(this.opts.project.workspaces.map(h=>{var d,m;let p=this.opts.project.configuration.get("nmSelfReferences");return p=(m=(d=h.manifest.installConfig)==null?void 0:d.selfReferences)!=null?m:p,[h.relativeCwd,p]})),o={VERSIONS:{std:1},topLevel:{name:null,reference:null},getLocator:(h,p)=>Array.isArray(p)?{name:p[0],reference:p[1]}:{name:h,reference:p},getDependencyTreeRoots:()=>this.opts.project.workspaces.map(h=>{let p=h.anchoredLocator;return{name:P.stringifyIdent(h.locator),reference:p.reference}}),getPackageInformation:h=>{let p=h.reference===null?this.opts.project.topLevelWorkspace.anchoredLocator:P.makeLocator(P.parseIdent(h.name),h.reference),d=this.localStore.get(p.locatorHash);if(typeof d>"u")throw new Error("Assertion failed: Expected the package reference to have been registered");return d.pnpNode},findPackageLocator:h=>{let p=this.opts.project.tryWorkspaceByCwd(K.toPortablePath(h));if(p!==null){let d=p.anchoredLocator;return{name:P.stringifyIdent(d),reference:d.reference}}throw new Error("Assertion failed: Unimplemented")},resolveToUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveUnqualified:()=>{throw new Error("Assertion failed: Unimplemented")},resolveRequest:()=>{throw new Error("Assertion failed: Unimplemented")},resolveVirtual:h=>K.fromPortablePath(yr.resolveVirtual(K.toPortablePath(h)))},{tree:a,errors:l,preserveSymlinksRequired:c}=rE(o,{pnpifyFs:!1,validateExternalSoftLinks:!0,hoistingLimitsByCwd:n,project:this.opts.project,selfReferencesByCwd:s});if(!a){for(let{messageName:h,text:p}of l)this.opts.report.reportError(h,p);return}let u=UO(a);await Zze(t,u,{baseFs:e,project:this.opts.project,report:this.opts.report,realLocatorChecksums:this.realLocatorChecksums,loadManifest:async h=>{let p=P.parseLocator(h),d=this.localStore.get(p.locatorHash);if(typeof d>"u")throw new Error("Assertion failed: Expected the slot to exist");return d.customPackageData.manifest}});let g=[];for(let[h,p]of u.entries()){if(Jle(h))continue;let d=P.parseLocator(h),m=this.localStore.get(d.locatorHash);if(typeof m>"u")throw new Error("Assertion failed: Expected the slot to exist");if(this.opts.project.tryWorkspaceByLocator(m.pkg))continue;let y=po.extractBuildScripts(m.pkg,m.customPackageData,m.dependencyMeta,{configuration:this.opts.project.configuration,report:this.opts.report});y.length!==0&&g.push({buildLocations:p.locations,locatorHash:d.locatorHash,buildDirective:y})}return c&&this.opts.report.reportWarning(72,`The application uses portals and that's why ${$.pretty(this.opts.project.configuration,"--preserve-symlinks",$.Type.CODE)} Node option is required for launching it`),{customData:this.customData,records:g}}};async function qze(r,e){var n;let t=(n=await ot.tryFind(e.prefixPath,{baseFs:e.packageFs}))!=null?n:new ot,i=new Set(["preinstall","install","postinstall"]);for(let s of t.scripts.keys())i.has(s)||t.scripts.delete(s);return{manifest:{bin:t.bin,scripts:t.scripts},misc:{extractHint:po.getExtractHint(e),hasBindingGyp:po.hasBindingGyp(e)}}}async function Jze(r,e,t,i,{installChangedByUser:n}){let s="";s+=`# Warning: This file is automatically generated. Removing it is fine, but will +`,s+=`# cause your node_modules installation to become invalidated. +`,s+=` +`,s+=`__metadata: +`,s+=` version: ${Hle} +`,s+=` nmMode: ${i.value} +`;let o=Array.from(e.keys()).sort(),a=P.stringifyLocator(r.topLevelWorkspace.anchoredLocator);for(let u of o){let g=e.get(u);s+=` +`,s+=`${JSON.stringify(u)}: +`,s+=` locations: +`;for(let h of g.locations){let p=v.contains(r.cwd,h);if(p===null)throw new Error(`Assertion failed: Expected the path to be within the project (${h})`);s+=` - ${JSON.stringify(p)} +`}if(g.aliases.length>0){s+=` aliases: +`;for(let h of g.aliases)s+=` - ${JSON.stringify(h)} +`}if(u===a&&t.size>0){s+=` bin: +`;for(let[h,p]of t){let d=v.contains(r.cwd,h);if(d===null)throw new Error(`Assertion failed: Expected the path to be within the project (${h})`);s+=` ${JSON.stringify(d)}: +`;for(let[m,y]of p){let B=v.relative(v.join(h,kr),y);s+=` ${JSON.stringify(m)}: ${JSON.stringify(B)} +`}}}}let l=r.cwd,c=v.join(l,kr,jle);n&&await M.removePromise(c),await M.changeFilePromise(c,s,{automaticNewlines:!0})}async function uM(r,{unrollAliases:e=!1}={}){let t=r.cwd,i=v.join(t,kr,jle),n;try{n=await M.statPromise(i)}catch{}if(!n)return null;let s=wi(await M.readFilePromise(i,"utf8"));if(s.__metadata.version>Hle)return null;let o=s.__metadata.nmMode||"classic",a=new Map,l=new Map;delete s.__metadata;for(let[c,u]of Object.entries(s)){let g=u.locations.map(p=>v.join(t,p)),h=u.bin;if(h)for(let[p,d]of Object.entries(h)){let m=v.join(t,K.toPortablePath(p)),y=me.getMapWithDefault(l,m);for(let[B,S]of Object.entries(d))y.set(Yr(B),K.toPortablePath([m,kr,S].join(v.sep)))}if(a.set(c,{target:Te.dot,linkType:"HARD",locations:g,aliases:u.aliases||[]}),e&&u.aliases)for(let p of u.aliases){let{scope:d,name:m}=P.parseLocator(c),y=P.makeLocator(P.makeIdent(d,m),p),B=P.stringifyLocator(y);a.set(B,{target:Te.dot,linkType:"HARD",locations:g,aliases:[]})}}return{locatorMap:a,binSymlinks:l,locationTree:Gle(a,{skipPrefix:r.cwd}),nmMode:o,mtimeMs:n.mtimeMs}}var sp=async(r,e)=>{if(r.split(v.sep).indexOf(kr)<0)throw new Error(`Assertion failed: trying to remove dir that doesn't contain node_modules: ${r}`);try{if(!e.innerLoop){let i=e.allowSymlink?await M.statPromise(r):await M.lstatPromise(r);if(e.allowSymlink&&!i.isDirectory()||!e.allowSymlink&&i.isSymbolicLink()){await M.unlinkPromise(r);return}}let t=await M.readdirPromise(r,{withFileTypes:!0});for(let i of t){let n=v.join(r,Yr(i.name));i.isDirectory()?(i.name!==kr||e&&e.innerLoop)&&await sp(n,{innerLoop:!0,contentsOnly:!1}):await M.unlinkPromise(n)}e.contentsOnly||await M.rmdirPromise(r)}catch(t){if(t.code!=="ENOENT"&&t.code!=="ENOTEMPTY")throw t}},Ole=4,sQ=(r,{skipPrefix:e})=>{let t=v.contains(e,r);if(t===null)throw new Error(`Assertion failed: Writing attempt prevented to ${r} which is outside project root: ${e}`);let i=t.split(v.sep).filter(l=>l!==""),n=i.indexOf(kr),s=i.slice(0,n).join(v.sep),o=v.join(e,s),a=i.slice(n);return{locationRoot:o,segments:a}},Gle=(r,{skipPrefix:e})=>{let t=new Map;if(r===null)return t;let i=()=>({children:new Map,linkType:"HARD"});for(let[n,s]of r.entries()){if(s.linkType==="SOFT"&&v.contains(e,s.target)!==null){let a=me.getFactoryWithDefault(t,s.target,i);a.locator=n,a.linkType=s.linkType}for(let o of s.locations){let{locationRoot:a,segments:l}=sQ(o,{skipPrefix:e}),c=me.getFactoryWithDefault(t,a,i);for(let u=0;u<l.length;++u){let g=l[u];if(g!=="."){let h=me.getFactoryWithDefault(c.children,g,i);c.children.set(g,h),c=h}u===l.length-1&&(c.locator=n,c.linkType=s.linkType)}}}return t},fM=async(r,e)=>{let t;try{process.platform==="win32"&&(t=await M.lstatPromise(r))}catch{}process.platform=="win32"&&(!t||t.isDirectory())?await M.symlinkPromise(r,e,"junction"):await M.symlinkPromise(v.relative(v.dirname(e),r),e)};async function Yle(r,e,t){let i=v.join(r,Yr(`${gM.default.randomBytes(16).toString("hex")}.tmp`));try{await M.writeFilePromise(i,t);try{await M.linkPromise(i,e)}catch{}}finally{await M.unlinkPromise(i)}}async function Wze({srcPath:r,dstPath:e,entry:t,globalHardlinksStore:i,baseFs:n,nmMode:s}){if(t.kind===qle.FILE){if(s.value==="hardlinks-global"&&i&&t.digest){let a=v.join(i,t.digest.substring(0,2),`${t.digest.substring(2)}.dat`),l;try{let c=await M.statPromise(a);if(c&&(!t.mtimeMs||c.mtimeMs>t.mtimeMs||c.mtimeMs<t.mtimeMs-Yze))if(await Ai.checksumFile(a,{baseFs:M,algorithm:"sha1"})!==t.digest){let g=v.join(i,Yr(`${gM.default.randomBytes(16).toString("hex")}.tmp`));await M.renamePromise(a,g);let h=await n.readFilePromise(r);await M.writeFilePromise(g,h);try{await M.linkPromise(g,a),t.mtimeMs=new Date().getTime(),await M.unlinkPromise(g)}catch{}}else t.mtimeMs||(t.mtimeMs=Math.ceil(c.mtimeMs));await M.linkPromise(a,e),l=!0}catch{l=!1}if(!l){let c=await n.readFilePromise(r);await Yle(i,a,c),t.mtimeMs=new Date().getTime();try{await M.linkPromise(a,e)}catch(u){u&&u.code&&u.code=="EXDEV"&&(s.value="hardlinks-local",await n.copyFilePromise(r,e))}}}else await n.copyFilePromise(r,e);let o=t.mode&511;o!==420&&await M.chmodPromise(e,o)}}var qle=(i=>(i.FILE="file",i.DIRECTORY="directory",i.SYMLINK="symlink",i))(qle||{}),zze=async(r,e,{baseFs:t,globalHardlinksStore:i,nmMode:n,packageChecksum:s})=>{await M.mkdirPromise(r,{recursive:!0});let o=async(c=Te.dot)=>{let u=v.join(e,c),g=await t.readdirPromise(u,{withFileTypes:!0}),h=new Map;for(let p of g){let d=v.join(c,p.name),m,y=v.join(u,p.name);if(p.isFile()){if(m={kind:"file",mode:(await t.lstatPromise(y)).mode},n.value==="hardlinks-global"){let B=await Ai.checksumFile(y,{baseFs:t,algorithm:"sha1"});m.digest=B}}else if(p.isDirectory())m={kind:"directory"};else if(p.isSymbolicLink())m={kind:"symlink",symlinkTo:await t.readlinkPromise(y)};else throw new Error(`Unsupported file type (file: ${y}, mode: 0o${await t.statSync(y).mode.toString(8).padStart(6,"0")})`);if(h.set(d,m),p.isDirectory()&&d!==kr){let B=await o(d);for(let[S,x]of B)h.set(S,x)}}return h},a;if(n.value==="hardlinks-global"&&i&&s){let c=v.join(i,s.substring(0,2),`${s.substring(2)}.json`);try{a=new Map(Object.entries(JSON.parse(await M.readFilePromise(c,"utf8"))))}catch{a=await o()}}else a=await o();let l=!1;for(let[c,u]of a){let g=v.join(e,c),h=v.join(r,c);if(u.kind==="directory")await M.mkdirPromise(h,{recursive:!0});else if(u.kind==="file"){let p=u.mtimeMs;await Wze({srcPath:g,dstPath:h,entry:u,nmMode:n,baseFs:t,globalHardlinksStore:i}),u.mtimeMs!==p&&(l=!0)}else u.kind==="symlink"&&await fM(v.resolve(v.dirname(h),u.symlinkTo),h)}if(n.value==="hardlinks-global"&&i&&l&&s){let c=v.join(i,s.substring(0,2),`${s.substring(2)}.json`);await M.removePromise(c),await Yle(i,c,Buffer.from(JSON.stringify(Object.fromEntries(a))))}};function Vze(r,e,t,i){let n=new Map,s=new Map,o=new Map,a=!1,l=(c,u,g,h,p)=>{let d=!0,m=v.join(c,u),y=new Set;if(u===kr||u.startsWith("@")){let S;try{S=M.statSync(m)}catch{}d=!!S,S?S.mtimeMs>t?(a=!0,y=new Set(M.readdirSync(m))):y=new Set(g.children.get(u).children.keys()):a=!0;let x=e.get(c);if(x){let F=v.join(c,kr,iQ),H;try{H=M.statSync(F)}catch{}if(!H)a=!0;else if(H.mtimeMs>t){a=!0;let q=new Set(M.readdirSync(F)),_=new Map;s.set(c,_);for(let[X,W]of x)q.has(X)&&_.set(X,W)}else s.set(c,x)}}else d=p.has(u);let B=g.children.get(u);if(d){let{linkType:S,locator:x}=B,F={children:new Map,linkType:S,locator:x};if(h.children.set(u,F),x){let H=me.getSetWithDefault(o,x);H.add(m),o.set(x,H)}for(let H of B.children.keys())l(m,H,B,F,y)}else B.locator&&i.storedBuildState.delete(P.parseLocator(B.locator).locatorHash)};for(let[c,u]of r){let{linkType:g,locator:h}=u,p={children:new Map,linkType:g,locator:h};if(n.set(c,p),h){let d=me.getSetWithDefault(o,u.locator);d.add(c),o.set(u.locator,d)}u.children.has(kr)&&l(c,kr,u,p,new Set)}return{locationTree:n,binSymlinks:s,locatorLocations:o,installChangedByUser:a}}function Jle(r){let e=P.parseDescriptor(r);return P.isVirtualDescriptor(e)&&(e=P.devirtualizeDescriptor(e)),e.range.startsWith("link:")}async function Xze(r,e,t,{loadManifest:i}){let n=new Map;for(let[a,{locations:l}]of r){let c=Jle(a)?null:await i(a,l[0]),u=new Map;if(c)for(let[g,h]of c.bin){let p=v.join(l[0],h);h!==""&&M.existsSync(p)&&u.set(g,h)}n.set(a,u)}let s=new Map,o=(a,l,c)=>{let u=new Map,g=v.contains(t,a);if(c.locator&&g!==null){let h=n.get(c.locator);for(let[p,d]of h){let m=v.join(a,K.toPortablePath(d));u.set(Yr(p),m)}for(let[p,d]of c.children){let m=v.join(a,p),y=o(m,m,d);y.size>0&&s.set(a,new Map([...s.get(a)||new Map,...y]))}}else for(let[h,p]of c.children){let d=o(v.join(a,h),l,p);for(let[m,y]of d)u.set(m,y)}return u};for(let[a,l]of e){let c=o(a,a,l);c.size>0&&s.set(a,new Map([...s.get(a)||new Map,...c]))}return s}var Mle=(r,e)=>{if(!r||!e)return r===e;let t=P.parseLocator(r);P.isVirtualLocator(t)&&(t=P.devirtualizeLocator(t));let i=P.parseLocator(e);return P.isVirtualLocator(i)&&(i=P.devirtualizeLocator(i)),P.areLocatorsEqual(t,i)};function hM(r){return v.join(r.get("globalFolder"),"store")}async function Zze(r,e,{baseFs:t,project:i,report:n,loadManifest:s,realLocatorChecksums:o}){let a=v.join(i.cwd,kr),{locationTree:l,binSymlinks:c,locatorLocations:u,installChangedByUser:g}=Vze(r.locationTree,r.binSymlinks,r.mtimeMs,i),h=Gle(e,{skipPrefix:i.cwd}),p=[],d=async({srcDir:X,dstDir:W,linkType:Z,globalHardlinksStore:A,nmMode:ne,packageChecksum:ue})=>{let te=(async()=>{try{Z==="SOFT"?(await M.mkdirPromise(v.dirname(W),{recursive:!0}),await fM(v.resolve(X),W)):await zze(W,X,{baseFs:t,globalHardlinksStore:A,nmMode:ne,packageChecksum:ue})}catch(O){throw O.message=`While persisting ${X} -> ${W} ${O.message}`,O}finally{F.tick()}})().then(()=>p.splice(p.indexOf(te),1));p.push(te),p.length>Ole&&await Promise.race(p)},m=async(X,W,Z)=>{let A=(async()=>{let ne=async(ue,te,O)=>{try{O.innerLoop||await M.mkdirPromise(te,{recursive:!0});let N=await M.readdirPromise(ue,{withFileTypes:!0});for(let ce of N){if(!O.innerLoop&&ce.name===iQ)continue;let he=v.join(ue,ce.name),xe=v.join(te,ce.name);ce.isDirectory()?(ce.name!==kr||O&&O.innerLoop)&&(await M.mkdirPromise(xe,{recursive:!0}),await ne(he,xe,{...O,innerLoop:!0})):_.value==="hardlinks-local"||_.value==="hardlinks-global"?await M.linkPromise(he,xe):await M.copyFilePromise(he,xe,Ule.default.constants.COPYFILE_FICLONE)}}catch(N){throw O.innerLoop||(N.message=`While cloning ${ue} -> ${te} ${N.message}`),N}finally{O.innerLoop||F.tick()}};await ne(X,W,Z)})().then(()=>p.splice(p.indexOf(A),1));p.push(A),p.length>Ole&&await Promise.race(p)},y=async(X,W,Z)=>{if(Z)for(let[A,ne]of W.children){let ue=Z.children.get(A);await y(v.join(X,A),ne,ue)}else{W.children.has(kr)&&await sp(v.join(X,kr),{contentsOnly:!1});let A=v.basename(X)===kr&&h.has(v.join(v.dirname(X),v.sep));await sp(X,{contentsOnly:X===a,allowSymlink:A})}};for(let[X,W]of l){let Z=h.get(X);for(let[A,ne]of W.children){if(A===".")continue;let ue=Z&&Z.children.get(A),te=v.join(X,A);await y(te,ne,ue)}}let B=async(X,W,Z)=>{if(Z){Mle(W.locator,Z.locator)||await sp(X,{contentsOnly:W.linkType==="HARD"});for(let[A,ne]of W.children){let ue=Z.children.get(A);await B(v.join(X,A),ne,ue)}}else{W.children.has(kr)&&await sp(v.join(X,kr),{contentsOnly:!0});let A=v.basename(X)===kr&&h.has(v.join(v.dirname(X),v.sep));await sp(X,{contentsOnly:W.linkType==="HARD",allowSymlink:A})}};for(let[X,W]of h){let Z=l.get(X);for(let[A,ne]of W.children){if(A===".")continue;let ue=Z&&Z.children.get(A);await B(v.join(X,A),ne,ue)}}let S=new Map,x=[];for(let[X,W]of u)for(let Z of W){let{locationRoot:A,segments:ne}=sQ(Z,{skipPrefix:i.cwd}),ue=h.get(A),te=A;if(ue){for(let O of ne)if(te=v.join(te,O),ue=ue.children.get(O),!ue)break;if(ue){let O=Mle(ue.locator,X),N=e.get(ue.locator),ce=N.target,he=te,xe=N.linkType;if(O)S.has(ce)||S.set(ce,he);else if(ce!==he){let De=P.parseLocator(ue.locator);P.isVirtualLocator(De)&&(De=P.devirtualizeLocator(De)),x.push({srcDir:ce,dstDir:he,linkType:xe,realLocatorHash:De.locatorHash})}}}}for(let[X,{locations:W}]of e.entries())for(let Z of W){let{locationRoot:A,segments:ne}=sQ(Z,{skipPrefix:i.cwd}),ue=l.get(A),te=h.get(A),O=A,N=e.get(X),ce=P.parseLocator(X);P.isVirtualLocator(ce)&&(ce=P.devirtualizeLocator(ce));let he=ce.locatorHash,xe=N.target,De=Z;if(xe===De)continue;let Re=N.linkType;for(let se of ne)te=te.children.get(se);if(!ue)x.push({srcDir:xe,dstDir:De,linkType:Re,realLocatorHash:he});else for(let se of ne)if(O=v.join(O,se),ue=ue.children.get(se),!ue){x.push({srcDir:xe,dstDir:De,linkType:Re,realLocatorHash:he});break}}let F=Pi.progressViaCounter(x.length),H=n.reportProgress(F),q=i.configuration.get("nmMode"),_={value:q};try{let X=_.value==="hardlinks-global"?`${hM(i.configuration)}/v1`:null;if(X&&!await M.existsPromise(X)){await M.mkdirpPromise(X);for(let Z=0;Z<256;Z++)await M.mkdirPromise(v.join(X,Z.toString(16).padStart(2,"0")))}for(let Z of x)(Z.linkType==="SOFT"||!S.has(Z.srcDir))&&(S.set(Z.srcDir,Z.dstDir),await d({...Z,globalHardlinksStore:X,nmMode:_,packageChecksum:o.get(Z.realLocatorHash)||null}));await Promise.all(p),p.length=0;for(let Z of x){let A=S.get(Z.srcDir);Z.linkType!=="SOFT"&&Z.dstDir!==A&&await m(A,Z.dstDir,{nmMode:_})}await Promise.all(p),await M.mkdirPromise(a,{recursive:!0});let W=await Xze(e,h,i.cwd,{loadManifest:s});await _ze(c,W,i.cwd),await Jze(i,e,W,_,{installChangedByUser:g}),q=="hardlinks-global"&&_.value=="hardlinks-local"&&n.reportWarningOnce(74,"'nmMode' has been downgraded to 'hardlinks-local' due to global cache and install folder being on different devices")}finally{H.stop()}}async function _ze(r,e,t){for(let i of r.keys()){if(v.contains(t,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);if(!e.has(i)){let n=v.join(i,kr,iQ);await M.removePromise(n)}}for(let[i,n]of e){if(v.contains(t,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);let s=v.join(i,kr,iQ),o=r.get(i)||new Map;await M.mkdirPromise(s,{recursive:!0});for(let a of o.keys())n.has(a)||(await M.removePromise(v.join(s,a)),process.platform==="win32"&&await M.removePromise(v.join(s,Yr(`${a}.cmd`))));for(let[a,l]of n){let c=o.get(a),u=v.join(s,a);c!==l&&(process.platform==="win32"?await(0,Kle.default)(K.fromPortablePath(l),K.fromPortablePath(u),{createPwshFile:!1}):(await M.removePromise(u),await fM(l,u),v.contains(t,await M.realpathPromise(l))!==null&&await M.chmodPromise(l,493)))}}}var oQ=class extends yl{constructor(){super(...arguments);this.mode="loose"}makeInstaller(t){return new pM(t)}},pM=class extends qu{constructor(){super(...arguments);this.mode="loose"}async transformPnpSettings(t){let i=new yr({baseFs:new Kn({libzip:await on(),maxOpenFiles:80,readOnlyArchives:!0})}),n=Ble(t,this.opts.project.cwd,i),{tree:s,errors:o}=rE(n,{pnpifyFs:!1,project:this.opts.project});if(!s){for(let{messageName:g,text:h}of o)this.opts.report.reportError(g,h);return}let a=new Map;t.fallbackPool=a;let l=(g,h)=>{let p=P.parseLocator(h.locator),d=P.stringifyIdent(p);d===g?a.set(g,p.reference):a.set(g,[d,p.reference])},c=v.join(this.opts.project.cwd,St.nodeModules),u=s.get(c);if(!(typeof u>"u")){if("target"in u)throw new Error("Assertion failed: Expected the root junction point to be a directory");for(let g of u.dirList){let h=v.join(c,g),p=s.get(h);if(typeof p>"u")throw new Error("Assertion failed: Expected the child to have been registered");if("target"in p)l(g,p);else for(let d of p.dirList){let m=v.join(h,d),y=s.get(m);if(typeof y>"u")throw new Error("Assertion failed: Expected the subchild to have been registered");if("target"in y)l(`${g}/${d}`,y);else throw new Error("Assertion failed: Expected the leaf junction to be a package")}}}}};var $ze={hooks:{cleanGlobalArtifacts:async r=>{let e=hM(r);await M.removePromise(e)}},configuration:{nmHoistingLimits:{description:"Prevent packages to be hoisted past specific levels",type:"STRING",values:["workspaces","dependencies","none"],default:"none"},nmMode:{description:'If set to "hardlinks-local" Yarn will utilize hardlinks to reduce disk space consumption inside "node_modules" directories. With "hardlinks-global" Yarn will use global content addressable storage to reduce "node_modules" size across all the projects using this option.',type:"STRING",values:["classic","hardlinks-local","hardlinks-global"],default:"classic"},nmSelfReferences:{description:"If set to 'false' the workspace will not be allowed to require itself and corresponding self-referencing symlink will not be created",type:"BOOLEAN",default:!0}},linkers:[nQ,oQ]},e5e=$ze;var f1={};ct(f1,{default:()=>AVe,npmConfigUtils:()=>nr,npmHttpUtils:()=>Pt,npmPublishUtils:()=>Cp});var _le=ve(zr());var cr="npm:";var Pt={};ct(Pt,{AuthType:()=>Zle,customPackageError:()=>r5e,del:()=>s5e,get:()=>mo,getIdentUrl:()=>bl,handleInvalidAuthenticationError:()=>Bl,post:()=>i5e,put:()=>n5e});var EM=ve(Um()),Xle=J("url");var nr={};ct(nr,{RegistryType:()=>Wle,getAuditRegistry:()=>t5e,getAuthConfiguration:()=>mM,getDefaultRegistry:()=>aQ,getPublishRegistry:()=>zle,getRegistryConfiguration:()=>Vle,getScopeConfiguration:()=>CM,getScopeRegistry:()=>fA,normalizeRegistry:()=>Co});var Wle=(i=>(i.AUDIT_REGISTRY="npmAuditRegistry",i.FETCH_REGISTRY="npmRegistryServer",i.PUBLISH_REGISTRY="npmPublishRegistry",i))(Wle||{});function Co(r){return r.replace(/\/$/,"")}function t5e(r,{configuration:e}){let t=e.get("npmAuditRegistry");return t!==null?Co(t):zle(r,{configuration:e})}function zle(r,{configuration:e}){var t;return(t=r.publishConfig)!=null&&t.registry?Co(r.publishConfig.registry):r.name?fA(r.name.scope,{configuration:e,type:"npmPublishRegistry"}):aQ({configuration:e,type:"npmPublishRegistry"})}function fA(r,{configuration:e,type:t="npmRegistryServer"}){let i=CM(r,{configuration:e});if(i===null)return aQ({configuration:e,type:t});let n=i.get(t);return n===null?aQ({configuration:e,type:t}):Co(n)}function aQ({configuration:r,type:e="npmRegistryServer"}){let t=r.get(e);return Co(t!==null?t:r.get("npmRegistryServer"))}function Vle(r,{configuration:e}){let t=e.get("npmRegistries"),i=Co(r),n=t.get(i);if(typeof n<"u")return n;let s=t.get(i.replace(/^[a-z]+:/,""));return typeof s<"u"?s:null}function CM(r,{configuration:e}){if(r===null)return null;let i=e.get("npmScopes").get(r);return i||null}function mM(r,{configuration:e,ident:t}){let i=t&&CM(t.scope,{configuration:e});return(i==null?void 0:i.get("npmAuthIdent"))||(i==null?void 0:i.get("npmAuthToken"))?i:Vle(r,{configuration:e})||e}var Zle=(n=>(n[n.NO_AUTH=0]="NO_AUTH",n[n.BEST_EFFORT=1]="BEST_EFFORT",n[n.CONFIGURATION=2]="CONFIGURATION",n[n.ALWAYS_AUTH=3]="ALWAYS_AUTH",n))(Zle||{});async function Bl(r,{attemptedAs:e,registry:t,headers:i,configuration:n}){var s,o;if(lQ(r))throw new rt(41,"Invalid OTP token");if(((s=r.originalError)==null?void 0:s.name)==="HTTPError"&&((o=r.originalError)==null?void 0:o.response.statusCode)===401)throw new rt(41,`Invalid authentication (${typeof e!="string"?`as ${await a5e(t,i,{configuration:n})}`:`attempted as ${e}`})`)}function r5e(r){var e;return((e=r.response)==null?void 0:e.statusCode)===404?"Package not found":null}function bl(r){return r.scope?`/@${r.scope}%2f${r.name}`:`/${r.name}`}async function mo(r,{configuration:e,headers:t,ident:i,authType:n,registry:s,...o}){if(i&&typeof s>"u"&&(s=fA(i.scope,{configuration:e})),i&&i.scope&&typeof n>"u"&&(n=1),typeof s!="string")throw new Error("Assertion failed: The registry should be a string");let a=await AQ(s,{authType:n,configuration:e,ident:i});a&&(t={...t,authorization:a});try{return await Vt.get(r.charAt(0)==="/"?`${s}${r}`:r,{configuration:e,headers:t,...o})}catch(l){throw await Bl(l,{registry:s,configuration:e,headers:t}),l}}async function i5e(r,e,{attemptedAs:t,configuration:i,headers:n,ident:s,authType:o=3,registry:a,otp:l,...c}){if(s&&typeof a>"u"&&(a=fA(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let u=await AQ(a,{authType:o,configuration:i,ident:s});u&&(n={...n,authorization:u}),l&&(n={...n,...op(l)});try{return await Vt.post(a+r,e,{configuration:i,headers:n,...c})}catch(g){if(!lQ(g)||l)throw await Bl(g,{attemptedAs:t,registry:a,configuration:i,headers:n}),g;l=await IM(g,{configuration:i});let h={...n,...op(l)};try{return await Vt.post(`${a}${r}`,e,{configuration:i,headers:h,...c})}catch(p){throw await Bl(p,{attemptedAs:t,registry:a,configuration:i,headers:n}),p}}}async function n5e(r,e,{attemptedAs:t,configuration:i,headers:n,ident:s,authType:o=3,registry:a,otp:l,...c}){if(s&&typeof a>"u"&&(a=fA(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let u=await AQ(a,{authType:o,configuration:i,ident:s});u&&(n={...n,authorization:u}),l&&(n={...n,...op(l)});try{return await Vt.put(a+r,e,{configuration:i,headers:n,...c})}catch(g){if(!lQ(g))throw await Bl(g,{attemptedAs:t,registry:a,configuration:i,headers:n}),g;l=await IM(g,{configuration:i});let h={...n,...op(l)};try{return await Vt.put(`${a}${r}`,e,{configuration:i,headers:h,...c})}catch(p){throw await Bl(p,{attemptedAs:t,registry:a,configuration:i,headers:n}),p}}}async function s5e(r,{attemptedAs:e,configuration:t,headers:i,ident:n,authType:s=3,registry:o,otp:a,...l}){if(n&&typeof o>"u"&&(o=fA(n.scope,{configuration:t})),typeof o!="string")throw new Error("Assertion failed: The registry should be a string");let c=await AQ(o,{authType:s,configuration:t,ident:n});c&&(i={...i,authorization:c}),a&&(i={...i,...op(a)});try{return await Vt.del(o+r,{configuration:t,headers:i,...l})}catch(u){if(!lQ(u)||a)throw await Bl(u,{attemptedAs:e,registry:o,configuration:t,headers:i}),u;a=await IM(u,{configuration:t});let g={...i,...op(a)};try{return await Vt.del(`${o}${r}`,{configuration:t,headers:g,...l})}catch(h){throw await Bl(h,{attemptedAs:e,registry:o,configuration:t,headers:i}),h}}}async function AQ(r,{authType:e=2,configuration:t,ident:i}){let n=mM(r,{configuration:t,ident:i}),s=o5e(n,e);if(!s)return null;let o=await t.reduceHook(a=>a.getNpmAuthenticationHeader,void 0,r,{configuration:t,ident:i});if(o)return o;if(n.get("npmAuthToken"))return`Bearer ${n.get("npmAuthToken")}`;if(n.get("npmAuthIdent")){let a=n.get("npmAuthIdent");return a.includes(":")?`Basic ${Buffer.from(a).toString("base64")}`:`Basic ${a}`}if(s&&e!==1)throw new rt(33,"No authentication configured for request");return null}function o5e(r,e){switch(e){case 2:return r.get("npmAlwaysAuth");case 1:case 3:return!0;case 0:return!1;default:throw new Error("Unreachable")}}async function a5e(r,e,{configuration:t}){var i;if(typeof e>"u"||typeof e.authorization>"u")return"an anonymous user";try{return(i=(await Vt.get(new Xle.URL(`${r}/-/whoami`).href,{configuration:t,headers:e,jsonResponse:!0})).username)!=null?i:"an unknown user"}catch{return"an unknown user"}}async function IM(r,{configuration:e}){var n;let t=(n=r.originalError)==null?void 0:n.response.headers["npm-notice"];if(t&&(await He.start({configuration:e,stdout:process.stdout,includeFooter:!1},async s=>{if(s.reportInfo(0,t.replace(/(https?:\/\/\S+)/g,$.pretty(e,"$1",$.Type.URL))),!process.env.YARN_IS_TEST_ENV){let o=t.match(/open (https?:\/\/\S+)/i);if(o&&ys.openUrl){let{openNow:a}=await(0,EM.prompt)({type:"confirm",name:"openNow",message:"Do you want to try to open this url now?",required:!0,initial:!0,onCancel:()=>process.exit(130)});a&&(await ys.openUrl(o[1])||(s.reportSeparator(),s.reportWarning(0,"We failed to automatically open the url; you'll have to open it yourself in your browser of choice.")))}}}),process.stdout.write(` +`)),process.env.YARN_IS_TEST_ENV)return process.env.YARN_INJECT_NPM_2FA_TOKEN||"";let{otp:i}=await(0,EM.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return process.stdout.write(` +`),i}function lQ(r){var e,t;if(((e=r.originalError)==null?void 0:e.name)!=="HTTPError")return!1;try{return((t=r.originalError)==null?void 0:t.response.headers["www-authenticate"].split(/,\s*/).map(n=>n.toLowerCase())).includes("otp")}catch{return!1}}function op(r){return{["npm-otp"]:r}}var cQ=class{supports(e,t){if(!e.reference.startsWith(cr))return!1;let{selector:i,params:n}=P.parseRange(e.reference);return!(!_le.default.valid(i)||n===null||typeof n.__archiveUrl!="string")}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let{params:i}=P.parseRange(e.reference);if(i===null||typeof i.__archiveUrl!="string")throw new Error("Assertion failed: The archiveUrl querystring parameter should have been available");let n=await mo(i.__archiveUrl,{configuration:t.project.configuration,ident:e});return await Ci.convertToZip(n,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}};var uQ=class{supportsDescriptor(e,t){return!(!e.range.startsWith(cr)||!P.tryParseDescriptor(e.range.slice(cr.length),!0))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){let i=P.parseDescriptor(e.range.slice(cr.length),!0);return t.resolver.getResolutionDependencies(i,t)}async getCandidates(e,t,i){let n=P.parseDescriptor(e.range.slice(cr.length),!0);return await i.resolver.getCandidates(n,t,i)}async getSatisfying(e,t,i){let n=P.parseDescriptor(e.range.slice(cr.length),!0);return i.resolver.getSatisfying(n,t,i)}resolve(e,t){throw new Error("Unreachable")}};var $le=ve(zr()),ece=J("url");var Ts=class{supports(e,t){if(!e.reference.startsWith(cr))return!1;let i=new ece.URL(e.reference);return!(!$le.default.valid(i.pathname)||i.searchParams.has("__archiveUrl"))}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote registry`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i;try{i=await mo(Ts.getLocatorUrl(e),{configuration:t.project.configuration,ident:e})}catch{i=await mo(Ts.getLocatorUrl(e).replace(/%2f/g,"/"),{configuration:t.project.configuration,ident:e})}return await Ci.convertToZip(i,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,t,{configuration:i}){let n=fA(e.scope,{configuration:i}),s=Ts.getLocatorUrl(e);return t=t.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),n=n.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),t=t.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),t===n+s||t===n+s.replace(/%2f/g,"/")}static getLocatorUrl(e){let t=Qt.clean(e.reference.slice(cr.length));if(t===null)throw new rt(10,"The npm semver resolver got selected, but the version isn't semver");return`${bl(e)}/-/${e.name}-${t}.tgz`}};var tce=ve(zr());var gQ=P.makeIdent(null,"node-gyp"),A5e=/\b(node-gyp|prebuild-install)\b/,fQ=class{supportsDescriptor(e,t){return e.range.startsWith(cr)?!!Qt.validRange(e.range.slice(cr.length)):!1}supportsLocator(e,t){if(!e.reference.startsWith(cr))return!1;let{selector:i}=P.parseRange(e.reference);return!!tce.default.valid(i)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=Qt.validRange(e.range.slice(cr.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(cr.length)}`);let s=await mo(bl(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0}),o=me.mapAndFilter(Object.keys(s.versions),c=>{try{let u=new Qt.SemVer(c);if(n.test(u))return u}catch{}return me.mapAndFilter.skip}),a=o.filter(c=>!s.versions[c.raw].deprecated),l=a.length>0?a:o;return l.sort((c,u)=>-c.compare(u)),l.map(c=>{let u=P.makeLocator(e,`${cr}${c.raw}`),g=s.versions[c.raw].dist.tarball;return Ts.isConventionalTarballUrl(u,g,{configuration:i.project.configuration})?u:P.bindLocator(u,{__archiveUrl:g})})}async getSatisfying(e,t,i){let n=Qt.validRange(e.range.slice(cr.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(cr.length)}`);return me.mapAndFilter(t,s=>{try{let{selector:o}=P.parseRange(s,{requireProtocol:cr}),a=new Qt.SemVer(o);if(n.test(a))return{reference:s,version:a}}catch{}return me.mapAndFilter.skip}).sort((s,o)=>-s.version.compare(o.version)).map(({reference:s})=>P.makeLocator(e,s))}async resolve(e,t){let{selector:i}=P.parseRange(e.reference),n=Qt.clean(i);if(n===null)throw new rt(10,"The npm semver resolver got selected, but the version isn't semver");let s=await mo(bl(e),{configuration:t.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"versions"))throw new rt(15,'Registry returned invalid data for - missing "versions" field');if(!Object.prototype.hasOwnProperty.call(s.versions,n))throw new rt(16,`Registry failed to return reference "${n}"`);let o=new ot;if(o.load(s.versions[n]),!o.dependencies.has(gQ.identHash)&&!o.peerDependencies.has(gQ.identHash)){for(let a of o.scripts.values())if(a.match(A5e)){o.dependencies.set(gQ.identHash,P.makeDescriptor(gQ,"latest")),t.report.reportWarningOnce(32,`${P.prettyLocator(t.project.configuration,e)}: Implicit dependencies on node-gyp are discouraged`);break}}if(typeof o.raw.deprecated=="string"&&o.raw.deprecated!==""){let a=P.prettyLocator(t.project.configuration,e),l=o.raw.deprecated.match(/\S/)?`${a} is deprecated: ${o.raw.deprecated}`:`${a} is deprecated`;t.report.reportWarningOnce(61,l)}return{...e,version:n,languageName:"node",linkType:"HARD",conditions:o.getConditions(),dependencies:o.dependencies,peerDependencies:o.peerDependencies,dependenciesMeta:o.dependenciesMeta,peerDependenciesMeta:o.peerDependenciesMeta,bin:o.bin}}};var hQ=class{supportsDescriptor(e,t){return!(!e.range.startsWith(cr)||!Rf.test(e.range.slice(cr.length)))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(cr.length),s=await mo(bl(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"dist-tags"))throw new rt(15,'Registry returned invalid data - missing "dist-tags" field');let o=s["dist-tags"];if(!Object.prototype.hasOwnProperty.call(o,n))throw new rt(16,`Registry failed to return tag "${n}"`);let a=o[n],l=P.makeLocator(e,`${cr}${a}`),c=s.versions[a].dist.tarball;return Ts.isConventionalTarballUrl(l,c,{configuration:i.project.configuration})?[l]:[P.bindLocator(l,{__archiveUrl:c})]}async getSatisfying(e,t,i){return null}async resolve(e,t){throw new Error("Unreachable")}};var Cp={};ct(Cp,{getGitHead:()=>oVe,getPublishAccess:()=>que,getReadmeContent:()=>Jue,makePublishBody:()=>sVe});var A1={};ct(A1,{default:()=>H9e,packUtils:()=>Aa});var Aa={};ct(Aa,{genPackList:()=>OQ,genPackStream:()=>a1,genPackageManifest:()=>Rue,hasPackScripts:()=>s1,prepareForPack:()=>o1});var n1=ve(Bn()),kue=ve(Sue()),Due=J("zlib"),k9e=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],D9e=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function s1(r){return!!(Yt.hasWorkspaceScript(r,"prepack")||Yt.hasWorkspaceScript(r,"postpack"))}async function o1(r,{report:e},t){await Yt.maybeExecuteWorkspaceLifecycleScript(r,"prepack",{report:e});try{let i=v.join(r.cwd,ot.fileName);await M.existsPromise(i)&&await r.manifest.loadFile(i,{baseFs:M}),await t()}finally{await Yt.maybeExecuteWorkspaceLifecycleScript(r,"postpack",{report:e})}}async function a1(r,e){var s,o;typeof e>"u"&&(e=await OQ(r));let t=new Set;for(let a of(o=(s=r.manifest.publishConfig)==null?void 0:s.executableFiles)!=null?o:new Set)t.add(v.normalize(a));for(let a of r.manifest.bin.values())t.add(v.normalize(a));let i=kue.default.pack();process.nextTick(async()=>{for(let a of e){let l=v.normalize(a),c=v.resolve(r.cwd,l),u=v.join("package",l),g=await M.lstatPromise(c),h={name:u,mtime:new Date(vr.SAFE_TIME*1e3)},p=t.has(l)?493:420,d,m,y=new Promise((S,x)=>{d=S,m=x}),B=S=>{S?m(S):d()};if(g.isFile()){let S;l==="package.json"?S=Buffer.from(JSON.stringify(await Rue(r),null,2)):S=await M.readFilePromise(c),i.entry({...h,mode:p,type:"file"},S,B)}else g.isSymbolicLink()?i.entry({...h,mode:p,type:"symlink",linkname:await M.readlinkPromise(c)},B):B(new Error(`Unsupported file type ${g.mode} for ${K.fromPortablePath(l)}`));await y}i.finalize()});let n=(0,Due.createGzip)();return i.pipe(n),n}async function Rue(r){let e=JSON.parse(JSON.stringify(r.manifest.raw));return await r.project.configuration.triggerHook(t=>t.beforeWorkspacePacking,r,e),e}async function OQ(r){var g,h,p,d,m,y,B,S;let e=r.project,t=e.configuration,i={accept:[],reject:[]};for(let x of D9e)i.reject.push(x);for(let x of k9e)i.accept.push(x);i.reject.push(t.get("rcFilename"));let n=x=>{if(x===null||!x.startsWith(`${r.cwd}/`))return;let F=v.relative(r.cwd,x),H=v.resolve(Te.root,F);i.reject.push(H)};n(v.resolve(e.cwd,t.get("lockfileFilename"))),n(t.get("cacheFolder")),n(t.get("globalFolder")),n(t.get("installStatePath")),n(t.get("virtualFolder")),n(t.get("yarnPath")),await t.triggerHook(x=>x.populateYarnPaths,e,x=>{n(x)});for(let x of e.workspaces){let F=v.relative(r.cwd,x.cwd);F!==""&&!F.match(/^(\.\.)?\//)&&i.reject.push(`/${F}`)}let s={accept:[],reject:[]},o=(h=(g=r.manifest.publishConfig)==null?void 0:g.main)!=null?h:r.manifest.main,a=(d=(p=r.manifest.publishConfig)==null?void 0:p.module)!=null?d:r.manifest.module,l=(y=(m=r.manifest.publishConfig)==null?void 0:m.browser)!=null?y:r.manifest.browser,c=(S=(B=r.manifest.publishConfig)==null?void 0:B.bin)!=null?S:r.manifest.bin;o!=null&&s.accept.push(v.resolve(Te.root,o)),a!=null&&s.accept.push(v.resolve(Te.root,a)),typeof l=="string"&&s.accept.push(v.resolve(Te.root,l));for(let x of c.values())s.accept.push(v.resolve(Te.root,x));if(l instanceof Map)for(let[x,F]of l.entries())s.accept.push(v.resolve(Te.root,x)),typeof F=="string"&&s.accept.push(v.resolve(Te.root,F));let u=r.manifest.files!==null;if(u){s.reject.push("/*");for(let x of r.manifest.files)Fue(s.accept,x,{cwd:Te.root})}return await R9e(r.cwd,{hasExplicitFileList:u,globalList:i,ignoreList:s})}async function R9e(r,{hasExplicitFileList:e,globalList:t,ignoreList:i}){let n=[],s=new So(r),o=[[Te.root,[i]]];for(;o.length>0;){let[a,l]=o.pop(),c=await s.lstatPromise(a);if(!Pue(a,{globalList:t,ignoreLists:c.isDirectory()?null:l}))if(c.isDirectory()){let u=await s.readdirPromise(a),g=!1,h=!1;if(!e||a!==Te.root)for(let m of u)g=g||m===".gitignore",h=h||m===".npmignore";let p=h?await vue(s,a,".npmignore"):g?await vue(s,a,".gitignore"):null,d=p!==null?[p].concat(l):l;Pue(a,{globalList:t,ignoreLists:l})&&(d=[...l,{accept:[],reject:["**/*"]}]);for(let m of u)o.push([v.resolve(a,m),d])}else(c.isFile()||c.isSymbolicLink())&&n.push(v.relative(Te.root,a))}return n.sort()}async function vue(r,e,t){let i={accept:[],reject:[]},n=await r.readFilePromise(v.join(e,t),"utf8");for(let s of n.split(/\n/g))Fue(i.reject,s,{cwd:e});return i}function F9e(r,{cwd:e}){let t=r[0]==="!";return t&&(r=r.slice(1)),r.match(/\.{0,1}\//)&&(r=v.resolve(e,r)),t&&(r=`!${r}`),r}function Fue(r,e,{cwd:t}){let i=e.trim();i===""||i[0]==="#"||r.push(F9e(i,{cwd:t}))}function Pue(r,{globalList:e,ignoreLists:t}){let i=LQ(r,e.accept);if(i!==0)return i===2;let n=LQ(r,e.reject);if(n!==0)return n===1;if(t!==null)for(let s of t){let o=LQ(r,s.accept);if(o!==0)return o===2;let a=LQ(r,s.reject);if(a!==0)return a===1}return!1}function LQ(r,e){let t=e,i=[];for(let n=0;n<e.length;++n)e[n][0]!=="!"?t!==e&&t.push(e[n]):(t===e&&(t=e.slice(0,n)),i.push(e[n].slice(1)));return xue(r,i)?2:xue(r,t)?1:0}function xue(r,e){let t=e,i=[];for(let n=0;n<e.length;++n)e[n].includes("/")?t!==e&&t.push(e[n]):(t===e&&(t=e.slice(0,n)),i.push(e[n]));return!!(n1.default.isMatch(r,t,{dot:!0,nocase:!0})||n1.default.isMatch(r,i,{dot:!0,basename:!0,nocase:!0}))}var Zu=class extends Pe{constructor(){super(...arguments);this.installIfNeeded=z.Boolean("--install-if-needed",!1,{description:"Run a preliminary `yarn install` if the package contains build scripts"});this.dryRun=z.Boolean("-n,--dry-run",!1,{description:"Print the file paths without actually generating the package archive"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.out=z.String("-o,--out",{description:"Create the archive at the specified path"});this.filename=z.String("--filename",{hidden:!0})}async execute(){var l;let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);await s1(n)&&(this.installIfNeeded?await i.install({cache:await Dt.find(t),report:new $r}):await i.restoreInstallState());let s=(l=this.out)!=null?l:this.filename,o=typeof s<"u"?v.resolve(this.context.cwd,N9e(s,{workspace:n})):v.resolve(n.cwd,"package.tgz");return(await He.start({configuration:t,stdout:this.context.stdout,json:this.json},async c=>{await o1(n,{report:c},async()=>{c.reportJson({base:K.fromPortablePath(n.cwd)});let u=await OQ(n);for(let g of u)c.reportInfo(null,K.fromPortablePath(g)),c.reportJson({location:K.fromPortablePath(g)});if(!this.dryRun){let g=await a1(n,u),h=M.createWriteStream(o);g.pipe(h),await new Promise(p=>{h.on("finish",p)})}}),this.dryRun||(c.reportInfo(0,`Package archive generated in ${$.pretty(t,o,$.Type.PATH)}`),c.reportJson({output:K.fromPortablePath(o)}))})).exitCode()}};Zu.paths=[["pack"]],Zu.usage=Qe.Usage({description:"generate a tarball from the active workspace",details:"\n This command will turn the active workspace into a compressed archive suitable for publishing. The archive will by default be stored at the root of the workspace (`package.tgz`).\n\n If the `-o,---out` is set the archive will be created at the specified path. The `%s` and `%v` variables can be used within the path and will be respectively replaced by the package name and version.\n ",examples:[["Create an archive from the active workspace","yarn pack"],["List the files that would be made part of the workspace's archive","yarn pack --dry-run"],["Name and output the archive in a dedicated folder","yarn pack --out /artifacts/%s-%v.tgz"]]});function N9e(r,{workspace:e}){let t=r.replace("%s",T9e(e)).replace("%v",L9e(e));return K.toPortablePath(t)}function T9e(r){return r.manifest.name!==null?P.slugifyIdent(r.manifest.name):"package"}function L9e(r){return r.manifest.version!==null?r.manifest.version:"unknown"}var O9e=["dependencies","devDependencies","peerDependencies"],M9e="workspace:",K9e=(r,e)=>{var i,n;e.publishConfig&&(e.publishConfig.type&&(e.type=e.publishConfig.type),e.publishConfig.main&&(e.main=e.publishConfig.main),e.publishConfig.browser&&(e.browser=e.publishConfig.browser),e.publishConfig.module&&(e.module=e.publishConfig.module),e.publishConfig.exports&&(e.exports=e.publishConfig.exports),e.publishConfig.imports&&(e.imports=e.publishConfig.imports),e.publishConfig.bin&&(e.bin=e.publishConfig.bin));let t=r.project;for(let s of O9e)for(let o of r.manifest.getForScope(s).values()){let a=t.tryWorkspaceByDescriptor(o),l=P.parseRange(o.range);if(l.protocol===M9e)if(a===null){if(t.tryWorkspaceByIdent(o)===null)throw new rt(21,`${P.prettyDescriptor(t.configuration,o)}: No local workspace found for this range`)}else{let c;P.areDescriptorsEqual(o,a.anchoredDescriptor)||l.selector==="*"?c=(i=a.manifest.version)!=null?i:"0.0.0":l.selector==="~"||l.selector==="^"?c=`${l.selector}${(n=a.manifest.version)!=null?n:"0.0.0"}`:c=l.selector;let u=s==="dependencies"?P.makeDescriptor(o,"unknown"):null,g=u!==null&&r.manifest.ensureDependencyMeta(u).optional?"optionalDependencies":s;e[g][P.stringifyIdent(o)]=c}}},U9e={hooks:{beforeWorkspacePacking:K9e},commands:[Zu]},H9e=U9e;var jue=J("crypto"),Gue=ve(Hue()),Yue=J("url");async function sVe(r,e,{access:t,tag:i,registry:n,gitHead:s}){let o=r.manifest.name,a=r.manifest.version,l=P.stringifyIdent(o),c=(0,jue.createHash)("sha1").update(e).digest("hex"),u=Gue.default.fromData(e).toString(),g=t!=null?t:que(r,o),h=await Jue(r),p=await Aa.genPackageManifest(r),d=`${l}-${a}.tgz`,m=new Yue.URL(`${Co(n)}/${l}/-/${d}`);return{_id:l,_attachments:{[d]:{content_type:"application/octet-stream",data:e.toString("base64"),length:e.length}},name:l,access:g,["dist-tags"]:{[i]:a},versions:{[a]:{...p,_id:`${l}@${a}`,name:l,version:a,gitHead:s,dist:{shasum:c,integrity:u,tarball:m.toString()}}},readme:h}}async function oVe(r){try{let{stdout:e}=await pr.execvp("git",["rev-parse","--revs-only","HEAD"],{cwd:r});return e.trim()===""?void 0:e.trim()}catch{return}}function que(r,e){let t=r.project.configuration;return r.manifest.publishConfig&&typeof r.manifest.publishConfig.access=="string"?r.manifest.publishConfig.access:t.get("npmPublishAccess")!==null?t.get("npmPublishAccess"):e.scope?"restricted":"public"}async function Jue(r){let e=K.toPortablePath(`${r.cwd}/README.md`),t=r.manifest.name,n=`# ${P.stringifyIdent(t)} +`;try{n=await M.readFilePromise(e,"utf8")}catch(s){if(s.code==="ENOENT")return n;throw s}return n}var g1={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:"BOOLEAN",default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:"SECRET",default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:"SECRET",default:null}},Wue={npmAuditRegistry:{description:"Registry to query for audit reports",type:"STRING",default:null},npmPublishRegistry:{description:"Registry to push packages to",type:"STRING",default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:"STRING",default:"https://registry.yarnpkg.com"}},aVe={configuration:{...g1,...Wue,npmScopes:{description:"Settings per package scope",type:"MAP",valueDefinition:{description:"",type:"SHAPE",properties:{...g1,...Wue}}},npmRegistries:{description:"Settings per registry",type:"MAP",normalizeKeys:Co,valueDefinition:{description:"",type:"SHAPE",properties:{...g1}}}},fetchers:[cQ,Ts],resolvers:[uQ,fQ,hQ]},AVe=aVe;var C1={};ct(C1,{default:()=>EVe});var DE=ve(Bn());As();var MQ=(i=>(i.All="all",i.Production="production",i.Development="development",i))(MQ||{}),KQ=(s=>(s.Info="info",s.Low="low",s.Moderate="moderate",s.High="high",s.Critical="critical",s))(KQ||{});var kE=["info","low","moderate","high","critical"];function Vue(r,e){let t=[],i=new Set,n=o=>{i.has(o)||(i.add(o),t.push(o))};for(let o of e)n(o);let s=new Set;for(;t.length>0;){let o=t.shift(),a=r.storedResolutions.get(o);if(typeof a>"u")throw new Error("Assertion failed: Expected the resolution to have been registered");let l=r.storedPackages.get(a);if(!!l){s.add(o);for(let c of l.dependencies.values())n(c.descriptorHash)}}return s}function lVe(r,e){return new Set([...r].filter(t=>!e.has(t)))}function cVe(r,e,{all:t}){let i=t?r.workspaces:[e],n=i.map(h=>h.manifest),s=new Set(n.map(h=>[...h.dependencies].map(([p,d])=>p)).flat()),o=new Set(n.map(h=>[...h.devDependencies].map(([p,d])=>p)).flat()),a=i.map(h=>[...h.dependencies.values()]).flat(),l=a.filter(h=>s.has(h.identHash)).map(h=>h.descriptorHash),c=a.filter(h=>o.has(h.identHash)).map(h=>h.descriptorHash),u=Vue(r,l),g=Vue(r,c);return lVe(g,u)}function Xue(r){let e={};for(let t of r)e[P.stringifyIdent(t)]=P.parseRange(t.range).selector;return e}function Zue(r){if(typeof r>"u")return new Set(kE);let e=kE.indexOf(r),t=kE.slice(e);return new Set(t)}function uVe(r,e){let t=Zue(e),i={};for(let n of t)i[n]=r[n];return i}function _ue(r,e){var i;let t=uVe(r,e);for(let n of Object.keys(t))if((i=t[n])!=null?i:0>0)return!0;return!1}function $ue(r,e){var s;let t={},i={children:t},n=Object.values(r.advisories);if(e!=null){let o=Zue(e);n=n.filter(a=>o.has(a.severity))}for(let o of me.sortMap(n,a=>a.module_name))t[o.module_name]={label:o.module_name,value:$.tuple($.Type.RANGE,o.findings.map(a=>a.version).join(", ")),children:{ID:{label:"ID",value:$.tuple($.Type.NUMBER,o.id)},Issue:{label:"Issue",value:$.tuple($.Type.NO_HINT,o.title)},URL:{label:"URL",value:$.tuple($.Type.URL,o.url)},Severity:{label:"Severity",value:$.tuple($.Type.NO_HINT,o.severity)},["Vulnerable Versions"]:{label:"Vulnerable Versions",value:$.tuple($.Type.RANGE,o.vulnerable_versions)},["Patched Versions"]:{label:"Patched Versions",value:$.tuple($.Type.RANGE,o.patched_versions)},Via:{label:"Via",value:$.tuple($.Type.NO_HINT,Array.from(new Set(o.findings.map(a=>a.paths).flat().map(a=>a.split(">")[0]))).join(", "))},Recommendation:{label:"Recommendation",value:$.tuple($.Type.NO_HINT,(s=o.recommendation)==null?void 0:s.replace(/\n/g," "))}}};return i}function ege(r,e,{all:t,environment:i}){let n=t?r.workspaces:[e],s=["all","production"].includes(i),o=[];if(s)for(let c of n)for(let u of c.manifest.dependencies.values())o.push(u);let a=["all","development"].includes(i),l=[];if(a)for(let c of n)for(let u of c.manifest.devDependencies.values())l.push(u);return Xue([...o,...l].filter(c=>P.parseRange(c.range).protocol===null))}function tge(r,e,{all:t}){var s;let i=cVe(r,e,{all:t}),n={};for(let o of r.storedPackages.values())n[P.stringifyIdent(o)]={version:(s=o.version)!=null?s:"0.0.0",integrity:o.identHash,requires:Xue(o.dependencies.values()),dev:i.has(P.convertLocatorToDescriptor(o).descriptorHash)};return n}var eg=class extends Pe{constructor(){super(...arguments);this.all=z.Boolean("-A,--all",!1,{description:"Audit dependencies from all workspaces"});this.recursive=z.Boolean("-R,--recursive",!1,{description:"Audit transitive dependencies as well"});this.environment=z.String("--environment","all",{description:"Which environments to cover",validator:Xi(MQ)});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.severity=z.String("--severity","info",{description:"Minimal severity requested for packages to be displayed",validator:Xi(KQ)});this.excludes=z.Array("--exclude",[],{description:"Array of glob patterns of packages to exclude from audit"});this.ignores=z.Array("--ignore",[],{description:"Array of glob patterns of advisory ID's to ignore in the audit report"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState();let s=ege(i,n,{all:this.all,environment:this.environment}),o=tge(i,n,{all:this.all});if(!this.recursive)for(let d of Object.keys(o))Object.prototype.hasOwnProperty.call(s,d)?o[d].requires={}:delete o[d];let a=Array.from(new Set([...t.get("npmAuditExcludePackages"),...this.excludes]));if(a){for(let d of Object.keys(s))DE.default.isMatch(d,a)&&delete s[d];for(let d of Object.keys(o))DE.default.isMatch(d,a)&&delete o[d];for(let d of Object.keys(o))for(let m of Object.keys(o[d].requires))DE.default.isMatch(m,a)&&delete o[d].requires[m]}let l={requires:s,dependencies:o},c=nr.getAuditRegistry(n.manifest,{configuration:t}),u,g=await ta.start({configuration:t,stdout:this.context.stdout},async()=>{u=await Pt.post("/-/npm/v1/security/audits/quick",l,{authType:Pt.AuthType.BEST_EFFORT,configuration:t,jsonResponse:!0,registry:c})});if(g.hasErrors())return g.exitCode();let h=Array.from(new Set([...t.get("npmAuditIgnoreAdvisories"),...this.ignores]));if(h){for(let d of Object.keys(u.advisories))if(DE.default.isMatch(d,h)){let m=u.advisories[d],y=0;m.findings.forEach(B=>y+=B.paths.length),u.metadata.vulnerabilities[m.severity]-=y,delete u.advisories[d]}}let p=_ue(u.metadata.vulnerabilities,this.severity);return!this.json&&p?(es.emitTree($ue(u,this.severity),{configuration:t,json:this.json,stdout:this.context.stdout,separators:2}),1):(await He.start({configuration:t,includeFooter:!1,json:this.json,stdout:this.context.stdout},async d=>{d.reportJson(u),p||d.reportInfo(1,"No audit suggestions")}),p?1:0)}};eg.paths=[["npm","audit"]],eg.usage=Qe.Usage({description:"perform a vulnerability audit against the installed packages",details:` + This command checks for known security reports on the packages you use. The reports are by default extracted from the npm registry, and may or may not be relevant to your actual program (not all vulnerabilities affect all code paths). + + For consistency with our other commands the default is to only check the direct dependencies for the active workspace. To extend this search to all workspaces, use \`-A,--all\`. To extend this search to both direct and transitive dependencies, use \`-R,--recursive\`. + + Applying the \`--severity\` flag will limit the audit table to vulnerabilities of the corresponding severity and above. Valid values are ${kE.map(t=>`\`${t}\``).join(", ")}. + + If the \`--json\` flag is set, Yarn will print the output exactly as received from the registry. Regardless of this flag, the process will exit with a non-zero exit code if a report is found for the selected packages. + + If certain packages produce false positives for a particular environment, the \`--exclude\` flag can be used to exclude any number of packages from the audit. This can also be set in the configuration file with the \`npmAuditExcludePackages\` option. + + If particular advisories are needed to be ignored, the \`--ignore\` flag can be used with Advisory ID's to ignore any number of advisories in the audit report. This can also be set in the configuration file with the \`npmAuditIgnoreAdvisories\` option. + + To understand the dependency tree requiring vulnerable packages, check the raw report with the \`--json\` flag or use \`yarn why <package>\` to get more information as to who depends on them. + `,examples:[["Checks for known security issues with the installed packages. The output is a list of known issues.","yarn npm audit"],["Audit dependencies in all workspaces","yarn npm audit --all"],["Limit auditing to `dependencies` (excludes `devDependencies`)","yarn npm audit --environment production"],["Show audit report as valid JSON","yarn npm audit --json"],["Audit all direct and transitive dependencies","yarn npm audit --recursive"],["Output moderate (or more severe) vulnerabilities","yarn npm audit --severity moderate"],["Exclude certain packages","yarn npm audit --exclude package1 --exclude package2"],["Ignore specific advisories","yarn npm audit --ignore 1234567 --ignore 7654321"]]});var h1=ve(zr()),p1=J("util"),tg=class extends Pe{constructor(){super(...arguments);this.fields=z.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"});this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.packages=z.Rest()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i}=await Ge.find(t,this.context.cwd),n=typeof this.fields<"u"?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,s=[],o=!1,a=await He.start({configuration:t,includeFooter:!1,json:this.json,stdout:this.context.stdout},async l=>{for(let c of this.packages){let u;if(c==="."){let F=i.topLevelWorkspace;if(!F.manifest.name)throw new we(`Missing ${$.pretty(t,"name",$.Type.CODE)} field in ${K.fromPortablePath(v.join(F.cwd,St.manifest))}`);u=P.makeDescriptor(F.manifest.name,"unknown")}else u=P.parseDescriptor(c);let g=Pt.getIdentUrl(u),h=d1(await Pt.get(g,{configuration:t,ident:u,jsonResponse:!0,customErrorMessage:Pt.customPackageError})),p=Object.keys(h.versions).sort(h1.default.compareLoose),m=h["dist-tags"].latest||p[p.length-1],y=Qt.validRange(u.range);if(y){let F=h1.default.maxSatisfying(p,y);F!==null?m=F:(l.reportWarning(0,`Unmet range ${P.prettyRange(t,u.range)}; falling back to the latest version`),o=!0)}else Object.prototype.hasOwnProperty.call(h["dist-tags"],u.range)?m=h["dist-tags"][u.range]:u.range!=="unknown"&&(l.reportWarning(0,`Unknown tag ${P.prettyRange(t,u.range)}; falling back to the latest version`),o=!0);let B=h.versions[m],S={...h,...B,version:m,versions:p},x;if(n!==null){x={};for(let F of n){let H=S[F];if(typeof H<"u")x[F]=H;else{l.reportWarning(1,`The ${$.pretty(t,F,$.Type.CODE)} field doesn't exist inside ${P.prettyIdent(t,u)}'s information`),o=!0;continue}}}else this.json||(delete S.dist,delete S.readme,delete S.users),x=S;l.reportJson(x),this.json||s.push(x)}});p1.inspect.styles.name="cyan";for(let l of s)(l!==s[0]||o)&&this.context.stdout.write(` +`),this.context.stdout.write(`${(0,p1.inspect)(l,{depth:1/0,colors:!0,compact:!1})} +`);return a.exitCode()}};tg.paths=[["npm","info"]],tg.usage=Qe.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command fetches information about a package from the npm registry and prints it in a tree format.\n\n The package does not have to be installed locally, but needs to have been published (in particular, local changes will be ignored even for workspaces).\n\n Append `@<range>` to the package argument to provide information specific to the latest version that satisfies the range or to the corresponding tagged version. If the range is invalid or if there is no version satisfying the range, the command will print a warning and fall back to the latest version.\n\n If the `-f,--fields` option is set, it's a comma-separated list of fields which will be used to only display part of the package information.\n\n By default, this command won't return the `dist`, `readme`, and `users` fields, since they are often very long. To explicitly request those fields, explicitly list them with the `--fields` flag or request the output in JSON mode.\n ",examples:[["Show all available information about react (except the `dist`, `readme`, and `users` fields)","yarn npm info react"],["Show all available information about react as valid JSON (including the `dist`, `readme`, and `users` fields)","yarn npm info react --json"],["Show all available information about react@16.12.0","yarn npm info react@16.12.0"],["Show all available information about react@next","yarn npm info react@next"],["Show the description of react","yarn npm info react --fields description"],["Show all available versions of react","yarn npm info react --fields versions"],["Show the readme of react","yarn npm info react --fields readme"],["Show a few fields of react","yarn npm info react --fields homepage,repository"]]});function d1(r){if(Array.isArray(r)){let e=[];for(let t of r)t=d1(t),t&&e.push(t);return e}else if(typeof r=="object"&&r!==null){let e={};for(let t of Object.keys(r)){if(t.startsWith("_"))continue;let i=d1(r[t]);i&&(e[t]=i)}return e}else return r||null}var rge=ve(Um()),rg=class extends Pe{constructor(){super(...arguments);this.scope=z.String("-s,--scope",{description:"Login to the registry configured for a given scope"});this.publish=z.Boolean("--publish",!1,{description:"Login to the publish registry"});this.alwaysAuth=z.Boolean("--always-auth",{description:"Set the npmAlwaysAuth configuration"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=await UQ({configuration:t,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await He.start({configuration:t,stdout:this.context.stdout,includeFooter:!1},async s=>{let o=await pVe({configuration:t,registry:i,report:s,stdin:this.context.stdin,stdout:this.context.stdout}),a=await fVe(i,o,t);return await hVe(i,a,{alwaysAuth:this.alwaysAuth,scope:this.scope}),s.reportInfo(0,"Successfully logged in")})).exitCode()}};rg.paths=[["npm","login"]],rg.usage=Qe.Usage({category:"Npm-related commands",description:"store new login info to access the npm registry",details:"\n This command will ask you for your username, password, and 2FA One-Time-Password (when it applies). It will then modify your local configuration (in your home folder, never in the project itself) to reference the new tokens thus generated.\n\n Adding the `-s,--scope` flag will cause the authentication to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the authentication to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n ",examples:[["Login to the default registry","yarn npm login"],["Login to the registry linked to the @my-scope registry","yarn npm login --scope my-scope"],["Login to the publish registry for the current package","yarn npm login --publish"]]});async function UQ({scope:r,publish:e,configuration:t,cwd:i}){return r&&e?nr.getScopeRegistry(r,{configuration:t,type:nr.RegistryType.PUBLISH_REGISTRY}):r?nr.getScopeRegistry(r,{configuration:t}):e?nr.getPublishRegistry((await Hh(t,i)).manifest,{configuration:t}):nr.getDefaultRegistry({configuration:t})}async function fVe(r,e,t){var u,g;let i=`/-/user/org.couchdb.user:${encodeURIComponent(e.name)}`,n={_id:`org.couchdb.user:${e.name}`,name:e.name,password:e.password,type:"user",roles:[],date:new Date().toISOString()},s={attemptedAs:e.name,configuration:t,registry:r,jsonResponse:!0,authType:Pt.AuthType.NO_AUTH};try{return(await Pt.put(i,n,s)).token}catch(h){if(!(((u=h.originalError)==null?void 0:u.name)==="HTTPError"&&((g=h.originalError)==null?void 0:g.response.statusCode)===409))throw h}let o={...s,authType:Pt.AuthType.NO_AUTH,headers:{authorization:`Basic ${Buffer.from(`${e.name}:${e.password}`).toString("base64")}`}},a=await Pt.get(i,o);for(let[h,p]of Object.entries(a))(!n[h]||h==="roles")&&(n[h]=p);let l=`${i}/-rev/${n._rev}`;return(await Pt.put(l,n,o)).token}async function hVe(r,e,{alwaysAuth:t,scope:i}){let n=o=>a=>{let l=me.isIndexableObject(a)?a:{},c=l[o],u=me.isIndexableObject(c)?c:{};return{...l,[o]:{...u,...t!==void 0?{npmAlwaysAuth:t}:{},npmAuthToken:e}}},s=i?{npmScopes:n(i)}:{npmRegistries:n(r)};return await Ee.updateHomeConfiguration(s)}async function pVe({configuration:r,registry:e,report:t,stdin:i,stdout:n}){t.reportInfo(0,`Logging in to ${$.pretty(r,e,$.Type.URL)}`);let s=!1;if(e.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(t.reportInfo(0,"You seem to be using the GitHub Package Registry. Tokens must be generated with the 'repo', 'write:packages', and 'read:packages' permissions."),s=!0),t.reportSeparator(),process.env.YARN_IS_TEST_ENV)return{name:process.env.YARN_INJECT_NPM_USER||"",password:process.env.YARN_INJECT_NPM_PASSWORD||""};let o=await(0,rge.prompt)([{type:"input",name:"name",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:i,stdout:n},{type:"password",name:"password",message:s?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:i,stdout:n}]);return t.reportSeparator(),o}var mp=new Set(["npmAuthIdent","npmAuthToken"]),ig=class extends Pe{constructor(){super(...arguments);this.scope=z.String("-s,--scope",{description:"Logout of the registry configured for a given scope"});this.publish=z.Boolean("--publish",!1,{description:"Logout of the publish registry"});this.all=z.Boolean("-A,--all",!1,{description:"Logout of all registries"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i=async()=>{var c;let s=await UQ({configuration:t,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),o=await Ee.find(this.context.cwd,this.context.plugins),a=P.makeIdent((c=this.scope)!=null?c:null,"pkg");return!nr.getAuthConfiguration(s,{configuration:o,ident:a}).get("npmAuthToken")};return(await He.start({configuration:t,stdout:this.context.stdout},async s=>{if(this.all&&(await CVe(),s.reportInfo(0,"Successfully logged out from everything")),this.scope){await ige("npmScopes",this.scope),await i()?s.reportInfo(0,`Successfully logged out from ${this.scope}`):s.reportWarning(0,"Scope authentication settings removed, but some other ones settings still apply to it");return}let o=await UQ({configuration:t,cwd:this.context.cwd,publish:this.publish});await ige("npmRegistries",o),await i()?s.reportInfo(0,`Successfully logged out from ${o}`):s.reportWarning(0,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}};ig.paths=[["npm","logout"]],ig.usage=Qe.Usage({category:"Npm-related commands",description:"logout of the npm registry",details:"\n This command will log you out by modifying your local configuration (in your home folder, never in the project itself) to delete all credentials linked to a registry.\n\n Adding the `-s,--scope` flag will cause the deletion to be done against whatever registry is configured for the associated scope (see also `npmScopes`).\n\n Adding the `--publish` flag will cause the deletion to be done against the registry used when publishing the package (see also `publishConfig.registry` and `npmPublishRegistry`).\n\n Adding the `-A,--all` flag will cause the deletion to be done against all registries and scopes.\n ",examples:[["Logout of the default registry","yarn npm logout"],["Logout of the @my-scope scope","yarn npm logout --scope my-scope"],["Logout of the publish registry for the current package","yarn npm logout --publish"],["Logout of all registries","yarn npm logout --all"]]});function dVe(r,e){let t=r[e];if(!me.isIndexableObject(t))return!1;let i=new Set(Object.keys(t));if([...mp].every(s=>!i.has(s)))return!1;for(let s of mp)i.delete(s);if(i.size===0)return r[e]=void 0,!0;let n={...t};for(let s of mp)delete n[s];return r[e]=n,!0}async function CVe(){let r=e=>{let t=!1,i=me.isIndexableObject(e)?{...e}:{};i.npmAuthToken&&(delete i.npmAuthToken,t=!0);for(let n of Object.keys(i))dVe(i,n)&&(t=!0);if(Object.keys(i).length!==0)return t?i:e};return await Ee.updateHomeConfiguration({npmRegistries:r,npmScopes:r})}async function ige(r,e){return await Ee.updateHomeConfiguration({[r]:t=>{let i=me.isIndexableObject(t)?t:{};if(!Object.prototype.hasOwnProperty.call(i,e))return t;let n=i[e],s=me.isIndexableObject(n)?n:{},o=new Set(Object.keys(s));if([...mp].every(l=>!o.has(l)))return t;for(let l of mp)o.delete(l);if(o.size===0)return Object.keys(i).length===1?void 0:{...i,[e]:void 0};let a={};for(let l of mp)a[l]=void 0;return{...i,[e]:{...s,...a}}}})}var ng=class extends Pe{constructor(){super(...arguments);this.access=z.String("--access",{description:"The access for the published package (public or restricted)"});this.tag=z.String("--tag","latest",{description:"The tag on the registry that the package should be attached to"});this.tolerateRepublish=z.Boolean("--tolerate-republish",!1,{description:"Warn and exit when republishing an already existing version of a package"});this.otp=z.String("--otp",{description:"The OTP token to use with the command"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);if(n.manifest.private)throw new we("Private workspaces cannot be published");if(n.manifest.name===null||n.manifest.version===null)throw new we("Workspaces must have valid names and versions to be published on an external registry");await i.restoreInstallState();let s=n.manifest.name,o=n.manifest.version,a=nr.getPublishRegistry(n.manifest,{configuration:t});return(await He.start({configuration:t,stdout:this.context.stdout},async c=>{var u,g;if(this.tolerateRepublish)try{let h=await Pt.get(Pt.getIdentUrl(s),{configuration:t,registry:a,ident:s,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(h,"versions"))throw new rt(15,'Registry returned invalid data for - missing "versions" field');if(Object.prototype.hasOwnProperty.call(h.versions,o)){c.reportWarning(0,`Registry already knows about version ${o}; skipping.`);return}}catch(h){if(((g=(u=h.originalError)==null?void 0:u.response)==null?void 0:g.statusCode)!==404)throw h}await Yt.maybeExecuteWorkspaceLifecycleScript(n,"prepublish",{report:c}),await Aa.prepareForPack(n,{report:c},async()=>{let h=await Aa.genPackList(n);for(let B of h)c.reportInfo(null,B);let p=await Aa.genPackStream(n,h),d=await me.bufferStream(p),m=await Cp.getGitHead(n.cwd),y=await Cp.makePublishBody(n,d,{access:this.access,tag:this.tag,registry:a,gitHead:m});await Pt.put(Pt.getIdentUrl(s),y,{configuration:t,registry:a,ident:s,otp:this.otp,jsonResponse:!0})}),c.reportInfo(0,"Package archive published")})).exitCode()}};ng.paths=[["npm","publish"]],ng.usage=Qe.Usage({category:"Npm-related commands",description:"publish the active workspace to the npm registry",details:'\n This command will pack the active workspace into a fresh archive and upload it to the npm registry.\n\n The package will by default be attached to the `latest` tag on the registry, but this behavior can be overriden by using the `--tag` option.\n\n Note that for legacy reasons scoped packages are by default published with an access set to `restricted` (aka "private packages"). This requires you to register for a paid npm plan. In case you simply wish to publish a public scoped package to the registry (for free), just add the `--access public` flag. This behavior can be enabled by default through the `npmPublishAccess` settings.\n ',examples:[["Publish the active workspace","yarn npm publish"]]});var nge=ve(zr());var sg=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=z.String({required:!1})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s;if(typeof this.package<"u")s=P.parseIdent(this.package);else{if(!n)throw new lt(i.cwd,this.context.cwd);if(!n.manifest.name)throw new we(`Missing 'name' field in ${K.fromPortablePath(v.join(n.cwd,St.manifest))}`);s=n.manifest.name}let o=await RE(s,t),l={children:me.sortMap(Object.entries(o),([c])=>c).map(([c,u])=>({value:$.tuple($.Type.RESOLUTION,{descriptor:P.makeDescriptor(s,c),locator:P.makeLocator(s,u)})}))};return es.emitTree(l,{configuration:t,json:this.json,stdout:this.context.stdout})}};sg.paths=[["npm","tag","list"]],sg.usage=Qe.Usage({category:"Npm-related commands",description:"list all dist-tags of a package",details:` + This command will list all tags of a package from the npm registry. + + If the package is not specified, Yarn will default to the current workspace. + `,examples:[["List all tags of package `my-pkg`","yarn npm tag list my-pkg"]]});async function RE(r,e){let t=`/-/package${Pt.getIdentUrl(r)}/dist-tags`;return Pt.get(t,{configuration:e,ident:r,jsonResponse:!0,customErrorMessage:Pt.customPackageError})}var og=class extends Pe{constructor(){super(...arguments);this.package=z.String();this.tag=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);let s=P.parseDescriptor(this.package,!0),o=s.range;if(!nge.default.valid(o))throw new we(`The range ${$.pretty(t,s.range,$.Type.RANGE)} must be a valid semver version`);let a=nr.getPublishRegistry(n.manifest,{configuration:t}),l=$.pretty(t,s,$.Type.IDENT),c=$.pretty(t,o,$.Type.RANGE),u=$.pretty(t,this.tag,$.Type.CODE);return(await He.start({configuration:t,stdout:this.context.stdout},async h=>{let p=await RE(s,t);Object.prototype.hasOwnProperty.call(p,this.tag)&&p[this.tag]===o&&h.reportWarning(0,`Tag ${u} is already set to version ${c}`);let d=`/-/package${Pt.getIdentUrl(s)}/dist-tags/${encodeURIComponent(this.tag)}`;await Pt.put(d,o,{configuration:t,registry:a,ident:s,jsonRequest:!0,jsonResponse:!0}),h.reportInfo(0,`Tag ${u} added to version ${c} of package ${l}`)})).exitCode()}};og.paths=[["npm","tag","add"]],og.usage=Qe.Usage({category:"Npm-related commands",description:"add a tag for a specific version of a package",details:` + This command will add a tag to the npm registry for a specific version of a package. If the tag already exists, it will be overwritten. + `,examples:[["Add a `beta` tag for version `2.3.4-beta.4` of package `my-pkg`","yarn npm tag add my-pkg@2.3.4-beta.4 beta"]]});var ag=class extends Pe{constructor(){super(...arguments);this.package=z.String();this.tag=z.String()}async execute(){if(this.tag==="latest")throw new we("The 'latest' tag cannot be removed.");let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);let s=P.parseIdent(this.package),o=nr.getPublishRegistry(n.manifest,{configuration:t}),a=$.pretty(t,this.tag,$.Type.CODE),l=$.pretty(t,s,$.Type.IDENT),c=await RE(s,t);if(!Object.prototype.hasOwnProperty.call(c,this.tag))throw new we(`${a} is not a tag of package ${l}`);return(await He.start({configuration:t,stdout:this.context.stdout},async g=>{let h=`/-/package${Pt.getIdentUrl(s)}/dist-tags/${encodeURIComponent(this.tag)}`;await Pt.del(h,{configuration:t,registry:o,ident:s,jsonResponse:!0}),g.reportInfo(0,`Tag ${a} removed from package ${l}`)})).exitCode()}};ag.paths=[["npm","tag","remove"]],ag.usage=Qe.Usage({category:"Npm-related commands",description:"remove a tag from a package",details:` + This command will remove a tag from a package from the npm registry. + `,examples:[["Remove the `beta` tag from package `my-pkg`","yarn npm tag remove my-pkg beta"]]});var Ag=class extends Pe{constructor(){super(...arguments);this.scope=z.String("-s,--scope",{description:"Print username for the registry configured for a given scope"});this.publish=z.Boolean("--publish",!1,{description:"Print username for the publish registry"})}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),i;return this.scope&&this.publish?i=nr.getScopeRegistry(this.scope,{configuration:t,type:nr.RegistryType.PUBLISH_REGISTRY}):this.scope?i=nr.getScopeRegistry(this.scope,{configuration:t}):this.publish?i=nr.getPublishRegistry((await Hh(t,this.context.cwd)).manifest,{configuration:t}):i=nr.getDefaultRegistry({configuration:t}),(await He.start({configuration:t,stdout:this.context.stdout},async s=>{var a,l;let o;try{o=await Pt.get("/-/whoami",{configuration:t,registry:i,authType:Pt.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?P.makeIdent(this.scope,""):void 0})}catch(c){if(((a=c.response)==null?void 0:a.statusCode)===401||((l=c.response)==null?void 0:l.statusCode)===403){s.reportError(41,"Authentication failed - your credentials may have expired");return}else throw c}s.reportInfo(0,o.username)})).exitCode()}};Ag.paths=[["npm","whoami"]],Ag.usage=Qe.Usage({category:"Npm-related commands",description:"display the name of the authenticated user",details:"\n Print the username associated with the current authentication settings to the standard output.\n\n When using `-s,--scope`, the username printed will be the one that matches the authentication settings of the registry associated with the given scope (those settings can be overriden using the `npmRegistries` map, and the registry associated with the scope is configured via the `npmScopes` map).\n\n When using `--publish`, the registry we'll select will by default be the one used when publishing packages (`publishConfig.registry` or `npmPublishRegistry` if available, otherwise we'll fallback to the regular `npmRegistryServer`).\n ",examples:[["Print username for the default registry","yarn npm whoami"],["Print username for the registry on a given scope","yarn npm whoami --scope company"]]});var mVe={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:"STRING",default:null},npmAuditExcludePackages:{description:"Array of glob patterns of packages to exclude from npm audit",type:"STRING",default:[],isArray:!0},npmAuditIgnoreAdvisories:{description:"Array of glob patterns of advisory IDs to exclude from npm audit",type:"STRING",default:[],isArray:!0}},commands:[eg,tg,rg,ig,ng,og,sg,ag,Ag]},EVe=mVe;var S1={};ct(S1,{default:()=>TVe,patchUtils:()=>lg});var lg={};ct(lg,{applyPatchFile:()=>jQ,diffFolders:()=>b1,ensureUnpatchedDescriptor:()=>E1,extractPackageToDisk:()=>B1,extractPatchFlags:()=>uge,isParentRequired:()=>w1,loadPatchFiles:()=>LE,makeDescriptor:()=>I1,makeLocator:()=>y1,makePatchHash:()=>Q1,parseDescriptor:()=>NE,parseLocator:()=>TE,parsePatchFile:()=>FE});var IVe=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function Ep(r){return v.relative(Te.root,v.resolve(Te.root,K.toPortablePath(r)))}function yVe(r){let e=r.trim().match(IVe);if(!e)throw new Error(`Bad header line: '${r}'`);return{original:{start:Math.max(Number(e[1]),1),length:Number(e[3]||1)},patched:{start:Math.max(Number(e[4]),1),length:Number(e[6]||1)}}}var wVe=420,BVe=493;var sge=()=>({semverExclusivity:null,diffLineFromPath:null,diffLineToPath:null,oldMode:null,newMode:null,deletedFileMode:null,newFileMode:null,renameFrom:null,renameTo:null,beforeHash:null,afterHash:null,fromPath:null,toPath:null,hunks:null}),bVe=r=>({header:yVe(r),parts:[]}),QVe={["@"]:"header",["-"]:"deletion",["+"]:"insertion",[" "]:"context",["\\"]:"pragma",undefined:"context"};function SVe(r){let e=[],t=sge(),i="parsing header",n=null,s=null;function o(){n&&(s&&(n.parts.push(s),s=null),t.hunks.push(n),n=null)}function a(){o(),e.push(t),t=sge()}for(let l=0;l<r.length;l++){let c=r[l];if(i==="parsing header")if(c.startsWith("@@"))i="parsing hunks",t.hunks=[],l-=1;else if(c.startsWith("diff --git ")){t&&t.diffLineFromPath&&a();let u=c.match(/^diff --git a\/(.*?) b\/(.*?)\s*$/);if(!u)throw new Error(`Bad diff line: ${c}`);t.diffLineFromPath=u[1],t.diffLineToPath=u[2]}else if(c.startsWith("old mode "))t.oldMode=c.slice(9).trim();else if(c.startsWith("new mode "))t.newMode=c.slice(9).trim();else if(c.startsWith("deleted file mode "))t.deletedFileMode=c.slice(18).trim();else if(c.startsWith("new file mode "))t.newFileMode=c.slice(14).trim();else if(c.startsWith("rename from "))t.renameFrom=c.slice(12).trim();else if(c.startsWith("rename to "))t.renameTo=c.slice(10).trim();else if(c.startsWith("index ")){let u=c.match(/(\w+)\.\.(\w+)/);if(!u)continue;t.beforeHash=u[1],t.afterHash=u[2]}else c.startsWith("semver exclusivity ")?t.semverExclusivity=c.slice(19).trim():c.startsWith("--- ")?t.fromPath=c.slice(6).trim():c.startsWith("+++ ")&&(t.toPath=c.slice(6).trim());else{let u=QVe[c[0]]||null;switch(u){case"header":o(),n=bVe(c);break;case null:i="parsing header",a(),l-=1;break;case"pragma":{if(!c.startsWith("\\ No newline at end of file"))throw new Error(`Unrecognized pragma in patch file: ${c}`);if(!s)throw new Error("Bad parser state: No newline at EOF pragma encountered without context");s.noNewlineAtEndOfFile=!0}break;case"context":case"deletion":case"insertion":{if(!n)throw new Error("Bad parser state: Hunk lines encountered before hunk header");s&&s.type!==u&&(n.parts.push(s),s=null),s||(s={type:u,lines:[],noNewlineAtEndOfFile:!1}),s.lines.push(c.slice(1))}break;default:me.assertNever(u);break}}}a();for(let{hunks:l}of e)if(l)for(let c of l)PVe(c);return e}function vVe(r){let e=[];for(let t of r){let{semverExclusivity:i,diffLineFromPath:n,diffLineToPath:s,oldMode:o,newMode:a,deletedFileMode:l,newFileMode:c,renameFrom:u,renameTo:g,beforeHash:h,afterHash:p,fromPath:d,toPath:m,hunks:y}=t,B=u?"rename":l?"file deletion":c?"file creation":y&&y.length>0?"patch":"mode change",S=null;switch(B){case"rename":{if(!u||!g)throw new Error("Bad parser state: rename from & to not given");e.push({type:"rename",semverExclusivity:i,fromPath:Ep(u),toPath:Ep(g)}),S=g}break;case"file deletion":{let x=n||d;if(!x)throw new Error("Bad parse state: no path given for file deletion");e.push({type:"file deletion",semverExclusivity:i,hunk:y&&y[0]||null,path:Ep(x),mode:HQ(l),hash:h})}break;case"file creation":{let x=s||m;if(!x)throw new Error("Bad parse state: no path given for file creation");e.push({type:"file creation",semverExclusivity:i,hunk:y&&y[0]||null,path:Ep(x),mode:HQ(c),hash:p})}break;case"patch":case"mode change":S=m||s;break;default:me.assertNever(B);break}S&&o&&a&&o!==a&&e.push({type:"mode change",semverExclusivity:i,path:Ep(S),oldMode:HQ(o),newMode:HQ(a)}),S&&y&&y.length&&e.push({type:"patch",semverExclusivity:i,path:Ep(S),hunks:y,beforeHash:h,afterHash:p})}if(e.length===0)throw new Error("Unable to parse patch file: No changes found. Make sure the patch is a valid UTF8 encoded string");return e}function HQ(r){let e=parseInt(r,8)&511;if(e!==wVe&&e!==BVe)throw new Error(`Unexpected file mode string: ${r}`);return e}function FE(r){let e=r.split(/\n/g);return e[e.length-1]===""&&e.pop(),vVe(SVe(e))}function PVe(r){let e=0,t=0;for(let{type:i,lines:n}of r.parts)switch(i){case"context":t+=n.length,e+=n.length;break;case"deletion":e+=n.length;break;case"insertion":t+=n.length;break;default:me.assertNever(i);break}if(e!==r.header.original.length||t!==r.header.patched.length){let i=n=>n<0?n:`+${n}`;throw new Error(`hunk header integrity check failed (expected @@ ${i(r.header.original.length)} ${i(r.header.patched.length)} @@, got @@ ${i(e)} ${i(t)} @@)`)}}var Ip=class extends Error{constructor(t,i){super(`Cannot apply hunk #${t+1}`);this.hunk=i}};async function yp(r,e,t){let i=await r.lstatPromise(e),n=await t();if(typeof n<"u"&&(e=n),r.lutimesPromise)await r.lutimesPromise(e,i.atime,i.mtime);else if(!i.isSymbolicLink())await r.utimesPromise(e,i.atime,i.mtime);else throw new Error("Cannot preserve the time values of a symlink")}async function jQ(r,{baseFs:e=new Zt,dryRun:t=!1,version:i=null}={}){for(let n of r)if(!(n.semverExclusivity!==null&&i!==null&&!Qt.satisfiesWithPrereleases(i,n.semverExclusivity)))switch(n.type){case"file deletion":if(t){if(!e.existsSync(n.path))throw new Error(`Trying to delete a file that doesn't exist: ${n.path}`)}else await yp(e,v.dirname(n.path),async()=>{await e.unlinkPromise(n.path)});break;case"rename":if(t){if(!e.existsSync(n.fromPath))throw new Error(`Trying to move a file that doesn't exist: ${n.fromPath}`)}else await yp(e,v.dirname(n.fromPath),async()=>{await yp(e,v.dirname(n.toPath),async()=>{await yp(e,n.fromPath,async()=>(await e.movePromise(n.fromPath,n.toPath),n.toPath))})});break;case"file creation":if(t){if(e.existsSync(n.path))throw new Error(`Trying to create a file that already exists: ${n.path}`)}else{let s=n.hunk?n.hunk.parts[0].lines.join(` +`)+(n.hunk.parts[0].noNewlineAtEndOfFile?"":` +`):"";await e.mkdirpPromise(v.dirname(n.path),{chmod:493,utimes:[vr.SAFE_TIME,vr.SAFE_TIME]}),await e.writeFilePromise(n.path,s,{mode:n.mode}),await e.utimesPromise(n.path,vr.SAFE_TIME,vr.SAFE_TIME)}break;case"patch":await yp(e,n.path,async()=>{await DVe(n,{baseFs:e,dryRun:t})});break;case"mode change":{let o=(await e.statPromise(n.path)).mode;if(oge(n.newMode)!==oge(o))continue;await yp(e,n.path,async()=>{await e.chmodPromise(n.path,n.newMode)})}break;default:me.assertNever(n);break}}function oge(r){return(r&64)>0}function age(r){return r.replace(/\s+$/,"")}function kVe(r,e){return age(r)===age(e)}async function DVe({hunks:r,path:e},{baseFs:t,dryRun:i=!1}){let n=await t.statSync(e).mode,o=(await t.readFileSync(e,"utf8")).split(/\n/),a=[],l=0,c=0;for(let g of r){let h=Math.max(c,g.header.patched.start+l),p=Math.max(0,h-c),d=Math.max(0,o.length-h-g.header.original.length),m=Math.max(p,d),y=0,B=0,S=null;for(;y<=m;){if(y<=p&&(B=h-y,S=Age(g,o,B),S!==null)){y=-y;break}if(y<=d&&(B=h+y,S=Age(g,o,B),S!==null))break;y+=1}if(S===null)throw new Ip(r.indexOf(g),g);a.push(S),l+=y,c=B+g.header.original.length}if(i)return;let u=0;for(let g of a)for(let h of g)switch(h.type){case"splice":{let p=h.index+u;o.splice(p,h.numToDelete,...h.linesToInsert),u+=h.linesToInsert.length-h.numToDelete}break;case"pop":o.pop();break;case"push":o.push(h.line);break;default:me.assertNever(h);break}await t.writeFilePromise(e,o.join(` +`),{mode:n})}function Age(r,e,t){let i=[];for(let n of r.parts)switch(n.type){case"context":case"deletion":{for(let s of n.lines){let o=e[t];if(o==null||!kVe(o,s))return null;t+=1}n.type==="deletion"&&(i.push({type:"splice",index:t-n.lines.length,numToDelete:n.lines.length,linesToInsert:[]}),n.noNewlineAtEndOfFile&&i.push({type:"push",line:""}))}break;case"insertion":i.push({type:"splice",index:t,numToDelete:0,linesToInsert:n.lines}),n.noNewlineAtEndOfFile&&i.push({type:"pop"});break;default:me.assertNever(n.type);break}return i}var FVe=/^builtin<([^>]+)>$/;function m1(r,e){let{source:t,selector:i,params:n}=P.parseRange(r);if(t===null)throw new Error("Patch locators must explicitly define their source");let s=i?i.split(/&/).map(c=>K.toPortablePath(c)):[],o=n&&typeof n.locator=="string"?P.parseLocator(n.locator):null,a=n&&typeof n.version=="string"?n.version:null,l=e(t);return{parentLocator:o,sourceItem:l,patchPaths:s,sourceVersion:a}}function NE(r){let{sourceItem:e,...t}=m1(r.range,P.parseDescriptor);return{...t,sourceDescriptor:e}}function TE(r){let{sourceItem:e,...t}=m1(r.reference,P.parseLocator);return{...t,sourceLocator:e}}function E1(r){if(!r.range.startsWith("patch:"))return r;let{sourceItem:e}=m1(r.range,P.parseDescriptor);return e}function lge({parentLocator:r,sourceItem:e,patchPaths:t,sourceVersion:i,patchHash:n},s){let o=r!==null?{locator:P.stringifyLocator(r)}:{},a=typeof i<"u"?{version:i}:{},l=typeof n<"u"?{hash:n}:{};return P.makeRange({protocol:"patch:",source:s(e),selector:t.join("&"),params:{...a,...l,...o}})}function I1(r,{parentLocator:e,sourceDescriptor:t,patchPaths:i}){return P.makeDescriptor(r,lge({parentLocator:e,sourceItem:t,patchPaths:i},P.stringifyDescriptor))}function y1(r,{parentLocator:e,sourcePackage:t,patchPaths:i,patchHash:n}){return P.makeLocator(r,lge({parentLocator:e,sourceItem:t,sourceVersion:t.version,patchPaths:i,patchHash:n},P.stringifyLocator))}function cge({onAbsolute:r,onRelative:e,onBuiltin:t},i){i.startsWith("~")&&(i=i.slice(1));let s=i.match(FVe);return s!==null?t(s[1]):v.isAbsolute(i)?r(i):e(i)}function uge(r){let e=r.startsWith("~");return e&&(r=r.slice(1)),{optional:e}}function w1(r){return cge({onAbsolute:()=>!1,onRelative:()=>!0,onBuiltin:()=>!1},r)}async function LE(r,e,t){let i=r!==null?await t.fetcher.fetch(r,t):null,n=i&&i.localPath?{packageFs:new jt(Te.root),prefixPath:v.relative(Te.root,i.localPath)}:i;i&&i!==n&&i.releaseFs&&i.releaseFs();let s=await me.releaseAfterUseAsync(async()=>await Promise.all(e.map(async o=>{let a=uge(o),l=await cge({onAbsolute:async()=>await M.readFilePromise(o,"utf8"),onRelative:async()=>{if(n===null)throw new Error("Assertion failed: The parent locator should have been fetched");return await n.packageFs.readFilePromise(v.join(n.prefixPath,o),"utf8")},onBuiltin:async c=>await t.project.configuration.firstHook(u=>u.getBuiltinPatch,t.project,c)},o);return{...a,source:l}})));for(let o of s)typeof o.source=="string"&&(o.source=o.source.replace(/\r\n?/g,` +`));return s}async function B1(r,{cache:e,project:t}){let i=t.storedPackages.get(r.locatorHash);if(typeof i>"u")throw new Error("Assertion failed: Expected the package to be registered");let n=t.storedChecksums,s=new $r,o=t.configuration.makeFetcher(),a=await o.fetch(r,{cache:e,project:t,fetcher:o,checksums:n,report:s}),l=await M.mktempPromise(),c=v.join(l,"source"),u=v.join(l,"user"),g=v.join(l,".yarn-patch.json");return await Promise.all([M.copyPromise(c,a.prefixPath,{baseFs:a.packageFs}),M.copyPromise(u,a.prefixPath,{baseFs:a.packageFs}),M.writeJsonPromise(g,{locator:P.stringifyLocator(r),version:i.version})]),M.detachTemp(l),u}async function b1(r,e){let t=K.fromPortablePath(r).replace(/\\/g,"/"),i=K.fromPortablePath(e).replace(/\\/g,"/"),{stdout:n,stderr:s}=await pr.execvp("git",["-c","core.safecrlf=false","diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index","--no-renames","--text",t,i],{cwd:K.toPortablePath(process.cwd()),env:{...process.env,GIT_CONFIG_NOSYSTEM:"1",HOME:"",XDG_CONFIG_HOME:"",USERPROFILE:""}});if(s.length>0)throw new Error(`Unable to diff directories. Make sure you have a recent version of 'git' available in PATH. +The following error was reported by 'git': +${s}`);let o=t.startsWith("/")?a=>a.slice(1):a=>a;return n.replace(new RegExp(`(a|b)(${me.escapeRegExp(`/${o(t)}/`)})`,"g"),"$1/").replace(new RegExp(`(a|b)${me.escapeRegExp(`/${o(i)}/`)}`,"g"),"$1/").replace(new RegExp(me.escapeRegExp(`${t}/`),"g"),"").replace(new RegExp(me.escapeRegExp(`${i}/`),"g"),"")}function Q1(r,e){let t=[];for(let{source:i}of r){if(i===null)continue;let n=FE(i);for(let s of n){let{semverExclusivity:o,...a}=s;o!==null&&e!==null&&!Qt.satisfiesWithPrereleases(e,o)||t.push(JSON.stringify(a))}}return Ai.makeHash(`${3}`,...t).slice(0,6)}function gge(r,{configuration:e,report:t}){for(let i of r.parts)for(let n of i.lines)switch(i.type){case"context":t.reportInfo(null,` ${$.pretty(e,n,"grey")}`);break;case"deletion":t.reportError(28,`- ${$.pretty(e,n,$.Type.REMOVED)}`);break;case"insertion":t.reportError(28,`+ ${$.pretty(e,n,$.Type.ADDED)}`);break;default:me.assertNever(i.type)}}var GQ=class{supports(e,t){return!!e.reference.startsWith("patch:")}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,{onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.patchPackage(e,t),skipIntegrityCheck:t.skipIntegrityCheck,...t.cacheOptions});return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async patchPackage(e,t){let{parentLocator:i,sourceLocator:n,sourceVersion:s,patchPaths:o}=TE(e),a=await LE(i,o,t),l=await M.mktempPromise(),c=v.join(l,"current.zip"),u=await t.fetcher.fetch(n,t),g=P.getIdentVendorPath(e),h=await on(),p=new qr(c,{libzip:h,create:!0,level:t.project.configuration.get("compressionLevel")});await me.releaseAfterUseAsync(async()=>{await p.copyPromise(g,u.prefixPath,{baseFs:u.packageFs,stableSort:!0})},u.releaseFs),p.saveAndClose();for(let{source:d,optional:m}of a){if(d===null)continue;let y=new qr(c,{libzip:h,level:t.project.configuration.get("compressionLevel")}),B=new jt(v.resolve(Te.root,g),{baseFs:y});try{await jQ(FE(d),{baseFs:B,version:s})}catch(S){if(!(S instanceof Ip))throw S;let x=t.project.configuration.get("enableInlineHunks"),F=!x&&!m?" (set enableInlineHunks for details)":"",H=`${P.prettyLocator(t.project.configuration,e)}: ${S.message}${F}`,q=_=>{!x||gge(S.hunk,{configuration:t.project.configuration,report:_})};if(y.discardAndClose(),m){t.report.reportWarningOnce(66,H,{reportExtra:q});continue}else throw new rt(66,H,q)}y.saveAndClose()}return new qr(c,{libzip:h,level:t.project.configuration.get("compressionLevel")})}};var YQ=class{supportsDescriptor(e,t){return!!e.range.startsWith("patch:")}supportsLocator(e,t){return!!e.reference.startsWith("patch:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){let{patchPaths:n}=NE(e);return n.every(s=>!w1(s))?e:P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){let{sourceDescriptor:i}=NE(e);return[i]}async getCandidates(e,t,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{parentLocator:n,sourceDescriptor:s,patchPaths:o}=NE(e),a=await LE(n,o,i.fetchOptions),l=t.get(s.descriptorHash);if(typeof l>"u")throw new Error("Assertion failed: The dependency should have been resolved");let c=Q1(a,l.version);return[y1(e,{parentLocator:n,sourcePackage:l,patchPaths:o,patchHash:c})]}async getSatisfying(e,t,i){return null}async resolve(e,t){let{sourceLocator:i}=TE(e);return{...await t.resolver.resolve(i,t),...e}}};var cg=class extends Pe{constructor(){super(...arguments);this.save=z.Boolean("-s,--save",!1,{description:"Add the patch to your resolution entries"});this.patchFolder=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState();let s=v.resolve(this.context.cwd,K.toPortablePath(this.patchFolder)),o=v.join(s,"../source"),a=v.join(s,"../.yarn-patch.json");if(!M.existsSync(o))throw new we("The argument folder didn't get created by 'yarn patch'");let l=await b1(o,s),c=await M.readJsonPromise(a),u=P.parseLocator(c.locator,!0);if(!i.storedPackages.has(u.locatorHash))throw new we("No package found in the project for the given locator");if(!this.save){this.context.stdout.write(l);return}let g=t.get("patchFolder"),h=v.join(g,`${P.slugifyLocator(u)}.patch`);await M.mkdirPromise(g,{recursive:!0}),await M.writeFilePromise(h,l);let p=new Map;for(let d of i.storedPackages.values()){if(P.isVirtualLocator(d))continue;let m=d.dependencies.get(u.identHash);if(!m)continue;let y=P.isVirtualDescriptor(m)?P.devirtualizeDescriptor(m):m,B=E1(y),S=i.storedResolutions.get(B.descriptorHash);if(!S)throw new Error("Assertion failed: Expected the resolution to have been registered");if(!i.storedPackages.get(S))throw new Error("Assertion failed: Expected the package to have been registered");let F=i.originalPackages.get(d.locatorHash);if(!F)throw new Error("Assertion failed: Expected the original package to have been registered");let H=F.dependencies.get(m.identHash);if(!H)throw new Error("Assertion failed: Expected the original dependency to have been registered");p.set(H.descriptorHash,H)}for(let d of p.values()){let m=I1(d,{parentLocator:null,sourceDescriptor:P.convertLocatorToDescriptor(u),sourceVersion:null,patchPaths:[`./${v.relative(i.cwd,h)}`]});i.topLevelWorkspace.manifest.resolutions.push({pattern:{descriptor:{fullName:P.stringifyIdent(m),description:d.range}},reference:m.range})}await i.persist()}};cg.paths=[["patch-commit"]],cg.usage=Qe.Usage({description:"generate a patch out of a directory",details:"\n By default, this will print a patchfile on stdout based on the diff between the folder passed in and the original version of the package. Such file is suitable for consumption with the `patch:` protocol.\n\n With the `-s,--save` option set, the patchfile won't be printed on stdout anymore and will instead be stored within a local file (by default kept within `.yarn/patches`, but configurable via the `patchFolder` setting). A `resolutions` entry will also be added to your top-level manifest, referencing the patched package via the `patch:` protocol.\n\n Note that only folders generated by `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "});var ug=class extends Pe{constructor(){super(...arguments);this.json=z.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=z.String()}async execute(){let t=await Ee.find(this.context.cwd,this.context.plugins),{project:i,workspace:n}=await Ge.find(t,this.context.cwd),s=await Dt.find(t);if(!n)throw new lt(i.cwd,this.context.cwd);await i.restoreInstallState();let o=P.parseLocator(this.package);if(o.reference==="unknown"){let a=me.mapAndFilter([...i.storedPackages.values()],l=>l.identHash!==o.identHash?me.mapAndFilter.skip:P.isVirtualLocator(l)?me.mapAndFilter.skip:l);if(a.length===0)throw new we("No package found in the project for the given locator");if(a.length>1)throw new we(`Multiple candidate packages found; explicitly choose one of them (use \`yarn why <package>\` to get more information as to who depends on them): +${a.map(l=>` +- ${P.prettyLocator(t,l)}`).join("")}`);o=a[0]}if(!i.storedPackages.has(o.locatorHash))throw new we("No package found in the project for the given locator");await He.start({configuration:t,json:this.json,stdout:this.context.stdout},async a=>{let l=await B1(o,{cache:s,project:i});a.reportJson({locator:P.stringifyLocator(o),path:K.fromPortablePath(l)}),a.reportInfo(0,`Package ${P.prettyLocator(t,o)} got extracted with success!`),a.reportInfo(0,`You can now edit the following folder: ${$.pretty(t,K.fromPortablePath(l),"magenta")}`),a.reportInfo(0,`Once you are done run ${$.pretty(t,`yarn patch-commit -s ${process.platform==="win32"?'"':""}${K.fromPortablePath(l)}${process.platform==="win32"?'"':""}`,"cyan")} and Yarn will store a patchfile based on your changes.`)})}};ug.paths=[["patch"]],ug.usage=Qe.Usage({description:"prepare a package for patching",details:"\n This command will cause a package to be extracted in a temporary directory intended to be editable at will.\n \n Once you're done with your changes, run `yarn patch-commit -s <path>` (with `<path>` being the temporary directory you received) to generate a patchfile and register it into your top-level manifest via the `patch:` protocol. Run `yarn patch-commit -h` for more details.\n "});var NVe={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:"BOOLEAN",default:!1},patchFolder:{description:"Folder where the patch files must be written",type:"ABSOLUTE_PATH",default:"./.yarn/patches"}},commands:[cg,ug],fetchers:[GQ],resolvers:[YQ]},TVe=NVe;var k1={};ct(k1,{default:()=>MVe});var qQ=class{supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the pnpm linker to be enabled");let i=P1(),n=t.project.installersCustomData.get(i);if(!n)throw new we(`The project in ${$.pretty(t.project.configuration,`${t.project.cwd}/package.json`,$.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let s=n.pathByLocator.get(e.locatorHash);if(typeof s>"u")throw new we(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed pnpm map - running an install might help`);return s}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=P1(),n=t.project.installersCustomData.get(i);if(!n)throw new we(`The project in ${$.pretty(t.project.configuration,`${t.project.cwd}/package.json`,$.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let s=e.match(/(^.*\/node_modules\/(@[^/]*\/)?[^/]+)(\/.*$)/);if(s){let l=n.locatorByPath.get(s[1]);if(l)return l}let o=e,a=e;do{a=o,o=v.dirname(a);let l=n.locatorByPath.get(a);if(l)return l}while(o!==a);return null}makeInstaller(e){return new v1(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="pnpm"}},v1=class{constructor(e){this.opts=e;this.asyncActions=new me.AsyncActions(10);this.customData={pathByLocator:new Map,locatorByPath:new Map}}getCustomDataKey(){return P1()}attachCustomData(e){}async installPackage(e,t,i){switch(e.linkType){case"SOFT":return this.installPackageSoft(e,t,i);case"HARD":return this.installPackageHard(e,t,i)}throw new Error("Assertion failed: Unsupported package link type")}async installPackageSoft(e,t,i){let n=v.resolve(t.packageFs.getRealPath(),t.prefixPath);return this.customData.pathByLocator.set(e.locatorHash,n),{packageLocation:n,buildDirective:null}}async installPackageHard(e,t,i){var u;let n=LVe(e,{project:this.opts.project});this.customData.locatorByPath.set(n,P.stringifyLocator(e)),this.customData.pathByLocator.set(e.locatorHash,n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{await M.mkdirPromise(n,{recursive:!0}),await M.copyPromise(n,t.prefixPath,{baseFs:t.packageFs,overwrite:!1})}));let o=P.isVirtualLocator(e)?P.devirtualizeLocator(e):e,a={manifest:(u=await ot.tryFind(t.prefixPath,{baseFs:t.packageFs}))!=null?u:new ot,misc:{hasBindingGyp:po.hasBindingGyp(t)}},l=this.opts.project.getDependencyMeta(o,e.version),c=po.extractBuildScripts(e,a,l,{configuration:this.opts.project.configuration,report:this.opts.report});return{packageLocation:n,buildDirective:c}}async attachInternalDependencies(e,t){this.opts.project.configuration.get("nodeLinker")==="pnpm"&&(!fge(e,{project:this.opts.project})||this.asyncActions.reduce(e.locatorHash,async i=>{await i;let n=this.customData.pathByLocator.get(e.locatorHash);if(typeof n>"u")throw new Error(`Assertion failed: Expected the package to have been registered (${P.stringifyLocator(e)})`);let s=v.join(n,St.nodeModules),o=[],a=await hge(s);for(let[l,c]of t){let u=c;fge(c,{project:this.opts.project})||(this.opts.report.reportWarningOnce(0,"The pnpm linker doesn't support providing different versions to workspaces' peer dependencies"),u=P.devirtualizeLocator(c));let g=this.customData.pathByLocator.get(u.locatorHash);if(typeof g>"u")throw new Error(`Assertion failed: Expected the package to have been registered (${P.stringifyLocator(c)})`);let h=P.stringifyIdent(l),p=v.join(s,h),d=v.relative(v.dirname(p),g),m=a.get(h);a.delete(h),o.push(Promise.resolve().then(async()=>{if(m){if(m.isSymbolicLink()&&await M.readlinkPromise(p)===d)return;await M.removePromise(p)}await M.mkdirpPromise(v.dirname(p)),process.platform=="win32"?await M.symlinkPromise(g,p,"junction"):await M.symlinkPromise(d,p)}))}o.push(pge(s,a)),await Promise.all(o)}))}async attachExternalDependents(e,t){throw new Error("External dependencies haven't been implemented for the pnpm linker")}async finalizeInstall(){let e=Cge(this.opts.project);if(this.opts.project.configuration.get("nodeLinker")!=="pnpm")await M.removePromise(e);else{let t=[],i=new Set;for(let s of this.customData.pathByLocator.values()){let o=v.contains(e,s);if(o!==null){let[a,,...l]=o.split(v.sep);i.add(a);let c=v.join(e,a);t.push(M.readdirPromise(c).then(u=>Promise.all(u.map(async g=>{let h=v.join(c,g);if(g===St.nodeModules){let p=await hge(h);return p.delete(l.join(v.sep)),pge(h,p)}else return M.removePromise(h)}))).catch(u=>{if(u.code!=="ENOENT")throw u}))}}let n;try{n=await M.readdirPromise(e)}catch{n=[]}for(let s of n)i.has(s)||t.push(M.removePromise(v.join(e,s)));await Promise.all(t)}return await this.asyncActions.wait(),await x1(e),this.opts.project.configuration.get("nodeLinker")!=="node-modules"&&await x1(dge(this.opts.project)),{customData:this.customData}}};function P1(){return JSON.stringify({name:"PnpmInstaller",version:2})}function dge(r){return v.join(r.cwd,St.nodeModules)}function Cge(r){return v.join(dge(r),".store")}function LVe(r,{project:e}){let t=P.slugifyLocator(r),i=P.getIdentVendorPath(r);return v.join(Cge(e),t,i)}function fge(r,{project:e}){return!P.isVirtualLocator(r)||!e.tryWorkspaceByLocator(r)}async function hge(r){let e=new Map,t=[];try{t=await M.readdirPromise(r,{withFileTypes:!0})}catch(i){if(i.code!=="ENOENT")throw i}try{for(let i of t)if(!i.name.startsWith("."))if(i.name.startsWith("@")){let n=await M.readdirPromise(v.join(r,i.name),{withFileTypes:!0});if(n.length===0)e.set(i.name,i);else for(let s of n)e.set(`${i.name}/${s.name}`,s)}else e.set(i.name,i)}catch(i){if(i.code!=="ENOENT")throw i}return e}async function pge(r,e){var n;let t=[],i=new Set;for(let s of e.keys()){t.push(M.removePromise(v.join(r,s)));let o=(n=P.tryParseIdent(s))==null?void 0:n.scope;o&&i.add(`@${o}`)}return Promise.all(t).then(()=>Promise.all([...i].map(s=>x1(v.join(r,s)))))}async function x1(r){try{await M.rmdirPromise(r)}catch(e){if(e.code!=="ENOENT"&&e.code!=="ENOTEMPTY")throw e}}var OVe={linkers:[qQ]},MVe=OVe;var wb=()=>({modules:new Map([["@yarnpkg/cli",Tm],["@yarnpkg/core",om],["@yarnpkg/fslib",zp],["@yarnpkg/libzip",xC],["@yarnpkg/parsers",rd],["@yarnpkg/shell",FC],["clipanion",K$(gd)],["semver",KVe],["typanion",hn],["yup",UVe],["@yarnpkg/plugin-essentials",CO],["@yarnpkg/plugin-compat",wO],["@yarnpkg/plugin-dlx",BO],["@yarnpkg/plugin-file",vO],["@yarnpkg/plugin-git",dO],["@yarnpkg/plugin-github",PO],["@yarnpkg/plugin-http",xO],["@yarnpkg/plugin-init",FO],["@yarnpkg/plugin-link",NO],["@yarnpkg/plugin-nm",dM],["@yarnpkg/plugin-npm",f1],["@yarnpkg/plugin-npm-cli",C1],["@yarnpkg/plugin-pack",A1],["@yarnpkg/plugin-patch",S1],["@yarnpkg/plugin-pnp",sM],["@yarnpkg/plugin-pnpm",k1]]),plugins:new Set(["@yarnpkg/plugin-essentials","@yarnpkg/plugin-compat","@yarnpkg/plugin-dlx","@yarnpkg/plugin-file","@yarnpkg/plugin-git","@yarnpkg/plugin-github","@yarnpkg/plugin-http","@yarnpkg/plugin-init","@yarnpkg/plugin-link","@yarnpkg/plugin-nm","@yarnpkg/plugin-npm","@yarnpkg/plugin-npm-cli","@yarnpkg/plugin-pack","@yarnpkg/plugin-patch","@yarnpkg/plugin-pnp","@yarnpkg/plugin-pnpm"])});_0({binaryVersion:Fr||"<unknown>",pluginConfiguration:wb()});})(); +/*! + * buildToken + * Builds OAuth token prefix (helper function) + * + * @name buildToken + * @function + * @param {GitUrl} obj The parsed Git url object. + * @return {String} token prefix + */ +/*! + * fill-range <https://github.com/jonschlinkert/fill-range> + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-extglob <https://github.com/jonschlinkert/is-extglob> + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ +/*! + * is-glob <https://github.com/jonschlinkert/is-glob> + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * is-number <https://github.com/jonschlinkert/is-number> + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * is-windows <https://github.com/jonschlinkert/is-windows> + * + * Copyright © 2015-2018, Jon Schlinkert. + * Released under the MIT License. + */ +/*! + * to-regex-range <https://github.com/micromatch/to-regex-range> + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ +/** + @license + Copyright (c) 2015, Rebecca Turner + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + */ +/** + @license + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/** + @license + Copyright Node.js contributors. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +/** + @license + The MIT License (MIT) + + Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ diff --git a/.yarnrc.yml b/.yarnrc.yml index 0b1cd8e1ae..466074db0a 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -10,4 +10,4 @@ plugins: - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs spec: '@yarnpkg/plugin-workspace-tools' -yarnPath: .yarn/releases/yarn-3.2.3.cjs +yarnPath: .yarn/releases/yarn-3.8.1.cjs diff --git a/ADOPTERS.md b/ADOPTERS.md index 7d22f72778..3878563683 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -30,7 +30,6 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [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. | -| [Netflix](https://www.netflix.com/) | [bleathem](https://github.com/bleathem) | Our Backstage implementation will be the front door to a unified experience connecting our internal platform products across important workflows with integrated knowledge and support. | | [b.well](https://www.icanbwell.com/) | [Jacob Rosales](https://github.com/jrosales) | Foundation for our engineering portal and cloud insights. | | [PagerDuty](https://www.pagerduty.com/) | [Mark Shaw](https://github.com/markshawtoronto) | Developer portal, initially focused on software templates and tech-docs. | | [MoonShiner](https://moonshiner.at) | [Fabian Hippmann](https://github.com/FabianHippmann) | Developer portal - helps us keep track of our customer projects, onboard new developers & improve our development process 🌕🚀🧑‍🚀 | @@ -264,3 +263,8 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Giant Swarm](https://giantswarm.io) | [Lucas Weatherhog](https://github.com/weatherhog) | At Giant Swarm we are using Backstage as our internal developer portal. Heavily using the service catalog and the TechDocs plugin. Further looking into adopting functionalities of our Web UI into Backstage to have a single pane of glass for our core business, managing all our components, and helping developers to be more productive. | | [WD Studios](https://wdstudios.tech) | [Mikael Aboagye](https://github.com/JailbreakPapa) | We are using Backstage as our main internal developer portal for our Programmers and Studio Partners. It's really proven its worth at our studio with on-boarding new programmers! | | [Anuclei](https://anuclei.com) | [Mark Jackson](https://github.com/markjacksonfishing) | At Anuclei, we are using Backstage as our internal portal for developers, providing all the tools and guidance needed for full-stack software projects. It simplifies our development methods, making innovation and investment in new ideas consistent and easy to repeat. +| [Fortnox](https://www.fortnox.se) | [@magnusp](https://github.com/magnusp) | With Backstage we consolidate our internal tools into a single pane of glass and let the catalog drive our user interface. Our software templates onboard our services and teams onto Backstage, and with Techdocs we are letting our developers get back in control of their own documentation. | +| [Wefox](https://www.wefox.com) | [@dibenlloch](https://github.com/dibenlloch) | Internal developer portal to consolidate all developers dashboards, company inventory with compliance reports, team management and self-service portal for IT/Team operations. | +| [Aurora Innovation](https://aurorainnovation.com) | [@O5ten](https://github.com/O5ten) | Heavy usage of scaffolder, techdocs, homepage, k8s plugin and homegrown plugins to track migration paths and so on within a developer portal. It acts as a starting point for new and old developers to find all of our internal tooling in one place. +| [ENSEK](https://ensek.com/) | [Timothy Deakin](https://github.com/cftad) |We are using Backstage as our internal developer portal to provide a single pane of glass for our developers to access all the tools and services they need to build and maintain our software. | +| [OP Financial Group](https://www.op.fi/op-financial-group) | [Heikki Hellgren](https://github.com/drodil), [Jyrki Koistinen](https://github.com/snyvision) | We are using Backstage as a gateway into our internal development platform offering to simplify complexity. | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be88ed2249..ce0e97c781 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,8 +8,6 @@ Contributions are welcome, and they are greatly appreciated! Every little bit he Backstage is released under the Apache 2.0 License, and original creations contributed to this repo are accepted under the same license. -You can find out more about the types of contributions over at [getting involved](https://backstage.io/docs/getting-started/getting-involved)! - If you need help, just jump into our [Discord chatroom](https://discord.gg/backstage-687207715902193673). ## Table of Contents diff --git a/OWNERS.md b/OWNERS.md index 1e92e68c40..ab35b5b1e5 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -63,10 +63,9 @@ Team: @backstage/kubernetes-maintainers Scope: The Kubernetes plugin and the base it provides for other plugins to build upon. -| Name | Organization | Team | GitHub | Discord | -| -------------- | ------------ | ---- | ---------------------------------------------- | ----------------- | -| Matthew Clarke | Spotify | | [mclarke47](http://github.com/mclarke47) | mclarke#0725 | -| Jamie Klassen | VMware | | [jamieklassen](http://github.com/jamieklassen) | jamieklassen#3047 | +| Name | Organization | Team | GitHub | Discord | +| -------------- | ------------ | ---- | ---------------------------------------- | ------------ | +| Matthew Clarke | Spotify | | [mclarke47](http://github.com/mclarke47) | mclarke#0725 | ### Permission Framework @@ -74,17 +73,14 @@ Team: @backstage/permission-maintainers Scope: The Permission Framework and plugins integrating with the permission framework -| Name | Organization | Team | GitHub | Discord | -| -------------------- | ------------ | --------------- | ----------------------------------------------- | ---------------- | -| Ainhoa Larumbe | Spotify | Imaginary Goats | [ainhoaL](http://github.com/ainhoaL) | ainhoa#8085 | -| Claire Casey | Spotify | Imaginary Goats | [clairelcasey](http://github.com/clairelcasey) | clairecasey#2710 | -| Eric Peterson | Spotify | Imaginary Goats | [iamEAP](http://github.com/iamEAP) | iamEAP#3058 | -| Harry Hogg | Spotify | Imaginary Goats | [HHogg](http://github.com/HHogg) | simplex#3451 | -| Joon Park | Spotify | Imaginary Goats | [Joonpark13](http://github.com/Joonpark13) | Sixpool#5060 | -| Lynette Lopez | Spotify | Imaginary Goats | [lynettelopez](https://github.com/lynettelopez) | lynettelopez | -| Mike Lewis | Spotify | Imaginary Goats | [mtlewis](http://github.com/mtlewis) | mtlewis#3658 | -| Tim Hansen | Spotify | Imaginary Goats | [timbonicus](http://github.com/timbonicus) | timbonicus#6871 | -| Vincenzo Scamporlino | Spotify | Imaginary Goats | [vinzscam](http://github.com/vinzscam) | vinzscam#6944 | +| Name | Organization | Team | GitHub | Discord | +| -------------------- | ------------ | --------------- | ------------------------------------------ | ------------- | +| Ainhoa Larumbe | Spotify | Imaginary Goats | [ainhoaL](http://github.com/ainhoaL) | ainhoa#8085 | +| Eric Peterson | Spotify | Imaginary Goats | [iamEAP](http://github.com/iamEAP) | iamEAP#3058 | +| Harry Hogg | Spotify | Imaginary Goats | [HHogg](http://github.com/HHogg) | simplex#3451 | +| Joon Park | Spotify | Imaginary Goats | [Joonpark13](http://github.com/Joonpark13) | Sixpool#5060 | +| Mike Lewis | Spotify | Imaginary Goats | [mtlewis](http://github.com/mtlewis) | mtlewis#3658 | +| Vincenzo Scamporlino | Spotify | Imaginary Goats | [vinzscam](http://github.com/vinzscam) | vinzscam#6944 | ### TechDocs @@ -108,15 +104,49 @@ Scope: The TechDocs plugin and related tooling These incubating project areas have shared ownership with @backstage/maintainers. +### Community Plugins + +Team: @backstage/community-plugins-maintainers + +Scope: Tooling and Community Repo Maintainers for the Backstage [Community Plugins repository](https://github.com/backstage/community-plugins) + +| Name | Organization | GitHub | Discord | +| -------------------- | ------------ | ------------------------------------------- | ------------ | +| Bethany Griggs | Red Hat | [BethGriggs](https://github.com/BethGriggs) | `bethgriggs` | +| Tomas Kral | Red Hat | [kadel](https://github.com/kadel) | `tomkral` | +| André Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | +| Philipp Hugenroth | Spotify | [tudi2d](https://github.com/tudi2d) | `tudi2d` | +| Vincenzo Scamporlino | Spotify | [vinzscam](https://github.com/vinzscam) | `vinzscam` | + +### Events + +Team: @backstage/events-maintainers + +Scope: The Events plugin and library, along with events modules in the main repository + +| Name | Organization | GitHub | Discord | +| ------------------ | ------------------------- | --------------------------------------------- | ------------- | +| Patrick Jungermann | Bonial International GmbH | [pjungermann](https://github.com/pjungermann) | `pjungermann` | + +### Notifications + +Team: @backstage/notifications-maintainers + +Scope: The Notifications and Signals plugins and libraries + +| Name | Organization | GitHub | Discord | +| ----------- | ------------ | ------------------------------------------- | --------- | +| Marek Libra | RedHat | [mareklibra](https://github.com/mareklibra) | `marekli` | + ### OpenAPI Tooling Team: @backstage/openapi-tooling-maintainers Scope: Tooling for frontend and backend schema-first OpenAPI development. -| Name | Organization | GitHub | Discord | -| -------------- | ------------ | --------------------------------------- | ------------- | -| Aramis Sennyey | | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | +| Name | Organization | GitHub | Discord | +| -------------- | ------------ | ----------------------------------------------------- | ------------- | +| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | ### Scaffolder @@ -140,18 +170,17 @@ Scope: The Scaffolder frontend and backend plugins, and related tooling. | Name | Organization | GitHub | Discord | | ------------------------------ | ------------------------- | ----------------------------------------------------- | ------------------------------ | -| Adam Harvey | Cisco | [adamdmharvey](https://github.com/adamdmharvey) | `adamharvey_` | +| Adam Harvey | Okta | [adamdmharvey](https://github.com/adamdmharvey) | `adamharvey_` | | Alex Crome | | [afscrome](https://github.com/afscrome) | `afscrome` | | Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | | Andrew Thauer | Wealthsimple | [andrewthauer](https://github.com/andrewthauer) | `andrewthauer#3060` | -| Aramis Sennyey | | [sennyeya](https://github.com/sennyeya) | `Aramis#7984` | +| Aramis Sennyey | | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | | Brian Fletcher | Roadie.io | [punkle](https://github.com/punkle) | `Brian Fletcher#7051` | | Carlos Esteban Lopez Jaramillo | VMWare | [luchillo17](https://github.com/luchillo17) | `luchillo17#8777` | | David Tuite | Roadie.io | [dtuite](https://github.com/dtuite) | `David Tuite (roadie.io)#1010` | | Deepankumar Loganathan | | [deepan10](https://github.com/deepan10) | `deepan10` | | Himanshu Mishra | Harness.io | [OrkoHunter](https://github.com/OrkoHunter) | `OrkoHunter#1520` | | Irma Solakovic | Roadie.io | [Irma12](https://github.com/Irma12) | `Irma#7629` | -| Jamie Klassen | VMware | [jamieklassen](https://github.com/jamieklassen) | `jamieklassen#3047` | | Jorge Lainfiesta | Roadie.io | [jorgelainfiesta](https://github.com/jorgelainfiesta) | `jorgel#8733` | | Jussi Hallila | Roadie.io | [Xantier](https://github.com/Xantier) | `Xantier#0086` | | Mark Avery | Cvent | [webark](https://github.com/webark) | `webark#8471` | @@ -174,6 +203,7 @@ Scope: The Scaffolder frontend and backend plugins, and related tooling. ## Emeritus Project Area Maintainers -| Maintainer | Organization | GitHub | Discord | -| ---------- | -------------- | ----------------------------------- | -------- | -| Paul Cowan | frontendrescue | [dagda1](https://github.com/dagda1) | `dagda1` | +| Maintainer | Organization | GitHub | Discord | +| ------------- | -------------- | ----------------------------------------------- | ------------------- | +| Paul Cowan | frontendrescue | [dagda1](https://github.com/dagda1) | `dagda1` | +| Jamie Klassen | VMware | [jamieklassen](https://github.com/jamieklassen) | `jamieklassen#3047` | diff --git a/README.md b/README.md index f7b74adee4..6cea4235e0 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ English \| [한국어](README-ko_kr.md) \| [中文版](README-zh_Hans.md) ## What is Backstage? -[Backstage](https://backstage.io/) is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly without compromising autonomy. +[Backstage](https://backstage.io/) is an open source framework for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly without compromising autonomy. Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end. diff --git a/app-config.yaml b/app-config.yaml index c53a6475f4..9e5b5c468c 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -32,6 +32,12 @@ backend: # auth: # keys: # - secret: ${BACKEND_SECRET} + + auth: + # TODO: once plugins have been migrated we can remove this, but right now it + # is require for the backend-next to work in this repo + dangerouslyDisableDefaultAuthPolicy: true + baseUrl: http://localhost:7007 listen: port: 7007 @@ -236,11 +242,10 @@ catalog: - Domain - Location providers: - openapi: + backstageOpenapi: plugins: - catalog - search - - todo processors: ldapOrg: @@ -390,9 +395,10 @@ auth: development: clientId: ${AUTH_ATLASSIAN_CLIENT_ID} clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET} - scopes: ${AUTH_ATLASSIAN_SCOPES} - myproxy: - development: {} + scope: ${AUTH_ATLASSIAN_SCOPES} + myproxy: {} + guest: {} + costInsights: engineerCost: 200000 engineerThreshold: 0.5 diff --git a/beps/0001-notifications-system/README.md b/beps/0001-notifications-system/README.md index e3507d05fa..4b4f3b0532 100644 --- a/beps/0001-notifications-system/README.md +++ b/beps/0001-notifications-system/README.md @@ -95,8 +95,8 @@ The role of the notifications plugin is to manage the lifecycle of notifications The notification backend stores notification using the [database service](https://backstage.io/docs/backend-system/core-services/index#database). In particular it needs to store the following information for each notification: - ID +- Recipients - Read date -- Done date - Saved status - Creation date - Updated date (optional, for scoped notifications) @@ -104,8 +104,8 @@ The notification backend stores notification using the [database service](https: - Title - Description (optional) - Origin - - Link - - Recipients + - Link (optional) + - Additional links (optional) - Severity (optional, default normal) - Topic (optional) - Scope (optional) @@ -113,6 +113,10 @@ The notification backend stores notification using the [database service](https: The recipients is **not** a list of users, but rather a filter that describes who should receive the notification. It must be possible to evaluate this filter in a database query, so that we can efficiently fetch all notifications for a given user. The same filter will also be used by the signal backend to determine which users should receive a signal. +The read date is a timestamp of marking the notifications as read by the user. If missing, the notification is still unread. + +The saved status is a timestamp indicating when/if the user marked the notification for better visibility in the future (to "pin" the message). Can be undefined. + The title is mandatory human-readable text shortly describing the notifications. The description is an optional human-readable text providing more details to the user. @@ -143,11 +147,15 @@ The link is a relative or absolute URL. As an example, it can be used: - by an external system to request an action within an asynchronous task - by a BE plugin to provide link to other part of the Backstage UI (i.e. to the Catalog) +The additional links are an array of title-URL pairs. They can represent immediate actions on the notification (i.e. yes-no) or lead the user to additional details. + The `notification-backend` does not provide any new permissions, since creating notifications can only be done by other backend plugins, while reading notifications can only be done by the authenticated user. It is possible that we want to add a permissions for reading notifications, in particular for admin and impersonation use cases, but that is not part of this proposal or the initial implementation. The `notification-backend` shall provide necessary parameters for paging and filtering notifications from the frontend. -The notification frontend plugin provides a UI for viewing notifications, which in the initial implementation can be as simple as needed. The only requirement is that a user is able to view recent notifications and distinguish between read and unread notifications. A notification as marked as read once it has been interacted with. The frontend plugin also subscribes to the notifications signal channel and alerts the user when a new notification is received. +The notification frontend plugin provides a UI for viewing notifications, which in the initial implementation can be as simple as needed. The only requirement is that a user is able to view recent notifications and distinguish between read and unread notifications. The frontend plugin also subscribes to the notifications signal channel and alerts the user when a new notification is received. + +Both the individual and broadcast messages are rendered together in a single list. There will be a filter choosing among those types or `all`. ### Architecture Overview @@ -159,11 +167,12 @@ The components that are presented with dashed lines are not directly part of thi Let's walk through the process of sending of a notification to a user: -1. A backend plugin that wants to send a notification to a user uses the `NotificationService`, which in turn makes a POST request to the notification backend. The request contains a filter to select the target users, as well as the notification payload. +1. A backend plugin that wants to send a notification to a user uses the `NotificationService`, which in turn makes a POST request to the notification backend. The request contains either a filter to select the target users or type `broadcast`, as well as the notification payload. 1b. As the notification backend handles the request it could optionally invoke a series of notification processors. These processors can be used to transform the notification payload, send the notification through other channels, and decide whether the regular notification flow should continue or not. This step is not in scope for this proposal. 2. The notification backend stores the received notification in its database. At this point the notification is available from the notification backend's read API. + 3. The notification backend published an event to the event bus on the `'signal'` topic. This event payload contains the signaling channel, in this case `'notifications'`, as well as the target user ID and the notification ID, but not the notification payload. 4. Each instance of the signal backend plugin subscribes to the `'signal'` topic and receives the event. 5. Each signal backend instance has a set of push channels set up to online users. The incoming event is filtered based on the target user ID and the signaling is pushed through all connections with a matching user ID. @@ -208,6 +217,7 @@ export type NotificationPayload = { export type Notification = { id: string; userRef: string; + isBroadcast: boolean; created: Date; saved?: Date; read?: Date; @@ -226,12 +236,29 @@ interface NotificationService { } ``` -Each notification is always routed to individual users unless it's a broadcast. The `notification-backend` will figure out which users will receive a notification based on the `recipients` parameter, resolving it to the concrete list of users at the time of sending the notification. - -Each notification contains a `title` and a `link` for user to see further information. The `created`, `id`, `read` and `saved` properties are handled by the backend based and cannot be changed during the notification creation. +Each notification contains a human readable `title`, `origin` and optionally `link` for additional details. The `created`, `id`, `read` and `saved` properties are handled by the backend based and cannot be passed during the notification creation. Calling `sendNotification` should never throw an error so that it doesn't block the current processing. Notifications should be considered as second-level citizens that are not critical if not delivered. +Each notification is always routed to individual users unless its type is `broadcast`. + +##### Individual user notifications + +The `notification-backend` will figure out which users will receive a notification based on the `recipients` parameter, resolving it to the concrete list of users at the time of sending the notification. + +##### Broadcast notifications + +Broadcast messages are stored in a separate database table for performance reasons and simplicity of queries. +There is only one record per message. + +To maintain flags, there will be another table with 1:N relation. This table will contain `user`, `read`, `saved` and `updated` columns, linked via message ID foreign-key. +This table of flags is not prefilled on a broadcast message creation but a record is added when there is an updating POST by a particular user. + +When notifications are queried, two (main) database queries are issued - for both the individual and broadcast messages. +Their results are merged into a single response but setting the `isBroadcast` flag based on source. + +If an individual message is queried (via GET `/notifications/:id`), both the individual and broadcast tables are searched. The first result found is used for the response. + #### `SignalService` ```ts @@ -263,7 +290,6 @@ Example signal payload for a new notification: #### Future considerations and BEP TODO -- Broadcast messages are to be saved to a separate table for performance reasons - OpenAPI tooling is taken into use for the notification router and client - Allow using dynamic values in notification payload, for example entity references `{{ user:default/john.doe }}` should be rendered by the frontend with `EntityRefLink` component. Defining the dynamic data values should be done before implementation. - Add configurable automatic clean-up of old notifications to save storage space @@ -273,37 +299,31 @@ Example signal payload for a new notification: Notification frontend shows users their own notifications in its own page and the number of unread notifications in the main menu item. -By default, notifications that are `undone` will be shown in the notifications view. The notification `read` status is indicated by the UI. +Notifications are set to `read` when the `Mark as read` action is triggered by the user (bulk or single). -Notifications are set to `read` when the notification link is opened or the notification is set as `done` by the user. +Notifications can be saved for better visibility in the future. -Notifications can be set to `done` by the user, and they are filtered out of the main view. +Notifications can be filtered by `read`, `saved`, `content` (text search in title or description), `created` (since multiple predefined options) and `severity`. -Notifications can be saved for later use by the user. - -Notifications can be filtered by their `read`, `done` and `saved` statuses. - -Notifications are displayed in pages. - -User can search for notifications based on their title and description. +Notifications are displayed in pages. To do so, the backend needs to implement filtering and sorting. The following frontend API is added as part of this proposal. #### `NotificationsApi` ```ts -export type NotificationType = 'undone' | 'done' | 'saved'; +export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; export type GetNotificationsOptions = { - type?: NotificationType; offset?: number; limit?: number; search?: string; + createdSince?: Date; + severity?: NotificationSeverity; }; export type NotificationUpdateOptions = { ids: string[]; - done?: boolean; read?: boolean; saved?: boolean; }; @@ -358,7 +378,7 @@ interface SignalApi { - Replace absent signal service with long polling. This requires changes to the `signals` plugin as well. - Render dynamic values with various different React elements such as the `EntityRefLink` for entity references (for example `{{ user:default/john.doe }}`) in the notification payload -- Handle `link` values that use route references. For example instead hard-coding link to `/catalog/default/component/artist-web` it should be possible to use `catalogPlugin.catalogEntity` route reference as a link of the notification. This should also allow using parameters to be passed to the route reference +- Handle `link` values that use route references. For example instead hard-coding link to `/catalog/default/component/artist-web` it should be possible to use `catalogPlugin.catalogEntity` route reference as a link of the notification. This should also allow using parameters to be passed to the route reference. Links to external systems are still supported. - Add support for `analyticsApi` to notification actions like marking notifications done, saved or opening links in the notifications - Add support for user settings to control how notifications are shown to the user and which notifications user wants to receive. This should also include support for different `NotificationProcessor`s that can send notification to external systems - Add a sound to be played when notification is received diff --git a/beps/0003-auth-architecture-evolution/README.md b/beps/0003-auth-architecture-evolution/README.md index dc475fa14d..33bf80a099 100644 --- a/beps/0003-auth-architecture-evolution/README.md +++ b/beps/0003-auth-architecture-evolution/README.md @@ -1,6 +1,6 @@ --- title: Auth Architecture Evolution -status: implementable +status: implemented authors: - '@Rugvip' owners: @@ -68,9 +68,9 @@ Two new backend service interfaces are introduced to support these new features. The proposed design leaves the decision for how different endpoints are protected to the implementation of the plugin backends themselves. This includes whether particular routes should allow anonymous access, access from users authenticated via a cookie, or perhaps only allow access from other plugin backends and external services. This means that integrators do not need to - and do not have the ability to - configure access controls of individual endpoints, except for what the permission system already provides, and what is made available through static configuration or extension points. -In order to allow for cookie-based authentication of incoming user requests, the `auth` plugin backend is extended to be able to issue user tokens with reduced scope, which in turn integrate with the new `AuthService` and `HttpAuthService`. The ability to use cookie auth for requests is an opt-in per route and is only be permitted for read methods (`GET`, `HEAD`, `OPTIONS`). The actual implementation of cookie-based flows will be up to each plugin, but with significant help from the new auth service interfaces. +To ensure a secure-by-default design, there is a default access control policy that applies to all plugin routes, known as the "default auth policy". This policy is to only allow access from authenticated users and services, and is implemented in the `HttpRouterService` interface. In order to allow either unauthenticated access or cookie-based access, a plugin must opt-out of the default auth policy for specific path prefixes, effectively leaving the access control implementation to the plugin itself. This is done through the new `addAuthPolicy` method that is added to the `HttpRouterService` interface. -In order to allow either unauthenticated access or cookie-based access, a plugin must explicitly opt-in the specific path prefixes that these should be available at. This is done through a new method that is added to the `HttpRouterService` interface. +In order to allow for cookie-based authentication of incoming user requests, the `AuthService` is able to issue user tokens with limited scope. These limited scope tokens can still be used to fetch user information and in on-behalf-of service calls, but they are rejected by the default auth policy. The `HttpAuthService` provides a standardized way of handling cookies, which integrates with the `'user-cookie'` auth policy. The limited tokens can also be used in other contexts where it is beneficial to avoid storing full user credentials, but instead use credentials that can be upgraded in a controlled manner, such as scaffolder tasks. The `AuthService` implementation can choose to have a longer expiry of the limited tokens compared to the full user tokens, but this is not a requirement. For service-to-service communication we will move away from reusing user tokens in upstream requests. We will instead implement an "On-Behalf-Of" flow where incoming user credentials are encapsulated in a service token for the upstream request. In line with this the new auth service interfaces will aim to make it difficult to directly forward credentials from incoming requests, and instead encourage that plugin backends issue new service credentials for upstream requests. @@ -98,7 +98,7 @@ export type BackstageUserPrincipal = { }; export type BackstageServicePrincipal = { - type: 'user'; + type: 'service'; // Exact format TBD, possibly 'plugin:<pluginId>' or 'external:<externalServiceId>' subject: string; @@ -110,6 +110,8 @@ export type BackstageServicePrincipal = { export type BackstageCredentials<TPrincipal = unknown> = { $$type: '@backstage/BackstageCredentials'; + expiresAt?: Date; + principal: TPrincipal; }; @@ -120,13 +122,20 @@ export type BackstagePrincipalTypes = { }; export interface AuthService { - authenticate(token: string): Promise<BackstageCredentials>; + authenticate( + token: string, + options?: { + allowLimitedAccess?: boolean; + }, + ): Promise<BackstageCredentials>; isPrincipal<TType extends keyof BackstagePrincipalTypes>( credentials: BackstageCredentials, type: TType, ): credentials is BackstageCredentials<BackstagePrincipalTypes[TType]>; + getNoneCredentials(): Promise<BackstageCredentials<BackstageUserPrincipal>>; + getOwnServiceCredentials(): Promise< BackstageCredentials<BackstageServicePrincipal> >; @@ -135,6 +144,10 @@ export interface AuthService { onBehalfOf: BackstageCredentials; targetPluginId: string; }): Promise<{ token: string }>; + + getLimitedUserToken( + credentials: BackstageCredentials<BackstageUserPrincipal>, + ): Promise<{ token: string; expiresAt: Date }>; } ``` @@ -149,6 +162,7 @@ export interface BackstageUserInfo { } export interface UserInfoService { + // The implementation of this method should support both regular and limited user credentials getUserInfo(credentials: BackstageCredentials): Promise<BackstageUserInfo>; } ``` @@ -159,7 +173,7 @@ The `UserInfoService` is exported by `@backstage/auth-node`, and the initial imp > Open question: Should this instead be added to the `HttpAuthService`? It may fit a bit better there, but on the other hand it might make sense to add additional policies unrelated to authentication too, such as rate limiting. -The `HttpRouterService` interface will be extended with the ability to opt-out of the default protection of endpoints, enabling either cookie auth or unauthenticated access. +The `HttpRouterService` interface will be extended with the ability to opt-out of the default protection of endpoints, enabling cookie or unauthenticated access. ```ts export interface HttpRouterServiceAuthPolicy { @@ -201,7 +215,7 @@ export default createBackendPlugin({ This is expected to be the pattern for the vast majority of plugins. -#### A plugin with an endpoint that only allows cookie auth +#### A plugin with a cookie-based authentication endpoint ```ts export default createBackendPlugin({ @@ -209,11 +223,25 @@ export default createBackendPlugin({ register(env) { env.registerInit({ deps: { + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, http: coreServices.httpRouter, }, - async init({ http }) { + async init({ auth, httpAuth, http }) { + const router = Router(); + + // Endpoint that sets the cookie for the user + router.get('/cookie', async (req, res) => { + const { expiresAt } = await httpAuth.issueUserCookie(res); + + res.json({ expiresAt: expiresAt.toISOString() }); + }); + + // Endpoint protected by cookie auth + router.get('/static', express.static(/* ... */)); + // The order of these two calls does not matter - http.use(await createRouter(/* ... */)); + http.use(router); http.addAuthPolicy({ path: '/static', allow: 'user-cookie', @@ -224,7 +252,7 @@ export default createBackendPlugin({ }); ``` -#### A plugin that allows both public access and cookie auth +#### A plugin that disabled the default auth policy and handles auth by itself ```ts export default createBackendPlugin({ @@ -236,15 +264,8 @@ export default createBackendPlugin({ }, async init({ http }) { http.use(await createRouter(/* ... */)); - http.addAuthPolicy({ path: '/', - allow: 'user-cookie', - }); - - // Unauthenticated access takes precedence, the /public endpoint does not require cookie auth - http.addAuthPolicy({ - path: '/public', allow: 'unauthenticated', }); }, @@ -274,16 +295,19 @@ export interface HttpAuthService { req: Request, options?: { allow?: Array<TAllowed>; - allowedAuthMethods?: Array<'token' | 'cookie'>; + allowLimitedAccess?: boolean; }, ): Promise< BackstageCredentials<BackstageHttpAccessToPrincipalTypesMapping[TAllowed]> >; - // The cookie issued by this method must be consumable by the `credentials` method, which in turn - // should create a credentials object that can be passed to the `getPluginRequestToken` method. - // The issued token must then in turn be a valid token for a user principal with full access. - issueUserCookie(res: Response): Promise<void>; + issueUserCookie( + res: Response, + options?: { + // If credentials are not provided, they will be read from the request + credentials?: BackstageCredentials<BackstageUserPrincipal>; + }, + ): Promise<{ expiresAt: Date }>; } ``` @@ -377,41 +401,22 @@ router.get('/read-data', (req, res) => { }); ``` -#### Issuing a cookie and allowing user cookie auth on a separate endpoint +#### Using limited user tokens to access user info ```ts -router.get('/cookie', async (req, res) => { - await httpAuth.issueUserCookie(res); // If this is a service call it'll throw - res.json({ ok: true }); +router.get('/read-data', (req, res) => { + const credentials = await httpAuth.credentials(req, { + allow: ['user'], + allowLimitedAccess: true, + }); + + const { userEntityRef, ownershipEntityRefs } = await userInfo.getUserInfo( + credentials, + ); + + console.log(`User ref=${userEntityRef} ownership=${ownershipEntityRefs}`); + // ... }); - -// Allowing cookie auth is a separate step where you call the addAuthPolicy method -// of the httpRouter API in your plugin setup code. -httpRouter.addAuthPolicy({ - path: '/static', - allow: 'user-cookie', -}); - -// Separate endpoint that serves static content, allowing user cookie auth as -// well as the default user and service auth methods -router.use('/static', express.static(staticContentDir)); -``` - -#### Passing along user identity from a cookie in an upstream request - -```ts -router.get( - '/read-data', - httpAuth.middleware({ allow: ['user-cookie'] }), - (req, res) => { - const credentials = await httpAuth.credentials(req, { allow: ['user'] }); - const { ownershipEntityRefs } = await userInfo.getUserInfo(credentials); - console.log( - `User ref=${credentials.userEntityRef} ownership=${ownershipEntityRefs}`, - ); - // ... - }, -); ``` ### Access Control Configuration @@ -425,6 +430,79 @@ backend: The exact impact that this has is that it disables the check in the `HttpRouterService` implementation, effectively applying the `unauthenticated` access level to all routes. Furthermore, it will also change `AuthService` so that the `getPluginRequestToken()` method will now issue an empty token for a `'none'` principal, rather than throwing. +### Token Details + +Note that this section is NOT normative. It illustrates the token shapes and major token flows that are involved in this proposal, but intentionally leaves out some low level details and is subject to change. + +#### Backstage Identity Tokens + +These are the regular tokens, commonly in short referred to just as "Backstage Tokens", that the auth backend generates for the user during sign-in. These are sent along with calls to backend plugins to identify the user. This BEP does not aim to change the shape of these tokens; this section is only here for informative purposes to convey what pieces of information that are at play. + +This is a JWT token. + +```yaml +# Header +{ + "alg": "ES256", + "kid": "4f5a0543-894a-4176-b0b7-699a7026b72f" +} +# Payload +{ + "iss": "http://localhost:7007/api/auth", + "sub": "user:default/example-user", + "ent": ["user:default/example-user", "group:default/my-team"], + "aud": "backstage", + "iat": 1708333140, + "exp": 1708336740 +} +``` + +The key ID is some random UUID. The `iss` (issuer) is the external base URL of your auth backend. Note that it uses the `ES256` asymmetric signature algorithm, and the auth backend exposes a JWKS that contains the public parts of the signing keys. The `sub` is an entity ref denoting who the signed in user is, and the `ent` is an array of entity refs that they claim ownership through. The `aud` (audience) is hardcoded to the string `"backstage"` always. + +#### Legacy Service Tokens + +These are the tokens that have been used for backend-to-backend communications before this BEP, and they will likely have changes as part of this work. + +This is a JWT token. + +```yaml +# Header +{ + "alg": "HS256" +} +# Payload +{ + "sub": "backstage-server", + "exp": 1708337056 +} +``` + +Note that unlike the identity token in the previous section, it uses the `HS256` symmetric signature algorithm. The key used is the first of the `backend.auth.keys` entries in your `app-config`, which is a shared secret among all backend plugins, enabling them to know that the caller is a legitimate one. But the token does not contain any information about who the caller is (it's just a generic `"backstage-server"`), nor who the receiver (audience) is. + +#### New Cookie Token Flow + +Some plugins serve static content that the browser engine requests directly, e.g. the TechDocs plugin. Those calls cannot easily have a bearer token attached to them. For these use cases a cookie based flow will be used instead. + +![Cookie token sequence diagram](./token-sequence-cookie.drawio.svg) + +The frontend part of the plugin ensures that a cookie endpoint on the backend part of the plugin is called before attempting to render static content. This endpoint validates the user's identity token and sets a corresponding cookie on the response. Subsequent requests for getting static content will automatically have this cookie attached to them by the browser. + +We intentionally do not specify here how the cookie token is acquired. It might be issued by the plugin itself or by the auth backend depending on how the architecture evolves, but this does not have any effect on plugin code. + +The cookie token contains the user's identifying information just like the identity cookie but is severely limited. It has the plugin itself specified as its audience. Thus, this token is not usable in any bearer token context, nor as a cookie toward any other plugin. + +#### New Service OBO Token Flow + +When a backend service needs to in turn make a request to another upstream service to fulfil the original request, it uses an On-Behalf-Of (OBO) token for the purpose. + +![OBO token sequence diagram](./token-sequence-obo.drawio.svg) + +The initial request in this picture is a frontend plugin, but the same concept applies if it is initiated by a service. The scaffolder backend in this example acquires an OBO token to be able to talk to the catalog plugin. + +We intentionally do not specify here how the OBO token is acquired. It might be issued by the plugin itself or by the auth backend depending on how the architecture evolves, but this does not have any effect on plugin code. + +The OBO token specifies the target service as its audience and itself as the subject, but additionally also contains the original caller's identifying information. Thus, the target service can identify who the nearest caller is but also apply permissions that are relevant to the original caller. The token is thus scoped to not be usable toward other backend plugins. + ## Release Plan The existing `IdentityService` and `TokenManagerService` will be deprecated and instead implemented in terms of the new `AuthService`. @@ -433,10 +511,11 @@ The new `AuthService` and `HttpAuthService` will need backwards compatible imple The backwards compatibility helpers will have the following behavior for each individual service call: -- `auth.authenticate(token)`: If the decoded token has the `backstage` audience, authenticate the token for a user principal using `identity.getIdentity(...)`, otherwise authenticate it using `tokenManager.authenticate(...)` and return a service principal with the subject `external:backstage-plugin`. If a no-op token manager is used then anything but a user token will be treated as a valid service token, which is consistent with existing behavior. +- `auth.authenticate(token, options)`: If the decoded token has the `backstage` audience, authenticate the token for a user principal using `identity.getIdentity(...)`, otherwise authenticate it using `tokenManager.authenticate(...)` and return a service principal with the subject `external:backstage-plugin`. If a no-op token manager is used then anything but a user token will be treated as a valid service token, which is consistent with existing behavior. The limited access option is ignored. - `auth.getOwnServiceCredentials()`: Use original implementation. - `auth.isPrincipal()`: Use original implementation. - `auth.getPluginRequestToken(options)`: Same behavior as the original implementation, using the `tokenManager` to issue service tokens, with the exception that a `none` principal will translate to an empty token rather than an error in order to properly forward calls with a no-op token manager. +- `auth.getLimitedUserToken(credentials)`: This is a no-op and returns the underlying user token with full scope. - `httpAuth.credentials(...)`: Use original implementation. - `httpAuth.issueUserCookie(...)`: This is a no-op as we do not need to support cookie auth in the legacy adapter. @@ -475,9 +554,9 @@ Cons: - Can be extremely confusing because the top-level middleware for more lax access will also apply to the more strict access levels. For example ```ts - const cookieRouter = Router(); - cookieRouter.use(rateLimit()); - http.useWithCookieAuthentication(cookieRouter); + const publicRouter = Router(); + publicRouter.use(rateLimit()); + http.useWithoutAuthentication(publicRouter); const mainRouter = Router(); // rateLimit() will apply here too @@ -487,7 +566,7 @@ Cons: This applied to any similar way of structuring this API, such as a single `.use()` method with additional options: ```ts -http.use(cookieRouter, { allow: ['user-cookie'] }); +http.use(publicRouter, { allow: ['unauthenticated'] }); ``` #### Separate configuration on different paths for `use` diff --git a/beps/0003-auth-architecture-evolution/token-sequence-cookie.drawio.svg b/beps/0003-auth-architecture-evolution/token-sequence-cookie.drawio.svg new file mode 100644 index 0000000000..b20b528c35 --- /dev/null +++ b/beps/0003-auth-architecture-evolution/token-sequence-cookie.drawio.svg @@ -0,0 +1,203 @@ +<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="391px" height="261px" viewBox="-0.5 -0.5 391 261" content="<mxfile><diagram id="Wjgsm-kAhxxm43YMIDME" name="Page-1">5VrbcqM4EP0aP8YFyGD8OHbizEN2a2ozVbv7KIOwVZGRI+Qk3q/fFkjchG8xziQ1TNUUanSBc7qPuuUM0Gz9di/wZvUHjwkbeE78NkC3A88beS78rwy7wuAHQWFYChoXJrcyPNL/iDY62rqlMckaHSXnTNJN0xjxNCWRbNiwEPy12S3hrLnqBi/1ik5leIwwI1a3v2ksV/qzwlrv74QuV2ZlXz9Y4OhpKfg21csNPDTPr+LxGpupdP9shWP+WjOhuwGaCc5lcbd+mxGmkDWoFePme56Wry1IKk8ZgPxixAtmW/3pEedPlCjQGLxZ8ZZyZ4CBF96o2+2azQVew+30dUUledzgSNlfwR3AtpJrBi1XPdb4AXZgN6Ah1UooYzPOuMjnRkmSeFEE9kwK/kRqT+JgEfiBGsFTWbM7+QV2+7s1FC9ESPJWM2kc7glfEyl20EU/Ndxqj3UNRa8V/2iibas696Yj1j63LKeugIcbjX03D57Nw1R5MRGHGHigCWE0VSRsiKCwKlHAMG3+UdmOkQRxJDEMEWWbMbzJ6CJfVSEsSLQVGX0hf5GsCFdl5VupVpqVYdhBa4xJmHTSGkQhWSTXpdUNmrwGNq1hB6tlv0tYRSOLVYvOGgkbTlOZL+dPB/5ti1Uu5IoveYpZndd2CPnqn41ocXVykF+dWJdOeTLYRk401hMba7cD616gDo9DTWLQeN1MeR42NfQziYX8pvaO6vF+TDK+FRFp0gwTLEmrn1rzIHKCMCwhrJpb2CVIuBYSP0m0inmUDbyAwftNF6AqwVLdTWG/IrBZfX2R8UkYj7ocPPQWKLjy3oG8XygywZcWGXQ+2E2RcZ3TVGbUB9bjS1Vmr7P1JxT5UBAyvKt10LRXM/9QhgpUK/0JnBYwxYx7Rjt+5+hy+UIu9ah6PtqaCPlHJio01pooJ64E6yQuR7ZO3t/9HKhInpscuIPaB7yAUqfBKWZ0mcJ9BJzm8aJ8mUIx8U0/WNM4VnOAvoGs4Urv7GBUIaXLoVA353hNmcJjBiBSlRE6f5LX7mAy/tkOprJS0osP6uVGV5A5QxDHoMlF0TrPDy2Gb9xRY9Ybd9KcgidJRi4m17k0UAFTsftHNYYO8ozhX0XccDIZG8Ptm6ayaO3qrZqE5sYYZysSl/PHJtngG5IWljlVX3R7cFf6ZELhOecIRTu+zeizhQIUZ4i8pn9OJsMwvJpceJZH5W7qlPUyT3Pwsw1Ps8+gHbYHlVFxsTzcgD4Eo7AfRWi6xE27nu5HEM4rxdosLLiUfA0PmKJwWp7ymBxH60ctqCOGs4xGjbh22yJwlLHumG+WGmiPDtTzIbONXkgVhOsQoXDsTILxeOROINtrRHPY07YPEw1diOfyOimqL5ay8ICUvcfn7EOdhTnUAb8DIqIi8iTJX0uQ5y3Jijf+fNphAqiH1ML1fLeVBPSjJOOWkrRm6EdJ7Hqr3AIklD2pRV+uFHnMO8eL5BoR4yucpXXQZ+nNXubKDcQETKABP1Lnuj2UXiO79PpdYXfDD4TdPlfbFgJGY3h9Kne/If6jj8Pft6tUc4qnvhieJFifQwbPW/Wz0fQ7YS9E7QOVyRz34eh5SwWpZ62au/bB4AJnQJ1OajXje7oaC3xK8UrGfKDeqs6Z7ipr197GSKImy8BxaLp8yFu3XjPVWjAePaldruFwB0vntrvtcZ5aEejmJ1u1ItDzS8M5ReDhBHJPune6r6rEHDmjXrZTFLQOAManpXfn5mHlz2qtdfZmi+3+k7NK0CCAytHKLau5huZE9Ui6Wc3ca37h24WmFUqfpFJ5j59+QFXiNdPA8meo86uSydA/PNW1KpFDHv0en/o61e/X8Cn03nMr26esqa7kU+jQQd1xn4Jm9WcpRffqL3/Q3f8=</diagram></mxfile>" style="background-color: rgb(255, 255, 255);"> + <defs/> + <g> + <path d="M 0 60 L 80 60 L 80 75 L 70 90 L 0 90 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/> + <path d="M 80 60 L 390 60 L 390 180 L 0 180 L 0 90" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 75px; margin-left: 1px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + cookie flow + </div> + </div> + </div> + </foreignObject> + <text x="40" y="79" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"> + cookie flow + </text> + </switch> + </g> + <rect x="80" y="0" width="80" height="40" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/> + <path d="M 120 40 L 120 260" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 20px; margin-left: 81px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + Browser + </div> + </div> + </div> + </foreignObject> + <text x="120" y="24" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"> + Browser + </text> + </switch> + </g> + <rect x="115" y="90" width="10" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/> + <rect x="240" y="0" width="80" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/> + <path d="M 280 40 L 280 260" fill="none" stroke="#82b366" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 20px; margin-left: 241px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + Techdocs + <br/> + Backend + </div> + </div> + </div> + </foreignObject> + <text x="280" y="24" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"> + Techdocs... + </text> + </switch> + </g> + <rect x="275" y="100" width="10" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"/> + <path d="M 125 100 L 190 100 Q 200 100 210 100 L 268.63 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/> + <path d="M 273.88 100 L 266.88 103.5 L 268.63 100 L 266.88 96.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 80px; margin-left: 186px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: "Courier New"; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + GET /cookie + </div> + </div> + </div> + </foreignObject> + <text x="186" y="83" fill="rgb(0, 0, 0)" font-family="Courier New" font-size="8px" text-anchor="middle"> + GET /cookie + </text> + </switch> + </g> + <path d="M 275 140 L 210 140 Q 200 140 190 139.98 L 127.56 139.88" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/> + <path d="M 133.44 136.39 L 126.44 139.88 L 133.43 143.39" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 120px; margin-left: 200px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + set cookie on response + </div> + </div> + </div> + </foreignObject> + <text x="200" y="123" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="8px" text-anchor="middle"> + set cookie on response + </text> + </switch> + </g> + <path d="M 120.34 220 L 190 220 Q 200 220 210 220 L 273.13 220" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/> + <path d="M 278.38 220 L 271.38 223.5 L 273.13 220 L 271.38 216.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 200px; margin-left: 203px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + browser static content requests + </div> + </div> + </div> + </foreignObject> + <text x="203" y="203" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="8px" text-anchor="middle"> + browser static content requests + </text> + </switch> + </g> + <rect x="160" y="207" width="80" height="10" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 212px; margin-left: 161px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 7px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + cookie token + </div> + </div> + </div> + </foreignObject> + <text x="200" y="214" fill="#000000" font-family="Helvetica" font-size="7px" text-anchor="middle"> + cookie token + </text> + </switch> + </g> + <rect x="160" y="127" width="80" height="10" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 132px; margin-left: 161px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 7px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + cookie token + </div> + </div> + </div> + </foreignObject> + <text x="200" y="134" fill="#000000" font-family="Helvetica" font-size="7px" text-anchor="middle"> + cookie token + </text> + </switch> + </g> + <rect x="160" y="87" width="80" height="10" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 92px; margin-left: 161px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 7px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + user identity token + </div> + </div> + </div> + </foreignObject> + <text x="200" y="94" fill="#000000" font-family="Helvetica" font-size="7px" text-anchor="middle"> + user identity token + </text> + </switch> + </g> + <path d="M 286 110 L 310 110 L 310 130.4 L 294.45 130.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/> + <path d="M 287.45 130.36 L 294.45 126.87 L 294.44 133.87 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 119px; margin-left: 314px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: left;"> + <div style="display: inline-block; font-size: 7px; font-family: "Courier New"; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"> + <font face="Helvetica"> + acquire cookie token + <br/> + based on user token + <br/> + </font> + </div> + </div> + </div> + </foreignObject> + <text x="314" y="121" fill="#000000" font-family="Courier New" font-size="7px"> + acquire cookie token... + </text> + </switch> + </g> + <path d="M 120.34 230 L 190 230 Q 200 230 210 230 L 273.13 230" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/> + <path d="M 278.38 230 L 271.38 233.5 L 273.13 230 L 271.38 226.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <path d="M 120.34 240 L 190 240 Q 200 240 210 240 L 273.13 240" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/> + <path d="M 278.38 240 L 271.38 243.5 L 273.13 240 L 271.38 236.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + </g> + <switch> + <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/> + <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"> + <text text-anchor="middle" font-size="10px" x="50%" y="100%"> + Text is not SVG - cannot display + </text> + </a> + </switch> +</svg> diff --git a/beps/0003-auth-architecture-evolution/token-sequence-obo.drawio.svg b/beps/0003-auth-architecture-evolution/token-sequence-obo.drawio.svg new file mode 100644 index 0000000000..f337f8b572 --- /dev/null +++ b/beps/0003-auth-architecture-evolution/token-sequence-obo.drawio.svg @@ -0,0 +1,203 @@ +<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="401px" height="251px" viewBox="-0.5 -0.5 401 251" content="<mxfile><diagram id="Wjgsm-kAhxxm43YMIDME" name="Page-1">7VrbcuI4EP0aHkP5jnkcIGQeMrupzVbt7qOwhVFFWIwsh7Bfvy1bvsgywSQwyWyNU5Wy2rrY3eecbikZufPtyx1Hu803FmM6cqz4ZeQuRo7jOTb8loZDafCDoDQknMSlyW4Mj+RfrIyWsuYkxpnWUTBGBdnpxoilKY6EZkOcs73ebc2ovuoOJWpFqzE8Rohio9tfJBYb9Vlhq/dXTJJNtbKvHqxQ9JRwlqdquZHjrourfLxF1VSqf7ZBMdu3TO7tyJ1zxkR5t32ZYyo9W3mtHLc88rR+bY5TMWSA45cjnhHN1afPpPcwV+8nDpVL4FV38jbf0nuyxpSk0JrtMCdbLKC/u6DK/NDYZvsNEfhxhyI5dA9YAdtGbCm0bLiF+AkEQ3jdphTtMrIqVrXAwnGU84w84z9wVsJEWlku5ErzOvzSuCaUzhllvHhhN0Y4XEdgzwRnT7j1JIhCvFrLEbB8y24VF9hNNyrPPmMu8EvLpNx6hxl8MT9Al+ppoEKsGFA19w2cKjRtWkhyKiQhheCknrkJI9yoSPZH1fWMqBrhbAVhx0gqiuX82chfdKLKuNiwhKWItuPa8fXalz+mR8urNwbF1evrGpSDne36mq+npq/tHl/b3iV8bRu+Bh1ZS8WRJAooLDZbybtE3s1AIDCow8/PLh+HsdcX2dBZuUVkr8gu1/lAdgU/Nbvc852ts8u2BtLLuYCzA7fH2SWppDNkbi/RD9bvuUybs6+YPmNBItSYKvah6HtOOJaxwvyZRPKOrVhRXQAtTbquUIZj2QmeWXmRFo91rSzwReWbVeYONHAMlYZqNtG/baxtBiNKklSSH6/lZBlQnaTJfdFaQMhmoCVfZL0DzRVl0ZPktCw/cFzRFt5libaEyujNWc5J8RG/4b16qIqvySuEBezww9/ylcZ2gbfC8I9cYez4tWHxotYsW4d2q4XuwkjRCtNZXS1Vq6as0L3SadJTegmIeIIrGAfHoH0UxzfW2HItlRs5pkiA8OmlYw9S1XQPksbNXF6gc8LuYD0DT0dYDWrgDrFCh1Y3JQ5Hl5lYvcssB3Z3te5wU67fPzjoH1y/a+l945OaeaqObL3OsBh1WV4HZJjKTk6rbJtKCjkt7hxNM2Vs9FKpD1od/Jm4Og9D58a+zmBVQIJXovkGD3tm5fLw++OfIynbS4Gyp6zX4feSuf0qFYGni/wlcwsIMP2iHmxJHBfSxmWZgZr6w0yOLUkKCzET4GKWDlGzHkGoQNTNdfXOUb3LqL396tMOkA7L6nD+IkJyY3varDf2VJ/iImyqKt23s6mVA6xuDgjDN+WAGGWbIk/ZeiJjO8ivhWVJ5BctXi0afxhLj6qu6+shrIl7IhmYjLf8savSbnF15p1Mx9PAfHxCoN8CF8eAS5ZHEc4+gySYSKjR/W6ayxIh8MILMVsn9lV4be5F5kggypJfW8/jW88enBjCchQiXvhxW09vQFH0ybaeJ3xdAnjw1nMybOt5iYOdSgXeW4Aau5gBULtuYel5OoKds7YJbuD3jj472/n2iYkumM+mRizvblWlC7EggmDw13I8Hn+C/Dagxh2c6DpkC18l2+Vr3LqmDa+Q+3yzSDmToFpN6+g17XQ6+UE17ScUCHc6DkKdnJNzNMK3PZigKVTt3rnOVgyQnrHVvnSwOsF0HPrX0hDfPIkUeLuDOMhTxEJFDp9APd4lECWl/jfVsW+mcHWGS+IqYNVxbidw+iHqiWK3e4x64b9DvqtcdTrJ3q62DCfq1e6B5ltKKN9Mu0fO3a/o/Y/dLFidUsueXMv70Gz+b6AkS/OvGe7tfw==</diagram></mxfile>" style="background-color: rgb(255, 255, 255);"> + <defs/> + <g> + <rect x="0" y="0" width="80" height="40" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/> + <path d="M 40 40 L 40 250" fill="none" stroke="#6c8ebf" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 20px; margin-left: 1px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + Browser + </div> + </div> + </div> + </foreignObject> + <text x="40" y="24" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"> + Browser + </text> + </switch> + </g> + <rect x="35" y="90" width="10" height="140" fill="#f5f5f5" stroke="#666666" pointer-events="all"/> + <rect x="160" y="0" width="80" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/> + <path d="M 200 40 L 200 250" fill="none" stroke="#82b366" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 20px; margin-left: 161px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + Scaffolder + <br/> + Backend + </div> + </div> + </div> + </foreignObject> + <text x="200" y="24" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"> + Scaffolder... + </text> + </switch> + </g> + <rect x="195" y="100" width="10" height="120" fill="#f5f5f5" stroke="#666666" pointer-events="all"/> + <path d="M 206 110 L 230 110 L 230 130.4 L 214.45 130.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/> + <path d="M 207.45 130.36 L 214.45 126.87 L 214.44 133.87 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 119px; margin-left: 234px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: left;"> + <div style="display: inline-block; font-size: 7px; font-family: "Courier New"; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"> + <font face="Helvetica"> + acquire service obo token + <br/> + based on user token + <br/> + </font> + </div> + </div> + </div> + </foreignObject> + <text x="234" y="121" fill="#000000" font-family="Courier New" font-size="7px"> + acquire service obo token... + </text> + </switch> + </g> + <path d="M 45 100 L 110 100 Q 120 100 130 100 L 188.63 100" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/> + <path d="M 193.88 100 L 186.88 103.5 L 188.63 100 L 186.88 96.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 80px; margin-left: 106px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: "Courier New"; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + POST /tasks + </div> + </div> + </div> + </foreignObject> + <text x="106" y="83" fill="rgb(0, 0, 0)" font-family="Courier New" font-size="8px" text-anchor="middle"> + POST /tasks + </text> + </switch> + </g> + <path d="M 194 220 L 47.57 219.96" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/> + <path d="M 53.45 216.46 L 46.45 219.96 L 53.45 223.46" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 211px; margin-left: 124px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + success + </div> + </div> + </div> + </foreignObject> + <text x="124" y="214" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="8px" text-anchor="middle"> + success + </text> + </switch> + </g> + <rect x="320" y="0" width="80" height="40" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/> + <path d="M 360 40 L 360 250" fill="none" stroke="#82b366" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 20px; margin-left: 321px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + Catalog + <br/> + Backend + </div> + </div> + </div> + </foreignObject> + <text x="360" y="24" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle"> + Catalog... + </text> + </switch> + </g> + <rect x="355" y="170" width="10" height="40" fill="#f5f5f5" stroke="#666666" pointer-events="all"/> + <path d="M 205 170 L 270 170 Q 280 170 290 170 L 348.63 170" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/> + <path d="M 353.88 170 L 346.88 173.5 L 348.63 170 L 346.88 166.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 151px; margin-left: 280px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: "Courier New"; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + GET /entities/... + </div> + </div> + </div> + </foreignObject> + <text x="280" y="154" fill="rgb(0, 0, 0)" font-family="Courier New" font-size="8px" text-anchor="middle"> + GET /entities/... + </text> + </switch> + </g> + <path d="M 354.68 210 L 289.68 210 Q 279.68 210 269.68 209.98 L 207.24 209.85" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/> + <path d="M 213.13 206.37 L 206.12 209.85 L 213.11 213.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 201px; margin-left: 284px;"> + <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 8px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;"> + template entity + </div> + </div> + </div> + </foreignObject> + <text x="284" y="204" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="8px" text-anchor="middle"> + template entity + </text> + </switch> + </g> + <rect x="80" y="86" width="80" height="10" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 91px; margin-left: 81px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 7px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + user identity token + </div> + </div> + </div> + </foreignObject> + <text x="120" y="93" fill="#000000" font-family="Helvetica" font-size="7px" text-anchor="middle"> + user identity token + </text> + </switch> + </g> + <rect x="240" y="157" width="80" height="10" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/> + <g transform="translate(-0.5 -0.5)"> + <switch> + <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> + <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 162px; margin-left: 241px;"> + <div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"> + <div style="display: inline-block; font-size: 7px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> + service obo token + </div> + </div> + </div> + </foreignObject> + <text x="280" y="164" fill="#000000" font-family="Helvetica" font-size="7px" text-anchor="middle"> + service obo token + </text> + </switch> + </g> + </g> + <switch> + <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/> + <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"> + <text text-anchor="middle" font-size="10px" x="50%" y="100%"> + Text is not SVG - cannot display + </text> + </a> + </switch> +</svg> diff --git a/beps/0004-scaffolder-task-idempotency/README.md b/beps/0004-scaffolder-task-idempotency/README.md index a7e592af39..208446158e 100644 --- a/beps/0004-scaffolder-task-idempotency/README.md +++ b/beps/0004-scaffolder-task-idempotency/README.md @@ -5,6 +5,7 @@ authors: - 'bnechyporenko@bol.com' - 'benjaminl@spotify.com' owners: + - '@backstage/scaffolder-maintainers' project-areas: - scaffolder creation-date: 2024-01-31 @@ -15,8 +16,9 @@ creation-date: 2024-01-31 When editing BEPs, aim for tightly-scoped, single-topic PRs to keep discussions focused. If you disagree with what is already in a document, open a new PR with suggested changes. --> +<!-- Your short, descriptive title --> -# BEP: <!-- Your short, descriptive title --> +# BEP: Scaffolder Retries and Idempotency <!-- Before merging the initial BEP PR, create a feature issue and update the below link. You can wait with this step until the BEP is ready to be merged. --> @@ -39,7 +41,7 @@ It has to be crafted to a solution when action can be re-run multiple times and ## Motivation -The aim is to make task engine more reliable in terms of system crash or redeployment. If the task engine is in process of executing +The aim is to make the task engine more reliable in terms of system crash or redeployment. If the task engine is in process of executing tasks and system stops, after restart task engine will restore all such tasks and continue their execution. Another purpose is to make it possible to manually retry the task from the last failed step. @@ -81,12 +83,11 @@ We believe that idempotency is the best way to do it. Idempotency allows to reru ### Serialization of workspace -We believe that a serialization of workspace is a way to achieve re-running the task on a non-sticky way. -That means that the task can be restored and retried on a different scaffolder node. +We believe that serialization of workspaces is the way to achieve re-running the task in a non-sticky way. This means that the task can be restored and retried on a different scaffolder task worker. This serialization can be stored in the database, or perhaps additional modules could be installed to provide additional options for storing this serialized workspace data since it may be large in some cases. ### Secrets -Secrets will be stored for a longer period of time in the database and wiped out once the task going into a complete state (successfully finished or archived). +Secrets will be stored for a longer period of time in the database and wiped out once the task goes into a completed state (successfully finished or archived). Depending on the life of the task, it's possible that these secrets could expire. The refresh of these tokens is out of scope for now, but perhaps could be achieved by notifying the user that they need to go back to a task page to re-trigger the task. ## Design Details @@ -153,7 +154,7 @@ export function createGithubRepoCreateAction(options: { username: owner, }); - await ctx.checkpoint('v1.task.checkpoint.repo.creation', async () => { + await ctx.checkpoint('repo.creation', async () => { const repoCreationPromise = user.data.type === 'Organization' ? client.rest.repos.createInOrg({ @@ -168,19 +169,16 @@ export function createGithubRepoCreateAction(options: { }); if (secrets) { - await ctx.checkpoint( - 'v1.task.checkpoint.repo.create.variables', - async () => { - for (const [key, value] of Object.entries(repoVariables ?? {})) { - await client.rest.actions.createRepoVariable({ - owner, - repo, - name: key, - value: value, - }); - } - }, - ); + await ctx.checkpoint('repo.create.variables', async () => { + for (const [key, value] of Object.entries(repoVariables ?? {})) { + await client.rest.actions.createRepoVariable({ + owner, + repo, + name: key, + value: value, + }); + } + }); } ctx.output('remoteUrl', newRepo.clone_url); @@ -191,7 +189,7 @@ export function createGithubRepoCreateAction(options: { #### Task context store -Implement the similar API to CatalogProcessorCache allowing to store markers or keys to enable users to write idempotent actions. +Implement the similar API to `CatalogProcessorCache` allowing to store markers or keys to enable users to write idempotent actions. This context persists across retries. ```typescript @@ -204,7 +202,7 @@ Checkpoints will allow action authors to create actions where code paths are ign This will be provided on a context object and action of author provide a key and a callback. ```typescript -await ctx.checkpoint('v1.task.checkpoint.repo.creation', async () => { +await ctx.checkpoint('repo.creation', async () => { const { repoUrl } = await client.rest.Repository.create({}); return { repoUrl }; }); @@ -215,7 +213,7 @@ It's going look like: ```json { - "v1.task.checkpoint.repo.creation": { + "repo.creation": { "status": "success", "result": { "repoUrl": "https://github.com/backstage/backstage.git" @@ -224,6 +222,52 @@ It's going look like: } ``` +or a failed attempt as: + +```json +{ + "repo.creation": { + "status": "failed", + "reason": "Namespace is not valid" + } +} +``` + +`DatabaseTaskStore` will provide two extra methods `saveTaskState` and `getTaskState`. The type of state in API will be +represented as `JsonObject`. + +Task state will be stored in the extra column `state` in the table `tasks` with the next structure: + +```json +{ + "state": { + "checkpoints": { + "repo.creation": { + "status": "success", + "result": { + "repoUrl": "https://github.com/backstage/backstage.git" + } + }, + "repo.add.member": { + "status": "success", + "result": { + "id": "2345" + } + } + } + } +} +``` + +#### Workspace Persistence + +The workspace will be serialized and stored in the database by default. This serialization should occur at the end of a step, and after each checkpoint. It will be possible to provide additional modules to extend the workspace serialization to other providers, such as GCS or S3 instead of the database. +This would be useful for larger workspaces, instead of taking up space in the database, we can store these directory structures in a more appropriate place. + +The workspace will need to be zipped up into a binary like a `tar` or `zip` and be stored as a binary in the remote store. This is going to be better for performance than iterating through each file path and storing the contents along with the permissions. + +There could be an impact to the speed of task recovery as it downloads the workspace, but this is an accepted risk and a tradeoff for the benefits of having the workspace stored in a remote store. + ## Release Plan <!-- @@ -232,12 +276,18 @@ This section should describe the rollout process for any new features. It must t If there is any particular feedback to be gathered during the rollout, this should be described here as well. --> +We're going to release this behind `EXPERIMENTAL_` flags in the template schema to enable this on a per template level. And once we're happy with the implementation and after heavy testing, we can consider this being opt in at the plugin level, before being rolled out to all templates and the scaffolder plugin entirely. + +There could also be the option to have this behind a `scaffolder.backstage.io/v1beta4` `apiVersion` if the `EXPERIMENTAL_` options are not enough, or causing too much of a headache. + ## Dependencies <!-- List any dependencies that this work has on other BEPs or features. --> +None present. However this BEP does unblock things like longer running tasks and [Gated Workflows](https://github.com/backstage/backstage/issues/16622) + ## Alternatives <!-- diff --git a/beps/0005-split-backend-discovery/README.md b/beps/0005-split-backend-discovery/README.md new file mode 100644 index 0000000000..396c3e4c37 --- /dev/null +++ b/beps/0005-split-backend-discovery/README.md @@ -0,0 +1,311 @@ +--- +title: Discovery API - Split Backends +status: provisional +authors: + - '@aramissennyeydd' +owners: + - '@aramissennyeydd' +project-areas: + - core +creation-date: 2024-02-16 +--- + +<!-- +**Note:** When your BEP is complete, all these pre-existing comments should be removed + +When editing BEPs, aim for tightly-scoped, single-topic PRs to keep discussions focused. If you disagree with what is already in a document, open a new PR with suggested changes. +--> + +# BEP: Discovery API - Split Backends + +<!-- Before merging the initial BEP PR, create a feature issue and update the below link. You can wait with this step until the BEP is ready to be merged. --> + +[**Discussion Issue**](https://github.com/backstage/backstage/issues/23496) + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) +- [Design Details](#design-details) +- [Release Plan](#release-plan) +- [Dependencies](#dependencies) +- [Alternatives](#alternatives) + +## Summary + +<!-- +The summary of the BEP is a few paragraphs long and give a high-level overview of the features to be implemented. It should be possible to read *only* the summary and understand what the BEP is proposing to accomplish and what impact it has for users. +--> + +The goal of this BEP is to define the architecture that we will be using for an automatic discovery API that handles split backends. While users can use the current target-based config, it is not runtime driven and adding plugins requires a config update. This new system allows existing backends to register with gateway nodes at start time, allows them to unregister before the program exits and catches system errors by timing out plugin registrations that haven't been refreshed recently. + +## Motivation + +<!-- +This section is for explicitly listing the motivation, goals, and non-goals of +this BEP. Describe why the change is important and the benefits to users. +--> + +Split backends are a consistently difficult space to operate in and design for. There has been a growing desire for the framework to provide a way to get a list of the installed plugins. This was nearly impossible in the old backend, where plugins were hosted on denormalized routes and had non-standard startup sequences. In the new backend, this has become significantly more doable. Moving this forward would unblock a number of cases that require knowledge of your entire Backstage installation, namely a single OpenAPI spec for your instance, checking installed permissions, and DevTools information. + +Ideally, this work will also make it easier for adopters to go down the path of split backends. + +### Goals + +<!-- +List the specific goals of the BEP. What is it trying to achieve? How will we +know that this has succeeded? +--> + +1. As an integrator, I can now get a list of currently installed plugins across my deployment. +1. As an administrator, I can use the default discovery API across both frontend and backend for complex situations like split backends, without writing my own. +1. As an administrator, I can add/remove plugins without having to do a full redeployment of all of my Backstage nodes. +1. Registrations will be authenticated and any plugins that are added to the registry will have a proof of access to write to the registry. + +### Non-Goals + +<!-- +What is out of scope for this BEP? Listing non-goals helps to focus discussion +and make progress. +--> + +1. I can't install plugins using the new discovery API. +1. I can't control my deployments using the new discovery API. +1. If I fork the BackendInitialization logic, I may not be able to use this API. + +## Proposal + +<!-- +This is where we get down to the specifics of what the proposal actually is. +This should have enough detail that reviewers can understand exactly what +you're proposing, but should not include things like API designs or +implementation. +--> + +## Design Details + +<!-- +This section should contain enough information that the specifics of your +change are understandable. This may include API specs or even code snippets. +If there's any ambiguity about HOW your proposal will be implemented, this is the place to discuss them. +--> + +### Glossary + +#### Gateway Node + +A node that serves as the primary discovery point. A gateway node will have all of the information necessary to route traffic through your system. The gateway node is _not_ an API gateway, it only has knowledge of which plugins are on which nodes, it will not automatically route traffic to the correct instance. + +#### Non-gateway Node + +A node that needs to call a Gateway node for routing outside of its own plugins. This node will still fire requests to other instances, but does not know which instances have which plugins. + +### New Discovery Plugin + +We propose a new Discovery plugin that exposes a set of HTTP endpoints that allow dynamic registration and unregistration of plugins across multiple instances in a deployment. This will allow a single instance or type of instance ("gateway node") to have information about all installed plugins across your entire deployment, which may be multiple instances. The API would look like this, + +```yaml +openapi: 3.0.3 +info: + title: Discovery API + version: v1 +paths: + /register: + post: + summary: Register a plugin with the gateway. + operationId: registerPlugin + requestBody: + content: + application/json: + schema: + type: object + properties: + pluginId: + type: string + externalUrl: + type: string + internalUrl: + type: string + required: true + responses: + '200': + description: Successful operation + '400': + description: Invalid input + /unregister: + post: + summary: Unregister a plugin with the gateway. + operationId: unregisterPlugin + requestBody: + content: + application/json: + schema: + type: object + properties: + pluginId: + type: string + externalUrl: + type: string + internalUrl: + type: string + required: true + responses: + '200': + description: Successful operation + '400': + description: Invalid input or already unregistered. + /registrations: + get: + summary: Get all registered pluginIds + operationId: listRegistrations + responses: + '200': + description: Success + content: + application/json: + schema: + type: array + items: + type: string + /by-plugin/{pluginId}: + get: + summary: Get registration URLs for a given pluginId. + operationId: getRegistrationByPlugin + parameters: + - name: pluginId + in: path + description: The plugin ID to get information for. + required: true + schema: + type: string + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + internal: + type: string + external: + type: string +``` + +### Backend Requests + +![](./discovery.drawio.png) + +Backend [`DiscoveryService`](https://github.com/backstage/backstage/blob/master/packages/backend-plugin-api/src/services/definitions/DiscoveryService.ts) requests will either + +1. route to their own instance and can use the existing `HostDiscovery` implementation, or +2. need to route to a separate instance and will have to go to the gateway node for routing information. + +To get that extra information, the backend instances will call the gateway node's `by-plugin/{pluginId}` endpoint and route with the given response. + +We also propose adding a new method to this service to give a list of plugins across the deployment, + +```ts +interface DiscoveryService { + ... + listPlugins: () => Promise<string[]>; +} +``` + +This new method is expected to call the gateway node's `discovery://registrations` method. + +### Registration Flow + +![](./registrations.drawio.png) + +On startup, _instances_ will send a request to the gateway node, `discovery://register` with information about the instance and what plugins it owns. This request must be signed using service-to-service auth keys between the two instances to prevent malicious registrations. We may revisit this in the future. + +### New `InstanceMetadataService` + +While we could attach the existing information to the `PluginMetadataService`, we propose a new service that handles instance-level information. The existing `PluginMetadataService` should reveal information about the plugin itself, its `pluginId`, dependencies or similar. The new `InstanceMetadataService` should give you information about the entire Backstage instance that you're interrogating. At launch, this should include the list of features installed _on your instance_ that can then be aggregated by the discovery API across the gateway nodes. One could imagine this service also having information about instance URLs, health or gateway status. + +```ts +interface InstanceMetadataService { + listFeatures: () => BackendFeature[]; + // or + listFeatures: () => string[]; // list of pluginIds/moduleIds. +} +``` + +### Frontend Requests + +![](./frontend.drawio.png) + +This will leverage the existing [`DiscoveryApi`](https://github.com/backstage/backstage/blob/master/packages/core-plugin-api/src/apis/definitions/DiscoveryApi.ts). We propose adding a new method, `listPlugins` that will return a list of all plugins installed in your Backstage deployment. + +```ts +interface DiscoveryApi { + ... + listPlugins: () => Promise<string[]>; +} +``` + +All methods will just call the gateway node's HTTP discovery endpoint for the data, see diagram for more information. + +### Gateway Scaling + +The primary concern with having multiple gateway nodes is alignment on what plugins are installed across the instance. For this, we propose a new database that will store, + +```ts +export interface PluginRegistrations { + plugin_id: string; + internal_url: string; + external_url: string; + last_health_check: timestamp; +} +``` + +As any gateway node _could_ be hit by any given plugin, the implementation should not rely on in-memory values per node. Gateway nodes should read and write from/to the database directly. + +The triplet `plugin_id`, `internal_url`, `external_url` should be unique. We may have multiple plugins on multiple URLs either internal or external. Routing in those cases is not covered in this BEP. Horizontally scaled plugins should use external technologies to route requests and handle load balancing. This should be reflected in their `backend.baseUrl` properties. Instance IP addresses should _not_ be sent or stored in this database. + +### Heartbeats + +To prevent stale data, we propose implementing heartbeats. Each plugin should expose a `/health` endpoint (this will be configurable per plugin). When registering, the plugin will send its internal and external reachable URLs to the gateway node. After registering, every x seconds the gateway node will send a heartbeat request to the health endpoint. That endpoint is expected to return a 200 HTTP response. If it doesn't respond with a 200 or doesn't respond within a reasonable timeout, that plugin will be considered unregistered at its instance URL. If this represents the last instance URL for a given plugin, the entire plugin will be considered unavailable. + +The goal with adopting heartbeats is to leverage the decentralized nature of health checks per plugin to enable horizontal scaling easily. Only a single instance has to respond to a health check for it to pass. + +These would initially be naively implemented, using in memory intervals on each gateway node that a plugin registers with. This brings with it 2 risks that would result in lost traffic. + +1. The gateway node handling heartbeats crashes. +1. The instance handling traffic crashes. + +Both may cause a temporary outage in plugin traffic. + +<!-- TODO: Figure out a good story around error handling and restoring state. --> + +### Unregistering Plugins + +Each plugin will send a request to the gateway node's `/unregister` endpoint on shutdown. Any responses will not block the shutdown process. This will remove the plugin/instance combination from the database. As we have to consider horizontally scaled deployments, this may be triggered multiple times for a given plugin/instance combination. For duplicates, the endpoint will send a 400. + +## Release Plan + +<!-- +This section should describe the rollout process for any new features. It must take our version policies into account and plan for a phased rollout if this change affects any existing stable APIs. + +If there is any particular feedback to be gathered during the rollout, this should be described here as well. +--> + +## Dependencies + +<!-- +List any dependencies that this work has on other BEPs or features. +--> + +## Alternatives + +<!-- +What other approaches did you consider, and why did you rule them out? These do +not need to be as detailed as the proposal, but should include enough +information to express the idea and why it was not acceptable. +--> + +## Per-instance registration + +This would involve sending a request on instance startup with a list of the current plugins and information about how to route to them. While this is useful with the instance restarts on every plugin addition, it has issues with unregistering plugins when the instance crashes and doesn't restart and causes extra stress on the gateway node in comparison to a pure health check/heartbeat. diff --git a/beps/0005-split-backend-discovery/discovery.drawio.png b/beps/0005-split-backend-discovery/discovery.drawio.png new file mode 100644 index 0000000000..3e60e175d1 Binary files /dev/null and b/beps/0005-split-backend-discovery/discovery.drawio.png differ diff --git a/beps/0005-split-backend-discovery/frontend.drawio.png b/beps/0005-split-backend-discovery/frontend.drawio.png new file mode 100644 index 0000000000..2846cc6565 Binary files /dev/null and b/beps/0005-split-backend-discovery/frontend.drawio.png differ diff --git a/beps/0005-split-backend-discovery/registrations.drawio.png b/beps/0005-split-backend-discovery/registrations.drawio.png new file mode 100644 index 0000000000..f95f755455 Binary files /dev/null and b/beps/0005-split-backend-discovery/registrations.drawio.png differ diff --git a/beps/0006-scaffolder-action-rollback/README.md b/beps/0006-scaffolder-action-rollback/README.md new file mode 100644 index 0000000000..fd6c7911b9 --- /dev/null +++ b/beps/0006-scaffolder-action-rollback/README.md @@ -0,0 +1,84 @@ +--- +title: Scaffolder Action Rollback +status: provisional +authors: + - 'bnechyporenko@bol.com' + - 'benjaminl@spotify.com' +owners: + - '@backstage/scaffolder-maintainers' +project-areas: + - scaffolder +creation-date: 2024-03-13 +--- + +# BEP: <!-- Your short, descriptive title --> + +[**Discussion Issue**](https://github.com/backstage/backstage/issues/NNNNN) + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) +- [Design Details](#design-details) +- [Release Plan](#release-plan) +- [Dependencies](#dependencies) +- [Alternatives](#alternatives) + +## Summary + +Introducing the rollback to scaffolder actions provides the mean to come back to the initial state. + +## Motivation + +The aim is to help to mitigate the issue of manual clean up the partially created resources. + +### Goals + +- We will extend action's API to be able to run rollback for failed tasks +- Rollback will be optional + +### Non-Goals + +We will not cover all built-in actions with a rollback functionality + +## Proposal + +Rollback is going to be performed: + +- when user manually decide to perform this action. +- task has to be recovered and TaskRecoverStrategy set to 'rollback' + +## Design Details + +We are going to introduce an extra function in action API which will look like: + +```typescript +const createPublishGitHubAction = createTemplateAction({ + id: 'publish:github', + async handler() {}, + async rollback() {}, +}); +``` + +## Release Plan + +<!-- +This section should describe the rollout process for any new features. It must take our version policies into account and plan for a phased rollout if this change affects any existing stable APIs. + +If there is any particular feedback to be gathered during the rollout, this should be described here as well. +--> + +## Dependencies + +<!-- +List any dependencies that this work has on other BEPs or features. +--> + +## Alternatives + +<!-- +What other approaches did you consider, and why did you rule them out? These do +not need to be as detailed as the proposal, but should include enough +information to express the idea and why it was not acceptable. +--> diff --git a/beps/0007-auth-external-services/README.md b/beps/0007-auth-external-services/README.md new file mode 100644 index 0000000000..d49cd7992f --- /dev/null +++ b/beps/0007-auth-external-services/README.md @@ -0,0 +1,215 @@ +--- +title: Authentication of External Services +status: provisional +authors: + - '@mareklibra' +owners: + - '@backstage/maintainers' +project-areas: + - core +creation-date: 2024-03-30 +--- + +# BEP: Authentication of External Services + +[**Discussion Issue**](https://github.com/backstage/backstage/issues/24349) + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) +- [Design Details](#design-details) +- [Release Plan](#release-plan) +- [Dependencies](#dependencies) +- [Alternatives](#alternatives) + +## Summary + +This proposal builds upon the foundation laid out in the [Auth Architecture Evolution BEP](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution), by improving the authentication mechanisms used by external callers seeking to access the REST APIs exposed by Backstage plugins. + +Specifically, the inclusion of shared-key based authentication is proposed, along with a framework for integrating different authentication types in the future. Compatibility with the legacy shared-secret token signature mechanism is retained. + +By implementing this proposed solution, security should not be compromised beyond the existing state when exposing the API to the internet. Nonetheless, it is advisable to maintain a level of protection by shielding your deployments from the internet access unless you explicitly need public access. + +## Motivation + +This proposal represents a progression from [the old service to service auth tutorial](https://backstage.io/docs/auth/service-to-service-auth--old/#usage-in-external-callers) in the context of the new `coreServices.auth` and `coreServices.httpAuth` authentication services. + +It offers expanded configuration possibilities and will include ready-to-use examples as part of the implementation to streamline the process of invoking REST services exposed by Backstage backend plugins for external services. + +The previous tutorial lacked clarity on how to effectively structure the call, resulting in a cumbersome experience. + +Examples of potential use-cases include: + +- An external asynchronous service requiring the ability to send notifications to users +- Integrations for external services interacting with the catalog +- Temporary `curl` friendly tokens in local development + +To facilitate this process, no code change but configuration only is needed on the Backstage side. + +### Goals + +- The primary objective is to facilitate access for external heterogeneous services to the Backstage REST API without involving unnecessary complexity. +- Moving to the proposed new auth scheme is entirely optional. The old shared key signature tokens remain usable. +- Configuration options will allow specification of which API endpoints can be accessed by an external entity. +- Limiting API context and granting distinct external access independently helps mitigate security risks. A compromised external service can only access a restricted portion of the API. +- Enhanced clarity and updated examples make it easy to comprehend and utilize. + +### Non-Goals + +It is not a goal + +- To replace the current Backstage service-to-service authentication or tokens, +- To offer a bypass option for Backstage plugins to circumvent existing service-to-service authentication. Even if feasible, such a bypass would be considered as an anti-pattern. + +## Proposal + +The `backend.auth.keys` section of your app config remains supported for the time being, but is considered legacy. It is read by the new auth handler code solely for backward compatibility reasons. Using this format will lead to a logged warning urging a migration to the new format described below. + +This BEP adds a `backend.auth.externalAccess` section to your app config. This section is the new recommended way of declaring all methods of external service access that you want to support. Like the legacy section above, it is an array, but each element has a `type` field to allow for extensibility. Using an array also means that the configuration system will not make any config merging of access methods across different config files - which avoids unintended mistakes that might otherwise have impacted security. + +The two types of external access covered by this BEP are `legacy` and `static`. More on that below. + +## Design Details + +### Configuration + +The following is an example of what an app config section with a single access method could look like: + +```yaml +backend: + auth: + externalAccess: + - type: static + options: + token: ${SERVICE_API_TOKEN} + scope: + plugins: catalog +``` + +Each entry has a `type`, which is any string. The framework handles a number of these types - initially a fixed set, but in the future we might make it extensible. + +The `options` is a general object, and is specific to each type, configuring it as needed. This particular type only had a `token`, which was configured to be taken from an environment variable. + +Each entry may also optionally have a `scope` section that controls what operations that this entry can be used for. Attempting to use this access method for any other scope will lead to 403 error rejections. Scopes can contain plugin IDs and/or permissions. + +Introducing a new external caller with its exclusive secret key entails updating the app-config.yaml file and restarting the backend. This mechanism is designed to support integration with selected services, and therefore dynamic addition of callers is not necessary at this point. + +### Scopes + +Scopes are optional. If you do not specify any scopes, the access method in question has unlimited scope and can perform all types of action. + +In the examples below, either a string or a list of strings can be given. + +If _any_ scope rule matches, the action is permitted. I.e., if you specify a plugin rule, then also adding permission rules for that plugin will have no effect since the plugin rule will have already matched. + +You can limit by the target plugin ID being accessed with the token: + +```yaml +scope: + plugin: catalog +``` + +You can limit by the type of permission being requested: + +```yaml +scope: + permission: catalog.entity.read +``` + +Or by permissions attribute: + +```yaml +scope: + permissionAttributes: { action: read } +``` + +### The Legacy Access Type + +Configuration example: + +```yaml +backend: + auth: + externalAccess: + - type: legacy + options: + secret: ${EXTERNAL_ACCESS_SIGNATURE_SECRET} + # scope: ... +``` + +This corresponds exactly to the old shared secret signature method, and any secrets entered here will be merged with those specified under `backend.auth.keys` if any. + +### The Static Access Type + +Configuration example: + +```yaml +backend: + auth: + externalAccess: + - type: static + options: + token: ${SERVICE_API_TOKEN} + # scope: ... +``` + +This allows you to specify any static token string as an API key, which callers send verbatim as the header `Authorization: Bearer <token>`. + +### Implementation + +The token verification of the two access methods will live entirely with the `coreServices.auth` service implementation, and will be returning regular credentials with a service principal. The implementation will only need to alter the `authenticate` method and no additions to the API will be necessary. + +The service principal type will need to be amended with an optional scope field, carried over from the configuration. This will let the `ServerPermissionClient` compare against the set of allowlisted actions. In addition, the auth service can early-reject based on plugin ID if such rules are given. + +## Release Plan + +<!-- +This section should describe the rollout process for any new features. It must take our version policies into account and plan for a phased rollout if this change affects any existing stable APIs. + +If there is any particular feedback to be gathered during the rollout, this should be described here as well. +--> + +The initial pilot implementation of the `legacy` and `static` types has already been merged, along with the corresponding config additions. + +Validating this implementation, and adding scope restrictions, is still on todo but could be added incrementally at any time without breaking changes - as long as the default scope is "all". + +We have left it out of the scope of this BEP to allow for addition of more access types. Making that a possibility will likely require the addition of service extension points at a framework level, which is not yet made a priority. + +Potential _future_ access types (not part of this BEP, but rather only for illustration) could for example be: + +```yaml +backend: + auth: + externalAccess: + - type: jwks + options: + url: https://other-service.acme.org/.well-known/jwks.json + - type: certificate + options: + publicCert: + $file: ./service-cert.pem +``` + +## Dependencies + +- [BEP-0003: Auth Architecture Evolution](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution) + +## Alternatives + +### Dynamic Persistence of Shared-Secrets in a Database + +This approach involves storing shared secrets dynamically in a database. Adding or removing a shared secret would not require changes to the `app-config.yaml`, and managing secrets would not require restarting the application. This solution offers clear benefits, but may encounter objections due to its complexity and the potential lack of need for such flexibility. + +### Maintain the Status Quo + +Alternatively, we could maintain the current state by allowing callers to independently compose JWT tokens suitable for the existing implementation. However, this approach may prove challenging given the diverse types and environmental setups of external callers. + +### Access Control on a Per-Plugin Basis + +Another alternative is to retain access control on a per-plugin basis, as demonstrated in https://github.com/backstage/backstage/pull/23441. Given the repetitive nature of this use-case, establishing a common mechanism may present a more favorable option. + +### Shared Token Requester + +Implementing a shared token requester, as showcased in https://github.com/backstage/backstage/pull/23465, offers another potential solution. This approach may streamline token management and enhance accessibility, but requires thorough consideration of its implications and integration into the existing system. diff --git a/beps/NNNN-template/README.md b/beps/NNNN-template/README.md index 40e2eb8f72..3ecb1ffb4e 100644 --- a/beps/NNNN-template/README.md +++ b/beps/NNNN-template/README.md @@ -4,6 +4,7 @@ status: provisional authors: - '@ghost' owners: + - '@ghost' project-areas: - aaa - bbb diff --git a/contrib/docker/minimal-harded-image/Dockerfile b/contrib/docker/minimal-harded-image/Dockerfile new file mode 100644 index 0000000000..8ee6a3d206 --- /dev/null +++ b/contrib/docker/minimal-harded-image/Dockerfile @@ -0,0 +1,61 @@ +# This dockerfile builds an image for the backend package. +# It should be executed with the root of the repo as docker context. +# +# Before building this image, be sure to have run the following commands in the repo root: +# +# yarn install +# yarn tsc +# yarn build:backend +# +# Once the commands have been run, you can build the image using `yarn docker-build` + +FROM cgr.dev/chainguard/wolfi-base:latest + +ENV NODE_VERSION 18=~18.19 +ENV PYTHON_VERSION 3.12=~3.12 + +RUN apk add nodejs-$NODE_VERSION yarn + +# 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. +# Additionally, we install dependencies for `techdocs.generator.runIn: local`. +# https://backstage.io/docs/features/techdocs/getting-started#disabling-docker-in-docker-situation-optional +RUN --mount=type=cache,target=/var/cache/apk,sharing=locked \ + --mount=type=cache,target=/var/lib/apk,sharing=locked \ + apk update && \ + apk add sqlite-dev python-$PYTHON_VERSION py3-pip python-3-dev py3-setuptools build-base gcc libffi-dev glibc-dev openssl-dev brotli-dev c-ares-dev nghttp2-dev icu-dev zlib-dev gcc-12 libuv-dev && \ + yarn config set python /usr/bin/python3 + +# Set up a virtual environment for mkdocs-techdocs-core. +ENV VIRTUAL_ENV=/opt/venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +RUN pip3 install mkdocs-techdocs-core==1.3.3 + +# From here on we use the least-privileged `node` user to run the backend. +WORKDIR /app +RUN chown nonroot:nonroot /app +USER nonroot + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + +# Copy over Yarn 3 configuration, release, and plugins +COPY --chown=nonroot:nonroot .yarn ./.yarn +COPY --chown=nonroot:nonroot .yarnrc.yml ./ + +# 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=nonroot:nonroot yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ +RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz + +RUN --mount=type=cache,target=/home/node/.yarn/berry/cache,sharing=locked,uid=1000,gid=1000 \ + yarn workspaces focus --all --production + +# Then copy the rest of the backend bundle, along with any other files we might want. +COPY --chown=nonroot:nonroot 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/contrib/docker/minimal-harded-image/README.md b/contrib/docker/minimal-harded-image/README.md new file mode 100644 index 0000000000..accb2188ac --- /dev/null +++ b/contrib/docker/minimal-harded-image/README.md @@ -0,0 +1,12 @@ +# Minimal Hardened Image for Backstage + +DockerHub images in general did not seem ideal for Backstage as the number of vulnerabilities were quite high regardless of the image used. + +The `Dockerfile` in this directory uses a [`wolfi-base`](https://github.com/wolfi-dev) image from Chainguard Images. This improves the security of the application and reduces false positives in scanners. + +## Considerations + +- `Wolfi` only releases the `latest` tag for public consumption however digests can be pinned. +- `Wolfi` OS uses packages from the [os repository](https://github.com/wolfi-dev/os) on GitHub. Some packages may be named differently. +- While `Wolfi` uses `apk`, the OS is designed to support `glibc`. +- Due to the stripped down nature of the base image, additional packages might be needed compared to a distribution like Debian or Ubuntu. diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index 8b71151ee9..838aaffef6 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -1,5 +1,14 @@ # Authenticate API requests +> [!CAUTION] +> This entire guide MUST NOT BE USED by users of Backstage 1.26 and +> newer. If you have applied the changes in this guide, you need to remove them +> again as you upgrade to recent versions of Backstage. When [the new auth +> changes](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution) +> landed backends became natively secured through the framework, and the +> instructions outlined in here can interfere with the backend functioning +> correctly. + The Backstage backend APIs are by default available without authentication. To avoid evil-doers from accessing or modifying data, one might use a network protection mechanism such as a firewall or an authenticating reverse proxy. For Backstage instances that are available on the Internet one can instead use the experimental IdentityClient as outlined below. API requests from frontend plugins include an authorization header with a Backstage identity token acquired when the user logs in. By adding a middleware that verifies said token to be valid and signed by Backstage, non-authenticated requests can be blocked with a 401 Unauthorized response. diff --git a/docs/assets/getting-started/create-app-output.png b/docs/assets/getting-started/create-app-output.png new file mode 100644 index 0000000000..1987ea41e1 Binary files /dev/null and b/docs/assets/getting-started/create-app-output.png differ diff --git a/docs/assets/getting-started/create-app_output.png b/docs/assets/getting-started/create-app_output.png deleted file mode 100644 index 875ad05122..0000000000 Binary files a/docs/assets/getting-started/create-app_output.png and /dev/null differ diff --git a/docs/assets/plugins/cloudbuild/CloudBuildPlugin.png b/docs/assets/plugins/cloudbuild/CloudBuildPlugin.png index 3b347f0f68..ae4f773e8a 100644 Binary files a/docs/assets/plugins/cloudbuild/CloudBuildPlugin.png and b/docs/assets/plugins/cloudbuild/CloudBuildPlugin.png differ diff --git a/docs/auth/atlassian/provider.md b/docs/auth/atlassian/provider.md index cded6e73ca..2680370d93 100644 --- a/docs/auth/atlassian/provider.md +++ b/docs/auth/atlassian/provider.md @@ -46,16 +46,16 @@ auth: development: clientId: ${AUTH_ATLASSIAN_CLIENT_ID} clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET} - scopes: ${AUTH_ATLASSIAN_SCOPES} + scope: ${AUTH_ATLASSIAN_SCOPES} ``` The Atlassian provider is a structure with three configuration keys: - `clientId`: The Key you generated in the developer console. - `clientSecret`: The Secret tied to the generated Key. -- `scopes`: List of scopes the app has permissions for, separated by spaces. +- `scope`: List of scopes the app has permissions for, separated by spaces. -**NOTE:** the scopes `offline_access` and `read:me` are provided by default. +**NOTE:** the scopes `offline_access`, `read:jira-work`, and `read:jira-user` are provided by default. ## Adding the provider to the Backstage frontend diff --git a/docs/auth/cloudflare/access.md b/docs/auth/cloudflare/access.md index b1d8e4c676..9df816c39f 100644 --- a/docs/auth/cloudflare/access.md +++ b/docs/auth/cloudflare/access.md @@ -24,71 +24,62 @@ Let's start by adding the following `auth` configuration in your auth: providers: cfaccess: + # You can find the team name in the Cloudflare Zero Trust dashboard. teamName: <Team Name> + # This service tokens section is optional -- you only need it if you have + # some Cloudflare Service Tokens that you want to be able to log in to your + # Backstage instance. + serviceTokens: + - token: '1uh2fh19efvfh129f1f919u21f2f19jf2.access' + subject: 'bot-user@your-company.com' + # This picks what sign in resolver(s) you want to use. + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail ``` -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. -This config section must be in place for the provider to load at all. Now let's -add the provider itself. +The `signIn` section picks what sign-in resolver(s) to use for sign-in attempts. +It is responsible for matching the upstream provider's sign-in result to a +corresponding Backstage identity, or to throw an error if the attempt should be +rejected for any reason. The `emailMatchingUserEntityProfileEmail` is a common +choice: it tries to match the email of the signed-in user to a `User` kind +entity in the catalog whose profile email matches that. + +If the builtin sign in resolvers do not match your needs, you can skip the +`signIn` section and instead [provide a custom resolver](#advanced-custom-sign-in-resolver). ## Backend Changes -Add a `providerFactories` entry to the router in -`packages/backend/plugin/auth.ts`. +We need to add the provider package as a dependency to our backend: -```ts title="packages/backend/plugin/auth.ts" -import { providers } from '@backstage/plugin-auth-backend'; +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-cloudflare-access-provider +``` -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - 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 sample code - // shown here, but you may want to query your LDAP server, or - // https://<teamName>.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 } }); - }, - }, - }), - }, - }); -} +And to tell the backend to load it: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add( + import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'), +); +/* highlight-add-end */ ``` 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. +`/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 +## Frontend Changes It is recommended to use the `ProxiedSignInPage` for this provider, which is -installed in `packages/app/src/App.tsx` like this: +installed in your app like this: -```tsx title="packages/app/src/App.tsx" +```tsx title="in packages/app/src/App.tsx" /* highlight-add-next-line */ import { ProxiedSignInPage } from '@backstage/core-components'; @@ -98,8 +89,87 @@ const app = createApp({ SignInPage: props => <ProxiedSignInPage {...props} provider="cfaccess" />, }, /* highlight-add-end */ - // .. + // ... }); ``` -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. +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. + +## Advanced: Custom Sign-in Resolver + +If none of the built-in sign in resolvers fit your needs, you need to provide a +customized version of the module. Now you should _not_ +`backend.add(import(...))`, instead you will do the following. + +```ts title="in packages/backend/plugin/auth.ts" +/* highlight-add-start */ +import { createCloudflareAccessAuthenticator } from '@backstage/plugin-auth-backend-module-cloudflare-access-provider'; +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + createProxyAuthProviderFactory, +} from '@backstage/plugin-auth-node'; + +const customAuth = createBackendModule({ + // This ID must be exactly "auth" because that's the plugin it targets + pluginId: 'auth', + // This ID must be unique, but can be anything + moduleId: 'custom-auth-provider', + register(reg) { + reg.registerInit({ + deps: { + providers: authProvidersExtensionPoint, + cache: coreServices.cache, + }, + async init({ providers, cache }) { + providers.registerProvider({ + // This ID must match the actual provider config, e.g. addressing + // auth.providers.github means that this must be "github". + providerId: 'cfaccess', + // Use createProxyAuthProviderFactory instead if it's one of the proxy + // based providers rather than an OAuth based one + factory: createProxyAuthProviderFactory({ + authenticator: createCloudflareAccessAuthenticator({ cache }), + async signInResolver(info, ctx) { + // This is where the body of the sign-in resolver goes! + const { profile } = info; + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + return ctx.signInWithCatalogUser({ + filter: { + 'spec.profile.email': profile.email, + }, + }); + }, + }), + }); + }, + }); + }, +}); +/* highlight-add-end */ + +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-remove-start */ +backend.add( + import('@backstage/plugin-auth-backend-module-cloudflare-access-provider'), +); +/* highlight-remove-end */ +/* highlight-add-next-line */ +backend.add(customAuth); +``` + +The body of the sign-in resolver is up to you to write! The example code above +is just a copy of what `emailMatchingUserEntityProfileEmail` does. The `info` +parameter contains all of the results of the sign-in attempt so far. The `ctx` +context [has several useful +functions](https://backstage.io/docs/reference/plugin-auth-node.authresolvercontext/) +for issuing tokens in various ways. diff --git a/docs/auth/guest/provider.md b/docs/auth/guest/provider.md new file mode 100644 index 0000000000..b28274d2ba --- /dev/null +++ b/docs/auth/guest/provider.md @@ -0,0 +1,66 @@ +--- +id: provider +title: Guest Authentication Provider +sidebar_label: Guest +description: Adding a guest authentication provider in Backstage +--- + +Audience: Admins or developers + +## Summary + +The goal of this guide is to get you set up with a guest authentication provider that emits tokens. This is different than the old guest authentication that is purely stored on the frontend and does not have tokens. The main reason you'd want to use this provider is to use permissioned plugins. + +:::caution +This provider should only ever be enabled for `development`. To prevent unauthorized access to your data, this package is _explicitly_ disabled for non-development environments. +::: + +## Installation + +### Backend + +:::note +This will only work with the new backend system. There is no support for this in the old backend. +::: + +Add the `@backstage/plugin-auth-backend-module-guest-provider` to your backend installation. + +```sh +# From your Backstage root directory +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-guest-provider +``` + +Then, add it to your backend's source, + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +backend.add(import('@backstage/plugin-auth-backend')); +// highlight-add-next-line +backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); + +await backend.start(); +``` + +### Frontend + +Add the following to your `SignInPage` providers, + +```ts +const providers = [ + // highlight-add-next-line + 'guest', + ... +] +``` + +### Config + +Similar to the other authentication providers, you have to enable the provider in config. Add the following to your `app-config.local.yaml`, + +```yaml title="app-config.local.yaml" +auth: + providers: + # highlight-add-next-line + guest: {} +``` diff --git a/docs/auth/identity-resolver--old.md b/docs/auth/identity-resolver--old.md new file mode 100644 index 0000000000..c1659f46d8 --- /dev/null +++ b/docs/auth/identity-resolver--old.md @@ -0,0 +1,379 @@ +--- +id: identity-resolver--old +title: Sign-in Identities and Resolvers (Old Backend System) +description: An introduction to Backstage user identities and sign-in resolvers in the old backend system +--- + +:::info +This documentation is written for the old backend which has been replaced by +[the new backend system](../backend-system/index.md), being the default since +Backstage [version 1.24](../releases/v1.24.0.md). If have migrated to the new +backend system, you may want to read [its own article](./identity-resolver.md) +instead. Otherwise, [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + +By default, every Backstage auth provider is configured only for the use-case of +access delegation. This enables Backstage to request resources and actions from +external systems on behalf of the user, for example re-triggering a build in CI. + +If you want to use an auth provider to sign in users, you need to explicitly configure +it have sign-in enabled and also tell it how the external identities should +be mapped to user identities within Backstage. + +## Quick Start + +> See [providers](../reference/plugin-auth-backend.providers.md) +> for a full list of auth providers and their built-in sign-in resolvers. + +Backstage projects created with `npx @backstage/create-app` come configured with a +sign-in resolver for GitHub guest access. This resolver makes all users share +a single "guest" identity and is only intended as a minimum requirement to quickly +get up and running. You can replace `github` for any of the other providers if you need. + +This resolver should not be used in production, as it uses a single shared identity, +and has no restrictions on who is able to sign-in. Be sure to read through the rest +of this page to understand the Backstage identity system once you need to install +a resolver for your production environment. + +The guest resolver can be useful for testing purposes too, and it looks like this: + +```ts +signIn: { + resolver(_, ctx) { + const userRef = 'user:default/guest' + return ctx.issueToken({ + claims: { + sub: userRef, + ent: [userRef], + }, + }), + }, +}, +``` + +## Backstage User Identity + +A user identity within Backstage is built up from two pieces of information, a +user [entity reference](../features/software-catalog/references.md), and a +set of ownership entity references. +When a user signs in, a Backstage token is generated with these two pieces of information, +which is then used to identify the user within the Backstage ecosystem. + +The user entity reference should uniquely identify the logged in user in Backstage. +It is encouraged that a matching user entity also exists within the Software Catalog, +but it is not required. If the user entity exists in the catalog it can be used to +store additional data about the user. There may even be some plugins that require +this for them to be able to function. + +The ownership references are also entity references, and it is likewise +encouraged that these entities exist within the catalog, but it is not a requirement. +The ownership references are used to determine what the user owns, as a set +of references that the user claims ownership though. For example, a user +Jane (`user:default/jane`) might have the ownership references `user:default/jane`, +`group:default/team-a`, and `group:default/admins`. Given these ownership claims, +any entity that is marked as owned by either of `user:jane`, `team-a`, or `admins` would +be considered owned by Jane. + +The ownership claims often contain the user entity reference itself, but it is not +required. It is also worth noting that the ownership claims can also be used to +resolve other relations similar to ownership, such as a claim for a `maintainer` or +`operator` status. + +The Backstage token that encapsulates the user identity is a JWT. The user entity +reference is stored in the `sub` claim of the payload, while the ownership references +are stored in a custom `ent` claim. Both the user and ownership references should +always be full entity references, as opposed to shorthands like just `jane` or `user:jane`. + +## Sign-in Resolvers + +Signing in a user into Backstage requires a mapping of the user identity from the +third-party auth provider to a Backstage user identity. This mapping can vary quite +a lot between different organizations and auth providers, and because of that there's +no default way to resolve user identities. The auth provider that one wants to use +for sign-in must instead be configured with a sign-in resolver, which is a function +that is responsible for creating this user identity mapping. + +The input to the sign-in resolver function is the result of a successful log in with +the given auth provider, as well as a context object that contains various helpers +for looking up users and issuing tokens. There are also a number of built-in sign-in +resolvers that can be used, which are covered a bit further down. + +Note that while it possible to configure multiple auth providers to be used for sign-in, +you should take care when doing so. It is best to make sure that the different auth +providers either do not have any user overlap, or that any users that are able to log +in with multiple providers always end up with the same Backstage identity. + +### Custom Resolver Example + +Let's look at an example of a custom sign-in resolver for the Google auth provider. +This all typically happens within your `packages/backend/src/plugins/auth.ts` file, +which is responsible for setting up and configuring the auth backend plugin. + +You provide the resolver as part of the options you pass when creating a new auth +provider factory. This means you need to replace the default Google provider with +one that you create. Be sure to also include the existing `defaultAuthProviderFactories` +if you want to keep all of the built-in auth providers installed. + +Now let's look at the example, with the rest of the commentary being made with in +the code comments: + +```ts +// File: packages/backend/src/plugins/auth.ts +import { + createRouter, + providers, + defaultAuthProviderFactories, +} from '@backstage/plugin-auth-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + return await createRouter({ + ...env, + providerFactories: { + ...defaultAuthProviderFactories, + google: providers.google.create({ + signIn: { + resolver: async (info, ctx) => { + const { + profile: { email }, + } = info; + // Profiles are not always guaranteed to to have an email address. + // You can also find more provider-specific information in `info.result`. + // It typically contains a `fullProfile` object as well as ID and/or access + // tokens that you can use for additional lookups. + if (!email) { + throw new Error('User profile contained no email'); + } + + // You can add your own custom validation logic here. + // Logins can be prevented by throwing an error like the one above. + myEmailValidator(email); + + // This example resolver simply uses the local part of the email as the name. + const [name] = email.split('@'); + + // This helper function handles sign-in by looking up a user in the catalog. + // The lookup can be done either by reference, annotations, or custom filters. + // + // The helper also issues a token for the user, using the standard group + // membership logic to determine the ownership references of the user. + return ctx.signInWithCatalogUser({ + entityRef: { name }, + }); + }, + }, + }), + }, + }); +} +``` + +### Built-in Resolvers + +You don't always have to write your own custom resolver. The auth backend plugin provides +built-in resolvers for many of the common sign-in patterns. You access these via the `resolvers` +property of each of the auth provider integrations. For example, the Google provider has +a built in resolver that works just like the one we defined above: + +```ts +// File: packages/backend/src/plugins/auth.ts +export default async function createPlugin( + // ... + return await createRouter({ + // ... + providerFactories: { + // ... + google: providers.google.create({ + signIn: { + resolver: providers.google.resolvers.emailLocalPartMatchingUserEntityName(), + }, + }); + } + }) +) +``` + +There are also other options, like the this one that looks up a user +by matching the `google.com/email` annotation of user entities in the catalog: + +```ts +providers.google.create({ + signIn: { + resolver: providers.google.resolvers.emailMatchingUserEntityAnnotation(), + }, +}); +``` + +## Custom Ownership Resolution + +If you want to have more control over the membership resolution and token generation +that happens during sign-in you can replace `ctx.signInWithCatalogUser` with a set +of lower-level calls: + +```ts +// File: packages/backend/src/plugins/auth.ts +import { getDefaultOwnershipEntityRefs } from '@backstage/plugin-auth-backend'; + +export default async function createPlugin( + // ... + return await createRouter({ + // ... + providerFactories: { + // ... + google: async ({ profile: { email } }, ctx) => { + if (!email) { + throw new Error('User profile contained no email'); + } + + // This step calls the catalog to look up a user entity. You could for example + // replace it with a call to a different external system. + const { entity } = await ctx.findCatalogUser({ + annotations: { + 'acme.org/email': email, + }, + }); + + // In this step we extract the ownership references from the user entity using + // the standard logic. It uses a reference to the entity itself, as well as the + // target of each `memberOf` relation where the target is of the kind `Group`. + // + // If you replace the catalog lookup with something that does not return + // an entity you will need to replace this step as well. + // + // You might also replace it if you for example want to filter out certain groups. + // + // Note that `getDefaultOwnershipEntityRefs` only includes groups to which the + // user has a direct MEMBER_OF relationship. It's perfectly fine to include + // groups that the user is transitively part of in the claims array, but the + // catalog doesn't currently provide a direct way of accessing this list of + // groups. + const ownershipRefs = getDefaultOwnershipEntityRefs(entity); + + // The last step is to issue the token, where we might provide more options in the future. + return ctx.issueToken({ + claims: { + sub: stringifyEntityRef(entity), + ent: ownershipRefs, + }, + }); + }; + } + }) +) +``` + +## Sign-In without Users in the Catalog + +While populating the catalog with organizational data unlocks more powerful ways +to browse your software ecosystem, it might not always be a viable or prioritized +option. However, even if you do not have user entities populated in your catalog, you +can still sign in users. As there are currently no built-in sign-in resolvers for +this scenario you will need to implement your own. + +Signing in a user that doesn't exist in the catalog is as simple as skipping the +catalog lookup step from the above example. Rather than looking up the user, we +instead immediately issue a token using whatever information is available. One caveat +is that it can be tricky to determine the ownership references, although it can +be achieved for example through a lookup to an external service. You typically +want to at least use the user itself as a lone ownership reference. + +Because we no longer use the catalog as an allow-list of users, it is often important +that you limit what users are allowed to sign in. This could be a simple email domain +check like in the example below, or you might for example look up the GitHub organizations +that the user belongs to using the user access token in the provided result object. + +```ts +// File: packages/backend/src/plugins/auth.ts +import { createRouter, providers } from '@backstage/plugin-auth-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; +import { + stringifyEntityRef, + DEFAULT_NAMESPACE, +} from '@backstage/catalog-model'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + return await createRouter({ + ...env, + providerFactories: { + google: providers.google.create({ + signIn: { + resolver: async ({ profile }, ctx) => { + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + // Split the email into the local part and the domain. + const [localPart, domain] = profile.email.split('@'); + + // Next we verify the email domain. It is recommended to include this + // kind of check if you don't look up the user in an external service. + if (domain !== 'acme.org') { + throw new Error( + `Login failed, this email ${profile.email} does not belong to the expected domain`, + ); + } + + // By using `stringifyEntityRef` we ensure that the reference is formatted correctly + const userEntity = stringifyEntityRef({ + kind: 'User', + name: localPart, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userEntity, + ent: [userEntity], + }, + }); + }, + }, + }), + }, + }); +} +``` + +## AuthHandler + +Similar to a custom sign-in resolver, you can also write a custom auth handler +function which is used to verify and convert the auth response into the profile +that will be presented to the user. This is where you can customize things like +display name and profile picture. + +This is also the place where you can do authorization and validation of the user +and throw errors if the user should not be allowed access in Backstage. + +```ts +// File: packages/backend/src/plugins/auth.ts +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + return await createRouter({ + ... + providerFactories: { + google: providers.google.create({ + authHandler: async ({ + fullProfile // Type: passport.Profile, + idToken // Type: (Optional) string, + }) => { + // Custom validation code goes here + return { + profile: { + email, + picture, + displayName, + } + }; + } + }) + } + }) +} +``` diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index 0a626ef175..406f789630 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -4,52 +4,44 @@ title: Sign-in Identities and Resolvers description: An introduction to Backstage user identities and sign-in resolvers --- +:::info +This documentation is written for [the new backend +system](../backend-system/index.md) which is the default since Backstage +[version 1.24](../releases/v1.24.0.md). If you are still on the old backend +system, you may want to read [its own article](./identity-resolver--old.md) +instead, and [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + By default, every Backstage auth provider is configured only for the use-case of access delegation. This enables Backstage to request resources and actions from external systems on behalf of the user, for example re-triggering a build in CI. -If you want to use an auth provider to sign in users, you need to explicitly configure -it have sign-in enabled and also tell it how the external identities should -be mapped to user identities within Backstage. +If you want to use an auth provider to sign in users, you need to explicitly +configure it have sign-in enabled and also tell it how the external identities +should be mapped to user identities within Backstage. You do this by either +choosing a built-in sign in resolver, or supplying your own. Both methods are +listed below. ## Quick Start -> See [providers](../reference/plugin-auth-backend.providers.md) -> for a full list of auth providers and their built-in sign-in resolvers. +Backstage projects created with `npx @backstage/create-app` come configured with +a [guest auth provider](https://backstage.io/docs/auth/guest/provider). This +provider makes all users share a single "guest" identity. This is useful for +testing purposes and quickly getting started locally, but is not safe for use in +production and that particular provider will refuse to work there. -Backstage projects created with `npx @backstage/create-app` come configured with a -sign-in resolver for GitHub guest access. This resolver makes all users share -a single "guest" identity and is only intended as a minimum requirement to quickly -get up and running. You can replace `github` for any of the other providers if you need. - -This resolver should not be used in production, as it uses a single shared identity, -and has no restrictions on who is able to sign-in. Be sure to read through the rest -of this page to understand the Backstage identity system once you need to install -a resolver for your production environment. - -The guest resolver can be useful for testing purposes too, and it looks like this: - -```ts -signIn: { - resolver(_, ctx) { - const userRef = 'user:default/guest' - return ctx.issueToken({ - claims: { - sub: userRef, - ent: [userRef], - }, - }), - }, -}, -``` +Because of this, one of the early things you want to do when standing up your +Backstage instance is to choose a production ready auth provider. See [the auth +overview page](./index.md) for a full list of providers and how to install and +configure them. ## Backstage User Identity -A user identity within Backstage is built up from two pieces of information, a -user [entity reference](../features/software-catalog/references.md), and a -set of ownership entity references. -When a user signs in, a Backstage token is generated with these two pieces of information, -which is then used to identify the user within the Backstage ecosystem. +A user identity within Backstage is built up from two main pieces of +information: a user [entity +reference](../features/software-catalog/references.md), and a set of ownership +references. When a user signs in, a Backstage token is generated which is then +used to identify the user within the Backstage ecosystem. The user entity reference should uniquely identify the logged in user in Backstage. It is encouraged that a matching user entity also exists within the Software Catalog, @@ -71,10 +63,13 @@ required. It is also worth noting that the ownership claims can also be used to resolve other relations similar to ownership, such as a claim for a `maintainer` or `operator` status. -The Backstage token that encapsulates the user identity is a JWT. The user entity -reference is stored in the `sub` claim of the payload, while the ownership references -are stored in a custom `ent` claim. Both the user and ownership references should -always be full entity references, as opposed to shorthands like just `jane` or `user:jane`. +The Backstage token that encapsulates the user identity is a JWT. The user +entity reference is stored in the `sub` claim of the payload, while the +ownership references are stored in a custom `ent` claim in the old backend +system but instead is made available through a user info API endpoint on the +auth backend in the new system. Both the user and ownership references should +always be full entity references, as opposed to shorthands like just `jane` or +`user:jane`. ## Sign-in Resolvers @@ -90,116 +85,170 @@ the given auth provider, as well as a context object that contains various helpe for looking up users and issuing tokens. There are also a number of built-in sign-in resolvers that can be used, which are covered a bit further down. -Note that while it possible to configure multiple auth providers to be used for sign-in, -you should take care when doing so. It is best to make sure that the different auth -providers either do not have any user overlap, or that any users that are able to log -in with multiple providers always end up with the same Backstage identity. +Note that while it possible to configure multiple auth providers to be used for +sign-in, you should take care when doing so. It is best to make sure that the +different auth providers either do not have any user overlap, or that any users +that are able to log in with multiple providers always end up with the same +Backstage identity. For most organizations, it makes the most sense to provide +only one sign-in method. -### Custom Resolver Example +### Using Builtin Resolvers -Let's look at an example of a custom sign-in resolver for the Google auth provider. -This all typically happens within your `packages/backend/src/plugins/auth.ts` file, -which is responsible for setting up and configuring the auth backend plugin. +Most auth providers come with a set of builtin sign in providers that you can +choose from. They target the most common use cases, and if they fit your needs, +you can pick one or more of them without having to write any code at all. You +still have to make a choice - as mentioned above, even if there are a set of +builtins, none of them are selected by default. -You provide the resolver as part of the options you pass when creating a new auth -provider factory. This means you need to replace the default Google provider with -one that you create. Be sure to also include the existing `defaultAuthProviderFactories` -if you want to keep all of the built-in auth providers installed. +You set up builtin sign in resolvers using [your app-config](../conf/index.md), +next to the respective provider's configuration. Here's an example for GitHub: -Now let's look at the example, with the rest of the commentary being made with in -the code comments: +```yaml title="in e.g. app-config.yaml" +auth: + environment: development + providers: + github: + development: + clientId: ${AUTH_GITHUB_CLIENT_ID} + clientSecret: ${AUTH_GITHUB_CLIENT_SECRET} + enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL} + signIn: + resolvers: + - resolver: usernameMatchingUserEntityName + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName +``` + +Note that in this instance it lists several resolvers, which means that the +framework will try them one by one until one succeeds. If none of them do, the +sign in attempt is rejected. + +The list of available resolvers is different for each provider, since they often +depend on the information model returned from the upstream provider service. +Consult the documentation of the respective provider to find the list. + +### Building Custom Resolvers + +If the builtins don't work for you, you can also provide a completely custom +sign-in resolver, through code. If you follow the installation instructions of +[one of the available providers](./index.md), you will likely have added a +dependency to your backend along with a line of code and some configuration. + +Using GitHub as an example, this is the relevant parts of the backend code: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); +``` + +When you want to supply a custom sign-in resolver, as a general pattern you +remove that last import and instead construct your own provider using the +facilities from the same package. You can leave the config unchanged from +before. + +```ts title="in packages/backend/src/index.ts" +/* highlight-add-start */ +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { githubAuthenticator } from '@backstage/plugin-auth-backend-module-github-provider'; +import { + authProvidersExtensionPoint, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; + +const customAuth = createBackendModule({ + // This ID must be exactly "auth" because that's the plugin it targets + pluginId: 'auth', + // This ID must be unique, but can be anything + moduleId: 'custom-auth-provider', + register(reg) { + reg.registerInit({ + deps: { providers: authProvidersExtensionPoint }, + async init({ providers }) { + providers.registerProvider({ + // This ID must match the actual provider config, e.g. addressing + // auth.providers.github means that this must be "github". + providerId: 'github', + // Use createProxyAuthProviderFactory instead if it's one of the proxy + // based providers rather than an OAuth based one + factory: createOAuthProviderFactory({ + authenticator: githubAuthenticator, + async signInResolver(info, ctx) { + /********************************************************************* + * Custom resolver code goes here, see farther down in this article! * + * "info" is the sign in result from the upstream (github here), and * + * "ctx" contains useful utilities for token issuance etc. * + *********************************************************************/ + }, + }), + }); + }, + }); + }, +}); +/* highlight-add-end */ + +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-remove-next-line */ +backend.add(import('@backstage/plugin-auth-backend-module-github-provider')); +/* highlight-add-next-line */ +backend.add(customAuth); +``` + +Check out [the naming patterns +article](../backend-system/architecture/07-naming-patterns.md) for what rules +apply regarding how to form valid IDs. In this example we also put the module +declaration directly in `packages/backend/src/index.ts` but that's just for +simplicity. You can place it anywhere you like, including in other packages, and +import from there if you prefer. + +The `createOAuthProviderFactory` / `createProxyAuthProviderFactory` functions +have additional options for profile and state transforms - not covered here, but +good to know about if you need them. + +So what would the body of a typical sign in resolver callback look like? Here's +an example: ```ts -// File: packages/backend/src/plugins/auth.ts -import { - createRouter, - providers, - defaultAuthProviderFactories, -} from '@backstage/plugin-auth-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; +// ... +async signInResolver(info, ctx) { + const { profile: { email } } = info; -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - return await createRouter({ - ...env, - providerFactories: { - ...defaultAuthProviderFactories, - google: providers.google.create({ - signIn: { - resolver: async (info, ctx) => { - const { - profile: { email }, - } = info; - // Profiles are not always guaranteed to to have an email address. - // You can also find more provider-specific information in `info.result`. - // It typically contains a `fullProfile` object as well as ID and/or access - // tokens that you can use for additional lookups. - if (!email) { - throw new Error('User profile contained no email'); - } + // Profiles are not always guaranteed to to have an email address. + // You can also find more provider-specific information in `info.result`. + // It typically contains a `fullProfile` object as well as ID and/or access + // tokens that you can use for additional lookups. + if (!email) { + throw new Error('User profile contained no email'); + } - // You can add your own custom validation logic here. - // Logins can be prevented by throwing an error like the one above. - myEmailValidator(email); + // You can add your own custom validation logic here. + // Logins can be prevented by throwing an error like the one above. + myEmailValidator(email); - // This example resolver simply uses the local part of the email as the name. - const [name] = email.split('@'); + // This example resolver simply uses the local part of the email as the name. + const [name] = email.split('@'); - // This helper function handles sign-in by looking up a user in the catalog. - // The lookup can be done either by reference, annotations, or custom filters. - // - // The helper also issues a token for the user, using the standard group - // membership logic to determine the ownership references of the user. - return ctx.signInWithCatalogUser({ - entityRef: { name }, - }); - }, - }, - }), - }, + // This helper function handles sign-in by looking up a user in the catalog. + // The lookup can be done either by reference, annotations, or custom filters. + // + // The helper also issues a token for the user, using the standard group + // membership logic to determine the ownership references of the user. + // + // There are a number of other methods on the ctx, feel free to explore them! + return ctx.signInWithCatalogUser({ + entityRef: { name }, }); } ``` -### Built-in Resolvers +If you throw an error in the sign in resolver function, the sign in attempt is +immediately rejected, and the error details are presented in the user interface. -You don't always have to write your own custom resolver. The auth backend plugin provides -built-in resolvers for many of the common sign-in patterns. You access these via the `resolvers` -property of each of the auth provider integrations. For example, the Google provider has -a built in resolver that works just like the one we defined above: +The `ctx` context [has several useful +functions](https://backstage.io/docs/reference/plugin-auth-node.authresolvercontext/) +for issuing tokens in various ways. -```ts -// File: packages/backend/src/plugins/auth.ts -export default async function createPlugin( - // ... - return await createRouter({ - // ... - providerFactories: { - // ... - google: providers.google.create({ - signIn: { - resolver: providers.google.resolvers.emailLocalPartMatchingUserEntityName(), - }, - }); - } - }) -) -``` - -There are also other options, like the this one that looks up a user -by matching the `google.com/email` annotation of user entities in the catalog: - -```ts -providers.google.create({ - signIn: { - resolver: providers.google.resolvers.emailMatchingUserEntityAnnotation(), - }, -}); -``` - -## Custom Ownership Resolution +### Custom Ownership Resolution If you want to have more control over the membership resolution and token generation that happens during sign-in you can replace `ctx.signInWithCatalogUser` with a set @@ -209,55 +258,48 @@ of lower-level calls: // File: packages/backend/src/plugins/auth.ts import { getDefaultOwnershipEntityRefs } from '@backstage/plugin-auth-backend'; -export default async function createPlugin( - // ... - return await createRouter({ - // ... - providerFactories: { - // ... - google: async ({ profile: { email } }, ctx) => { - if (!email) { - throw new Error('User profile contained no email'); - } +// ... +async signInResolver({ profile: { email} }, ctx) { + if (!email) { + throw new Error('User profile contained no email'); + } - // This step calls the catalog to look up a user entity. You could for example - // replace it with a call to a different external system. - const { entity } = await ctx.findCatalogUser({ - annotations: { - 'acme.org/email': email, - }, - }); + // This step calls the catalog to look up a user entity. You could for example + // replace it with a call to a different external system. + const { entity } = await ctx.findCatalogUser({ + annotations: { + 'acme.org/email': email, + }, + }); - // In this step we extract the ownership references from the user entity using - // the standard logic. It uses a reference to the entity itself, as well as the - // target of each `memberOf` relation where the target is of the kind `Group`. - // - // If you replace the catalog lookup with something that does not return - // an entity you will need to replace this step as well. - // - // You might also replace it if you for example want to filter out certain groups. - // - // Note that `getDefaultOwnershipEntityRefs` only includes groups to which the - // user has a direct MEMBER_OF relationship. It's perfectly fine to include - // groups that the user is transitively part of in the claims array, but the - // catalog doesn't currently provide a direct way of accessing this list of - // groups. - const ownershipRefs = getDefaultOwnershipEntityRefs(entity); + // In this step we extract the ownership references from the user entity using + // the standard logic. It uses a reference to the entity itself, as well as the + // target of each `memberOf` relation where the target is of the kind `Group`. + // + // If you replace the catalog lookup with something that does not return + // an entity you will need to replace this step as well. + // + // You might also replace it if you for example want to filter out certain groups. + // + // Note that `getDefaultOwnershipEntityRefs` only includes groups to which the + // user has a direct MEMBER_OF relationship. It's perfectly fine to include + // groups that the user is transitively part of in the claims array, but the + // catalog doesn't currently provide a direct way of accessing this list of + // groups. + const ownershipRefs = getDefaultOwnershipEntityRefs(entity); - // The last step is to issue the token, where we might provide more options in the future. - return ctx.issueToken({ - claims: { - sub: stringifyEntityRef(entity), - ent: ownershipRefs, - }, - }); - }; - } - }) -) + // The last step is to issue the token, where we might provide more options in the + // future. + return ctx.issueToken({ + claims: { + sub: stringifyEntityRef(entity), + ent: ownershipRefs, + }, + }); +} ``` -## Sign-In without Users in the Catalog +### Sign-In without Users in the Catalog While populating the catalog with organizational data unlocks more powerful ways to browse your software ecosystem, it might not always be a viable or prioritized @@ -278,63 +320,44 @@ check like in the example below, or you might for example look up the GitHub org that the user belongs to using the user access token in the provided result object. ```ts -// File: packages/backend/src/plugins/auth.ts -import { createRouter, providers } from '@backstage/plugin-auth-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; -import { - stringifyEntityRef, - DEFAULT_NAMESPACE, -} from '@backstage/catalog-model'; +import { stringifyEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - return await createRouter({ - ...env, - providerFactories: { - google: providers.google.create({ - signIn: { - resolver: async ({ profile }, ctx) => { - if (!profile.email) { - throw new Error( - 'Login failed, user profile does not contain an email', - ); - } - // Split the email into the local part and the domain. - const [localPart, domain] = profile.email.split('@'); +// ... +async signInResolver({ profile }, ctx) { + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + // Split the email into the local part and the domain. + const [localPart, domain] = profile.email.split('@'); - // Next we verify the email domain. It is recommended to include this - // kind of check if you don't look up the user in an external service. - if (domain !== 'acme.org') { - throw new Error( - `Login failed, this email ${profile.email} does not belong to the expected domain`, - ); - } + // Next we verify the email domain. It is recommended to include this + // kind of check if you don't look up the user in an external service. + if (domain !== 'acme.org') { + throw new Error( + `Login failed, '${profile.email}' does not belong to the expected domain`, + ); + } - // By using `stringifyEntityRef` we ensure that the reference is formatted correctly - const userEntity = stringifyEntityRef({ - kind: 'User', - name: localPart, - namespace: DEFAULT_NAMESPACE, - }); - return ctx.issueToken({ - claims: { - sub: userEntity, - ent: [userEntity], - }, - }); - }, - }, - }), + // By using `stringifyEntityRef` we ensure that the reference is formatted correctly + const userEntity = stringifyEntityRef({ + kind: 'User', + name: localPart, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userEntity, + ent: [userEntity], }, }); } ``` -## AuthHandler +## Profile Transforms -Similar to a custom sign-in resolver, you can also write a custom auth handler +Similar to a custom sign-in resolver, you can also write a custom profile transform function which is used to verify and convert the auth response into the profile that will be presented to the user. This is where you can customize things like display name and profile picture. @@ -343,29 +366,43 @@ This is also the place where you can do authorization and validation of the user and throw errors if the user should not be allowed access in Backstage. ```ts -// File: packages/backend/src/plugins/auth.ts -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - return await createRouter({ - ... - providerFactories: { - google: providers.google.create({ - authHandler: async ({ - fullProfile // Type: passport.Profile, - idToken // Type: (Optional) string, - }) => { - // Custom validation code goes here - return { - profile: { - email, - picture, - displayName, - } - }; - } - }) - } - }) -} +const customAuth = createBackendModule({ + // This ID must be exactly "auth" because that's the plugin it targets + pluginId: 'auth', + // This ID must be unique, but can be anything + moduleId: 'custom-auth-provider', + register(reg) { + reg.registerInit({ + deps: { providers: authProvidersExtensionPoint }, + async init({ providers }) { + providers.registerProvider({ + // This ID must match the actual provider config, e.g. addressing + // auth.providers.github means that this must be "github". + providerId: 'github', + // Use createProxyAuthProviderFactory instead if it's one of the proxy + // based providers rather than an OAuth based one + factory: createOAuthProviderFactory({ + authenticator: githubAuthenticator, + async profileTransform(result, ctx) { + /********************************************************************** + * Custom transform code goes here! * + * "info" is the sign in result from the upstream (github here), and * + * "ctx" contains useful utilities. * + **********************************************************************/ + return { + profile: { + email, + picture, + displayName, + }, + }; + }, + }), + }); + }, + }); + }, +}); ``` + +Remember to `backend.add` the created module just like above. diff --git a/docs/auth/microsoft/azure-easyauth.md b/docs/auth/microsoft/azure-easyauth.md index 07a3923da1..5fec3354d7 100644 --- a/docs/auth/microsoft/azure-easyauth.md +++ b/docs/auth/microsoft/azure-easyauth.md @@ -7,63 +7,52 @@ description: Adding Azure's EasyAuth Proxy as an authentication provider in Back The Backstage `core-plugin-api` package comes with a Microsoft authentication provider that can authenticate users using Microsoft Entra ID (formerly Azure Active Directory) for PaaS service hosted in Azure that support Easy Auth, such as Azure App Services. -## Backstage Changes +## Backend Changes -Add the following into your `app-config.yaml` or `app-config.production.yaml` file +Add the following into your `app-config.yaml` under the root `auth` configuration: -```yaml +```yaml title="app-config.yaml" auth: - environment: development providers: - azure-easyauth: - development: {} + azureEasyAuth: + signIn: + resolvers: + - resolver: idMatchingUserEntityAnnotation + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName ``` -Add a `providerFactories` entry to the router in -`packages/backend/src/plugins/auth.ts`. +The `idMatchingUserEntityAnnotation` is +[a builtin sign-in resolver](../identity-resolver.md#using-builtin-resolvers) from `azureEasyAuth` provider. +It tries to find a user entity with [a `graph.microsoft.com/user-id` annotation](../../features/software-catalog/well-known-annotations.md#graphmicrosoftcomtenant-id-graphmicrosoftcomgroup-id-graphmicrosoftcomuser-id) +which matches the object ID of the user attempting to sign in. +If you want to provide your own sign-in resolver, +see [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers). -```ts -import { providers } from '@backstage/plugin-auth-backend'; +Add the `@backstage/plugin-auth-backend-module-azure-easyauth-provider` to your backend installation. -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - const authProviderFactories = { - 'azure-easyauth': providers.easyAuth.create({ - signIn: { - resolver: async (info, ctx) => { - const { - fullProfile: { id }, - } = info.result; +```sh +# From your Backstage root directory +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-azure-easyauth-provider +``` - if (!id) { - throw new Error('User profile contained no id'); - } +Then, add it to your backend's source, - return await ctx.signInWithCatalogUser({ - annotations: { - 'graph.microsoft.com/user-id': id, - }, - }); - }, - }, - }), - }; +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); - return await createRouter({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - providerFactories: authProviderFactories, - }); -} +backend.add(import('@backstage/plugin-auth-backend')); +// highlight-add-next-line +backend.add( + import('@backstage/plugin-auth-backend-module-azure-easyauth-provider'), +); + +await backend.start(); ``` Now the backend is ready to serve auth requests on the -`/api/auth/azure-easyauth/refresh` endpoint. All that's left is to update the frontend -sign-in mechanism to poll that endpoint through the IAP, on the user's behalf. +`/api/auth/azureEasyAuth/refresh` endpoint. All that's left is to update the frontend +sign-in mechanism to poll that endpoint through the Easy Auth proxy, on the user's behalf. ## Frontend Changes @@ -82,7 +71,7 @@ const app = createApp({ SignInPage: props => { const configApi = useApi(configApiRef); if (configApi.getString('auth.environment') !== 'development') { - return <ProxiedSignInPage {...props} provider="azure-easyauth" />; + return <ProxiedSignInPage {...props} provider="azureEasyAuth" />; } return ( <SignInPage diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index 5cff655c02..ef11827039 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -22,8 +22,7 @@ The provider configuration can be added to your `app-config.yaml` under the root auth: environment: development providers: - oauth2Proxy: - development: {} + oauth2Proxy: {} ``` Right now no configuration options are supported, but the empty object is needed diff --git a/docs/auth/oidc.md b/docs/auth/oidc.md index de369660dd..98d0e63255 100644 --- a/docs/auth/oidc.md +++ b/docs/auth/oidc.md @@ -92,6 +92,7 @@ export const apis: AnyApiFactory[] = [ }, factory: ({ discoveryApi, oauthRequestApi, configApi }) => OAuth2.create({ + configApi, discoveryApi, oauthRequestApi, provider: { diff --git a/docs/auth/service-to-service-auth--old.md b/docs/auth/service-to-service-auth--old.md new file mode 100644 index 0000000000..8341d69341 --- /dev/null +++ b/docs/auth/service-to-service-auth--old.md @@ -0,0 +1,177 @@ +--- +id: service-to-service-auth--old +title: Service to Service Auth +# prettier-ignore +description: This section describes how to use service to service authentication, both internally within Backstage plugins and towards external services. +--- + +:::info +This documentation is written for the old backend which has been replaced by +[the new backend system](../backend-system/index.md), being the default since +Backstage [version 1.24](../releases/v1.24.0.md). If have migrated to the new +backend system, you may want to read [its own article](./identity-resolver.md) +instead. Otherwise, [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + +This article describes the steps needed to introduce _service-to-service auth_ (formerly _backend-to-backend_ auth). +This allows plugin backends to determine whether a given request originates from +a legitimate Backstage plugin (or other external caller), by requiring a special +type of service-to-service token which is signed with a shared secret. + +When enabling this protection on your Backstage backend plugins, for example the +catalog, other callers in the ecosystem such as the search indexer and +scaffolder would need to present a valid token to the catalog to be able to +request its contents. + +## Setup + +In a newly created Backstage app, the backend is setup up to not require any +auth at all. This means that generated service-to-service tokens are empty, and +that incoming requests are not validated. If you want to enable +service-to-service auth, the first step is to switch out the following line in +your backend setup at `packages/backend/src/index.ts`: + +```ts title="packages/backend/src/index.ts" +/* highlight-remove-next-line */ +const tokenManager = ServerTokenManager.noop(); +/* highlight-add-next-line */ +const tokenManager = ServerTokenManager.fromConfig(config, { logger: root }); +``` + +By switching from the no-op `ServiceTokenManager` to one created from config, +you enable service-to-service auth for any plugin that implements it. The local +development setup will generally not be impacted by this, as temporary keys are +generated under the hood. But for the production setup, this means you must now +provide a shared secret that enables your backend plugins to communicate with +each other. + +Backstage service-to-service tokens are currently always signed with a single +secret key. It needs to be shared across all backend plugins and services that +ones wishes to communicate across. The key can be any base64 encoded secret. +The following command can be used to generate such a key in a terminal: + +```bash +node -p 'require("crypto").randomBytes(24).toString("base64")' +``` + +Then place it in the backend configuration, either as a direct value or +injected as an env variable. + +```yaml +# commonly in your app-config.production.yaml +backend: + auth: + keys: + - secret: <the string returned by the above crypto command> + # - secret: ${BACKEND_SECRET} - if you want to use an env variable instead +``` + +**NOTE**: For ease of development, we auto-generate a key for you if you haven't +configured a secret in dev mode. You _must set your own secret_ in order for +service-to-service auth to work in production; the `ServiceTokenManager` will +throw an exception in production if it has no keys to work with, which will lead +to the backend failing to start up. + +## Usage in Backend Plugins + +There are a few steps if you want to make use of the service-to-service auth in +your own backend plugin. First you need to add the `TokenManager` dependency to +the `createRouter` options. Typically as `tokenManager: TokenManager`. Along +with this you'll need to ask users to start providing this new dependency in +their backend setup code. + +Once the `TokenManager` is available, you use the `.getToken()` method to generate +a new token for any outgoing requests towards other Backstage backend plugins. +This method should be called for every request that you make; do not store the +token for later use. The `TokenManager` implementations should already cache +tokens as needed. The returned token should then be added as a `Bearer` token +for the upstream request, for example: + +```ts +const { token } = await this.tokenManager.getToken(); + +const response = await fetch(pluginBackendApiUrl, { + method: 'GET', + headers: { + ...headers, + Authorization: `Bearer ${token}`, + }, +}); +``` + +To authenticate an incoming request you use the `.authenticate(token)` method. +At the time of writing this method doesn't return anything, it will simply +throw if the token is invalid. + +```ts +await tokenManager.authenticate(token); // throws if token is invalid +``` + +## Usage in External Callers + +If you have enabled server-to-server auth, you may be interested in generating +tokens in code that is external to Backstage itself. External callers may even +be written in other languages than Node.js. This section explains how to generate +a valid token yourself. + +The token must be a JWT with a `HS256` signature, using the raw base64 decoded +value of the configured key as the secret. It must also have the following payload: + +- `sub`: "backstage-server" (only this value supported currently) +- `exp`: one hour from the time it was generated, in epoch seconds + +> NOTE: The JWT must encode the `alg` header as a protected header, such as with +> [setProtectedHeader](https://github.com/panva/jose/blob/main/docs/classes/jwt_sign.SignJWT.md#setprotectedheader). + +## Granular Access Control + +We plan to build out the service-to-service auth to be much more powerful in the +future, but before that is done there are a few tricks you can use with the +current system to harden your deployments. This section assumes that you have +already split your backend plugins into more than one backend deployment, in +order to scale or isolate them. + +The backend auth configuration has support for providing multiple keys, for +example: + +```yaml +backend: + auth: + keys: + - secret: my-secret-key-1 + - secret: my-secret-key-2 + - secret: my-secret-key-3 +``` + +The first key will be used for signing requests, while all of the keys will be +used for validation. This means that you can set up an asymmetric configuration +where some backend deployments do not have access to each other. + +For example, consider the case where we have split up the catalog, scaffolder, +and search plugin into three separate backend deployments. We can use the +following configurations to allow both the scaffolder and search plugin to speak +to the +catalog, but not the other way around, and to not allow any communication between +the scaffolder and search plugins. + +```yaml +# catalog config +backend: + auth: + keys: + - secret: my-secret-key-catalog + - secret: my-secret-key-scaffolder + - secret: my-secret-key-search + +# scaffolder config +backend: + auth: + keys: + - secret: my-secret-key-scaffolder + +# search config +backend: + auth: + keys: + - secret: my-secret-key-search +``` diff --git a/docs/auth/service-to-service-auth.md b/docs/auth/service-to-service-auth.md index aac61be563..c1d6643769 100644 --- a/docs/auth/service-to-service-auth.md +++ b/docs/auth/service-to-service-auth.md @@ -2,168 +2,167 @@ id: service-to-service-auth title: Service to Service Auth # prettier-ignore -description: This section describes how to use service to service authentication, both internally within Backstage plugins and towards external services. +description: This section describes service to service authentication works, both internally within Backstage plugins and when external callers want to make requests. --- -This article describes the steps needed to introduce _service-to-service auth_ (formerly _backend-to-backend_ auth). -This allows plugin backends to determine whether a given request originates from -a legitimate Backstage plugin (or other external caller), by requiring a special -type of service-to-service token which is signed with a shared secret. +:::info +This documentation is written for [the new backend +system](../backend-system/index.md) which is the default since Backstage +[version 1.24](../releases/v1.24.0.md). If you are still on the old backend +system, you may want to read [its own article](./service-to-service-auth--old.md) +instead, and [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: -When enabling this protection on your Backstage backend plugins, for example the -catalog, other callers in the ecosystem such as the search indexer and -scaffolder would need to present a valid token to the catalog to be able to -request its contents. +This article describes how _service-to-service auth_ works in Backstage, both +between Backstage backend plugins and for external callers who want to make +requests to them. This is in contrast to _user and user-to-service auth_ which +use different flows. -## Setup +Each section describes one distinct type of auth flow. -In a newly created Backstage app, the backend is setup up to not require any -auth at all. This means that generated service-to-service tokens are empty, and -that incoming requests are not validated. If you want to enable -service-to-service auth, the first step is to switch out the following line in -your backend setup at `packages/backend/src/index.ts`: +## Standard Plugin-to-Plugin Auth -```ts title="packages/backend/src/index.ts" -/* highlight-remove-next-line */ -const tokenManager = ServerTokenManager.noop(); -/* highlight-add-next-line */ -const tokenManager = ServerTokenManager.fromConfig(config, { logger: root }); +Backstage plugins that use the new backend system and handle credentials using +the `auth` and `httpAuth` service APIs are secure by default, without requiring +any configuration. They generate self-signed tokens automatically for making +requests to other Backstage backend plugins, and the receivers use the caller's +public key set endpoint to be able to perform verification. + +This flow has only one configuration option to set in your app-config: +`backend.auth.dangerouslyDisableDefaultAuthPolicy`, which can be set to `true` +if you for some reason need to completely disable both the issuing and +verification of tokens between backend plugins. This makes your backends +insecure and callable by anyone without auth, so only use this as a last resort +and when your deployment is behind a secure ingress like a VPN. + +External callers cannot leverage this flow; it's only used internally by backend +plugins calling other backend plugins. + +## Static Tokens + +This access method consists of random static tokens that can be handed out to +external callers who want to make requests to Backstage backend plugins. This is +useful for the most basic callers such as command line scripts, web hooks and +similar. + +You configure this access method by adding one or more entries of type `static` +to the `backend.auth.externalAccess` app-config key: + +```yaml title="in e.g. app-config.production.yaml" +backend: + auth: + externalAccess: + - type: static + options: + token: ${CICD_TOKEN} + subject: cicd-system-completion-events + - type: static + options: + token: ${ADMIN_CURL_TOKEN} + subject: admin-curl-access ``` -By switching from the no-op `ServiceTokenManager` to one created from config, -you enable service-to-service auth for any plugin that implements it. The local -development setup will generally not be impacted by this, as temporary keys are -generated under the hood. But for the production setup, this means you must now -provide a shared secret that enables your backend plugins to communicate with -each other. +The tokens can be any string without whitespace, but for security reasons should +be sufficiently long so as not to be easy to guess by brute force. You can for +example generate them on the command line: -Backstage service-to-service tokens are currently always signed with a single -secret key. It needs to be shared across all backend plugins and services that -ones wishes to communicate across. The key can be any base64 encoded secret. -The following command can be used to generate such a key in a terminal: - -```bash +```shell node -p 'require("crypto").randomBytes(24).toString("base64")' ``` -Then place it in the backend configuration, either as a direct value or -injected as an env variable. +The subjects must be strings without whitespace. They are used for identifying +each caller, and become part of the credentials object that request recipient +plugins get. + +Callers pass along the tokens verbatim with requests in the `Authorization` +header: ```yaml -# commonly in your app-config.production.yaml +Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW +``` + +## Legacy Tokens + +Plugins and backends that are _not_ on the new backend system use a legacy token +flow, where shared static secrets in your app-config are used for signing and +verification. If you are on the new backend system and are not using legacy +plugins using the compatibility wrapper, you can skip this section. + +### Configuration (legacy) + +In local development, there is no need to configure anything for this auth +method. But in production, you must configure at least one legacy type external +access method: + +```yaml title="in e.g. app-config.production.yaml" backend: auth: - keys: - - secret: <the string returned by the above crypto command> - # - secret: ${BACKEND_SECRET} - if you want to use an env variable instead + externalAccess: + - type: legacy + options: + secret: my-secret-key-catalog + subject: legacy-catalog + - type: legacy + options: + secret: my-secret-key-scaffolder + subject: legacy-scaffolder ``` -**NOTE**: For ease of development, we auto-generate a key for you if you haven't -configured a secret in dev mode. You _must set your own secret_ in order for -service-to-service auth to work in production; the `ServiceTokenManager` will -throw an exception in production if it has no keys to work with, which will lead -to the backend failing to start up. +The old style keys config is also supported as an alternative, but please +consider using the new style above instead: -## Usage in Backend Plugins - -There are a few steps if you want to make use of the service-to-service auth in -your own backend plugin. First you need to add the `TokenManager` dependency to -the `createRouter` options. Typically as `tokenManager: TokenManager`. Along -with this you'll need to ask users to start providing this new dependency in -their backend setup code. - -Once the `TokenManager` is available, you use the `.getToken()` method to generate -a new token for any outgoing requests towards other Backstage backend plugins. -This method should be called for every request that you make; do not store the -token for later use. The `TokenManager` implementations should already cache -tokens as needed. The returned token should then be added as a `Bearer` token -for the upstream request, for example: - -```ts -const { token } = await this.tokenManager.getToken(); - -const response = await fetch(pluginBackendApiUrl, { - method: 'GET', - headers: { - ...headers, - Authorization: `Bearer ${token}`, - }, -}); -``` - -To authenticate an incoming request you use the `.authenticate(token)` method. -At the time of writing this method doesn't return anything, it will simply -throw if the token is invalid. - -```ts -await tokenManager.authenticate(token); // throws if token is invalid -``` - -## Usage in External Callers - -If you have enabled server-to-server auth, you may be interested in generating -tokens in code that is external to Backstage itself. External callers may even -be written in other languages than Node.js. This section explains how to generate -a valid token yourself. - -The token must be a JWT with a `HS256` signature, using the raw base64 decoded -value of the configured key as the secret. It must also have the following payload: - -- `sub`: "backstage-server" (only this value supported currently) -- `exp`: one hour from the time it was generated, in epoch seconds - -> NOTE: The JWT must encode the `alg` header as a protected header, such as with -> [setProtectedHeader](https://github.com/panva/jose/blob/main/docs/classes/jwt_sign.SignJWT.md#setprotectedheader). - -## Granular Access Control - -We plan to build out the service-to-service auth to be much more powerful in the -future, but before that is done there are a few tricks you can use with the -current system to harden your deployments. This section assumes that you have -already split your backend plugins into more than one backend deployment, in -order to scale or isolate them. - -The backend auth configuration has support for providing multiple keys, for -example: - -```yaml -backend: - auth: - keys: - - secret: my-secret-key-1 - - secret: my-secret-key-2 - - secret: my-secret-key-3 -``` - -The first key will be used for signing requests, while all of the keys will be -used for validation. This means that you can set up an asymmetric configuration -where some backend deployments do not have access to each other. - -For example, consider the case where we have split up the catalog, scaffolder, -and search plugin into three separate backend deployments. We can use the -following configurations to allow both the scaffolder and search plugin to speak -to the -catalog, but not the other way around, and to not allow any communication between -the scaffolder and search plugins. - -```yaml -# catalog config +```yaml title="in e.g. app-config.production.yaml" backend: auth: keys: - secret: my-secret-key-catalog - secret: my-secret-key-scaffolder - - secret: my-secret-key-search - -# scaffolder config -backend: - auth: - keys: - - secret: my-secret-key-scaffolder - -# search config -backend: - auth: - keys: - - secret: my-secret-key-search +``` + +The secrets must be any base64-encoded random data, but for security reasons +should be sufficiently long so as not to be easy to guess by brute force. You +can for example generate them on the command line: + +```shell +node -p 'require("crypto").randomBytes(24).toString("base64")' +``` + +The subjects must be strings without whitespace. They are used for identifying +each caller, and become part of the credentials object that request recipient +plugins get. + +In both of the examples we showed two secrets being specified, but the minimum +is one. The order is significant: the first one is always used for signing of +outgoing requests to other backend plugins, while all of the keys are used for +verification. This is useful if you want to be able to have unique keys per +deployment if you are using split deployments of Backstage. Then each deployment +lists its own signing secret at the top, and only adds the secrets for those +other deployments that it wants to permit to call it. + +For most organizations, we recommend leaving it at just one key and +[migrating](../backend-system/building-backends/08-migrating.md) to the new +backend system as soon as possible instead of experimenting with multiple legacy +secrets. + +### External Callers (legacy) + +For legacy Backstage backend plugins, the above configuration is enough. But +external callers who wish to make requests using this flow must generate tokens +according to the following rules. + +The token must be a JWT with a `HS256` signature, using the raw base64 decoded +value of the configured key as the secret. It must also have the following +payload: + +- `sub`: the exact string "backstage-server" +- `exp`: one hour from the time it was generated, in epoch seconds + +> NOTE: The JWT must encode the `alg` header as a protected header, such as with +> [setProtectedHeader](https://github.com/panva/jose/blob/main/docs/classes/jwt_sign.SignJWT.md#setprotectedheader). + +The caller then passes along the JWT token with requests in the `Authorization` +header: + +```yaml +Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW ``` diff --git a/docs/backend-system/architecture/01-index.md b/docs/backend-system/architecture/01-index.md index 9c37df7b66..681d0fada2 100644 --- a/docs/backend-system/architecture/01-index.md +++ b/docs/backend-system/architecture/01-index.md @@ -56,8 +56,7 @@ Just like plugins, modules also have access to services and can depend on their ## Package structure A detailed explanation of the package architecture can be found in the -[Backstage Architecture -Overview](../../overview/architecture-overview.md#package-architecture). The +[Backstage Architecture Overview](../../overview/architecture-overview.md#package-architecture). The most important packages to consider for this system are the following: - `plugin-<pluginId>-backend` houses the implementation of the backend plugins diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 9eada30ef6..1d7e1dcd03 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -632,7 +632,7 @@ A basic installation of the events plugin looks as follows. ```ts title="packages/backend/src/index.ts" const backend = createBackend(); /* highlight-add-next-line */ -backend.add(import('@backstage/plugin-events-backend')); +backend.add(import('@backstage/plugin-events-backend/alpha')); ``` If you have other customizations made to `plugins/events.ts`, such as adding @@ -646,6 +646,7 @@ depends on the appropriate extension point and interacts with it. ```ts title="packages/backend/src/index.ts" /* highlight-add-start */ +import { eventsServiceRef } from '@backstage/plugin-events-node'; import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { createBackendModule } from '@backstage/backend-plugin-api'; /* highlight-add-end */ @@ -663,7 +664,28 @@ const eventsModuleCustomExtensions = createBackendModule({ async init({ events /* ..., other dependencies */ }) { // Here you have the opportunity to interact with the extension // point before the plugin itself gets instantiated - events.addSubscribers(new MySubscriber()); // just an example + events.addHttpPostIngress({ + // ... + }); + }, + }); + }, +}); +/* highlight-add-end */ + +/* highlight-add-start */ +const otherPluginModuleCustomExtensions = createBackendModule({ + pluginId: 'other-plugin', // name of the plugin that the module is targeting + moduleId: 'custom-extensions', + register(env) { + env.registerInit({ + deps: { + events: eventsServiceRef, + // ... and other dependencies as needed + }, + async init({ events /* ..., other dependencies */ }) { + // Here you have the opportunity to interact with the extension + // point before the plugin itself gets instantiated }, }); }, @@ -671,17 +693,11 @@ const eventsModuleCustomExtensions = createBackendModule({ /* highlight-add-end */ const backend = createBackend(); -backend.add(import('@backstage/plugin-events-backend')); +backend.add(import('@backstage/plugin-events-backend/alpha')); /* highlight-add-next-line */ backend.add(eventsModuleCustomExtensions()); -``` - -This also requires that you have a dependency on the corresponding node package, -if you didn't already have one. - -```bash -# from the repository root -yarn --cwd packages/backend add @backstage/plugin-events-node +/* highlight-add-next-line */ +backend.add(otherPluginModuleCustomExtensions()); ``` Here we've placed the module directly in the backend index file just to get @@ -1026,3 +1042,312 @@ backend.add(import('@backstage/plugin-auth-backend')); backend.add(authModuleGoogleProvider); /* highlight-add-end */ ``` + +#### Using Legacy Providers + +Not all authentication providers have been refactored to support the new backend system. If your authentication provider module is not available yet, you will need to import your backend auth plugin using the legacy helper: + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +/* highlight-add-next-line */ +import { legacyPlugin } from '@backstage/backend-common'; +import { coreServices } from '@backstage/backend-plugin-api'; + +const backend = createBackend(); +/* highlight-remove-next-line */ +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-next-line */ +backend.add(legacyPlugin('auth', import('./plugins/auth'))); + +backend.start(); +``` + +> You can track the progress of the module migration efforts [here](https://github.com/backstage/backstage/issues/19476). + +### The Search Plugin + +A basic installation of the Search plugin will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-search-backend/alpha')); +/* highlight-add-end */ +``` + +> Note: this will use the Lunr search engine which stores its index in memory + +#### Search Engines + +The following sections outline how you can add other Search engines than the default lunr engine. + +##### Postgres + +An installation of the Search plugin using the Postgres search engine will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-search-backend/alpha')); +backend.add(import('@backstage/plugin-search-backend-module-pg/alpha')); +/* highlight-add-end */ +``` + +##### Elasticsearch + +A basic installation of the Search plugin using the Elasticsearch search engine will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-search-backend/alpha')); +backend.add( + import('@backstage/plugin-search-backend-module-elasticsearch/alpha'), +); +/* highlight-add-end */ +``` + +#### Search Collators + +The following sections outline how you add search collators (input sources for the search indexing process). + +##### Catalog + +A basic installation of the Search plugin with the Catalog collator will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-search-backend/alpha')); +backend.add(import('@backstage/plugin-search-backend-module-catalog/alpha')); +/* highlight-add-end */ +``` + +##### TechDocs + +A basic installation of the Search plugin with the TechDocs collator will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-search-backend/alpha')); +backend.add(import('@backstage/plugin-search-backend-module-techdocs/alpha')); +/* highlight-add-end */ +``` + +### The Permission Plugin + +A basic installation of the Permission plugin will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-permission-backend/alpha')); +backend.add( + import('@backstage/plugin-permission-backend-module-allow-all-policy'), +); +/* highlight-add-end */ +``` + +> Note: The above example includes a default allow-all policy. If that is not what you want, do not add the second line and instead investigate one of the options below. + +#### Custom Permission Policy + +In order to add your own permission policy you'll need to do the following: + +```ts +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { + PolicyDecision, + AuthorizeResult, +} from '@backstage/plugin-permission-common'; +import { + PermissionPolicy, + PolicyQuery, +} from '@backstage/plugin-permission-node'; +import { policyExtensionPoint } from '@backstage/plugin-permission-node/alpha'; + +class CustomPermissionPolicy implements PermissionPolicy { + async handle( + request: PolicyQuery, + user?: BackstageIdentityResponse, + ): Promise<PolicyDecision> { + // TODO: Add code here that inspects the incoming request and user, and returns AuthorizeResult.ALLOW, AuthorizeResult.DENY, or AuthorizeResult.CONDITIONAL as needed. See the docs at https://backstage.io/docs/permissions/writing-a-policy for more information + + return { + result: AuthorizeResult.ALLOW, + }; + } +} + +const customPermissionBackendModule = createBackendModule({ + pluginId: 'permission', + moduleId: 'custom-policy', + register(reg) { + reg.registerInit({ + deps: { policy: policyExtensionPoint }, + async init({ policy }) { + policy.setPolicy(new CustomPermissionPolicy()); + }, + }); + }, +}); + +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-permission-backend/alpha')); +backend.add(customPermissionBackendModule); +/* highlight-add-end */ +``` + +### The TechDocs Plugin + +A basic installation of the TechDocs plugin will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-techdocs-backend/alpha')); +/* highlight-add-end */ +``` + +### The Kubernetes Plugin + +A basic installation of the Kubernetes plugin will look as follows: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); +/* highlight-add-end */ +``` + +### The Plugins in Backstage Repo + +The vast majority of the backend plugins that currently live in the Backstage Repo have been migrated and their respective `README`s have details on how they should be installed using the New Backend System. + +| Package | Role | Migrated | Uses Alpha Export | Link to `README` | +| ------------------------------------------------------------------ | --------------------- | -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| @backstage-community/plugin-adr-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/adr/plugins/adr-backend/README.md) | +| @backstage-community/plugin-airbrake-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/airbrake/plugins/airbrake-backend/README.md) | +| @backstage/plugin-app-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/app-backend/README.md) | +| @backstage/plugin-auth-backend | backend-plugin | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend/README.md) | +| @backstage/plugin-auth-backend-module-atlassian-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-atlassian-provider/README.md) | +| @backstage/plugin-auth-backend-module-aws-alb-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-aws-alb-provider/README.md) | +| @backstage/plugin-auth-backend-module-gcp-iap-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-gcp-iap-provider/README.md) | +| @backstage/plugin-auth-backend-module-github-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-github-provider/README.md) | +| @backstage/plugin-auth-backend-module-gitlab-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-gitlab-provider/README.md) | +| @backstage/plugin-auth-backend-module-google-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-google-provider/README.md) | +| @backstage/plugin-auth-backend-module-guest-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-guest-provider/README.md) | +| @backstage/plugin-auth-backend-module-microsoft-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-microsoft-provider/README.md) | +| @backstage/plugin-auth-backend-module-oauth2-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-oauth2-provider/README.md) | +| @backstage/plugin-auth-backend-module-oauth2-proxy-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-oauth2-proxy-provider/README.md) | +| @backstage/plugin-auth-backend-module-oidc-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-oidc-provider/README.md) | +| @backstage/plugin-auth-backend-module-okta-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-okta-provider/README.md) | +| @backstage/plugin-auth-backend-module-pinniped-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-pinniped-provider/README.md) | +| @backstage/plugin-auth-backend-module-vmware-cloud-provider | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-vmware-cloud-provider/README.md) | +| @backstage-community/plugin-azure-devops-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/azure-devops/plugins/azure-devops-backend/README.md) | +| @backstage-community/plugin-azure-sites-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/azure-sites/plugins/azure-sites-backend/README.md) | +| @backstage-community/plugin-badges-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/badges/plugins/badges-backend/README.md) | +| @backstage-community/plugin-bazaar-backend | backend-plugin | true | true | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/bazaar/plugins/bazaar-backend/README.md) | +| @backstage/plugin-catalog-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend/README.md) | +| @backstage/plugin-catalog-backend-module-aws | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-aws/README.md) | +| @backstage/plugin-catalog-backend-module-azure | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-azure/README.md) | +| @backstage/plugin-catalog-backend-module-backstage-openapi | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-backstage-openapi/README.md) | +| @backstage/plugin-catalog-backend-module-bitbucket-cloud | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-bitbucket-cloud/README.md) | +| @backstage/plugin-catalog-backend-module-bitbucket-server | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-bitbucket-server/README.md) | +| @backstage/plugin-catalog-backend-module-gcp | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-gcp/README.md) | +| @backstage/plugin-catalog-backend-module-gerrit | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-gerrit/README.md) | +| @backstage/plugin-catalog-backend-module-github | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-github/README.md) | +| @backstage/plugin-catalog-backend-module-github-org | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-github-org/README.md) | +| @backstage/plugin-catalog-backend-module-gitlab | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-gitlab/README.md) | +| @backstage/plugin-catalog-backend-module-incremental-ingestion | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-incremental-ingestion/README.md) | +| @backstage/plugin-catalog-backend-module-ldap | backend-plugin-module | | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-ldap/README.md) | +| @backstage/plugin-catalog-backend-module-msgraph | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/README.md) | +| @backstage/plugin-catalog-backend-module-openapi | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-openapi/README.md) | +| @backstage/plugin-catalog-backend-module-puppetdb | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-puppetdb/README.md) | +| @backstage/plugin-catalog-backend-module-scaffolder-entity-model | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-scaffolder-entity-model/README.md) | +| @backstage/plugin-catalog-backend-module-unprocessed | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-unprocessed/README.md) | +| @backstage-community/plugin-code-coverage-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/code-coverage/plugins/code-coverage-backend/README.md) | +| @backstage/plugin-devtools-backend | backend-plugin | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/devtools-backend/README.md) | +| @backstage-community/plugin-entity-feedback-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/entity-feedback/plugins/entity-feedback-backend/README.md) | +| @backstage/plugin-events-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend/README.md) | +| @backstage/plugin-events-backend-module-aws-sqs | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-aws-sqs/README.md) | +| @backstage/plugin-events-backend-module-azure | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-azure/README.md) | +| @backstage/plugin-events-backend-module-bitbucket-cloud | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-bitbucket-cloud/README.md) | +| @backstage/plugin-events-backend-module-gerrit | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gerrit/README.md) | +| @backstage/plugin-events-backend-module-github | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-github/README.md) | +| @backstage/plugin-events-backend-module-gitlab | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md) | +| @internal/plugin-todo-list-backend | backend-plugin | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/example-todo-list-backend/README.md) | +| @backstage-community/plugin-explore-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/explore/plugins/explore-backend/README.md) | +| @backstage-community/plugin-jenkins-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/jenkins/plugins/jenkins-backend/README.md) | +| @backstage-community/plugin-kafka-backend | backend-plugin | true | true | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/kafka/plugins/kafka-backend/README.md) | +| @backstage/plugin-kubernetes-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/kubernetes-backend/README.md) | +| @backstage-community/plugin-lighthouse-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/lighthouse/plugins/lighthouse-backend/README.md) | +| @backstage-community/plugin-linguist-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/linguist/plugins/linguist-backend/README.md) | +| @backstage-community/plugin-nomad-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/nomad/plugins/nomad-backend/README.md) | +| @backstage/plugin-notifications-backend | backend-plugin | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/notifications-backend/README.md) | +| @backstage-community/plugin-periskop-backend | backend-plugin | true | true | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/periskop/plugins/periskop-backend/README.md) | +| @backstage/plugin-permission-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/permission-backend/README.md) | +| @backstage/plugin-permission-backend-module-allow-all-policy | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/permission-backend-module-policy-allow-all/README.md) | +| @backstage-community/plugin-playlist-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/playlist/plugins/playlist-backend/README.md) | +| @backstage/plugin-proxy-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/proxy-backend/README.md) | +| @backstage-community/plugin-rollbar-backend | backend-plugin | | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/rollbar/plugins/rollbar-backend/README.md) | +| @backstage/plugin-scaffolder-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/README.md) | +| @backstage/plugin-scaffolder-backend-module-azure | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-azure/README.md) | +| @backstage/plugin-scaffolder-backend-module-bitbucket | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-bitbucket/README.md) | +| @backstage/plugin-scaffolder-backend-module-bitbucket-cloud | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-bitbucket-cloud/README.md) | +| @backstage/plugin-scaffolder-backend-module-bitbucket-server | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-bitbucket-server/README.md) | +| @backstage/plugin-scaffolder-backend-module-confluence-to-markdown | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-confluence-to-markdown/README.md) | +| @backstage/plugin-scaffolder-backend-module-cookiecutter | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-cookiecutter/README.md) | +| @backstage/plugin-scaffolder-backend-module-gerrit | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-gerrit/README.md) | +| @backstage/plugin-scaffolder-backend-module-gitea | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-gitea/README.md) | +| @backstage/plugin-scaffolder-backend-module-github | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/README.md) | +| @backstage/plugin-scaffolder-backend-module-gitlab | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-gitlab/README.md) | +| @backstage/plugin-scaffolder-backend-module-rails | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-rails/README.md) | +| @backstage/plugin-scaffolder-backend-module-sentry | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-sentry/README.md) | +| @backstage/plugin-scaffolder-backend-module-yeoman | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-yeoman/README.md) | +| @backstage/plugin-search-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend/README.md) | +| @backstage/plugin-search-backend-module-catalog | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-catalog/README.md) | +| @backstage/plugin-search-backend-module-elasticsearch | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-elasticsearch/README.md) | +| @backstage/plugin-search-backend-module-explore | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-explore/README.md) | +| @backstage/plugin-search-backend-module-pg | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-pg/README.md) | +| @backstage/plugin-search-backend-module-stack-overflow-collator | backend-plugin-module | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-stack-overflow-collator/README.md) | +| @backstage/plugin-search-backend-module-techdocs | backend-plugin-module | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-techdocs/README.md) | +| @backstage/plugin-signals-backend | backend-plugin | true | | [README](https://github.com/backstage/backstage/blob/master/plugins/signals-backend/README.md) | +| @backstage-community/plugin-sonarqube-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/sonarqube/plugins/sonarqube-backend/README.md) | +| @backstage-community/plugin-stack-overflow-backend | backend-plugin | | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/stack-overflow/plugins/stack-overflow-backend/README.md) | +| @backstage-community/plugin-tech-insights-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/tech-insights/plugins/tech-insights-backend/README.md) | +| @backstage-community/plugin-tech-insights-backend-module-jsonfc | backend-plugin-module | true | | [README](https://github.com/backstage/community-plugins/blob/main/workspaces/tech-insights/plugins/tech-insights-backend-module-jsonfc/README.md) | +| @backstage/plugin-techdocs-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend/README.md) | +| @backstage-community/plugin-todo-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/todo/plugins/todo-backend/README.md) | +| @backstage/plugin-user-settings-backend | backend-plugin | true | true | [README](https://github.com/backstage/backstage/blob/master/plugins/user-settings-backend/README.md) | +| @backstage-community/plugin-vault-backend | backend-plugin | true | | [README](https://github.com/backstage/community-plugins/blob/master/workspaces/vault/plugins/vault-backend/README.md) | diff --git a/docs/backend-system/core-services/01-index.md b/docs/backend-system/core-services/01-index.md index 9074998719..04d2e57ae8 100644 --- a/docs/backend-system/core-services/01-index.md +++ b/docs/backend-system/core-services/01-index.md @@ -8,666 +8,30 @@ description: Core backend service APIs The default backend provides several [core services](https://github.com/backstage/backstage/blob/master/packages/backend-plugin-api/src/services/definitions/coreServices.ts) out of the box which includes access to configuration, logging, URL Readers, databases and more. -All core services are available through the `coreServices` namespace in the `@backstage/backend-plugin-api` package. +All core services are available through the `coreServices` namespace in the `@backstage/backend-plugin-api` package: ```ts import { coreServices } from '@backstage/backend-plugin-api'; ``` -## HTTP Router Service - -One of the most common services is the HTTP router service which is used to expose HTTP endpoints for other plugins to consume. - -### Using the service - -The following example shows how to register a HTTP router for the `example` plugin. -This single route will be available at the `/api/example/hello` path. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { Router } from 'express'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { http: coreServices.httpRouter }, - async init({ http }) { - const router = Router(); - router.get('/hello', (_req, res) => { - res.status(200).json({ hello: 'world' }); - }); - // Registers the router at the /api/example path - http.use(router); - }, - }); - }, -}); -``` - -### Configuring the service - -There's additional configuration that you can optionally pass to setup the `httpRouter` core service. - -- `getPath` - Can be used to generate a path for each plugin. Currently defaults to `/api/${pluginId}` - -You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: - -```ts -import { httpRouterServiceFactory } from '@backstage/backend-app-api'; - -const backend = createBackend(); - -backend.add( - httpRouterServiceFactory({ - getPath: (pluginId: string) => `/plugins/${pluginId}`, - }), -); -``` - -## Root HTTP Router - -The root HTTP router is a service that allows you to register routes on the root of the backend service. This is useful for things like health checks, or other routes that you want to expose on the root of the backend service. It is used as the base router that backs the `httpRouter` service. Most likely you won't need to use this service directly, but rather use the `httpRouter` service. - -### Using the service - -The following example shows how to get the root HTTP router service in your `example` backend plugin to register a health check route. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { Router } from 'express'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - rootHttpRouter: coreServices.rootHttpRouter, - }, - async init({ rootHttpRouter }) { - const router = Router(); - router.get('/health', (request, response) => { - response.send('OK'); - }); - - rootHttpRouter.use(router); - }, - }); - }, -}); -``` - -### Configuring the service - -There's additional options that you can pass to configure the root HTTP Router service. These options are passed when you call `createBackend`. - -- `indexPath` - optional path to forward all unmatched requests to. Defaults to `/api/app` which is the `app-backend` plugin responsible for serving the frontend application through the backend. - -- `configure` - this is an optional function that you can use to configure the `express` instance. This is useful if you want to add your own middleware to the root router, such as logging, or other things that you want to do before the request is handled by the backend. It's also useful to override the order in which middleware is applied. - -You can configure the root HTTP Router service by passing the options to the `createBackend` function. - -```ts -import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api'; - -const backend = createBackend(); - -backend.add( - rootHttpRouterServiceFactory({ - configure: ({ app, middleware, routes, config, logger, lifecycle }) => { - // the built in middleware is provided through an option in the configure function - app.use(middleware.helmet()); - app.use(middleware.cors()); - app.use(middleware.compression()); - - // you can add you your own middleware in here - app.use(custom.logging()); - - // here the routes that are registered by other plugins - app.use(routes); - - // some other middleware that comes after the other routes - app.use(middleware.notFound()); - app.use(middleware.error()); - }, - }), -); -``` - -## Root Config - -This service allows you to read configuration values out of your `app-config` YAML files. - -### Using the service - -The following example shows how you can use the default config service to be able to get a config value, and then log it to the console. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - log: coreServices.logger, - config: coreServices.rootConfig, - }, - async init({ log, config }) { - const baseUrl = config.getString('backend.baseUrl'); - log.warn(`The backend is running at ${baseUrl}`); - }, - }); - }, -}); -``` - -### Configuring the service - -There's additional configuration that you can optionally pass to setup the `config` core service. - -- `argv` - Override the arguments that are passed to the config loader, instead of using `process.argv` -- `remote` - Configure remote configuration loading - -You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: - -```ts -import { rootConfigServiceFactory } from '@backstage/backend-app-api'; - -const backend = createBackend(); - -backend.add( - rootConfigServiceFactory({ - argv: [ - '--config', - '/backstage/app-config.development.yaml', - '--config', - '/backstage/app-config.yaml', - ], - remote: { reloadIntervalSeconds: 60 }, - }), -); -``` - -## Logging - -This service allows plugins to output logging information. There are actually two logger services: a root logger, and a plugin logger which is bound to individual plugins, so that you will get nice messages with the plugin ID referenced in the log lines. - -### Using the service - -The following example shows how to get the logger in your `example` backend plugin and create a warning message that will be printed nicely to the console. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - log: coreServices.logger, - }, - async init({ log }) { - log.warn("Here's a nice log line that's a warning!"); - }, - }); - }, -}); -``` - -### Root Logger - -The root logger is the logger that is used by other root services. It's where the implementation lies for creating child loggers around the backstage ecosystem including child loggers for plugins with the correct metadata and annotations. - -If you want to override the implementation for logging across all of the backend, this is the service that you should override. - -### Configuring the service - -The following example is how you can override the root logger service to add additional metadata to all log lines. - -```ts -import { coreServices } from '@backstage/backend-plugin-api'; -import { WinstonLogger } from '@backstage/backend-app-api'; - -const backend = createBackend(); - -backend.add( - createServiceFactory({ - service: coreServices.rootLogger, - deps: { - config: coreServices.rootConfig, - }, - async factory({ config }) { - const logger = WinstonLogger.create({ - meta: { - service: 'backstage', - // here's some additional information that is not part of the - // original implementation - podName: 'myk8spod', - }, - level: process.env.LOG_LEVEL || 'info', - format: - process.env.NODE_ENV === 'production' - ? format.json() - : WinstonLogger.colorFormat(), - transports: [new transports.Console()], - }); - - return logger; - }, - }), -); -``` - -## Cache - -This service lets your plugin interact with a cache. It is bound to your plugin too, so that you will only set and get values in your plugin's private namespace. - -### Using the service - -The following example shows how to get a cache client in your `example` backend plugin and setting and getting values from the cache. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - cache: coreServices.cache, - }, - async init({ cache }) { - const { key, value } = { key: 'test:key', value: 'bob' }; - await cache.set(key, value, { ttl: 1000 }); - - // .. some other stuff. - - await cache.get(key); // 'bob' - }, - }); - }, -}); -``` - -## Database - -This service lets your plugins get a `knex` client hooked up to a database which is configured in your `app-config` YAML files, for your persistence needs. - -If there's no config provided in `backend.database` then you will automatically get a simple in-memory SQLite 3 database for your plugin whose contents will be lost when the service restarts. - -This service is scoped per plugin too, so that table names do not conflict across plugins. - -### Using the service - -The following example shows how to get access to the database service in your `example` backend plugin and getting a client for interacting with the database. It also runs some migrations from a certain directory for your plugin. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { resolvePackagePath } from '@backstage/backend-common'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - database: coreServices.database, - }, - async init({ database }) { - const client = await database.getClient(); - const migrationsDir = resolvePackagePath( - '@internal/my-plugin', - 'migrations', - ); - if (!database.migrations?.skip) { - await client.migrate.latest({ - directory: migrationsDir, - }); - } - }, - }); - }, -}); -``` - -## Discovery - -When building plugins, you might find that you will need to look up another plugin's base URL to be able to communicate with it. This could be for example an HTTP route or some `ws` protocol URL. For this we have a discovery service which can provide both internal and external base URLs for a given a plugin ID. - -### Using the service - -The following example shows how to get the discovery service in your `example` backend plugin and making a request to both the internal and external base URLs for the `derp` plugin. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { fetch } from 'node-fetch'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - discovery: coreServices.discovery, - }, - async init({ discovery }) { - const url = await discovery.getBaseUrl('derp'); // can also use discovery.getExternalBaseUrl to retrieve external URL - const response = await fetch(`${url}/hello`); - }, - }); - }, -}); -``` - -## Identity - -When working with backend plugins, you might find that you will need to interact with the `auth-backend` plugin to both authenticate backstage tokens, and to deconstruct them to get the user's entity ref and/or ownership claims out of them. - -### Using the service - -The following example shows how to get the identity service in your `example` backend plugin and retrieve the user's entity ref and ownership claims for the incoming request. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { Router } from 'express'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - identity: coreServices.identity, - http: coreServices.httpRouter, - }, - async init({ http, identity }) { - const router = Router(); - router.get('/test-me', (request, response) => { - // use the identity service to pull out the header from the request and get the user - const { - identity: { userEntityRef, ownershipEntityRefs }, - } = await identity.getIdentity({ - request, - }); - - // send the decoded and validated things back to the user - response.json({ - userEntityRef, - ownershipEntityRefs, - }); - }); - - http.use(router); - }, - }); - }, -}); -``` - -### Configuring the service - -There's additional configuration that you can optionally pass to setup the `identity` core service. - -- `issuer` - Set an optional issuer for validation of the JWT token -- `algorithms` - `alg` header for validation of the JWT token, defaults to `ES256`. More info on supported algorithms can be found in the [`jose` library documentation](https://github.com/panva/jose) - -You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: - -```ts -import { identityServiceFactory } from '@backstage/backend-app-api'; - -const backend = createBackend(); - -backend.add( - identityServiceFactory({ - issuer: 'backstage', - algorithms: ['ES256', 'RS256'], - }), -); -``` - -## Lifecycle - -This service allows your plugins to register hooks for cleaning up resources as the service is shutting down (e.g. when a pod is being torn down, or when pressing `Ctrl+C` during local development). Other core services also leverage this same mechanism internally to stop themselves cleanly. - -### Using the service - -The following example shows how to get the lifecycle service in your `example` backend plugin to clean up a long running interval when the service is shutting down. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - lifecycle: coreServices.lifecycle, - logger: coreServices.logger, - }, - async init({ lifecycle, logger }) { - // some example work that we want to stop when shutting down - const interval = setInterval(async () => { - await fetch('http://google.com/keepalive').then(r => r.json()); - // do some other stuff. - }, 1000); - - lifecycle.addShutdownHook(() => clearInterval(interval)); - }, - }); - }, -}); -``` - -## Root Lifecycle - -This service is the same as the lifecycle service, but should only be used by the root services. This is also where the implementation for the actual lifecycle hooks are collected and executed, so if you want to override the implementation of how those are processed, you should override this service. - -### Configure the service - -The following example shows how to override the default implementation of the lifecycle service with something that listens on different process events to the original. - -```ts -class MyCustomLifecycleService implements RootLifecycleService { - constructor(private readonly logger: LoggerService) {} - - #isCalled = false; - #shutdownTasks: Array<{ - hook: LifecycleServiceShutdownHook; - options?: LifecycleServiceShutdownOptions; - }> = []; - - addShutdownHook( - hook: LifecycleServiceShutdownHook, - options?: LifecycleServiceShutdownOptions, - ): void { - this.#shutdownTasks.push({ hook, options }); - } - - async shutdown(): Promise<void> { - if (this.#isCalled) { - return; - } - this.#isCalled = true; - - this.logger.info(`Running ${this.#shutdownTasks.length} shutdown tasks...`); - await Promise.all( - this.#shutdownTasks.map(async ({ hook, options }) => { - const logger = options?.logger ?? this.logger; - try { - await hook(); - logger.info(`Shutdown hook succeeded`); - } catch (error) { - logger.error(`Shutdown hook failed, ${error}`); - } - }), - ); - } -} - -const backend = createBackend(); - -backend.add( - createServiceFactory({ - service: coreServices.rootLifecycle, - deps: { - logger: coreServices.rootLogger, - }, - async factory({ logger }) { - return new MyCustomLifecycleService(logger); - }, - }), -); -``` - -## Permissions - -This service allows your plugins to ask [the permissions framework](https://backstage.io/docs/permissions/overview) for authorization of user actions. - -### Using the service - -The following example shows how to get the permissions service in your `example` backend to check to see if the user is allowed to perform a certain action with a custom permission rule. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { Router } from 'express'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - permissions: coreServices.permissions, - http: coreServices.httpRouter, - }, - async init({ permissions, http }) { - const router = Router(); - router.get('/test-me', (request, response) => { - // use the identity service to pull out the token from request headers - const { token } = await identity.getIdentity({ - request, - }); - - // ask the permissions framework what the decision is for the permission - const permissionResponse = await permissions.authorize( - [ - { - permission: myCustomPermission, - }, - ], - { token }, - ); - }); - - http.use(router); - }, - }); - }, -}); -``` - -## Scheduler - -When writing plugins, you sometimes want to have things running on a schedule, or something similar to cron jobs that are distributed through instances that your backend plugin is running on. We supply a task scheduler for this purpose that is scoped per plugin so that you can create these tasks and orchestrate their execution. - -### Using the service - -The following example shows how to get the scheduler service in your `example` backend to issue a scheduled task that runs across your instances at a given interval. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { fetch } from 'node-fetch'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - scheduler: coreServices.scheduler, - }, - async init({ scheduler }) { - await scheduler.scheduleTask({ - frequency: { minutes: 10 }, - timeout: { seconds: 30 }, - id: 'ping-google', - fn: async () => { - await fetch('http://google.com/ping'); - }, - }); - }, - }); - }, -}); -``` - -## URL Readers - -Plugins will require communication with certain integrations that users have configured. Popular integrations are things like Version Control Systems (VSC), such as GitHub, BitBucket GitLab etc. These integrations are configured in the `integrations` section of the `app-config.yaml` file. - -These URL readers are basically wrappers with authentication for files and folders that could be stored in these VCS repositories. - -### Using the service - -The following example shows how to get the URL Reader service in your `example` backend plugin to read a file and a directory from a GitHub repository. - -```ts -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import os from 'os'; - -createBackendPlugin({ - pluginId: 'example', - register(env) { - env.registerInit({ - deps: { - urlReader: coreServices.urlReader, - }, - async init({ urlReader }) { - const buffer = await urlReader - .read('https://github.com/backstage/backstage/blob/master/README.md') - .then(r => r.buffer()); - - const tmpDir = os.tmpdir(); - const directory = await urlReader - .readTree( - 'https://github.com/backstage/backstage/tree/master/packages/backend', - ) - .then(tree => tree.dir({ targetDir: tmpDir })); - }, - }); - }, -}); -``` +## Service Documentation Index + +- [Auth Service](./auth.md) - Token authentication and credentials management. +- [Cache Service](./cache.md) - Key-value store for caching data. +- [Database Service](./database.md) - Database access and management via [knex](https://knexjs.org/). +- [Discovery Service](./discovery.md) - Service discovery for inter-plugin communication. +- [Http Auth Service](./http-auth.md) - Authentication of HTTP requests. +- [Http Router Service](./http-router.md) - HTTP route registration for plugins. +- [Identity Service](./identity.md) - Deprecated user authentication service, use the [Auth Service](./auth.md) instead. +- [Lifecycle Service](./lifecycle.md) - Registration of plugin startup and shutdown lifecycle hooks. +- [Logger Service](./logger.md) - Plugin-level logging. +- [Permissions Service](./permissions.md) - Permission system integration for authorization of user actions. +- [Plugin Metadata Service](./plugin-metadata.md) - Built-in service for accessing metadata about the current plugin. +- [Root Config Service](./root-config.md) - Access to static configuration. +- [Root Http Router Service](./root-http-router.md) - HTTP route registration for root services. +- [Root Lifecycle Service](./root-lifecycle.md) - Registration of backend startup and shutdown lifecycle hooks. +- [Root Logger Service](./root-logger.md) - Root-level logging. +- [Scheduler Service](./scheduler.md) - Scheduling of distributed background tasks. +- [Token Manager Service](./token-manager.md) - Deprecated service authentication service, use the [Auth Service](./auth.md) instead. +- [Url Reader Service](./url-reader.md) - Reading content from external systems. +- [User Info Service](./user-info.md) - Authenticated user information retrieval. diff --git a/docs/backend-system/core-services/auth.md b/docs/backend-system/core-services/auth.md new file mode 100644 index 0000000000..4f1229a9d7 --- /dev/null +++ b/docs/backend-system/core-services/auth.md @@ -0,0 +1,8 @@ +--- +id: auth +title: Auth Service +sidebar_label: Auth +description: Documentation for the Auth service +--- + +TODO diff --git a/docs/backend-system/core-services/cache.md b/docs/backend-system/core-services/cache.md new file mode 100644 index 0000000000..0e26e8e1f5 --- /dev/null +++ b/docs/backend-system/core-services/cache.md @@ -0,0 +1,38 @@ +--- +id: cache +title: Cache Service +sidebar_label: Cache +description: Documentation for the Cache service +--- + +This service lets your plugin interact with a cache. It is bound to your plugin too, so that you will only set and get values in your plugin's private namespace. + +## Using the service + +The following example shows how to get a cache client in your `example` backend plugin and setting and getting values from the cache. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + cache: coreServices.cache, + }, + async init({ cache }) { + const { key, value } = { key: 'test:key', value: 'bob' }; + await cache.set(key, value, { ttl: 1000 }); + + // .. some other stuff. + + await cache.get(key); // 'bob' + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/database.md b/docs/backend-system/core-services/database.md new file mode 100644 index 0000000000..e083f0b44d --- /dev/null +++ b/docs/backend-system/core-services/database.md @@ -0,0 +1,47 @@ +--- +id: database +title: Database Service +sidebar_label: Database +description: Documentation for the Database service +--- + +This service lets your plugins get a `knex` client hooked up to a database which is configured in your `app-config` YAML files, for your persistence needs. + +If there's no config provided in `backend.database` then you will automatically get a simple in-memory SQLite 3 database for your plugin whose contents will be lost when the service restarts. + +This service is scoped per plugin too, so that table names do not conflict across plugins. + +## Using the service + +The following example shows how to get access to the database service in your `example` backend plugin and getting a client for interacting with the database. It also runs some migrations from a certain directory for your plugin. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { resolvePackagePath } from '@backstage/backend-common'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + database: coreServices.database, + }, + async init({ database }) { + const client = await database.getClient(); + const migrationsDir = resolvePackagePath( + '@internal/my-plugin', + 'migrations', + ); + if (!database.migrations?.skip) { + await client.migrate.latest({ + directory: migrationsDir, + }); + } + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/discovery.md b/docs/backend-system/core-services/discovery.md new file mode 100644 index 0000000000..455e398d8b --- /dev/null +++ b/docs/backend-system/core-services/discovery.md @@ -0,0 +1,35 @@ +--- +id: discovery +title: Discovery Service +sidebar_label: Discovery +description: Documentation for the Discovery service +--- + +When building plugins, you might find that you will need to look up another plugin's base URL to be able to communicate with it. This could be for example an HTTP route or some `ws` protocol URL. For this we have a discovery service which can provide both internal and external base URLs for a given a plugin ID. + +## Using the service + +The following example shows how to get the discovery service in your `example` backend plugin and making a request to both the internal and external base URLs for the `derp` plugin. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { fetch } from 'node-fetch'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + discovery: coreServices.discovery, + }, + async init({ discovery }) { + const url = await discovery.getBaseUrl('derp'); // can also use discovery.getExternalBaseUrl to retrieve external URL + const response = await fetch(`${url}/hello`); + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/http-auth.md b/docs/backend-system/core-services/http-auth.md new file mode 100644 index 0000000000..7af30c3251 --- /dev/null +++ b/docs/backend-system/core-services/http-auth.md @@ -0,0 +1,8 @@ +--- +id: http-auth +title: Http Auth Service +sidebar_label: Http Auth +description: Documentation for the Http Auth service +--- + +TODO diff --git a/docs/backend-system/core-services/http-router.md b/docs/backend-system/core-services/http-router.md new file mode 100644 index 0000000000..4dfa7d80e1 --- /dev/null +++ b/docs/backend-system/core-services/http-router.md @@ -0,0 +1,42 @@ +--- +id: http-router +title: Http Router Service +sidebar_label: Http Router +description: Documentation for the Http Router service +--- + +One of the most common services is the HTTP router service which is used to expose HTTP endpoints for other plugins to consume. + +## Using the service + +The following example shows how to register a HTTP router for the `example` plugin. +This single route will be available at the `/api/example/hello` path. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { Router } from 'express'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { http: coreServices.httpRouter }, + async init({ http }) { + const router = Router(); + router.get('/hello', (_req, res) => { + res.status(200).json({ hello: 'world' }); + }); + // Registers the router at the /api/example path + http.use(router); + }, + }); + }, +}); +``` + +## Configuring the service + +This service does not have any configuration options. diff --git a/docs/backend-system/core-services/identity.md b/docs/backend-system/core-services/identity.md new file mode 100644 index 0000000000..eb7d1f4ac7 --- /dev/null +++ b/docs/backend-system/core-services/identity.md @@ -0,0 +1,73 @@ +--- +id: identity +title: Identity Service +sidebar_label: Identity +description: Documentation for the Identity service +--- + +When working with backend plugins, you might find that you will need to interact with the `auth-backend` plugin to both authenticate backstage tokens, and to deconstruct them to get the user's entity ref and/or ownership claims out of them. + +## Using the service + +The following example shows how to get the identity service in your `example` backend plugin and retrieve the user's entity ref and ownership claims for the incoming request. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { Router } from 'express'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + identity: coreServices.identity, + http: coreServices.httpRouter, + }, + async init({ http, identity }) { + const router = Router(); + router.get('/test-me', (request, response) => { + // use the identity service to pull out the header from the request and get the user + const { + identity: { userEntityRef, ownershipEntityRefs }, + } = await identity.getIdentity({ + request, + }); + + // send the decoded and validated things back to the user + response.json({ + userEntityRef, + ownershipEntityRefs, + }); + }); + + http.use(router); + }, + }); + }, +}); +``` + +## Configuring the service + +There's additional configuration that you can optionally pass to setup the `identity` core service. + +- `issuer` - Set an optional issuer for validation of the JWT token +- `algorithms` - `alg` header for validation of the JWT token, defaults to `ES256`. More info on supported algorithms can be found in the [`jose` library documentation](https://github.com/panva/jose) + +You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: + +```ts +import { identityServiceFactory } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + identityServiceFactory({ + issuer: 'backstage', + algorithms: ['ES256', 'RS256'], + }), +); +``` diff --git a/docs/backend-system/core-services/lifecycle.md b/docs/backend-system/core-services/lifecycle.md new file mode 100644 index 0000000000..aa547d6cc9 --- /dev/null +++ b/docs/backend-system/core-services/lifecycle.md @@ -0,0 +1,40 @@ +--- +id: lifecycle +title: Lifecycle Service +sidebar_label: Lifecycle +description: Documentation for the Lifecycle service +--- + +This service allows your plugins to register hooks for cleaning up resources as the service is shutting down (e.g. when a pod is being torn down, or when pressing `Ctrl+C` during local development). Other core services also leverage this same mechanism internally to stop themselves cleanly. + +## Using the service + +The following example shows how to get the lifecycle service in your `example` backend plugin to clean up a long running interval when the service is shutting down. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + lifecycle: coreServices.lifecycle, + logger: coreServices.logger, + }, + async init({ lifecycle, logger }) { + // some example work that we want to stop when shutting down + const interval = setInterval(async () => { + await fetch('http://google.com/keepalive').then(r => r.json()); + // do some other stuff. + }, 1000); + + lifecycle.addShutdownHook(() => clearInterval(interval)); + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/logger.md b/docs/backend-system/core-services/logger.md new file mode 100644 index 0000000000..015d2055d5 --- /dev/null +++ b/docs/backend-system/core-services/logger.md @@ -0,0 +1,77 @@ +--- +id: logger +title: Logger Service +sidebar_label: Logger +description: Documentation for the Logger service +--- + +This service allows plugins to output logging information. There are actually two logger services: a root logger, and a plugin logger which is bound to individual plugins, so that you will get nice messages with the plugin ID referenced in the log lines. + +## Using the service + +The following example shows how to get the logger in your `example` backend plugin and create a warning message that will be printed nicely to the console. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + log: coreServices.logger, + }, + async init({ log }) { + log.warn("Here's a nice log line that's a warning!"); + }, + }); + }, +}); +``` + +## Root Logger + +The root logger is the logger that is used by other root services. It's where the implementation lies for creating child loggers around the backstage ecosystem including child loggers for plugins with the correct metadata and annotations. + +If you want to override the implementation for logging across all of the backend, this is the service that you should override. + +## Configuring the service + +The following example is how you can override the root logger service to add additional metadata to all log lines. + +```ts +import { coreServices } from '@backstage/backend-plugin-api'; +import { WinstonLogger } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + createServiceFactory({ + service: coreServices.rootLogger, + deps: { + config: coreServices.rootConfig, + }, + async factory({ config }) { + const logger = WinstonLogger.create({ + meta: { + service: 'backstage', + // here's some additional information that is not part of the + // original implementation + podName: 'myk8spod', + }, + level: process.env.LOG_LEVEL || 'info', + format: + process.env.NODE_ENV === 'production' + ? format.json() + : WinstonLogger.colorFormat(), + transports: [new transports.Console()], + }); + + return logger; + }, + }), +); +``` diff --git a/docs/backend-system/core-services/permissions.md b/docs/backend-system/core-services/permissions.md new file mode 100644 index 0000000000..d979932c2f --- /dev/null +++ b/docs/backend-system/core-services/permissions.md @@ -0,0 +1,53 @@ +--- +id: permissions +title: Permissions Service +sidebar_label: Permissions +description: Documentation for the Permissions service +--- + +This service allows your plugins to ask [the permissions framework](https://backstage.io/docs/permissions/overview) for authorization of user actions. + +## Using the service + +The following example shows how to get the permissions service in your `example` backend to check to see if the user is allowed to perform a certain action with a custom permission rule. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { Router } from 'express'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + permissions: coreServices.permissions, + http: coreServices.httpRouter, + }, + async init({ permissions, http }) { + const router = Router(); + router.get('/test-me', (request, response) => { + // use the identity service to pull out the token from request headers + const { token } = await identity.getIdentity({ + request, + }); + + // ask the permissions framework what the decision is for the permission + const permissionResponse = await permissions.authorize( + [ + { + permission: myCustomPermission, + }, + ], + { token }, + ); + }); + + http.use(router); + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/plugin-metadata.md b/docs/backend-system/core-services/plugin-metadata.md new file mode 100644 index 0000000000..f045ed7f19 --- /dev/null +++ b/docs/backend-system/core-services/plugin-metadata.md @@ -0,0 +1,8 @@ +--- +id: plugin-metadata +title: Plugin Metadata Service +sidebar_label: Plugin Metadata +description: Documentation for the Plugin Metadata service +--- + +TODO diff --git a/docs/backend-system/core-services/root-config.md b/docs/backend-system/core-services/root-config.md new file mode 100644 index 0000000000..7cdc10f38c --- /dev/null +++ b/docs/backend-system/core-services/root-config.md @@ -0,0 +1,62 @@ +--- +id: root-config +title: Root Config Service +sidebar_label: Root Config +description: Documentation for the Root Config service +--- + +This service allows you to read configuration values out of your `app-config` YAML files. + +## Using the service + +The following example shows how you can use the default config service to be able to get a config value, and then log it to the console. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + log: coreServices.logger, + config: coreServices.rootConfig, + }, + async init({ log, config }) { + const baseUrl = config.getString('backend.baseUrl'); + log.warn(`The backend is running at ${baseUrl}`); + }, + }); + }, +}); +``` + +## Configuring the service + +There's additional configuration that you can optionally pass to setup the `config` core service. + +- `argv` - Override the arguments that are passed to the config loader, instead of using `process.argv` +- `remote` - Configure remote configuration loading + +You can configure these additional options by adding an override for the core service when calling `createBackend` like follows: + +```ts +import { rootConfigServiceFactory } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + rootConfigServiceFactory({ + argv: [ + '--config', + '/backstage/app-config.development.yaml', + '--config', + '/backstage/app-config.yaml', + ], + remote: { reloadIntervalSeconds: 60 }, + }), +); +``` diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md new file mode 100644 index 0000000000..b3522e1752 --- /dev/null +++ b/docs/backend-system/core-services/root-http-router.md @@ -0,0 +1,103 @@ +--- +id: root-http-router +title: Root Http Router Service +sidebar_label: Root Http Router +description: Documentation for the Root Http Router service +--- + +The root HTTP router is a service that allows you to register routes on the root of the backend service. This is useful for things like health checks, or other routes that you want to expose on the root of the backend service. It is used as the base router that backs the `httpRouter` service and starts the Node.js HTTP server on backend startup. Most likely you won't need to use this service directly, but rather use the `httpRouter` service. + +The `/api/:pluginId/` path prefix is reserved for use by plugins to register their own routes via the [HttpRouter](./http-router.md) service. + +## Using the service + +The following example shows how to get the root HTTP router service in your `example` backend plugin to register a health check route. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { Router } from 'express'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + rootHttpRouter: coreServices.rootHttpRouter, + }, + async init({ rootHttpRouter }) { + const router = Router(); + router.get('/readiness', (request, response) => { + response.send('OK'); + }); + + rootHttpRouter.use('/health', router); + }, + }); + }, +}); +``` + +## Configuring the service + +There's additional options that you can pass to configure the root HTTP Router service. These options are passed when you call `createBackend`. + +- `indexPath` - optional path to forward all unmatched requests to. Defaults to `/api/app` which is the `app-backend` plugin responsible for serving the frontend application through the backend. + +- `configure` - this is an optional function that you can use to configure the `express` instance. This is useful if you want to add your own middleware to the root router, such as logging, or other things that you want to do before the request is handled by the backend. It's also useful to override the order in which middleware is applied. + +You can configure the root HTTP Router service by passing the options to the `createBackend` function. + +```ts +import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + rootHttpRouterServiceFactory({ + configure: ({ app, middleware, routes, config, logger, lifecycle }) => { + // the built in middleware is provided through an option in the configure function + app.use(middleware.helmet()); + app.use(middleware.cors()); + app.use(middleware.compression()); + + // you can add you your own middleware in here + app.use(custom.logging()); + + // here the routes that are registered by other plugins + app.use(routes); + + // some other middleware that comes after the other routes + app.use(middleware.notFound()); + app.use(middleware.error()); + }, + }), +); +``` + +Note that requests towards `/api/*` will never be handled by the `routes` handler unless a matching plugin exists, and will instead typically falling through to the `middleware.notFound()` handler. That is the case regardless of whether there is a configured `indexPath` or not. + +The root HTTP Router service also allows for configuration of the underlying Node.js HTTP server object. This is useful for modifying settings on the HTTP server itself, such as server [timeout](https://nodejs.org/api/http.html#servertimeout), [keepAliveTimeout](https://nodejs.org/api/http.html#serverkeepalivetimeout), and [headersTimeout](https://nodejs.org/api/http.html#serverheaderstimeout). + +A `applyDefaults` helper is also made available to use the default app/router configuration while still enabling custom server configuration + +```ts +import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api'; + +const backend = createBackend(); + +backend.add( + rootHttpRouterServiceFactory({ + configure: ({ server, applyDefaults }) => { + // apply default app/router configuration + applyDefaults(); + + // customize the Node.js HTTP Server timeouts + server.keepAliveTimeout = 65 * 1000; + server.headersTimeout = 66 * 1000; + }, + }), +); +``` diff --git a/docs/backend-system/core-services/root-lifecycle.md b/docs/backend-system/core-services/root-lifecycle.md new file mode 100644 index 0000000000..be981e9bd8 --- /dev/null +++ b/docs/backend-system/core-services/root-lifecycle.md @@ -0,0 +1,65 @@ +--- +id: root-lifecycle +title: Root Lifecycle Service +sidebar_label: Root Lifecycle +description: Documentation for the Root Lifecycle service +--- + +This service is the same as the lifecycle service, but should only be used by the root services. This is also where the implementation for the actual lifecycle hooks are collected and executed, so if you want to override the implementation of how those are processed, you should override this service. + +## Configure the service + +The following example shows how to override the default implementation of the lifecycle service with something that listens on different process events to the original. + +```ts +class MyCustomLifecycleService implements RootLifecycleService { + constructor(private readonly logger: LoggerService) {} + + #isCalled = false; + #shutdownTasks: Array<{ + hook: LifecycleServiceShutdownHook; + options?: LifecycleServiceShutdownOptions; + }> = []; + + addShutdownHook( + hook: LifecycleServiceShutdownHook, + options?: LifecycleServiceShutdownOptions, + ): void { + this.#shutdownTasks.push({ hook, options }); + } + + async shutdown(): Promise<void> { + if (this.#isCalled) { + return; + } + this.#isCalled = true; + + this.logger.info(`Running ${this.#shutdownTasks.length} shutdown tasks...`); + await Promise.all( + this.#shutdownTasks.map(async ({ hook, options }) => { + const logger = options?.logger ?? this.logger; + try { + await hook(); + logger.info(`Shutdown hook succeeded`); + } catch (error) { + logger.error(`Shutdown hook failed, ${error}`); + } + }), + ); + } +} + +const backend = createBackend(); + +backend.add( + createServiceFactory({ + service: coreServices.rootLifecycle, + deps: { + logger: coreServices.rootLogger, + }, + async factory({ logger }) { + return new MyCustomLifecycleService(logger); + }, + }), +); +``` diff --git a/docs/backend-system/core-services/root-logger.md b/docs/backend-system/core-services/root-logger.md new file mode 100644 index 0000000000..09b7929efe --- /dev/null +++ b/docs/backend-system/core-services/root-logger.md @@ -0,0 +1,8 @@ +--- +id: root-logger +title: Root Logger Service +sidebar_label: Root Logger +description: Documentation for the Root Logger service +--- + +TODO diff --git a/docs/backend-system/core-services/scheduler.md b/docs/backend-system/core-services/scheduler.md new file mode 100644 index 0000000000..e4c67a1199 --- /dev/null +++ b/docs/backend-system/core-services/scheduler.md @@ -0,0 +1,41 @@ +--- +id: scheduler +title: Scheduler Service +sidebar_label: Scheduler +description: Documentation for the Scheduler service +--- + +When writing plugins, you sometimes want to have things running on a schedule, or something similar to cron jobs that are distributed through instances that your backend plugin is running on. We supply a task scheduler for this purpose that is scoped per plugin so that you can create these tasks and orchestrate their execution. + +## Using the service + +The following example shows how to get the scheduler service in your `example` backend to issue a scheduled task that runs across your instances at a given interval. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { fetch } from 'node-fetch'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + scheduler: coreServices.scheduler, + }, + async init({ scheduler }) { + await scheduler.scheduleTask({ + frequency: { minutes: 10 }, + timeout: { seconds: 30 }, + id: 'ping-google', + fn: async () => { + await fetch('http://google.com/ping'); + }, + }); + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/token-manager.md b/docs/backend-system/core-services/token-manager.md new file mode 100644 index 0000000000..b62499462f --- /dev/null +++ b/docs/backend-system/core-services/token-manager.md @@ -0,0 +1,8 @@ +--- +id: token-manager +title: Token Manager Service +sidebar_label: Token Manager +description: Documentation for the Token Manager service +--- + +TODO diff --git a/docs/backend-system/core-services/url-reader.md b/docs/backend-system/core-services/url-reader.md new file mode 100644 index 0000000000..b9616a029e --- /dev/null +++ b/docs/backend-system/core-services/url-reader.md @@ -0,0 +1,47 @@ +--- +id: url-reader +title: Url Reader Service +sidebar_label: Url Reader +description: Documentation for the Url Reader service +--- + +# URL Readers + +Plugins will require communication with certain integrations that users have configured. Popular integrations are things like Version Control Systems (VSC), such as GitHub, BitBucket GitLab etc. These integrations are configured in the `integrations` section of the `app-config.yaml` file. + +These URL readers are basically wrappers with authentication for files and folders that could be stored in these VCS repositories. + +## Using the service + +The following example shows how to get the URL Reader service in your `example` backend plugin to read a file and a directory from a GitHub repository. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import os from 'os'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + urlReader: coreServices.urlReader, + }, + async init({ urlReader }) { + const buffer = await urlReader + .read('https://github.com/backstage/backstage/blob/master/README.md') + .then(r => r.buffer()); + + const tmpDir = os.tmpdir(); + const directory = await urlReader + .readTree( + 'https://github.com/backstage/backstage/tree/master/packages/backend', + ) + .then(tree => tree.dir({ targetDir: tmpDir })); + }, + }); + }, +}); +``` diff --git a/docs/backend-system/core-services/user-info.md b/docs/backend-system/core-services/user-info.md new file mode 100644 index 0000000000..5ca717ddd5 --- /dev/null +++ b/docs/backend-system/core-services/user-info.md @@ -0,0 +1,8 @@ +--- +id: user-info +title: User Info Service +sidebar_label: User Info +description: Documentation for the User Info service +--- + +TODO diff --git a/docs/conf/defining.md b/docs/conf/defining.md index 9e13442f7b..1c2fb8d273 100644 --- a/docs/conf/defining.md +++ b/docs/conf/defining.md @@ -84,13 +84,16 @@ receive schema validation and autocompletion. For example: ## Visibility The `https://backstage.io/schema/config-v1` meta schema is a superset of JSON -Schema Draft 07. The single addition is a custom `visibility` keyword, which is -used to indicate whether the given config value should be visible in the -frontend or not. The possible values are `frontend`, `backend`, and `secret`, -where `backend` is the default. A visibility of `secret` has the same scope at -runtime, but it will be treated with more care in certain contexts, and defining -both `frontend` and `secret` for the same value in two different schemas will -result in an error during schema merging. +Schema Draft 07. The only additions are the custom `visibility` and +`deepVisibility` keywords, which are used to indicate whether the given config +value should be visible in the frontend or not. The `visibility` marker applies +only to the field it's on, while the `deepVisibility` marker applies to the +field it's on and downwards in the hierarchy as well. The possible values are +`frontend`, `backend`, and `secret`, where `backend` is the default. A +visibility of `secret` has the same scope at runtime, but it will be treated +with more care in certain contexts, and defining both `frontend` and `secret` +for the same value in two different schemas will result in an error during +schema merging. The visibility only applies to the direct parent of where the keyword is placed in the schema. For example, if you set the visibility to `frontend` for a subset @@ -105,17 +108,38 @@ declare the visibility of a leaf node of `type: "string"`. | `backend` | (Default) Only in backend | | `secret` | Only in backend and may be excluded from logs for security reasons | -You can set visibility with an `@visibility` comment in the `Config` Typescript -interface. +You can set visibility with a `@visibility` or `@deepVisibility` comment in the +`Config` Typescript interface. ```ts export interface Config { app: { /** * Frontend root URL + * NOTE: Visibility applies to only this field * @visibility frontend */ baseUrl: string; + + /** + * Some custom complex type + * NOTE: Visibility applies recursively downward + * This is particularly useful for complex types like durations + * @deepVisibility frontend + */ + customSchedule: HumanDuration; + }; + + backend: { + /** + * Some custom credentials type + * NOTE: Visibility applies recursively downward, and this would NOT have + * been safe if the regular visibility keyword had been used + * @deepVisibility secret + */ + customCredentials: { + password: string; + }; }; } ``` diff --git a/docs/conf/reading.md b/docs/conf/reading.md index 976a418905..5f7218479a 100644 --- a/docs/conf/reading.md +++ b/docs/conf/reading.md @@ -141,6 +141,37 @@ from `@backstage/core-plugin-api`. ## Accessing ConfigApi in Backend Plugins -In backend plugins the configuration is passed in via options from the main +### Old Backend System + +In the old backend system plugins, the configuration is passed in via options from the main backend package. See for example [packages/backend/src/plugins/auth.ts](https://github.com/backstage/backstage/blob/244eef851f5aa19f91c7c9b5c12d5df95cf482ca/packages/backend/src/plugins/auth.ts#L23). + +### New Backend System + +In the new backend system, plugins are able to directly access config through dependencies. You can access config like so, + +```ts title="plugins/your-plugin-backend/src/plugin.ts" +export const yourPlugin = createBackendPlugin({ + pluginId: 'yourPlugin', + register(env) { + env.registerInit({ + deps: { + httpRouter: coreServices.httpRouter, + logger: coreServices.logger, + // highlight-next-line + config: coreServices.rootConfig, + }, + async init({ + httpRouter, + logger, + // highlight-next-line + config, + }) { + // highlight-next-line + console.log(config.getOptionalString('backend.test.property')); + }, + }); + }, +}); +``` diff --git a/docs/conf/writing.md b/docs/conf/writing.md index e0eb72f828..6e827c075e 100644 --- a/docs/conf/writing.md +++ b/docs/conf/writing.md @@ -101,6 +101,9 @@ All loaded configuration files are merged together using the following rules: contents. - Objects are merged together deeply, meaning that if any of the included configs contain a value for a given path, it will be found. +- A `null` value in a config file will be treated as an explicit absence of + configuration. This means that the reading will not fall back to a lower priority + config, but it will still be treated as if the configuration was not present. The priority of the configurations is determined by the following rules, in order: @@ -196,6 +199,18 @@ configuration value will evaluate to `undefined`. The substitution syntax can be escaped using `$${...}`, which will be resolved as `${...}`. +Parameter substitution syntax (e.g. `${MY_VAR:-default-value}`) is also +supported to provide a default or fallback value for a given environment +variable if it is unset, or is declared but has no value. For example: + +```yaml +app: + baseUrl: https://${HOST:-localhost:3000} +``` + +In the above example, when `HOST` is unset or has no value, it will be +substituted with `localhost:3000`. + ## Combining Includes and Environment Variable Substitution The Includes and Environment Variable Substitutions can be combined to do diff --git a/docs/getting-started/getting-involved.md b/docs/contribute/getting-involved.md similarity index 90% rename from docs/getting-started/getting-involved.md rename to docs/contribute/getting-involved.md index 7c0be46273..c11e870752 100644 --- a/docs/getting-started/getting-involved.md +++ b/docs/contribute/getting-involved.md @@ -17,15 +17,15 @@ Look through the GitHub issues for [bugs](https://github.com/backstage/backstage ### Build a plugin -The value of Backstage grows with every new plugin that gets added. Wouldn't it be fantastic if there was a plugin for every infrastructure project out there? We think so. And we would love your help. +The value of Backstage grows with every new plugin that gets added. Wouldn't it be fantastic if there was a plugin for every infrastructure project out there? We think so. And we would love your help. Head over to [the community plugins repo](https://github.com/backstage/community-plugins) and get started! A great reference example of a plugin can be found on [our blog](https://backstage.io/blog/2020/04/06/lighthouse-plugin) (thanks [@fastfrwrd](https://github.com/fastfrwrd)!) -What kind of plugins should/could be created? Some inspiration from the 120+ plugins that we have developed inside Spotify can be found [here](https://backstage.io/demos), but we will keep a running list of suggestions labeled with [[plugin]](https://github.com/backstage/backstage/labels/plugin). +What kind of plugins should/could be created? Some inspiration from the 120+ plugins that we have developed inside Spotify can be found [here](https://backstage.io/demos), but we will keep a running list of suggestions labeled with [[plugin]](https://github.com/backstage/community-plugins/labels/plugin) in our [community plugins repo](https://github.com/backstage/community-plugins). ### Suggesting a plugin -If you start developing a plugin that you aim to release as open source, we suggest that you create a [new Issue](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME). This helps the community know what plugins are in development. +If you start developing a plugin that you aim to release as open source, we suggest that you create a [new Issue](https://github.com/backstage/community-plugins/issues/new/choose) in the community plugins repo. This helps the community know what plugins are in development. You can also use this process if you have an idea for a good plugin but you hope that someone else will pick up the work. diff --git a/docs/contribute/index.md b/docs/contribute/index.md new file mode 100644 index 0000000000..34ed1561cb --- /dev/null +++ b/docs/contribute/index.md @@ -0,0 +1,14 @@ +--- +id: index +title: Contributors +# prettier-ignore +description: Documentation on how to get set up for doing development on the Backstage repository +--- + +Our vision for Backstage is for it to become the trusted standard toolbox (read: UX layer) for the open source infrastructure landscape. Think of it like Kubernetes for developer experience. We realize this is an ambitious goal. We can’t do it alone. + +Therefore we want to create a strong community of contributors -- all working together to create the kind of delightful experience that our developers deserve. + +Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. ❤️ + +To get you started, we've put together a [Contributors Guide in the Backstage GitHub repo](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) that has all the information you need. diff --git a/docs/getting-started/project-structure.md b/docs/contribute/project-structure.md similarity index 100% rename from docs/getting-started/project-structure.md rename to docs/contribute/project-structure.md diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 675a8de947..791882224d 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -16,7 +16,7 @@ are stateless, so for a production deployment you will want to set up and connect to an external PostgreSQL instance where the backend plugins can store their state, rather than using SQLite. -This section assumes that an [app](https://backstage.io/docs/getting-started/create-an-app) +This section assumes that an [app](https://backstage.io/docs/getting-started/) has already been created with `@backstage/create-app`, in which the frontend is bundled and served from the backend. This is done using the `@backstage/plugin-app-backend` plugin, which also injects the frontend @@ -338,3 +338,15 @@ Here's an example of these flags in use: ```sh docker image build . -f packages/backend/Dockerfile --tag backstage --progress=plain --no-cache ``` + +## Community Contributed Dockerfile Alternatives + +The `Dockerfile` mentioned above located in `packages/backend` is maintained by the maintainers of Backstage, however there are also community contributed Dockerfile alternatives located in `contrib/docker`. The `Dockerfile`s in `contrib/docker` are not maintained by the maintainers of Backstage and are not necessarily updated when the `Dockerfile` located in `packages/backend` is updated. + +### Minimal Hardened Image + +A contributed `Dockerfile` exists within the directory of `contrib/docker/minimal-harded-image` which uses the [`wolfi-base`](https://github.com/wolfi-dev) image to reduce vulnerabilities. When this was contributed, this alternative `Dockerfile` reduced 98.2% of vulnerabilities in the built Backstage docker image when compared with the image built from `packages/backend/Dockerfile`. + +To reduce maintenance, the digest of the image has been removed from the `contrib/docker/minimal-harded-image/Dockerfile` file. A complete example with the digest would be `cgr.dev/chainguard/wolfi-base:latest@sha256:3d6dece13cdb5546cd03b20e14f9af354bc1a56ab5a7b47dca3e6c1557211fcf` and it is suggested to update the `FROM` line in the `Dockerfile` to use a digest. Please do a docker pull on the image to get the latest digest. Using the digest allows tools such as Dependabot or Renovate to know exactly which image digest is being utilized and allows for Pull Requests to be triggered when a new digest is available. + +It is suggested to setup Dependabot/Renovate or a similar tool to ensure the image is kept up to date so that vulnerability fixes that have been addressed are pulled in frequently. diff --git a/docs/deployment/k8s.md b/docs/deployment/k8s.md index 479d99510b..00bf7464e3 100644 --- a/docs/deployment/k8s.md +++ b/docs/deployment/k8s.md @@ -209,6 +209,7 @@ spec: volumeMounts: - mountPath: /var/lib/postgresql/data name: postgresdb + subPath: data volumes: - name: postgresdb persistentVolumeClaim: diff --git a/docs/deployment/koyeb.md b/docs/deployment/koyeb.md index 9ff87350be..3e30881752 100644 --- a/docs/deployment/koyeb.md +++ b/docs/deployment/koyeb.md @@ -26,7 +26,7 @@ backend: listen: # The $PORT environment variable is a feature of Koyeb # https://www.koyeb.com/docs/apps/services - port: ${PORT] + port: ${PORT} ``` ## Push and deploy Backstage to Koyeb diff --git a/docs/faq/product.md b/docs/faq/product.md index 9d2a32f33e..79465cf53d 100644 --- a/docs/faq/product.md +++ b/docs/faq/product.md @@ -6,7 +6,7 @@ description: Questions related to product and design. ### Can we call Backstage something different? So that it fits our company better? -Yes, Backstage is just a platform for building your own developer portal. We +Yes, Backstage is just a framework for building your own developer portal. We happen to call our internal version Backstage, as well, as a reference to our music roots. You can call your version whatever suits your team, company, or brand. diff --git a/docs/faq/technical.md b/docs/faq/technical.md index 55bb1af615..ffd99dadcd 100644 --- a/docs/faq/technical.md +++ b/docs/faq/technical.md @@ -47,7 +47,7 @@ gets a consistent UX, no matter what tool or service is being accessed on the other side. Each plugin is treated as a self-contained web app and can include almost any -type of content. Plugins all use a common set of platform APIs and reusable UI +type of content. Plugins all use a common set of framework APIs and reusable UI components. Plugins can fetch data either from the backend or an API exposed through the proxy. @@ -100,10 +100,10 @@ You can browse and search for all available plugins in the [Plugin Directory](https://backstage.io/plugins). If you can't find it in the directory, before you write a plugin -[search the plugin issues](https://github.com/backstage/backstage/issues?q=is%3Aissue+label%3Aplugin+) +[search the plugin issues on the community plugins repo](https://github.com/backstage/community-plugins/issues?q=is%3Aissue+is%3Aopen+label%3Aplugin) to see if is in the works. If no one's thought of it yet, great! Open a new issue as -[a plugin suggestion](https://github.com/backstage/backstage/issues/new/choose) +[a plugin suggestion](https://github.com/backstage/community-plugins/issues/new/choose) and describe what your plugin will do. This will help coordinate our contributors' efforts and avoid duplicating existing functionality. @@ -115,7 +115,7 @@ where you write documentation using the same workflow as you write your code. This makes it easier to create, find, and update documentation. [TechDocs is now open source.](https://backstage.io/docs/features/techdocs/) (See also: -"[Will Spotify's internal plugins be open sourced, too?](#will-spotifys-internal-plugins-be-open-sourced-too)" +"[Will Spotify's internal plugins be open sourced, too?](https://backstage.io/docs/faq/product#will-spotifys-internal-plugins-be-open-sourced-too)" above) ### Are you planning to have plugins baked into the repo? Or should they be developed in separate repos? @@ -179,7 +179,7 @@ No. Backstage does not collect any telemetry from any third party using the platform. Spotify, and the open source community, do have access to [GitHub Insights](https://github.com/features/insights), which contains information such as contributors, commits, traffic, and dependencies. Backstage -is an open platform, but you are in control of your own data. You control who +is an open source framework, but you are in control of your own data. You control who has access to any data you provide to your version of Backstage and who that data is shared with. @@ -195,10 +195,9 @@ ambition will be to keep Backstage modular. ### How can I get involved? Jump right in! Come help us fix some of the -[early bugs and good first issues](https://github.com/backstage/backstage/contribute) -or reach [a new milestone](https://github.com/backstage/backstage/milestones). -Or write an open source plugin for Backstage, like this -[Lighthouse plugin](https://github.com/backstage/backstage/tree/master/plugins/lighthouse). +[early bugs and good first issues](https://github.com/backstage/backstage/contribute). +Or write an open source plugin for Backstage in our +[community plugins repository](https://github.com/backstage/community-plugins). See all the ways you can [contribute here](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md). We'd love to have you as part of the community. diff --git a/docs/features/kubernetes/authenticationstrategy.md b/docs/features/kubernetes/authenticationstrategy.md new file mode 100644 index 0000000000..a7d093248a --- /dev/null +++ b/docs/features/kubernetes/authenticationstrategy.md @@ -0,0 +1,318 @@ +--- +id: authentication-strategies +title: Kubernetes Authentication Strategies +sidebar_label: Authentication Strategies +description: Authentication Strategies in Kubernetes plugin +--- + +# Kubernetes Auth Strategies + +A Kubernetes Auth Strategy specifies the authentication steps executed on the **server side** to authenticate against a Kubernetes cluster, +it also defines what authentication metadata about a Kubernetes cluster is returned to the front-end in case a +**client side auth provider** requires it. + +## Context + +Backstage includes by default some [Kubernetes Auth Providers](./authentication.md) to ease the authentication proccess to +kubernetes clusters, it includes: + +- `Server Side Providers` like `localKubectlProxy` or `serviceAccount` where the same set + of kubernetes permissions are shared and granted among the Backstage users and plugins. +- `Client Side Providers` like `aks` or `oidc` where the user is authenticated with the cluster, getting only the + kubernetes permissions granted to that specific user. + +Although there are `Server Side Providers` and `Client Side Providers`, authenticating with a cluster requires code on both sides. Perhaps one of them does +most of the job, but in general not all steps to authenticate against a Kubernetes cluster are always executed exclusively on the server side or client side. +A Kubernetes authentication flow could require splitting the authentication process among steps on the client side **and** steps on the server side. + +## AuthenticationStrategy interface + +The [`AuthenticationStrategy`][2] interface defines the steps executed on the **server side** to authenticate against a Kubernetes cluster. It is similar to the [`KubernetesAuthProvider`](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-react/src/kubernetes-auth-provider/types.ts#L21) interface, which defines corresponding steps on the **client side**. + +```ts title="plugins/kubernetes-node/src/types/types.ts" +export interface AuthenticationStrategy { + getCredential( + clusterDetails: ClusterDetails, + authConfig: KubernetesRequestAuth, + ): Promise<KubernetesCredential>; + + presentAuthMetadata(authMetadata: AuthMetadata): AuthMetadata; + + validateCluster(authMetadata: AuthMetadata): Error[]; +} +``` + +The `AuthenticationStrategy` interface defines the following signature: + +- `getCredential`: Executes the steps require on the server side to authenticate against a Kubernetes Cluster. It receives the cluster info on the `clusterDetails` parameter and the authentication data provided from the Client Side on the `authConfig` parameter. +- `presentAuthMetadata`: A Kubernetes cluster configuration could include extra metadata specific to a given authentication flow (like [AWS clusters](authentication.md#aws) do). The `presentAuthMetadata` method receives that metadata and filters/adds information that could be required by the front-end in a client side authentication process. The front-end gets this info via the [`/clusters` endpoint](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts#L379). +- `validateCluster`: Allows strategies to reject clusters if they have invalid metadata. Currently this method only gets invoked when [reading](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/cluster-locator/ConfigClusterLocator.ts#L96) clusters from the app-config. + +### KubernetesCredential type + +Something to highlight is that the `getCredential` method on an `AuthenticationStrategy` will return a [`KubernetesCredential`](https://github.com/backstage/backstage/blob/0226d424f5a3104239eb9e1eaa9f0cbf29cc1f1c/plugins/kubernetes-node/src/types/types.ts#L140) object representing a single method of authenticating with a Kubernetes cluster. This value can be: + +- A bearer token +- A x509 client certificate and key +- Anonymous authentication + +```ts title="plugins/kubernetes-node/src/types/types.ts" +export type KubernetesCredential = + | { type: 'bearer token'; token: string } + | { type: 'x509 client certificate'; cert: string; key: string } + | { type: 'anonymous' }; +``` + +## AuthenticationStrategies examples + +### AksStrategy + +Some kubernetes Authentication Strategies are pretty simple, since the Authentication process was executed on the client side by the `KubernetesAuthProvider`, +So Authentication Strategies like [`AksStrategy`](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/auth/AksStrategy.ts#L28) or [`GoogleStrategy`](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/auth/GoogleStrategy.ts#L29C14-L29C28) only map the info that the corresponding `KubernetesAuthProvider` returned on the client side. + +```ts title="plugins/kubernetes-backend/src/auth/AksStrategy.ts" +export class AksStrategy implements AuthenticationStrategy { + public async getCredential( + _: ClusterDetails, + requestAuth: KubernetesRequestAuth, + ): Promise<KubernetesCredential> { + const token = requestAuth.aks; + return token + ? { type: 'bearer token', token: token as string } + : { type: 'anonymous' }; + } + + public validateCluster(): Error[] { + return []; + } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } +} +``` + +The `AksStrategy` is pretty simple, it is only mapping the token that [`AksKubernetesAuthProvider.ts`](https://github.com/backstage/backstage/blob/f0ffd38136163edd75ae340e5653cf6b349dcbc1/plugins/kubernetes-react/src/kubernetes-auth-provider/AksKubernetesAuthProvider.ts#L21) was able to get in the Client Side authentication flow. + +### AwsIamStrategy + +Another AuthenticationStrategy is [`AwsIamStrategy`][3], it is more complex than `AksStrategy`, since it consumes some AWS APIs to get a kubernetes token. + +```ts title="plugins/kubernetes-backend/src/auth/AwsIamStrategy.ts" +export class AwsIamStrategy implements AuthenticationStrategy { + // ... code ... + + public async getCredential( + clusterDetails: ClusterDetails, + ): Promise<KubernetesCredential> { + return { + type: 'bearer token', + token: await this.getBearerToken( + clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_CLUSTER_ID] ?? + clusterDetails.name, + clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE], + clusterDetails.authMetadata[ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID], + ), + }; + } + + private async getBearerToken( + clusterId: string, + assumeRole?: string, + externalId?: string, + ): Promise<string> { + // ... code ... + + const request = await signer.presign( + { + headers: { + host: `sts.${region}.amazonaws.com`, + 'x-k8s-aws-id': clusterId, + }, + hostname: `sts.${region}.amazonaws.com`, + method: 'GET', + path: '/', + protocol: 'https:', + query: { + Action: 'GetCallerIdentity', + Version: '2011-06-15', + }, + }, + { expiresIn: 0 }, + ); + + // ... code ... + } + + public presentAuthMetadata(_authMetadata: AuthMetadata): AuthMetadata { + return {}; + } + public validateCluster(): Error[] { + return []; + } +} +``` + +## Custom AuthStrategy + +Sometimes you need to add a new way to authenticate against a kubernetes cluster not support by default by Backstage. This is how integrators can bring their own kubernetes auth strategies through the use of the [`addAuthStrategy`](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts#L211) method on `KubernetesBuilder` or through the [AuthStrategyExtensionPoint](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/plugin.ts#L112). So, on the following sections, we are going to introduce a new AuthStrategy for [Pinniped][1], an authentication service for Kubernetes clusters. + +### Custom Pinniped auth strategy in the new backend system + +To add a new AuthStrategy, we need to create a new Pinniped [backend module](../../backend-system/building-plugins-and-modules/01-index.md#modules) to extend the Kubernetes-Backend plugin. The Pinniped module will interact with the Kubernetes-Backend plugin through the [extension points](../../backend-system/architecture/05-extension-points.md) registered by the plugin. The Kubernetes-Backend plugin [registers](https://github.com/backstage/backstage/blob/ebe7afad9d19f279469168ca0d4feceb92c1ad36/plugins/kubernetes-backend/src/plugin.ts#L155) multiple extension points like `kubernetesObjectsProvider`, `kubernetesClusterSupplier`, `kubernetesFetcher`, `kubernetesServiceLocator` and the `kubernetesAuthStrategy`. + +Notice that this guide assumes that you already installed the [Kubernetes Plugin](./installation.md). + +To create the Backend module, run `yarn new`, select `backend-module`. Then fill out: + +``` +? What do you want to create? backend-module - A new backend module +? Enter the ID of the plugin [required] kubernetes +? Enter the ID of the module [required] pinniped +``` + +This will create a new package at `plugins/kubernetes-backend-module-pinniped`. We are going to need also the `@backstage/plugin-kubernetes-node` and `@backstage/plugin-kubernetes-common` dependencies, the `@backstage/plugin-kubernetes-node` houses the [kubernetesAuthStrategyExtensionPoint](https://github.com/backstage/backstage/blob/ebe7afad9d19f279469168ca0d4feceb92c1ad36/plugins/kubernetes-node/src/extensions.ts#L77) and a [Pinniped Helper](https://github.com/backstage/backstage/blob/ebe7afad9d19f279469168ca0d4feceb92c1ad36/plugins/kubernetes-node/src/auth/PinnipedHelper.ts#L53) class. + +```bash +# From your Backstage root directory +yarn --cwd plugins/kubernetes-backend-module-pinniped add @backstage/plugin-kubernetes-node +yarn --cwd plugins/kubernetes-backend-module-pinniped add @backstage/plugin-kubernetes-common +``` + +Let's create a new file to house the Pinniped authentication strategy which will implement the `AuthenticationStrategy` interface. + +```ts title="plugins/kubernetes-backend-module-pinniped/src/PinnipedStrategy.ts" +import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; +import { Logger } from 'winston'; +import { + AuthMetadata, + AuthenticationStrategy, + ClusterDetails, + KubernetesCredential, + PinnipedClientCerts, + PinnipedHelper, + PinnipedParameters, +} from '@backstage/plugin-kubernetes-node'; +import { JsonObject } from '@backstage/types'; + +export class PinnipedStrategy implements AuthenticationStrategy { + private pinnipedHelper: PinnipedHelper; + + constructor(private readonly logger: Logger) { + this.pinnipedHelper = new PinnipedHelper(logger); + } + + public async getCredential( + clusterDetails: ClusterDetails, + requestAuth: KubernetesRequestAuth, + ): Promise<KubernetesCredential> { + const params: PinnipedParameters = { + token: + ((requestAuth.pinniped as JsonObject)?.clusteridtoken as string) || '', + authenticator: { + apiGroup: 'authentication.concierge.pinniped.dev', + kind: 'JWTAuthenticator', + name: 'supervisor', + }, + tokenCredentialRequest: { + apiGroup: 'login.concierge.pinniped.dev/v1alpha1', + }, + }; + + const x509Data: PinnipedClientCerts = + await this.pinnipedHelper.tokenCredentialRequest(clusterDetails, params); + return { + type: 'x509 client certificate', + cert: x509Data.cert, + key: x509Data.key, + }; + } + + public validateCluster(): Error[] { + return []; + } + + presentAuthMetadata: (authMetadata: AuthMetadata): AuthMetadata => { + return { + audience: authMetadata['kubernetes.io/x-pinniped-audience'], + }; + }, +} +``` + +The `PinnipedStrategy` implements the `AuthenticationStrategy` interface, it uses the PinnipedHelper class to exchange the clusterIdToken ( created by a custom Pinniped client-side `KubernetesAuthProvider` ) for a x509 certificate, certificate that will allow us to consume the kubernetes cluster. It also returns the audience value to the front-end through `presentAuthMetadata`. + +> Notice that the PinnipedHelper class will help you only to exchange the token, It doesn't introduce a cache layer, something that your strategy could introduce. + +Finally we could use the `kubernetesAuthStrategyExtensionPoint` to register our new PinnipedStrategy. + +```ts title="plugins/kubernetes-backend-module-pinniped/src/module.ts" +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { + AuthenticationStrategy, + kubernetesAuthStrategyExtensionPoint, +} from '@backstage/plugin-kubernetes-node'; +import { PinnipedStrategy } from './PinnipedStrategy'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; + +export const kubernetesModulePinniped = createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'pinniped', + register(reg) { + reg.registerInit({ + deps: { + logger: coreServices.logger, + authStrategy: kubernetesAuthStrategyExtensionPoint, + }, + async init({ logger, authStrategy }) { + const winstonLogger = loggerToWinstonLogger(logger); + const pinnipedStrategy: AuthenticationStrategy = new PinnipedStrategy( + winstonLogger, + ); + authStrategy.addAuthStrategy('pinniped', pinnipedStrategy); + }, + }); + }, +}); +``` + +### Custom Pinniped auth strategy in the old backend system + +To add a new AuthStrategy, You could use [`addAuthStrategy`](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts#L211) method on `KubernetesBuilder`. +We are going to reuse the `PinnipedStrategy` created on the previous section. So when setting up the [Kubernetes Backend plugin](./installation.md#adding-kubernetes-backend-plugin), you could add a new Strategy: + +```ts title="packages/backend/src/plugins/kubernetes.ts" +import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; +import { CatalogClient } from '@backstage/catalog-client'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { AuthenticationStrategy } from '@backstage/plugin-kubernetes-node'; +import { PinnipedStrategy } from '@internal/plugin-kubernetes-backend-module-pinniped'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); + const winstonLogger = loggerToWinstonLogger(env.logger); + const pinnipedStrategy: AuthenticationStrategy = new PinnipedStrategy( + winstonLogger, + ); + const { router } = await KubernetesBuilder.createBuilder({ + logger: env.logger, + config: env.config, + catalogApi, + permissions: env.permissions, + }) + .addAuthStrategy('pinniped', pinnipedStrategy) + .build(); + return router; +} +``` + +[1]: https://pinniped.dev +[2]: https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/kubernetes-node/src/types/types.ts#L149 +[3]: https://github.com/backstage/backstage/blob/f0ffd38136163edd75ae340e5653cf6b349dcbc1/plugins/kubernetes-backend/src/auth/AwsIamStrategy.ts#L52C40-L52C62 diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index ff3a42c7ed..064f7c803c 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -59,6 +59,8 @@ Valid values are: - `singleTenant` - This configuration assumes that current component run on one cluster in provided clusters. +- `catalogRelation` - This configuration assumes that the current component runs only on all clusters it is dependant on. + ### `clusterLocatorMethods` This is an array used to determine where to retrieve cluster configuration from. diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index bdd14098ff..42ceaaa016 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -75,6 +75,7 @@ export default async function createPlugin( logger: env.logger, config: env.config, catalogApi, + discovery: env.discovery, permissions: env.permissions, }).build(); return router; @@ -102,6 +103,31 @@ async function main() { That's it! The Kubernetes frontend and backend have now been added to your Backstage app. +### New Backend System + +To get the Kubernetes plugin install using the New Backend System you will need to do the following: + +Run this command to add the package: + +```bash +# From your Backstage root directory +yarn --cwd packages/backend add @backstage/plugin-kubernetes-backend +``` + +Then add it to your backend `index.ts` file: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); +/* highlight-add-end */ + +backend.start(); +``` + ### Custom cluster discovery If either existing @@ -173,6 +199,45 @@ export default async function createPlugin( } ``` +### New Backend System Custom cluster discovery + +To use Custom cluster discovery with the New Backend System you'll need to create a module and add it to your backend. Here's a very simplified example: + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { Duration } from 'luxon'; +import { kubernetesClusterSupplierExtensionPoint } from '@backstage/plugin-kubernetes-node'; +import { CustomClustersSupplier } from './path/to/class'; + +const backend = createBackend(); + +export const kubernetesModuleCustomClusterDiscovery = createBackendModule({ + pluginId: 'kubernetes', + moduleId: 'custom-cluster-discovery', + register(env) { + env.registerInit({ + deps: { + kubernetes: kubernetesClusterSupplierExtensionPoint, + }, + async init({ kubernetes }) { + kubernetes.addClusterSupplier( + CustomClustersSupplier.create(Duration.fromObject({ minutes: 60 })), + ); + }, + }); + }, +}); + +// Other plugins... +backend.add(import('@backstage/plugin-kubernetes-backend/alpha')); +backend.add(kubernetesModuleCustomClusterDiscovery); + +backend.start(); +``` + +> Note: this example assumes the `CustomClustersSupplier` class is the same from the [previous example](#custom-cluster-discovery) + ## Configuration After installing the plugins in the code, you'll need to then diff --git a/docs/features/search/README.md b/docs/features/search/README.md index 97d3d7efcb..93aa22ebe1 100644 --- a/docs/features/search/README.md +++ b/docs/features/search/README.md @@ -32,11 +32,11 @@ The following sections show the plugins and search engines currently supported b ### Plugins integrated with Backstage Search -| Plugin | Support Status | -| ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- | -| Software Catalog | ✅ | -| [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) | ✅ | +| Plugin | Support Status | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| Software Catalog | ✅ | +| [TechDocs](./how-to-guides.md#how-to-index-techdocs-documents) | ✅ | +| [Stack Overflow](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-stack-overflow-collator/README.md#index-stack-overflow-questions-to-search) | ✅ | ### Search engines diff --git a/docs/features/software-catalog/api.md b/docs/features/software-catalog/api.md index 46f32e9064..d002b12015 100644 --- a/docs/features/software-catalog/api.md +++ b/docs/features/software-catalog/api.md @@ -5,7 +5,9 @@ description: The Software Catalog API --- The software catalog backend has a JSON based REST API, which can be leveraged -by external systems. This page describes its shape and features. +by external systems. This page describes its shape and features. The OpenAPI spec +for this API can be found [here](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend/src/schema/openapi.yaml). +A UI visualizing the OpenAPI endpoints including the ability to try them out in the browser can be found [here](https://www.postman.com/backstage-io/workspace/catalog-api/overview). ## Overview diff --git a/docs/features/software-catalog/catalog-customization.md b/docs/features/software-catalog/catalog-customization.md index c2ffa0c22a..3dc47a610a 100644 --- a/docs/features/software-catalog/catalog-customization.md +++ b/docs/features/software-catalog/catalog-customization.md @@ -5,64 +5,232 @@ title: Catalog Customization description: How to add custom filters or interface elements to the Backstage software catalog --- -The Backstage software catalog comes with a default `CatalogIndexPage` to filter -and find catalog entities. This is already set up by default by -`@backstage/create-app`. +The Backstage software catalog comes with a default `CatalogIndexPage` to filter and find catalog entities. This is already set up by default by `@backstage/create-app`. If you want to change the default index page - to set the initially selected filter, adjust columns, add actions, or to add a custom filter to the catalog - the following sections will show you how. -If you want to change the default index page - such as to add a custom filter to -the catalog - you can create your own `CatalogIndexPage`. +## Pagination -> Note: The catalog index page is designed to have a minimal code footprint to -> support easy customization, but creating a copy does introduce a possibility -> of drifting out of date over time. Be sure to check the catalog -> [CHANGELOG](https://github.com/backstage/backstage/blob/master/plugins/catalog/CHANGELOG.md) -> periodically. +Initial support for pagination of the `CatalogIndexPage` was added in v1.21.0 of Backstage, so make sure you are on that version or newer to use this feature. To enable pagination you simply need to pass in the `pagination` prop like this: -For example, suppose that I want to allow filtering by a custom annotation added -to entities, `company.com/security-tier`. To start, I'll copy the code for the -default catalog page and create a component. - -```tsx -// imports, etc omitted for brevity. for full source see: -// https://github.com/backstage/backstage/blob/master/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx -export const CustomCatalogPage = ({ - columns, - actions, - initiallySelectedFilter = 'owned', -}: CatalogPageProps) => { - const createComponentLink = useRouteRef( - catalogPlugin.externalRoutes.createComponent, - ); - return ( - <PageWithHeader title={`${orgName} Catalog`} themeId="home"> - <EntityListProvider> - <Content> - <ContentHeader titleComponent={<CatalogKindHeader />}> - <CreateButton title="Create Component" to={createComponentLink()} /> - <SupportButton>All your software catalog entities</SupportButton> - </ContentHeader> - <CatalogFilterLayout> - <CatalogFilterLayout.Filters> - <EntityTypePicker /> - <UserListPicker initialFilter={initiallySelectedFilter} /> - <EntityTagPicker /> - </CatalogFilterLayout.Filters> - <CatalogFilterLayout.Content> - <CatalogTable columns={columns} actions={actions} /> - </CatalogFilterLayout.Content> - </CatalogFilterLayout> - </Content> - </EntityListProvider> - </PageWithHeader> - ); -}; +```tsx title="packages/app/src/App.tsx" +<Route path="/catalog" element={<CatalogIndexPage pagination />} /> ``` -The `EntityListProvider` shown here provides a list of entities from the -`catalog-backend`, and a way to hook in filters. +## Initially Selected Filter -Now we're ready to create a new filter that implements the `EntityFilter` -interface: +By default the initially selected filter defaults to Owned. If you are still building up your catalog this may show an empty list to start. If you would prefer this to show All as the default, here's how you can make that change: + +```tsx title="packages/app/src/App.tsx" +<Route + path="/catalog" + element={<CatalogIndexPage initiallySelectedFilter="all" />} +/> +``` + +Possible options are: owned, starred, or all + +## Initially Selected Kind + +By default the initially selected Kind when viewing the Catalog is Component, but you may have reasons that you want this to be different. Let's say at your Organization they would like it to always default to Domain, here's how you would do that: + +```tsx title="packages/app/src/App.tsx" +<Route path="/catalog" element={<CatalogIndexPage initialKind="domain" />} /> +``` + +Possible options are all the [default Kinds](system-model.md) as well as any custom Kinds that you have added. + +## Owner Picker Mode + +The Owner filter by default will only contain a list of Users and/or Groups that actually own an entity in the Catalog, now you may have reason to change this. Here's how: + +```tsx title="packages/app/src/App.tsx" +<Route path="/catalog" element={<CatalogIndexPage ownerPickerMode="all" />} /> +``` + +Possible options are: owners-only or all + +## Table Options + +The tables used within Backstage are built on top of [`@material-table/core`](https://material-table-core.github.io/) and the `CatalogIndexPage` has a `tableOptions` prop that allows you to customize the underlying table to a certain extent, but there are some hard coded Backstage settings that can't be changed. Here's an example of how to use this prop to disable the search filter field in the table's header: + +```tsx title="packages/app/src/App.tsx" +<Route + path="/catalog" + element={<CatalogIndexPage tableOptions={{ search: false }} />} +/> +``` + +There are many options that can be set using `tableOptions`, the full list of settings can be found in the [`@material-table/core` `Options` interface](https://github.com/material-table-core/core/blob/v3.1.0/types/index.d.ts#L323) (this link goes to `v3.1.0` of `@material-table/core` as that is the version currently used by Backstage). + +## Customize Columns + +By default the columns you see in the `CatalogIndexPage` were selected to be a good starting point for most but there may be reasons that you would like to customize these with more or less columns. One primary use case for this customization is if you added a custom Kind. Support for this was added in v1.23.0 of Backstage, make sure you are on that version or newer to use this feature. Here's an example of how to make this customization: + +```tsx title="packages/app/src/App.tsx" +import { + CatalogEntityPage, + CatalogIndexPage, + catalogPlugin, + {/* highlight-add-start */} + CatalogTable, + CatalogTableColumnsFunc, + {/* highlight-add-end */} +} from '@backstage/plugin-catalog'; + +{/* highlight-add-start */} +const myColumnsFunc: CatalogTableColumnsFunc = entityListContext => { + if (entityListContext.filters.kind?.value === 'MyKind') { + return [ + CatalogTable.columns.createNameColumn(), + CatalogTable.columns.createOwnerColumn(), + ]; + } + + return CatalogTable.defaultColumnsFunc(entityListContext); +}; +{/* highlight-add-end */} + +{/* highlight-remove-next-line */} +<Route path="/catalog" element={<CatalogIndexPage />} /> +{/* highlight-add-next-line */} +<Route path="/catalog" element={<CatalogIndexPage columns={myColumnsFunc} />} /> +``` + +> Note: the above example has been simplified and you will most likely have more code then just this in your `App.tsx` file. + +## Customize Actions + +The `CatalogIndexPage` comes with three default actions - view, edit, and star. You might want to add more. + +To do this, first you'll need to add `@mui/utils` to your `packages/app/package.json`: + +```sh +yarn --cwd packages/app add @mui/utils +``` + +Then you'll do the following: + +```tsx title="packages/app/src/App.tsx" +import { + AlertDisplay, + OAuthRequestDialog, + SignInPage, + {/* highlight-add-next-line */} + TableProps, +} from '@backstage/core-components'; + +import { + CatalogEntityPage, + CatalogIndexPage, + {/* highlight-add-next-line */} + CatalogTableRow, + catalogPlugin, +} from '@backstage/plugin-catalog'; + +{/* highlight-add-start */} +import { Typography } from '@material-ui/core'; +import OpenInNew from '@material-ui/icons/OpenInNew'; +import { visuallyHidden } from '@mui/utils'; +{/* highlight-add-end */} + +{/* highlight-add-start */} +const customActions: TableProps<CatalogTableRow>['actions'] = [ + ({ entity }) => { + const url = 'https://backstage.io/'; + const title = `View - ${entity.metadata.name}`; + + return { + icon: () => ( + <> + <Typography style={visuallyHidden}>{title}</Typography> + <OpenInNew fontSize="small" /> + </> + ), + tooltip: title, + disabled: !url, + onClick: () => { + if (!url) return; + window.open(url, '_blank'); + }, + }; + }, +]; +{/* highlight-add-end */} + +{/* highlight-remove-next-line */} +<Route path="/catalog" element={<CatalogIndexPage />} /> +{/* highlight-add-next-line */} +<Route path="/catalog" element={<CatalogIndexPage actions={customActions} />} /> +``` + +> Note: the above example has been simplified and you will most likely have more code then just this in your `App.tsx` file. + +The above customization will override the existing actions. Currently the only way to keep them and add your own is to also include the existing actions in your array by copying them from the [`defaultActions`](https://github.com/backstage/backstage/blob/57397e7d6d2d725712c439f4ab93f2ac6aa27bf8/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx#L113-L168). + +## Customize Filters + +There are three options you have for filters: adjusting the existing filters with props, adding or removing the default filters, or creating a brand new custom filter. The following sections cover these cases + +### Default Filter Props + +There are a set of default filters that you can use, which surface all the props mentioned earlier in this document. Here's how they can be used: + +```tsx title="packages/app/src/App.tsx" +import { DefaultFilters } from '@backstage/plugin-catalog-react'; + +<Route + path="/catalog" + element={ + <CatalogIndexPage + filters={ + <> + <DefaultFilters + initialKind="Domain" + initiallySelectedFilter="all" + ownerPickerMode="all" + /> + </> + } + /> + } +/>; +``` + +### Removing Default Filters + +You may have reasons not use the Lifecycle, Tag, and Processing Status filters, here's an example of how you would remove them: + +```tsx title="packages/app/src/App.tsx" +import { + EntityKindPicker, + EntityTypePicker, + UserListPicker, + EntityOwnerPicker, + EntityNamespacePicker, +} from '@backstage/plugin-catalog-react'; + +<Route + path="/catalog" + element={ + <CatalogIndexPage + filters={ + <> + <EntityKindPicker /> + <EntityTypePicker /> + <UserListPicker /> + <EntityOwnerPicker /> + <EntityNamespacePicker /> + </> + } + /> + } +/>; +``` + +### Custom Filters + +You can add custom filters. For example, suppose that I want to allow filtering by a custom annotation added to entities, `company.com/security-tier`. Here is how we can build a filter to support that need. + +First we need to create a new filter that implements the `EntityFilter` interface: ```ts import { EntityFilter } from '@backstage/plugin-catalog-react'; @@ -77,13 +245,9 @@ class EntitySecurityTierFilter implements EntityFilter { } ``` -The `EntityFilter` interface permits backend filters, which are passed along to -the `catalog-backend` - or frontend filters, which are applied after entities -are loaded from the backend. +The `EntityFilter` interface permits backend filters, which are passed along to the `catalog-backend` - or frontend filters, which are applied after entities are loaded from the backend. -We'll use this filter to extend the default filters in a type-safe way. Let's -create the custom filter shape extending the default somewhere alongside this -filter: +We'll use this filter to extend the default filters in a type-safe way. Let's create the custom filter shape extending the default somewhere alongside this filter: ```ts export type CustomFilters = DefaultEntityFilters & { @@ -91,11 +255,7 @@ export type CustomFilters = DefaultEntityFilters & { }; ``` -To control this filter, we can create a React component that shows checkboxes -for the security tiers. This component will make use of the -`useEntityList` hook, which accepts this extended filter type as a -[generic](https://www.typescriptlang.org/docs/handbook/2/generics.html) -parameter: +To control this filter, we can create a React component that shows checkboxes for the security tiers. This component will make use of the `useEntityList` hook, which accepts this extended filter type as a [generic](https://www.typescriptlang.org/docs/handbook/2/generics.html) parameter: ```tsx export const EntitySecurityTierPicker = () => { @@ -140,36 +300,109 @@ export const EntitySecurityTierPicker = () => { }; ``` -Now we can add the component to `CustomCatalogPage`: +Now we can add the component to `CatalogIndexPage`: -```tsx -export const CustomCatalogPage = ({ - columns, - actions, - initiallySelectedFilter = 'owned', -}: CatalogPageProps) => { - return ( +```tsx title="packages/app/src/App.tsx" +{ + /* highlight-add-start */ +} +import { DefaultFilters } from '@backstage/plugin-catalog-react'; +{ + /* highlight-add-end */ +} + +const routes = ( + <FlatRoutes> + <Navigate key="/" to="catalog" /> + {/* highlight-remove-next-line */} + <Route path="/catalog" element={<CatalogIndexPage />} /> + {/* highlight-add-start */} + <Route + path="/catalog" + element={ + <CatalogIndexPage + filters={ + <> + <DefaultFilters /> + <EntitySecurityTierPicker /> + </> + } + /> + } + /> + {/* highlight-add-end */} {/* ... */} - <EntityListProvider> + </FlatRoutes> +); +``` + +The same method can be used to customize the _default_ filters with a different interface - for such usage, the generic argument isn't needed since the filter shape remains the same as the default. + +## Advanced Customization + +For those where none of the above fits their needs you can take the option of creating a fully custom `CatalogIndexPage`. + +```tsx title="packages/app/src/components/catalog/CustomCatalogIndex.tsx" +import { + PageWithHeader, + Content, + ContentHeader, + SupportButton, +} from '@backstage/core-components'; +import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { CatalogTable } from '@backstage/plugin-catalog'; +import { + EntityListProvider, + CatalogFilterLayout, + EntityKindPicker, + EntityLifecyclePicker, + EntityNamespacePicker, + EntityOwnerPicker, + EntityProcessingStatusPicker, + EntityTagPicker, + EntityTypePicker, + UserListPicker, +} from '@backstage/plugin-catalog-react'; +import React from 'react'; + +export const CustomCatalogPage = () => { + const orgName = + useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; + + return ( + <PageWithHeader title={orgName} themeId="home"> + <Content> + <ContentHeader title=""> + <SupportButton>All your software catalog entities</SupportButton> + </ContentHeader> + <EntityListProvider pagination> <CatalogFilterLayout> <CatalogFilterLayout.Filters> - <EntityKindPicker initialFilter="component" hidden /> + <EntityKindPicker /> <EntityTypePicker /> - <UserListPicker initialFilter={initiallySelectedFilter} /> - {/* highlight-add-next-line */} - <EntitySecurityTierPicker /> + <UserListPicker /> + <EntityOwnerPicker /> + <EntityLifecyclePicker /> <EntityTagPicker /> - <CatalogFilterLayout.Filters> + <EntityProcessingStatusPicker /> + <EntityNamespacePicker /> + </CatalogFilterLayout.Filters> <CatalogFilterLayout.Content> - <CatalogTable columns={columns} actions={actions} /> + <CatalogTable /> </CatalogFilterLayout.Content> </CatalogFilterLayout> </EntityListProvider> - {/* ... */} + </Content> + </PageWithHeader> + ); }; ``` -Finally, we can apply our new `CustomCatalogPage`. +The above is a very basic version of a fully custom `CatalogIndexPage`, you'll want to explore the various props to see what you can all do with them. This was built off the building blocks seen in the [`DefaultCatalogPage`](https://github.com/backstage/backstage/blob/master/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx) + +> Note: The catalog index page is designed to have a minimal code footprint to support easy customization, but creating a replica does introduce a possibility of drifting out of date over time. Be sure to check the catalog [CHANGELOG](https://github.com/backstage/backstage/blob/master/plugins/catalog/CHANGELOG.md) periodically. + +To use this custom `CatalogIndexPage` which we called `CustomCatalogPage`, you'll need to make the following change: ```tsx title="packages/app/src/App.tsx" const routes = ( @@ -186,7 +419,3 @@ const routes = ( </FlatRoutes> ); ``` - -The same method can be used to customize the _default_ filters with a different -interface - for such usage, the generic argument isn't needed since the filter -shape remains the same as the default. diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 054b727e78..416eb27fbd 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -659,6 +659,8 @@ metadata: name: v1beta2-demo title: Test Action template description: scaffolder v1beta2 template demo + annotations: + backstage.io/time-saved: PT4H spec: owner: backstage/techdocs-core type: service @@ -736,6 +738,16 @@ A list of strings that can be associated with the template, e.g. This list will also be used in the frontend to display to the user so you can potentially search and group templates by these tags. +### `metadata.annotations.[backstage.io/time-saved]` [optional] + +An ISO 8601 duration representing the approximate amount of time saved when +someone uses this template (e.g. `PT8H` to mean "8 hours saved" or `PT15M` to +mean "15 minutes saved"). + +Can be used in combination with the `backstage.io/source-template` annotation, +or analytics data, to calculate how much time has been saved through the use +of the Scaffolder plugin. + ### `spec.type` [required] The type of component created by the template, e.g. `website`. This is used for @@ -955,6 +967,14 @@ some form, that the group may wish to be used for contacting them. The picture is expected to be a URL pointing to an image that's representative of the group, and that a browser could fetch and render on a group page or similar. +The fields of a profile are: + +| Field | Type | Description | +| ------------------------ | ------ | -------------------------------------------------------------- | +| `displayName` (optional) | String | A human-readable name for the group. | +| `email` (optional) | String | An email the group may wish to be used for contacting them. | +| `picture` (optional) | String | A URL pointing to an image that's representative of the group. | + ### `spec.parent` [optional] The immediate parent group in the hierarchy, if any. Not all groups must have a @@ -1040,6 +1060,14 @@ of some form, that the user may wish to be used for contacting them. The picture is expected to be a URL pointing to an image that's representative of the user, and that a browser could fetch and render on a profile page or similar. +The fields of a profile are: + +| Field | Type | Description | +| ------------------------ | ------ | ------------------------------------------------------------- | +| `displayName` (optional) | String | A human-readable name for the user. | +| `email` (optional) | String | An email the user may wish to be used for contacting them. | +| `picture` (optional) | String | A URL pointing to an image that's representative of the user. | + ### `spec.memberOf` [required] The list of groups that the user is a direct member of (i.e., no transitive @@ -1237,6 +1265,7 @@ metadata: description: Everything about artists spec: owner: artist-relations-team + subdomainOf: audio-domain ``` In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata) @@ -1265,6 +1294,15 @@ but there will always be one ultimate owner. | ------------------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------------------- | | [`Group`](#kind-group) (default), [`User`](#kind-user) | Same as this entity, typically `default` | [`ownerOf`, and reverse `ownedBy`](well-known-relations.md#ownedby-and-ownerof) | +### `spec.subdomainOf` [optional] + +An [entity reference](references.md#string-references) to another domain of +which the domain is a part, e.g. `audio`. This field is optional. + +| [`kind`](#apiversion-and-kind-required) | Default [`namespace`](#namespace-optional) | Generated [relation](well-known-relations.md) type | +| --------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- | +| [`Domain`](#kind-domain) (default) | Same as this entity, typically `default` | [`partOf`, and reverse `hasPart`](well-known-relations.md#partof-and-haspart) | + ## Kind: Location Describes the following entity kind: diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index fec924fa91..b3d7de3a65 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -120,7 +120,7 @@ the infrastructure tooling through plugins. Different plugins are used for managing different types of components. For example, the -[Lighthouse plugin](https://github.com/backstage/backstage/tree/master/plugins/lighthouse) +[Lighthouse plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/lighthouse/plugins/lighthouse) only makes sense for Websites. The more specific you can be in how you model your software, the easier it is to provide plugins that are contextual. @@ -139,11 +139,12 @@ Example intents: > data in annotation values, not just strings." After pieces of raw entity data have been read from a location, they are passed -through a fixed number of so called `Validators`, as part of the entity policy -check step. They ensure that the types and syntax of the base envelope and -metadata make sense - in short, things that aren't entity-kind-specific. Some or -all of these validators can be replaced when building the backend catalog using -the `CatalogBuilder`. +through a field format validation step. This ensures that the types and syntax +of the base envelope and metadata make sense - in short, things that aren't +entity-kind-specific. Some or all of these validators can be replaced when +building the backend using the catalog's dedicated `catalogModelExtensionPoint` +(or directly on the `CatalogBuilder` if you are still using the old backend +system). The risk and impact of this type of extension varies, based on what it is that you want to do. For example, extending the valid character set for kinds, @@ -154,9 +155,56 @@ aren't careful about encoding arguments. Supporting non-strings in annotations may be possible but has not yet been tried out in the real world - there is likely to be some level of plugin breakage that can be hard to predict. +You must also be careful about not making the rules _more strict_ than they used +to be after populating the catalog with data. This risks making previously valid +entities start having processing errors and fail to update. + Before making this kind of extension, we recommend that you contact the Backstage maintainers or a support partner to discuss your use case. +This is an example of relaxing the format rules of the `metadata.name` field: + +```ts +import { createBackend } from '@backstage/backend-defaults'; +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { catalogModelExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; + +const myCatalogCustomizations = createBackendModule({ + pluginId: 'catalog', + moduleId: 'catalog-customization', + register(reg) { + reg.registerInit({ + deps: { + catalogModel: catalogModelExtensionPoint, + }, + async init({ catalogModel }) { + catalogModel.setFieldValidators({ + // This is only one of many methods that you can pass into + // setFieldValidators; your editor of choice should help you + // find the others. The length checks and regexp inside are + // just examples and can be adjusted as needed, but take care + // to test your changes thoroughly to ensure that you get + // them right. + isValidEntityName(value) { + return ( + typeof value === 'string' && + value.length >= 1 && + value.length <= 63 && + /^[A-Za-z0-9@+_.-]+$/.test(value) + ); + }, + }); + }, + }); + }, +}); + +const backend = createBackend(); +// ... add other backend features and the catalog backend itself here ... +backend.add(myCatalogCustomizations); +backend.start(); +``` + ## Changing the Validation Rules for Core Entity Fields Example intent: @@ -451,7 +499,7 @@ You can generate an isomorphic plugin package by running:`yarn new --select plug or you can run `yarn new` and then select "plugin-common" from the list of options There's at this point no existing templates for generating isomorphic plugins -using the `@backstage/cli`. Perhaps the simplest wat to get started right now is +using the `@backstage/cli`. Perhaps the simplest way to get started right now is to copy the contents of one of the existing packages in the main repository, such as `plugins/scaffolder-common`, and rename the folder and file contents to the desired name. This example uses _foobar_ as the plugin name so the plugin diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 38c30bd701..a1dcbabb99 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -279,6 +279,45 @@ the `connect` call has been made to the provider. Start up the backend - it should now start reading from the previously registered location and you'll see your entities start to appear in Backstage. +#### New Backend System + +To install the provider using the new backend system you will need to create a module and add it to your backend. The following is a very simplified example of what that would look like: + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { FrobsProvider } from './path/to/class'; + +export const catalogModuleFrobsProvider = createBackendModule({ + pluginId: 'catalog', + moduleId: 'frobs-provider', + register(env) { + env.registerInit({ + deps: { + catalog: catalogProcessingExtensionPoint, + reader: coreServices.urlReader, + }, + async init({ catalog, reader }) { + catalog.addEntityProvider(new FrobsProvider('dev', reader)); + }, + }); + }, +}); + +const backend = createBackend(); + +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +backend.add(catalogModuleFrobsProvider); + +// Other plugins ... + +backend.start(); +``` + ### Example User Entity Provider If you have a 3rd party entity provider such as an internal HR system that you wish to use you are not limited to using our entity providers, (or simply wish to add to existing entity providers with your own data). @@ -586,6 +625,45 @@ export default async function createPlugin( Start up the backend - it should now start reading from the previously registered location and you'll see your entities start to appear in Backstage. +#### Installing Processor Using New Backend System + +To install the processor using the new backend system you will need to create a module and add it to your backend. The following is a very simplified example of what that would look like: + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { SystemXReaderProcessor } from '../path/to/class'; + +export const catalogModuleSystemXReaderProcessor = createBackendModule({ + pluginId: 'catalog', + moduleId: 'system-x-reader-processor', + register(env) { + env.registerInit({ + deps: { + catalog: catalogProcessingExtensionPoint, + reader: coreServices.urlReader, + }, + async init({ catalog, reader }) { + catalog.addProcessor(new SystemXReaderProcessor(reader)); + }, + }); + }, +}); + +const backend = createBackend(); + +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +backend.add(catalogModuleSystemXReaderProcessor); + +// Other plugins ... + +backend.start(); +``` + ### Caching processing results The catalog periodically refreshes entities in the catalog, and in doing so it @@ -679,9 +757,10 @@ export class SystemXReaderProcessor implements CatalogProcessor { if (error.name === 'NotModifiedError' && cacheItem) { // The ETag matches and we have a cached value from the previous run. emit(processingResult.entity(location, cacheItem.entity)); + } else { + const message = `Unable to read ${location.type}, ${error}`; + emit(processingResult.generalError(location, message)); } - const message = `Unable to read ${location.type}, ${error}`; - emit(processingResult.generalError(location, message)); } return true; @@ -807,3 +886,42 @@ import { customEntityDataParser } from '../lib/customEntityDataParser'; builder.setEntityDataParser(customEntityDataParser); ``` + +#### Using Custom Entity Data Parser with New Backend System + +To use a custom entity data parse with the new backend system you will need to create a module and add it to your backend. The following is a very simplified example of what that would look like: + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { catalogModelExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { customEntityDataParser } from '../lib/customEntityDataParser'; + +export const catalogModuleCustomDataParser = createBackendModule({ + pluginId: 'catalog', + moduleId: 'custom-data-parser', + register(env) { + env.registerInit({ + deps: { + catalog: catalogModelExtensionPoint, + reader: coreServices.urlReader, + }, + async init({ catalog, reader }) { + catalog.setEntityDataParser(customEntityDataParser); + }, + }); + }, +}); + +const backend = createBackend(); + +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +backend.add(catalogModuleCustomDataParser); + +// Other plugins ... + +backend.start(); +``` diff --git a/docs/features/software-catalog/index.md b/docs/features/software-catalog/index.md index ae3a4ef4c2..c98d6911b4 100644 --- a/docs/features/software-catalog/index.md +++ b/docs/features/software-catalog/index.md @@ -40,9 +40,11 @@ browse the catalog at `http://localhost:3000`. ## Adding components to the catalog -The source of truth for the components in your software catalog are -[metadata YAML files](descriptor-format.md) stored in source control (GitHub, -GitHub Enterprise, GitLab, ...). +The source of truth for the components in your software catalog are [metadata +YAML files](descriptor-format.md) stored in source control (GitHub, GitHub +Enterprise, GitLab, ...). Repositories can include one or multiple metadata +files. Usually the metadata file is located in the repository root. This is not +a formal requirement & metadata files can be placed anywhere in the repository. There are 3 ways to add components to the catalog: @@ -132,7 +134,7 @@ in the catalog. ![screenshot of tools](https://backstage.io/assets/images/tabs-abfdf72185d3ceb1d92c4237f7f78809.png) -The Backstage platform can be customized by incorporating +Your Backstage developer portal can be customized by incorporating [existing open source plugins](https://github.com/backstage/backstage/tree/master/plugins), or by [building your own](../../plugins/index.md). diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 70f5ff5e14..974fa80993 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -146,6 +146,25 @@ repository itself. If the URL points to a folder, it is important that it is suffixed with a `'/'` in order for relative path resolution to work consistently. +### backstage.io/source-template + +```yaml +# Example: +metadata: + annotations: + backstage.io/source-template: template:default/create-react-app-template +``` + +Represents the entity ref of the Scaffolder template that was originally used +to create the given entity. Useful to power "create something similar" +experiences, as well as to track adherence to software standards across the +Catalog. + +Note that this value is only automatically added to an entity when the +`catalog:write` action is used to create the `catalog-info.yaml` file. It is +otherwise the template author's responsibility to ensure that any entity +definition included as part of the template contains this annotation. + ### jenkins.io/job-full-name ```yaml diff --git a/docs/features/software-catalog/well-known-relations.md b/docs/features/software-catalog/well-known-relations.md index bfcbcb780a..6d61847a15 100644 --- a/docs/features/software-catalog/well-known-relations.md +++ b/docs/features/software-catalog/well-known-relations.md @@ -99,11 +99,12 @@ A relation with a [Domain](descriptor-format.md#kind-domain), [System](descriptor-format.md#kind-system) or [Component](descriptor-format.md#kind-component) entity, typically from a [Component](descriptor-format.md#kind-component), -[API](descriptor-format.md#kind-api), or -[System](descriptor-format.md#kind-system). +[API](descriptor-format.md#kind-api), +[System](descriptor-format.md#kind-system), or +[Domain](descriptor-format.md#kind-domain), These relations express that a component belongs to a larger component; a -component, API or resource belongs to a system; or that a system is grouped -under a domain. +component, API or resource belongs to a system; that a system is grouped +under a domain; or that a domain belongs to a larger domain. This relation is commonly based on `spec.system` or `spec.domain`. diff --git a/docs/features/software-templates/authorizing-parameters-steps-and-actions.md b/docs/features/software-templates/authorizing-parameters-steps-and-actions.md index 27e8d48023..072f750a14 100644 --- a/docs/features/software-templates/authorizing-parameters-steps-and-actions.md +++ b/docs/features/software-templates/authorizing-parameters-steps-and-actions.md @@ -15,6 +15,8 @@ apiVersion: scaffolder.backstage.io/v1beta3 kind: Template metadata: name: my_custom_template +spec: + type: service parameters: - title: Provide some simple information properties: @@ -173,3 +175,58 @@ class ExamplePermissionPolicy implements PermissionPolicy { ``` Although the rules exported by the scaffolder are simple, combining them can help you achieve more complex cases. + +### Authorizing in the New Backend System + +Instead of the changes in `permission.ts` noted in the above example you will make them in your `index.ts`. You will need to create a module where your permission policy will get added. Here is a very simplified example of how to do that: + +```ts title="packages/backend/src/index.ts" +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { + PolicyDecision, + AuthorizeResult, +} from '@backstage/plugin-permission-common'; +import { + PermissionPolicy, + PolicyQuery, +} from '@backstage/plugin-permission-node'; +import { policyExtensionPoint } from '@backstage/plugin-permission-node/alpha'; + +class ExamplePermissionPolicy implements PermissionPolicy { + async handle( + request: PolicyQuery, + user?: BackstageIdentityResponse, + ): Promise<PolicyDecision> { + // Various scaffolder permission checks ... + + return { + result: AuthorizeResult.ALLOW, + }; + } +} + +const customPermissionBackendModule = createBackendModule({ + pluginId: 'permission', + moduleId: 'allow-all-policy', + register(reg) { + reg.registerInit({ + deps: { policy: policyExtensionPoint }, + async init({ policy }) { + policy.setPolicy(new ExamplePermissionPolicy()); + }, + }); + }, +}); + +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-permission-backend/alpha')); +backend.add(customPermissionBackendModule); +/* highlight-add-end */ +``` + +> Note: the `ExamplePermissionPolicy` here could be the one from the [Authorizing parameters and steps](#authorizing-parameters-and-steps) example or from the [Authorizing actions](#authorizing-actions) example. It would work the same way for both of them. diff --git a/docs/features/software-templates/builtin-actions.md b/docs/features/software-templates/builtin-actions.md index 1b3a53b5d9..94b2d2298b 100644 --- a/docs/features/software-templates/builtin-actions.md +++ b/docs/features/software-templates/builtin-actions.md @@ -8,8 +8,58 @@ The scaffolder comes with several built-in actions for fetching content, registering in the catalog and of course actions for creating and publishing a git repository. -There are several repository providers supported out of the box such as GitHub, -Azure, GitLab and Bitbucket. +## Action Modules + +There are also several modules available for various SCM tools: + +- Azure DevOps: `@backstage/plugin-scaffolder-backend-module-azure` +- Bitbucket Cloud: `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` +- Bitbucket Server: `@backstage/plugin-scaffolder-backend-module-bitbucket-server` +- Gerrit: `@backstage/plugin-scaffolder-backend-module-gerrit` +- Gitea: `@backstage/plugin-scaffolder-backend-module-gitea` +- GitHub: `@backstage/plugin-scaffolder-backend-module-github` +- GitLab: `@backstage/plugin-scaffolder-backend-module-gitlab` + +## Installing Action Modules + +Here's how to add an action module, first you need to run this command: + +```sh +# From your Backstage root directory +yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-github +``` + +Then you need to add it to your backend, this is a simplified new backend system for example purposes: + +```ts title="/packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; + +const backend = createBackend(); + +backend.add(import('@backstage/plugin-app-backend/alpha')); + +// catalog plugin +backend.add(import('@backstage/plugin-catalog-backend/alpha')); +backend.add( + import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'), +); + +// scaffolder plugin +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +{ + /* highlight-add-start */ +} +backend.add(import('@backstage/plugin-scaffolder-backend-module-github')); +{ + /* highlight-add-end */ +} + +backend.start(); +``` + +> Note: This is a simplified example of what your backend may look like, you may have more code in here then this. + +## Listing Actions A list of all registered actions can be found under `/create/actions`. For local development you should be able to reach them at diff --git a/docs/features/software-templates/index.md b/docs/features/software-templates/index.md index aa650a9703..d0c1bea9b2 100644 --- a/docs/features/software-templates/index.md +++ b/docs/features/software-templates/index.md @@ -12,7 +12,7 @@ code, template in some variables, and then publish the template to some locations like GitHub or GitLab. <video width="100%" height="100%" controls> - <source src="https://backstage.io/blog/assets/2020-08-05/feature.mp4" type="video/mp4" /> + <source src="/video/software-templates.mp4" type="video/mp4" /> </video> ## Getting Started diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index ad56ef2d36..a95cee24f4 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -194,3 +194,47 @@ parameters: input: message: 'production step' ``` + +## Use parameters as conditional for fields + +```yaml +parameters: + - title: Fill in some steps + properties: + includeName: + title: Include Name? + type: boolean + default: true + + dependencies: + includeName: + allOf: + - if: + properties: + includeName: + const: true + then: + properties: + lastName: + title: Last Name + type: string +``` + +## Conditionally set parameters + +```yaml +spec: + parameters: + - title: Fill in some steps + properties: + path: + title: path + type: string + + steps: + - id: fetch + name: Fetch template + action: fetch:template + input: + url: ${{ parameters.path if parameters.path else '/root' }} +``` diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 929ba150d2..92ff092948 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -107,7 +107,7 @@ export const createNewFileAction = () => { }; ``` -#### Naming Conventions +### Naming Conventions Try to keep names consistent for both your own custom actions, and any actions contributed to open source. We've found that a separation of `:` and using a verb as the last part of the name works well. We follow `provider:entity:verb` or as close to this as possible for our built in actions. For example, `github:actions:create` or `github:repo:create`. @@ -189,6 +189,42 @@ export default async function createPlugin( } ``` +### Register Action With New Backend System + +To register your new custom action in the New Backend System you will need to create a backend module. Here is a very simplified example of how to do that: + +```ts title="packages/backend/src/index.ts" +/* highlight-add-start */ +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; +import { createBackendModule } from '@backstage/backend-plugin-api'; +/* highlight-add-end */ + +/* highlight-add-start */ +const scaffolderModuleCustomExtensions = createBackendModule({ + pluginId: 'scaffolder', // name of the plugin that the module is targeting + moduleId: 'custom-extensions', + register(env) { + env.registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + // ... and other dependencies as needed + }, + async init({ scaffolder /* ..., other dependencies */ }) { + // Here you have the opportunity to interact with the extension + // point before the plugin itself gets instantiated + scaffolder.addActions(new createNewFileAction()); // just an example + }, + }); + }, +}); +/* highlight-add-end */ + +const backend = createBackend(); +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +/* highlight-add-next-line */ +backend.add(scaffolderModuleCustomExtensions()); +``` + ## List of custom action packages Here is a list of Open Source custom actions that you can add to your Backstage diff --git a/docs/features/software-templates/writing-custom-field-extensions.md b/docs/features/software-templates/writing-custom-field-extensions.md index f22cecd22c..d53b8bdf2f 100644 --- a/docs/features/software-templates/writing-custom-field-extensions.md +++ b/docs/features/software-templates/writing-custom-field-extensions.md @@ -30,7 +30,8 @@ As an example, we will create a component that validates whether a string is in ```tsx //packages/app/src/scaffolder/ValidateKebabCase/ValidateKebabCaseExtension.tsx import React from 'react'; -import { FieldProps, FieldValidation } from '@rjsf/core'; +import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react'; +import type { FieldValidation } from '@rjsf/utils'; import FormControl from '@material-ui/core/FormControl'; /* This is the actual component that will get rendered in the form @@ -40,7 +41,7 @@ export const ValidateKebabCase = ({ rawErrors, required, formData, -}: FieldProps<string>) => { +}: FieldExtensionComponentProps<string>) => { return ( <FormControl margin="normal" diff --git a/docs/features/software-templates/writing-tests-for-actions.md b/docs/features/software-templates/writing-tests-for-actions.md new file mode 100644 index 0000000000..0c92811b6f --- /dev/null +++ b/docs/features/software-templates/writing-tests-for-actions.md @@ -0,0 +1,57 @@ +--- +id: writing-tests-for-actions +title: Writing Tests For Actions +description: How to write tests for actions +--- + +Once you created a new action, your own custom one, or you would like to contribute new actions, you have to cover it with +Unit tests to be sure that your actions do what they suppose to do. + +Make sure that you cover the most of scenario's, which could happen with the action. +One of indispensable part of the test is to supply the context to a handler of action for the execution. +We encourage you to use a utility method for that, so your tests are immune to structural changes of context. +What is inevitably going to happen during the time. + +Example how to use it: + +```typescript +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; + +const mockContext = createMockActionContext({ + input: { repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org' }, +}); + +await action.handler(mockContext); + +expect(mockContext.output).toHaveBeenCalledWith( + 'remoteUrl', + 'https://dev.azure.com/organization/project/_git/repo', +); +``` + +One thing to be aware about: if you would like to call `createMockActionContext` inside `it`, +you have to provide a `workspacePath`. By default, `createMockActionContext` uses +`import { createMockDirectory } from '@backstage/backend-test-utils';` to create it for you. +This implementation contains a hook inside which creates this limitation. So in this case you can do then: + +```typescript +describe('github:autolinks:create', async () => { + const workspacePath = createMockDirectory().resolve('workspace'); + // ... + + it('should call the githubApis for creating alphanumeric autolink reference', async () => { + // ... + await action.handler( + createMockActionContext({ + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + keyPrefix: 'TICKET-', + urlTemplate: 'https://example.com/TICKET?query=<num>', + }, + workspacePath, + }), + ); + //... + }); +}); +``` diff --git a/docs/features/techdocs/README.md b/docs/features/techdocs/README.md index c6e1fd42ad..bee03ab45e 100644 --- a/docs/features/techdocs/README.md +++ b/docs/features/techdocs/README.md @@ -69,6 +69,7 @@ See [TechDocs Architecture](architecture.md) to get an overview of where the bel | GitLab | Yes ✅ | | GitLab Enterprise | Yes ✅ | | Gitea | Yes ✅ | +| AWS CodeCommit | Yes ✅ | ### File storage providers diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index eaa6c2de72..bf55c90af9 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -194,6 +194,33 @@ async function main() { That's it! TechDocs frontend and backend have now been added to your Backstage app. Now let us tweak some configurations to suit your needs. +### New Backend System + +To install TechDocs when using the New Backend system you will need to do the following. + +Navigate to `packages/backend` of your Backstage app, and install the `@backstage/plugin-techdocs-backend` package. + +```bash +# From your Backstage root directory +yarn --cwd packages/backend add @backstage/plugin-techdocs-backend +``` + +Then in your backend `index.ts` you will add the following line. + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-techdocs-backend/alpha')); +/* highlight-add-end */ + +backend.start(); +``` + +> Note: The above is a very simplified example, you may have more content then this in your version. + ## Setting the configuration **See [TechDocs Configuration Options](configuration.md) for complete diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index afc257f20b..b25c2a3928 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -721,6 +721,53 @@ and publish the documentation for them. If the value of the `company.com/techdoc annotation is anything other than `'local'`, the user is responsible for publishing documentation to the appropriate location in the TechDocs external storage. +### Hybrid build strategy using the New Backend System + +To setup a hybrid build strategy using the New Backend System you'll follow the same steps as above but for Step 4 you will need to do the following: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { + DocsBuildStrategy, + techdocsBuildsExtensionPoint, +} from '@backstage/plugin-techdocs-node'; + +const techdocsCustomBuildStrategy = createBackendModule({ + pluginId: 'techdocs', + moduleId: 'customBuildStrategy', + register(env) { + env.registerInit({ + deps: { + techdocs: techdocsBuildsExtensionPoint, + }, + async init({ techdocs }) { + const docsBuildStrategy: DocsBuildStrategy = { + shouldBuild: async params => + params.entity.metadata?.annotations?.[ + 'demo.backstage.io/techdocs-builder' + ] === 'local', + }; + + techdocs.setBuildStrategy(docsBuildStrategy); + }, + }); + }, +}); + +// Other plugins... + +/* highlight-add-start */ +backend.add(import('@backstage/plugin-techdocs-backend/alpha')); +backend.add(techdocsCustomBuildStrategy()); +/* highlight-add-end */ + +backend.start(); +``` + +> Note: You may need to add the `@backstage/plugin-techdocs-node` package to your backend `package.json` if it's not been imported already. + ## How to use other mkdocs plugins? The default plugin [mkdocs-techdocs-core](https://github.com/backstage/mkdocs-techdocs-core) provides a set of plugins that can be viewed as the minimum required plugins to enable TechDocs. Your organization might have needs beyond the core set though, here is the recommended way to enable other plugins. diff --git a/docs/frontend-system/building-apps/01-index.md b/docs/frontend-system/building-apps/01-index.md index e23f628fb6..ea7fe20948 100644 --- a/docs/frontend-system/building-apps/01-index.md +++ b/docs/frontend-system/building-apps/01-index.md @@ -74,7 +74,7 @@ Remember that package extensions that are not auto-discovered must be manually a ### Configure extensions individually -It is possible to enable, disable and configure extensions individually in the `app-config.yaml` config file. To get familiar with what is available for app extensions personalization, go to the [built-in extensions](./02-built-in-extensions.md) documentation. For plugin customizations, we recommend that you read the instructions in each plugin's README file. +It is possible to enable, disable and configure extensions individually in the `app-config.yaml` config file. To get familiar with what is available for app extensions personalization, go to the [built-in extensions](./03-built-in-extensions.md) documentation. For plugin customizations, we recommend that you read the instructions in each plugin's README file. ### Customize or override built-in extensions @@ -139,7 +139,7 @@ const app = createApp({ // Calls an async utility method that fetches the config object from the server const config = await getConfigFromServer(); // Feel free to manipulate the config object before returning it - // A common example is conditionally modify the config based on the running enviroment + // A common example is conditionally modify the config based on the running environment return { config }; }, }); diff --git a/docs/frontend-system/building-apps/02-configuring-extensions.md b/docs/frontend-system/building-apps/02-configuring-extensions.md new file mode 100644 index 0000000000..2fd4ce69fc --- /dev/null +++ b/docs/frontend-system/building-apps/02-configuring-extensions.md @@ -0,0 +1,9 @@ +--- +id: configuring-extensions +title: Configuring Extensions in the App +sidebar_label: Configuring Extensions +# prettier-ignore +description: Documentation for how to configure extensions in a Backstage app +--- + +TODO diff --git a/docs/frontend-system/building-apps/02-built-in-extensions.md b/docs/frontend-system/building-apps/03-built-in-extensions.md similarity index 100% rename from docs/frontend-system/building-apps/02-built-in-extensions.md rename to docs/frontend-system/building-apps/03-built-in-extensions.md diff --git a/docs/frontend-system/building-apps/08-migrating.md b/docs/frontend-system/building-apps/08-migrating.md new file mode 100644 index 0000000000..937e865133 --- /dev/null +++ b/docs/frontend-system/building-apps/08-migrating.md @@ -0,0 +1,437 @@ +--- +id: migrating +title: Migrating Apps +sidebar_label: Migration Guide +# prettier-ignore +description: How to migrate existing apps to the new frontend system +--- + +## Overview + +This section describes how to migrate an existing Backstage app package to use the new frontend system. The app package is typically found at `packages/app` in your project and is responsible for wiring together the Backstage frontend application. + +## Switching out `createApp` + +The first step in migrating an app is to switch out the `createApp` function for the new one from `@backstage/frontend-api-app`: + +```tsx title="in packages/app/src/App.tsx" +// highlight-remove-next-line +import { createApp } from '@backstage/app-defaults'; +// highlight-add-next-line +import { createApp } from '@backstage/frontend-app-api'; +``` + +This immediate switch will lead to a lot of breakages that we need to fix. + +Let's start by addressing the change to `app.createRoot(...)`, which no longer accepts any arguments. This represents a fundamental change that the new frontend system introduces. In the old system the app element tree that you passed to `app.createRoot(...)` was the primary way that you installed and configured plugins and features in your app. In the new system this is instead replaced by extensions that are wired together into an extension tree. Much more responsibility has now been shifted to plugins, for example you no longer have to manually provide the route path for each plugin page, but instead only configure it if you want to override the default. For more information on how the new system works, see the [architecture](../architecture/01-index.md) section. + +Given that the app element tree is most of what builds up the app, it's likely also going to be the majority of the migration effort. In order to make the migration as smooth as possible we have provided a helper that lets you convert an existing app element tree into plugins that you can install in a new app. This in turn allows for a gradual migration of individual plugins, rather than needing to migrate the entire app structure at once. + +The helper is called `convertLegacyApp` and is exported from the `@backstage/core-compat-api` package, which you will need to add as a dependency to your app package: + +```bash +yarn --cwd packages/app add @backstage/core-compat-api +``` + +Once installed, import `convertLegacyApp`. If your app currently looks like this: + +```tsx title="in packages/app/src/App.tsx" +const app = createApp({ + /* other options */ +}); + +export default app.createRoot( + <> + <AlertDisplay transientTimeoutMs={2500} /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </>, +); +``` + +Migrate it to the following: + +```tsx title="in packages/app/src/App.tsx" +const legacyFeatures = convertLegacyApp( + <> + <AlertDisplay transientTimeoutMs={2500} /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </>, +); + +const app = createApp({ + /* other options */ + features: [...legacyFeatures], +}); + +export default app.createRoot(); +``` + +We've taken all the elements that were previously passed to `app.createRoot(...)`, and instead passed them to `convertLegacyApp(...)`. We then pass the features returned by `convertLegacyApp` and forward them to the `features` option of the new `createApp`. + +There is one more detail that we need to deal with before moving on. The `app.createRoot()` function now returns a React element rather than a component, so we need to update our app `index.tsx` as follows: + +```tsx title="in packages/app/src/index.tsx" +import '@backstage/cli/asset-types'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; +// highlight-remove-next-line +import App from './App'; +// highlight-add-next-line +import app from './App'; + +// highlight-remove-next-line +ReactDOM.createRoot(document.getElementById('root')!).render(<App />); +// highlight-add-next-line +ReactDOM.createRoot(document.getElementById('root')!).render(app); +``` + +At this point the contents of your app should be past the initial migration stage, and we can move on to migrating any remaining options that you may have passed to `createApp`. + +## Migrating `createApp` Options + +Many of the `createApp` options have been migrated to use extensions instead. Each will have their own [extension creator](../architecture/03-extensions.md#extension-creators) that you use to create a custom extension. To add these standalone extensions to the app they need to be passed to `createExtensionOverrides`, which bundles them into a _feature_ that you can install in the app. See the [standalone extensions](../architecture/05-extension-overrides.md#create-standalone-extensions) section for more information. + +For example, assuming you have a `lightTheme` extension that you want to add to your app, you can use the following: + +```ts +const app = createApp({ + features: [ + // highlight-add-start + createExtensionOverrides({ + extensions: [lightTheme], + }), + // highlight-add-end + ], +}); +``` + +You can then also add any additional extensions that you may need to create as part of this migration to the `extensions` array as well. + +### `apis` + +[Utility API](../utility-apis/01-index.md) factories are now installed as extensions instead. Pass the existing factory to `createApiExtension` and install it in the app. For more information, see the section on [configuring Utility APIs](../utility-apis/04-configuring.md). + +For example, the following API configuration: + +```ts +const app = createApp({ + apis: [ + createApiFactory({ + api: scmIntegrationsApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), + }), + ], +}); +``` + +Can be converted to the following extension: + +```ts +const scmIntegrationsApi = createApiExtension({ + factory: createApiFactory({ + api: scmIntegrationsApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), + }), +}); +``` + +### `icons` + +Icons are currently installed through the usual options to `createApp`, but will be switched to use extensions in the future. + +### `plugins` + +Plugins are now passed through the `features` options instead. + +### `featureFlags` + +Declaring features flags in the app is no longer supported, move these declarations to the appropriate plugins instead. + +### `components` + +Many app components are now installed as extensions instead using `createComponentExtension`. See the section on [configuring app components](./01-index.md#configure-your-app) for more information. + +The `Router` component is now a built-in extension that you can override using `createRouterExtension`. + +The Sign-in page is now installed as an extension using the `createSignInPageExtension` instead. + +For example, the following sign-in page configuration: + +```tsx +const app = createApp({ + components: { + SignInPage: props => ( + <SignInPage + {...props} + provider={{ + id: 'github-auth-provider', + title: 'GitHub', + message: 'Sign in using GitHub', + apiRef: githubAuthApiRef, + }} + /> + ), + }, +}); +``` + +Can be converted to the following extension: + +```tsx +const signInPage = createSignInPageExtension({ + loader: async () => props => + ( + <SignInPage + {...props} + provider={{ + id: 'github-auth-provider', + title: 'GitHub', + message: 'Sign in using GitHub', + apiRef: githubAuthApiRef, + }} + /> + ), +}); +``` + +### `themes` + +Themes are now installed as extensions, using `createThemeExtension`. + +For example, the following theme configuration: + +```tsx +const app = createApp({ + themes: [ + { + id: 'light', + title: 'Light', + variant: 'light', + Provider: ({ children }) => ( + <UnifiedThemeProvider theme={customLightTheme}> + {children} + </UnifiedThemeProvider> + ), + }, + ], +``` + +Can be converted to the following extension: + +```tsx +const lightTheme = createThemeExtension({ + id: 'light', + title: 'Light Theme', + variant: 'light', + icon: <LightIcon />, + Provider: ({ children }) => ( + <UnifiedThemeProvider theme={builtinThemes.light} children={children} /> + ), +}); +``` + +### `configLoader` + +The config loader API has been slightly changed. Rather than returning a promise for an array of `AppConfig` objects, it should now return the `ConfigApi` directly. + +```ts +const app = createApp({ + async configLoader() { + const appConfigs = await loadAppConfigs(); + // highlight-remove-next-line + return appConfigs; + // highlight-add-next-line + return { config: ConfigReader.fromConfigs(appConfigs) }; + }, +}); +``` + +### `bindRoutes` + +Route bindings can still be done using this option, but you now also have the ability to bind routes using static configuration instead. See the section on [binding routes](../architecture/07-routes.md#binding-external-route-references) for more information. + +Note that if you are binding routes from a legacy plugin that was converted using `convertLegacyApp`, you will need to use the `convertLegacyRouteRefs` and/or `convertLegacyRouteRef` to convert the routes to be compatible with the new system. + +For example, if both the `catalogPlugin` and `scaffolderPlugin` are legacy plugins, you can bind their routes like this: + +```ts +const app = createApp({ + features: convertLegacyApp(...), + bindRoutes({ bind }) { + bind(convertLegacyRouteRefs(catalogPlugin.externalRoutes), { + createComponent: convertLegacyRouteRef(scaffolderPlugin.routes.root), + }); + }, +}); +``` + +### `__experimentalTranslations` + +Translations are now installed as extensions, using `createTranslationExtension`. + +## Gradual Migration + +After updating all `createApp` options as well as using `convertLegacyApp` to use your existing app structure, you should be able to start up the app and see that it still works. If that is not the case, make sure you read any error messages that you may see in the app as they can provide hints on what you need to fix. If you are still stuck, you can check if anyone else ran into the same issue in our [GitHub issues](https://github.com/backstage/backstage/issues), or ask for help in our [community Discord](https://discord.gg/backstage-687207715902193673). + +Assuming your app is now working, let's continue by migrating the rest of the app element tree to use the new system. + +First off we'll want to trim away any top-level elements in the app so that only the `routes` are left. For example, continuing where we left off with the following elements: + +```tsx title="in packages/app/src/App.tsx" +const legacyFeatures = convertLegacyApp( + <> + <AlertDisplay transientTimeoutMs={2500} /> + <OAuthRequestDialog /> + <AppRouter> + <Root>{routes}</Root> + </AppRouter> + </>, +); +``` + +You can remove all surrounding elements and just keep the `routes`: + +```tsx title="in packages/app/src/App.tsx" +const legacyFeatures = convertLegacyApp(routes); +``` + +This will remove many extension overrides that `convertLegacyApp` put in place, and switch over the shell of the app to the new system. This includes the root layout of the app along with the elements, router, and sidebar. The app will likely not look the same as before, and you'll need to refer to the [sidebar](#sidebar), [app root elements](#app-root-elements) and [app root wrappers](#app-root-wrappers) sections below for information on how to migrate those. + +Once that step is complete the work that remains is to migrate all of the [routes](#top-level-routes) and [entity pages](#entity-pages) in the app, including any plugins that do not yet support the new system. For information on how to migrate your own internal plugins, refer to the [plugin migration guide](../building-plugins/05-migrating.md). For external plugins you will need to check the migration status of each plugin and potentially contribute to the effort. + +Once these migrations are complete you should be left with an empty `convertLegacyApp(...)` call that you can now remove, and your app should be fully migrated to the new system! 🎉 + +### Top-level Routes + +Your top-level routes are the routes directly under the `AppRouter` component with the `<FlatRoutes>` element. In a small app they might look something like this: + +```tsx title="in packages/app/src/App.tsx" +const routes = ( + <FlatRoutes> + <Route path="/catalog" element={<CatalogIndexPage />} /> + <Route + path="/catalog/:namespace/:kind/:name" + element={<CatalogEntityPage />} + > + {entityPage} + </Route> + <Route path="/create" element={<ScaffolderPage />} /> + <Route + path="/tech-radar" + element={<TechRadarPage width={1500} height={800} />} + /> + </FlatRoutes> +); +``` + +Each of these routes needs to be migrated to the new system. You can do it as gradually as you want, with the only restriction being that **all routes from a single plugin must be migrated at once**. This is because plugins discovered from these legacy routes will override any plugins that are installed in your app. If you for example only migrate one of the two routes defined by a plugin, the other route will remain and still override any plugin with the same ID, and you're left with a partial and likely broken plugin. + +To migrate a route, you need to remove it from your list of routes and instead install the new version of the plugin in your app. Before doing this you should make sure that the plugin supports the new system. Let's remove the scaffolder route as an example: + +```tsx title="in packages/app/src/App.tsx" +const routes = ( + <FlatRoutes> + <Route path="/catalog" element={<CatalogIndexPage />} /> + <Route + path="/catalog/:namespace/:kind/:name" + element={<CatalogEntityPage />} + > + {entityPage} + </Route> + {/* highlight-remove-next-line */} + <Route path="/create" element={<ScaffolderPage />} /> + <Route + path="/tech-radar" + element={<TechRadarPage width={1500} height={800} />} + /> + </FlatRoutes> +); +``` + +If you are using [app feature discovery](../architecture/02-app.md#feature-discovery) the installation step is simple, it's already done! The new version of the scaffolder plugin was already discovered and present in the app, it was simply disabled because the plugin created from the legacy route had higher priority. If you do not use feature discovery, you will instead need to manually install the new scaffolder plugin in your app through the `features` option of `createApp`. + +Continue this process for each of your legacy routes until you have migrated all of them. For any plugin with additional extensions installed as children of the `Route`, refer to the plugin READMEs for more detailed instructions. For the entity pages, refer to the [separate section](#entity-pages). + +### Entity Pages + +The entity pages are typically defined in `packages/app/src/components/catalog` and rendered as a child of the `/catalog/:namespace/:kind/:name` route. The entity pages are typically quite large and bringing in content from quite a lot of different plugins. At the moment we do not provide a way to gradually migrate entity pages to the new system, although that is planned as a future improvement. This means that the entire entity page and all of its plugins need to be migrated at once, including any other usages of those plugins. + +### Sidebar + +New apps feature a built-in sidebar extension (`app/nav`) that will render all nav item extensions provided by plugins. This is a placeholder implementation and not intended as a long-term solution. In the future we will aim to provide a more flexible sidebar extension that allows for more customization out of the box. + +Because the built-in sidebar is quite limited you may want to override the sidebar with your own custom implementation. To do so, use `createExtension` directly and refer to the [original sidebar implementation](https://github.com/backstage/backstage/blob/master/packages/frontend-app-api/src/extensions/AppNav.tsx). The following is an example of how to take your existing sidebar from the `Root` component that you typically find in `packages/app/src/components/Root.tsx`, and use it in an extension override: + +```tsx +const nav = createExtension({ + namespace: 'app', + name: 'nav', + attachTo: { id: 'app/layout', input: 'nav' }, + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + return { + element: ( + <Sidebar> + {/* Sidebar contents from packages/app/src/components/Root.tsx go here */} + </Sidebar> + ), + }; + }, +}); +``` + +### App Root Elements + +App root elements are React elements that are rendered adjacent to your current `Root` component. For example, in this snippet `AlertDisplay`, `OAuthRequestDialog` and `VisitListener` are all app root elements: + +```tsx +export default app.createRoot( + <> + {/* highlight-next-line */} + <AlertDisplay transientTimeoutMs={2500} /> + {/* highlight-next-line */} + <OAuthRequestDialog /> + <AppRouter> + {/* highlight-next-line */} + <VisitListener /> + <Root>{routes}</Root> + </AppRouter> + </>, +); +``` + +The `AlertDisplay` and `OAuthRequestDialog` are already provided as built-in extensions, and so will `VisitListener`. But, if you have your own custom root elements you will need to migrate them to be extensions that you install in the app instead. Use `createAppRootElementExtension` to create said extension and then install it in the app. + +Whether the element used to be rendered as a child of the `AppRouter` or not doesn't matter. All new root app elements will be rendered as a child of the app router. + +### App Root Wrappers + +App root wrappers are React elements that are rendered as a parent of the current `Root` elements. For example, in this snippet the `CustomAppBarrier` is an app root wrapper: + +```tsx +export default app.createRoot( + <> + <AlertDisplay transientTimeoutMs={2500} /> + <OAuthRequestDialog /> + <AppRouter> + {/* highlight-next-line */} + <CustomAppBarrier> + <Root>{routes}</Root> + {/* highlight-next-line */} + </CustomAppBarrier> + </AppRouter> + </>, +); +``` + +Any app root wrapper needs to be migrated to be an extension, using `createAppRootWrapperExtension`. Note that if you have multiple wrappers they must be completely independent of each other, i.e. the order in which they the appear in the React tree should not matter. If that is not the case then you should group them into a single wrapper. diff --git a/docs/frontend-system/building-plugins/05-migrating.md b/docs/frontend-system/building-plugins/05-migrating.md new file mode 100644 index 0000000000..16f465ece7 --- /dev/null +++ b/docs/frontend-system/building-plugins/05-migrating.md @@ -0,0 +1,225 @@ +--- +id: migrating +title: Migrating Plugins +sidebar_label: Migration Guide +# prettier-ignore +description: How to migrate an existing frontend plugin to the new frontend system +--- + +This guide allows you to migrate a frontend plugin and its own components, routes, apis to the new frontend system. + +The main concept is that routes, components, apis are now extensions. You can use the appropriate extension creators to migrate all of them to extensions. + +## Migrating the plugin + +In the legacy frontend system a plugin was defined in its own `plugin.ts` file as following: + +```ts title="my-plugin/src/plugin.ts" + import { createPlugin } from '@backstage/core-plugin-api'; + + export const myPlugin = createPlugin({ + id: 'my-plugin', + apis: [], + routes: { + ... + }, + externalRoutes: { + ... + }, + }); +``` + +In order to migrate the actual definition of the plugin you need to recreate the plugin using the new `createPlugin` utility exported by `@backstage/frontend-plugin-api`. +The new `createPlugin` function doesn't accept apis anymore as apis are now extensions. + +```ts title="my-plugin/src/alpha.ts" + import { createPlugin } from '@backstage/frontend-plugin-api'; + + export default createPlugin({ + id: 'my-plugin', + // bind all the extensions to the plugin + /* highlight-next-line */ + extensions: [], + // convert old route refs to the new system + /* highlight-next-line */ + routes: convertLegacyRouteRefs({ + ... + }), + /* highlight-next-line */ + externalRoutes: convertLegacyRouteRefs({ + ... + }), + }); +``` + +The code above binds all the extensions to the plugin. _Important_: Make sure to export the plugin as default export of your package as a separate entrypoint, preferably `/alpha`, as suggested by the code snippet above. Make sure `src/alpha.ts` is exported in your `package.json`: + +```ts title="my-plugin/package.json" + "exports": { + ".": "./src/index.ts", + /* highlight-add-next-line */ + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + /* highlight-add-start */ + "alpha": [ + "src/alpha.ts" + ], + /* highlight-add-end */ + "package.json": [ + "package.json" + ] + } + }, +``` + +## Migrating Pages + +Pages that were previously created using the `createRoutableExtension` extension function can be migrated to the new Frontend System using the `createPageExtension` extension creator, exported by `@backstage/frontend-plugin-api`. + +For example, given the following page: + +```ts +export const FooPage = fooPlugin.provide( + createRoutableExtension({ + name: 'FooPage', + component: () => import('./components').then(m => m.FooPage), + mountPoint: rootRouteRef, + }), +); +``` + +it can be migrated as the following: + +```tsx +import { createPageExtension } from '@backstage/frontend-plugin-api'; +import { + compatWrapper, + convertLegacyRouteRef, +} from '@backstage/core-compat-api'; + +const fooPage = createPageExtension({ + defaultPath: '/foo', + // you can reuse the existing routeRef + // by wrapping into the convertLegacyRouteRef. + routeRef: convertLegacyRouteRef(rootRouteRef), + // these inputs usually match the props required by the component. + loader: ({ inputs }) => + import('./components/').then(m => + // The compatWrapper utility allows you to use the existing + // legacy frontend utilities used internally by the components. + compatWrapper(<m.FooPage />), + ), +}); +``` + +then add the `fooPage` extension to the plugin: + +```ts title="my-plugin/src/alpha.ts" + import { createPlugin } from '@backstage/frontend-plugin-api'; + + export default createPlugin({ + id: 'my-plugin', + // bind all the extensions to the plugin + /* highlight-remove-next-line */ + extensions: [], + /* highlight-add-next-line */ + extensions: [fooPage], + ... + }); +``` + +## Migrating Components + +The equivalent utility to replace components created with `createComponentExtension` is `createExtension` from `@backstage/frontend-plugin-api`. However, we recommend searching for a more appropriate extension creator first. + +## Migrating APIs + +There are a few things to keep in mind in regards to utility APIs. + +### React package interface and ref changes + +Let's begin with [your `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md). The act of exporting TypeScript interfaces and API refs have not changed from the old system. You can typically keep those as-is. For illustrative purposes, this is an example of an interface and its API ref: + +```tsx title="in @internal/plugin-example-react" +import { createApiRef } from '@backstage/frontend-plugin-api'; + +/** + * Performs some work. + * @public + */ +export interface WorkApi { + doWork(): Promise<void>; +} + +/** + * The work interface for the Example plugin. + * @public + */ +export const workApiRef = createApiRef<WorkApi>({ + id: 'plugin.example.work', +}); +``` + +Note at the top of the file that it uses the updated import from `@backstage/frontend-plugin-api` that we migrated in the previous section, instead of the old `@backstage/core-plugin-api`. + +Now let's migrate the implementation of the api. Before we changed the `core-plugin-api` imports the api would have looked somewhat similar to the following: + +```tsx title="in @internal/plugin-example, NOTE THIS IS LEGACY CODE" +import { storageApiRef, createApiFactory } from '@backstage/core-plugin-api'; +import { workApiRef } from '@internal/plugin-example-react'; +import { WorkImpl } from './WorkImpl'; + +const exampleWorkApi = createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), +}); +``` + +The major changes we'll make are + +- Change the old `@backstage/core-plugin-api` imports to the new `@backstage/frontend-plugin-api` package as per the top section of this guide +- Wrap the existing API factory in a `createApiExtension` + +The end result, after simplifying imports and cleaning up a bit, might look like this: + +```tsx title="in @internal/plugin-example" +import { + storageApiRef, + createApiFactory, + createApiExtension, +} from '@backstage/frontend-plugin-api'; +import { workApiRef } from '@internal/plugin-example-react'; +import { WorkImpl } from './WorkImpl'; + +const exampleWorkApi = createApiExtension({ + factory: createApiFactory({ + api: workApiRef, + deps: { storageApi: storageApiRef }, + factory: ({ storageApi }) => new WorkImpl({ storageApi }), + }), +}); +``` + +Finally, let's add the `exampleWorkApi` extension to the plugin: + +```ts title="my-plugin/src/alpha.ts" + import { createPlugin } from '@backstage/frontend-plugin-api'; + + export default createPlugin({ + id: 'my-plugin', + // bind all the extensions to the plugin + /* highlight-remove-next-line */ + extensions: [fooPage], + /* highlight-add-next-line */ + extensions: [exampleWorkApi, fooPage], + ... + }); +``` + +### Further work + +Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](../utility-apis/02-creating.md) to your API, if that makes sense for your current application. diff --git a/docs/frontend-system/utility-apis/01-index.md b/docs/frontend-system/utility-apis/01-index.md index 2d0f0a9698..37120a5152 100644 --- a/docs/frontend-system/utility-apis/01-index.md +++ b/docs/frontend-system/utility-apis/01-index.md @@ -40,4 +40,4 @@ These cases are all described in [the main article](./04-configuring.md). ## Migrating from the old frontend system -If you want to learn how to migrate your own utility APIs from the old frontend system to the new one, that's described in [a dedicated migration guide](./05-migrating.md). +If you want to learn how to migrate your own utility APIs from the old frontend system to the new one, that's described in the [Migrating APIs guide](../building-plugins/05-migrating.md#migrating-apis). diff --git a/docs/frontend-system/utility-apis/02-creating.md b/docs/frontend-system/utility-apis/02-creating.md index 8935b31b75..fcb7ff1a65 100644 --- a/docs/frontend-system/utility-apis/02-creating.md +++ b/docs/frontend-system/utility-apis/02-creating.md @@ -8,7 +8,7 @@ description: Creating new utility APIs in your plugins and app > **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** -This section describes how to make a Utility API from scratch, or to add configurability and inputs to an existing one. If you are instead interested in migrating an existing Utility API from the old frontend system, check out [the migrating section](./05-migrating.md). +This section describes how to make a Utility API from scratch, or to add configurability and inputs to an existing one. If you are instead interested in migrating an existing Utility API from the old frontend system, check out the [Migrating APIs section](../building-plugins/05-migrating.md#migrating-apis). ## Creating the Utility API contract diff --git a/docs/frontend-system/utility-apis/05-migrating.md b/docs/frontend-system/utility-apis/05-migrating.md deleted file mode 100644 index a81dc796ac..0000000000 --- a/docs/frontend-system/utility-apis/05-migrating.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -id: migrating -title: Migrating Utility APIs from the old frontend system -sidebar_label: Migrating -# prettier-ignore -description: Migrating Utility APIs from the old frontend system ---- - -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - -If you are migrating your plugins or app over from the old frontend system, there are a few things to keep in mind in regards to utility APIs. - -## Overview - -- Migrate your repo overall to the latest release of Backstage -- Follow the plugin migration guide <!-- TODO: Link --> -- Optionally change your package dependencies and code from `core-*-api` to `frontend-*-api` -- Keep the TypeScript interface and API ref exported as they were, except possibly reconsidering the choice of ID of the latter -- Wrap the old API factory call in an extension using `createApiExtension` -- Make sure that this extension is referenced by your migrated plugin - -## Prerequisites - -This guide assumes that you first [upgrade your repo](../../getting-started/keeping-backstage-updated.md) to the latest release of Backstage. This ensures that you do not have to fight several types of incompatibilities and updates at the same time. - -## Dependency changes - -In this article we will discuss some old interfaces that you used to import from the `@backstage/core-plugin-api` package. Those are now generally lifted over to `@backstage/frontend-plugin-api`, next to the new interfaces that are specific to the new frontend system. If you want to, you can already update your `package.json` and code imports to only use the new plugin API, but for the time being you don't have to. The old core exports will continue to work for the foreseeable future. - -To at least get access to the new interfaces, you'll need to run the following command. Note that it's just an example! It refers to `plugins/example`, which you'll have to change to the actual folder name that your package to migrate is in. - -```bash title="from your repo root" -yarn --cwd plugins/example add @backstage/frontend-plugin-api -``` - -## React package interface and ref changes - -Let's begin with [your `-react` package](../../architecture-decisions/adr011-plugin-package-structure.md). The act of exporting TypeScript interfaces and API refs have not changed from the old system. You can typically keep those as-is. For illustrative purposes, this is an example of an interface and its API ref: - -```tsx title="in @internal/plugin-example-react" -import { createApiRef } from '@backstage/frontend-plugin-api'; - -/** - * Performs some work. - * @public - */ -export interface WorkApi { - doWork(): Promise<void>; -} - -/** - * The work interface for the Example plugin. - * @public - */ -export const workApiRef = createApiRef<WorkApi>({ - id: 'plugin.example.work', -}); -``` - -In this example, the plugin ID already follows <!-- TODO: Link --> the common naming convention. If it doesn't, you may want to consider renaming that ID at this point. Don't worry, this won't hurt consumers in the old frontend system since the ID is mostly used for debugging purposes there. In the new system, it's much more important and appears in app-config files and similar. - -Note at the top of the file that it uses the updated import from `@backstage/frontend-plugin-api` that we migrated in the previous section, instead of the old `@backstage/core-plugin-api`. - -## Plugin package changes - -Now let's turn to the main plugin package where the plugin itself is exported. You will probably already have a `createPlugin` call in here. Before we changed the `core-plugin-api` imports it'll have looked somewhat similar to the following: - -```tsx title="in @internal/plugin-example, NOTE THIS IS LEGACY CODE" -import { - storageApiRef, - createPlugin, - createApiFactory, -} from '@backstage/core-plugin-api'; -import { workApiRef } from '@internal/plugin-example-react'; -import { WorkImpl } from './WorkImpl'; - -const exampleWorkApi = createApiFactory({ - api: workApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => new WorkImpl({ storageApi }), -}); - -/** @public */ -export const catalogPlugin = createPlugin({ - id: 'example', - apis: [exampleWorkApi], -}); -``` - -The major changes we'll make are - -- Optionally change the old imports to the new package as per the top section of this guide -- Wrap the existing API factory in a `createApiExtension` -- Change to the new version of `createPlugin` which exports this extension -- Change the plugin export to be the default instead - -The end result, after simplifying imports and cleaning up a bit, might look like this: - -```tsx title="in @internal/plugin-example" -import { - storageApiRef, - createPlugin, - createApiFactory, - createApiExtension, -} from '@backstage/frontend-plugin-api'; -import { workApiRef } from '@internal/plugin-example-react'; -import { WorkImpl } from './WorkImpl'; - -const exampleWorkApi = createApiExtension({ - factory: createApiFactory({ - api: workApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => new WorkImpl({ storageApi }), - }), -}); - -/** @public */ -export default createPlugin({ - id: 'example', - extensions: [exampleWorkApi], -}); -``` - -## Further work - -Since utility APIs are now complete extensions, you may want to take a bigger look at how they used to be used, and what the new frontend system offers. You may for example consider [adding configurability or inputs](./02-creating.md) to your API, if that makes sense for your current application. diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index d6a13ca6e3..8aadeaf19a 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -4,56 +4,42 @@ title: Customize the look-and-feel of your App description: Documentation on Customizing look and feel of the App --- -Backstage ships with a default theme with a light and dark mode variant. The -themes are provided as a part of the -[`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package, -which also includes utilities for customizing the default theme, or creating -completely new themes. +Backstage ships with a default theme with a light and dark mode variant. The themes are provided as a part of the [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package, which also includes utilities for customizing the default theme, or creating completely new themes. ## Creating a Custom Theme -The easiest way to create a new theme is to use the `createTheme` function -exported by the -[`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package. You -can use it to override some basic parameters of the default theme such as the -color palette and font. +The easiest way to create a new theme is to use the `createUnifiedTheme` function exported by the [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package. You can use it to override some basic parameters of the default theme such as the color palette and font. -For example, you can create a new theme based on the default light theme like -this: +For example, you can create a new theme based on the default light theme like this: -```ts -import { createTheme, lightTheme } from '@backstage/theme'; +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; -const myTheme = createTheme({ - palette: lightTheme.palette, +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + }), fontFamily: 'Comic Sans MS', defaultPageTheme: 'home', }); ``` -If you want more control over the theme, and for example customize font sizes -and margins, you can use the lower-level `createThemeOverrides` function -exported by [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) -in combination with -[`createTheme`](https://material-ui.com/customization/theming/#createmuitheme-options-args-theme) -from [`@material-ui/core`](https://www.npmjs.com/package/@material-ui/core). See -the "Overriding Backstage and Material UI css rules" section below. +> Note: we recommend creating a `theme` folder in `packages/app/src` to place your theme file to keep things nicely organized. -You can also create a theme from scratch that matches the `BackstageTheme` type -exported by [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). -See the -[Material UI docs on theming](https://material-ui.com/customization/theming/) -for more information about how that can be done. +You can also create a theme from scratch that matches the `BackstageTheme` type exported by [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). See the +[Material UI docs on theming](https://material-ui.com/customization/theming/) for more information about how that can be done. ## Using your Custom Theme -To add a custom theme to your Backstage app, you pass it as configuration to -`createApp`. +To add a custom theme to your Backstage app, you pass it as configuration to `createApp`. -For example, adding the theme that we created in the previous section can be -done like this: +For example, adding the theme that we created in the previous section can be done like this: -```tsx +```tsx title="packages/app/src/App.tsx" import { createApp } from '@backstage/app-defaults'; import { ThemeProvider } from '@material-ui/core/styles'; import CssBaseline from '@material-ui/core/CssBaseline'; @@ -68,70 +54,68 @@ const app = createApp({ variant: 'light', icon: <LightIcon />, Provider: ({ children }) => ( - <ThemeProvider theme={myTheme}> - <CssBaseline>{children}</CssBaseline> - </ThemeProvider> + <UnifiedThemeProvider theme={myTheme} children={children} /> ), }] }) ``` -Note that your list of custom themes overrides the default themes. If you still -want to use the default themes, they are exported as `lightTheme` and -`darkTheme` from -[`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). +Note that your list of custom themes overrides the default themes. If you still want to use the default themes, they are exported as `themes.light` and `themes.light` from [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). ## Example of a custom theme -```ts +```ts title="packages/app/src/theme/myTheme.ts" import { - createTheme, + createBaseThemeOptions, + createUnifiedTheme, genPageTheme, - lightTheme, + palettes, shapes, } from '@backstage/theme'; -const myTheme = createTheme({ - palette: { - ...lightTheme.palette, - primary: { - main: '#343b58', +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: { + ...palettes.light, + primary: { + main: '#343b58', + }, + secondary: { + main: '#565a6e', + }, + error: { + main: '#8c4351', + }, + warning: { + main: '#8f5e15', + }, + info: { + main: '#34548a', + }, + success: { + main: '#485e30', + }, + background: { + default: '#d5d6db', + paper: '#d5d6db', + }, + banner: { + info: '#34548a', + error: '#8c4351', + text: '#343b58', + link: '#565a6e', + }, + errorBackground: '#8c4351', + warningBackground: '#8f5e15', + infoBackground: '#343b58', + navigation: { + background: '#343b58', + indicator: '#8f5e15', + color: '#d5d6db', + selectedColor: '#ffffff', + }, }, - secondary: { - main: '#565a6e', - }, - error: { - main: '#8c4351', - }, - warning: { - main: '#8f5e15', - }, - info: { - main: '#34548a', - }, - success: { - main: '#485e30', - }, - background: { - default: '#d5d6db', - paper: '#d5d6db', - }, - banner: { - info: '#34548a', - error: '#8c4351', - text: '#343b58', - link: '#565a6e', - }, - errorBackground: '#8c4351', - warningBackground: '#8f5e15', - infoBackground: '#343b58', - navigation: { - background: '#343b58', - indicator: '#8f5e15', - color: '#d5d6db', - selectedColor: '#ffffff', - }, - }, + }), defaultPageTheme: 'home', fontFamily: 'Comic Sans MS', /* below drives the header colors */ @@ -161,16 +145,182 @@ const myTheme = createTheme({ }); ``` -For a more complete example of a custom theme including Backstage and -Material UI component overrides, see the [Aperture -theme](https://github.com/backstage/demo/blob/master/packages/app/src/theme/aperture.ts) -from the [Backstage demo site](https://demo.backstage.io). +For a more complete example of a custom theme including Backstage and Material UI component overrides, see the [Aperture theme](https://github.com/backstage/demo/blob/master/packages/app/src/theme/aperture.ts) from the [Backstage demo site](https://demo.backstage.io). + +## Custom Typography + +When creating a custom theme you can also customize various aspects of the default typography, here's an example using simplified theme: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + htmlFontSize: 16, + fontFamily: 'Arial, sans-serif', + h1: { + fontSize: 54, + fontWeight: 700, + marginBottom: 10, + }, + h2: { + fontSize: 40, + fontWeight: 700, + marginBottom: 8, + }, + h3: { + fontSize: 32, + fontWeight: 700, + marginBottom: 6, + }, + h4: { + fontWeight: 700, + fontSize: 28, + marginBottom: 6, + }, + h5: { + fontWeight: 700, + fontSize: 24, + marginBottom: 4, + }, + h6: { + fontWeight: 700, + fontSize: 20, + marginBottom: 2, + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +If you wanted to only override a sub-set of the typography setting, for example just `h1` then you would do this: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + defaultTypography, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + ...defaultTypography, + htmlFontSize: 16, + fontFamily: 'Roboto, sans-serif', + h1: { + fontSize: 72, + fontWeight: 700, + marginBottom: 10, + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +## Custom Fonts + +To add custom fonts, you first need to store the font so that it can be imported. We suggest creating the `assets/fonts` directory in your front-end application `src` folder. + +You can then declare the font style following the `@font-face` syntax from [Material UI Typography](https://mui.com/material-ui/customization/typography/). + +After that you can then utilize the `styleOverrides` of `MuiCssBaseline` under components to add a font to the `@font-face` array. + +```ts title="packages/app/src/theme/myTheme.ts" +import MyCustomFont from '../assets/fonts/My-Custom-Font.woff2'; + +const myCustomFont = { + fontFamily: 'My-Custom-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Custom-Font'), + url(${MyCustomFont}) format('woff2'), + `, +}; + +export const myTheme = createUnifiedTheme({ + fontFamily: 'My-Custom-Font', + palette: palettes.light, + components: { + MuiCssBaseline: { + styleOverrides: { + '@font-face': [myCustomFont], + }, + }, + }, +}); +``` + +If you want to utilize different or multiple fonts, then you can set the top level `fontFamily` to what you want for your body, and then override `fontFamily` in `typography` to control fonts for various headings. + +```ts title="packages/app/src/theme/myTheme.ts" +import MyCustomFont from '../assets/fonts/My-Custom-Font.woff2'; +import myAwesomeFont from '../assets/fonts/My-Awesome-Font.woff2'; + +const myCustomFont = { + fontFamily: 'My-Custom-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Custom-Font'), + url(${MyCustomFont}) format('woff2'), + `, +}; + +const myAwesomeFont = { + fontFamily: 'My-Awesome-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Awesome-Font'), + url(${myAwesomeFont}) format('woff2'), + `, +}; + +export const myTheme = createUnifiedTheme({ + fontFamily: 'My-Custom-Font', + components: { + MuiCssBaseline: { + styleOverrides: { + '@font-face': [myCustomFont, myAwesomeFont], + }, + }, + }, + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + ...defaultTypography, + htmlFontSize: 16, + fontFamily: 'My-Custom-Font', + h1: { + fontSize: 72, + fontWeight: 700, + marginBottom: 10, + fontFamily: 'My-Awesome-Font', + }, + }, + defaultPageTheme: 'home', + }), +}); +``` ## Overriding Backstage and Material UI components styles -When creating a custom theme you would be applying different values to -component's css rules that use the theme object. For example, a Backstage -component's styles might look like this: +When creating a custom theme you would be applying different values to component's CSS rules that use the theme object. For example, a Backstage component's styles might look like this: ```tsx const useStyles = makeStyles<BackstageTheme>( @@ -185,83 +335,50 @@ const useStyles = makeStyles<BackstageTheme>( ); ``` -Notice how the `padding` is getting its value from `theme.spacing`, that means -that setting a value for spacing in your custom theme would affect this -component padding property and the same goes for `backgroundImage` which uses -`theme.page.backgroundImage`. However, the `boxShadow` property doesn't -reference any value from the theme, that means that creating a custom theme -wouldn't be enough to alter the `box-shadow` property or to add css rules that -aren't already defined like a margin. For these cases you should also create an -override. +Notice how the `padding` is getting its value from `theme.spacing`, that means that setting a value for spacing in your custom theme would affect this component padding property and the same goes for `backgroundImage` which uses `theme.page.backgroundImage`. However, the `boxShadow` property doesn't reference any value from the theme, that means that creating a custom theme wouldn't be enough to alter the `box-shadow` property or to add css rules that aren't already defined like a margin. For these cases you should also create an override. -```tsx -import { createApp } from '@backstage/core-app-api'; -import { BackstageTheme, lightTheme } from '@backstage/theme'; -/** - * The `@backstage/core-components` package exposes this type that - * contains all Backstage and `material-ui` components that can be - * overridden along with the classes key those components use. - */ -import { BackstageOverrides } from '@backstage/core-components'; +Here's how you would do that: -export const createCustomThemeOverrides = ( - theme: BackstageTheme, -): BackstageOverrides => { - return { +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + }), + fontFamily: 'Comic Sans MS', + defaultPageTheme: 'home', + components: { BackstageHeader: { - header: { - width: 'auto', - margin: '20px', - boxShadow: 'none', - borderBottom: `4px solid ${theme.palette.primary.main}`, + styleOverrides: { + header: ({ theme }) => ({ + width: 'auto', + margin: '20px', + boxShadow: 'none', + borderBottom: `4px solid ${theme.palette.primary.main}`, + }), }, }, - }; -}; - -const customTheme: BackstageTheme = { - ...lightTheme, - overrides: { - // These are the overrides that Backstage applies to `material-ui` components - ...lightTheme.overrides, - // These are your custom overrides, either to `material-ui` or Backstage components. - ...createCustomThemeOverrides(lightTheme), }, -}; - -const app = createApp({ - apis: ..., - plugins: ..., - themes: [{ - id: 'my-theme', - title: 'My Custom Theme', - variant: 'light', - Provider: ({ children }) => ( - <ThemeProvider theme={customTheme}> - <CssBaseline>{children}</CssBaseline> - </ThemeProvider> - ), - }] }); ``` ## Custom Logo -In addition to a custom theme, you can also customize the logo displayed at the -far top left of the site. +In addition to a custom theme, you can also customize the logo displayed at the far top left of the site. -In your frontend app, locate `src/components/Root/` folder. You'll find two -components: +In your frontend app, locate `src/components/Root/` folder. You'll find two components: - `LogoFull.tsx` - A larger logo used when the Sidebar navigation is opened. -- `LogoIcon.tsx` - A smaller logo used when the sidebar navigation is closed. +- `LogoIcon.tsx` - A smaller logo used when the Sidebar navigation is closed. -To replace the images, you can simply replace the relevant code in those -components with raw SVG definitions. +To replace the images, you can simply replace the relevant code in those components with raw SVG definitions. -You can also use another web image format such as PNG by importing it. To do -this, place your new image into a new subdirectory such as -`src/components/Root/logo/my-company-logo.png`, and then add this code: +You can also use another web image format such as PNG by importing it. To do this, place your new image into a new subdirectory such as `src/components/Root/logo/my-company-logo.png`, and then add this code: ```tsx import MyCustomLogoFull from './logo/my-company-logo.png'; @@ -290,8 +407,6 @@ You can change the following [icons](https://github.com/backstage/backstage/blob 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 title="customIcons.tsx" import { SvgIcon, SvgIconProps } from '@material-ui/core'; @@ -408,7 +523,7 @@ For this example we'll show you how you can expand the sidebar with a sub-menu: 3. Then update the `@backstage/core-components` import like this: - ```tsx + ```tsx title="packages/app/src/components/Root/Root.tsx" import { Sidebar, sidebarConfig, @@ -430,7 +545,7 @@ For this example we'll show you how you can expand the sidebar with a sub-menu: 4. Finally replace `<SidebarItem icon={HomeIcon} to="catalog" text="Home" />` with this: - ```tsx + ```tsx title="packages/app/src/components/Root/Root.tsx" <SidebarItem icon={HomeIcon} to="catalog" text="Home"> <SidebarSubmenu title="Catalog"> <SidebarSubmenuItem diff --git a/docs/getting-started/config/authentication.md b/docs/getting-started/config/authentication.md new file mode 100644 index 0000000000..874964696a --- /dev/null +++ b/docs/getting-started/config/authentication.md @@ -0,0 +1,146 @@ +--- +id: authentication +title: Authentication +description: How to set up authentication into your Backstage installation +--- + +Audience: Admins or Developers + +### Setting up authentication + +There are multiple authentication providers available for you to use with +Backstage, feel free to follow +[the instructions for adding authentication](../../auth/index.md). + +For this tutorial we choose to use GitHub, a free service most of you might be +familiar with. For other options, see +[the auth provider documentation](../../auth/github/provider.md#create-an-oauth-app-on-github). + +Go to +[https://github.com/settings/applications/new](https://github.com/settings/applications/new) +to create your OAuth App. The `Homepage URL` should point to Backstage's +frontend, in our tutorial it would be `http://localhost:3000`. The +`Authorization callback URL` will point to the auth backend, which will most +likely be `http://localhost:7007/api/auth/github/handler/frame`. + +![Screenshot of the GitHub OAuth creation page](../../assets/getting-started/gh-oauth.png) + +Take note of the `Client ID` and the `Client Secret`. Open `app-config.yaml`, +and add your `clientId` and `clientSecret` to this file. It should end up +looking like this: + +```yaml title="app-config.yaml" +auth: + # see https://backstage.io/docs/auth/ to learn about auth providers + environment: development + providers: + github: + development: + clientId: YOUR CLIENT ID + clientSecret: YOUR CLIENT SECRET +``` + +### Add sign-in option to the frontend + +Backstage will re-read the configuration. If there's no errors, that's great! We +can continue with the last part of the configuration. The next step is needed to +change the sign-in page, this you actually need to add in the source code. + +Open `packages/app/src/App.tsx` and below the last `import` line, add: + +```typescript title="packages/app/src/App.tsx" +import { githubAuthApiRef } from '@backstage/core-plugin-api'; +import { SignInPage } from '@backstage/core-components'; +``` + +Search for `const app = createApp({` in this file, and below `apis,` add: + +```tsx title="packages/app/src/App.tsx" +components: { + SignInPage: props => ( + <SignInPage + {...props} + auto + provider={{ + id: 'github-auth-provider', + title: 'GitHub', + message: 'Sign in using GitHub', + apiRef: githubAuthApiRef, + }} + /> + ), +}, +``` + +:::note Note + +The default Backstage app comes with a guest Sign In Resolver. This resolver makes all users share a single "guest" identity and is only intended as a minimum requirement to quickly get up and running. You can read more about how [Sign In Resolvers](../../auth/identity-resolver.md#sign-in-resolvers) play a role in creating a [Backstage User Identity](../../auth/identity-resolver.md#backstage-user-identity) for logged in users. + +::: + +Restart Backstage from the terminal, by stopping it with `Control-C`, and starting it with `yarn dev` . You should be welcomed by a login prompt! + +:::note Note + +Sometimes the frontend starts before the backend resulting in errors on the sign in page. Wait for the backend to start and then reload Backstage to proceed. + +::: + +To learn more about Authentication in Backstage, here are some docs you +could read: + +- [Authentication in Backstage](../../auth/index.md) +- [Using organizational data from GitHub](../../integrations/github/org.md) + +### Setting up a GitHub Integration + +The GitHub integration supports loading catalog entities from GitHub or GitHub +Enterprise. Entities can be added to static catalog configuration, registered +with the catalog-import plugin, or discovered from a GitHub organization. Users +and Groups can also be loaded from an organization. While using [GitHub Apps](../../integrations/github/github-apps.md) +might be the best way to set up integrations, for this tutorial you'll use a +Personal Access Token. + +Create your Personal Access Token by opening +[the GitHub token creation page](https://github.com/settings/tokens/new). Use a +name to identify this token and put it in the notes field. Choose a number of +days for expiration. If you have a hard time picking a number, we suggest to go +for 7 days, it's a lucky number. + +![Screenshot of the GitHub Personal Access Token creation page](../../assets/getting-started/gh-pat.png) + +Set the scope to your likings. For this tutorial, selecting `repo` and `workflow` is required as the scaffolding job in this guide configures a GitHub actions workflow for the newly created project. + +For this tutorial, we will be writing the token to `app-config.local.yaml`. This file might not exist for you, so if it doesn't go ahead and create it alongside the `app-config.yaml` at the root of the project. +This file should also be excluded in `.gitignore`, to avoid accidental committing of this file. + +In your `app-config.local.yaml` go ahead and add the following: + +```yaml title="app-config.local.yaml" +integrations: + github: + - host: github.com + token: ghp_urtokendeinfewinfiwebfweb # this should be the token from GitHub +``` + +That's settled. This information will be leveraged by other plugins. + +If you're looking for a more production way to manage this secret, then you can do the following with the token being stored in an environment variable called `GITHUB_TOKEN`. + +```yaml title="app-config.local.yaml" +integrations: + github: + - host: github.com + token: ${GITHUB_TOKEN} # this will use the environment variable GITHUB_TOKEN +``` + +:::note Note + +If you've updated the configuration for your integration, it's likely that the backend will need a restart to apply these changes. To do this, stop the running instance in your terminal with `Control-C`, then start it again with `yarn dev`. Once the backend has restarted, retry the operation. + +::: + +Some helpful links, for if you want to learn more about: + +- [Other available integrations](../../integrations/index.md) +- [Using GitHub Apps instead of a Personal Access Token](../../integrations/github/github-apps.md#docsNav) diff --git a/docs/getting-started/config/database.md b/docs/getting-started/config/database.md new file mode 100644 index 0000000000..a560fe507b --- /dev/null +++ b/docs/getting-started/config/database.md @@ -0,0 +1,139 @@ +--- +id: database +title: Database +description: How to set up PostgreSQL for your Backstage instance. +--- + +Audience: Admins + +### Summary + +This guide walks through how to set up a PostgreSQL database to host your Backstage data. It assumes you've already have a scaffolded Backstage app from following the [Standalone Install](../index.md) guide. + +By the end of this tutorial, you will have a working PostgreSQL database hooked up to your Backstage install. + +### Prerequisites + +This guide assumes a basic understanding of working on a Linux based operating system and have some experience with the terminal, specifically, these commands: `apt-get`, `psql`, `yarn`. + +- Access to a Linux-based operating system, such as Linux, MacOS or + [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) +- An account with elevated rights to install prerequisites on your operating + system +- If the database is not hosted on the same server as the Backstage app, the + PostgreSQL port needs to be accessible (the default is `5432` or `5433`) + +### 1. Install and configure PostgreSQL + +:::tip Already configured your database? + +If you've already installed PostgreSQL and created a schema and user, you can skip to [Step 2](#2-configuring-backstage-pg-client). + +::: + +Let's install PostgreSQL and get it set up for our Backstage app. First, we'll need to actually install the SQL server. + +:::caution + +The command below is for Linux. If you're not on Linux or having issues with package managers, check out [how to install PostgreSQL](https://www.postgresql.org/download/) to help you get sorted. + +::: + +```shell +sudo apt-get install postgresql +``` + +To test if your database is working: + +```shell +sudo -u postgres psql +``` + +You should see a very welcoming message, like: + +```shell +psql (12.9 (Ubuntu 12.9-0ubuntu0.20.04.1)) +Type "help" for help. + +postgres=# +``` + +For this tutorial we're going to use the existing postgres user. The next step is to set the password for this user. You'll want to replace the `<secret>` with a real password in the command below. Keep note of the password you choose here, you'll need it later. + +```shell +postgres=# ALTER USER postgres PASSWORD '<secret>'; +``` + +That's enough database administration to get started. Type `\q`, followed by +pressing the enter key. Then again type `exit` and press enter. Next, you need +to install and configure the client. + +### 2. Configuring Backstage `pg` Client + +Go to the root directory of your freshly installed Backstage +App. Run the following to install the PostgreSQL client into your backend: + +```bash +# From your Backstage root directory +yarn --cwd packages/backend add pg +``` + +Use your favorite editor to open `app-config.yaml` and add your PostgreSQL +configuration in the root directory of your Backstage app using the credentials from the previous steps. + +```yaml title="app-config.yaml" +backend: + database: + # highlight-remove-start + client: better-sqlite3 + connection: ':memory:' + # highlight-remove-end + # highlight-add-start + # config options: https://node-postgres.com/apis/client + client: pg + connection: + host: ${POSTGRES_HOST} + port: ${POSTGRES_PORT} + user: ${POSTGRES_USER} + password: ${POSTGRES_PASSWORD} + # highlight-add-end +``` + +The `${...}` syntax denotes environment variables, specifically, + +1. `POSTGRES_HOST` - The URL/IP to access your PostgreSQL database at. If you've installed PostgreSQL locally, this will likely be 127.0.0.1. +2. `POSTGRES_PORT` - The port to access your PostgreSQL database on. If you've installed PostgreSQL locally, this will be `5432` or `5433`. +3. `POSTGRES_USER` - The user from the SQL command above, `postgres`. +4. `POSTGRES_PASSWORD` - The password you set in the SQL command above. + +When filling these out, you have 2 choices, + +1. Use environment variables when you launch Backstage, either using an environment variable injector like [`dotenv-cli`](https://www.npmjs.com/package/dotenv-cli) or [`env-cmd`](https://www.npmjs.com/package/env-cmd) or loading the variables directly with `EXPORT POSTGRES_...=...`. +2. Replacing the entire `${POSTGRES_...}` string with the value you identified earlier. This is the less secure option, but worth doing if you don't have much experience with environment variables. + +:::danger + +If you opt for the second option of replacing the entire string, take care to not commit your `app-config.yaml` to source control. It may contain passwords that you don't want leaked. + +::: + +[Start the Backstage app](../index.md#2-run-the-backstage-app): + +```shell +yarn dev +``` + +After the Backstage frontend launches, you should notice that nothing has changed. This is a good sign. If everything is setup correctly above, this means that the data is flowing from the demo data files directly into your database! + +We've now made your data persist in your Backstage database. + +## Next Steps + +We recommend you read [Setting up authentication](./authentication.md) next. + +## Further Reading + +If you want to read more about the database configuration, here are some helpful links: + +- [Configuring Plugin Databases](../../tutorials/configuring-plugin-databases.md#privileges) +- [Read more about Knex](http://knexjs.org/), the database wrapper that we use. diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md deleted file mode 100644 index 0c813b1aee..0000000000 --- a/docs/getting-started/configuration.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: configuration -title: Getting Started, configuring Backstage -description: Getting started with your initial Backstage configuration ---- - -This is part two of the Getting Started documentation of Backstage. The steps in -this tutorial assume you've installed Backstage app from the npm repository, -like in the [Getting Started guide](./index.md) and want to configure Backstage. - -At the end of this tutorial, you can expect: - -- Backstage to use a PostgreSQL database -- You'll authenticate using one of the auth providers -- The Backstage GitHub integration to be configured -- You're able to use Software Templates - -### Prerequisites - -- Access to a Linux-based operating system, such as Linux, MacOS or - [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) -- An account with elevated rights to install prerequisites on your operating - system -- If the database is not hosted on the same server as the Backstage app, the - PostgreSQL port needs to be accessible (the default is 5432 or 5433) - -### Install and configure PostgreSQL - -These instructions can be skipped if you already have a PostgreSQL server -installed and created a schema and user. The example below is for Linux, but -luckily there are detailed instructions on how to -[install PostgreSQL](https://www.postgresql.org/download/) to help you get -started. - -```shell -sudo apt-get install postgresql -``` - -Test if your database is working: - -```shell -sudo -u postgres psql -``` - -You should see a very welcoming message, like: - -```shell -psql (12.9 (Ubuntu 12.9-0ubuntu0.20.04.1)) -Type "help" for help. - -postgres=# -``` - -For this tutorial we're going to use the existing postgres user. The next step -is to set the password for this user: - -```shell -postgres=# ALTER USER postgres PASSWORD 'secret'; -``` - -That's enough database administration to get started. Type `\q`, followed by -pressing the enter key. Then again type `exit` and press enter. Next, you need -to install and configure the client. - -Stop Backstage, and go to the root directory of your freshly installed Backstage -App. Use the following commands to start the PostgreSQL client installation: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add pg -``` - -Use your favorite editor to open `app-config.yaml` and add your PostgreSQL -configuration in the root directory of your Backstage app using the credentials -from the previous steps. - -```yaml title="app-config.yaml" -backend: - database: - # highlight-remove-start - client: better-sqlite3 - connection: ':memory:' - # highlight-remove-end - # highlight-add-start - # config options: https://node-postgres.com/apis/client - client: pg - connection: - host: ${POSTGRES_HOST} - port: ${POSTGRES_PORT} - user: ${POSTGRES_USER} - password: ${POSTGRES_PASSWORD} - # https://node-postgres.com/features/ssl - # ssl: - # host is only needed if the connection name differs from the certificate name. - # This is for example the case with CloudSQL. - # host: servername in the certificate - # ca: - # $file: <file-path>/server.pem - # key: - # $file: <file-path>/client.key - # cert: - # $file: <file-path>/client-cert.pem - # highlight-add-end -``` - -You'll use the connection details from the previous step. You can either set the -`POSTGRES_` environment variables prior to launching Backstage, or remove the -`${...}` values and set actual values in this configuration file. - -The default port for PostgreSQL is `5432` or `5433`, and the host name could be -`127.0.0.1` if installed locally. A word of caution: In general, using -connection details in a configuration file is not recommended. - -Start the Backstage app: - -```shell -yarn dev -``` - -After Backstage is completely started you'll notice the catalog is populated -with the information, still coming from the configuration files. If you add a -new component, or register an existing one it will be saved in the database. -Later in this tutorial you'll add a service, and you can test if it's persistent -as advertised. - -If you want to read more about the database configuration, here are some helpful -links: - -- [Configuring Plugin Databases](../tutorials/configuring-plugin-databases.md#privileges) -- [Read more about Knex](http://knexjs.org/), which is the library we use for - the database backend - -### Setting up authentication - -There are multiple authentication providers available for you to use with -Backstage, feel free to follow -[the instructions for adding authentication](../auth/index.md). - -For this tutorial we choose to use GitHub, a free service most of you might be -familiar with. For other options, see -[the auth provider documentation](../auth/github/provider.md#create-an-oauth-app-on-github). - -Go to -[https://github.com/settings/applications/new](https://github.com/settings/applications/new) -to create your OAuth App. The `Homepage URL` should point to Backstage's -frontend, in our tutorial it would be `http://localhost:3000`. The -`Authorization callback URL` will point to the auth backend, which will most -likely be `http://localhost:7007/api/auth/github/handler/frame`. - -![Screenshot of the GitHub OAuth creation page](../assets/getting-started/gh-oauth.png) - -Take note of the `Client ID` and the `Client Secret`. Open `app-config.yaml`, -and add your `clientId` and `clientSecret` to this file. It should end up -looking like this: - -```yaml title="app-config.yaml" -auth: - # see https://backstage.io/docs/auth/ to learn about auth providers - environment: development - providers: - github: - development: - clientId: YOUR CLIENT ID - clientSecret: YOUR CLIENT SECRET -``` - -### Add sign-in option to the frontend - -Backstage will re-read the configuration. If there's no errors, that's great! We -can continue with the last part of the configuration. The next step is needed to -change the sign-in page, this you actually need to add in the source code. - -Open `packages/app/src/App.tsx` and below the last `import` line, add: - -```typescript title="packages/app/src/App.tsx" -import { githubAuthApiRef } from '@backstage/core-plugin-api'; -import { SignInPage } from '@backstage/core-components'; -``` - -Search for `const app = createApp({` in this file, and below `apis,` add: - -```tsx title="packages/app/src/App.tsx" -components: { - SignInPage: props => ( - <SignInPage - {...props} - auto - provider={{ - id: 'github-auth-provider', - title: 'GitHub', - message: 'Sign in using GitHub', - apiRef: githubAuthApiRef, - }} - /> - ), -}, -``` - -> Note: The default Backstage app comes with a guest Sign In Resolver. This resolver makes all users share a single "guest" identity and is only intended as a minimum requirement to quickly get up and running. You can read more about how [Sign In Resolvers](../auth/identity-resolver.md#sign-in-resolvers) play a role in creating a [Backstage User Identity](../auth/identity-resolver.md#backstage-user-identity) for logged in users. - -Restart Backstage from the terminal, by stopping it with `Control-C`, and starting it with `yarn dev` . You should be welcomed by a login prompt! - -> Note: Sometimes the frontend starts before the backend resulting in errors on the sign in page. Wait for the backend to start and then reload Backstage to proceed. - -To learn more about Authentication in Backstage, here are some docs you -could read: - -- [Authentication in Backstage](../auth/index.md) -- [Using organizational data from GitHub](../integrations/github/org.md) - -### Setting up a GitHub Integration - -The GitHub integration supports loading catalog entities from GitHub or GitHub -Enterprise. Entities can be added to static catalog configuration, registered -with the catalog-import plugin, or discovered from a GitHub organization. Users -and Groups can also be loaded from an organization. While using [GitHub Apps](../integrations/github/github-apps.md) -might be the best way to set up integrations, for this tutorial you'll use a -Personal Access Token. - -Create your Personal Access Token by opening -[the GitHub token creation page](https://github.com/settings/tokens/new). Use a -name to identify this token and put it in the notes field. Choose a number of -days for expiration. If you have a hard time picking a number, we suggest to go -for 7 days, it's a lucky number. - -![Screenshot of the GitHub Personal Access Token creation page](../assets/getting-started/gh-pat.png) - -Set the scope to your likings. For this tutorial, selecting `repo` and `workflow` is required as the scaffolding job in this guide configures a GitHub actions workflow for the newly created project. - -For this tutorial, we will be writing the token to `app-config.local.yaml`. This file might not exist for you, so if it doesn't go ahead and create it alongside the `app-config.yaml` at the root of the project. -This file should also be excluded in `.gitignore`, to avoid accidental committing of this file. - -In your `app-config.local.yaml` go ahead and add the following: - -```yaml title="app-config.local.yaml" -integrations: - github: - - host: github.com - token: ghp_urtokendeinfewinfiwebfweb # this should be the token from GitHub -``` - -That's settled. This information will be leveraged by other plugins. - -If you're looking for a more production way to manage this secret, then you can do the following with the token being stored in an environment variable called `GITHUB_TOKEN`. - -```yaml title="app-config.local.yaml" -integrations: - github: - - host: github.com - token: ${GITHUB_TOKEN} # this will use the environment variable GITHUB_TOKEN -``` - -> Note: If you've updated the configuration for your integration, it's likely that the backend will need a restart to apply these changes. To do this, stop the running instance in your terminal with `Control-C`, then start it again with `yarn dev`. Once the backend has restarted, retry the operation. - -Some helpful links, for if you want to learn more about: - -- [Other available integrations](../integrations/index.md) -- [Using GitHub Apps instead of a Personal Access Token](../integrations/github/github-apps.md#docsNav) - -### Explore what we've done so far - -## Login to Backstage and check profile - -Open your Backstage frontend. You should see your login screen if you're not -logged in yet. As soon as you've logged in, go to Settings, you'll see your -profile. Hopefully you'll recognize the profile picture and name on your screen, -otherwise something went terribly wrong. - -## Register an existing component - -- Register a new component, by going to `create` and choose - `Register existing component` - - <!-- todo: Needs zoomable plugin --> - - ![Software template main screen, with a blue button to add an existing component](../assets/getting-started/b-existing-1.png) - -- As URL use `https://github.com/backstage/backstage/blob/master/catalog-info.yaml`. - This is used in our [demo site](https://demo.backstage.io) catalog. - - ![Register a new component wizard, asking for an URL to the existing component YAML file](../assets/getting-started/b-existing-2.png) - -- Hit `Analyze` and review the changes. Apply them if correct. - - ![Register a new component wizard, showing the metadata for the component YAML we use in this tutorial](../assets/getting-started/b-existing-3.png) - -- You should receive a message that your entities have been added. -- If you go back to `Home`, you should be able to find `backstage`. You should be - able to click it and see the details - -## Create a new component using a software template - -> Note: if you're running Backstage with Node 20 or later, you'll need to pass the flag `--no-node-snapshot` to Node in order to -> use the templates feature. -> One way to do this is to specify the `NODE_OPTIONS` environment variable before starting Backstage: -> `export NODE_OPTIONS=--no-node-snapshot` - -- Go to `create` and choose to create a website with the `Example Node.js Template` -- Type in a name, let's use `tutorial` and click `Next Step` - -![Software template deployment input screen asking for a name](../assets/getting-started/b-scaffold-1.png) - -- You should see the following screen: - -![Software template deployment input screen asking for the GitHub username, and name of the new repo to create](../assets/getting-started/b-scaffold-2.png) - -- For host, it should default to github.com -- As owner, type your GitHub username -- For the repository name, type `tutorial`. Go to the next step - -- Review the details of this new service, and press `Create` if you want to - deploy it like this. -- You can follow along with the progress, and as soon as every step is - finished, you can take a look at your new service - -Achievement unlocked. You've set up an installation of the core Backstage App, -made it persistent, and configured it so you are now able to use software -templates. - -Let us know how your experience was: [on discord](https://discord.gg/backstage-687207715902193673), -file issues for any -[feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md) -or -[plugin suggestions](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME), -or -[bugs](https://github.com/backstage/backstage/issues/new?labels=bug&template=bug_template.md) -you have, and feel free to -[contribute](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md)! diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index 724746ca16..2fdb016e7b 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -11,7 +11,7 @@ infrastructure needs - CI/CD, monitoring, auditing, and more. ## Adding existing plugins to your app The following steps assume that you have -[created a Backstage app](./create-an-app.md) and want to add an existing plugin +[created a Backstage app](./index.md) and want to add an existing plugin to it. We are using the @@ -75,7 +75,7 @@ to an entity in the software catalog. ### Adding a plugin page to the Sidebar In a standard Backstage app created with -[@backstage/create-app](./create-an-app.md), the sidebar is managed inside +[@backstage/create-app](./index.md), the sidebar is managed inside `packages/app/src/components/Root/Root.tsx`. The file exports the entire `Sidebar` element of your app, which you can extend with additional entries by adding new `SidebarItem` elements. diff --git a/docs/getting-started/contributors.md b/docs/getting-started/contributors.md deleted file mode 100644 index 9ba338af96..0000000000 --- a/docs/getting-started/contributors.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -id: contributors -title: Contributors -# prettier-ignore -description: Documentation on how to get set up for doing development on the Backstage repository ---- - -Our vision for Backstage is for it to become the trusted standard toolbox (read: UX layer) for the open source infrastructure landscape. Think of it like Kubernetes for developer experience. We realize this is an ambitious goal. We can’t do it alone. - -Therefore we want to create a strong community of contributors -- all working together to create the kind of delightful experience that our developers deserve. - -Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. ❤️ - -To get you started we've put together a [Contributors Guide in the Backstage GitHub repo](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) that has all the information you need. diff --git a/docs/getting-started/create-a-component.md b/docs/getting-started/create-a-component.md new file mode 100644 index 0000000000..29ba99db83 --- /dev/null +++ b/docs/getting-started/create-a-component.md @@ -0,0 +1,43 @@ +--- +id: create-a-component +title: Create a Component +description: Leverage the scaffolder to start creating components with best practices. +--- + +Audience: Developers + +## Summary + +This guide will walk you through how to use Software Templates to create new components with baked in best practices. + +## Prerequisites + +:::note + +If you're running Backstage with Node 20 or later, you'll need to pass the flag `--no-node-snapshot` to Node in order to use the templates feature. One way to do this is to specify the `NODE_OPTIONS` environment variable before starting Backstage: `export NODE_OPTIONS=--no-node-snapshot` + +::: + +You should already have [a standalone app](./index.md). + +You will also need to register the [GitHub Scaffolder Action module](../features/software-templates/builtin-actions.md#installing-action-modules) before moving forward. + +## Creating your component + +- Go to `create` and choose to create a website with the `Example Node.js Template` +- Type in a name, let's use `tutorial` and click `Next Step` + +![Software template deployment input screen asking for a name](../assets/getting-started/b-scaffold-1.png) + +- You should see the following screen: + +![Software template deployment input screen asking for the GitHub username, and name of the new repo to create](../assets/getting-started/b-scaffold-2.png) + +- For host, it should default to github.com +- As owner, type your GitHub username +- For the repository name, type `tutorial`. Go to the next step + +- Review the details of this new service, and press `Create` if you want to + deploy it like this. +- You can follow along with the progress, and as soon as every step is + finished, you can take a look at your new service diff --git a/docs/getting-started/create-an-app.md b/docs/getting-started/create-an-app.md deleted file mode 100644 index 9c6f34dd2c..0000000000 --- a/docs/getting-started/create-an-app.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -id: create-an-app -title: Create an App -description: Documentation on Creating an App ---- - -To get set up quickly with your own Backstage project you can create a Backstage -App. - -A Backstage App is a monorepo setup with `lerna` that includes everything you -need to run Backstage in your own environment. - -If you intend to contribute a plugin, new feature, or bug fix to the Backstage project, you -may want to read the [Contributors](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) guide instead. - -## Create an app - -To create a Backstage app, you will need to have -Node.js [Active LTS Release](https://nodejs.org/en/about/releases/) installed. - -Backstage provides a utility for creating new apps. It guides you through the -initial setup of selecting the name of the app and a database for the backend. -The database options are either SQLite or PostgreSQL, where the latter requires -you to set up a separate database instance. If in doubt, choose SQLite, but -don't worry about the choice, it's easy to change later! Here is a -[tutorial](../tutorials/switching-sqlite-postgres.md) for it. - -The easiest way to run the create app package is with `npx`: - -```bash -npx @backstage/create-app@latest -``` - -This will create a new Backstage App inside the current folder. The name of the -app-folder is the name that was provided when prompted. - -![create app](../assets/getting-started/create-app_output.png) - -Inside that directory, it will generate all the files and folder structure -needed for you to run your app. - -### General folder structure - -Below is a simplified layout of the files and folders generated when creating an -app. - -``` -app -├── app-config.yaml -├── catalog-info.yaml -├── lerna.json -├── package.json -└── packages -   ├── app -   └── backend -``` - -- **app-config.yaml**: Main configuration file for the app. See - [Configuration](https://backstage.io/docs/conf/) for more information. -- **catalog-info.yaml**: Catalog Entities descriptors. See - [Descriptor Format of Catalog Entities](https://backstage.io/docs/features/software-catalog/descriptor-format) - to get started. -- **lerna.json**: Contains information about workspaces and other lerna - configuration needed for the monorepo setup. -- **package.json**: Root package.json for the project. _Note: Be sure that you - don't add any npm dependencies here as they probably should be installed in - the intended workspace rather than in the root._ -- **packages/**: Lerna leaf packages or "workspaces". Everything here is going - to be a separate package, managed by lerna. -- **packages/app/**: An fully functioning Backstage frontend app, that acts as a - good starting point for you to get to know Backstage. -- **packages/backend/**: We include a backend that helps power features such as - [Authentication](https://backstage.io/docs/auth/), - [Software Catalog](https://backstage.io/docs/features/software-catalog/), - [Software Templates](https://backstage.io/docs/features/software-templates/) - and [TechDocs](https://backstage.io/docs/features/techdocs/) - amongst other things. - -### Troubleshooting - -The create app command doesn't always work as expected, this is a collection of -some of the commonly encountered issues and solutions. - -#### Couldn't find any versions for "file-saver" - -You may encounter the following error message: - -```text -Couldn't find any versions for "file-saver" that matches "eligrey-FileSaver.js-1.3.8.tar.gz-art-external" -``` - -This is likely because you have a globally configured npm proxy, which breaks -the installation of the `material-table` dependency. This is a known issue and -being worked on in `material-table`, but for now you can work around it using -the following: - -```bash -NPM_CONFIG_REGISTRY=https://registry.npmjs.org npx @backstage/create-app -``` - -#### Can't find Python executable "python" - -The install process may also fail if no Python installation is available. Python -is commonly available in most systems already, but if it isn't you can head for -example [here](https://www.python.org/downloads/) to install it. - -#### Could not execute command yarn install - -Install Yarn on your system with `npm install --global yarn` or for more details -refer to the [prerequisites](index.md#prerequisites). - -## Run the app - -When the installation is complete you can open the app folder and start the app. - -```bash -cd my-backstage-app -yarn dev -``` - -The `yarn dev` command will run both the frontend and backend as separate -processes (named `[0]` and `[1]`) in the same window. When the command finishes -running, it should open up a browser window displaying your app. If not, you can -open a browser and directly navigate to the frontend at `http://localhost:3000`. - -Now you're free to hack away on your own Backstage installation! - -As you get more experienced with the app, in future you can run just the -frontend with `yarn start` in one window, and the backend with -`yarn start-backend` in a different window. diff --git a/docs/getting-started/homepage.md b/docs/getting-started/homepage.md index 18f23f6607..7e1a2ed909 100644 --- a/docs/getting-started/homepage.md +++ b/docs/getting-started/homepage.md @@ -19,7 +19,7 @@ At the end of this tutorial, you can expect: Before we begin, make sure -- You have created your own standalone Backstage app using [`@backstage/create-app`](index.md#create-your-backstage-app) and not using a fork of the [backstage](https://github.com/backstage/backstage) repository. +- You have created your own standalone Backstage app using [`@backstage/create-app`](./index.md#1-create-your-backstage-app) and not using a fork of the [backstage](https://github.com/backstage/backstage) repository. - You do not have an existing homepage, and by default you are redirected to Software Catalog when you open Backstage. Now, let's get started by installing the home plugin and creating a simple homepage for your Backstage app. diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 11de12feb9..99fdb3d8ed 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -1,23 +1,27 @@ --- id: index -title: Getting Started -description: Documentation on How to get started with Backstage +title: Installing a standalone server +sidebar_label: Introduction +description: How to install Backstage for your own use. --- -For most Backstage installations, installing the standalone app will bring you -the best and most streamlined experience. In this guide you will: +Audience: Developers and Admins -- Deploy Backstage Standalone with npm packages -- Run Backstage Standalone with a SQLite in-memory database and demo content +## Summary -This guide assumes a basic understanding of working on a Linux based operating -system using tools like apt-get, npm, yarn, curl. Docker knowledge is also -helpful for making the best use of your Backstage installation. +This guide walks through how to get started creating your very own Backstage customizable app. This is the first step in evaluating, developing on, or demoing Backstage. -If you are planning to contribute plugins or to the project in general, we advise -you to use the [Contributors](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) guide to do a repository-based installation. +By the end of this guide, you will have a standalone Backstage installation running locally with a `SQLite` database and demo content. To be clear, this is not a production-ready installation, and it does not contain information specific to your organization. -### Prerequisites +:::note Contributors + +If you are planning to contribute a new feature or bug fix to the Backstage project, we advise you to follow the [Contributors](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#get-started) guide instead to do a repository-based installation. + +::: + +## Prerequisites + +This guide assumes a basic understanding of working on a Linux based operating system and have some experience with the terminal, specifically, these commands: `npm`, `yarn`. - Access to a Unix-based operating system, such as Linux, MacOS or [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) @@ -39,57 +43,128 @@ you to use the [Contributors](https://github.com/backstage/backstage/blob/master - `docker` [installation](https://docs.docker.com/engine/install/) - `git` [installation](https://github.com/git-guides/install-git) - If the system is not directly accessible over your network the following ports - need to be opened: 3000, 7007. This is quite uncommon, unless when you're - installing in a container, VM or remote system. + need to be opened: 3000, 7007. This is quite uncommon, unless you're installing in a container, VM or remote system. -### Create your Backstage App +## 1. Create your Backstage App -To install the Backstage Standalone app, we make use of `npx`, a tool to run -Node executables straight from the registry. This tool is part of your Node.js -installation. Running the command below will install Backstage. The wizard will -create a subdirectory inside your current working directory. +:::caution + +The Backstage app we'll be creating will only have demo data until we set up integrations with your specific data sources! + +::: + +To install the Backstage Standalone app, we will make use of `npx`. `npx` is a tool that comes preinstalled with Node.js and lets you run commands straight from `npm` or other registries. Before we jump in to running the command, let's chat about what it does. + +This command will create a new directory with a Backstage app inside. The wizard will ask you for the name of the app. This name will be created as sub directory in your current working directory. + +![create app](../assets/getting-started/create-app-output.png) + +Inside that directory, it will generate all the files and folder structure +needed for you to run your app. + +### General folder structure + +Below is a simplified layout of the files and folders generated when creating an app. + +``` +app +├── app-config.yaml +├── catalog-info.yaml +├── package.json +└── packages +   ├── app +   └── backend +``` + +- **app-config.yaml**: Main configuration file for the app. See + [Configuration](https://backstage.io/docs/conf/) for more information. +- **catalog-info.yaml**: Catalog Entities descriptors. See + [Descriptor Format of Catalog Entities](https://backstage.io/docs/features/software-catalog/descriptor-format) + to get started. +- **package.json**: Root package.json for the project. _Note: Be sure that you + don't add any npm dependencies here as they probably should be installed in + the intended workspace rather than in the root._ +- **packages/**: Lerna leaf packages or "workspaces". Everything here is going + to be a separate package, managed by lerna. +- **packages/app/**: An fully functioning Backstage frontend app, that acts as a + good starting point for you to get to know Backstage. +- **packages/backend/**: We include a backend that helps power features such as + [Authentication](https://backstage.io/docs/auth/), + [Software Catalog](https://backstage.io/docs/features/software-catalog/), + [Software Templates](https://backstage.io/docs/features/software-templates/) + and [TechDocs](https://backstage.io/docs/features/techdocs/) + amongst other things. + +Now, that we know what it does, let's run it! ```bash npx @backstage/create-app@latest ``` -> Note: If this fails on the `yarn install` step, it's likely that you will need to install some additional dependencies which are used to configure `isolated-vm`. You can find out more in their [requirements section](https://github.com/laverdet/isolated-vm#requirements), and then run `yarn install` manually again after you've completed those steps. +This may take a few minutes to fully install everything. Don't stress if the loading seems to be spinning nonstop, there's a lot going on in the background. -The wizard will ask you for the name of the app, which will also be the name of the directory +:::note -![Screenshot of the wizard asking for a name for the app.](../assets/getting-started/wizard.png) +If this fails on the `yarn install` step, it's likely that you will need to install some additional dependencies which are used to configure `isolated-vm`. You can find out more in their [requirements section](https://github.com/laverdet/isolated-vm#requirements), and then run `yarn install` manually again after you've completed those steps. -### Run the Backstage app +::: -When the installation is complete you can go to the application directory and -start the app. The `yarn dev` command will run both the frontend and backend as -separate processes (named `[0]` and `[1]`) in the same window. +## 2. Run the Backstage app + +You Backstage app is fully installed and ready to be run! Now that the installation is complete, you can go to the application directory and start the app using the `yarn dev` command. The `yarn dev` command will run both the frontend and backend as separate processes (named `[0]` and `[1]`) in the same window. ```bash -cd my-backstage-app +cd my-backstage-app # your app name yarn dev ``` ![Screenshot of the command output, with the message web pack compiled successfully](../assets/getting-started/startup.png) -It might take a little while, but as soon as the message -`[0] webpack compiled successfully` appears, you can open a browser and directly -navigate to your freshly installed Backstage portal at `http://localhost:3000`. -You can start exploring the demo immediately. Please note that the in-memory -database will be cleared when you restart the app, so you'll most likely want to -carry on with the database steps. +Here again, there's a small wait for the frontend to start up. Once the frontend is built, your browser window should automatically open. + +:::tip Browser window didn't open + +When you see the message `[0] webpack compiled successfully`, you can navigate directly to `http://localhost:3000` to see your Backstage app. + +::: + +You can start exploring the demo immediately. ![Screenshot of the Backstage portal.](../assets/getting-started/portal.png) -In the next part of this tutorial, you'll learn how to change to a persistent -database, configure authentication, and add your first integration. Continue -with [getting started: Configuring Backstage](configuration.md). +## Recap + +This tutorial walked through how to deploy Backstage using the `npx @backstage/create-app@latest` command. That command created a new directory that holds your new Backstage app. That app is currently only configured for development purposes, as it is using an in-memory database and contains demo data. + +## Next steps + +Choose the correct next steps for your user role, if you're likely to be deploying and managing a Backstage instance for your organization, look through the [Admin](#admin) section. If you're likely to be developing on/for Backstage, take a look through the [Developer](#developer) section. + +### Admin + +- Deploying a production server + - [Deploying with Docker](../deployment/docker.md) + - [Deploying with Kubernetes](../deployment/k8s.md) + - [Deploying with AWS Lightsail](../deployment/backstage-deploy/aws.md) +- Configuring Backstage + - [Database](./config/database.md) + - [Authentication](./config/authentication.md) + - [Plugins](./configure-app-with-plugins.md) + - [Theme](./app-custom-theme.md) + - [Homepage](./homepage.md) + +### Developer + +- Using your Backstage instance + - [Logging into Backstage](./logging-in.md) + - [Register a component](./register-a-component.md) + - [Create a new component](./create-a-component.md) Share your experiences, comments, or suggestions with us: [on discord](https://discord.gg/backstage-687207715902193673), file issues for any [feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md) or -[plugin suggestions](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME), +[plugin suggestions](https://github.com/backstage/community-plugins/issues/new/choose), or [bugs](https://github.com/backstage/backstage/issues/new?labels=bug&template=bug_template.md) you have, and feel free to diff --git a/docs/getting-started/logging-in.md b/docs/getting-started/logging-in.md new file mode 100644 index 0000000000..fef8907e07 --- /dev/null +++ b/docs/getting-started/logging-in.md @@ -0,0 +1,33 @@ +--- +id: logging-in +title: Logging into Backstage +description: Getting up and running with Backstage and your identity provider +--- + +Audience: All + +## Summary + +This guide will provide a quick tutorial on how to log in to your Backstage instance. It should be used as both an introduction to Backstage's authentication system as well as a debugging guide for any issues you may have while logging in. + +## Prerequisites + +You should have already [have a standalone app](./index.md) and completed the Github OAuth app setup defined in [the authentication tutorial](./config/authentication.md). + +## 1. Login to Backstage + +Run your Backstage app with `yarn dev`. Navigate to `http://localhost:3000`. + +If you're not already logged in, you should see a login screen like this, + +To login, you should choose the "Github" provider and click the "Sign in" button. This will redirect you to a Github OAuth page. Verify that the scopes mentioned on that page match the setup you did in [the authentication tutorial](./config/authentication.md). Once you click "Confirm", you will be brought back to the Backstage interface and signed in! + +If you are already logged in, you will be automatically brought to your Backstage instance. + +## 2. Verify that you're logged in + +Once you've logged in, find the "Settings" item in the navigation bar to the left. Click it and you will see your profile. If you see your profile picture and name from Github here, congratulations! You've successfully set up a Github authentication integration. + +<!-- Would like to have more FAQs here for help instead of funneling to Discord --> + +If you don't see your profile picture and name, check that you followed all of the steps in [the authentication tutorial](./config/authentication.md). If you have, search for similar issues on [the Discord server](https://discord.gg/backstage-687207715902193673). diff --git a/docs/getting-started/register-a-component.md b/docs/getting-started/register-a-component.md new file mode 100644 index 0000000000..c935d25807 --- /dev/null +++ b/docs/getting-started/register-a-component.md @@ -0,0 +1,41 @@ +--- +id: register-a-component +title: Registering a Component +description: Start populating your Backstage app with your data. +--- + +Audience: Developers + +## Summary + +This guide will walk you through how to pull Backstage data from other locations manually. There are integrations that will automatically do this for you. + +## Prerequisites + +You should have already [have a standalone app](./index.md). + +## 1. Finding our template + +Register a new component, by going to `create` and choose `Register existing component` + + <!-- todo: Needs zoomable plugin --> + +![Software template main screen, with a blue button to add an existing component](../assets/getting-started/b-existing-1.png) + +## 2. Filling out the template + +For repository URL, use `https://github.com/backstage/backstage/blob/master/catalog-info.yaml`. This is used in our [demo site](https://demo.backstage.io) catalog. + +![Register a new component wizard, asking for an URL to the existing component YAML file](../assets/getting-started/b-existing-2.png) + +Hit `Analyze` and review the changes. + +## 3. Import the entity + +If the changes from `Analyze` are correct, click `Apply`. + +![Register a new component wizard, showing the metadata for the component YAML we use in this tutorial](../assets/getting-started/b-existing-3.png) + +You should receive a message that your entities have been added. + +If you go back to `Home`, you should be able to find `backstage`. You can click it and see the details for this new entity. diff --git a/docs/integrations/aws-codecommit/locations.md b/docs/integrations/aws-codecommit/locations.md new file mode 100644 index 0000000000..05a13e5b21 --- /dev/null +++ b/docs/integrations/aws-codecommit/locations.md @@ -0,0 +1,43 @@ +--- +id: locations +sidebar_label: Locations +title: Amazon Web Services CodeCommit Locations +# prettier-ignore +description: Setting up an integration with Amazon Web Services CodeCommit +--- + +The AWS CodeCommit integration supports loading catalog entities from CodeCommit Repositories. +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 + +To use this integration, add configuration to your `app-config.yaml`: + +```yaml +integrations: + awsCodeCommit: + - accessKeyId: ${AWS_ACCESS_KEY_ID} + secretAccessKey: ${AWS_SECRET_ACCESS_KEY} +``` + +Then make sure the environment variables `AWS_ACCESS_KEY_ID` and +`AWS_SECRET_ACCESS_KEY` are set when you run Backstage. + +Users with multiple AWS accounts may want to use a role for CodeCommit that is +in a different AWS account. Using the `roleArn` parameter as seen below, you can +instruct the AWS CodeCommit reader to assume a role before accessing CodeCommit: + +```yaml +integrations: + awsCodeCommit: + - accessKeyId: ${AWS_ACCESS_KEY_ID} + secretAccessKey: ${AWS_SECRET_ACCESS_KEY} + roleArn: 'arn:aws:iam::xxxxxxxxxxxx:role/example-role' + externalId: 'some-id' # optional +``` + +When no entries are added, the AWS CodeCommit reader will add a default entry that uses the [standard credentials provider chain](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html). diff --git a/docs/integrations/azure/discovery.md b/docs/integrations/azure/discovery.md index 742fbb6076..7fbba5228d 100644 --- a/docs/integrations/azure/discovery.md +++ b/docs/integrations/azure/discovery.md @@ -93,6 +93,8 @@ _Note:_ 5. In the window that appears, enter the name of the branch you want to add and click "Add". 6. The added branch will now appear in the "Searchable branches" list. +It may take some time before the branch is indexed and searchable. + As this provider is not one of the default providers, you will first need to install the Azure catalog plugin: @@ -160,11 +162,14 @@ catalog: # Or use a custom file format and location - type: azure-discovery target: https://dev.azure.com/myorg/myproject/_git/*?path=/src/*/catalog-info.yaml + # And optionally provide a specific branch name using the version parameter + - type: azure-discovery + target: https://dev.azure.com/myorg/myproject/_git/*?path=/catalog-info.yaml&version=GBtopic/catalog-info ``` Note the `azure-discovery` type, as this is not a regular `url` processor. -When using a custom pattern, the target is composed of five parts: +When using a custom pattern, the target is composed of these parts: - The base instance URL, `https://dev.azure.com` in this case - The organization name which is required, `myorg` in this case @@ -175,3 +180,4 @@ When using a custom pattern, the target is composed of five parts: - The path within each repository to find the catalog YAML file. This will usually be `/catalog-info.yaml`, `/src/*/catalog-info.yaml` or a similar variation for catalog files stored in the root directory of each repository. +- The repository branch to scan which is optional, `topic/catalog-info` in this case. If omitted, the repo's default branch will be scanned. The `GB` prefix is required, as this is how Azure DevOps identifies the version as a branch. diff --git a/docs/integrations/bitbucketCloud/discovery.md b/docs/integrations/bitbucketCloud/discovery.md index a7477a2a61..81770afbf8 100644 --- a/docs/integrations/bitbucketCloud/discovery.md +++ b/docs/integrations/bitbucketCloud/discovery.md @@ -24,7 +24,35 @@ package. yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-bitbucket-cloud ``` -### Installation without Events Support +### Installation with New Backend System + +```ts +// optional if you want HTTP endpojnts to receive external events +// backend.add(import('@backstage/plugin-events-backend/alpha')); +// optional if you want to use AWS SQS instead of HTTP endpoints to receive external events +// backend.add(import('@backstage/plugin-events-backend-module-aws-sqs/alpha')); +backend.add( + import('@backstage/plugin-events-backend-module-bitbucket-cloud/alpha'), +); +backend.add( + import('@backstage/plugin-catalog-backend-module-bitbucket-cloud/alpha'), +); +``` + +You need to decide how you want to receive events from external sources like + +- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +Further documentation: + +- <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md> +- <https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md> +- <https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-bitbucket-cloud/README.md> + +### Installation with Legacy Backend System + +#### Installation without Events Support And then add the entity provider to your catalog builder: @@ -49,7 +77,7 @@ export default async function createPlugin( } ``` -### Installation with Events Support +#### Installation with Events Support Please follow the installation instructions at @@ -83,6 +111,7 @@ export default async function createPlugin( env.config, { catalogApi: new CatalogClient({ discoveryApi: env.discovery }), + events: env.events, logger: env.logger, scheduler: env.scheduler, tokenManager: env.tokenManager, diff --git a/docs/integrations/bitbucketServer/discovery.md b/docs/integrations/bitbucketServer/discovery.md index f37732b600..d9fc946460 100644 --- a/docs/integrations/bitbucketServer/discovery.md +++ b/docs/integrations/bitbucketServer/discovery.md @@ -63,6 +63,7 @@ catalog: filters: # optional projectKey: '^apis-.*$' # optional; RegExp repoSlug: '^service-.*$' # optional; RegExp + skipArchivedRepos: true # optional; boolean schedule: # same options as in TaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } @@ -81,6 +82,8 @@ catalog: Regular expression used to filter results based on the project key. - **`repoSlug`** _(optional)_: Regular expression used to filter results based on the repo slug. + - **`skipArchivedRepos`** _(optional)_: + Boolean flag to filter out archived repositories. - **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 461fab8af8..d0721e06f6 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -26,31 +26,35 @@ package. yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-github ``` -And then add the entity provider to your catalog builder: +And then update your backend by adding the following line: -```ts title="packages/backend/src/plugins/catalog.ts" -/* highlight-add-next-line */ -import { GithubEntityProvider } from '@backstage/plugin-catalog-backend-module-github'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - const builder = await CatalogBuilder.create(env); - /* highlight-add-start */ - builder.addEntityProvider( - GithubEntityProvider.fromConfig(env.config, { - logger: env.logger, - scheduler: env.scheduler, - }), - ); - /* highlight-add-end */ - - // .. -} +```ts title="packages/backend/src/index.ts" +// github discovery +backend.add(import('@backstage/plugin-catalog-backend-module-github/alpha')); ``` ## Installation with Events Support +_For the legacy backend system, please read the sub-section below._ + +The catalog module for GitHub comes with events support enabled. +This will make it subscribe to its relevant topics (`github.push`) +and expects these events to be published via the `EventsService`. + +Additionally, you should install the +[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md) +which will route received events from the generic topic `github` to more specific ones +based on the event type (e.g., `github.push`). + +In order to receive Webhook events by GitHub, you have to decide how you want them +to be ingested into Backstage and published to its `EventsService`. +You can decide between the following options (extensible): + +- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +### Legacy Backend System + Please follow the installation instructions at - <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md> @@ -78,10 +82,10 @@ export default async function createPlugin( builder.addProcessor(new ScaffolderEntitiesProcessor()); /* highlight-add-start */ const githubProvider = GithubEntityProvider.fromConfig(env.config, { + events: env.events, logger: env.logger, scheduler: env.scheduler, }); - env.eventBroker.subscribe(githubProvider); builder.addEntityProvider(githubProvider); /* highlight-add-end */ const { processingEngine, router } = await builder.build(); @@ -95,7 +99,7 @@ You can check the official docs to [configure your webhook](https://docs.github. ## 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). +[set up](locations.md) with either a [Personal Access Token](../../getting-started/config/authentication.md) or [GitHub Apps](./github-apps.md). For Personal Access Tokens you should pay attention to the [required scopes](https://backstage.io/docs/integrations/github/locations/#token-scopes), where you will need at least the `repo` scope for reading components. For GitHub Apps you will need to grant it the [required permissions](https://backstage.io/docs/integrations/github/github-apps#app-permissions) instead, where you will need at least the `Contents: Read-only` permissions for reading components. Then you can add a `github` config to the catalog providers configuration: @@ -294,7 +298,7 @@ export default async function createPlugin( ## Configuration To use the discovery processor, 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). +[set up](locations.md) with either a [Personal Access Token](../../getting-started/config/authentication.md) or [GitHub Apps](./github-apps.md). Then you can add a location target to the catalog configuration: diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index 263ceda6c6..974362c125 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -103,6 +103,32 @@ export default async function createPlugin( ## Installation with Events Support +_For the legacy backend system, please read the subsection below._ + +The catalog module `github-org` comes with events support enabled for the `GithubMultiOrgEntityProvider`. +This will make it subscribe to its relevant topics and expects these events to be published via the `EventsService`. + +Topics: + +- `github.installation` +- `github.membership` +- `github.organization` +- `github.team` + +Additionally, you should install the +[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md) +which will route received events from the generic topic `github` to more specific ones +based on the event type (e.g., `github.membership`). + +In order to receive Webhook events by GitHub, you have to decide how you want them +to be ingested into Backstage and published to its `EventsService`. +You can decide between the following options (extensible): + +- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +### Legacy Backend System + Please follow the installation instructions at - <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md> @@ -133,12 +159,12 @@ export default async function createPlugin( id: 'production', orgUrl: 'https://github.com/backstage', logger: env.logger, + events: env.events, schedule: env.scheduler.createScheduledTaskRunner({ frequency: { minutes: 60 }, timeout: { minutes: 15 }, }), }); - env.eventBroker.subscribe(githubOrgProvider); builder.addEntityProvider(githubOrgProvider); /* highlight-add-end */ const { processingEngine, router } = await builder.build(); @@ -169,12 +195,11 @@ export default async function createPlugin( // also omit this option to ingest all orgs accessible by your GitHub integration orgs: ['org-a', 'org-b'], logger: env.logger, + events: env.events, schedule: env.scheduler.createScheduledTaskRunner({ frequency: { minutes: 60 }, timeout: { minutes: 15 }, }), - // Pass in the eventBroker to allow this provider to subscribe to GitHub events - eventBroker: env.eventBroker, }), ); /* highlight-add-end */ diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index d41f4f8de5..91efe05fee 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -11,28 +11,11 @@ entities from GitLab. The entity provider will crawl the GitLab instance and reg entities matching the configured paths. This can be useful as an alternative to static locations or manually adding things to the catalog. -To use the discovery provider, you'll need a GitLab integration -[set up](locations.md) with a `token`. Then you can add a provider config per group -to the catalog configuration: +This provider can also be configured to ingest GitLab data based on [GitLab Webhooks](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#configure-a-webhook-in-gitlab). The events currently accepted are: -```yaml -catalog: - providers: - gitlab: - yourProviderId: - host: gitlab-host # Identifies one of the hosts set up in the integrations - branch: main # Optional. Used to discover on a specific branch - fallbackBranch: main # Optional. Fallback to be used if there is no default branch configured at the Gitlab repository. It is only used, if `branch` is undefined. Uses `master` as default - skipForkedRepos: false # Optional. If the project is a fork, skip repository - group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole instance 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]*`, which means to not filter anything - schedule: # optional; same options as in TaskScheduleDefinition - # supports cron, ISO duration, "human duration" as used in code - frequency: { minutes: 30 } - # supports ISO duration, "human duration" as used in code - timeout: { minutes: 3 } -``` +- [`push`](https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events). + +## Installation As this provider is not one of the default providers, you will first need to install the gitlab catalog plugin: @@ -42,15 +25,93 @@ the gitlab catalog plugin: yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab ``` -Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`: +### Installation with New Backend System + +Then add the following to your backend initialization: + +```ts title="packages/backend/src/index.ts +// optional if you want HTTP endpoints to receive external events +// backend.add(import('@backstage/plugin-events-backend/alpha')); +// optional if you want to use AWS SQS instead of HTTP endpoints to receive external events +// backend.add(import('@backstage/plugin-events-backend-module-aws-sqs/alpha')); +// optional - event router for gitlab. See.: https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md +// backend.add(eventsModuleGitlabEventRouter()); +// optional - token validator for the gitlab topic +// backend.add(eventsModuleGitlabWebhook()); +backend.add(import('@backstage/plugin-catalog-backend-module-gitlab/alpha')); +``` + +You need to decide how you want to receive events from external sources like + +- [via HTTP endpoint](https://github.com/backstage/backstage/blob/master/plugins/events-backend/README.md#configuration) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +Further documentation: + +- [Events Plugin](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [GitLab Module for the Events Plugin](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md) + +### Installation with Legacy Backend System + +#### Installation without Events Support + +Add the segment below to `packages/backend/src/plugins/catalog.ts`: ```ts title="packages/backend/src/plugins/catalog.ts" +/* highlight-add-next-line */ import { GitlabDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab'; -const builder = await CatalogBuilder.create(env); -/** ... other processors and/or providers ... */ -builder.addEntityProvider( - ...GitlabDiscoveryEntityProvider.fromConfig(env.config, { +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + const builder = await CatalogBuilder.create(env); + /* highlight-add-start */ + builder.addEntityProvider( + ...GitlabDiscoveryEntityProvider.fromConfig(env.config, { + logger: env.logger, + // optional: alternatively, use scheduler with schedule defined in app-config.yaml + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // optional: alternatively, use schedule + scheduler: env.scheduler, + }), + ); + /* highlight-add-end */ + // .. +} +``` + +#### Installation with Events Support + +Please follow the installation instructions at + +- [Events Plugin](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [GitLab Module for the Events Plugin](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md) + +Additionally, you need to decide how you want to receive events from external sources like + +- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +Set up your provider + +```ts title="packages/backend/src/plugins/catalog.ts" +import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; +/* highlight-add-next-line */ +import { GitlabDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab'; +import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + const builder = await CatalogBuilder.create(env); + builder.addProcessor(new ScaffolderEntitiesProcessor()); + /* highlight-add-start */ + const gitlabProvider = GitlabDiscoveryEntityProvider.fromConfig(env.config, { logger: env.logger, // optional: alternatively, use scheduler with schedule defined in app-config.yaml schedule: env.scheduler.createScheduledTaskRunner({ @@ -59,19 +120,45 @@ builder.addEntityProvider( }), // optional: alternatively, use schedule scheduler: env.scheduler, - }), -); + }); + env.eventBroker.subscribe(gitlabProvider); + builder.addEntityProvider(gitlabProvider); + /* highlight-add-end */ + const { processingEngine, router } = await builder.build(); + await processingEngine.start(); + return router; +} +``` + +## Configuration + +To use the discovery provider, you'll need a GitLab integration +[set up](locations.md) with a `token`. Then you can add a provider config per group +to the catalog configuration. + +> > NOTE: if you are using the New Backend System, the `schedule` has to be setup in the config, as shown below. + +```yaml title="app-config.yaml" +catalog: + providers: + gitlab: + yourProviderId: + host: gitlab-host # Identifies one of the hosts set up in the integrations + branch: main # Optional. Used to discover on a specific branch + fallbackBranch: master # Optional. Fallback to be used if there is no default branch configured at the Gitlab repository. It is only used, if `branch` is undefined. Uses `master` as default + skipForkedRepos: false # Optional. If the project is a fork, skip repository + group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole instance 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]*`, which means to not filter anything + schedule: # Same options as in TaskScheduleDefinition. Optional for the Legacy Backend System + # supports cron, ISO duration, "human duration" as used in code + frequency: { minutes: 30 } + # supports ISO duration, "human duration" as used in code + timeout: { minutes: 3 } ``` ## Alternative processor -```yaml -catalog: - locations: - - type: gitlab-discovery - target: https://gitlab.com/group/subgroup/blob/main/catalog-info.yaml -``` - As alternative to the entity provider `GitlabDiscoveryEntityProvider` you can still use the `GitLabDiscoveryProcessor`. @@ -109,6 +196,15 @@ export default async function createPlugin( } ``` +And add the following to your app-config.yaml + +```yaml +catalog: + locations: + - type: gitlab-discovery + target: https://gitlab.com/group/subgroup/blob/main/catalog-info.yaml +``` + If you don't want create location object if file with component definition do not exists in project, you can set the `skipReposWithoutExactFileMatch` option. That can reduce count of request to gitlab with 404 status code. If you don't want to create location object if the project is a fork, you can set the `skipForkedRepos` option. diff --git a/docs/integrations/gitlab/org.md b/docs/integrations/gitlab/org.md index f2a483c9d1..14587461e5 100644 --- a/docs/integrations/gitlab/org.md +++ b/docs/integrations/gitlab/org.md @@ -11,34 +11,134 @@ groups -- directly from GitLab. The result is a hierarchy of [`Group`](../../features/software-catalog/descriptor-format.md#kind-group) entities that mirrors your org setup. +This provider can also be configured to ingest GitLab data based on [GitLab System hooks](https://docs.gitlab.com/ee/administration/system_hooks.html). The events currently accepted are: + +- `group_create` +- `group_destroy` +- `group_rename` +- `user_create` +- `user_destroy` +- `user_add_to_group` +- `user_remove_from_group` + +## Installation + As this provider is not one of the default providers, you will first need to install the Gitlab provider plugin: ```bash # From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab +yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab @backstage/plugin-catalog-backend-module-gitlab-org ``` -Then add the plugin to the plugin catalog `packages/backend/src/plugins/catalog.ts`: +### Installation with New Backend System + +Then add the following to your backend initialization: + +```ts title="packages/backend/src/index.ts +// optional if you want HTTP endpoints to receive external events +// backend.add(import('@backstage/plugin-events-backend/alpha')); +// optional if you want to use AWS SQS instead of HTTP endpoints to receive external events +// backend.add(import('@backstage/plugin-events-backend-module-aws-sqs/alpha')); +// optional - event router for gitlab. See.: https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md +// backend.add(eventsModuleGitlabEventRouter()); +// optional - token validator for the gitlab topic +// backend.add(eventsModuleGitlabWebhook()); +backend.add(import('@backstage/plugin-catalog-backend-module-gitlab-org')); +``` + +You need to decide how you want to receive events from external sources like + +- [via HTTP endpoint](https://github.com/backstage/backstage/blob/master/plugins/events-backend/README.md#configuration) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +Further documentation: + +- [GitLab System hooks](https://docs.gitlab.com/ee/administration/system_hooks.html) +- [Events Plugin](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [GitLab Module for the Events Plugin](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md) + +### Installation with Legacy Backend System + +#### Installation without Events Support + +Add the plugin to the plugin catalog `packages/backend/src/plugins/catalog.ts`: ```ts /* packages/backend/src/plugins/catalog.ts */ /* highlight-add-next-line */ import { GitlabOrgDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab'; -const builder = await CatalogBuilder.create(env); -/** ... other processors and/or providers ... */ -/* highlight-add-start */ -builder.addEntityProvider( - ...GitlabOrgDiscoveryEntityProvider.fromConfig(env.config, { - logger: env.logger, - // optional: alternatively, use scheduler with schedule defined in app-config.yaml - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + const builder = await CatalogBuilder.create(env); + /** ... other processors and/or providers ... */ + /* highlight-add-start */ + builder.addEntityProvider( + ...GitlabOrgDiscoveryEntityProvider.fromConfig(env.config, { + logger: env.logger, + // optional: alternatively, use scheduler with schedule defined in app-config.yaml + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // optional: alternatively, use schedule + scheduler: env.scheduler, }), - }), -); -/* highlight-add-end */ + ); + /* highlight-add-end */ + // .. +} +``` + +#### Installation with Events Support + +Please follow the installation instructions at + +- [Events Plugin](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [GitLab Module for the Events Plugin](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md) + +Additionally, you need to decide how you want to receive events from external sources like + +- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) +- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) + +Set up your provider + +```ts title="packages/backend/src/plugins/catalog.ts" +import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; +/* highlight-add-next-line */ +import { GitlabOrgDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab'; +import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise<Router> { + const builder = await CatalogBuilder.create(env); + builder.addProcessor(new ScaffolderEntitiesProcessor()); + /* highlight-add-start */ + const gitlabOrgProvider = GitlabOrgDiscoveryEntityProvider.fromConfig( + env.config, + { + logger: env.logger, + // optional: alternatively, use scheduler with schedule defined in app-config.yaml + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // optional: alternatively, use schedule + scheduler: env.scheduler, + }, + ); + env.eventBroker.subscribe(gitlabOrgProvider); + builder.addEntityProvider(gitlabOrgProvider); + /* highlight-add-end */ + const { processingEngine, router } = await builder.build(); + await processingEngine.start(); + return router; +} ``` ## Configuration @@ -58,6 +158,8 @@ amount of data, this can take significant time and resources. The token used must have the `read_api` scope, and the Users and Groups fetched will be those visible to the account which provisioned the token. +> > NOTE: if you are using the New Backend System, the `schedule` has to be setup in the config, as shown below. + ```yaml catalog: providers: @@ -66,7 +168,13 @@ catalog: host: gitlab.com orgEnabled: true group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only groups under the provided path (which will be stripped) + allowInherited: true # Allow groups to be ingested even if there are no direct members. groupPattern: '[\s\S]*' # Optional. Filters found groups based on provided pattern. Defaults to `[\s\S]*`, which means to not filter anything + schedule: # Same options as in TaskScheduleDefinition. Optional for the Legacy Backend System. + # supports cron, ISO duration, "human duration" as used in code + frequency: { minutes: 30 } + # supports ISO duration, "human duration" as used in code + timeout: { minutes: 3 } ``` ### Groups @@ -107,6 +215,74 @@ catalog: - allow: [Group, User] ``` +### Custom Transformers + +You can inject your own transformation logic to help map GitLab API responses +into Backstage entities. You can do this on the user and group requests to +enable you to do further processing or updates to these entities. + +To enable this you pass a function into the `GitlabOrgDiscoveryEntityProvider`. You can +pass a `UserTransformer`, a `GroupEntitiesTransformer` or a `GroupNameTransformer` (or all of them)). The function is invoked +for each item (user or group) that is returned from the API. + +The example below uses the groupNameTransformer option to change the metadata.name property of the Backstage Group Entity. Instead of populating it with the usual `group.full_path` data that comes from GitLab, it uses the `group.id`: + +```ts +import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { eventsServiceRef } from '@backstage/plugin-events-node'; +import { + GitlabOrgDiscoveryEntityProvider, + /* highlight-add-next-line */ + GroupNameTransformerOptions, +} from '@backstage/plugin-catalog-backend-module-gitlab'; + +/* highlight-add-start */ +function customGroupNameTransformer( + options: GroupNameTransformerOptions, +): string { + return `${options.group.id}`; +} +/* highlight-add-end */ + +/** + * Registers the GitlabDiscoveryEntityProvider with the catalog processing extension point. + * + * @alpha + */ +export const catalogModuleGitlabOrgDiscoveryEntityProvider = + createBackendModule({ + pluginId: 'catalog', + moduleId: 'gitlabOrgDiscoveryEntityProvider', + register(env) { + env.registerInit({ + deps: { + config: coreServices.rootConfig, + catalog: catalogProcessingExtensionPoint, + logger: coreServices.logger, + scheduler: coreServices.scheduler, + events: eventsServiceRef, + }, + async init({ config, catalog, logger, scheduler, events }) { + const gitlabOrgDiscoveryEntityProvider = + GitlabOrgDiscoveryEntityProvider.fromConfig(config, { + /* highlight-add-next-line */ + groupNameTransformer: customGroupNameTransformer, + logger: loggerToWinstonLogger(logger), + events, + scheduler, + }); + catalog.addEntityProvider(gitlabOrgDiscoveryEntityProvider); + }, + }); + }, + }); +``` + ## Troubleshooting **NOTE**: If any groups that are being ingested are empty groups (i.e. do not diff --git a/docs/integrations/ldap/org.md b/docs/integrations/ldap/org.md index 9bc2667aa7..49a2776fb1 100644 --- a/docs/integrations/ldap/org.md +++ b/docs/integrations/ldap/org.md @@ -110,6 +110,18 @@ This is the URL of the targeted server, typically on the form `ldaps://ds.example.net` for SSL enabled servers or `ldap://ds.example.net` without SSL. +#### target.tls.keys + +`keys` in TLS options specifies location of a file, that contains private keys +to establish connection with your LDAP server, in PEM format. See an example +for Google Secure LDAP Service below. + +#### target.tls.certs + +`certs` in TLS options specifies location of a file, that contains certificate +chains to establish connection with your LDAP server, in PEM format. See an +example for Google Secure LDAP Service below. + ### bind The bind block specifies how the plugin should bind (essentially, to @@ -374,3 +386,28 @@ catalog: rules: - allow: [User, Group] ``` + +### Example configurations + +#### Google Secure LDAP Service + +To sync Google Workspace/Cloud Identity organization data to users and groups in backstage, +you must [configure Secure LDAP Service](https://support.google.com/a/answer/9048516) first. + +Once Secure LDAP Service is configured, you can enable TLS options in LDAP configuration, +as mentioned below. `keys` and `certs` specify the location of files that are generated +while configuring Secure LDAP Service above. + +```yaml +ldap: + providers: + - target: ldaps://ldap.google.com:636 + tls: + rejectUnauthorized: false + keys: '/var/secrets/tls/gldap.key' + certs: '/var/secrets/tls/gldap.crt' + users: + # users configuration comes here + groups: + # groups configuration comes here +``` diff --git a/docs/local-dev/cli-commands.md b/docs/local-dev/cli-commands.md index 29cc8635aa..173d616e61 100644 --- a/docs/local-dev/cli-commands.md +++ b/docs/local-dev/cli-commands.md @@ -128,7 +128,7 @@ Build a package for production deployment or publishing Options: --role <name> Run the command with an explicit package role - --minify Minify the generated code. Does not apply to app or backend packages. + --minify Minify the generated code. Does not apply to app package (app is minified by default). --skip-build-dependencies Skip the automatic building of local dependencies. Applies to backend packages only. --stats If bundle stats are available, write them to the output directory. Applies to app packages only. --config <path> Config files to load instead of app-config.yaml. Applies to app packages only. (default: []) diff --git a/docs/openapi/01-getting-started.md b/docs/openapi/01-getting-started.md index 5b9908756f..a9c70c61f8 100644 --- a/docs/openapi/01-getting-started.md +++ b/docs/openapi/01-getting-started.md @@ -33,7 +33,9 @@ This tutorial assumes that you're already familiar with the following, There are two required npm packages before we start, 1. `@backstage/repo-tools`, this package contains all OpenAPI related commands for your plugins. We will be using this throughout the tutorial. -2. `@opticdev/optic`, this package is a dependency of `@backstage/repo-tools` but is only required for OpenAPI related commands. +2. `@useoptic/optic`, this package is a dependency of `@backstage/repo-tools` but is only required for OpenAPI related commands. + +Further, for generating the client a `java` binary has to be available on your PATH. You should install both of the above packages in the _root_ of your workspace. diff --git a/docs/overview/adopting.md b/docs/overview/adopting.md index 15450c995b..5b6c3bcaed 100644 --- a/docs/overview/adopting.md +++ b/docs/overview/adopting.md @@ -156,7 +156,11 @@ Backstage as _the_ platform: Again, any feedback is appreciated. Please use the Edit button at the bottom of the page to make a suggestion. -_**Note!** It might be tempting to try to optimize Backstage usage and +:::note Note + +It might be tempting to try to optimize Backstage usage and "engagement". Even though you want to consolidate all your tooling and technical documentation in Backstage, it is important to remember that time spent in -Backstage is time not spent writing code_ 🙃 +Backstage is time not spent writing code 🙃 + +::: diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index f975baf1e1..2295a3e503 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -61,9 +61,9 @@ The CircleCI plugin is available on `/circleci`. Each plugin is a client side application which mounts itself on the UI. Plugins are written in TypeScript or JavaScript. They each live in their own directory -in `backstage/plugins`. For example, the source code for the lighthouse plugin +in the `plugins` folder. For example, the source code for the catalog plugin is available at -[backstage/plugins/lighthouse](https://github.com/backstage/backstage/tree/master/plugins/lighthouse). +[plugins/catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog). ### Installing plugins diff --git a/docs/overview/versioning-policy.md b/docs/overview/versioning-policy.md index 2ff3588af1..0b1bc975bd 100644 --- a/docs/overview/versioning-policy.md +++ b/docs/overview/versioning-policy.md @@ -34,7 +34,7 @@ their own release cadence and versioning policy. Release cadence: Monthly, specifically on the Tuesday before the third Wednesday of each month. The first release took place in March 2022. -The main release line in versioned with a major, minor and patch version but +The main release line is versioned with a major, minor and patch version but does **not** adhere to [semver](https://semver.org). The version format is `<major>.<minor>.<patch>`, for example `1.3.0`. @@ -68,7 +68,9 @@ The following versioning policy applies to the main-line releases only. done when necessary and with the goal of having minimal impact. When possible, there will always be a deprecation path for a breaking change. - Security fixes **may** be backported to older releases based on the simplicity - of the upgrade path, and the severity of the vulnerability. + of the upgrade path, and the severity of the vulnerability. Vulnerabilities + with a severity of `high` or `critical` will always be backported to releases + for the last 6 months if feasible. - Bug reports are valid only if reproducible in the most recent release, and bug fixes are only applied to the next release. - We will do our best to adhere to this policy. diff --git a/docs/overview/what-is-backstage.md b/docs/overview/what-is-backstage.md index e91b9774d7..ef452d5d15 100644 --- a/docs/overview/what-is-backstage.md +++ b/docs/overview/what-is-backstage.md @@ -2,12 +2,12 @@ id: what-is-backstage title: What is Backstage? # prettier-ignore -description: Backstage is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure +description: Backstage is an open source framework for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure --- ![software-catalog](../assets/header.png) -[Backstage](https://backstage.io/) is an open platform for building developer +[Backstage](https://backstage.io/) is an open source framework for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly — without compromising autonomy. diff --git a/docs/plugins/analytics.md b/docs/plugins/analytics.md index 0673566217..6b1f0a8254 100644 --- a/docs/plugins/analytics.md +++ b/docs/plugins/analytics.md @@ -40,6 +40,7 @@ choice below. | [Google Analytics 4][ga4] | Yes ✅ | | [New Relic Browser][newrelic-browser] | Community ✅ | | [Matomo][matomo] | Community ✅ | +| [Quantum Metric][qm] | Community ✅ | To suggest an integration, please [open an issue][add-tool] for the analytics tool your organization uses. Or jump to [Writing Integrations][int-howto] to @@ -48,6 +49,7 @@ learn how to contribute the integration yourself! [ga]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md [ga4]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga4/README.md [newrelic-browser]: https://github.com/backstage/backstage/blob/master/plugins/analytics-module-newrelic-browser/README.md +[qm]: https://github.com/quantummetric/analytics-module-qm/blob/main/README.md [matomo]: https://github.com/janus-idp/backstage-plugins/blob/main/plugins/analytics-module-matomo/README.md [add-tool]: https://github.com/backstage/backstage/issues/new?assignees=&labels=plugin&template=plugin_template.md&title=%5BAnalytics+Module%5D+THE+ANALYTICS+TOOL+TO+INTEGRATE [int-howto]: #writing-integrations @@ -62,7 +64,7 @@ installed, may be captured. | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `navigate` | The URL of the page that was navigated to. | Fired immediately when route location changes (unless associated plugin/route data is ambiguous, in which case the event is fired after plugin/route data becomes known, immediately before the next event or document unload). The parameters of the current route will be included as attributes. | | `click` | The text of the link that was clicked on. | The `to` attribute represents the URL clicked to. | -| `create` | The `name` of the software being created; if no `name` property is requested by the given Software Template, then the string `new {templateName}` is used instead. | The context holds an `entityRef`, set to the template's ref (e.g. `template:default/template-name`). | +| `create` | The `name` of the software being created; if no `name` property is requested by the given Software Template, then the string `new {templateName}` is used instead. | The context holds an `entityRef`, set to the template's ref (e.g. `template:default/template-name`). The `value` represents the number of minutes saved by running the template (based on the template's `backstage.io/time-saved` annotation, if available). | | `search` | The search term entered in any search bar component. | The context holds `searchTypes`, representing `types` constraining the search. The `value` represents the total number of search results for the query. This may not be visible if the permission framework is being used. | | `discover` | The title of the search result that was clicked on | The `value` is the result rank. A `to` attribute is also provided. | | `not-found` | The path of the resource that resulted in a not found page | Fired by at least TechDocs. | diff --git a/docs/plugins/backend-plugin.md b/docs/plugins/backend-plugin.md index 22d4bae371..7a51cb635c 100644 --- a/docs/plugins/backend-plugin.md +++ b/docs/plugins/backend-plugin.md @@ -41,16 +41,16 @@ standalone mode. You can do a first-light test of your service: ```sh cd plugins/carmen-backend -LEGACY_BACKEND_START=true yarn start +yarn start ``` -> Note: `LEGACY_BACKEND_START=true` is needed while we transition fully to the [New Backend System](../backend-system/index.md). The templates have not been migrated yet; you can track this in [issue 21288](https://github.com/backstage/backstage/issues/21288) +> Note: this documentation assumes you are using the latest version of Backstage and the new backend system. If you are not, please upgrade and migrate your backend using the [Migration Guide](../backend-system/building-backends/08-migrating.md) This will think for a bit, and then say `Listening on :7007`. In a different terminal window, now run ```sh -curl localhost:7007/carmen/health +curl localhost:7007/api/carmen/health ``` This should return `{"status":"ok"}`. Success! Press `Ctrl + c` to stop it @@ -72,38 +72,19 @@ to your backend. yarn --cwd packages/backend add @internal/plugin-carmen-backend@^0.1.0 # Change this to match the plugin's package.json ``` -Create a new file named `packages/backend/src/plugins/carmen.ts`, and add the -following to it +Update `packages/backend/src/index` with the following, ```ts -import { createRouter } from '@internal/plugin-carmen-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; +const backend = createBackend(); -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - // Here is where you will add all of the required initialization code that - // your backend plugin needs to be able to start! - - // The env contains a lot of goodies, but our router currently only - // needs a logger - return await createRouter({ - logger: env.logger, - }); -} -``` - -And finally, wire this into the overall backend router. Edit -`packages/backend/src/index.ts`: - -```ts -import carmen from './plugins/carmen'; // ... -async function main() { - // ... - const carmenEnv = useHotMemoize(module, () => createEnv('carmen')); - apiRouter.use('/carmen', await carmen(carmenEnv)); + +// highlight-add-next-line +backend.add(import('@internal/plugin-carmen-backend')); + +// ... + +backend.start(); ``` After you start the backend (e.g. using `yarn start-backend` from the repo @@ -116,36 +97,123 @@ curl localhost:7007/api/carmen/health This should return `{"status":"ok"}` like before. Success! +## Secure by Default + +In 1.25, Backstage started moving to a secure by default model for plugins. This means that network requests to plugins will by default not allow unauthenticated users. Let's take a deeper look at the above curl request which should allow unauthenticated access. + +The actual endpoint that is being called is defined in + +```ts title="plugins/carmen-backend/src/service/router.ts" +export async function createRouter( + options: RouterOptions, +): Promise<express.Router> { + // ... + + // highlight-start + router.get('/health', (_, response) => { + logger.info('PONG!'); + response.json({ status: 'ok' }); + }); + // highlight-end + + // ... + return router; +} +``` + +You'll notice that there is no authentication mechanism defined here, just the route name and response data. That's because the authentication is handled in your plugin definition, + +```ts title="plugins/carmen-backend/src/plugin.ts" +httpRouter.use( + await createRouter({ + logger, + }), +); +// highlight-start +httpRouter.addAuthPolicy({ + path: '/health', + allow: 'unauthenticated', +}); +// highlight-end +``` + +This allows requests to this plugin's `/health` endpoint to go through unauthenticated! + +## Using Dependencies + +In the new backend, dependencies are defined statically during registration and then "injected" during initialization. Here's an example of what this looks like, + +```ts title="plugins/carmen-backend/src/plugin.ts" + +// highlight-start +deps: { + httpRouter: coreServices.httpRouter, + logger: coreServices.logger, +}, +// highlight-end +// And then you can use them through the options property! +// highlight-next-line +async init({ httpRouter, logger }) { + // ... +}, + +``` + +You can add your own dependencies by adding a named item to the `deps` parameter: + +```ts +deps: { + // highlight-next-line + myDependency: coreServices.rootConfig, +}, +``` + +And then you can access it by referencing it in the `init` block of your plugin definition, + +```ts +async init({ myDependency }) { + // .. +} +``` + +And then you're free to call it and pass it into your router as needed. + +Backstage provides a bunch of `coreServices` out of box, see the more in depth docs [here](../backend-system/core-services/01-index.md). + ## Making Use of a Database The Backstage backend comes with a builtin facility for SQL database access. Most plugins that have persistence needs will choose to make use of this facility, so that Backstage operators can manage database needs uniformly. -As part of the environment object that is passed to your `createPlugin` -function, there is a `database` field. You can use that to get a -[Knex](http://knexjs.org/) connection object. - -```ts -// in packages/backend/src/plugins/carmen.ts -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - const db: Knex<any, unknown[]> = await env.database.getClient(); +You can access this by adding a dependency on the `coreServices.database` service. +That will give you a [Knex](http://knexjs.org/) connection object. +```ts title="plugins/carmen-backend/src/plugin.ts" +deps: { + // ... + // highlight-next-line + database: coreServices.database, +}, +async init({ + // highlight-next-line + database, +}) { // You will then pass this client into your actual plugin implementation // code, maybe similar to the following: - const model = new CarmenDatabaseModel(db); - return await createRouter({ - model: model, - logger: env.logger, - }); + const model = new CarmenDatabaseModel(database); + httpRouter.use( + await createRouter({ + // highlight-next-line + model, + logger, + }), + ); } ``` -You may note that the `getClient` call has no parameters. This is because all -plugin database needs are configured under the `backend.database` config key of -your `app-config.yaml`. The framework may even make sure behind the scenes that +All plugin database needs are configured under the `backend.database` config key +of your `app-config.yaml`. The framework may even make sure behind the scenes that the logical database is created automatically if it doesn't exist, based on rules that the Backstage operator decides on. @@ -159,37 +227,67 @@ database.. ## Making Use of the User's Identity -The Backstage backend comes with a facility for retrieving the identity of the -logged in user. +The Backstage backend also offers a core service to access the user's identity. You can access it through the `coreServices.httpAuth` and `coreServices.userInfo` dependencies. -As part of the environment object that is passed to your `createPlugin` -function, there is a `identity` field. You can use that to get an identity -from the request. - -```ts -// in packages/backend/src/plugins/carmen.ts -export default async function createPlugin( - env: PluginEnvironment, -): Promise<Router> { - return await createRouter({ - model: model, - logger: env.logger, - identity: env.identity, - }); +```ts title="plugins/carmen-backend/src/plugin.ts" +deps: { + // highlight-start + httpAuth: coreServices.httpAuth, + userInfo: coreServices.userInfo, + // highlight-end +}, +async init({ + // highlight-start + httpAuth, + userInfo, + // highlight-end +}) { + httpRouter.use( + await createRouter({ + // highlight-start + httpAuth, + userInfo, + // highlight-end + logger, + }), + ); } ``` The plugin can then extract the identity from the request. ```ts +export interface RouterOptions { + logger: LoggerService; + // highlight-start + userInfo: UserInfoService; + httpAuth: HttpAuthService; + // highlight-end +} + export async function createRouter( options: RouterOptions, ): Promise<express.Router> { - const router = Router(); - const { identity } = options; + const { userInfo, httpAuth } = options; - router.post('/example', async (req, res) => { - const userIdentity = await identity.getIdentity({ request: req }); - ... + router.post('/me', async (req, res) => { + const credentials = await httpAuth.credentials(req, { + // This rejects request from non-users. Only use this if your plugin needs to access the + // user identity, most of the time it's enough to just call `httpAuth.credentials(req)` + allow: ['user'], + }); + + const userInfo = await userInfo.getUserInfo(credentials); + + res.json({ + // The catalog entity ref of the user. + userEntityRef: userInfo.userEntityRef, + + // The list of entities that this user or any teams this user is a part of owns. + ownershipEntityRefs: userInfo.ownershipEntityRefs, + }); }); + + // ... +} ``` diff --git a/docs/plugins/call-existing-api.md b/docs/plugins/call-existing-api.md index da76fa8434..065427b9ee 100644 --- a/docs/plugins/call-existing-api.md +++ b/docs/plugins/call-existing-api.md @@ -137,9 +137,8 @@ router.use('/summary', async (req, res) => { ``` For a more detailed example, see -[the lighthouse plugin](https://github.com/backstage/backstage/tree/master/plugins/lighthouse) -that stores some state in a database and adds new capabilities to the underlying -API. +[the user-settings plugin backend](https://github.com/backstage/backstage/tree/master/plugins/user-settings-backend) +that stores some state in a database and surfaces an API for the frontend plugin to use. Internally at Spotify, this has been a fairly popular choice for different reasons. Commonly, the backend has been used as a caching and data massaging diff --git a/docs/plugins/index.md b/docs/plugins/index.md index 755c1b8a7d..94de3bc482 100644 --- a/docs/plugins/index.md +++ b/docs/plugins/index.md @@ -22,7 +22,7 @@ To create a plugin, follow the steps outlined [here](create-a-plugin.md). If you start developing a plugin that you aim to release as open source, we suggest that you create a -[new Issue](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME). +[new Issue in the community plugins repo](https://github.com/backstage/community-plugins/issues/new/choose). This helps the community know what plugins are in development. You can also use this process if you have an idea for a good plugin but you hope diff --git a/docs/plugins/internationalization.md b/docs/plugins/internationalization.md index fd12452cff..0f48e35a25 100644 --- a/docs/plugins/internationalization.md +++ b/docs/plugins/internationalization.md @@ -30,7 +30,7 @@ export const myPluginTranslationRef = createTranslationRef({ }); ``` -And the using this messages in your components like: +And then use these messages in your components like: ```tsx import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; @@ -46,7 +46,7 @@ return ( ); ``` -You will see how the initial dictionary structure and nesting gets converted into dot notation, so we encourage `camelCase` in key names and lean on the nesting structure to separate keys. +You will see how the initial dictionary structure and nesting get converted into dot notation, so we encourage `camelCase` in key names and lean on the nesting structure to separate keys. ### Guidelines for `i18n` messages and keys @@ -149,26 +149,53 @@ export const myPluginTranslationRef = createTranslationRef({ ## For an application developer overwrite plugin messages +Step 1: Create translation resources + +```ts +// packages/app/src/translations/userSettings.ts + +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +export const userSettingsMessages = createTranslationResource({ + ref: userSettingsTranslationRef, + translations: { + zh: () => + Promise.resolve({ + default: { + 'languageToggle.title': '语言', + 'languageToggle.select': '选择{{language}}', + 'languageToggle.description': '切换语言', + 'themeToggle.title': '主题', + 'themeToggle.description': '切换主题', + 'themeToggle.select': '选择{{theme}}', + 'themeToggle.selectAuto': '选择自动主题', + 'themeToggle.names.auto': '自动', + 'themeToggle.names.dark': '暗黑', + 'themeToggle.names.light': '明亮', + }, + }), + }, +}); +``` + +You should change `zh` under the translations object to your local language. + +Step 2: Config translations in `packages/app/src/App.tsx` + In an app you can both override the default messages, as well as register translations for additional languages: ```diff ++ import { userSettingsMessages } from './translations/userSettings'; + const app = createApp({ + __experimentalTranslations: { + availableLanguages: ['en', 'zh'], -+ resources: [ -+ createTranslationMessages({ -+ ref: myPluginTranslationRef, -+ messages: { -+ 'indexPage.createButtonTitle': 'Create new entity', -+ }, -+ }), -+ createTranslationResource({ -+ ref: myPluginTranslationRef, -+ messages: { -+ zh: () => import('./translations/zh'), -+ }, -+ }), -+ ], ++ resources: [userSettingsMessages], + }, }) ``` + +Step 3: Check everything is working correctly + +Go to `Settings` page, you should see change language buttons just under change theme buttons. And then switch language, you should see language had changed diff --git a/docs/plugins/testing.md b/docs/plugins/testing.md index 3a7da2d410..bc212a2581 100644 --- a/docs/plugins/testing.md +++ b/docs/plugins/testing.md @@ -26,10 +26,14 @@ To run both `MyComponent.test.tsx` and `MyControl.test.tsx` suite of tests: yarn test MyCo -Note: if `console.logs` are not appearing, run only the individual test you are +:::note Note + +if `console.log`s are not appearing, run only the individual test you are working on. [This is a bug in Jest](https://github.com/facebook/jest/issues/2441). +::: + ## Naming Test Files Tests should be named `[filename].test.ts`, or `[filename].test.tsx` if it contains JSX (as is the case for a lot of React tests, e.g. components). diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 8266dd02f7..6db16443e2 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -27,7 +27,7 @@ A type of [OAuth flow](#oauth) used by confidential and public clients to get an ## Backstage -1. A platform for creating and deploying [developer portals](#developer-portal), originally created at Spotify. Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). +1. An open source framework for creating and deploying [developer portals](#developer-portal), originally created at Spotify. Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). 2. [The Backstage Framework](#backstage-framework). @@ -105,7 +105,7 @@ An executable or package file with all of the necessary information required to ## Developer Portal -A centralized system comprising a user interface and database used to facilitate and document all the software projects within an organization. Backstage is both a developer portal and (by virtue of being based on plugins) a platform for creating developer portals. +A centralized system comprising a user interface and database used to facilitate and document all the software projects within an organization. Backstage is both a developer portal and (by virtue of being based on plugins) a framework for creating developer portals. ## Document (search plugin) diff --git a/docs/releases/v1.1.0.md b/docs/releases/v1.1.0.md index daf31a536f..f484cc5b57 100644 --- a/docs/releases/v1.1.0.md +++ b/docs/releases/v1.1.0.md @@ -38,11 +38,11 @@ The permission related packages received a number of **BREAKING** changes. Among ### Stack Overflow -There’s a new Stack Overflow [frontend](https://github.com/backstage/backstage/tree/master/plugins/stack-overflow) plugin with a corresponding [backend](https://github.com/backstage/backstage/tree/master/plugins/stack-overflow-backend]! +There’s a new Stack Overflow [frontend](https://github.com/backstage/backstage/tree/v1.1.0/plugins/stack-overflow) plugin with a corresponding [backend](https://github.com/backstage/backstage/tree/v1.1.0/plugins/stack-overflow-backend)! ### Misc -- The [CI/CD Statistics plugin](https://github.com/backstage/backstage/tree/master/plugins/cicd-statistics) now has GitLab support, through the new [GitLab module](https://github.com/backstage/backstage/tree/master/plugins/cicd-statistics-module-gitlab). Thanks [@djamaile](https://github.com/djamaile)! ([#10140](https://github.com/backstage/backstage/pull/10140)) +- The [CI/CD Statistics plugin](https://github.com/backstage/backstage/tree/v1.1.0/plugins/cicd-statistics) now has GitLab support, through the new [GitLab module](https://github.com/backstage/backstage/tree/v1.1.0/plugins/cicd-statistics-module-gitlab). Thanks [@djamaile](https://github.com/djamaile)! ([#10140](https://github.com/backstage/backstage/pull/10140)) - The catalog [AWS module](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-aws) added a new `AwsS3EntityProvider` as a replacement for the `AwsS3DiscoveryProcessor`. Thanks [@pjungermann](https://github.com/pjungermann)! ([#10480](https://github.com/backstage/backstage/pull/10480)) diff --git a/docs/releases/v1.10.0-changelog.md b/docs/releases/v1.10.0-changelog.md index db3955bb3f..486ed2d268 100644 --- a/docs/releases/v1.10.0-changelog.md +++ b/docs/releases/v1.10.0-changelog.md @@ -253,7 +253,7 @@ - e4469d0ec1: The ADR plugin can now work with sites other than GitHub. Expanded the ADR backend plugin to provide endpoints to facilitate this. - **BREAKING** The ADR plugin now requires the `@backstage/plugin-adr-backend` plugin to be installed by using the `createRouter` method to add into your `backend`. You read more in the [install instructions](https://github.com/backstage/backstage/blob/master/plugins/adr-backend/README.md#install) + **BREAKING** The ADR plugin now requires the `@backstage/plugin-adr-backend` plugin to be installed by using the `createRouter` method to add into your `backend`. You read more in the [install instructions](https://github.com/backstage/backstage/blob/v1.10.0/plugins/adr-backend/README.md#install) ### Patch Changes @@ -809,7 +809,7 @@ ### Patch Changes -- aa17643a06: This plugin now exports a `createRouter` method which uses `UrlReaders` to make requests to your SCM. Please make sure you read the [install instructions](https://github.com/backstage/backstage/blob/master/plugins/adr-backend/README.md#install) +- aa17643a06: This plugin now exports a `createRouter` method which uses `UrlReaders` to make requests to your SCM. Please make sure you read the [install instructions](https://github.com/backstage/backstage/blob/v1.10.0/plugins/adr-backend/README.md#install) - 21ffbdd5ee: Clarify that default ADR parsers support MADR specification v2.x - Updated dependencies - @backstage/backend-common@0.18.0 diff --git a/docs/releases/v1.11.0-changelog.md b/docs/releases/v1.11.0-changelog.md index 42f9e9720b..f6c7901cb6 100644 --- a/docs/releases/v1.11.0-changelog.md +++ b/docs/releases/v1.11.0-changelog.md @@ -402,7 +402,7 @@ - d1fb4b7bf1: Add the new GraphQL Voyager tool as a plugin for backstage, expose necessary API and components needed for it. - For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager/README.md) of the plugin. + For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/v1.11.0/plugins/graphql-voyager/README.md) of the plugin. ### Patch Changes @@ -538,7 +538,7 @@ - 44412375bb: Created a new plugin `@backstage/plugin-microsoft-calendar` to display events from a Microsoft Calendar. - please refer to the [README.md](https://github.com/backstage/backstage/blob/master/plugins/microsoft-calendar/README.md) for step-by-step instructions to setup the plugin in your Backstage instance. + please refer to the [README.md](https://github.com/backstage/backstage/blob/v1.11.0/plugins/microsoft-calendar/README.md) for step-by-step instructions to setup the plugin in your Backstage instance. ### Patch Changes diff --git a/docs/releases/v1.11.0-next.2-changelog.md b/docs/releases/v1.11.0-next.2-changelog.md index 65f6622921..089f6d8853 100644 --- a/docs/releases/v1.11.0-next.2-changelog.md +++ b/docs/releases/v1.11.0-next.2-changelog.md @@ -156,7 +156,7 @@ - d1fb4b7bf1: Add the new GraphQL Voyager tool as a plugin for backstage, expose necessary API and components needed for it. - For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager/README.md) of the plugin. + For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/v1.11.0-next.2/plugins/graphql-voyager/README.md) of the plugin. ### Patch Changes diff --git a/docs/releases/v1.11.0.md b/docs/releases/v1.11.0.md index 1afed5fbb6..ad2118c754 100644 --- a/docs/releases/v1.11.0.md +++ b/docs/releases/v1.11.0.md @@ -41,37 +41,37 @@ We created a separate ESlint plugin package that houses some rules that are help ### New plugin: Entity Feedback -A plugin that allows users to rate the quality of entities in your Backstage catalog. Allowing your users to rate entities brings them into the feedback loop that can help notify owners if something is wrong with their entity (i.e. taking inspiration from the feedback model of TechDocs). Check out [the README](https://github.com/backstage/backstage/tree/master/plugins/entity-feedback)! +A plugin that allows users to rate the quality of entities in your Backstage catalog. Allowing your users to rate entities brings them into the feedback loop that can help notify owners if something is wrong with their entity (i.e. taking inspiration from the feedback model of TechDocs). Check out [the README](https://github.com/backstage/backstage/tree/v1.11.0/plugins/entity-feedback)! Contributed by [@kuangp](https://github.com/kuangp) in [#15881](https://github.com/backstage/backstage/pull/15881) ### New plugin: Entity Validator -This plugin helps users create and edit their YAML definitions of entities, with live validation. It leverages the actual catalog backend for checks, so that you can submit catalog info file changes that fit your particular organization with greater confidence. Installation instructions and details are in [the README](https://github.com/backstage/backstage/tree/master/plugins/entity-validation). +This plugin helps users create and edit their YAML definitions of entities, with live validation. It leverages the actual catalog backend for checks, so that you can submit catalog info file changes that fit your particular organization with greater confidence. Installation instructions and details are in [the README](https://github.com/backstage/backstage/tree/v1.11.0/plugins/entity-validation). Contributed by [@ivangonzalezacuna](https://github.com/ivangonzalezacuna) in [#16050](https://github.com/backstage/backstage/pull/16050) ### New Plugin: Microsoft Calendar -This plugin lets you show your MS calendars directly in Backstage. More information and installation instructions in [the README](https://github.com/backstage/backstage/tree/master/plugins/microsoft-calendar)! +This plugin lets you show your MS calendars directly in Backstage. More information and installation instructions in [the README](https://github.com/backstage/backstage/tree/v1.11.0/plugins/microsoft-calendar)! Contributed by [@Abhay-soni-developer](https://github.com/Abhay-soni-developer) in [#16101](https://github.com/backstage/backstage/pull/16101) ### New plugin: GraphQL Voyager -This nifty plugin presents a graph structure of your entire GraphQL API. Check out [its README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager) for a screenshot and instructions on installing it. +This nifty plugin presents a graph structure of your entire GraphQL API. Check out [its README](https://github.com/backstage/backstage/tree/v1.11.0/plugins/graphql-voyager) for a screenshot and instructions on installing it. Contributed by [@MitchWijt](https://github.com/MitchWijt) in [#16015](https://github.com/backstage/backstage/pull/16015) ### New plugin: Linguist -This plugin lets you see a nice visual representation of the breakdown of languages that a component’s repository is using, similar to the repository information that e.g. GitHub presents. More about that [in the README](https://github.com/backstage/backstage/tree/master/plugins/linguist)! +This plugin lets you see a nice visual representation of the breakdown of languages that a component’s repository is using, similar to the repository information that e.g. GitHub presents. More about that [in the README](https://github.com/backstage/backstage/tree/v1.11.0/plugins/linguist)! Contributed by [@ahhhndre](https://github.com/ahhhndre) in [#14718](https://github.com/backstage/backstage/pull/14718) ### Lighthouse Backend -The [Lighthouse plugin](https://github.com/backstage/backstage/tree/master/plugins/lighthouse) now has a [corresponding backend](https://github.com/backstage/backstage/tree/master/plugins/lighthouse-backend). This allows you to conveniently schedule audits from within Backstage. +The [Lighthouse plugin](https://github.com/backstage/backstage/tree/v1.11.0/plugins/lighthouse) now has a [corresponding backend](https://github.com/backstage/backstage/tree/v1.11.0/plugins/lighthouse-backend). This allows you to conveniently schedule audits from within Backstage. Note that as part of this, a `@backstage/plugin-lighthouse-common` package was also created, and types that were common to the frontend and backend were moved there. This means that if you were explicitly importing types from the frontend package, you may see compilation errors and need to add a dependency on the new common package and point your imports there instead. diff --git a/docs/releases/v1.12.0-changelog.md b/docs/releases/v1.12.0-changelog.md index 7a8b52e33b..df25020aee 100644 --- a/docs/releases/v1.12.0-changelog.md +++ b/docs/releases/v1.12.0-changelog.md @@ -449,7 +449,7 @@ ### Minor Changes -- f3a15259e91: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) +- f3a15259e91: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/v1.12.0/plugins/stackstorm/README.md) ### Patch Changes diff --git a/docs/releases/v1.12.0-next.0-changelog.md b/docs/releases/v1.12.0-next.0-changelog.md index b7f71b53e6..7732ebf22d 100644 --- a/docs/releases/v1.12.0-next.0-changelog.md +++ b/docs/releases/v1.12.0-next.0-changelog.md @@ -125,7 +125,7 @@ ### Minor Changes -- f3a15259e9: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) +- f3a15259e9: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/v1.12.0-next.0/plugins/stackstorm/README.md) ### Patch Changes diff --git a/docs/releases/v1.13.0-changelog.md b/docs/releases/v1.13.0-changelog.md index 506800eb38..52f14bea1b 100644 --- a/docs/releases/v1.13.0-changelog.md +++ b/docs/releases/v1.13.0-changelog.md @@ -509,7 +509,7 @@ ### Minor Changes -- 70a036e940e: Initial version of [PuppetDB plugin](https://github.com/backstage/backstage/blob/master/plugins/puppetdb/README.md). +- 70a036e940e: Initial version of [PuppetDB plugin](https://github.com/backstage/backstage/blob/v1.13.0/plugins/puppetdb/README.md). ### Patch Changes diff --git a/docs/releases/v1.14.0-changelog.md b/docs/releases/v1.14.0-changelog.md index ff43be94a4..f207ab569c 100644 --- a/docs/releases/v1.14.0-changelog.md +++ b/docs/releases/v1.14.0-changelog.md @@ -2356,7 +2356,7 @@ - The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. - As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details + As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/v1.14.0/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details - Updated dependencies - @backstage/theme@0.3.0 diff --git a/docs/releases/v1.14.0-next.1-changelog.md b/docs/releases/v1.14.0-next.1-changelog.md index 2f91cb402e..0fa508bbd6 100644 --- a/docs/releases/v1.14.0-next.1-changelog.md +++ b/docs/releases/v1.14.0-next.1-changelog.md @@ -1502,7 +1502,7 @@ - The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. - As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details + As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/v1.14.0-next.1/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details - Updated dependencies - @backstage/core-components@0.13.1-next.0 diff --git a/docs/releases/v1.17.0-changelog.md b/docs/releases/v1.17.0-changelog.md index a67226ca9e..700ab6ccea 100644 --- a/docs/releases/v1.17.0-changelog.md +++ b/docs/releases/v1.17.0-changelog.md @@ -773,7 +773,7 @@ ### Patch Changes -- ec7357258853: Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-newrelic-browser) for more details! +- ec7357258853: Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/v1.17.0/plugins/analytics-module-newrelic-browser) for more details! - Updated dependencies - @backstage/core-components@0.13.4 - @backstage/core-plugin-api@1.5.3 diff --git a/docs/releases/v1.17.0-next.0-changelog.md b/docs/releases/v1.17.0-next.0-changelog.md index 2d343696de..2cd71285ce 100644 --- a/docs/releases/v1.17.0-next.0-changelog.md +++ b/docs/releases/v1.17.0-next.0-changelog.md @@ -435,7 +435,7 @@ ### Patch Changes -- ec7357258853: Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-newrelic-browser) for more details! +- ec7357258853: Introduced the New Relic Browser analytics module. Check out the plugins [README.md](https://github.com/backstage/backstage/tree/v1.17.0-next.0/plugins/analytics-module-newrelic-browser) for more details! - Updated dependencies - @backstage/core-components@0.13.4-next.0 - @backstage/core-plugin-api@1.5.3 diff --git a/docs/releases/v1.18.0.md b/docs/releases/v1.18.0.md index cae0301fd5..eb42a5f58a 100644 --- a/docs/releases/v1.18.0.md +++ b/docs/releases/v1.18.0.md @@ -34,7 +34,7 @@ Contributed by [@sbarrypoppulo](https://github.com/sbarrypoppulo) in [#18889](ht ### New plugin: OpenCost -There’s a new [OpenCost](https://www.opencost.io/) plugin that provides a port of the latest OpenCost UI to Backstage. The [plugin's README](https://github.com/backstage/backstage/blob/master/plugins/opencost/README.md) covers installation and configuration. +There’s a new [OpenCost](https://www.opencost.io/) plugin that provides a port of the latest OpenCost UI to Backstage. The [plugin's README](https://github.com/backstage/backstage/blob/v1.18.0/plugins/opencost/README.md) covers installation and configuration. Contributed by [@mattray](https://github.com/mattray) in [#18383](https://github.com/backstage/backstage/pull/18383) diff --git a/docs/releases/v1.23.0-changelog.md b/docs/releases/v1.23.0-changelog.md new file mode 100644 index 0000000000..ef87a5955a --- /dev/null +++ b/docs/releases/v1.23.0-changelog.md @@ -0,0 +1,4531 @@ +# Release v1.23.0 + +## @backstage/app-defaults@1.5.0 + +### Minor Changes + +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. +- 7f11009: Added stack trace display to `ErrorPage` and updated existing refs + +### Patch Changes + +- f899eec: Change default icon for `kind:resource` to the storage icon. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. +- 214f2da: Fix invalid HTTP status code 501 in Error Page +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + +## @backstage/backend-common@0.21.0 + +### Minor Changes + +- bbe374e: **BREAKING**: `A gitilesBaseUrl` must be provided for the Gerrit integration to work. + You can disable this check by setting `DISABLE_GERRIT_GITILES_REQUIREMENT=1` but + this will be removed in a future release. If you are not able to use the Gitiles + Gerrit plugin, please open an issue towards `https://github.com/backstage/backstage` +- e85aa98: drop databases after unit tests if the database instance is not running in docker + +### Patch Changes + +- 6707216: Added a new `LegacyRootDatabaseService` interface that can be used to avoid direct dependencies on the `DatabaseManager`. +- 842171a: Fix a bug with S3 Fetch that caused all objects to be flattened within a single folder on the local file system. +- 3489d05: `FetchUrlReader#readUrl()` now supports passing an optional `token` to authenticate requests. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- ece5a8f: Add a User-Agent header for calls towards Google Cloud Storage. +- 1f020fe: Support `token` in `readTree`, `readUrl` and `search` +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- e27b7f3: Fix rate limit detection by looking for HTTP status code 429 and updating the header `x-ratelimit-remaining` to look for in case of a 403 code is returned +- 7fb7a79: Add a config declaration for `workingDirectory` +- Updated dependencies + - @backstage/backend-app-api@0.5.11 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/integration-aws-node@0.1.9 + - @backstage/integration@1.9.0 + - @backstage/config-loader@1.6.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/backend-dynamic-feature-service@0.2.0 + +### Minor Changes + +- d7adbbf: Implement the discovery of additional individual configuration schemas for dynamic plugins, and provide: + + - an alternate implementation of the root logger service that takes them into account, + - an extension to the App backend plugin to set a global configuration schema that takes them into account. + +### Patch Changes + +- 8723c5a: Fix wrong `alpha` support in dynamic plugins support: the `alpha` sub-package should not be required for the dynamic plugins to be loaded under the new backend system. +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/cli-node@0.2.3 + - @backstage/backend-app-api@0.5.11 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-catalog-backend@1.17.0 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-events-backend@0.2.19 + - @backstage/config-loader@1.6.2 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/plugin-app-node@0.1.10 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.19 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/backend-test-utils@0.3.0 + +### Minor Changes + +- e85aa98: drop databases after unit tests if the database instance is not running in docker + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-app-api@0.5.11 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.0 + +### Minor Changes + +- 43dad25: Add API to get location by entity +- 04907c3: Updates the OpenAPI specification title to plugin ID instead of package name. + +### Patch Changes + +- c04c42b: Internal updates to auto-generated files. +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/errors@1.2.3 + +## @backstage/core-app-api@1.12.0 + +### Minor Changes + +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.2.0 + +### Minor Changes + +- e586f79: Add support to the new analytics api. + +### Patch Changes + +- 1fa5041: The backwards compatibility provider will now use the new `ComponentsApi` and `IconsApi` when implementing the old `AppContext`. +- edfd3a5: Updated dependency `@oriflame/backstage-plugin-score-card` to `^0.8.0`. +- bc621aa: Updates to use the new `RouteResolutionsApi`. +- 7155c30: Added `convertLegacyRouteRefs` for bulk conversion of plugin routes. +- 46b63de: Allow external route refs in the new system to have a `defaultTarget` pointing to a route that it'll resolve to by default if no explicit bindings were made by the adopter. +- 2f2a1d2: Plugins converted by `convertLegacyApp` now have their `routes` and `externalRoutes` included as well, allowing them to be used to bind external routes in configuration. +- 1184990: collectLegacyRoutes throws in case invalid <Route /> element is found +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-app-api@1.12.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.0 + +### Minor Changes + +- 281e8c6: **BREAKING**: Removed the `SidebarIntro` component as it was providing instructions for features that do not exist, along with `IntroCard`. If you were relying on this component and want to keep using it you can refer to the original implementations of [`SidebarIntro`](https://github.com/backstage/backstage/blob/80f2413334ed9b221ec3c2b7c22fa737ad8d8885/packages/core-components/src/layout/Sidebar/Intro.tsx#L149) and [`IntroCard`](https://github.com/backstage/backstage/blob/80f2413334ed9b221ec3c2b7c22fa737ad8d8885/packages/core-components/src/layout/Sidebar/Intro.tsx#L100). + +### Patch Changes + +- 3e1c6e2: Added possibility to show arrow heads for graph edges for better understandability. + + In order to show arrow heads in the catalog graph page, add `showArrowHeads` attribute to `CatalogGraphPage` component + (typically in `packages/app/src/App.tsx`): + + ```diff + - <CatalogGraphPage /> + + <CatalogGraphPage showArrowHeads /> + ``` + + In order to show arrow heads in entity graphs, add `showArrowHeads` attribute to `EntityCatalogGraphCard` components + (typically multiple occurrences in `packages/app/src/components/catalog/EntityPage.tsx`): + + ```diff + - <EntityCatalogGraphCard variant="gridItem" height={400} /> + + <EntityCatalogGraphCard variant="gridItem" height={400} showArrowHeads /> + ``` + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. + +- 7f11009: Added stack trace display to `ErrorPage` and updated existing refs + +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. + +- 214f2da: Fix invalid HTTP status code 501 in Error Page + +- Updated dependencies + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-plugin-api@1.9.0 + +### Minor Changes + +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- e586f79: Throw a more specific exception `NotImplementedError` when an API implementation cannot be found. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-app-api@0.6.0 + +### Minor Changes + +- bdf4a8e: **BREAKING**: Removed the experimental `createExtensionTree` API. +- 86346c2: **BREAKING**: The `app.routes.bindings` app-config mapping has been simplified. You now only need to specify the plugin ID and route ID on both sides of the mapping. + + Old form: + + ```yaml + app: + routes: + bindings: + plugin.catalog.externalRoutes.viewTechDoc: plugin.techdocs.routes.docRoot + plugin.catalog.externalRoutes.createComponent: plugin.catalog-import.routes.importPage + ``` + + New form: + + ```yaml + app: + routes: + bindings: + catalog.viewTechDoc: techdocs.docRoot + catalog.createComponent: catalog-import.importPage + ``` + +### Patch Changes + +- 42ebf27: Added `IconsApi` implementation and the ability to configure icons through the `icons` option for `createApp` and `createSpecializedApp`. This is not a long-term solution as icons should be installable via extensions instead. This is just a stop-gap to make sure there is feature parity with the existing frontend system. +- bc621aa: Updates to use the new `RouteResolutionsApi`. +- e586f79: Wrap the root element with the analytics context to ensure it always exists for all extensions. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 8472188: Added or fixed the `repository` field in `package.json`. +- e0a4dd1: Improved the error message when data input/output shapes do not match +- fb9b5e7: The default `ComponentsApi` implementation now uses the `ComponentRef` ID as the component key, rather than the reference instance. This fixes a bug where duplicate installations of `@backstage/frontend-plugin-api` would break the app. +- 46b63de: Allow external route refs in the new system to have a `defaultTarget` pointing to a route that it'll resolve to by default if no explicit bindings were made by the adopter. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.0 + +### Minor Changes + +- e586f79: **BREAKING**: Replace default plugin extension and plugin ids to be `app` instead of `root`. + +### Patch Changes + +- 7eae3e0: Added initial `IconsApi` definition. +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- bc621aa: Added `RouteResolutionsApi` as a replacement for the routing context. +- 1e61ad3: App component extensions are no longer wrapped in an `ExtensionBoundary`, allowing them to inherit the outer context instead. +- 46b63de: Allow external route refs in the new system to have a `defaultTarget` pointing to a route that it'll resolve to by default if no explicit bindings were made by the adopter. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/integration@1.9.0 + +### Minor Changes + +- e27b7f3: Fix rate limit detection by looking for HTTP status code 429 and updating the header `x-ratelimit-remaining` to look for in case of a 403 code is returned + +### Patch Changes + +- 6d898f7: All single-line secrets read from config will now have both leading and trailing whitespace trimmed. This is done to ensure that the secrets are always valid HTTP header values, since many fetch implementations will include the header value itself when an error is thrown due to invalid header values. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 2d0e7cd: Validate if the `baseUrl` is a valid URL +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/repo-tools@0.6.0 + +### Minor Changes + +- 04907c3: Updates the OpenAPI client template to support the new format for identifying plugin ID. You should now use `info.title` like so, + + ```diff + info: + + title: yourPluginId + - title: @internal/plugin-*-backend + + servers: + - / + - - yourPluginId + ``` + +- b10c603: Add support for `oneOf` in client generated by `schema openapi generate-client`. + +- 4c62935: **BREAKING**: The `schema openapi *` commands are now renamed into `package schema openapi *` and `repo schema openapi *`. The aim is to make it more clear what the command is operating on, the entire repo or just a single package. + + The following commands now live under the `package` namespace, + + - `schema openapi generate` is now `package schema openapi generate --server` + - `schema openapi generate-client` is now `package schema openapi generate --client-package` + - `schema openapi init` is now `package schema openapi init` + + And these commands live under the new `repo` namespace, + + - `schema openapi lint` is now `repo schema openapi lint` + - `schema openapi test` is now `repo schema openapi test` + - `schema openapi verify` is now `repo schema openapi verify` + + The `package schema openapi generate` now supports defining both `--server` and `--client-package` to generate both at once.This update also reworks the `--client-package` flag to accept only an output directory as the input directory can now be inferred. + +### Patch Changes + +- aa91cd6: Resolved an issue with generate-catalog-info where it was replacing upper case characters with -. +- 60a68f1: Introduced `knip` to the `knip-reports` command, which generates a `knip-report.md` file for your packages with dependency warnings, if any. +- ec16093: Add an internal limiter on concurrency when launching processes +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. +- c04c42b: Fixes an issue where comments would be duplicated in the template. Also, removes a header with the title and version of the OpenAPI spec from generated code. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/cli-node@0.2.3 + - @backstage/catalog-model@1.4.4 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + +## @backstage/test-utils@1.5.0 + +### Minor Changes + +- bb40898: Added `components` option to `TestAppOptions`, which will be forwarded as the `components` option to `createApp`. + +### Patch Changes + +- 07e7d12: Fix wording in API reference +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. +- Updated dependencies + - @backstage/core-app-api@1.12.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-analytics-module-ga@0.2.0 + +### Minor Changes + +- e586f79: Add support to the new analytics api. + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-analytics-module-ga4@0.2.0 + +### Minor Changes + +- e586f79: Add support to the new analytics api. + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.0 + +### Minor Changes + +- e586f79: Add support to the new analytics api. + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-api-docs@0.11.0 + +### Minor Changes + +- 172a717: Migrate the `api-docs` to the new frontend system. It is experimental and available via alpha subpath. + +### Patch Changes + +- 874e8cf: Updated README to list AsyncApi v3 as supported +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 170c023: Adding `supportedSubmitMethods` prop to `api-docs` to pass to the Swagger UI. This allows users to specify which HTTP methods they wish to allow end-users to make requests through the `Try It Out` button on the Swagger UI. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- c03f977: Updated dependency `graphiql` to `3.1.0`. +- 49b3b5e: Updated dependency `@asyncapi/react-component` to `1.2.13`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-catalog@1.17.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-auth-backend@0.21.0 + +### Minor Changes + +- 7dd8463: **BREAKING**: The `saml` provider has been migrated from `passport-saml` to `@node-saml/passport-saml`. + + This comes with breaking changes to config options: + + - `audience` is now mandatory + - `wantAuthnResponseSigned` is now exposed and defaults to `true` + - `wantAssertionsSigned` is now exposed and defaults to `true` + +### Patch Changes + +- 97f8724: Support additional algorithms in the `/.well-known/openid-configuration` endpoint. +- a3f1fa3: Use the externalized `auth-backend-module-microsoft-provider` again. +- a9e0107: The auth backend will now refuse to issue user tokens are excessively large. +- 5d2fcba: Migrated oidc auth provider to new `@backstage/plugin-auth-backend-module-oidc-provider` module package. +- d4cc552: The helper function `makeProfileInfo` and `PassportHelpers.transformProfile` + were refactored to use the `jose` library. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 23a98f8: Migrated the AWS ALB auth provider to new `@backstage/plugin-auth-backend-module-aws-alb-provider` module package. +- f5e04e3: Internal refactor to no longer use deprecated types +- 8321c97: Added `experimentalExtraAllowedOrigins` to config +- 8e8a25d: Ability for user to configure backstage token expiration +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.3 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.2 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.2 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.5 + - @backstage/plugin-auth-backend-module-github-provider@0.1.7 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.7 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.7 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.7 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.4 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.0 + +### Minor Changes + +- 23a98f8: Migrated the AWS ALB auth provider to new `@backstage/plugin-auth-backend-module-aws-alb-provider` module package. + +### Patch Changes + +- d309cad: Refactored to use the `jose` library for JWT handling. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-backend@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/errors@1.2.3 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.0 + +### Minor Changes + +- 5d2fcba: Created new `@backstage/plugin-auth-backend-module-oidc-provider` module package to house oidc auth provider migration. + +### Patch Changes + +- e471890: Fixed a bug where the OIDC authenticator did not properly persist granted OAuth scopes. +- 8472188: Added or fixed the `repository` field in `package.json`. +- 8afb6f4: Updated dependency `passport` to `^0.7.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-backend@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-azure-sites-backend@0.2.0 + +### Minor Changes + +- 28610f4: **BREAKING**: `catalogApi` and `permissionsApi` are now a requirement to be passed through to the `createRouter` function. + + You can fix the typescript issues by passing through the required dependencies like the below `diff` shows: + + ```diff + import { + createRouter, + AzureSitesApi, + } from '@backstage/plugin-azure-sites-backend'; + import { Router } from 'express'; + import { PluginEnvironment } from '../types'; + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise<Router> { + + const catalogClient = new CatalogClient({ + + discoveryApi: env.discovery, + + }); + + return await createRouter({ + logger: env.logger, + azureSitesApi: AzureSitesApi.fromConfig(env.config), + + catalogApi: catalogClient, + + permissionsApi: env.permissions, + }); + } + ``` + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- 4376655: Added `permissionIntegrationRouter` for azure-sites-backend routes + +- 5a409bb: Azure Sites `start` and `stop` action is now protected with the Permissions framework. + + The below example describes an action that forbids anyone but the owner of the catalog entity to trigger actions towards a site tied to an entity. + + ```typescript + // packages/backend/src/plugins/permission.ts + import { azureSitesActionPermission } from '@backstage/plugin-azure-sites-common'; + ... + class TestPermissionPolicy implements PermissionPolicy { + async handle(request: PolicyQuery, user?: BackstageIdentityResponse): Promise<PolicyDecision> { + if (isPermission(request.permission, azureSitesActionPermission)) { + return createCatalogConditionalDecision( + request.permission, + catalogConditions.isEntityOwner({ + claims: user?.identity.ownershipEntityRefs ?? [], + }), + ); + } + ... + return { + result: AuthorizeResult.ALLOW, + }; + } + ... + } + ``` + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-azure-sites-common@0.1.2 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-catalog@1.17.0 + +### Minor Changes + +- d208a93: Updated the paginated catalog table to support server side text filtering. +- 1f8c2fa: Add entity warning components to the default entity overview page. +- e541c0e: Exported `CatalogTable.defaultColumnsFunc` for defining the columns in `<CatalogTable />` of some Kinds while using the default columns for the others. + +### Patch Changes + +- 916da47: Change default icon for unknown entities to nothing instead of the help icon. +- f899eec: Change default icon for `kind:resource` to the storage icon. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 797a329: Fixed inconsistencies in icons used for System and Template +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 987f565: Add line clamping to `CatalogSearchResultListItem` +- 172a717: Fix entity content extension filtering. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-search-react@1.7.6 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-catalog-backend@1.17.0 + +### Minor Changes + +- 43dad25: Add API to get location by entity +- 126c2f9: Updates the OpenAPI spec to use plugin as `info.title` instead of package name. +- 04907c3: Updates the OpenAPI specification title to plugin ID instead of package name. +- d8a54d0: Adds support for supplying field validators to the new backend's catalog plugin. If you're using entity policies, you should use the new `transformLegacyPolicyToProcessor` function to install them as processors instead. + + ```ts + import { + catalogProcessingExtensionPoint, + catalogModelExtensionPoint, + } from '@backstage/plugin-catalog-node/alpha'; + import {myPolicy} from './my-policy'; + + export const catalogModulePolicyProvider = createBackendModule({ + pluginId: 'catalog', + moduleId: 'internal-policy-provider', + register(reg) { + reg.registerInit({ + deps: { + modelExtensions: catalogModelExtensionPoint, + processingExtensions: catalogProcessingExtensionPoint, + }, + async init({ modelExtensions, processingExtensions }) { + modelExtensions.setFieldValidators({ + ... + }); + processingExtensions.addProcessors(transformLegacyPolicyToProcessor(myPolicy)) + }, + }); + }, + }); + ``` + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- 89b674c: Minor performance improvement for `queryEntities` when the limit is 0. + +- 81e19b1: Replace uses of deprecated types with replacements internally. + +- efa8160: Rollback the change for wildcard discovery, this fixes a bug with the `AzureUrlReader` not working with wildcard paths + +- d208a93: Fixed a bug where `fullTextFilter` wasn't preserved correctly in the cursor. + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. + +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. + +- 0a395b3: Upgraded `prom-client` to version 15 + +- 9b2eb3f: Add support for `onProcessingError` handler at the catalog plugin (new backend system). + + You can use `setOnProcessingErrorHandler` at the `catalogProcessingExtensionPoint` + as replacement for + + ```ts + catalogBuilder.subscribe({ + onProcessingError: hander, + }); + ``` + +- Updated dependencies + - @backstage/repo-tools@0.6.0 + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-search-backend-module-catalog@0.1.14 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/backend-openapi-utils@0.1.3 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-events-node@0.2.19 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-catalog-backend-module-github@0.5.0 + +### Minor Changes + +- a950ed0: Prevent Entity Providers from eliminating Users and Groups from the DB when the synchronisation fails + +### Patch Changes + +- 785ff24: Added `validateLocationsExist` to the config +- 9477133: Decreased number of teams fetched by GraphQL Query responsible for fetching Teams and Members in organization, due to timeouts when running against big organizations +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-catalog-backend@1.17.0 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-catalog-graph@0.4.0 + +### Minor Changes + +- 3dc64e9: Migrate plugin to the new frontend system, it is experimental and available via alpha subpath. + +### Patch Changes + +- 916da47: Change default icon for unknown entities to nothing instead of the help icon. + +- f937aae: use `CatalogClient.getEntitiesByRefs()` to reduce the number of backend requests from plugin `catalog-graph` + +- 3e1c6e2: Added possibility to show arrow heads for graph edges for better understandability. + + In order to show arrow heads in the catalog graph page, add `showArrowHeads` attribute to `CatalogGraphPage` component + (typically in `packages/app/src/App.tsx`): + + ```diff + - <CatalogGraphPage /> + + <CatalogGraphPage showArrowHeads /> + ``` + + In order to show arrow heads in entity graphs, add `showArrowHeads` attribute to `EntityCatalogGraphCard` components + (typically multiple occurrences in `packages/app/src/components/catalog/EntityPage.tsx`): + + ```diff + - <EntityCatalogGraphCard variant="gridItem" height={400} /> + + <EntityCatalogGraphCard variant="gridItem" height={400} showArrowHeads /> + ``` + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-node@1.7.0 + +### Minor Changes + +- d8a54d0: Adds support for supplying field validators to the new backend's catalog plugin. If you're using entity policies, you should use the new `transformLegacyPolicyToProcessor` function to install them as processors instead. + + ```ts + import { + catalogProcessingExtensionPoint, + catalogModelExtensionPoint, + } from '@backstage/plugin-catalog-node/alpha'; + import {myPolicy} from './my-policy'; + + export const catalogModulePolicyProvider = createBackendModule({ + pluginId: 'catalog', + moduleId: 'internal-policy-provider', + register(reg) { + reg.registerInit({ + deps: { + modelExtensions: catalogModelExtensionPoint, + processingExtensions: catalogProcessingExtensionPoint, + }, + async init({ modelExtensions, processingExtensions }) { + modelExtensions.setFieldValidators({ + ... + }); + processingExtensions.addProcessors(transformLegacyPolicyToProcessor(myPolicy)) + }, + }); + }, + }); + ``` + +### Patch Changes + +- 9b2eb3f: Add support for `onProcessingError` handler at the catalog plugin (new backend system). + + You can use `setOnProcessingErrorHandler` at the `catalogProcessingExtensionPoint` + as replacement for + + ```ts + catalogBuilder.subscribe({ + onProcessingError: hander, + }); + ``` + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-catalog-react@1.10.0 + +### Minor Changes + +- d208a93: Added support for server side text filtering to paginated entity requests. +- 3dc64e9: Add support to `configSchema` option on the `createEntityCardExtension` factory function. + +### Patch Changes + +- 916da47: Change default icon for unknown entities to nothing instead of the help icon. +- 71c6d7a: Overflowing labels in OwnerPicker (Catalog) are now truncated. Hovering over them shows the full label +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-cloudbuild@0.4.0 + +### Minor Changes + +- 0328d1b: Changed build list view to automatically filter builds based on repository name matching component-info's metadata.name. + Added optional `google.com/cloudbuild-repo-name` annotation which allows you to specify a different repository to filter on. + Added optional `google.com/cloudbuild-trigger-name` annotation which allows you to filter based on a trigger name instead of a repo name. + Updated the ReadMe with information about the filtering and some other minor verbiage updates. + Changed `substitutions.BRANCH_NAME` to `substitutions.REF_NAME` so that the Ref field is populated properly. + Added optional `google.com/cloudbuild-location` annotation which allows you to specify the Cloud Build location of your builds. Default is global scope. + Changed build list view to show builds in a specific location if the location annotation is used. + Updated ReadMe with information about the use of the location filtering. + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- ef3cad4: Add telemetry HTTP header Google Cloud Platform +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-kubernetes-backend@0.15.0 + +### Minor Changes + +- 666eff5: **BREAKING** The backend will fail to start if two clusters in the app-config + have the same name. The requirement for unique names has been declared in the + docs for some time, but is now enforced. + +### Patch Changes + +- 7233f57: Fixed an issue where a misleading error message would be logged when an + unsupported service locator method was specified. +- afe9473: The `/clusters` API now surfaces cluster titles. +- a775596: Enabled a way to include custom auth metadata info on the clusters endpoint. If you want to implement a Kubernetes auth strategy which requires surfacing custom auth metadata to the frontend, use the new presentAuthMetadata method on the AuthenticationStrategy interface. +- 7278d80: The purpose of this patch is to add a new login method which is `googleServiceAccount` configuring the kubernetes properties in the app-config.yaml file with authProvider key +- 2a50cbf: adds a x-goog-api-client header to existing API requests in this plugin to clearly identify API requests from this GKE plugin. headers are formatted as follows where `libVersion` represents the current dotted version number of the Backstage GKE plugin and `libName` represent the current Google API used at backstage. +- 3b3d549: Responses from the `/api/kubernetes/services/:serviceId` endpoint now include the cluster title. +- a2e7fc6: Organized imports in plugin.ts +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- daad576: Clusters configured with the `aws` authentication strategy can now customize the + `x-k8s-aws-id` header value used to generate tokens. This value can be specified + specified via the `kubernetes.io/x-k8s-aws-id` parameter (in + `metadata.annotations` for clusters in the catalog, or the `authMetadata` block + on clusters in the app-config). This is particularly helpful when a Backstage + instance contains multiple AWS clusters with the same name in different regions + \-- using this new parameter, the clusters can be given different logical names + to distinguish them but still use the same ID for the purposes of generating + tokens. +- f180cba: Enabling authentication to kubernetes clusters with mTLS x509 client certs +- 7f6ff25: Custom per-cluster auth metadata (mainly for use with custom `AuthenticationStrategy` implementations) can now be specified in the `authMetadata` property of clusters in the app-config. +- 6009d2a: Clusters in the catalog can now specify a human-readable title via `metadata.title`. +- 7ee5b30: Clusters in the app-config can now specify a `title` property for human readability. +- 1c3cb3b: Backstage will log a warning whenever duplicate cluster names are detected -- + even if clusters sharing the same name come from separate locators. +- ceda378: On LocalKubectlProxyClusterLocator, when resolving localhost, IPv4 address is placed before IPv6 address, ignoring the order from the DNS resolver. This change is necessary since by default kubectl proxy listen on IPv4 +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration-aws-node@0.1.9 + - @backstage/plugin-kubernetes-node@0.1.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-kubernetes-react@0.3.0 + +### Minor Changes + +- 0dfc185: **BREAKING** The `PodScope`, `PodAndErrors`, and `PodExecTerminalProps` types no + longer have a `clusterName` field; instead they now have the field `cluster` + which contains the full `ClusterAttributes`. +- 0d526c8: **BREAKING** The pod exec terminal is now disabled by default since there are several scenarios where it is known not to work. It can be re-enabled at your own risk by setting the config parameter `kubernetes.podExecTerminal.enabled` to `true`. + +### Patch Changes + +- 5bf0c17: Pod dialogs display cluster title when specified. +- 74770c8: The `ErrorPanel` component will display the `title` field (when specified) for + clusters with errors. +- 536f67d: Fix broken XtermJS CSS import +- b01c86c: The `ErrorReporting` component's cluster column now displays cluster titles when + specified. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 8472188: Added or fixed the `repository` field in `package.json`. +- 2b305eb: The `Cluster` component now renders the cluster's title, if specified. +- 3c184af: Extracted common dialog component. +- db1054b: Fixed a bug where the logs dialog and any other functionality depending on the proxy endpoint would fail for clusters configured with the OIDC auth provider. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder@1.18.0 + +### Minor Changes + +- c56f1a2: Remove the old legacy exports from `/alpha` +- 9b9c05c: Updating the `EntityPicker` to only select `kind` `metadata.name` and `metadata.namespace` by default to improve performance on larger datasets. +- a86920b: Introduced a new `MultiEntityPicker` field that supports selecting multiple Entities +- 7f11009: Added stack trace display to `ErrorPage` and updated existing refs + +### Patch Changes + +- b0d1d80: Added basic support for the new frontend system, exported from the `/alpha` subpath. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- da059d7: Removed alpha symbol from Task List header +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 31f0a0a: Added `ScaffolderPageContextMenu` to `ActionsPage`, `ListTaskPage`, and `TemplateEditorPage` so that you can more easily navigate between these pages +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- e6f0831: Updated dependency `@rjsf/utils` to `5.17.0`. + Updated dependency `@rjsf/core` to `5.17.0`. + Updated dependency `@rjsf/material-ui` to `5.17.0`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.0`. +- 6a74ffd: Updated dependency `@rjsf/utils` to `5.16.1`. + Updated dependency `@rjsf/core` to `5.16.1`. + Updated dependency `@rjsf/material-ui` to `5.16.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.16.1`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 11b9a08: Introduced the first version of recoverable tasks. +- 3dff4b0: Remove unused deps +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/plugin-scaffolder-react@1.8.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-scaffolder-backend@1.21.0 + +### Minor Changes + +- 458bf21: Created a gitea module for the scaffolder. This module provides a new action "publish:gitea" able to create a gitea repository owned by an organization. See: <https://gitea.com/api/swagger#/organization/createOrgRepo> +- 11b9a08: Introduced the first version of recoverable tasks. +- 78c100b: Support providing an overriding token for `fetch:template`, `fetch:plain` and `fetch:file` when interacting with upstream integrations +- e9a5228: The built-in module list has been trimmed down when using the new Backend System. Provider specific modules should now be installed with `backend.add` to provide additional actions to the scaffolder. These modules are as follows: + + - `@backstage/plugin-scaffolder-backend-module-github` + - `@backstage/plugin-scaffolder-backend-module-gitlab` + - `@backstage/plugin-scaffolder-backend-module-bitbucket` + - `@backstage/plugin-scaffolder-backend-module-gitea` + - `@backstage/plugin-scaffolder-backend-module-gerrit` + - `@backstage/plugin-scaffolder-backend-module-confluence-to-markdown` + - `@backstage/plugin-scaffolder-backend-module-cookiecutter` + - `@backstage/plugin-scaffolder-backend-module-rails` + - `@backstage/plugin-scaffolder-backend-module-sentry` + - `@backstage/plugin-scaffolder-backend-module-yeoman` + +### Patch Changes + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Server. + + - `publish:bitbucketServer` + - `publish:bitbucketServer:pull-request` + +- 09f8b31: Simple typo fix in the fetch:template action example on the word 'skeleton'. + +- c25a500: Fix some deprecations and misplaced `await` usage. + +- f6792c6: Move the `NODE_OPTIONS` messaging for `--no-node-snapshot` to the `SecureTemplater` in order to get better messaging at runtime + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. + +- 52ae6b9: Updated dependency `esbuild` to `^0.20.0`. + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Cloud. + + - `publish:bitbucketCloud` + - `bitbucket:pipelines:run` + +- 0a395b3: Upgraded `prom-client` to version 15 + +- e1c479d: When using node 20+ the `scaffolder-backend` will now throw an error at startup if the `--no-node-snapshot` option was + not provided to node. + +- e0e5afe: Add option to configure nunjucks with the `trimBlocks` and `lstripBlocks` options in the fetch:template action + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.13 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.2 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.7 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.0 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.0 + +### Minor Changes + +- 5eb6882: Split `@backstage/plugin-scaffolder-backend-module-bitbucket` into + `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` and + `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. + + `@backstage/plugin-scaffolder-backend-module-bitbucket` was **deprecated** in favor of these two replacements. + + Please use any of the two replacements depending on your needs. + + ```diff + - backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket')); + + backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket-cloud')); + + backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket-server')); + ``` + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- fc98bb6: Enhanced the pull request action to allow for adding new content to the PR as described in this issue #21762 +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.0 + +### Minor Changes + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Cloud. + + - `publish:bitbucketCloud` + - `bitbucket:pipelines:run` + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.0 + +### Minor Changes + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Server. + + - `publish:bitbucketServer` + - `publish:bitbucketServer:pull-request` + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.0 + +### Minor Changes + +- 458bf21: Created a gitea module for the scaffolder. This module provides a new action "publish:gitea" able to create a gitea repository owned by an organization. See: <https://gitea.com/api/swagger#/organization/createOrgRepo> + +### Patch Changes + +- ef0f44e: - Fix issue for infinite loop when repository already exists + - Log the root cause of error reported by `checkGiteaOrg` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.0 + +### Minor Changes + +- fd5eb1c: Allow to force the creation of a pull request from a forked repository +- 3d5c668: support oidc customization + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-common@1.5.0 + +### Minor Changes + +- 11b9a08: Introduced the first version of recoverable tasks. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-scaffolder-node@0.3.0 + +### Minor Changes + +- 3a9ba42: Added functions to clone a repo, create a branch, add files and push and commit to the branch. This allows for files to be added to the a PR for use in the bitbucket pull request action for issue #21762 +- 11b9a08: Introduced the first version of recoverable tasks. +- 78c100b: Support providing an overriding token for `fetch:template`, `fetch:plain` and `fetch:file` when interacting with upstream integrations + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 9b0bf20: Add gitea as new type to be used from integrations configuration +- e0e5afe: Add option to configure nunjucks with the `trimBlocks` and `lstripBlocks` options in the fetch:template action +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.0 + +### Minor Changes + +- c56f1a2: Remove the old legacy exports from `/alpha` +- 11b9a08: Introduced the first version of recoverable tasks. +- b07ec70: Use more distinguishable icons for link (`Link`) and text output (`Description`). + +### Patch Changes + +- 3f60ad5: fix for: converting circular structure to JSON error +- 0b0c6b6: Allow defining default output text to be shown +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 31f0a0a: Added `ScaffolderPageContextMenu` to `ActionsPage`, `ListTaskPage`, and `TemplateEditorPage` so that you can more easily navigate between these pages +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- e6f0831: Updated dependency `@rjsf/utils` to `5.17.0`. + Updated dependency `@rjsf/core` to `5.17.0`. + Updated dependency `@rjsf/material-ui` to `5.17.0`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.0`. +- 6a74ffd: Updated dependency `@rjsf/utils` to `5.16.1`. + Updated dependency `@rjsf/core` to `5.16.1`. + Updated dependency `@rjsf/material-ui` to `5.16.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.16.1`. +- 3dff4b0: Remove unused deps +- 82affc7: Fix issue where `ui:schema` was replaced with an empty object if `dependencies` is defined +- 2985186: Fix bug that erroneously caused a separator or a 0 to render in the TemplateCard for Templates with empty links +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-search-backend@1.5.0 + +### Minor Changes + +- 126c2f9: Updates the OpenAPI spec to use plugin as `info.title` instead of package name. +- 04907c3: Updates the OpenAPI specification title to plugin ID instead of package name. + +### Patch Changes + +- 3ed0eac: Authorized search engine now obeys query page limit +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-openapi-utils@0.1.3 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-techdocs@1.10.0 + +### Minor Changes + +- af4d147: Updated the styling for `<code>` tags to avoid word break. + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/backend-app-api@0.5.11 + +### Patch Changes + +- e0c18ef: Include the extension point ID and the module ID in the backend init error message. +- 7ae5704: Updated the default error handling middleware to filter out certain known error types that should never be returned in responses. The errors are instead logged along with a correlation ID, which is also returned in the response. Initially only PostgreSQL protocol errors from the `pg-protocol` package are filtered out. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 54ad8e1: Allow the `createConfigSecretEnumerator` to take an optional `schema` argument with an already-loaded global configuration schema. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/cli-node@0.2.3 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/config-loader@1.6.2 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.10 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-app-api@0.5.11 + +## @backstage/backend-dev-utils@0.1.4 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +## @backstage/backend-openapi-utils@0.1.3 + +### Patch Changes + +- 2067689: Internal updates due to `json-schema-to-ts` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/errors@1.2.3 + +## @backstage/backend-plugin-api@0.6.10 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 1f020fe: Support `token` in `readTree`, `readUrl` and `search` +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-tasks@0.5.15 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/backend-tasks@0.5.15 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6707216: The `TaskScheduler.fromConfig` method now accepts the `LegacyRootDatabaseService` interface rather than the full `DatabaseManager` implementation. +- b68248b: Updated dependency `cron` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/catalog-model@1.4.4 + +### Patch Changes + +- 07e7d12: Fix wording in API reference +- Updated dependencies + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/cli@0.25.2 + +### Patch Changes + +- d557d47: Added check for the `repository` field in the `repo fix` command. +- b58673e: Upgrade jest +- c624938: Add experimental support for an optional `public` app entry point that lets users sign-in before being able to access the full app. +- c52e7d5: Make `http://localhost:3000` the default base URL for serving locally, and `/` the default public path for built apps. The app build no longer requires any configuration values to be present. +- 9a96ef2: Updated dependency `vite-plugin-node-polyfills` to `^0.21.0`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 2f1f8fd: Updated dependency `esbuild-loader` to `^4.0.0`. +- fd20d5b: Updated dependency `eslint-config-prettier` to `^9.0.0`. +- acd2860: Updated dependency `vite-plugin-node-polyfills` to `^0.19.0`. +- 40c27f3: Updated dependency `eslint-webpack-plugin` to `^4.0.0`. +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. +- ba56063: Updated dependency `fork-ts-checker-webpack-plugin` to `^9.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 52ae6b9: Updated dependency `esbuild` to `^0.20.0`. +- 404e82b: Updated dependency `eslint-plugin-deprecation` to `^2.0.0`. +- 5c05f8a: Harmonize the package naming and allow custom prefix +- 35725e2: Updated dependencies in frontend plugin templates +- c7259dc: Updated the backend module template to make the module instance the package default export. +- 08804c3: Fixed an issue that would cause an invalid `__backstage-autodetected-plugins__.js` to be written when using experimental module discovery. +- Updated dependencies + - @backstage/cli-node@0.2.3 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/config-loader@1.6.2 + - @backstage/eslint-plugin@0.1.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.3 + +### Patch Changes + +- d557d47: Added `repository` field to `BackstagePackageJson` type. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/codemods@0.1.47 + +### Patch Changes + +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/config-loader@1.6.2 + +### Patch Changes + +- 0a9a03c: Make schema processing gracefully handle an empty config. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- bf3da16: Updated dependency `typescript-json-schema` to `^0.63.0`. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/create-app@0.5.11 + +### Patch Changes + +- c70c3dc: Bumped create-app version. + +- c420081: Add a seed file for `yarn.lock` in newly created apps. This file is downloaded directly from `https://github.com/backstage/backstage` at the time of creating a new project, ensuring that users always receive the latest version. The purpose of the seed file is to initialize the lock file with known good versions of individual dependencies that have had bad new releases published. The seed file will have no effect if the dependency is not present, it can not be used to install additional packages. + +- f71352c: Bumped TypeScript to version `5.3`. + +- 03e55b1: Updated the default app index template at `packages/app/public/index.html` to have a fallback value for the `app.title` config. + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. + +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. + +- aeec29c: Updated `packages/app` as well as the root `package.json` type resolutions to use React v18. + + The `@testing-library/*` dependencies have also been updated to the ones compatible with React v18, and the test at `packages/app/src/App.test.tsx` had been updated to use more modern patterns that work better with these new versions. + + For information on how to migrate existing apps to React v18, see the [migration guide](https://backstage.io/docs/tutorials/react18-migration) + +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.27 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/app-defaults@1.5.0 + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/integration-react@1.1.24 + +## @backstage/e2e-test-utils@0.1.1 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. + +## @backstage/eslint-plugin@0.1.5 + +### Patch Changes + +- 995d280: Added new `@backstage/no-top-level-material-ui-4-imports` rule that forbids top level imports from Material UI v4 packages + +## @backstage/frontend-test-utils@0.1.2 + +### Patch Changes + +- bc621aa: Updates to use the new `RouteResolutionsApi`. +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/frontend-app-api@0.6.0 + - @backstage/test-utils@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/integration-aws-node@0.1.9 + +### Patch Changes + +- 6d898f7: All single-line secrets read from config will now have both leading and trailing whitespace trimmed. This is done to ensure that the secrets are always valid HTTP header values, since many fetch implementations will include the header value itself when an error is thrown due to invalid header values. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/integration-react@1.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + +## @techdocs/cli@1.8.2 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. +- d8d243c: fix: mkdocs parameter casing +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## @backstage/theme@0.5.1 + +### Patch Changes + +- dd5d7cc: Fixed missing extra variables like `applyDarkStyles` in Mui V5 theme after calling `createUnifiedThemeFromV4` function +- 8fe56a8: Widen `@types/react` dependency range to include version 18. + +## @backstage/plugin-adr@0.6.13 + +### Patch Changes + +- 0b03962: Updated README +- 987f565: Fix alignment of text in `AdrSearchResultListItem`. Update size and font to match other `SearchResultListItem`. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-adr-common@0.2.20 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-adr-backend@0.4.7 + +### Patch Changes + +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-adr-common@0.2.20 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-adr-common@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-airbrake@0.3.30 + +### Patch Changes + +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/test-utils@1.5.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/dev-utils@1.0.27 + +## @backstage/plugin-airbrake-backend@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + +## @backstage/plugin-allure@0.1.46 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-apache-airflow@0.2.20 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-api-docs-module-protoc-gen-doc@0.1.6 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. + +## @backstage/plugin-apollo-explorer@0.1.20 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-app-backend@0.3.58 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 998ccf6: Support injecting config multiple times in a single bundle +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 54ad8e1: Allow the `app-backend` plugin to use a global configuration schema provided externally through an extension. +- 9dfd57d: Do not force caching of the Javascript asset that contains the injected config. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config-loader@1.6.2 + - @backstage/plugin-app-node@0.1.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.10 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 54ad8e1: Allow the `app-backend` plugin to use a global configuration schema provided externally through an extension. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config-loader@1.6.2 + +## @backstage/plugin-app-visualizer@0.1.1 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.2 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.7 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.7 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.5 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 1ff2684: Added the possibility to use custom scopes for performing login with Microsoft EntraID. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.7 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.2 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/errors@1.2.3 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.3 + +### Patch Changes + +- cd5114c: Added missing `additionalScopes` option to configuration schema. +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.4 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.2 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + +## @backstage/plugin-auth-node@0.4.4 + +### Patch Changes + +- 71c3b7f: Fix error when Microsoft tokens (or any other using the `defaultProfileTransform`) are requested without the profile scope. +- d4cc552: The helper function `makeProfileInfo` and `PassportHelpers.transformProfile` + were refactored to use the `jose` library. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.3.12 + +### Patch Changes + +- e2083df: Added alpha support for the New Frontend System (Declarative Integration) +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 995d280: Updated imports from named to default imports to help with the Material UI v4 to v5 migration +- cb0afaa: Prefer `dev.azure.com/build-definition` annotation when it is provided, as it is more specific than `dev.azure.com/project-repo`. This can also be used as a filter for mono-repos. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/plugin-azure-devops-common@0.3.2 + +## @backstage/plugin-azure-devops-backend@0.5.2 + +### Patch Changes + +- 353244d: Added a note about Service Principles +- b64ce5a: Updated New Backend System instructions to use default import +- 25bda45: Fixed bug with `extractPartsFromAsset` that resulted in a leading `.` being removed from the path in an otherwise valid path (ex. `.assets/image.png`). The leading `.` will now only be moved for paths beginning with `./`. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/plugin-azure-devops-common@0.3.2 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-azure-sites@0.1.19 + +### Patch Changes + +- 09a9c95: Updated README + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. + +- 5a409bb: Azure Sites `start` and `stop` action is now protected with the Permissions framework. + + The below example describes an action that forbids anyone but the owner of the catalog entity to trigger actions towards a site tied to an entity. + + ```typescript + // packages/backend/src/plugins/permission.ts + import { azureSitesActionPermission } from '@backstage/plugin-azure-sites-common'; + ... + class TestPermissionPolicy implements PermissionPolicy { + async handle(request: PolicyQuery, user?: BackstageIdentityResponse): Promise<PolicyDecision> { + if (isPermission(request.permission, azureSitesActionPermission)) { + return createCatalogConditionalDecision( + request.permission, + catalogConditions.isEntityOwner({ + claims: user?.identity.ownershipEntityRefs ?? [], + }), + ); + } + ... + return { + result: AuthorizeResult.ALLOW, + }; + } + ... + } + ``` + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-azure-sites-common@0.1.2 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-azure-sites-common@0.1.2 + +### Patch Changes + +- 5a409bb: Azure Sites `start` and `stop` action is now protected with the Permissions framework. + + The below example describes an action that forbids anyone but the owner of the catalog entity to trigger actions towards a site tied to an entity. + + ```typescript + // packages/backend/src/plugins/permission.ts + import { azureSitesActionPermission } from '@backstage/plugin-azure-sites-common'; + ... + class TestPermissionPolicy implements PermissionPolicy { + async handle(request: PolicyQuery, user?: BackstageIdentityResponse): Promise<PolicyDecision> { + if (isPermission(request.permission, azureSitesActionPermission)) { + return createCatalogConditionalDecision( + request.permission, + catalogConditions.isEntityOwner({ + claims: user?.identity.ownershipEntityRefs ?? [], + }), + ); + } + ... + return { + result: AuthorizeResult.ALLOW, + }; + } + ... + } + ``` + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-badges@0.2.54 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-badges-backend@0.3.7 + +### Patch Changes + +- 6991e5f: Updating the `authorization` middleware to call the Catalog to check that the requesting user has permission to see the Entity before generating the UUID. +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bazaar@0.2.22 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-bazaar-backend@0.3.8 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + +## @backstage/plugin-bitbucket-cloud-common@0.2.16 + +### Patch Changes + +- 2e6af00: Updated dependency `ts-morph` to `^21.0.0`. +- Updated dependencies + - @backstage/integration@1.9.0 + +## @backstage/plugin-bitrise@0.1.57 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- e24e4d3: Update README +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-catalog-backend-module-aws@0.3.4 + +### Patch Changes + +- a81b1ba: The default EKS cluster entity transformer now sets the new + `kubernetes.io/x-k8s-aws-id` annotation. +- 22927c4: Move the AWS account e-mail from labels to annotations to fix the creation of `cloud-account` resources. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration-aws-node@0.1.9 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-backend-module-azure@0.1.29 + +### Patch Changes + +- 534786a: Fixed issue where specifying a branch for discovery did not work +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.3 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/backend-openapi-utils@0.1.3 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.16 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.26 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.4 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-catalog-backend-module-github@0.5.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.7 + +### Patch Changes + +- 60e4c2a: Added the option to provide custom `groupTransformer`, `userTransformer` and `groupNameTransformer` to allow custom transformations of groups and users +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-catalog-backend@1.17.0 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.19 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.17 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.27 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-catalog-backend@1.17.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.15 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- bc644fb: Added `latest_report_status` parameter from the PuppetDB node api and added it as a tag to the nodes. The status is valuable information as it displays which nodes are compliant to your configuration and which ones are failing are making changes. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.7 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.7 + +### Patch Changes + +- d3dd64a: Explicitly only depend on the `use` method from the `HttpRouterService`. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + +## @backstage/plugin-catalog-common@1.0.21 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-catalog-import@0.10.6 + +### Patch Changes + +- 916da47: Change default icon for unknown entities to nothing instead of the help icon. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.8 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-cicd-statistics@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.26 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-cicd-statistics@0.1.32 + +## @backstage/plugin-circleci@0.3.30 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-code-climate@0.1.30 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-code-coverage@0.2.23 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-code-coverage-backend@0.2.24 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-codescene@0.1.22 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-config-schema@0.1.50 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.19 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.9 + +### Patch Changes + +- c12a86c: Refactored code to improve accessibility by moving elements outside the `ul` tag and placing them appropriately. Also adjusted theme to offer better contrast. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- b89d8be: Added alpha support for the New Frontend System (Declarative Integration) +- 995d280: Updated imports from named to default imports to help with the Material UI v4 to v5 migration +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/errors@1.2.3 + - @backstage/plugin-devtools-common@0.1.8 + +## @backstage/plugin-devtools-backend@0.2.7 + +### Patch Changes + +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config-loader@1.6.2 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.8 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-dynatrace@9.0.0 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 0930c9e: Fixed Dynatrace plugin proxy configuration +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-entity-feedback@0.2.13 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.7 + +### Patch Changes + +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.15 + +### Patch Changes + +- 916da47: Change default icon for unknown entities to nothing instead of the help icon. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 1f70e46: Improves UX of the EntityValidationPage: Moves the validate button below the EntityTextArea which is actually validated, the location TextField can now be hidden to prevent confusion about what is validated and additional content can be added to the top of the validation page. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-events-backend@0.2.19 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-module-aws-sqs@0.2.13 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-module-azure@0.1.20 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.20 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-module-gerrit@0.1.20 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-module-github@0.1.20 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-module-gitlab@0.1.20 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-backend-test-utils@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-events-node@0.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-explore@0.4.16 + +### Patch Changes + +- 07e7d12: Fix wording in API reference +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 796d427: Use the EntityDisplayName component for rendering Group nodes +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/errors@1.2.3 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.36 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-explore-backend@0.0.20 + +### Patch Changes + +- fd3d51c: Add support for the new backend system. + + A new backend plugin for the explore backend + was added and exported as `default`. + + You can use it with the new backend system like + + ```ts title="packages/backend/src/index.ts" + backend.add(import('@backstage/plugin-explore-backend')); + ``` + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-search-backend-module-explore@0.1.14 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-explore-react@0.0.36 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-fossa@0.2.62 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-gcalendar@0.3.23 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-gcp-projects@0.3.46 + +### Patch Changes + +- 984d508: Add a `x-google-api-client` header for calls towards Google Cloud Projects +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-git-release-manager@0.3.42 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-github-actions@0.6.11 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/integration-react@1.1.24 + +## @backstage/plugin-github-deployments@0.1.61 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + +## @backstage/plugin-github-issues@0.2.19 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-github-pull-requests-board@0.1.24 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-gitops-profiles@0.3.45 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-gocd@0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-graphiql@0.3.3 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-graphql-voyager@0.1.12 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-home@0.6.2 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- dc7ae8b: Use EntityDisplayName JSX element entity information directly for FeaturedDocsCard. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- e6f0831: Updated dependency `@rjsf/utils` to `5.17.0`. + Updated dependency `@rjsf/core` to `5.17.0`. + Updated dependency `@rjsf/material-ui` to `5.17.0`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.0`. +- 6a74ffd: Updated dependency `@rjsf/utils` to `5.16.1`. + Updated dependency `@rjsf/core` to `5.16.1`. + Updated dependency `@rjsf/material-ui` to `5.16.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.16.1`. +- e9cdfd3: Fix typo in VisitsStorageApi +- 384c132: Added filter support for HomePageVisitedByType in order to enable filtering entities from the list +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-home-react@0.1.8 + - @backstage/config@1.1.1 + +## @backstage/plugin-home-react@0.1.8 + +### Patch Changes + +- e6f0831: Updated dependency `@rjsf/utils` to `5.17.0`. + Updated dependency `@rjsf/core` to `5.17.0`. + Updated dependency `@rjsf/material-ui` to `5.17.0`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.0`. +- 6a74ffd: Updated dependency `@rjsf/utils` to `5.16.1`. + Updated dependency `@rjsf/core` to `5.16.1`. + Updated dependency `@rjsf/material-ui` to `5.16.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.16.1`. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-ilert@0.2.19 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-jenkins@0.9.5 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.24 + +## @backstage/plugin-jenkins-backend@0.3.4 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-jenkins-common@0.1.24 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-jenkins-common@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-kafka@0.3.30 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-kafka-backend@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-kubernetes@0.11.5 + +### Patch Changes + +- b01c86c: The `ErrorReporting` component's cluster column now displays cluster titles when + specified. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-kubernetes-react@0.3.0 + - @backstage/core-components@0.14.0 + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-kubernetes-cluster@0.0.6 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-kubernetes-react@0.3.0 + - @backstage/core-components@0.14.0 + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-kubernetes-common@0.7.4 + +### Patch Changes + +- a643af8: The `ClusterAttributes` type now includes the cluster title. +- daad576: Clusters configured with the `aws` authentication strategy can now customize the + `x-k8s-aws-id` header value used to generate tokens. This value can be specified + specified via the `kubernetes.io/x-k8s-aws-id` parameter (in + `metadata.annotations` for clusters in the catalog, or the `authMetadata` block + on clusters in the app-config). This is particularly helpful when a Backstage + instance contains multiple AWS clusters with the same name in different regions + \-- using this new parameter, the clusters can be given different logical names + to distinguish them but still use the same ID for the purposes of generating + tokens. +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-kubernetes-node@0.1.4 + +### Patch Changes + +- a775596: Enabled a way to include custom auth metadata info on the clusters endpoint. If you want to implement a Kubernetes auth strategy which requires surfacing custom auth metadata to the frontend, use the new presentAuthMetadata method on the AuthenticationStrategy interface. +- 8472188: Added or fixed the `repository` field in `package.json`. +- 043cf88: The `ClusterDetails` type now has a `title` field, which should be a + human-readable name. +- cceed8a: Introduced `PinnipedHelper` class to enable authentication to Kubernetes clusters through Pinniped +- f180cba: Enabling authentication to kubernetes clusters with mTLS x509 client certs +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.7.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-lighthouse@0.4.15 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-lighthouse-common@0.1.4 + +## @backstage/plugin-lighthouse-backend@0.4.2 + +### Patch Changes + +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.4 + +## @backstage/plugin-linguist@0.1.15 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 995d280: Updated imports from named to default imports to help with the Material UI v4 to v5 migration +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.7 + +### Patch Changes + +- b64ce5a: Updated New Backend System instructions to use default import +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.12 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-newrelic@0.3.45 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-newrelic-dashboard@0.3.5 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-nomad@0.1.11 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-nomad-backend@0.1.12 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-notifications@0.0.1 + +### Patch Changes + +- 9873c44: Add support for signal type in notifications +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-signals-react@0.0.1 + - @backstage/plugin-notifications-common@0.0.1 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications-backend@0.0.1 + +### Patch Changes + +- 9873c44: Add support for signal type in notifications +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/plugin-notifications-common@0.0.1 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-notifications-node@0.0.1 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-notifications-common@0.0.1 + +### Patch Changes + +- 9873c44: Add support for signal type in notifications +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage + +## @backstage/plugin-notifications-node@0.0.1 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/plugin-notifications-common@0.0.1 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + +## @backstage/plugin-octopus-deploy@0.2.12 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-opencost@0.2.5 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 8472188: Added or fixed the `repository` field in `package.json`. +- 03c5bbe: Updated dependency `date-fns` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-org@0.6.20 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 6e1bf50: Added basic support for the new frontend system, exported from the `/alpha` subpath. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-catalog-common@1.0.21 + +## @backstage/plugin-org-react@0.1.19 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + +## @backstage/plugin-pagerduty@0.7.2 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-home-react@0.1.8 + - @backstage/errors@1.2.3 + +## @backstage/plugin-periskop@0.1.28 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-periskop-backend@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + +## @backstage/plugin-permission-backend@0.5.33 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.7 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-permission-node@0.7.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-permission-react@0.4.20 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-playlist@0.2.4 + +### Patch Changes + +- 5a03537: Conditionally render playlist description only when it's non-empty +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 7f11009: Added stack trace display to `ErrorPage` and updated existing refs +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-search-react@1.7.6 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-playlist-common@0.1.14 + +## @backstage/plugin-playlist-backend@0.3.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-playlist-common@0.1.14 + +## @backstage/plugin-proxy-backend@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + +## @backstage/plugin-puppetdb@0.1.13 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-rollbar@0.4.30 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-rollbar-backend@0.1.55 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/config@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.2 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.11 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.34 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.2 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- 8b269e1: Provide default branch when creating repositories. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.13 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 1cd2740: Use the Gitbeaker library for `gitlab:projectAccessToken:create` action, enabling the `expiresAt` option +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.27 + +### Patch Changes + +- e9a5228: Make `containerRunner` argument optional +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.18 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.31 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search@1.4.6 + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-catalog@0.1.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration-aws-node@0.1.9 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-explore@0.1.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-pg@0.5.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.3 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-module-techdocs@0.1.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-backend-node@1.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-search-react@1.7.6 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-sentry@0.5.15 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-shortcuts@0.3.19 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- 1ab22c4: Allow defining signal type to publish and receive +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-signals-react@0.0.1 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-backend@0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-signals-node@0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- 1ab22c4: Allow defining signal type to publish and receive +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.19 + +## @backstage/plugin-signals-react@0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- 1ab22c4: Allow defining signal type to publish and receive +- Updated dependencies + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.12 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-sonarqube-react@0.1.13 + +## @backstage/plugin-sonarqube-backend@0.2.12 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-sonarqube-react@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-splunk-on-call@0.4.19 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-stack-overflow@0.1.25 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- c1bc331: Fixes a bug that made the API return questions not related to the tags provided +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/plugin-home-react@0.1.8 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-stack-overflow-backend@0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.3 + +## @backstage/plugin-stackstorm@0.1.11 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-tech-insights@0.3.22 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.24 + +### Patch Changes + +- 7201af3: Add support for the new backend system. + + A new backend plugin for the tech-insights backend + was added and exported as `default`. + + You can use it with the new backend system like + + ```ts title="packages/backend/src/index.ts" + backend.add(import('@backstage/plugin-tech-insights-backend')); + ``` + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- 341c2a2: Move `FactRetrieverRegistry` and `PersistenceContext` to `@backstage/plugin-tech-insights-node`. + + Original exports are marked as deprecated and re-export the moved types. + + Please replace uses like + + ```ts + import { + FactRetrieverRegistry, + PersistenceContext, + } from '@backstage/plugin-tech-insights-backend'; + ``` + + with + + ```ts + import { + FactRetrieverRegistry, + PersistenceContext, + } from '@backstage/plugin-tech-insights-node'; + ``` + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-tech-insights-node@0.4.16 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.42 + +### Patch Changes + +- 25cfb76: Add support for the new backend system. + + A new backend module for the tech-insights backend + was added and exported as `default`. + + The module will register the `JsonRulesEngineFactCheckerFactory` + as `FactCheckerFactory`, loading checks from the config. + + You can use it with the new backend system like + + ```ts title="packages/backend/src/index.ts" + backend.add(import('@backstage/plugin-tech-insights-backend-module-jsonfc')); + ``` + +- bc72782: Support loading `TechInsightsJsonRuleCheck` instances from config. + + Uses the check `id` as key. + + Example: + + ```yaml title="app-config.yaml" + techInsights: + factChecker: + checks: + groupOwnerCheck: + type: json-rules-engine + name: Group Owner Check + description: Verifies that a group has been set as the spec.owner for this entity + factIds: + - entityOwnershipFactRetriever + rule: + conditions: + all: + - fact: hasGroupOwner + operator: equal + value: true + ``` + +- 9aac2b0: Use `--cwd` as the first `yarn` argument + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-tech-insights-node@0.4.16 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-node@0.4.16 + +### Patch Changes + +- 7201af3: Add support for the new backend system. + + A new backend plugin for the tech-insights backend + was added and exported as `default`. + + You can use it with the new backend system like + + ```ts title="packages/backend/src/index.ts" + backend.add(import('@backstage/plugin-tech-insights-backend')); + ``` + +- 341c2a2: Move `FactRetrieverRegistry` and `PersistenceContext` to `@backstage/plugin-tech-insights-node`. + + Original exports are marked as deprecated and re-export the moved types. + + Please replace uses like + + ```ts + import { + FactRetrieverRegistry, + PersistenceContext, + } from '@backstage/plugin-tech-insights-backend'; + ``` + + with + + ```ts + import { + FactRetrieverRegistry, + PersistenceContext, + } from '@backstage/plugin-tech-insights-node'; + ``` + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.6.13 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.27 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-catalog@1.17.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/core-app-api@1.12.0 + - @backstage/test-utils@1.5.0 + - @backstage/plugin-techdocs@1.10.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/integration-react@1.1.24 + +## @backstage/plugin-techdocs-backend@1.9.3 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.14 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.5 + +### Patch Changes + +- ab9c9eb: Fixed the value label text color in dark mode for the TextSize addon. +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 131ffdc: Fix position of the ReportIssue component when is displaying at the top of the container. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/integration-react@1.1.24 + +## @backstage/plugin-techdocs-node@1.11.2 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 77e3050: Update to a newer version of `@trendyol-js/openstack-swift-sdk` +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration-aws-node@0.1.9 + - @backstage/integration@1.9.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.10 + +## @backstage/plugin-techdocs-react@1.1.16 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.34 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-todo-backend@0.3.8 + +### Patch Changes + +- 126c2f9: Updates the OpenAPI spec to use plugin as `info.title` instead of package name. +- 04907c3: Updates the OpenAPI specification title to plugin ID instead of package name. +- Updated dependencies + - @backstage/repo-tools@0.6.0 + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/backend-openapi-utils@0.1.3 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-user-settings@0.8.1 + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- d5b14a0: conditionally rendering the user name and email in user settings page +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.25 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## @backstage/plugin-vault-backend@0.4.3 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-vault-node@0.1.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + +## @backstage/plugin-vault-node@0.1.3 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + +## @backstage/plugin-xcmetrics@0.2.48 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + +## example-app@0.2.92 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.3.12 + - @backstage/frontend-app-api@0.6.0 + - @backstage/plugin-scaffolder-react@1.8.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-catalog-import@0.10.6 + - @backstage/plugin-catalog-graph@0.4.0 + - @backstage/plugin-catalog@1.17.0 + - @backstage/plugin-azure-sites@0.1.19 + - @backstage/plugin-api-docs@0.11.0 + - @backstage/plugin-adr@0.6.13 + - @backstage/app-defaults@1.5.0 + - @backstage/plugin-gcp-projects@0.3.46 + - @backstage/plugin-airbrake@0.3.30 + - @backstage/plugin-scaffolder@1.18.0 + - @backstage/plugin-devtools@0.1.9 + - @backstage/cli@0.25.2 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.5 + - @backstage/plugin-signals@0.0.1 + - @backstage/plugin-kubernetes@0.11.5 + - @backstage/plugin-notifications@0.0.1 + - @backstage/plugin-catalog-unprocessed-entities@0.1.8 + - @backstage/plugin-microsoft-calendar@0.1.12 + - @backstage/plugin-github-actions@0.6.11 + - @backstage/plugin-octopus-deploy@0.2.12 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/core-app-api@1.12.0 + - @backstage/plugin-code-coverage@0.2.23 + - @backstage/plugin-cost-insights@0.12.19 + - @backstage/plugin-tech-insights@0.3.22 + - @backstage/plugin-lighthouse@0.4.15 + - @backstage/plugin-tech-radar@0.6.13 + - @backstage/plugin-dynatrace@9.0.0 + - @backstage/plugin-shortcuts@0.3.19 + - @backstage/plugin-graphiql@0.3.3 + - @backstage/plugin-linguist@0.1.15 + - @backstage/plugin-newrelic@0.3.45 + - @backstage/plugin-jenkins@0.9.5 + - @backstage/plugin-rollbar@0.4.30 + - @backstage/plugin-badges@0.2.54 + - @backstage/plugin-sentry@0.5.15 + - @backstage/plugin-nomad@0.1.11 + - @backstage/plugin-home@0.6.2 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-explore@0.4.16 + - @backstage/plugin-user-settings@0.8.1 + - @backstage/plugin-techdocs@1.10.0 + - @backstage/plugin-search@1.4.6 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-playlist@0.2.4 + - @backstage/plugin-apache-airflow@0.2.20 + - @backstage/plugin-cloudbuild@0.4.0 + - @backstage/plugin-entity-feedback@0.2.13 + - @backstage/plugin-gcalendar@0.3.23 + - @backstage/plugin-kafka@0.3.30 + - @backstage/plugin-kubernetes-cluster@0.0.6 + - @backstage/plugin-newrelic-dashboard@0.3.5 + - @backstage/plugin-org@0.6.20 + - @backstage/plugin-pagerduty@0.7.2 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-puppetdb@0.1.13 + - @backstage/plugin-search-react@1.7.6 + - @backstage/plugin-stack-overflow@0.1.25 + - @backstage/plugin-stackstorm@0.1.11 + - @backstage/plugin-gocd@0.1.36 + - @backstage/plugin-todo@0.2.34 + - @backstage/config@1.1.1 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + +## example-app-next@0.0.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.3.12 + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/frontend-app-api@0.6.0 + - @backstage/plugin-scaffolder-react@1.8.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-catalog-import@0.10.6 + - @backstage/plugin-catalog-graph@0.4.0 + - @backstage/plugin-catalog@1.17.0 + - @backstage/plugin-azure-sites@0.1.19 + - @backstage/plugin-api-docs@0.11.0 + - @backstage/plugin-adr@0.6.13 + - @backstage/app-defaults@1.5.0 + - @backstage/plugin-gcp-projects@0.3.46 + - @backstage/plugin-airbrake@0.3.30 + - @backstage/plugin-scaffolder@1.18.0 + - @backstage/plugin-devtools@0.1.9 + - @backstage/cli@0.25.2 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.5 + - @backstage/plugin-kubernetes@0.11.5 + - @backstage/plugin-catalog-unprocessed-entities@0.1.8 + - @backstage/plugin-microsoft-calendar@0.1.12 + - @backstage/plugin-github-actions@0.6.11 + - @backstage/plugin-octopus-deploy@0.2.12 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/core-app-api@1.12.0 + - @backstage/plugin-code-coverage@0.2.23 + - @backstage/plugin-cost-insights@0.12.19 + - @backstage/plugin-tech-insights@0.3.22 + - @backstage/plugin-lighthouse@0.4.15 + - @backstage/plugin-tech-radar@0.6.13 + - @backstage/plugin-dynatrace@9.0.0 + - @backstage/plugin-shortcuts@0.3.19 + - @backstage/plugin-graphiql@0.3.3 + - @backstage/plugin-linguist@0.1.15 + - @backstage/plugin-newrelic@0.3.45 + - @backstage/plugin-jenkins@0.9.5 + - @backstage/plugin-rollbar@0.4.30 + - @backstage/plugin-badges@0.2.54 + - @backstage/plugin-sentry@0.5.15 + - @backstage/plugin-home@0.6.2 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-explore@0.4.16 + - @backstage/plugin-user-settings@0.8.1 + - @backstage/plugin-techdocs@1.10.0 + - @backstage/plugin-search@1.4.6 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-playlist@0.2.4 + - @backstage/plugin-apache-airflow@0.2.20 + - @backstage/plugin-cloudbuild@0.4.0 + - @backstage/plugin-entity-feedback@0.2.13 + - @backstage/plugin-gcalendar@0.3.23 + - @backstage/plugin-kafka@0.3.30 + - @backstage/plugin-newrelic-dashboard@0.3.5 + - @backstage/plugin-org@0.6.20 + - @backstage/plugin-pagerduty@0.7.2 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-puppetdb@0.1.13 + - @backstage/plugin-search-react@1.7.6 + - @backstage/plugin-stackstorm@0.1.11 + - @backstage/plugin-app-visualizer@0.1.1 + - app-next-example-plugin@0.0.6 + - @backstage/plugin-gocd@0.1.36 + - @backstage/plugin-todo@0.2.34 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + +## app-next-example-plugin@0.0.6 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + +## example-backend@0.2.92 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.27 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.7 + - @backstage/plugin-scaffolder-backend@1.21.0 + - @backstage/plugin-badges-backend@0.3.7 + - @backstage/plugin-azure-devops-backend@0.5.2 + - @backstage/plugin-explore-backend@0.0.20 + - @backstage/plugin-auth-backend@0.21.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.42 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-entity-feedback-backend@0.2.7 + - @backstage/plugin-lighthouse-backend@0.4.2 + - @backstage/plugin-devtools-backend@0.2.7 + - @backstage/plugin-linguist-backend@0.5.7 + - @backstage/plugin-adr-backend@0.4.7 + - @backstage/plugin-kubernetes-backend@0.15.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.11 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.13 + - @backstage/plugin-signals-backend@0.0.1 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/plugin-tech-insights-backend@0.5.24 + - @backstage/plugin-tech-insights-node@0.4.16 + - @backstage/plugin-search-backend-module-techdocs@0.1.14 + - @backstage/plugin-search-backend-module-catalog@0.1.14 + - @backstage/plugin-search-backend-module-explore@0.1.14 + - @backstage/plugin-code-coverage-backend@0.2.24 + - @backstage/plugin-playlist-backend@0.3.14 + - @backstage/plugin-catalog-backend@1.17.0 + - @backstage/plugin-jenkins-backend@0.3.4 + - @backstage/plugin-rollbar-backend@0.1.55 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-events-backend@0.2.19 + - @backstage/plugin-nomad-backend@0.1.12 + - @backstage/plugin-app-backend@0.3.58 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-search-backend@1.5.0 + - @backstage/plugin-todo-backend@0.3.8 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.7 + - @backstage/plugin-techdocs-backend@1.9.3 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-azure-sites-common@0.1.2 + - example-app@0.2.92 + - @backstage/plugin-kafka-backend@0.3.8 + - @backstage/plugin-permission-backend@0.5.33 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/plugin-proxy-backend@0.4.8 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.13 + - @backstage/plugin-search-backend-module-pg@0.5.19 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-events-node@0.2.19 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + +## example-backend-next@0.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.7 + - @backstage/plugin-scaffolder-backend@1.21.0 + - @backstage/plugin-badges-backend@0.3.7 + - @backstage/plugin-azure-devops-backend@0.5.2 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-entity-feedback-backend@0.2.7 + - @backstage/plugin-lighthouse-backend@0.4.2 + - @backstage/plugin-devtools-backend@0.2.7 + - @backstage/plugin-linguist-backend@0.5.7 + - @backstage/plugin-adr-backend@0.4.7 + - @backstage/plugin-kubernetes-backend@0.15.0 + - @backstage/plugin-signals-backend@0.0.1 + - @backstage/plugin-notifications-backend@0.0.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.27 + - @backstage/plugin-search-backend-module-techdocs@0.1.14 + - @backstage/plugin-search-backend-module-catalog@0.1.14 + - @backstage/plugin-search-backend-module-explore@0.1.14 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-defaults@0.2.10 + - @backstage/plugin-sonarqube-backend@0.2.12 + - @backstage/plugin-playlist-backend@0.3.14 + - @backstage/plugin-catalog-backend@1.17.0 + - @backstage/plugin-jenkins-backend@0.3.4 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-nomad-backend@0.1.12 + - @backstage/plugin-app-backend@0.3.58 + - @backstage/plugin-search-backend@1.5.0 + - @backstage/plugin-todo-backend@0.3.8 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.7 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.7 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.3 + - @backstage/plugin-techdocs-backend@1.9.3 + - @backstage/plugin-permission-backend@0.5.33 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/plugin-proxy-backend@0.4.8 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/plugin-permission-common@0.7.12 + +## e2e-test@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.11 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + +## techdocs-cli-embedded-app@0.2.91 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.17.0 + - @backstage/app-defaults@1.5.0 + - @backstage/cli@0.25.2 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/core-app-api@1.12.0 + - @backstage/catalog-model@1.4.4 + - @backstage/test-utils@1.5.0 + - @backstage/plugin-techdocs@1.10.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/integration-react@1.1.24 + +## @internal/plugin-todo-list@1.0.22 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + +## @internal/plugin-todo-list-backend@1.0.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/errors@1.2.3 diff --git a/docs/releases/v1.23.0-next.1-changelog.md b/docs/releases/v1.23.0-next.1-changelog.md index 19bdba21dc..ffda51052e 100644 --- a/docs/releases/v1.23.0-next.1-changelog.md +++ b/docs/releases/v1.23.0-next.1-changelog.md @@ -399,7 +399,7 @@ ### Minor Changes -- af4d147: Updated the styling for code tags to avoid word break. +- af4d147: Updated the styling for `<code>` tags to avoid word break. ### Patch Changes diff --git a/docs/releases/v1.23.0.md b/docs/releases/v1.23.0.md new file mode 100644 index 0000000000..413db12988 --- /dev/null +++ b/docs/releases/v1.23.0.md @@ -0,0 +1,82 @@ +--- +id: v1.23.0 +title: v1.23.0 +description: Backstage Release v1.23.0 +--- + +These are the release notes for the v1.23.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 + +### Auth module migrations + +Several more auth providers have been migrated to be implemented as standalone modules, adding support for them in the [new backend system](https://backstage.io/docs/backend-system/building-backends/migrating#the-auth-plugin). The migrated providers are `microsoft`, `oidc`, and `aws-alb`. If you detect any issues, please reach out on [Discord](https://discord.gg/backstage-687207715902193673) or [open an issue](https://github.com/backstage/backstage/issues). + +### Scaffolder + +We’ve removed the last of the legacy exports from `/alpha`. Please [open an issue](https://github.com/backstage/backstage/issues) if there’s a reason why you still need to use them. + +If you’re using the New Backend System and the Scaffolder plugin, the built in modules have been trimmed down, so you’ll need to install other modules in order to pull in additional actions. You can read more [in the migration guide](https://backstage.io/docs/backend-system/building-backends/migrating#the-scaffolder-plugin) + +### New Module: `@backstage/plugin-scaffolder-backend-module-gitea` + +Provides actions to the Scaffolder for creating repositories and pushing to Gitea. Thanks to [@cmoulliard](https://github.com/cmoulliard)! + +### New Modules: `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` and `@backstage/plugin-scaffolder-backend-module-bitbucket-server` + +Thanks to [@pjungermann](https://github.com/pjungermann)’s work, we’ve now broken apart the BitBucket module into two separate modules to provide different actions to support the different BitBucket offerings. + +This change also deprecates the original `@backstage/plugin-scaffolder-backend-module-bitbucket`, so if you’re using the new Backend System we encourage you to move towards using these new modules instead. + +### New lint rule to forbid top-level MUI imports + +The `@backstage/eslint-rules` package now provides the `@backstage/no-top-level-material-ui-4-imports` rule that forbids imports such as `import { Box } from '@material-ui/core'`. This rule is currently disabled by default and needs to be manually enabled in `.eslintrc.js`: + +```ts +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); +``` + +### Automatic package `repository` fields + +The `backstage-cli repo fix` command will now update the `repository` fields in all workspace packages, as long as the root `package.json` has the `repository` field set. + +### Kubernetes cluster name uniqueness check + +The Kubernetes plugin now enforces the policy of all configured clusters having unique names. The backend will now fail to start if that is not the case. + +### Auth backend SAML provider dependency switch + +The implementation of the SAML provider in the auth backend is now based on [`@node-saml/passport-saml`](https://www.npmjs.com/package/@node-saml/passport-saml) instead of the deprecated [`passport-saml`](https://www.npmjs.com/package/passport-saml) package. This is a breaking change since the `audience` configuration is now mandatory, and the `wantAuthnResponseSigned` and `wantAssertionsSigned` options are enabled by default but possible to configure. + +### Update repo-tools OpenAPI commands structure + +The `schema openapi` commands of the `@backstage/repo-tools` package have been restructured. They are now divided into `package schema openapi` and `repo schema openapi` commands. For a more detailed list of changes, see the changelog of the [repo-tools changelog](https://github.com/backstage/backstage/blob/master/packages/repo-tools/CHANGELOG.md#060). + +### Gerrit integration now requires Gitiles + +When integrating a Gerrit instance with Backstage it is now required to have the Gitiles plugin installed in Gerrit. This allowed the Backstage integration to use a richer set of APIs, rather than interacting only over the git protocol. + +This behavior can be temporarily disabled via setting `DISABLE_GERRIT_GITILES_REQUIREMENT=1` in the environment. This flag will be removed in a future release, so if you depend on this behavior please [open an issue](https://github.com/backstage/backstage/issues). + +## Security Fixes + +This release contains an improvement to the default backend error handling middleware that will filter out some known error types that should never be returned in client responses. + +## 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/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.23.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://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.24.0-changelog.md b/docs/releases/v1.24.0-changelog.md new file mode 100644 index 0000000000..d55fe0cc0e --- /dev/null +++ b/docs/releases/v1.24.0-changelog.md @@ -0,0 +1,4774 @@ +# Release v1.24.0 + +## @backstage/backend-app-api@0.6.0 + +### Minor Changes + +- 4a3d434: **BREAKING**: For users that have migrated to the new backend system, incoming requests will now be rejected if they are not properly authenticated (e.g. with a Backstage bearer token or a backend token). Please see the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on how to circumvent this behavior in the short term and how to properly leverage it in the longer term. + + Added service factories for the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/), [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth), and [`userInfo`](https://backstage.io/docs/backend-system/core-services/user-info) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- 81e0120: Fixed an issue where configuration schema for the purpose of redacting secrets from logs was not being read correctly. +- 15fda44: Provide some sane defaults for `WinstonLogger.create` making some of the arguments optional +- 0502d82: Updated the `permissionsServiceFactory` to forward the `AuthService` to the implementation. +- 9d91128: Add the possibility to disable watching files in the new backend system +- a5d341e: Adds an initial rate-limiting implementation so that any incoming requests that have a `'none'` principal are rate-limited automatically. +- 9802004: Made the `DefaultUserInfoService` claims check stricter +- f235ca7: Make sure to not filter out schemas in `createConfigSecretEnumerator` +- af5f7a6: The experimental feature discovery service exported at the `/alpha` sub-path will no longer attempt to load packages that are not Backstage backend packages. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/config-loader@1.7.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/cli-node@0.2.4 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/cli@0.26.0 + +### Minor Changes + +- 0d72065: The backend devlopment server transpilation has been replaced with a simplified solution based on SWC, which is already the transpiler used for tests. This fixed an issue where never versions of the `tsx` dependency had a new contract for signalling dependencies, breaking watch mode. This change fixed file watches as well as enables sourcemaps. + +### Patch Changes + +- fe1a55e: Extend option to minify generated code to the `backend` package. +- b0875e5: Fixed a bug that could cause the `build-workspace` command to fail when invoked with `--alwaysYarnPack` enabled in environments with limited resources. +- bdf9ec1: New backend plugins with cli are now created using the new backend system +- cadbb82: Added a `EXPERIMENTAL_LAZY_COMPILATION` flag, which enables the experimental Webpack lazy compilation option in frontend builds. +- 999224f: Bump dependency `minimatch` to v9 +- 1bd4596: Removed the `ts-node` dev dependency. +- 8dce287: Fix prettier issues on default plugins & module templates +- f86e34c: Removed unused `replace-in-file` dependency +- 2398c7c: Updated dependency `@spotify/prettier-config` to `^15.0.0`. + Updated dependency `@spotify/eslint-config-base` to `^15.0.0`. + Updated dependency `@spotify/eslint-config-react` to `^15.0.0`. + Updated dependency `@spotify/eslint-config-typescript` to `^15.0.0`. +- f4404e5: Add .ico import support +- f39dfd3: Tweak the descriptions of the CLI templates +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.6 + - @backstage/config-loader@1.7.0 + - @backstage/cli-node@0.2.4 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/config@1.2.0 + +### Minor Changes + +- 50cf9df: The `ConfigReader` now treats `null` values as present but explicitly undefined, meaning it will not fall back to the next level of configuration. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/config-loader@1.7.0 + +### Minor Changes + +- db8358d: Forward `null` values read from configuration files in configuration data, rather than treating them as an absence of config. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.7.0 + +### Minor Changes + +- 8bfcc50: Fix knip-report command to send 1 exit status in case of fail + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- 1bd4596: Removed the `ts-node` dev dependency. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/errors@1.2.4 + - @backstage/cli-node@0.2.4 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + +## @backstage/plugin-auth-backend@0.22.0 + +### Minor Changes + +- 293c835: Add support for Service Tokens to Cloudflare Access auth provider +- 492fe83: **BREAKING**: The `CatalogIdentityClient` constructor now also requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support the new auth services, which has also been done for the `createRouter` function. + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- 7c29e7f: Fixed refresh scope to match start method in OneLogin provider. +- 2af5354: Bump dependency `jose` to v5 +- 38af71a: Updated dependency `google-auth-library` to `^9.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- fa7ea3f: Internal refactor to break out how the router is constructed +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.4 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.7 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.9 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.5 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.9 + - @backstage/plugin-auth-backend-module-google-provider@0.1.11 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.6 + - @backstage/plugin-auth-backend-module-github-provider@0.1.11 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.11 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.11 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.7 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.0 + +### Minor Changes + +- 1bedb23: Adds a new guest provider that maps guest users to actual tokens. This also shifts the default guest login to `user:development/guest` to reduce overlap with your production/real data. To change that (or set it back to the old default, use the new `auth.providers.guest.userEntityRef` config key) like so, + + ```yaml title=app-config.yaml + auth: + providers: + guest: + userEntityRef: user:default/guest + ``` + + This also adds a new property to control the ownership entity refs, + + ```yaml title=app-config.yaml + auth: + providers: + guest: + ownershipEntityRefs: + - guests + - development/custom + ``` + +### Patch Changes + +- 72dd380: Ensure that the config schema is present +- 50a331b: Fix issue for issuing a token when `guest` user does not exist in catalog +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-azure-devops@0.4.0 + +### Minor Changes + +- 9fdb86a: Ability to fetch the README file from a different Azure DevOps path. + + Defaults to the current, Azure DevOps default behaviour (`README.md` in the root of the git repo); to use a different path, add the annotation `dev.azure.com/readme-path` + + Example: + + ```yaml + dev.azure.com/readme-path: /my-path/README.md + ``` + +- a9e7bd6: **BREAKING** The `AzureDevOpsClient` no longer requires `identityAPi` but now requires `fetchApi`. + + Updated to use `fetchApi` as per [ADR013](https://backstage.io/docs/architecture-decisions/adrs-adr013) + +- 3270b1b: Azure DevOps plugin is now integrated with permission framework for its core features, see the <https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md#permission-framework> for more details. + +### Patch Changes + +- b7b0466: Remove the use of the deprecated `customStyles` for `Avatar` +- 9f19476: Updated README +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-azure-devops-common@0.4.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-devops-backend@0.6.0 + +### Minor Changes + +- 9fdb86a: Ability to fetch the README file from a different Azure DevOps path. + + Defaults to the current, Azure DevOps default behaviour (`README.md` in the root of the git repo); to use a different path, add the annotation `dev.azure.com/readme-path` + + Example: + + ```yaml + dev.azure.com/readme-path: /my-path/README.md + ``` + +- 3270b1b: Azure DevOps plugin is now integrated with permission framework for its core features, see the <https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md#permission-framework> for more details. + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. +- 2f77e24: The `azureDevOps` configuration section is now optional and the `azureDevOps.token` has been deprecated. Use `integrations.azure` instead, see the [Azure DevOps Locations](https://backstage.io/docs/integrations/azure/locations) documentation for more details. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-azure-devops-common@0.4.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-azure-devops-common@0.4.0 + +### Minor Changes + +- 9fdb86a: Ability to fetch the README file from a different Azure DevOps path. + + Defaults to the current, Azure DevOps default behaviour (`README.md` in the root of the git repo); to use a different path, add the annotation `dev.azure.com/readme-path` + + Example: + + ```yaml + dev.azure.com/readme-path: /my-path/README.md + ``` + +### Patch Changes + +- 3270b1b: Azure DevOps plugin is now integrated with permission framework for its core features, see the <https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md#permission-framework> for more details. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-azure-sites-backend@0.3.0 + +### Minor Changes + +- 6b802a2: **BREAKING**: The `createRouter` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. +- acf3e00: Azure Sites list now hides the internal/microsoft only `hidden-` tags from the list of tags that are returned. Updated the log endpoint to /logstream-quickstart rather than just /logstream to stream logs in the Azure Portal UI. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 4467036: Allow unauthenticated access to health check endpoint. +- 85db926: Added new backend system for the Azure Sites backend plugin +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-azure-sites-common@0.1.3 + +## @backstage/plugin-catalog@1.18.0 + +### Minor Changes + +- 72b8827: Adds a title to the `PaginatedCatalogTable` for better visibility on what you're viewing. + +### Patch Changes + +- 50b6687: Resolved an issue where the `PaginatedCatalogTable` was not propagating table options to its child table. +- 9332425: The entity page extension provided by the `/alpha` plugin now correctly renders the entity 404 page. +- 1c0b179: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- 2ac1630: Added support for passing in custom filters to `CatalogIndexPage` +- 298953b: Added support for providing an `initiallySelectedNamespaces` which accepts an array of Namespaces to have selected by default +- 6727665: Allow the `spec.target` field to be searchable in the catalog table for locations. Previously, only the `spec.targets` field was be searchable. This makes locations generated by providers such as the `GithubEntityProvider` searchable in the catalog table. [#23098](https://github.com/backstage/backstage/issues/23098) +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-catalog-backend@1.18.0 + +### Minor Changes + +- df12231: Allow setting EntityDataParser using CatalogModelExtensionPoint +- 15ba00f: Migrated to support new auth services. The `CatalogBuilder.create` method now accepts a `discovery` option, which is recommended to forward from the plugin environment, as it will otherwise fall back to use the `HostDiscovery` implementation. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 999224f: Bump dependency `minimatch` to v9 +- 6f830bb: Allow passing optional filter to `getEntitiesByRefs` +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- b65788b: Move @backstage/repo-tools to dev dependencies +- 280edeb: Add index for original value in search table for faster entity facet response +- dad018f: Do not fail on stitching when the entity contains `null` values associated to deeply nested or long keys. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-module-catalog@0.1.18 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-openapi-utils@0.1.7 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.0 + +### Minor Changes + +- 9e527c9: BREAKING CHANGE: Migrates the `BitbucketCloudEntityProvider` to use the `EventsService`; fix new backend system support. + + `BitbucketCloudEntityProvider.fromConfig` accepts `events: EventsService` as optional argument to its `options`. + With provided `events`, the event-based updates/refresh will be available. + However, the `EventSubscriber` interface was removed including its `supportsEventTopics()` and `onEvent(params)`. + + The event subscription happens on `connect(connection)` if the `events` is available. + + **Migration:** + + ```diff + const bitbucketCloudProvider = BitbucketCloudEntityProvider.fromConfig( + env.config, + { + catalogApi: new CatalogClient({ discoveryApi: env.discovery }), + + events: env.events, + logger: env.logger, + scheduler: env.scheduler, + tokenManager: env.tokenManager, + }, + ); + - env.eventBroker.subscribe(bitbucketCloudProvider); + ``` + + **New Backend System:** + + Before this change, using this module with the new backend system was broken. + Now, you can add the catalog module for Bitbucket Cloud incl. event support backend. + Event support will always be enabled. + However, no updates/refresh will happen without receiving events. + + ```ts + backend.add( + import('@backstage/plugin-catalog-backend-module-bitbucket-cloud/alpha'), + ); + ``` + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-bitbucket-cloud-common@0.2.17 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.0 + +### Minor Changes + +- 924c1ac: **BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` constructor is now private, and have been moved to using the static `.create` method instead which now requires a `PermissionService` and `DiscoveryService`. + + If you're using this module in the old backend system you'll need to migrate to using the `.create` method and pass in the new required parameters in `packages/backend/src/plugins/catalog.ts`. + + No changes should be required if you're using the new backend system. + + ```diff + - const unprocessed = new UnprocessedEntitiesModule( + - await env.database.getClient(), + - router, + - ); + + const unprocessed = UnprocessedEntitiesModule.create({ + + database: await env.database.getClient(), + + router, + + permissions: env.permissions, + + discovery: env.discovery, + + }); + + unprocessed.registerRoutes(); + ``` + + Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-node@1.8.0 + +### Minor Changes + +- df12231: Allow setting EntityDataParser using CatalogModelExtensionPoint + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-react@1.11.0 + +### Minor Changes + +- 72b8827: Number of results is now directly added as the field `totalItems` on `useEntityList`. + +### Patch Changes + +- 930b5c1: Added 'root' and 'label' class keys for EntityAutocompletePicker, EntityOwnerPicker and EntityProcessingStatusPicker +- b2a9926: Adds an argument for which filters should be applied when fetching/counting available values +- a6e237f: Added `DefaultFilters` component +- 298953b: Added support for providing an `initiallySelectedNamespaces` which accepts an array of Namespaces to have selected by default +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.0 + +### Minor Changes + +- 924c1ac: **BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` constructor is now private, and have been moved to using the static `.create` method instead which now requires a `PermissionService` and `DiscoveryService`. + + If you're using this module in the old backend system you'll need to migrate to using the `.create` method and pass in the new required parameters in `packages/backend/src/plugins/catalog.ts`. + + No changes should be required if you're using the new backend system. + + ```diff + - const unprocessed = new UnprocessedEntitiesModule( + - await env.database.getClient(), + - router, + - ); + + const unprocessed = UnprocessedEntitiesModule.create({ + + database: await env.database.getClient(), + + router, + + permissions: env.permissions, + + discovery: env.discovery, + + }); + + unprocessed.registerRoutes(); + ``` + + Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance. + +### Patch Changes + +- 2b397fe: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-devtools-backend@0.3.0 + +### Minor Changes + +- 4dc5b48: **BREAKING**: The `createRouter` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 4467036: Allow unauthenticated access to health check endpoint. +- 8b0026d: Removed unused `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/config-loader@1.7.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9 + +## @backstage/plugin-events-backend@0.3.0 + +### Minor Changes + +- c4bd794: BREAKING CHANGE: Migrate `HttpPostIngressEventPublisher` and `eventsPlugin` to use `EventsService`. + + Uses the `EventsService` instead of `EventBroker` at `HttpPostIngressEventPublisher`, + dropping the use of `EventPublisher` including `setEventBroker(..)`. + + Now, `HttpPostIngressEventPublisher.fromConfig` requires `events: EventsService` as option. + + ```diff + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + + events: env.events, + logger: env.logger, + }); + http.bind(eventsRouter); + + // e.g. at packages/backend/src/plugins/events.ts + - await new EventsBackend(env.logger) + - .setEventBroker(env.eventBroker) + - .addPublishers(http) + - .start(); + + // or for other kinds of setups + - await Promise.all(http.map(publisher => publisher.setEventBroker(eventBroker))); + ``` + + `eventsPlugin` uses the `eventsServiceRef` as dependency. + Unsupported (and deprecated) extension point methods will throw an error to prevent unintended behavior. + + ```ts + import { eventsServiceRef } from '@backstage/plugin-events-node'; + ``` + +### Patch Changes + +- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system. + + **Summary:** + + - new: + `EventsService`, `eventsServiceRef`, `TestEventsService` + - deprecated: + `EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`, + most parts of `EventsExtensionPoint` (alpha), + `TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber` + + Add the `eventsServiceRef` as dependency to your backend plugins + or backend plugin modules. + + **Details:** + + The previous implementation using the `EventsExtensionPoint` was added in the early stages + of the new backend system and does not respect the plugin isolation. + This made it not compatible anymore with the new backend system. + + Additionally, the previous interfaces had some room for simplification, + supporting less exposure of internal concerns as well. + + Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`. + The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore. + Instead, it is expected that the `EventsService` gets passed into publishers and subscribers, + and used internally. There is no need to expose anything of that at their own interfaces. + + Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable + (by other plugins or their modules) anyway. + + The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation. + Optionally, an instance can be passed as argument to allow mixed setups to operate alongside. + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.0 + +### Minor Changes + +- 132d672: BREAKING CHANGE: Migrate `AwsSqsConsumingEventPublisher` and its backend module to use `EventsService`. + + Uses the `EventsService` instead of `EventBroker` at `AwsSqsConsumingEventPublisher`, + dropping the use of `EventPublisher` including `setEventBroker(..)`. + + Now, `AwsSqsConsumingEventPublisher.fromConfig` requires `events: EventsService` as option. + + ```diff + const sqs = AwsSqsConsumingEventPublisher.fromConfig({ + config: env.config, + + events: env.events, + logger: env.logger, + scheduler: env.scheduler, + }); + + await Promise.all(sqs.map(publisher => publisher.start())); + + // e.g. at packages/backend/src/plugins/events.ts + - await new EventsBackend(env.logger) + - .setEventBroker(env.eventBroker) + - .addPublishers(sqs) + - .start(); + + // or for other kinds of setups + - await Promise.all(sqs.map(publisher => publisher.setEventBroker(eventBroker))); + ``` + + `eventsModuleAwsSqsConsumingEventPublisher` uses the `eventsServiceRef` as dependency, + instead of `eventsExtensionPoint`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/backend-tasks@0.5.19 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-events-backend-module-gerrit@0.2.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-events-backend-module-github@0.2.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-events-backend-module-gitlab@0.2.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-events-node@0.3.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system. + + **Summary:** + + - new: + `EventsService`, `eventsServiceRef`, `TestEventsService` + - deprecated: + `EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`, + most parts of `EventsExtensionPoint` (alpha), + `TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber` + + Add the `eventsServiceRef` as dependency to your backend plugins + or backend plugin modules. + + **Details:** + + The previous implementation using the `EventsExtensionPoint` was added in the early stages + of the new backend system and does not respect the plugin isolation. + This made it not compatible anymore with the new backend system. + + Additionally, the previous interfaces had some room for simplification, + supporting less exposure of internal concerns as well. + + Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`. + The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore. + Instead, it is expected that the `EventsService` gets passed into publishers and subscribers, + and used internally. There is no need to expose anything of that at their own interfaces. + + Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable + (by other plugins or their modules) anyway. + + The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation. + Optionally, an instance can be passed as argument to allow mixed setups to operate alongside. + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-home@0.7.0 + +### Minor Changes + +- 8807d2a: Resolved styling inconsistencies and title visibility issues in Top Visited and Recently Visited cards + +### Patch Changes + +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- 2e17681: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-home-react@0.1.9 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-jenkins-backend@0.4.0 + +### Minor Changes + +- 55191cc: **BREAKING**: Both `createRouter` and `DefaultJenkinsInfoProvider.fromConfig` now require the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + + The `JenkinsInfoProvider` interface has been updated to receive `credentials` of the type `BackstageCredentials` rather than a token. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-jenkins-common@0.1.25 + +## @backstage/plugin-kubernetes-backend@0.16.0 + +### Minor Changes + +- e1e540c: **BREAKING**: The `KubernetesBuilder.createBuilder` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + +### Patch Changes + +- b9a0888: Fixed a bug in the proxy endpoint. Now when the `serviceAccount` strategy is used and no `serviceAccountToken` has been provided, the proxy endpoint assumes backstage is running on Kubernetes and gets the URL and CA from the Pod instance. +- 69d0217: Pass user credentials when calling catalog get entities api. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/plugin-kubernetes-node@0.1.8 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/catalog-model@1.4.5 + - @backstage/integration-aws-node@0.1.10 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications@0.1.0 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options +- cd96173: Notifications-backend URL query parameters changed from `sort/sortOrder` to `orderField` and `created_after` to `createdAfter` to unify with other plugins. +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- dff7a7e: All notifications can be marked and filtered by severity critical, high, normal or low, the default is 'normal' +- 75f2d84: the user can newly mark notifications as "Saved" for their better visibility in the future +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## @backstage/plugin-notifications-backend@0.1.0 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options +- cd96173: Notifications-backend URL query parameters changed from `sort/sortOrder` to `orderField` and `created_after` to `createdAfter` to unify with other plugins. +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- ba14c0e: Support for broadcast notifications + +- dff7a7e: All notifications can be marked and filtered by severity critical, high, normal or low, the default is 'normal' + +- 4467036: Allow unauthenticated access to health check endpoint. + +- 6c1547a: **BREAKING** Type definition added to signal recipients + + Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}` + instead string entity references + +- 75f2d84: the user can newly mark notifications as "Saved" for their better visibility in the future + +- a790a3d: Move notification origin resolving to backend with new auth + +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- 84af361: Migrated to using the new auth services. + +- 6d84ee6: Changed to use the refactored signal service naming + +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-notifications-node@0.1.0 + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-notifications-node@0.1.0 + +### Minor Changes + +- 84af361: Migrated to using the new auth services. + +### Patch Changes + +- ba14c0e: Support for broadcast notifications +- a790a3d: Move notification origin resolving to backend with new auth +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-scaffolder@1.19.0 + +### Minor Changes + +- a3b4d90: Added a menu to the header of template page for direct access to editing the template + +### Patch Changes + +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- a7e6fb3: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-scaffolder-react@1.8.1 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend@1.22.0 + +### Minor Changes + +- e9663a9: Move away from using `ctx.logStream` +- aa543c9: Migrate plugin to use the new auth services, add an optional service discovery to the router options and change the permissions type to be `PermissionsService`. +- e9663a9: Enable the redaction of secrets using the redacting logger and the secrets from the `TaskSpec` +- c6b132e: Introducing checkpoints for scaffolder task action idempotency + +### Patch Changes + +- 984abfa: Fixing the lost of the initial state after a task recovery. + +- 703ebc9: Fix support for unauthenticated requests to create scaffolder tasks + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0 + +### Minor Changes + +- 6bfb7b1: Output the `iid` as `issuesIid` from the `gitlab:issues:create` action + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-node@0.4.0 + +### Minor Changes + +- 02ee466: **DEPRECATION** - Deprecated the `logStream` in the `ActionContext`. Please move to using `ctx.logger.x` instead. +- aa543c9: Update task context type to contain the new auth initiator credentials. + +### Patch Changes + +- 85f4723: Fixed file corruption for non UTF-8 data in fetch contents +- 984abfa: Fixing the lost of the initial state after a task recovery. +- c6b132e: Introducing checkpoints for scaffolder task action idempotency +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.0 + +### Minor Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- aa543c9: Add an initiator credentials getter to the default mock context. +- 563dfd0: Fix issue with package bundling, should be `dist/index.cjs.js` instead of `dist/index.esm.js`. +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/backend-test-utils@0.3.4 + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-backend@0.1.0 + +### Minor Changes + +- 6c1547a: **BREAKING** Type definition added to signal recipients + + Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}` + instead string entity references + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 6d84ee6: Changed to use the refactored signal service naming +- df45710: Improved error logging and fixed authentication +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.0 + +### Minor Changes + +- 6c1547a: **BREAKING** Type definition added to signal recipients + + Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}` + instead string entity references + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- 6d84ee6: Renamed `SignalService` to `SignalsService` and `signalService` to `signalServiceRef` + to follow the naming scheme of services and their references +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-tech-insights-node@0.5.0 + +### Minor Changes + +- d621468: **BREAKING**: The `FactRetrieverContext` type now contains an additional `auth` field. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.7.0 + +### Minor Changes + +- 0453619: Fixed example snippet in `README.md` to reflect correct timeline item order. + +### Patch Changes + +- a2327ac: Fixed an issue with the "moved in direction" table header cell getting squished and becoming unreadable if a timeline description is too long +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-techdocs-backend@1.10.0 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- 3f14e9f: Migrate plugin to use the new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-module-techdocs@0.1.18 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-techdocs-node@1.12.0 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- 5b4f565: Fix handling of default plugins that have configuration +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/integration-aws-node@0.1.10 + +## @backstage/plugin-techdocs-react@1.2.0 + +### Minor Changes + +- 3f14e9f: Create a new api method for issuing user cookie. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/app-defaults@1.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/backend-common@0.21.4 + +### Patch Changes + +- 7422430: Resolve the `basePath` before constructing the target path + +- 999224f: Bump dependency `minimatch` to v9 + +- e0b997c: Fix issue where `resolveSafeChildPath` path would incorrectly resolve when operating on a symlink + +- 9802004: Added the `UserInfoApi` as both an optional input and as an output for `createLegacyAuthAdapters` + +- 2af5354: Bump dependency `jose` to v5 + +- ff40ada: Updated dependency `mysql2` to `^3.0.0`. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- 568881f: Updated dependency `yauzl` to `^3.0.0`. + +- 4a3d434: Added a `createLegacyAuthAdapters` function that can be used as a compatibility adapter for backend plugins who want to start using the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). + + See the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on the usage of this adapter. + +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/backend-app-api@0.6.0 + - @backstage/config-loader@1.7.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/integration-aws-node@0.1.10 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.14 + +### Patch Changes + +- 7cbb760: Added support for the new auth services, which are now installed by default. See the [migration guide](https://backstage.io/docs/tutorials/auth-service-migration) for details. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/backend-app-api@0.6.0 + +## @backstage/backend-dynamic-feature-service@0.2.4 + +### Patch Changes + +- 5247909: Add `events: EventsService` to `LegacyPluginEnvironment`. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-events-backend@0.3.0 + - @backstage/plugin-events-node@0.3.0 + - @backstage/plugin-catalog-backend@1.18.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/backend-app-api@0.6.0 + - @backstage/config-loader@1.7.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/cli-node@0.2.4 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.14 + +## @backstage/backend-openapi-utils@0.1.7 + +### Patch Changes + +- 85ec23e: Updated dependency `json-schema-to-ts` to `^3.0.0`. +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/backend-plugin-api@0.6.14 + +### Patch Changes + +- 4a3d434: Added the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/), [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth), and [`userInfo`](https://backstage.io/docs/backend-system/core-services/user-info) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution) to the `coreServices`. + + At the same time, the [`httpRouter`](https://backstage.io/docs/backend-system/core-services/http-router) service gained a new `addAuthPolicy` method that lets your plugin declare exemptions to the default auth policy - for example if you want to allow unauthenticated or cookie-based access to some subset of your feature routes. + + If you have migrated to the new backend system, please see the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on how to move toward using these services. + +- 0502d82: Updated the `PermissionsService` methods to accept `BackstageCredentials` through options. + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/backend-tasks@0.5.19 + - @backstage/types@1.1.1 + +## @backstage/backend-tasks@0.5.19 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.4 + +### Patch Changes + +- 4a3d434: Added support for the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). These services will be present by default in test apps, and you can access mocked versions of their features under `mockServices.auth` and `mockServices.httpAuth` if you want to inspect or replace their behaviors. + + There is also a new `mockCredentials` that you can use for acquiring mocks of the various types of credentials that are used in the new system. + +- 9802004: Added `mockServices.userInfo`, which now also automatically is made available in test backends. + +- fd61d39: Updated dependency `testcontainers` to `^10.0.0`. + +- ff40ada: Updated dependency `mysql2` to `^3.0.0`. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/backend-app-api@0.6.0 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.1 + +### Patch Changes + +- 6f830bb: Allow passing optional filter to `getEntitiesByRefs` +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/catalog-model@1.4.5 + +## @backstage/catalog-model@1.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/codemods@0.1.48 + +### Patch Changes + +- 1bd4596: Removed the `ts-node` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/core-app-api@1.12.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.1 + +### Patch Changes + +- 2ff3e6e: The translation support for the `Link` component has been removed for now, in order to avoid broad breakages of tests in existing projects where the component is tested without being wrapped in an API provider. +- 2d06e4b: Move the text-transform styling on BackstageTableHeader from inline styling to `withStyles` so it can be customised easier +- 5c271fa: Removed inline styling in breadcrumbs and replaced with a theme reachable class of BreadcrumbsCurrentPage +- ff33ee2: Removed hardcoded font-family on select input +- ff7e126: Support i18n for core components +- 7854120: Create a component abstraction to consume system icons. +- ce73c3b: Removed the inline color from select icon to allow it to be colored via a theme +- 0c9d5ea: Updated MUI imports for core-components to not be top level +- 90d08b0: Updated dependency `react-idle-timer` to `5.7.2`. +- a8f7904: `SignInPage`'s `'guest'` provider now supports the `@backstage/plugin-auth-backend-module-guest-provider` package to generate tokens. It will continue to use the old frontend-only auth as a fallback. +- 0a8a1e9: Fix a spacing issue for the SidebarSubmenu in case a SidebarScrollWrapper is used that made it hard to reach the SidebarSubmenu +- aa1c88d: Deprecate the `customStyles` prop for the `Avatar` component in favour of the `classes` prop. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-plugin-api@1.9.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.12 + +### Patch Changes + +- 4cca80f: Bumped create-app version. +- 8db51ca: Bumped create-app version. +- 778bc48: Bumped create-app version. +- 1bd4596: Removed the `ts-node` dev dependency. +- 829a249: Migrated the backend of the create app template to use the new backend system. For information on how to migrate your existing backend, see the [migration guide](https://backstage.io/docs/backend-system/building-backends/migrating). +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/app-defaults@1.5.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/errors@1.2.4 + +### Patch Changes + +- 2636075: Fixed an issue that was causing ResponseError not to report the HTTP status from the provided response. +- Updated dependencies + - @backstage/types@1.1.1 + +## @backstage/eslint-plugin@0.1.6 + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 + +## @backstage/frontend-app-api@0.6.1 + +### Patch Changes + +- 48d6628: Add `loadingComponent` parameter to `createApp()` +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/test-utils@1.5.1 + - @backstage/types@1.1.1 + +## @backstage/integration@1.9.1 + +### Patch Changes + +- 0386fa7: Fixed an issue with resolution of SCM URLs against a base URL with a trailing slash. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/integration-aws-node@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/integration-react@1.1.25 + +### Patch Changes + +- b38dc55: Updated `microsoftAuthApi` scopes for Azure DevOps to be fully qualified. +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + +## @techdocs/cli@1.8.6 + +### Patch Changes + +- 1bd4596: Removed the `ts-node` dev dependency. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + +## @backstage/test-utils@1.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/theme@0.5.2 + +### Patch Changes + +- 6f4d2a0: Exported `defaultTypography` to make adjusting these values in a custom theme easier + +## @backstage/plugin-adr@0.6.14 + +### Patch Changes + +- 5335634: Fixed Azure DevOps ADR file path reading +- 669efc6: Remove unused package dependencies +- 38b92a0: Added ESLint rule `no-top-level-material-ui-4-imports` in the ADR plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/plugin-adr-common@0.2.21 + - @backstage/core-components@0.14.1 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-adr-backend@0.4.11 + +### Patch Changes + +- 334c5fe: Updated dependency `marked` to `^12.0.0`. +- c8fdd83: Migrated `DefaultAdrCollatorFactory` to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/plugin-adr-common@0.2.21 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-adr-common@0.2.21 + +### Patch Changes + +- 5335634: Fixed Azure DevOps ADR file path reading +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-airbrake@0.3.31 + +### Patch Changes + +- 31d58ae: Added an optional ESLint rule - no-top-level-material-ui-4-imports - which has an auto fix function to migrate the imports and using it migrated the imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/dev-utils@1.0.28 + - @backstage/test-utils@1.5.1 + +## @backstage/plugin-airbrake-backend@0.3.11 + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-allure@0.1.47 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-analytics-module-ga@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-analytics-module-ga4@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-apache-airflow@0.2.21 + +### Patch Changes + +- 161114f: added an optional ESLint rule - no-top-level-material-ui-4-imports - which has an auto fix function to migrate the imports and used it to migrate the imports for plugins/apache-airflow +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-api-docs@0.11.1 + +### Patch Changes + +- c60dc3b: added an optional ESLint rule - no-top-level-material-ui-4-imports - in api-docs plugin which has an auto fix function to migrate the imports and used it to migrate the material-ui imports for plugins/api-docs +- 7854120: Use the `AppIcon` component in the navigation item extension. +- 2be27b9: Updated dependency `graphiql` to `3.1.1`. +- efba3d2: Updated dependency `@asyncapi/react-component` to `1.3.1`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-apollo-explorer@0.1.21 + +### Patch Changes + +- bb9e31e: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in apollo-explorer plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/apollo-explorer. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-app-backend@0.3.62 + +### Patch Changes + +- 52e43f2: Disable default auth policy, allowing unauthenticated access to app bundle. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/config-loader@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.14 + +## @backstage/plugin-app-node@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14 + - @backstage/config-loader@1.7.0 + +## @backstage/plugin-app-visualizer@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.6 + +### Patch Changes + +- c511186: Addressed OAuth flow issue in Atlassian auth module +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.5 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-auth-backend@0.22.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.9 + +### Patch Changes + +- 38af71a: Updated dependency `google-auth-library` to `^9.0.0`. +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.11 + +### Patch Changes + +- 38af71a: Updated dependency `google-auth-library` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.9 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.7 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- e77d7a9: Internal refactor to avoid deprecated method. +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.4 + +### Patch Changes + +- 74b1dc9: Increased HTTP request timeout used by OIDC authenticator. +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-auth-backend@0.22.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.8 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.6 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-auth-node@0.4.9 + +### Patch Changes + +- b4fc6e3: Deprecated the `getBearerTokenFromAuthorizationHeader` function, which is being replaced by the new `HttpAuthService`. +- 2af5354: Bump dependency `jose` to v5 +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.0.1 + +### Patch Changes + +- 62bcaf8: Create a generic React component for refreshing user cookie. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-azure-sites@0.1.20 + +### Patch Changes + +- 8679bda: Modified azure table to only show loading UI on initial load. Sorted tags in table is their order from the api is indeterminate, and they would randomly shuffle on each load +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-sites-common@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-badges@0.2.55 + +### Patch Changes + +- 944de94: Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-badges-backend@0.3.11 + +### Patch Changes + +- 29a1f91: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-bazaar@0.2.23 + +### Patch Changes + +- b7b0466: Remove the use of the deprecated `customStyles` for `Avatar` +- cb64381: Added an optional ESLint rule - no-top-level-material-ui-4-imports - in bazaar plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/bazaar +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-bazaar-backend@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-bitbucket-cloud-common@0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1 + +## @backstage/plugin-bitrise@0.1.58 + +### Patch Changes + +- afdee56: Added the `no-top-level-material-ui-4-import` ESLint rule to the Bitrise plugin to aid with the migration to Material UI v5. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-catalog-backend-module-aws@0.3.8 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/catalog-model@1.4.5 + - @backstage/integration-aws-node@0.1.10 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-azure@0.1.33 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.7 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 43a9ae1: Migrated to use new auth service. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-openapi-utils@0.1.7 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.27 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.30 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + +## @backstage/plugin-catalog-backend-module-github@0.5.4 + +### Patch Changes + +- a936a8f: Migrated the `GithubLocationAnalyzer` to support new auth services. + +- 999224f: Bump dependency `minimatch` to v9 + +- 2eb0da3: Support EventsService and events with the new backend system (through EventsService) for `GithubOrgEntityProvider` and `GithubMultiOrgEntityProvider`. + + _New/Current Backend System:_ + + The events support for the provider will be enabled always, making it ready to consume events from its subscribed topics. + In order to receive events and make use of this feature, you still need to set up receiving events from the event source as before. + + _Legacy Backend System:_ + + You can pass the `EventsService` instance to the factory method as one of its options: + + ```diff + // packages/backend/src/plugins/catalog.ts + const githubOrgProvider = GithubOrgEntityProvider.fromConfig(env.config, { + events: env.events, + // ... + }); + - env.eventBroker.subscribe(githubOrgProvider); + ``` + + ```diff + // packages/backend/src/plugins/catalog.ts + const githubMultiOrgProvider = GithubMultiOrgEntityProvider.fromConfig(env.config, { + events: env.events, + // ... + }); + - env.eventBroker.subscribe(githubMultiOrgProvider); + ``` + +- bcf55d5: Support EventsService and events with the new backend system (through EventsService). + + _New/Current Backend System:_ + + The events support for the provider will be enabled always, making it ready to consume events from its subscribed topics. + In order to receive events and make use of this feature, you still need to set up receiving events from the event source as before. + + _Legacy Backend System:_ + + You can pass the `EventsService` instance to the factory method as one of its options: + + ```diff + // packages/backend/src/plugins/catalog.ts + const githubProvider = GithubEntityProvider.fromConfig(env.config, { + + events: env.events, + logger: env.logger, + scheduler: env.scheduler, + }); + - env.eventBroker.subscribe(githubProvider); + ``` + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- 9eab52a: Add location analyzer when installing the module + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/plugin-catalog-backend@1.18.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.8 + +### Patch Changes + +- 2eb0da3: Support EventsService and events with the new backend system (through EventsService) for `GithubOrgEntityProvider` and `GithubMultiOrgEntityProvider`. + + _New/Current Backend System:_ + + The events support for the provider will be enabled always, making it ready to consume events from its subscribed topics. + In order to receive events and make use of this feature, you still need to set up receiving events from the event source as before. + + _Legacy Backend System:_ + + You can pass the `EventsService` instance to the factory method as one of its options: + + ```diff + // packages/backend/src/plugins/catalog.ts + const githubOrgProvider = GithubOrgEntityProvider.fromConfig(env.config, { + events: env.events, + // ... + }); + - env.eventBroker.subscribe(githubOrgProvider); + ``` + + ```diff + // packages/backend/src/plugins/catalog.ts + const githubMultiOrgProvider = GithubMultiOrgEntityProvider.fromConfig(env.config, { + events: env.events, + // ... + }); + - env.eventBroker.subscribe(githubMultiOrgProvider); + ``` + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-backend-module-github@0.5.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.11 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 9f5b8bc: Add GitLab `visibility` to group entity annotations. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.18 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/plugin-catalog-backend@1.18.0 + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.29 + +### Patch Changes + +- 4b4bbf7: Add TLS support to ingest GSuite LDAP data +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.21 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.18.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.19 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-catalog-common@1.0.22 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-graph@0.4.1 + +### Patch Changes + +- d4ff0bb: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.7 + +### Patch Changes + +- b91a8d2: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- 75f686b: Fixed an issue generating a wrong entity link at the end of the import process +- adc0414: fix related to component name not adhering to kubernetes valid object name. +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + +### Patch Changes + +- 924c1ac: **BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` constructor is now private, and have been moved to using the static `.create` method instead which now requires a `PermissionService` and `DiscoveryService`. + + If you're using this module in the old backend system you'll need to migrate to using the `.create` method and pass in the new required parameters in `packages/backend/src/plugins/catalog.ts`. + + No changes should be required if you're using the new backend system. + + ```diff + - const unprocessed = new UnprocessedEntitiesModule( + - await env.database.getClient(), + - router, + - ); + + const unprocessed = UnprocessedEntitiesModule.create({ + + database: await env.database.getClient(), + + router, + + permissions: env.permissions, + + discovery: env.discovery, + + }); + + unprocessed.registerRoutes(); + ``` + + Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance. + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-cicd-statistics@0.1.33 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.27 + +### Patch Changes + +- 402d991: Align `p-limit` dependency version to v3 +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-cicd-statistics@0.1.33 + +## @backstage/plugin-circleci@0.3.31 + +### Patch Changes + +- 88878a4: Added an optional ESLint rule - no-top-level-material-ui-4-imports - in CircleCI plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for `plugins/circleci`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-cloudbuild@0.4.1 + +### Patch Changes + +- 7a5e933: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in cloudbuild plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/cloudbuild. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-code-climate@0.1.31 + +### Patch Changes + +- 875c594: Added ESLint rule `no-top-level-material-ui-4-imports` in the Code-Climate plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-code-coverage@0.2.24 + +### Patch Changes + +- eca0835: Added ESLint rule `no-top-level-material-ui-4-imports` in the Code-Coverage plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-code-coverage-backend@0.2.28 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 4467036: Allow unauthenticated access to health check endpoint. +- cceebae: Fix jacoco convertor to not require annotation to be set to scm-only. +- 8efe690: Migrated to support new auth services. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 1914e2a: Updated README +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-codescene@0.1.23 + +### Patch Changes + +- e477ec4: Extending code scene plugin in Entity page. +- f2d3ea0: Added ESLint rule `no-top-level-material-ui-4-imports` in the Codescene plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-config-schema@0.1.51 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.20 + +### Patch Changes + +- 083ba28: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- 1b4fd09: Updated dependency `yup` to `^1.0.0`. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.10 + +### Patch Changes + +- a0e3393: Updated to use `fetchApi` as per [ADR013](https://backstage.io/docs/architecture-decisions/adrs-adr013) +- 8b0026d: Removed unused `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-devtools-common@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/types@1.1.1 + +## @backstage/plugin-dynatrace@10.0.0 + +### Patch Changes + +- e550b2b: Adjusted MUI imports for better tree shaking +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-entity-feedback@0.2.14 + +### Patch Changes + +- 96adf78: Remove empty Chip in `FeedbackResponseTable.tsx` when there is no response, and fix typo in Feedback Dialog Box. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.11 + +### Patch Changes + +- 45115fd: Add in description for 400 response when encountering an invalid rating request +- 4f8ecd6: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-events-backend-test-utils@0.1.24 + +### Patch Changes + +- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system. + + **Summary:** + + - new: + `EventsService`, `eventsServiceRef`, `TestEventsService` + - deprecated: + `EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`, + most parts of `EventsExtensionPoint` (alpha), + `TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber` + + Add the `eventsServiceRef` as dependency to your backend plugins + or backend plugin modules. + + **Details:** + + The previous implementation using the `EventsExtensionPoint` was added in the early stages + of the new backend system and does not respect the plugin isolation. + This made it not compatible anymore with the new backend system. + + Additionally, the previous interfaces had some room for simplification, + supporting less exposure of internal concerns as well. + + Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`. + The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore. + Instead, it is expected that the `EventsService` gets passed into publishers and subscribers, + and used internally. There is no need to expose anything of that at their own interfaces. + + Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable + (by other plugins or their modules) anyway. + + The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation. + Optionally, an instance can be passed as argument to allow mixed setups to operate alongside. + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + +## @backstage/plugin-explore@0.4.17 + +### Patch Changes + +- 053d43f: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in explore plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/explore. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-explore-backend@0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-backend-module-explore@0.1.18 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-explore-react@0.0.37 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-fossa@0.2.63 + +### Patch Changes + +- 89cdfad: Adjusted MUI imports for better tree shaking +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-gcalendar@0.3.24 + +### Patch Changes + +- 9c9e0a1: Added ESLint rule `no-top-level-material-ui-4-imports` in the `gcalendar` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-gcp-projects@0.3.47 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-git-release-manager@0.3.43 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-github-actions@0.6.12 + +### Patch Changes + +- 8ab3218: Fixed bug in WorkflowRunStatus component where skipped and cancelled workflow runs appeared as success +- 692316d: Fixed bug in WorkflowRunStatus component where status description of skipped and cancelled workflow runs appeared as success +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-github-deployments@0.1.62 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-github-issues@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-github-pull-requests-board@0.1.25 + +### Patch Changes + +- 3c2d7c0: The `CardHeader` component in the `github-pull-requests-board` plugin will show the status for the PR +- 402d991: Align `p-limit` dependency version to v3 +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-gitops-profiles@0.3.46 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-gocd@0.1.37 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-graphiql@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + +## @backstage/plugin-graphql-voyager@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-home-react@0.1.9 + +### Patch Changes + +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-ilert@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-jenkins@0.9.6 + +### Patch Changes + +- 75277ab: Added ESLint rule `no-top-level-material-ui-4-imports` in the Jenkins plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-jenkins-common@0.1.25 + +## @backstage/plugin-jenkins-common@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-kafka@0.3.31 + +### Patch Changes + +- 3913fd8: Added ESLint rule `no-top-level-material-ui-4-imports` in the Kafka plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-kafka-backend@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-kubernetes@0.11.6 + +### Patch Changes + +- 0e1941b: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in kubernetes plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/kubernetes. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-kubernetes-react@0.3.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-kubernetes-cluster@0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-kubernetes-react@0.3.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-kubernetes-common@0.7.5 + +### Patch Changes + +- 4642cb7: Add support to fetch data for Daemon Sets and display an accordion in the same way as with Deployments +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-node@0.1.8 + +### Patch Changes + +- 69d0217: Accept auth credentials to get kubernetes clusters +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-react@0.3.1 + +### Patch Changes + +- 4642cb7: Add support to fetch data for Daemon Sets and display an accordion in the same way as with Deployments +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-lighthouse@0.4.16 + +### Patch Changes + +- c4c8476: Added ESLint rule `no-top-level-material-ui-4-imports` in the Lighthouse plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-lighthouse-backend@0.4.6 + +### Patch Changes + +- 9f9ba70: **BREAKING**: The `createScheduler` function now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-lighthouse-common@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + +## @backstage/plugin-linguist@0.1.16 + +### Patch Changes + +- 4fb9600: Get component's title from translation file. See: <https://backstage.io/docs/plugins/internationalization#for-an-application-developer-overwrite-plugin-messages> +- a0e3393: Updated to use `fetchApi` as per [ADR013](https://backstage.io/docs/architecture-decisions/adrs-adr013) +- 786c9c4: Updated dependency `luxon` to `^3.0.0`. +- 051fda1: Removed unused `dependencies` and `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.11 + +### Patch Changes + +- 61ff58f: Migrated to support new auth services. +- 4467036: Allow unauthenticated access to health check endpoint. +- 786c9c4: Updated dependency `luxon` to `^3.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 051fda1: Removed unused `dependencies` and `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-newrelic@0.3.46 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-newrelic-dashboard@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-nomad@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-nomad-backend@0.1.16 + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-notifications-common@0.0.2 + +### Patch Changes + +- ba14c0e: Support for broadcast notifications +- a790a3d: Move notification origin resolving to backend with new auth +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +## @backstage/plugin-octopus-deploy@0.2.13 + +### Patch Changes + +- a207927: Added dropdown field extension for Octopus Deploy project groups +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-scaffolder-react@1.8.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-opencost@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-org@0.6.21 + +### Patch Changes + +- b7b0466: Remove the use of the deprecated `customStyles` for `Avatar` +- 526f00a: Document the new frontend system extensions for the org plugin. +- 2219f8c: Add `relationsType` argument to `MembersListCard`. + This can be used to display an aggregated user list for groups by default. +- a767aaa: Fixed an issue where the `OwnershipCard` component failed to scroll properly when used alongside `react-grid-layout`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-org-react@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-pagerduty@0.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-home-react@0.1.9 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-periskop@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-periskop-backend@0.2.12 + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-permission-backend@0.5.37 + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. + +- 9802004: Migrated to use the new auth services introduced in [BEP-0003](https://github.com/backstage/backstage/blob/master/beps/0003-auth-architecture-evolution/README.md). + + The `createRouter` function now accepts `auth`, `httpAuth` and `userInfo` options. Theses are used internally to support the new backend system, and can be ignored. + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.25 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.25 + +## @backstage/plugin-permission-common@0.7.13 + +### Patch Changes + +- 0502d82: The `token` option of the `PermissionEvaluator` methods is now deprecated. The options that only apply to backend implementations have been moved to `PermissionsService` from `@backstage/backend-plugin-api` instead. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-node@0.7.25 + +### Patch Changes + +- 0502d82: The `ServerPermissionClient` has been migrated to implement the `PermissionsService` interface, now accepting the new `BackstageCredentials` object in addition to the `token` option, which is now deprecated. It now also optionally depends on the new `AuthService`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-react@0.4.21 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-playlist@0.2.5 + +### Patch Changes + +- fbb705c: Adjusted MUI imports for better tree shaking. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist-common@0.1.15 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-playlist-backend@0.3.18 + +### Patch Changes + +- 6813366: Migrated to support new auth services. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-playlist-common@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-proxy-backend@0.4.12 + +### Patch Changes + +- 1b4fd09: Updated dependency `yup` to `^1.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-puppetdb@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-rollbar@0.4.31 + +### Patch Changes + +- 2481d8a: Adjusted MUI imports for better tree shaking. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-rollbar-backend@0.1.59 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.6 + +### Patch Changes + +- 2bd1410: Removed unused dependencies + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies + +- 0e48aaf: Added an option to specify a commit author by adding `gitAuthorName` and `gitAuthorEmail` options to the `publish:bitbucketServer:pull-request` action + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.15 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.38 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.4 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 9f19476: Updated README + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.4 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 35fe005: Export `getOctokitOptions` for easy re-use of Octokit configuration handling + +- 1753898: Updated dependency `octokit-plugin-create-pull-request` to `^5.0.0`. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.31 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.22 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.35 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-common@1.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.1 + +### Patch Changes + +- 930b5c1: Added 'root' and 'label' class key to TemplateCategoryPicker +- 6d649d2: Updated dependency `flatted` to `3.3.1`. +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-search@1.4.7 + +### Patch Changes + +- 70ee3b7: Remove the hardcoded 'black' color give to the search type accordion icon as it doesn't work with dark themes +- f0464b0: Removes ADR from the default set of search filters +- cd872b9: Added ESLint rule `no-top-level-material-ui-4-imports` in the `search` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-search-backend@1.5.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 744c0cb: Update the router to use the new `auth` services, it now accepts an optional discovery service option to get credentials for the permission service. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-openapi-utils@0.1.7 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-backend-module-catalog@0.1.18 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.17 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- e1f73d0: Added config.d.ts entry with secrets for the shared auth block +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/integration-aws-node@0.1.10 + +## @backstage/plugin-search-backend-module-explore@0.1.18 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-search-backend-module-pg@0.5.23 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-backend-node@1.2.18 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.1.18 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-search-backend-node@1.2.18 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 744c0cb: Exports `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` types. These new types were extracted from the `@backstage/plugin-search-common` package and the `token` property was deprecated in favor of the a new credentials one. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + +## @backstage/plugin-search-common@1.2.11 + +### Patch Changes + +- 744c0cb: Deprecate `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` in favor of the types exported from `@backstage/plugin-search-backend-node`. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-react@1.7.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-sentry@0.5.16 + +### Patch Changes + +- 2df7265: Added ESLint rule `no-top-level-material-ui-4-imports` in the `sentry` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-shortcuts@0.3.20 + +### Patch Changes + +- 26a15f7: Added ESLint rule `no-top-level-material-ui-4-imports` in the `shortcuts` plugin to migrate the Material UI imports. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.2 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 72df7c6: Added ESLint rule `no-top-level-material-ui-4-imports` in the `signals` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## @backstage/plugin-signals-react@0.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.13 + +### Patch Changes + +- e38b29c: Added ESLint rule `no-top-level-material-ui-4-imports` in the `sonarqube` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-sonarqube-react@0.1.14 + +## @backstage/plugin-sonarqube-backend@0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-sonarqube-react@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-splunk-on-call@0.4.20 + +### Patch Changes + +- 51f814b: Added ESLint rule `no-top-level-material-ui-4-imports` in the `splunk-on-call` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-stack-overflow@0.1.26 + +### Patch Changes + +- c6779ac: fix: fix decode issues in title and author fields in `StackOverflowSearchResultListItem` +- 6429213: Added ESLint rule `no-top-level-material-ui-4-imports` in the `stack-overflow` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-home-react@0.1.9 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-stack-overflow-backend@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.7 + +## @backstage/plugin-stackstorm@0.1.12 + +### Patch Changes + +- b8234ce: Added ESLint rule `no-top-level-material-ui-4-imports` in the `stackstorm` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-tech-insights@0.3.23 + +### Patch Changes + +- 6aec725: Added ESLint rule `no-top-level-material-ui-4-imports` in the `tech-insights` plugin to migrate the Material UI imports. +- aa66ae0: Added `onlyFailed` prop to `ScorecardsCard`, and `isFailed` to each check type. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.28 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- d621468: Added support for the new `AuthService`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-tech-insights-node@0.5.0 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.46 + +### Patch Changes + +- 6ce8c0b: Fixes an invalid line in the schema that was causing AJV to complain. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-tech-insights-node@0.5.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-techdocs@1.10.1 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- 62bcaf8: Use the new generic refresh user cookie provider. +- 28f27f0: Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5. +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-react@0.0.1 + - @backstage/theme@0.5.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.28 + +### Patch Changes + +- 3f14e9f: Mock the new issue user cookie api method. +- 62bcaf8: Use the new generic refresh user cookie provider. +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.1 + - @backstage/plugin-search-react@1.7.7 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-todo@0.2.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-todo-backend@0.3.12 + +### Patch Changes + +- b65788b: Move @backstage/repo-tools to dev dependencies +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-openapi-utils@0.1.7 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-user-settings@0.8.2 + +### Patch Changes + +- ee584af: Added ESLint rule `no-top-level-material-ui-4-imports` in the `user-settings` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/core-app-api@1.12.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.26 + +### Patch Changes + +- e780d3a: Added ESLint rule `no-top-level-material-ui-4-imports` in the `vault` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-vault-backend@0.4.7 + +### Patch Changes + +- 7277fe2: Removed lock inside recursion to avoid deadlocks +- 4467036: Allow unauthenticated access to health check endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-vault-node@0.1.7 + +## @backstage/plugin-vault-node@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14 + +## @backstage/plugin-xcmetrics@0.2.49 + +### Patch Changes + +- 7984d1e: Fixed bug in XcMetricsClient where it was not including parameter for excludeCI, which is now a required parameter for XCMetrics. +- 9daf301: Added ESLint rule `no-top-level-material-ui-4-imports` in the `xcmetrics` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/core-plugin-api@1.9.1 + +## example-app@0.2.93 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-apache-airflow@0.2.21 + - @backstage/plugin-catalog-import@0.10.7 + - @backstage/cli@0.26.0 + - @backstage/plugin-shortcuts@0.3.20 + - @backstage/plugin-github-pull-requests-board@0.1.25 + - @backstage/plugin-techdocs@1.10.1 + - @backstage/config@1.2.0 + - @backstage/plugin-adr@0.6.14 + - @backstage/plugin-api-docs@0.11.1 + - @backstage/core-components@0.14.1 + - @backstage/plugin-notifications@0.1.0 + - @backstage/plugin-stack-overflow@0.1.26 + - @backstage/plugin-rollbar@0.4.31 + - @backstage/plugin-search@1.4.7 + - @backstage/theme@0.5.2 + - @backstage/plugin-explore@0.4.17 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-github-actions@0.6.12 + - @backstage/plugin-dynatrace@10.0.0 + - @backstage/plugin-scaffolder@1.19.0 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-gcalendar@0.3.24 + - @backstage/plugin-airbrake@0.3.31 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-azure-devops@0.4.0 + - @backstage/plugin-user-settings@0.8.2 + - @backstage/plugin-org@0.6.21 + - @backstage/plugin-linguist@0.1.16 + - @backstage/plugin-badges@0.2.55 + - @backstage/plugin-cloudbuild@0.4.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.0 + - @backstage/plugin-tech-radar@0.7.0 + - @backstage/frontend-app-api@0.6.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-devtools@0.1.10 + - @backstage/plugin-cost-insights@0.12.20 + - @backstage/plugin-entity-feedback@0.2.14 + - @backstage/plugin-kubernetes@0.11.6 + - @backstage/plugin-stackstorm@0.1.12 + - @backstage/plugin-scaffolder-react@1.8.1 + - @backstage/plugin-azure-sites@0.1.20 + - @backstage/plugin-playlist@0.2.5 + - @backstage/plugin-home@0.7.0 + - @backstage/plugin-signals@0.0.2 + - @backstage/plugin-lighthouse@0.4.16 + - @backstage/plugin-sentry@0.5.16 + - @backstage/plugin-tech-insights@0.3.23 + - @backstage/plugin-octopus-deploy@0.2.13 + - @backstage/plugin-catalog-graph@0.4.1 + - @backstage/plugin-kafka@0.3.31 + - @backstage/plugin-jenkins@0.9.6 + - @backstage/plugin-code-coverage@0.2.24 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6 + - @backstage/app-defaults@1.5.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-gcp-projects@0.3.47 + - @backstage/plugin-gocd@0.1.37 + - @backstage/plugin-graphiql@0.3.4 + - @backstage/plugin-kubernetes-cluster@0.0.7 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.13 + - @backstage/plugin-newrelic@0.3.46 + - @backstage/plugin-newrelic-dashboard@0.3.6 + - @backstage/plugin-nomad@0.1.12 + - @backstage/plugin-pagerduty@0.7.3 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-puppetdb@0.1.14 + - @backstage/plugin-search-react@1.7.7 + - @backstage/plugin-todo@0.2.35 + +## example-app-next@0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-apache-airflow@0.2.21 + - @backstage/plugin-catalog-import@0.10.7 + - @backstage/cli@0.26.0 + - @backstage/plugin-shortcuts@0.3.20 + - @backstage/plugin-techdocs@1.10.1 + - @backstage/plugin-adr@0.6.14 + - @backstage/plugin-api-docs@0.11.1 + - @backstage/core-components@0.14.1 + - @backstage/plugin-rollbar@0.4.31 + - @backstage/plugin-search@1.4.7 + - @backstage/theme@0.5.2 + - @backstage/plugin-explore@0.4.17 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-github-actions@0.6.12 + - @backstage/plugin-dynatrace@10.0.0 + - @backstage/plugin-scaffolder@1.19.0 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-gcalendar@0.3.24 + - @backstage/plugin-airbrake@0.3.31 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-azure-devops@0.4.0 + - @backstage/plugin-user-settings@0.8.2 + - @backstage/plugin-org@0.6.21 + - @backstage/plugin-linguist@0.1.16 + - @backstage/plugin-badges@0.2.55 + - @backstage/plugin-cloudbuild@0.4.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.0 + - @backstage/plugin-tech-radar@0.7.0 + - @backstage/frontend-app-api@0.6.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-devtools@0.1.10 + - @backstage/plugin-cost-insights@0.12.20 + - @backstage/plugin-entity-feedback@0.2.14 + - @backstage/plugin-kubernetes@0.11.6 + - @backstage/plugin-stackstorm@0.1.12 + - @backstage/plugin-scaffolder-react@1.8.1 + - @backstage/plugin-azure-sites@0.1.20 + - @backstage/plugin-playlist@0.2.5 + - @backstage/plugin-home@0.7.0 + - @backstage/plugin-lighthouse@0.4.16 + - @backstage/plugin-sentry@0.5.16 + - @backstage/plugin-tech-insights@0.3.23 + - @backstage/plugin-octopus-deploy@0.2.13 + - @backstage/plugin-catalog-graph@0.4.1 + - @backstage/plugin-kafka@0.3.31 + - @backstage/plugin-jenkins@0.9.6 + - @backstage/plugin-code-coverage@0.2.24 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6 + - @backstage/app-defaults@1.5.1 + - app-next-example-plugin@0.0.7 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-app-visualizer@0.1.2 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-gcp-projects@0.3.47 + - @backstage/plugin-gocd@0.1.37 + - @backstage/plugin-graphiql@0.3.4 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.13 + - @backstage/plugin-newrelic@0.3.46 + - @backstage/plugin-newrelic-dashboard@0.3.6 + - @backstage/plugin-pagerduty@0.7.3 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-puppetdb@0.1.14 + - @backstage/plugin-search-react@1.7.7 + - @backstage/plugin-todo@0.2.35 + +## app-next-example-plugin@0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/frontend-plugin-api@0.6.1 + +## example-backend@0.2.93 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-backend@0.3.0 + - @backstage/plugin-events-node@0.3.0 + - @backstage/plugin-scaffolder-backend@1.22.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.31 + - @backstage/plugin-linguist-backend@0.5.11 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.0 + - @backstage/plugin-catalog-backend@1.18.0 + - @backstage/plugin-code-coverage-backend@0.2.28 + - @backstage/plugin-devtools-backend@0.3.0 + - @backstage/plugin-jenkins-backend@0.4.0 + - @backstage/plugin-search-backend@1.5.4 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/plugin-lighthouse-backend@0.4.6 + - @backstage/config@1.2.0 + - @backstage/plugin-azure-devops-backend@0.6.0 + - @backstage/plugin-permission-backend@0.5.37 + - @backstage/plugin-signals-backend@0.1.0 + - @backstage/plugin-nomad-backend@0.1.16 + - @backstage/plugin-entity-feedback-backend@0.2.11 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.17 + - @backstage/plugin-search-backend-module-pg@0.5.23 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/plugin-playlist-backend@0.3.18 + - @backstage/plugin-auth-backend@0.22.0 + - @backstage/plugin-techdocs-backend@1.10.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.15 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-module-techdocs@0.1.18 + - @backstage/plugin-search-backend-module-catalog@0.1.18 + - @backstage/plugin-search-backend-module-explore@0.1.18 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.46 + - @backstage/catalog-client@1.6.1 + - @backstage/plugin-kubernetes-backend@0.16.0 + - @backstage/plugin-adr-backend@0.4.11 + - @backstage/plugin-proxy-backend@0.4.12 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-tech-insights-backend@0.5.28 + - @backstage/plugin-app-backend@0.3.62 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-todo-backend@0.3.12 + - @backstage/plugin-tech-insights-node@0.5.0 + - @backstage/plugin-badges-backend@0.3.11 + - example-app@0.2.93 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11 + - @backstage/plugin-explore-backend@0.0.24 + - @backstage/plugin-rollbar-backend@0.1.59 + - @backstage/plugin-kafka-backend@0.3.12 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-azure-sites-common@0.1.3 + +## example-backend-next@0.0.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.1.0 + - @backstage/plugin-scaffolder-backend@1.22.0 + - @backstage/plugin-linguist-backend@0.5.11 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.7 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.0 + - @backstage/plugin-catalog-backend@1.18.0 + - @backstage/plugin-devtools-backend@0.3.0 + - @backstage/plugin-jenkins-backend@0.4.0 + - @backstage/plugin-search-backend@1.5.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/plugin-lighthouse-backend@0.4.6 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.0 + - @backstage/plugin-azure-devops-backend@0.6.0 + - @backstage/plugin-permission-backend@0.5.37 + - @backstage/plugin-signals-backend@0.1.0 + - @backstage/plugin-nomad-backend@0.1.16 + - @backstage/plugin-entity-feedback-backend@0.2.11 + - @backstage/plugin-playlist-backend@0.3.18 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-auth-backend@0.22.0 + - @backstage/plugin-techdocs-backend@1.10.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-module-techdocs@0.1.18 + - @backstage/plugin-search-backend-module-catalog@0.1.18 + - @backstage/plugin-search-backend-module-explore@0.1.18 + - @backstage/backend-defaults@0.2.14 + - @backstage/plugin-kubernetes-backend@0.16.0 + - @backstage/plugin-adr-backend@0.4.11 + - @backstage/plugin-proxy-backend@0.4.12 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-app-backend@0.3.62 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-todo-backend@0.3.12 + - @backstage/plugin-badges-backend@0.3.11 + - @backstage/plugin-auth-backend-module-github-provider@0.1.11 + - @backstage/plugin-catalog-backend-module-openapi@0.1.31 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.11 + - @backstage/plugin-sonarqube-backend@0.2.16 + - @backstage/catalog-model@1.4.5 + +## e2e-test@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.12 + - @backstage/errors@1.2.4 + - @backstage/cli-common@0.1.13 + +## techdocs-cli-embedded-app@0.2.92 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.26.0 + - @backstage/plugin-techdocs@1.10.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/app-defaults@1.5.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.1 + +## @internal/plugin-todo-list@1.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/core-plugin-api@1.9.1 + +## @internal/plugin-todo-list-backend@1.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## @internal/plugin-todo-list-common@1.0.18 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 diff --git a/docs/releases/v1.24.0-next.0-changelog.md b/docs/releases/v1.24.0-next.0-changelog.md new file mode 100644 index 0000000000..c46cd38c26 --- /dev/null +++ b/docs/releases/v1.24.0-next.0-changelog.md @@ -0,0 +1,4281 @@ +# Release v1.24.0-next.0 + +## @backstage/backend-app-api@0.6.0-next.0 + +### Minor Changes + +- 4a3d434: **BREAKING**: For users that have migrated to the new backend system, incoming requests will now be rejected if they are not properly authenticated (e.g. with a Backstage bearer token or a backend token). Please see the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on how to circumvent this behavior in the short term and how to properly leverage it in the longer term. + + Added service factories for the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/), [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth), and [`userInfo`](https://backstage.io/docs/backend-system/core-services/user-info) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- 0502d82: Updated the `permissionsServiceFactory` to forward the `AuthService` to the implementation. +- 9802004: Made the `DefaultUserInfoService` claims check stricter +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/config-loader@1.6.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend@0.22.0-next.0 + +### Minor Changes + +- 293c835: Add support for Service Tokens to Cloudflare Access auth provider +- 492fe83: **BREAKING**: The `CatalogIdentityClient` constructor now also requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support the new auth services, which has also been done for the `createRouter` function. + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- 2af5354: Bump dependency `jose` to v5 +- 38af71a: Updated dependency `google-auth-library` to `^9.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- fa7ea3f: Internal refactor to break out how the router is constructed +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.6-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.8-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.4-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.3-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.8-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.5-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.6-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.0-next.0 + +### Minor Changes + +- 1bedb23: Adds a new guest provider that maps guest users to actual tokens. This also shifts the default guest login to `user:development/guest` to reduce overlap with your production/real data. To change that (or set it back to the old default, use the new `auth.providers.guest.userEntityRef` config key) like so, + + ```yaml title=app-config.yaml + auth: + providers: + guest: + userEntityRef: user:default/guest + ``` + + This also adds a new property to control the ownership entity refs, + + ```yaml title=app-config.yaml + auth: + providers: + guest: + ownershipEntityRefs: + - guests + - development/custom + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-azure-devops@0.4.0-next.0 + +### Minor Changes + +- 9fdb86a: Ability to fetch the README file from a different Azure DevOps path. + + Defaults to the current, Azure DevOps default behaviour (`README.md` in the root of the git repo); to use a different path, add the annotation `dev.azure.com/readme-path` + + Example: + + ```yaml + dev.azure.com/readme-path: /my-path/README.md + ``` + +- a9e7bd6: **BREAKING** The `AzureDevOpsClient` no longer requires `identityAPi` but now requires `fetchApi`. + + Updated to use `fetchApi` as per [ADR013](https://backstage.io/docs/architecture-decisions/adrs-adr013) + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-azure-devops-common@0.4.0-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## @backstage/plugin-azure-devops-backend@0.6.0-next.0 + +### Minor Changes + +- 9fdb86a: Ability to fetch the README file from a different Azure DevOps path. + + Defaults to the current, Azure DevOps default behaviour (`README.md` in the root of the git repo); to use a different path, add the annotation `dev.azure.com/readme-path` + + Example: + + ```yaml + dev.azure.com/readme-path: /my-path/README.md + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-azure-devops-common@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-azure-devops-common@0.4.0-next.0 + +### Minor Changes + +- 9fdb86a: Ability to fetch the README file from a different Azure DevOps path. + + Defaults to the current, Azure DevOps default behaviour (`README.md` in the root of the git repo); to use a different path, add the annotation `dev.azure.com/readme-path` + + Example: + + ```yaml + dev.azure.com/readme-path: /my-path/README.md + ``` + +## @backstage/plugin-azure-sites-backend@0.3.0-next.0 + +### Minor Changes + +- 6b802a2: **BREAKING**: The `createRouter` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + +### Patch Changes + +- 85db926: Added new backend system for the Azure Sites backend plugin +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.0 + +## @backstage/plugin-catalog-backend@1.18.0-next.0 + +### Minor Changes + +- df12231: Allow setting EntityDataParser using CatalogModelExtensionPoint +- 15ba00f: Migrated to support new auth services. The `CatalogBuilder.create` method now accepts a `discovery` option, which is recommended to forward from the plugin environment, as it will otherwise fall back to use the `HostDiscovery` implementation. + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 280edeb: Add index for original value in search table for faster entity facet response +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/repo-tools@0.6.3-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.17-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-openapi-utils@0.1.6-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.0-next.0 + +### Minor Changes + +- 9e527c9: BREAKING CHANGE: Migrates the `BitbucketCloudEntityProvider` to use the `EventsService`; fix new backend system support. + + `BitbucketCloudEntityProvider.fromConfig` accepts `events: EventsService` as optional argument to its `options`. + With provided `events`, the event-based updates/refresh will be available. + However, the `EventSubscriber` interface was removed including its `supportsEventTopics()` and `onEvent(params)`. + + The event subscription happens on `connect(connection)` if the `events` is available. + + **Migration:** + + ```diff + const bitbucketCloudProvider = BitbucketCloudEntityProvider.fromConfig( + env.config, + { + catalogApi: new CatalogClient({ discoveryApi: env.discovery }), + + events: env.events, + logger: env.logger, + scheduler: env.scheduler, + tokenManager: env.tokenManager, + }, + ); + - env.eventBroker.subscribe(bitbucketCloudProvider); + ``` + + **New Backend System:** + + Before this change, using this module with the new backend system was broken. + Now, you can add the catalog module for Bitbucket Cloud incl. event support backend. + Event support will always be enabled. + However, no updates/refresh will happen without receiving events. + + ```ts + backend.add( + import('@backstage/plugin-catalog-backend-module-bitbucket-cloud/alpha'), + ); + ``` + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.17-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-node@1.8.0-next.0 + +### Minor Changes + +- df12231: Allow setting EntityDataParser using CatalogModelExtensionPoint + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-devtools-backend@0.3.0-next.0 + +### Minor Changes + +- 4dc5b48: **BREAKING**: The `createRouter` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/config-loader@1.6.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9-next.0 + +## @backstage/plugin-events-backend@0.3.0-next.0 + +### Minor Changes + +- c4bd794: BREAKING CHANGE: Migrate `HttpPostIngressEventPublisher` and `eventsPlugin` to use `EventsService`. + + Uses the `EventsService` instead of `EventBroker` at `HttpPostIngressEventPublisher`, + dropping the use of `EventPublisher` including `setEventBroker(..)`. + + Now, `HttpPostIngressEventPublisher.fromConfig` requires `events: EventsService` as option. + + ```diff + const http = HttpPostIngressEventPublisher.fromConfig({ + config: env.config, + + events: env.events, + logger: env.logger, + }); + http.bind(eventsRouter); + + // e.g. at packages/backend/src/plugins/events.ts + - await new EventsBackend(env.logger) + - .setEventBroker(env.eventBroker) + - .addPublishers(http) + - .start(); + + // or for other kinds of setups + - await Promise.all(http.map(publisher => publisher.setEventBroker(eventBroker))); + ``` + + `eventsPlugin` uses the `eventsServiceRef` as dependency. + Unsupported (and deprecated) extension point methods will throw an error to prevent unintended behavior. + + ```ts + import { eventsServiceRef } from '@backstage/plugin-events-node'; + ``` + +### Patch Changes + +- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system. + + **Summary:** + + - new: + `EventsService`, `eventsServiceRef`, `TestEventsService` + - deprecated: + `EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`, + most parts of `EventsExtensionPoint` (alpha), + `TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber` + + Add the `eventsServiceRef` as dependency to your backend plugins + or backend plugin modules. + + **Details:** + + The previous implementation using the `EventsExtensionPoint` was added in the early stages + of the new backend system and does not respect the plugin isolation. + This made it not compatible anymore with the new backend system. + + Additionally, the previous interfaces had some room for simplification, + supporting less exposure of internal concerns as well. + + Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`. + The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore. + Instead, it is expected that the `EventsService` gets passed into publishers and subscribers, + and used internally. There is no need to expose anything of that at their own interfaces. + + Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable + (by other plugins or their modules) anyway. + + The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation. + Optionally, an instance can be passed as argument to allow mixed setups to operate alongside. + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.0-next.0 + +### Minor Changes + +- 132d672: BREAKING CHANGE: Migrate `AwsSqsConsumingEventPublisher` and its backend module to use `EventsService`. + + Uses the `EventsService` instead of `EventBroker` at `AwsSqsConsumingEventPublisher`, + dropping the use of `EventPublisher` including `setEventBroker(..)`. + + Now, `AwsSqsConsumingEventPublisher.fromConfig` requires `events: EventsService` as option. + + ```diff + const sqs = AwsSqsConsumingEventPublisher.fromConfig({ + config: env.config, + + events: env.events, + logger: env.logger, + scheduler: env.scheduler, + }); + + await Promise.all(sqs.map(publisher => publisher.start())); + + // e.g. at packages/backend/src/plugins/events.ts + - await new EventsBackend(env.logger) + - .setEventBroker(env.eventBroker) + - .addPublishers(sqs) + - .start(); + + // or for other kinds of setups + - await Promise.all(sqs.map(publisher => publisher.setEventBroker(eventBroker))); + ``` + + `eventsModuleAwsSqsConsumingEventPublisher` uses the `eventsServiceRef` as dependency, + instead of `eventsExtensionPoint`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.0-next.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.0-next.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.0-next.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.0-next.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.0-next.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-events-node@0.3.0-next.0 + +### Minor Changes + +- eff3ca9: BREAKING CHANGE: Migrate `EventRouter` implementations from `EventBroker` to `EventsService`. + + `EventRouter` uses the new `EventsService` instead of the `EventBroker` now, + causing a breaking change to its signature. + + All of its extensions and implementations got adjusted accordingly. + (`SubTopicEventRouter`, `AzureDevOpsEventRouter`, `BitbucketCloudEventRouter`, + `GerritEventRouter`, `GithubEventRouter`, `GitlabEventRouter`) + + Required adjustments were made to all backend modules for the new backend system, + now also making use of the `eventsServiceRef` instead of the `eventsExtensionPoint`. + + **Migration:** + + Example for implementations of `SubTopicEventRouter`: + + ```diff + import { + EventParams, + + EventsService, + SubTopicEventRouter, + } from '@backstage/plugin-events-node'; + + export class GithubEventRouter extends SubTopicEventRouter { + - constructor() { + - super('github'); + + constructor(options: { events: EventsService }) { + + super({ + + events: options.events, + + topic: 'github', + + }); + } + + + protected getSubscriberId(): string { + + return 'GithubEventRouter'; + + } + + + // ... + } + ``` + + Example for a direct extension of `EventRouter`: + + ```diff + class MyEventRouter extends EventRouter { + - constructor(/* ... */) { + + constructor(options: { + + events: EventsService; + + // ... + + }) { + - super(); + // ... + + super({ + + events: options.events, + + topics: topics, + + }); + } + + + + protected getSubscriberId(): string { + + return 'MyEventRouter'; + + } + - + - supportsEventTopics(): string[] { + - return this.topics; + - } + } + ``` + +### Patch Changes + +- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system. + + **Summary:** + + - new: + `EventsService`, `eventsServiceRef`, `TestEventsService` + - deprecated: + `EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`, + most parts of `EventsExtensionPoint` (alpha), + `TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber` + + Add the `eventsServiceRef` as dependency to your backend plugins + or backend plugin modules. + + **Details:** + + The previous implementation using the `EventsExtensionPoint` was added in the early stages + of the new backend system and does not respect the plugin isolation. + This made it not compatible anymore with the new backend system. + + Additionally, the previous interfaces had some room for simplification, + supporting less exposure of internal concerns as well. + + Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`. + The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore. + Instead, it is expected that the `EventsService` gets passed into publishers and subscribers, + and used internally. There is no need to expose anything of that at their own interfaces. + + Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable + (by other plugins or their modules) anyway. + + The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation. + Optionally, an instance can be passed as argument to allow mixed setups to operate alongside. + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-jenkins-backend@0.4.0-next.0 + +### Minor Changes + +- 55191cc: **BREAKING**: Both `createRouter` and `DefaultJenkinsInfoProvider.fromConfig` now require the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + + The `JenkinsInfoProvider` interface has been updated to receive `credentials` of the type `BackstageCredentials` rather than a token. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-jenkins-common@0.1.25-next.0 + +## @backstage/plugin-kubernetes-backend@0.16.0-next.0 + +### Minor Changes + +- e1e540c: **BREAKING**: The `KubernetesBuilder.createBuilder` method now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/plugin-kubernetes-node@0.1.7-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications@0.1.0-next.0 + +### Minor Changes + +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.0 + +## @backstage/plugin-notifications-backend@0.1.0-next.0 + +### Minor Changes + +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 84af361: Migrated to using the new auth services. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-notifications-node@0.1.0-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-notifications-node@0.1.0-next.0 + +### Minor Changes + +- 84af361: Migrated to using the new auth services. + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-scaffolder-backend@1.22.0-next.0 + +### Minor Changes + +- c6b132e: Introducing checkpoints for scaffolder task action idempotency + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.3-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.3-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.3-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.5-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.3-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.16-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.5-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.3-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.10-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.0 + +### Minor Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-test-utils@0.3.3-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-tech-insights-node@0.5.0-next.0 + +### Minor Changes + +- d621468: **BREAKING**: The `FactRetrieverContext` type now contains an additional `auth` field. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/app-defaults@1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## @backstage/backend-common@0.21.3-next.0 + +### Patch Changes + +- 7422430: Resolve the `basePath` before constructing the target path + +- 999224f: Bump dependency `minimatch` to v9 + +- e0b997c: Fix issue where `resolveSafeChildPath` path would incorrectly resolve when operating on a symlink + +- 9802004: Added the `UserInfoApi` as both an optional input and as an output for `createLegacyAuthAdapters` + +- 2af5354: Bump dependency `jose` to v5 + +- ff40ada: Updated dependency `mysql2` to `^3.0.0`. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- 568881f: Updated dependency `yauzl` to `^3.0.0`. + +- 4a3d434: Added a `createLegacyAuthAdapters` function that can be used as a compatibility adapter for backend plugins who want to start using the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). + + See the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on the usage of this adapter. + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-app-api@0.6.0-next.0 + - @backstage/config-loader@1.6.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.13-next.0 + +### Patch Changes + +- 7cbb760: Added support for the new auth services, which are now installed by default. See the [migration guide](https://backstage.io/docs/tutorials/auth-service-migration) for details. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-app-api@0.6.0-next.0 + +## @backstage/backend-dynamic-feature-service@0.2.3-next.0 + +### Patch Changes + +- 5247909: Add `events: EventsService` to `LegacyPluginEnvironment`. +- Updated dependencies + - @backstage/plugin-events-backend@0.3.0-next.0 + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-app-api@0.6.0-next.0 + - @backstage/plugin-catalog-backend@1.18.0-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/config-loader@1.6.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-app-node@0.1.13-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/backend-openapi-utils@0.1.6-next.0 + +### Patch Changes + +- 85ec23e: Updated dependency `json-schema-to-ts` to `^3.0.0`. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/backend-plugin-api@0.6.13-next.0 + +### Patch Changes + +- 4a3d434: Added the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/), [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth), and [`userInfo`](https://backstage.io/docs/backend-system/core-services/user-info) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution) to the `coreServices`. + + At the same time, the [`httpRouter`](https://backstage.io/docs/backend-system/core-services/http-router) service gained a new `addAuthPolicy` method that lets your plugin declare exemptions to the default auth policy - for example if you want to allow unauthenticated or cookie-based access to some subset of your feature routes. + + If you have migrated to the new backend system, please see the [Auth Service Migration tutorial](https://backstage.io/docs/tutorials/auth-service-migration) for more information on how to move toward using these services. + +- 0502d82: Updated the `PermissionsService` methods to accept `BackstageCredentials` through options. + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/backend-tasks@0.5.18-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.3-next.0 + +### Patch Changes + +- 4a3d434: Added support for the new [`auth`](https://backstage.io/docs/backend-system/core-services/auth/) and [`httpAuth`](https://backstage.io/docs/backend-system/core-services/http-auth) services that were created as part of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). These services will be present by default in test apps, and you can access mocked versions of their features under `mockServices.auth` and `mockServices.httpAuth` if you want to inspect or replace their behaviors. + + There is also a new `mockCredentials` that you can use for acquiring mocks of the various types of credentials that are used in the new system. + +- 9802004: Added `mockServices.userInfo`, which now also automatically is made available in test backends. + +- fd61d39: Updated dependency `testcontainers` to `^10.0.0`. + +- ff40ada: Updated dependency `mysql2` to `^3.0.0`. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-app-api@0.6.0-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/catalog-model@1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/cli@0.25.3-next.0 + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- f86e34c: Removed unused `replace-in-file` dependency +- f4404e5: Add .ico import support +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/eslint-plugin@0.1.6-next.0 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/config-loader@1.6.3-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/config@1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/config-loader@1.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.1-next.0 + +### Patch Changes + +- ff33ee2: Removed hardcoded font-family on select input +- ff7e126: Support i18n for core components +- 7854120: Create a component abstraction to consume system icons. +- ce73c3b: Removed the inline color from select icon to allow it to be colored via a theme +- a8f7904: `SignInPage`'s `'guest'` provider now supports the `@backstage/plugin-auth-backend-module-guest-provider` package to generate tokens. It will continue to use the old frontend-only auth as a fallback. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-plugin-api@1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.12-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/app-defaults@1.5.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + +## @backstage/errors@1.2.4-next.0 + +### Patch Changes + +- 2636075: Fixed an issue that was causing ResponseError not to report the HTTP status from the provided response. +- Updated dependencies + - @backstage/types@1.1.1 + +## @backstage/eslint-plugin@0.1.6-next.0 + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 + +## @backstage/frontend-app-api@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.1-next.0 + - @backstage/test-utils@1.5.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/integration@1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/integration-aws-node@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/integration-react@1.1.25-next.0 + +### Patch Changes + +- b38dc55: Updated `microsoftAuthApi` scopes for Azure DevOps to be fully qualified. +- Updated dependencies + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/repo-tools@0.6.3-next.0 + +### Patch Changes + +- 999224f: Bump dependency `minimatch` to v9 +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + +## @techdocs/cli@1.8.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + +## @backstage/test-utils@1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## @backstage/theme@0.5.2-next.0 + +### Patch Changes + +- 6f4d2a0: Exported `defaultTypography` to make adjusting these values in a custom theme easier + +## @backstage/plugin-adr@0.6.14-next.0 + +### Patch Changes + +- 5335634: Fixed Azure DevOps ADR file path reading +- 669efc6: Remove unused package dependencies +- Updated dependencies + - @backstage/plugin-adr-common@0.2.21-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## @backstage/plugin-adr-backend@0.4.10-next.0 + +### Patch Changes + +- 334c5fe: Updated dependency `marked` to `^12.0.0`. +- c8fdd83: Migrated `DefaultAdrCollatorFactory` to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-adr-common@0.2.21-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-adr-common@0.2.21-next.0 + +### Patch Changes + +- 5335634: Fixed Azure DevOps ADR file path reading +- Updated dependencies + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-airbrake@0.3.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/dev-utils@1.0.28-next.0 + - @backstage/test-utils@1.5.1-next.0 + +## @backstage/plugin-airbrake-backend@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-allure@0.1.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-analytics-module-ga@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## @backstage/plugin-analytics-module-ga4@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## @backstage/plugin-apache-airflow@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-api-docs@0.11.1-next.0 + +### Patch Changes + +- 7854120: Use the `AppIcon` component in the navigation item extension. +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## @backstage/plugin-apollo-explorer@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-app-backend@0.3.61-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config-loader@1.6.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-app-node@0.1.13-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config-loader@1.6.3-next.0 + +## @backstage/plugin-app-visualizer@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.4-next.0 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-auth-backend@0.22.0-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.8-next.0 + +### Patch Changes + +- 38af71a: Updated dependency `google-auth-library` to `^9.0.0`. +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.10-next.0 + +### Patch Changes + +- 38af71a: Updated dependency `google-auth-library` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.8-next.0 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.6-next.0 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- e77d7a9: Internal refactor to avoid deprecated method. +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.3-next.0 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-auth-backend@0.22.0-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.7-next.0 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.5-next.0 + +### Patch Changes + +- 2af5354: Bump dependency `jose` to v5 +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-auth-node@0.4.8-next.0 + +### Patch Changes + +- b4fc6e3: Deprecated the `getBearerTokenFromAuthorizationHeader` function, which is being replaced by the new `HttpAuthService`. +- 2af5354: Bump dependency `jose` to v5 +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- b1b012d: Fix issue with `providerInfo` not being set properly for some proxy providers, by making `providerInfo` an explicit optional return from `authenticate` +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-sites@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## @backstage/plugin-azure-sites-common@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-badges@0.2.55-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-badges-backend@0.3.10-next.0 + +### Patch Changes + +- 29a1f91: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-bazaar@0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-bazaar-backend@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-bitbucket-cloud-common@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-bitrise@0.1.58-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-catalog@1.17.1-next.0 + +### Patch Changes + +- 9332425: The entity page extension provided by the `/alpha` plugin now correctly renders the entity 404 page. +- 6727665: Allow the `spec.target` field to be searchable in the catalog table for locations. Previously, only the `spec.targets` field was be searchable. This makes locations generated by providers such as the `GithubEntityProvider` searchable in the catalog table. [#23098](https://github.com/backstage/backstage/issues/23098) +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.3.7-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.32-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.6-next.0 + +### Patch Changes + +- 43a9ae1: Migrated to use new auth service. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-openapi-utils@0.1.6-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.26-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.29-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.5.3-next.0 + +### Patch Changes + +- a936a8f: Migrated the `GithubLocationAnalyzer` to support new auth services. +- 999224f: Bump dependency `minimatch` to v9 +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-backend@1.18.0-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-catalog-backend-module-github@0.5.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.10-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.17-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-backend@1.18.0-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.28-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.20-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-backend@1.18.0-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.18-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-catalog-common@1.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-catalog-graph@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.7-next.0 + +### Patch Changes + +- 75f686b: Fixed an issue generating a wrong entity link at the end of the import process +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-catalog-react@1.10.1-next.0 + +### Patch Changes + +- 930b5c1: Added 'root' and 'label' class keys for EntityAutocompletePicker, EntityOwnerPicker and EntityProcessingStatusPicker +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-cicd-statistics@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.27-next.0 + +### Patch Changes + +- 402d991: Align `p-limit` dependency version to v3 +- Updated dependencies + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-cicd-statistics@0.1.33-next.0 + +## @backstage/plugin-circleci@0.3.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-cloudbuild@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-code-climate@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-code-coverage@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-code-coverage-backend@0.2.27-next.0 + +### Patch Changes + +- cceebae: Fix jacoco convertor to not require annotation to be set to scm-only. +- 8efe690: Migrated to support new auth services. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-codescene@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-config-schema@0.1.51-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.20-next.0 + +### Patch Changes + +- 1b4fd09: Updated dependency `yup` to `^1.0.0`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.10-next.0 + +### Patch Changes + +- a0e3393: Updated to use `fetchApi` as per [ADR013](https://backstage.io/docs/architecture-decisions/adrs-adr013) +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-devtools-common@0.1.9-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## @backstage/plugin-devtools-common@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-dynatrace@9.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-entity-feedback@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.10-next.0 + +### Patch Changes + +- 4f8ecd6: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.23-next.0 + +### Patch Changes + +- 56969b6: Add new `EventsService` as well as `eventsServiceRef` for the new backend system. + + **Summary:** + + - new: + `EventsService`, `eventsServiceRef`, `TestEventsService` + - deprecated: + `EventBroker`, `EventPublisher`, `EventSubscriber`, `DefaultEventBroker`, `EventsBackend`, + most parts of `EventsExtensionPoint` (alpha), + `TestEventBroker`, `TestEventPublisher`, `TestEventSubscriber` + + Add the `eventsServiceRef` as dependency to your backend plugins + or backend plugin modules. + + **Details:** + + The previous implementation using the `EventsExtensionPoint` was added in the early stages + of the new backend system and does not respect the plugin isolation. + This made it not compatible anymore with the new backend system. + + Additionally, the previous interfaces had some room for simplification, + supporting less exposure of internal concerns as well. + + Hereby, this change adds a new `EventsService` interface as replacement for the now deprecated `EventBroker`. + The new interface does not require any `EventPublisher` or `EventSubscriber` interfaces anymore. + Instead, it is expected that the `EventsService` gets passed into publishers and subscribers, + and used internally. There is no need to expose anything of that at their own interfaces. + + Most parts of `EventsExtensionPoint` (alpha) are deprecated as well and were not usable + (by other plugins or their modules) anyway. + + The `DefaultEventBroker` implementation is deprecated and wraps the new `DefaultEventsService` implementation. + Optionally, an instance can be passed as argument to allow mixed setups to operate alongside. + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + +## @backstage/plugin-explore@0.4.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37-next.0 + +## @backstage/plugin-explore-backend@0.0.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.17-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-explore-react@0.0.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-fossa@0.2.63-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-gcalendar@0.3.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-gcp-projects@0.3.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-git-release-manager@0.3.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-github-actions@0.6.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-github-deployments@0.1.62-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-github-issues@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-github-pull-requests-board@0.1.25-next.0 + +### Patch Changes + +- 3c2d7c0: The `CardHeader` component in the `github-pull-requests-board` plugin will show the status for the PR +- 402d991: Align `p-limit` dependency version to v3 +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-gitops-profiles@0.3.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-gocd@0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-graphiql@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## @backstage/plugin-graphql-voyager@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-home@0.6.3-next.0 + +### Patch Changes + +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-home-react@0.1.9-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## @backstage/plugin-home-react@0.1.9-next.0 + +### Patch Changes + +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-ilert@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-jenkins@0.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-jenkins-common@0.1.25-next.0 + +## @backstage/plugin-jenkins-common@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-kafka@0.3.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-kafka-backend@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-kubernetes@0.11.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/plugin-kubernetes-react@0.3.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/plugin-kubernetes-react@0.3.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-kubernetes-common@0.7.5-next.0 + +### Patch Changes + +- 4642cb7: Add support to fetch data for Daemon Sets and display an accordion in the same way as with Deployments +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-node@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-react@0.3.1-next.0 + +### Patch Changes + +- 4642cb7: Add support to fetch data for Daemon Sets and display an accordion in the same way as with Deployments +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-lighthouse@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-lighthouse-common@0.1.5-next.0 + +## @backstage/plugin-lighthouse-backend@0.4.5-next.0 + +### Patch Changes + +- 9f9ba70: **BREAKING**: The `createScheduler` function now requires the `discovery` service to be forwarded from the plugin environment. This is part of the migration to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.5-next.0 + +## @backstage/plugin-lighthouse-common@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-linguist@0.1.16-next.0 + +### Patch Changes + +- 4fb9600: Get component's title from translation file. See: <https://backstage.io/docs/plugins/internationalization#for-an-application-developer-overwrite-plugin-messages> +- a0e3393: Updated to use `fetchApi` as per [ADR013](https://backstage.io/docs/architecture-decisions/adrs-adr013) +- 786c9c4: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.10-next.0 + +### Patch Changes + +- 61ff58f: Migrated to support new auth services. +- 786c9c4: Updated dependency `luxon` to `^3.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-newrelic@0.3.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-newrelic-dashboard@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-nomad@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-nomad-backend@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-notifications-common@0.0.2-next.0 + +### Patch Changes + +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +## @backstage/plugin-octopus-deploy@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-opencost@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-org@0.6.21-next.0 + +### Patch Changes + +- 526f00a: Document the new frontend system extensions for the org plugin. +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-org-react@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-pagerduty@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-home-react@0.1.9-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-periskop@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-periskop-backend@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-permission-backend@0.5.36-next.0 + +### Patch Changes + +- 9802004: Migrated to use the new auth services introduced in [BEP-0003](https://github.com/backstage/backstage/blob/master/beps/0003-auth-architecture-evolution/README.md). + + The `createRouter` function now accepts `auth`, `httpAuth` and `userInfo` options. Theses are used internally to support the new backend system, and can be ignored. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + +## @backstage/plugin-permission-common@0.7.13-next.0 + +### Patch Changes + +- 0502d82: The `token` option of the `PermissionEvaluator` methods is now deprecated. The options that only apply to backend implementations have been moved to `PermissionsService` from `@backstage/backend-plugin-api` instead. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-node@0.7.24-next.0 + +### Patch Changes + +- 0502d82: The `ServerPermissionClient` has been migrated to implement the `PermissionsService` interface, now accepting the new `BackstageCredentials` object in addition to the `token` option, which is now deprecated. It now also optionally depends on the new `AuthService`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-permission-react@0.4.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-playlist@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + - @backstage/plugin-playlist-common@0.1.15-next.0 + +## @backstage/plugin-playlist-backend@0.3.17-next.0 + +### Patch Changes + +- 6813366: Migrated to support new auth services. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-playlist-common@0.1.15-next.0 + +## @backstage/plugin-playlist-common@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + +## @backstage/plugin-proxy-backend@0.4.11-next.0 + +### Patch Changes + +- 1b4fd09: Updated dependency `yup` to `^1.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-puppetdb@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-rollbar@0.4.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-rollbar-backend@0.1.58-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-scaffolder@1.18.1-next.0 + +### Patch Changes + +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-scaffolder-react@1.8.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.5-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.3-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.14-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.37-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.5-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 1753898: Updated dependency `octokit-plugin-create-pull-request` to `^5.0.0`. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.16-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.30-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.21-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.34-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-common@1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.3.3-next.0 + +### Patch Changes + +- 85f4723: Fixed file corruption for non UTF-8 data in fetch contents +- c6b132e: Introducing checkpoints for scaffolder task action idempotency +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-scaffolder-react@1.8.1-next.0 + +### Patch Changes + +- 930b5c1: Added 'root' and 'label' class key to TemplateCategoryPicker +- 6d649d2: Updated dependency `flatted` to `3.3.1`. +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## @backstage/plugin-search@1.4.7-next.0 + +### Patch Changes + +- f0464b0: Removes ADR from the default set of search filters +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-search-backend@1.5.3-next.0 + +### Patch Changes + +- 744c0cb: Update the router to use the new `auth` services, it now accepts an optional discovery service option to get credentials for the permission service. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-openapi-utils@0.1.6-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-backend-module-catalog@0.1.17-next.0 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.16-next.0 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + +## @backstage/plugin-search-backend-module-explore@0.1.17-next.0 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-search-backend-module-pg@0.5.22-next.0 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-search-backend-module-techdocs@0.1.17-next.0 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-search-backend-node@1.2.17-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 744c0cb: Exports `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` types. These new types were extracted from the `@backstage/plugin-search-common` package and the `token` property was deprecated in favor of the a new credentials one. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-search-common@1.2.11-next.0 + +### Patch Changes + +- 744c0cb: Deprecate `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` in favor of the types exported from `@backstage/plugin-search-backend-node`. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-react@1.7.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-sentry@0.5.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-shortcuts@0.3.20-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.2-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.0 + +## @backstage/plugin-signals-backend@0.0.4-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.0.4-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-sonarqube-react@0.1.14-next.0 + +## @backstage/plugin-sonarqube-backend@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## @backstage/plugin-sonarqube-react@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-splunk-on-call@0.4.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-stack-overflow@0.1.26-next.0 + +### Patch Changes + +- c6779ac: fix: fix decode issues in title and author fields in `StackOverflowSearchResultListItem` +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-home-react@0.1.9-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## @backstage/plugin-stack-overflow-backend@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.6-next.0 + +## @backstage/plugin-stackstorm@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-tech-insights@0.3.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.27-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- d621468: Added support for the new `AuthService`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-tech-insights-node@0.5.0-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-tech-insights-node@0.5.0-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.6.14-next.0 + +### Patch Changes + +- a2327ac: Fixed an issue with the "moved in direction" table header cell getting squished and becoming unreadable if a timeline description is too long +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## @backstage/plugin-techdocs@1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-techdocs@1.10.1-next.0 + - @backstage/test-utils@1.5.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/core-app-api@1.12.1-next.0 + +## @backstage/plugin-techdocs-backend@1.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.17-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + +## @backstage/plugin-techdocs-node@1.11.5-next.0 + +### Patch Changes + +- 5b4f565: Fix handling of default plugins that have configuration +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + +## @backstage/plugin-techdocs-react@1.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-todo-backend@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/repo-tools@0.6.3-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-openapi-utils@0.1.6-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## @backstage/plugin-user-settings@0.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @backstage/plugin-vault-backend@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-vault-node@0.1.6-next.0 + +## @backstage/plugin-vault-node@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @backstage/plugin-xcmetrics@0.2.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## example-app@0.2.93-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-github-pull-requests-board@0.1.25-next.0 + - @backstage/plugin-adr@0.6.14-next.0 + - @backstage/plugin-stack-overflow@0.1.26-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-notifications@0.1.0-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/cli@0.25.3-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-azure-devops@0.4.0-next.0 + - @backstage/plugin-linguist@0.1.16-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/plugin-org@0.6.21-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search@1.4.7-next.0 + - @backstage/plugin-devtools@0.1.10-next.0 + - @backstage/plugin-tech-radar@0.6.14-next.0 + - @backstage/plugin-scaffolder-react@1.8.1-next.0 + - @backstage/plugin-api-docs@0.11.1-next.0 + - @backstage/plugin-cost-insights@0.12.20-next.0 + - @backstage/plugin-home@0.6.3-next.0 + - @backstage/plugin-scaffolder@1.18.1-next.0 + - @backstage/plugin-shortcuts@0.3.20-next.0 + - @backstage/plugin-signals@0.0.2-next.0 + - @backstage/plugin-catalog-import@0.10.7-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-app-api@0.6.1-next.0 + - @backstage/plugin-badges@0.2.55-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.0 + - @backstage/plugin-code-coverage@0.2.24-next.0 + - @backstage/plugin-entity-feedback@0.2.14-next.0 + - @backstage/plugin-explore@0.4.17-next.0 + - @backstage/plugin-gcalendar@0.3.24-next.0 + - @backstage/plugin-gocd@0.1.37-next.0 + - @backstage/plugin-jenkins@0.9.6-next.0 + - @backstage/plugin-microsoft-calendar@0.1.13-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.0 + - @backstage/plugin-pagerduty@0.7.3-next.0 + - @backstage/plugin-playlist@0.2.5-next.0 + - @backstage/plugin-puppetdb@0.1.14-next.0 + - @backstage/plugin-stackstorm@0.1.12-next.0 + - @backstage/plugin-tech-insights@0.3.23-next.0 + - @backstage/plugin-techdocs@1.10.1-next.0 + - @backstage/plugin-todo@0.2.35-next.0 + - @backstage/plugin-user-settings@0.8.2-next.0 + - @backstage/app-defaults@1.5.1-next.0 + - @backstage/plugin-azure-sites@0.1.20-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/plugin-airbrake@0.3.31-next.0 + - @backstage/plugin-apache-airflow@0.2.21-next.0 + - @backstage/plugin-catalog-graph@0.4.1-next.0 + - @backstage/plugin-cloudbuild@0.4.1-next.0 + - @backstage/plugin-dynatrace@9.0.1-next.0 + - @backstage/plugin-gcp-projects@0.3.47-next.0 + - @backstage/plugin-github-actions@0.6.12-next.0 + - @backstage/plugin-graphiql@0.3.4-next.0 + - @backstage/plugin-kafka@0.3.31-next.0 + - @backstage/plugin-kubernetes@0.11.6-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.7-next.0 + - @backstage/plugin-lighthouse@0.4.16-next.0 + - @backstage/plugin-newrelic@0.3.46-next.0 + - @backstage/plugin-nomad@0.1.12-next.0 + - @backstage/plugin-octopus-deploy@0.2.13-next.0 + - @backstage/plugin-rollbar@0.4.31-next.0 + - @backstage/plugin-sentry@0.5.16-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## example-app-next@0.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr@0.6.14-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/cli@0.25.3-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-azure-devops@0.4.0-next.0 + - @backstage/plugin-linguist@0.1.16-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/plugin-org@0.6.21-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search@1.4.7-next.0 + - @backstage/plugin-devtools@0.1.10-next.0 + - @backstage/plugin-tech-radar@0.6.14-next.0 + - @backstage/plugin-scaffolder-react@1.8.1-next.0 + - @backstage/plugin-api-docs@0.11.1-next.0 + - @backstage/plugin-cost-insights@0.12.20-next.0 + - @backstage/plugin-home@0.6.3-next.0 + - @backstage/plugin-scaffolder@1.18.1-next.0 + - @backstage/plugin-shortcuts@0.3.20-next.0 + - @backstage/plugin-catalog-import@0.10.7-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-app-api@0.6.1-next.0 + - @backstage/plugin-badges@0.2.55-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.0 + - @backstage/plugin-code-coverage@0.2.24-next.0 + - @backstage/plugin-entity-feedback@0.2.14-next.0 + - @backstage/plugin-explore@0.4.17-next.0 + - @backstage/plugin-gcalendar@0.3.24-next.0 + - @backstage/plugin-gocd@0.1.37-next.0 + - @backstage/plugin-jenkins@0.9.6-next.0 + - @backstage/plugin-microsoft-calendar@0.1.13-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.0 + - @backstage/plugin-pagerduty@0.7.3-next.0 + - @backstage/plugin-playlist@0.2.5-next.0 + - @backstage/plugin-puppetdb@0.1.14-next.0 + - @backstage/plugin-stackstorm@0.1.12-next.0 + - @backstage/plugin-tech-insights@0.3.23-next.0 + - @backstage/plugin-techdocs@1.10.1-next.0 + - @backstage/plugin-todo@0.2.35-next.0 + - @backstage/plugin-user-settings@0.8.2-next.0 + - @backstage/app-defaults@1.5.1-next.0 + - @backstage/plugin-azure-sites@0.1.20-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - app-next-example-plugin@0.0.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/plugin-airbrake@0.3.31-next.0 + - @backstage/plugin-apache-airflow@0.2.21-next.0 + - @backstage/plugin-app-visualizer@0.1.2-next.0 + - @backstage/plugin-catalog-graph@0.4.1-next.0 + - @backstage/plugin-cloudbuild@0.4.1-next.0 + - @backstage/plugin-dynatrace@9.0.1-next.0 + - @backstage/plugin-gcp-projects@0.3.47-next.0 + - @backstage/plugin-github-actions@0.6.12-next.0 + - @backstage/plugin-graphiql@0.3.4-next.0 + - @backstage/plugin-kafka@0.3.31-next.0 + - @backstage/plugin-kubernetes@0.11.6-next.0 + - @backstage/plugin-lighthouse@0.4.16-next.0 + - @backstage/plugin-newrelic@0.3.46-next.0 + - @backstage/plugin-octopus-deploy@0.2.13-next.0 + - @backstage/plugin-rollbar@0.4.31-next.0 + - @backstage/plugin-sentry@0.5.16-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## app-next-example-plugin@0.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## example-backend@0.2.93-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-backend@0.3.0-next.0 + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/plugin-linguist-backend@0.5.10-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/plugin-lighthouse-backend@0.4.5-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.16-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.22-next.0 + - @backstage/plugin-playlist-backend@0.3.17-next.0 + - @backstage/plugin-code-coverage-backend@0.2.27-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.10-next.0 + - @backstage/plugin-catalog-backend@1.18.0-next.0 + - @backstage/plugin-auth-backend@0.22.0-next.0 + - @backstage/plugin-jenkins-backend@0.4.0-next.0 + - @backstage/plugin-azure-devops-backend@0.6.0-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.16-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.30-next.0 + - @backstage/plugin-scaffolder-backend@1.22.0-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.17-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.17-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.17-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/plugin-kubernetes-backend@0.16.0-next.0 + - @backstage/plugin-adr-backend@0.4.10-next.0 + - @backstage/plugin-proxy-backend@0.4.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/plugin-signals-backend@0.0.4-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/plugin-tech-insights-backend@0.5.27-next.0 + - @backstage/plugin-search-backend@1.5.3-next.0 + - @backstage/plugin-devtools-backend@0.3.0-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/plugin-tech-insights-node@0.5.0-next.0 + - @backstage/plugin-badges-backend@0.3.10-next.0 + - @backstage/plugin-permission-backend@0.5.36-next.0 + - @backstage/plugin-app-backend@0.3.61-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.10-next.0 + - @backstage/plugin-explore-backend@0.0.23-next.0 + - @backstage/plugin-rollbar-backend@0.1.58-next.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.45-next.0 + - @backstage/plugin-techdocs-backend@1.9.6-next.0 + - @backstage/plugin-kafka-backend@0.3.11-next.0 + - @backstage/plugin-nomad-backend@0.1.15-next.0 + - @backstage/plugin-todo-backend@0.3.11-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.10-next.0 + - example-app@0.2.93-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.0 + +## example-backend-next@0.0.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-linguist-backend@0.5.10-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/plugin-lighthouse-backend@0.4.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.0-next.0 + - @backstage/plugin-playlist-backend@0.3.17-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.10-next.0 + - @backstage/plugin-notifications-backend@0.1.0-next.0 + - @backstage/plugin-catalog-backend@1.18.0-next.0 + - @backstage/plugin-auth-backend@0.22.0-next.0 + - @backstage/plugin-jenkins-backend@0.4.0-next.0 + - @backstage/plugin-azure-devops-backend@0.6.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.3-next.0 + - @backstage/plugin-scaffolder-backend@1.22.0-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.17-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.17-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.17-next.0 + - @backstage/backend-defaults@0.2.13-next.0 + - @backstage/plugin-kubernetes-backend@0.16.0-next.0 + - @backstage/plugin-adr-backend@0.4.10-next.0 + - @backstage/plugin-proxy-backend@0.4.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/plugin-signals-backend@0.0.4-next.0 + - @backstage/plugin-search-backend@1.5.3-next.0 + - @backstage/plugin-devtools-backend@0.3.0-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.6-next.0 + - @backstage/plugin-badges-backend@0.3.10-next.0 + - @backstage/plugin-permission-backend@0.5.36-next.0 + - @backstage/plugin-app-backend@0.3.61-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.10-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.30-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.10-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.10-next.0 + - @backstage/plugin-sonarqube-backend@0.2.15-next.0 + - @backstage/plugin-techdocs-backend@1.9.6-next.0 + - @backstage/plugin-nomad-backend@0.1.15-next.0 + - @backstage/plugin-todo-backend@0.3.11-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.10-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## e2e-test@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.12-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/cli-common@0.1.13 + +## techdocs-cli-embedded-app@0.2.92-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/cli@0.25.3-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-techdocs@1.10.1-next.0 + - @backstage/app-defaults@1.5.1-next.0 + - @backstage/test-utils@1.5.1-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/core-app-api@1.12.1-next.0 + +## @internal/plugin-todo-list@1.0.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## @internal/plugin-todo-list-backend@1.0.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + +## @internal/plugin-todo-list-common@1.0.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 diff --git a/docs/releases/v1.24.0-next.1-changelog.md b/docs/releases/v1.24.0-next.1-changelog.md new file mode 100644 index 0000000000..1336073128 --- /dev/null +++ b/docs/releases/v1.24.0-next.1-changelog.md @@ -0,0 +1,3299 @@ +# Release v1.24.0-next.1 + +## @backstage/config@1.2.0-next.1 + +### Minor Changes + +- 50cf9df: The `ConfigReader` now treats `null` values as present but explicitly undefined, meaning it will not fall back to the next level of configuration. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/config-loader@1.7.0-next.1 + +### Minor Changes + +- db8358d: Forward `null` values read from configuration files in configuration data, rather than treating them as an absence of config. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.7.0-next.1 + +### Minor Changes + +- 8bfcc50: Fix knip-report command to send 1 exit status in case of fail + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-azure-devops@0.4.0-next.1 + +### Minor Changes + +- 3270b1b: Azure DevOps plugin is now integrated with permission framework for its core features, see the <https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md#permission-framework> for more details. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-azure-devops-common@0.4.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-azure-devops-backend@0.6.0-next.1 + +### Minor Changes + +- 3270b1b: Azure DevOps plugin is now integrated with permission framework for its core features, see the <https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md#permission-framework> for more details. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-azure-devops-common@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-notifications@0.1.0-next.1 + +### Minor Changes + +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## @backstage/plugin-notifications-backend@0.1.0-next.1 + +### Minor Changes + +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- a790a3d: Move notification origin resolving to backend with new auth +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/plugin-notifications-node@0.1.0-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-scaffolder-backend@1.22.0-next.1 + +### Minor Changes + +- aa543c9: Migrate plugin to use the new auth services, add an optional service discovery to the router options and change the permissions type to be `PermissionsService`. + +### Patch Changes + +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.6-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.17-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-scaffolder-node@0.4.0-next.1 + +### Minor Changes + +- aa543c9: Update task context type to contain the new auth initiator credentials. + +### Patch Changes + +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-signals-backend@0.1.0-next.1 + +### Minor Changes + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- df45710: Improved error logging and fixed authentication +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-signals-node@0.1.0-next.1 + +### Minor Changes + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/app-defaults@1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/theme@0.5.2-next.0 + +## @backstage/backend-app-api@0.6.0-next.1 + +### Patch Changes + +- 81e0120: Fixed an issue where configuration schema for the purpose of redacting secrets from logs was not being read correctly. +- f235ca7: Make sure to not filter out schemas in `createConfigSecretEnumerator` +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/backend-common@0.21.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/backend-app-api@0.6.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + +## @backstage/backend-dynamic-feature-service@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/backend-app-api@0.6.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-catalog-backend@1.18.0-next.1 + - @backstage/plugin-events-backend@0.3.0-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-app-node@0.1.14-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/backend-openapi-utils@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/backend-plugin-api@0.6.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/types@1.1.1 + +## @backstage/backend-tasks@0.5.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-app-api@0.6.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/cli@0.25.3-next.1 + +### Patch Changes + +- 8dce287: Fix prettier issues on default plugins & module templates +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/eslint-plugin@0.1.6-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.1-next.1 + +### Patch Changes + +- 2ff3e6e: The translation support for the `Link` component has been removed for now, in order to avoid broad breakages of tests in existing projects where the component is tested without being wrapped in an API provider. +- 2d06e4b: Move the text-transform styling on BackstageTableHeader from inline styling to `withStyles` so it can be customised easier +- 5c271fa: Removed inline styling in breadcrumbs and replaced with a theme reachable class of BreadcrumbsCurrentPage +- 0a8a1e9: Fix a spacing issue for the SidebarSubmenu in case a SidebarScrollWrapper is used that made it hard to reach the SidebarSubmenu +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-plugin-api@1.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.12-next.1 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/app-defaults@1.5.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + +## @backstage/frontend-app-api@0.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.1-next.1 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/integration@1.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/integration-aws-node@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/integration-react@1.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + +## @techdocs/cli@1.8.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + +## @backstage/test-utils@1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-adr@0.6.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-adr-common@0.2.21-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-adr-backend@0.4.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-adr-common@0.2.21-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-adr-common@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-airbrake@0.3.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/dev-utils@1.0.28-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-airbrake-backend@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + +## @backstage/plugin-allure@0.1.47-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-analytics-module-ga@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + +## @backstage/plugin-analytics-module-ga4@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + +## @backstage/plugin-apache-airflow@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-api-docs@0.11.1-next.1 + +### Patch Changes + +- efba3d2: Updated dependency `@asyncapi/react-component` to `1.3.1`. +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-apollo-explorer@0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-app-backend@0.3.62-next.1 + +### Patch Changes + +- 52e43f2: Disable default auth policy, allowing unauthenticated access to app bundle. +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-app-node@0.1.14-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.7.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + +## @backstage/plugin-app-visualizer@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + +## @backstage/plugin-auth-backend@0.22.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.5-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.9-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.4-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.6-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.9-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.11-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.11-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.1.11-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.11-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.7-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.7-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-backend@0.22.0-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.0-next.1 + +### Patch Changes + +- 72dd380: Ensure that the config schema is present +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-backend@0.22.0-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-auth-node@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops-common@0.4.0-next.1 + +### Patch Changes + +- 3270b1b: Azure DevOps plugin is now integrated with permission framework for its core features, see the <https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md#permission-framework> for more details. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-azure-sites@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.1 + +## @backstage/plugin-azure-sites-backend@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-azure-sites-common@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-badges@0.2.55-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-badges-backend@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-bazaar@0.2.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-bazaar-backend@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + +## @backstage/plugin-bitbucket-cloud-common@0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.1 + +## @backstage/plugin-bitrise@0.1.58-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-catalog@1.17.1-next.1 + +### Patch Changes + +- 2ac1630: Added support for passing in custom filters to `CatalogIndexPage` +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-catalog-backend@1.18.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/repo-tools@0.7.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.18-next.1 + - @backstage/backend-openapi-utils@0.1.7-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.1.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/backend-openapi-utils@0.1.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.17-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-catalog-backend@1.18.0-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-catalog-backend-module-github@0.5.4-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.11-next.1 + +### Patch Changes + +- 9f5b8bc: Add GitLab `visibility` to group entity annotations. +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-catalog-backend@1.18.0-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-catalog-backend@1.18.0-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-catalog-common@1.0.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-catalog-graph@0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-node@1.8.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-react@1.10.1-next.1 + +### Patch Changes + +- b2a9926: Adds an argument for which filters should be applied when fetching/counting available values +- a6e237f: Added `DefaultFilters` component +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-cicd-statistics@0.1.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-cicd-statistics@0.1.33-next.1 + +## @backstage/plugin-circleci@0.3.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-cloudbuild@0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-code-climate@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-code-coverage@0.2.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-code-coverage-backend@0.2.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-codescene@0.1.23-next.1 + +### Patch Changes + +- e477ec4: Extending code scene plugin in Entity page. +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + +## @backstage/plugin-config-schema@0.1.51-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-devtools-common@0.1.9-next.1 + +## @backstage/plugin-devtools-backend@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9-next.1 + +## @backstage/plugin-devtools-common@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-dynatrace@9.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-entity-feedback@0.2.14-next.1 + +### Patch Changes + +- 96adf78: Remove empty Chip in `FeedbackResponseTable.tsx` when there is no response, and fix typo in Feedback Dialog Box. +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.11-next.1 + +### Patch Changes + +- 45115fd: Add in description for 400 response when encountering an invalid rating request +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-events-backend@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-module-github@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-backend-test-utils@0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.1 + +## @backstage/plugin-events-node@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + +## @backstage/plugin-explore@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-explore-backend@0.0.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.18-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-explore-react@0.0.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-fossa@0.2.63-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-gcalendar@0.3.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-gcp-projects@0.3.47-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-git-release-manager@0.3.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + +## @backstage/plugin-github-actions@0.6.12-next.1 + +### Patch Changes + +- 8ab3218: Fixed bug in WorkflowRunStatus component where skipped and cancelled workflow runs appeared as success +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-github-deployments@0.1.62-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-github-issues@0.2.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-github-pull-requests-board@0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-gitops-profiles@0.3.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-gocd@0.1.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-graphiql@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + +## @backstage/plugin-graphql-voyager@0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-home@0.6.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-home-react@0.1.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/theme@0.5.2-next.0 + +## @backstage/plugin-home-react@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-ilert@0.2.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-jenkins@0.9.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-jenkins-common@0.1.25-next.1 + +## @backstage/plugin-jenkins-backend@0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-jenkins-common@0.1.25-next.1 + +## @backstage/plugin-jenkins-common@0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-kafka@0.3.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-kafka-backend@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-kubernetes@0.11.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-kubernetes-react@0.3.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-backend@0.16.0-next.1 + +### Patch Changes + +- 69d0217: Pass user credentials when calling catalog get entities api. +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-kubernetes-node@0.1.8-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-cluster@0.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-kubernetes-react@0.3.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-common@0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-node@0.1.8-next.1 + +### Patch Changes + +- 69d0217: Accept auth credentials to get kubernetes clusters +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-react@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-lighthouse@0.4.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-lighthouse-common@0.1.5-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-lighthouse-backend@0.4.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-lighthouse-common@0.1.5-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-lighthouse-common@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-linguist@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-newrelic@0.3.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-newrelic-dashboard@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-nomad@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-nomad-backend@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-notifications-common@0.0.2-next.1 + +### Patch Changes + +- a790a3d: Move notification origin resolving to backend with new auth + +## @backstage/plugin-notifications-node@0.1.0-next.1 + +### Patch Changes + +- a790a3d: Move notification origin resolving to backend with new auth +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-octopus-deploy@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-opencost@0.2.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-org@0.6.21-next.1 + +### Patch Changes + +- a767aaa: Fixed an issue where the `OwnershipCard` component failed to scroll properly when used alongside `react-grid-layout`. +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-org-react@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-pagerduty@0.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-home-react@0.1.9-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-periskop@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-periskop-backend@0.2.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + +## @backstage/plugin-permission-backend@0.5.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + +## @backstage/plugin-permission-common@0.7.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-permission-node@0.7.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-permission-react@0.4.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + +## @backstage/plugin-playlist@0.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-playlist-common@0.1.15-next.1 + +## @backstage/plugin-playlist-backend@0.3.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-playlist-common@0.1.15-next.1 + +## @backstage/plugin-playlist-common@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + +## @backstage/plugin-proxy-backend@0.4.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + +## @backstage/plugin-puppetdb@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-rollbar@0.4.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-rollbar-backend@0.1.59-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + +## @backstage/plugin-scaffolder@1.18.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-scaffolder-react@1.8.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.1 + +### Patch Changes + +- 35fe005: Export `getOctokitOptions` for easy re-use of Octokit configuration handling +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-common@1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.1 + +### Patch Changes + +- aa543c9: Add an initiator credentials getter to the default mock context. +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-test-utils@0.3.4-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-scaffolder-react@1.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-search@1.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend@1.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/backend-openapi-utils@0.1.7-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-catalog@0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.17-next.1 + +### Patch Changes + +- e1f73d0: Added config.d.ts entry with secrets for the shared auth block +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-explore@0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-pg@0.5.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-techdocs@0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-node@1.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-common@1.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-react@1.7.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-sentry@0.5.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-shortcuts@0.3.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## @backstage/plugin-signals-react@0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-sonarqube-react@0.1.14-next.1 + +## @backstage/plugin-sonarqube-backend@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-sonarqube-react@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-splunk-on-call@0.4.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-stack-overflow@0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-home-react@0.1.9-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-stack-overflow-backend@0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.7-next.1 + +## @backstage/plugin-stackstorm@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-tech-insights@0.3.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-tech-insights-node@0.5.0-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.46-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-tech-insights-node@0.5.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-node@0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.6.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + +## @backstage/plugin-techdocs@1.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/plugin-techdocs@1.10.1-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + +## @backstage/plugin-techdocs-backend@1.9.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + +## @backstage/plugin-techdocs-node@1.11.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-techdocs-react@1.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-todo-backend@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/repo-tools@0.7.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/backend-openapi-utils@0.1.7-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.1 + +## @backstage/plugin-user-settings@0.8.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-vault-backend@0.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-vault-node@0.1.7-next.1 + +## @backstage/plugin-vault-node@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.1 + +## @backstage/plugin-xcmetrics@0.2.49-next.1 + +### Patch Changes + +- 7984d1e: Fixed bug in XcMetricsClient where it was not including parameter for excludeCI, which is now a required parameter for XCMetrics. +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## example-app@0.2.93-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-github-actions@0.6.12-next.1 + - @backstage/cli@0.25.3-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-entity-feedback@0.2.14-next.1 + - @backstage/plugin-api-docs@0.11.1-next.1 + - @backstage/plugin-notifications@0.1.0-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/plugin-azure-devops@0.4.0-next.1 + - @backstage/plugin-org@0.6.21-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-app-api@0.6.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-catalog-import@0.10.7-next.1 + - @backstage/plugin-cost-insights@0.12.20-next.1 + - @backstage/plugin-home@0.6.3-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-stack-overflow@0.1.26-next.1 + - @backstage/plugin-techdocs@1.10.1-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/app-defaults@1.5.1-next.1 + - @backstage/plugin-adr@0.6.14-next.1 + - @backstage/plugin-airbrake@0.3.31-next.1 + - @backstage/plugin-apache-airflow@0.2.21-next.1 + - @backstage/plugin-azure-sites@0.1.20-next.1 + - @backstage/plugin-badges@0.2.55-next.1 + - @backstage/plugin-catalog-graph@0.4.1-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.1 + - @backstage/plugin-cloudbuild@0.4.1-next.1 + - @backstage/plugin-code-coverage@0.2.24-next.1 + - @backstage/plugin-devtools@0.1.10-next.1 + - @backstage/plugin-dynatrace@9.0.1-next.1 + - @backstage/plugin-explore@0.4.17-next.1 + - @backstage/plugin-gcalendar@0.3.24-next.1 + - @backstage/plugin-gcp-projects@0.3.47-next.1 + - @backstage/plugin-github-pull-requests-board@0.1.25-next.1 + - @backstage/plugin-gocd@0.1.37-next.1 + - @backstage/plugin-graphiql@0.3.4-next.1 + - @backstage/plugin-jenkins@0.9.6-next.1 + - @backstage/plugin-kafka@0.3.31-next.1 + - @backstage/plugin-kubernetes@0.11.6-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.7-next.1 + - @backstage/plugin-lighthouse@0.4.16-next.1 + - @backstage/plugin-linguist@0.1.16-next.1 + - @backstage/plugin-microsoft-calendar@0.1.13-next.1 + - @backstage/plugin-newrelic@0.3.46-next.1 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.1 + - @backstage/plugin-nomad@0.1.12-next.1 + - @backstage/plugin-octopus-deploy@0.2.13-next.1 + - @backstage/plugin-pagerduty@0.7.3-next.1 + - @backstage/plugin-playlist@0.2.5-next.1 + - @backstage/plugin-puppetdb@0.1.14-next.1 + - @backstage/plugin-rollbar@0.4.31-next.1 + - @backstage/plugin-scaffolder@1.18.1-next.1 + - @backstage/plugin-scaffolder-react@1.8.1-next.1 + - @backstage/plugin-search@1.4.7-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/plugin-sentry@0.5.16-next.1 + - @backstage/plugin-shortcuts@0.3.20-next.1 + - @backstage/plugin-signals@0.0.2-next.1 + - @backstage/plugin-stackstorm@0.1.12-next.1 + - @backstage/plugin-tech-insights@0.3.23-next.1 + - @backstage/plugin-tech-radar@0.6.14-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.1 + - @backstage/plugin-todo@0.2.35-next.1 + - @backstage/plugin-user-settings@0.8.2-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## example-app-next@0.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-github-actions@0.6.12-next.1 + - @backstage/cli@0.25.3-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-entity-feedback@0.2.14-next.1 + - @backstage/plugin-api-docs@0.11.1-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/plugin-azure-devops@0.4.0-next.1 + - @backstage/plugin-org@0.6.21-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-app-api@0.6.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-catalog-import@0.10.7-next.1 + - @backstage/plugin-cost-insights@0.12.20-next.1 + - @backstage/plugin-home@0.6.3-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-techdocs@1.10.1-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/app-defaults@1.5.1-next.1 + - app-next-example-plugin@0.0.7-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-adr@0.6.14-next.1 + - @backstage/plugin-airbrake@0.3.31-next.1 + - @backstage/plugin-apache-airflow@0.2.21-next.1 + - @backstage/plugin-app-visualizer@0.1.2-next.1 + - @backstage/plugin-azure-sites@0.1.20-next.1 + - @backstage/plugin-badges@0.2.55-next.1 + - @backstage/plugin-catalog-graph@0.4.1-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.1 + - @backstage/plugin-cloudbuild@0.4.1-next.1 + - @backstage/plugin-code-coverage@0.2.24-next.1 + - @backstage/plugin-devtools@0.1.10-next.1 + - @backstage/plugin-dynatrace@9.0.1-next.1 + - @backstage/plugin-explore@0.4.17-next.1 + - @backstage/plugin-gcalendar@0.3.24-next.1 + - @backstage/plugin-gcp-projects@0.3.47-next.1 + - @backstage/plugin-gocd@0.1.37-next.1 + - @backstage/plugin-graphiql@0.3.4-next.1 + - @backstage/plugin-jenkins@0.9.6-next.1 + - @backstage/plugin-kafka@0.3.31-next.1 + - @backstage/plugin-kubernetes@0.11.6-next.1 + - @backstage/plugin-lighthouse@0.4.16-next.1 + - @backstage/plugin-linguist@0.1.16-next.1 + - @backstage/plugin-microsoft-calendar@0.1.13-next.1 + - @backstage/plugin-newrelic@0.3.46-next.1 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.1 + - @backstage/plugin-octopus-deploy@0.2.13-next.1 + - @backstage/plugin-pagerduty@0.7.3-next.1 + - @backstage/plugin-playlist@0.2.5-next.1 + - @backstage/plugin-puppetdb@0.1.14-next.1 + - @backstage/plugin-rollbar@0.4.31-next.1 + - @backstage/plugin-scaffolder@1.18.1-next.1 + - @backstage/plugin-scaffolder-react@1.8.1-next.1 + - @backstage/plugin-search@1.4.7-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/plugin-sentry@0.5.16-next.1 + - @backstage/plugin-shortcuts@0.3.20-next.1 + - @backstage/plugin-stackstorm@0.1.12-next.1 + - @backstage/plugin-tech-insights@0.3.23-next.1 + - @backstage/plugin-tech-radar@0.6.14-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.1 + - @backstage/plugin-todo@0.2.35-next.1 + - @backstage/plugin-user-settings@0.8.2-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## app-next-example-plugin@0.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + +## example-backend@0.2.93-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-entity-feedback-backend@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend@1.22.0-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.17-next.1 + - @backstage/plugin-app-backend@0.3.62-next.1 + - @backstage/plugin-signals-backend@0.1.0-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/plugin-azure-devops-backend@0.6.0-next.1 + - @backstage/plugin-kubernetes-backend@0.16.0-next.1 + - example-app@0.2.93-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-adr-backend@0.4.11-next.1 + - @backstage/plugin-auth-backend@0.22.0-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-badges-backend@0.3.11-next.1 + - @backstage/plugin-catalog-backend@1.18.0-next.1 + - @backstage/plugin-code-coverage-backend@0.2.28-next.1 + - @backstage/plugin-devtools-backend@0.3.0-next.1 + - @backstage/plugin-events-backend@0.3.0-next.1 + - @backstage/plugin-explore-backend@0.0.24-next.1 + - @backstage/plugin-jenkins-backend@0.4.0-next.1 + - @backstage/plugin-kafka-backend@0.3.12-next.1 + - @backstage/plugin-lighthouse-backend@0.4.6-next.1 + - @backstage/plugin-linguist-backend@0.5.11-next.1 + - @backstage/plugin-nomad-backend@0.1.16-next.1 + - @backstage/plugin-permission-backend@0.5.37-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-playlist-backend@0.3.18-next.1 + - @backstage/plugin-proxy-backend@0.4.12-next.1 + - @backstage/plugin-rollbar-backend@0.1.59-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.17-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.31-next.1 + - @backstage/plugin-search-backend@1.5.4-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.18-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.18-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.23-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-tech-insights-backend@0.5.28-next.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.46-next.1 + - @backstage/plugin-tech-insights-node@0.5.0-next.1 + - @backstage/plugin-techdocs-backend@1.9.7-next.1 + - @backstage/plugin-todo-backend@0.3.12-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.11-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## example-backend-next@0.0.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-entity-feedback-backend@0.2.11-next.1 + - @backstage/plugin-notifications-backend@0.1.0-next.1 + - @backstage/plugin-scaffolder-backend@1.22.0-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.1 + - @backstage/plugin-app-backend@0.3.62-next.1 + - @backstage/plugin-signals-backend@0.1.0-next.1 + - @backstage/plugin-azure-devops-backend@0.6.0-next.1 + - @backstage/plugin-kubernetes-backend@0.16.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-adr-backend@0.4.11-next.1 + - @backstage/plugin-auth-backend@0.22.0-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-badges-backend@0.3.11-next.1 + - @backstage/plugin-catalog-backend@1.18.0-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.7-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.31-next.1 + - @backstage/plugin-devtools-backend@0.3.0-next.1 + - @backstage/plugin-jenkins-backend@0.4.0-next.1 + - @backstage/plugin-lighthouse-backend@0.4.6-next.1 + - @backstage/plugin-linguist-backend@0.5.11-next.1 + - @backstage/plugin-nomad-backend@0.1.16-next.1 + - @backstage/plugin-permission-backend@0.5.37-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-playlist-backend@0.3.18-next.1 + - @backstage/plugin-proxy-backend@0.4.12-next.1 + - @backstage/plugin-search-backend@1.5.4-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.18-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.18-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-sonarqube-backend@0.2.16-next.1 + - @backstage/plugin-techdocs-backend@1.9.7-next.1 + - @backstage/plugin-todo-backend@0.3.12-next.1 + - @backstage/backend-defaults@0.2.14-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.11-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.11-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.11-next.1 + +## e2e-test@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.12-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4-next.0 + +## techdocs-cli-embedded-app@0.2.92-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/cli@0.25.3-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/plugin-techdocs@1.10.1-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/app-defaults@1.5.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + +## @internal/plugin-todo-list@1.0.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @internal/plugin-todo-list-backend@1.0.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + +## @internal/plugin-todo-list-common@1.0.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 diff --git a/docs/releases/v1.24.0-next.2-changelog.md b/docs/releases/v1.24.0-next.2-changelog.md new file mode 100644 index 0000000000..141dceabae --- /dev/null +++ b/docs/releases/v1.24.0-next.2-changelog.md @@ -0,0 +1,3126 @@ +# Release v1.24.0-next.2 + +## @backstage/plugin-azure-sites-backend@0.3.0-next.2 + +### Minor Changes + +- acf3e00: Azure Sites list now hides the internal/microsoft only `hidden-` tags from the list of tags that are returned. Updated the log endpoint to /logstream-quickstart rather than just /logstream to stream logs in the Azure Portal UI. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-catalog@1.18.0-next.2 + +### Minor Changes + +- 72b8827: Adds a title to the `PaginatedCatalogTable` for better visibility on what you're viewing. + +### Patch Changes + +- 298953b: Added support for providing an `initiallySelectedNamespaces` which accepts an array of Namespaces to have selected by default +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-catalog-react@1.11.0-next.2 + +### Minor Changes + +- 72b8827: Number of results is now directly added as the field `totalItems` on `useEntityList`. + +### Patch Changes + +- 298953b: Added support for providing an `initiallySelectedNamespaces` which accepts an array of Namespaces to have selected by default +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## @backstage/plugin-home@0.7.0-next.2 + +### Minor Changes + +- 8807d2a: Resolved styling inconsistencies and title visibility issues in Top Visited and Recently Visited cards + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-home-react@0.1.9-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + +## @backstage/plugin-notifications@0.1.0-next.2 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## @backstage/plugin-notifications-backend@0.1.0-next.2 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options + +### Patch Changes + +- 6d84ee6: Changed to use the refactored signal service naming +- Updated dependencies + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-notifications-node@0.1.0-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-events-node@0.3.0-next.2 + - @backstage/plugin-notifications-common@0.0.2-next.1 + +## @backstage/plugin-scaffolder@1.19.0-next.2 + +### Minor Changes + +- a3b4d90: Added a menu to the header of template page for direct access to editing the template + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-scaffolder-react@1.8.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-scaffolder-backend@1.22.0-next.2 + +### Minor Changes + +- e9663a9: Move away from using `ctx.logStream` +- e9663a9: Enable the redaction of secrets using the redacting logger and the secrets from the `TaskSpec` + +### Patch Changes + +- 703ebc9: Fix support for unauthenticated requests to create scaffolder tasks +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.6-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.4-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0-next.2 + +### Minor Changes + +- 6bfb7b1: Output the `iid` as `issuesIid` from the `gitlab:issues:create` action + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-node@0.4.0-next.2 + +### Minor Changes + +- 02ee466: **DEPRECATION** - Deprecated the `logStream` in the `ActionContext`. Please move to using `ctx.logger.x` instead. + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-tech-radar@0.7.0-next.2 + +### Minor Changes + +- 0453619: Fixed example snippet in `README.md` to reflect correct timeline item order. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-techdocs-backend@1.10.0-next.2 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- 3f14e9f: Migrate plugin to use the new auth services. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + +## @backstage/plugin-techdocs-node@1.12.0-next.2 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-techdocs-react@1.2.0-next.2 + +### Minor Changes + +- 3f14e9f: Create a new api method for issuing user cookie. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/app-defaults@1.5.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## @backstage/backend-app-api@0.6.0-next.2 + +### Patch Changes + +- 15fda44: Provide some sane defaults for `WinstonLogger.create` making some of the arguments optional +- 9d91128: Add the possibility to disable watching files in the new backend system +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/backend-common@0.21.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-app-api@0.6.0-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + +## @backstage/backend-dynamic-feature-service@0.2.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-catalog-backend@1.18.0-next.2 + - @backstage/backend-app-api@0.6.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.14-next.2 + - @backstage/plugin-events-backend@0.3.0-next.2 + - @backstage/plugin-events-node@0.3.0-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/backend-openapi-utils@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/errors@1.2.4-next.0 + +## @backstage/backend-plugin-api@0.6.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + +## @backstage/backend-tasks@0.5.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.1-next.1 + +### Patch Changes + +- 6f830bb: Allow passing optional filter to `getEntitiesByRefs` +- Updated dependencies + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/cli@0.25.3-next.2 + +### Patch Changes + +- f39dfd3: Tweak the descriptions of the CLI templates +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/eslint-plugin@0.1.6-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.1-next.2 + +### Patch Changes + +- 0c9d5ea: Updated MUI imports for core-components to not be top level +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.12-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/app-defaults@1.5.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + +## @backstage/frontend-app-api@0.6.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/integration@1.9.1-next.2 + +### Patch Changes + +- 0386fa7: Fixed an issue with resolution of SCM URLs against a base URL with a trailing slash. +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/integration-react@1.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/repo-tools@0.7.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4-next.0 + - @backstage/errors@1.2.4-next.0 + +## @techdocs/cli@1.8.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-adr@0.6.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/plugin-adr-common@0.2.21-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-adr-backend@0.4.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-adr-common@0.2.21-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-adr-common@0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-airbrake@0.3.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/dev-utils@1.0.28-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/test-utils@1.5.1-next.1 + +## @backstage/plugin-airbrake-backend@0.3.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-allure@0.1.47-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-analytics-module-ga@0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-analytics-module-ga4@0.2.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-apache-airflow@0.2.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-api-docs@0.11.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## @backstage/plugin-apollo-explorer@0.1.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-app-backend@0.3.62-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.14-next.2 + +## @backstage/plugin-app-node@0.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config-loader@1.7.0-next.1 + +## @backstage/plugin-app-visualizer@0.1.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-auth-backend@0.22.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.4-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.6-next.2 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.5-next.2 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.9-next.2 + - @backstage/plugin-auth-backend-module-github-provider@0.1.11-next.2 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.11-next.2 + - @backstage/plugin-auth-backend-module-google-provider@0.1.11-next.2 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.9-next.2 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.11-next.2 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.7-next.2 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.7-next.2 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-backend@0.22.0-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.4-next.2 + +### Patch Changes + +- 74b1dc9: Increased HTTP request timeout used by OIDC authenticator. +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-backend@0.22.0-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-auth-node@0.4.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.4.0-next.2 + +### Patch Changes + +- 9f19476: Updated README +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-azure-devops-common@0.4.0-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## @backstage/plugin-azure-devops-backend@0.6.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-azure-devops-common@0.4.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-azure-sites@0.1.20-next.2 + +### Patch Changes + +- 8679bda: Modified azure table to only show loading UI on initial load. Sorted tags in table is their order from the api is indeterminate, and they would randomly shuffle on each load +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-azure-sites-common@0.1.3-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## @backstage/plugin-badges@0.2.55-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-badges-backend@0.3.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-bazaar@0.2.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-bazaar-backend@0.3.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-bitbucket-cloud-common@0.2.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + +## @backstage/plugin-bitrise@0.1.58-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-catalog-backend@1.18.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 6f830bb: Allow passing optional filter to `getEntitiesByRefs` +- b65788b: Move @backstage/repo-tools to dev dependencies +- dad018f: Do not fail on stitching when the entity contains `null` values associated to deeply nested or long keys. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.18-next.2 + - @backstage/backend-openapi-utils@0.1.7-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-events-node@0.3.0-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-catalog-backend-module-aws@0.3.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.1.33-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.7-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-openapi-utils@0.1.7-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.17-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.5.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.18.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.5.4-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.18.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-events-node@0.3.0-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.18.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.3.11-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + +## @backstage/plugin-catalog-graph@0.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.7-next.2 + +### Patch Changes + +- adc0414: fix related to component name not adhering to kubernetes valid object name. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-catalog-node@1.8.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-cicd-statistics@0.1.33-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-cicd-statistics@0.1.33-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-circleci@0.3.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-cloudbuild@0.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-code-climate@0.1.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-code-coverage@0.2.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-code-coverage-backend@0.2.28-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 1914e2a: Updated README +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-codescene@0.1.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + +## @backstage/plugin-config-schema@0.1.51-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.10-next.2 + +### Patch Changes + +- 8b0026d: Removed unused `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-devtools-common@0.1.9-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## @backstage/plugin-devtools-backend@0.3.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 8b0026d: Removed unused `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0-next.1 + - @backstage/config-loader@1.7.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-dynatrace@10.0.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-entity-feedback@0.2.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-events-backend@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-module-azure@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-module-gerrit@0.2.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-module-github@0.2.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-module-gitlab@0.2.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-backend-test-utils@0.1.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-events-node@0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-explore@0.4.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-explore-backend@0.0.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-module-explore@0.1.18-next.2 + +## @backstage/plugin-firehydrant@0.2.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-fossa@0.2.63-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-gcalendar@0.3.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-gcp-projects@0.3.47-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-git-release-manager@0.3.43-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-github-actions@0.6.12-next.2 + +### Patch Changes + +- 692316d: Fixed bug in WorkflowRunStatus component where status description of skipped and cancelled workflow runs appeared as success +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-github-deployments@0.1.62-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-github-issues@0.2.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-github-pull-requests-board@0.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-gitops-profiles@0.3.46-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-gocd@0.1.37-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-graphiql@0.3.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-graphql-voyager@0.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-home-react@0.1.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-ilert@0.2.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-jenkins@0.9.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-jenkins-common@0.1.25-next.1 + +## @backstage/plugin-jenkins-backend@0.4.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-jenkins-common@0.1.25-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-kafka@0.3.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-kafka-backend@0.3.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-kubernetes@0.11.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-kubernetes-react@0.3.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-backend@0.16.0-next.2 + +### Patch Changes + +- b9a0888: Fixed a bug in the proxy endpoint. Now when the `serviceAccount` strategy is used and no `serviceAccountToken` has been provided, the proxy endpoint assumes backstage is running on Kubernetes and gets the URL and CA from the Pod instance. +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-kubernetes-node@0.1.8-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-kubernetes-cluster@0.0.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-kubernetes-react@0.3.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-node@0.1.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-kubernetes-react@0.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5-next.1 + +## @backstage/plugin-lighthouse@0.4.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-lighthouse-common@0.1.5-next.1 + +## @backstage/plugin-lighthouse-backend@0.4.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.5-next.1 + +## @backstage/plugin-linguist@0.1.16-next.2 + +### Patch Changes + +- 051fda1: Removed unused `dependencies` and `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.11-next.2 + +### Patch Changes + +- 051fda1: Removed unused `dependencies` and `devDependencies` identified in Knip Report +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-newrelic@0.3.46-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-newrelic-dashboard@0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-nomad@0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-nomad-backend@0.1.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-notifications-node@0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.1 + +## @backstage/plugin-octopus-deploy@0.2.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-opencost@0.2.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-org@0.6.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## @backstage/plugin-org-react@0.1.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-pagerduty@0.7.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-home-react@0.1.9-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-periskop@0.1.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-periskop-backend@0.2.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-permission-backend@0.5.37-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + +## @backstage/plugin-permission-node@0.7.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-permission-common@0.7.13-next.1 + +## @backstage/plugin-playlist@0.2.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-playlist-common@0.1.15-next.1 + +## @backstage/plugin-playlist-backend@0.3.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-playlist-common@0.1.15-next.1 + +## @backstage/plugin-proxy-backend@0.4.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-puppetdb@0.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-rollbar@0.4.31-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-rollbar-backend@0.1.59-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/config@1.2.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.6-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.38-next.2 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.4-next.2 + +### Patch Changes + +- 9f19476: Updated README +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.31-next.2 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 563dfd0: Fix issue with package bundling, should be `dist/index.cjs.js` instead of `dist/index.esm.js`. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-test-utils@0.3.4-next.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## @backstage/plugin-search@1.4.7-next.2 + +### Patch Changes + +- 70ee3b7: Remove the hardcoded 'black' color give to the search type accordion icon as it doesn't work with dark themes +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend@1.5.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-openapi-utils@0.1.7-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-catalog@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-explore@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-pg@0.5.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-module-techdocs@0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-backend-node@1.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-search-react@1.7.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-sentry@0.5.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-shortcuts@0.3.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## @backstage/plugin-signals-backend@0.1.0-next.2 + +### Patch Changes + +- 6d84ee6: Changed to use the refactored signal service naming +- Updated dependencies + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-signals-node@0.1.0-next.2 + +### Patch Changes + +- 6d84ee6: Renamed `SignalService` to `SignalsService` and `signalService` to `signalServiceRef` + to follow the naming scheme of services and their references +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## @backstage/plugin-sonarqube@0.7.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-sonarqube-react@0.1.14-next.1 + +## @backstage/plugin-sonarqube-backend@0.2.16-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-splunk-on-call@0.4.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-stack-overflow@0.1.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-home-react@0.1.9-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-stack-overflow-backend@0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.7-next.2 + +## @backstage/plugin-stackstorm@0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-tech-insights@0.3.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.5.0-next.2 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.46-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.5.0-next.2 + +## @backstage/plugin-tech-insights-node@0.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-techdocs@1.10.1-next.2 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.28-next.2 + +### Patch Changes + +- 3f14e9f: Mock the new issue user cookie api method. +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/test-utils@1.5.1-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @backstage/plugin-todo@0.2.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-todo-backend@0.3.12-next.2 + +### Patch Changes + +- b65788b: Move @backstage/repo-tools to dev dependencies +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-openapi-utils@0.1.7-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-user-settings@0.8.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## @backstage/plugin-vault-backend@0.4.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-vault-node@0.1.7-next.2 + +## @backstage/plugin-vault-node@0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.14-next.2 + +## @backstage/plugin-xcmetrics@0.2.49-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## example-app@0.2.93-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1-next.2 + - @backstage/plugin-search@1.4.7-next.2 + - @backstage/plugin-scaffolder@1.19.0-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/plugin-notifications@0.1.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-tech-radar@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-azure-devops@0.4.0-next.2 + - @backstage/plugin-devtools@0.1.10-next.2 + - @backstage/plugin-azure-sites@0.1.20-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/plugin-linguist@0.1.16-next.2 + - @backstage/plugin-catalog-import@0.10.7-next.2 + - @backstage/plugin-home@0.7.0-next.2 + - @backstage/plugin-github-actions@0.6.12-next.2 + - @backstage/cli@0.25.3-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/plugin-github-pull-requests-board@0.1.25-next.2 + - @backstage/app-defaults@1.5.1-next.2 + - @backstage/frontend-app-api@0.6.1-next.2 + - @backstage/plugin-adr@0.6.14-next.2 + - @backstage/plugin-airbrake@0.3.31-next.2 + - @backstage/plugin-apache-airflow@0.2.21-next.2 + - @backstage/plugin-api-docs@0.11.1-next.2 + - @backstage/plugin-badges@0.2.55-next.2 + - @backstage/plugin-catalog-graph@0.4.1-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.2 + - @backstage/plugin-cloudbuild@0.4.1-next.2 + - @backstage/plugin-code-coverage@0.2.24-next.2 + - @backstage/plugin-cost-insights@0.12.20-next.2 + - @backstage/plugin-dynatrace@10.0.0-next.2 + - @backstage/plugin-entity-feedback@0.2.14-next.2 + - @backstage/plugin-explore@0.4.17-next.2 + - @backstage/plugin-gcalendar@0.3.24-next.2 + - @backstage/plugin-gcp-projects@0.3.47-next.2 + - @backstage/plugin-gocd@0.1.37-next.2 + - @backstage/plugin-graphiql@0.3.4-next.2 + - @backstage/plugin-jenkins@0.9.6-next.2 + - @backstage/plugin-kafka@0.3.31-next.2 + - @backstage/plugin-kubernetes@0.11.6-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.7-next.2 + - @backstage/plugin-lighthouse@0.4.16-next.2 + - @backstage/plugin-microsoft-calendar@0.1.13-next.2 + - @backstage/plugin-newrelic@0.3.46-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.2 + - @backstage/plugin-nomad@0.1.12-next.2 + - @backstage/plugin-octopus-deploy@0.2.13-next.2 + - @backstage/plugin-org@0.6.21-next.2 + - @backstage/plugin-pagerduty@0.7.3-next.2 + - @backstage/plugin-playlist@0.2.5-next.2 + - @backstage/plugin-puppetdb@0.1.14-next.2 + - @backstage/plugin-rollbar@0.4.31-next.2 + - @backstage/plugin-scaffolder-react@1.8.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/plugin-sentry@0.5.16-next.2 + - @backstage/plugin-shortcuts@0.3.20-next.2 + - @backstage/plugin-signals@0.0.2-next.2 + - @backstage/plugin-stack-overflow@0.1.26-next.2 + - @backstage/plugin-stackstorm@0.1.12-next.2 + - @backstage/plugin-tech-insights@0.3.23-next.2 + - @backstage/plugin-todo@0.2.35-next.2 + - @backstage/plugin-user-settings@0.8.2-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## example-app-next@0.0.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1-next.2 + - @backstage/plugin-search@1.4.7-next.2 + - @backstage/plugin-scaffolder@1.19.0-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-tech-radar@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-azure-devops@0.4.0-next.2 + - @backstage/plugin-devtools@0.1.10-next.2 + - @backstage/plugin-azure-sites@0.1.20-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/plugin-linguist@0.1.16-next.2 + - @backstage/plugin-catalog-import@0.10.7-next.2 + - @backstage/plugin-home@0.7.0-next.2 + - @backstage/plugin-github-actions@0.6.12-next.2 + - @backstage/cli@0.25.3-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/app-defaults@1.5.1-next.2 + - app-next-example-plugin@0.0.7-next.2 + - @backstage/frontend-app-api@0.6.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-adr@0.6.14-next.2 + - @backstage/plugin-airbrake@0.3.31-next.2 + - @backstage/plugin-apache-airflow@0.2.21-next.2 + - @backstage/plugin-api-docs@0.11.1-next.2 + - @backstage/plugin-app-visualizer@0.1.2-next.2 + - @backstage/plugin-badges@0.2.55-next.2 + - @backstage/plugin-catalog-graph@0.4.1-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.2 + - @backstage/plugin-cloudbuild@0.4.1-next.2 + - @backstage/plugin-code-coverage@0.2.24-next.2 + - @backstage/plugin-cost-insights@0.12.20-next.2 + - @backstage/plugin-dynatrace@10.0.0-next.2 + - @backstage/plugin-entity-feedback@0.2.14-next.2 + - @backstage/plugin-explore@0.4.17-next.2 + - @backstage/plugin-gcalendar@0.3.24-next.2 + - @backstage/plugin-gcp-projects@0.3.47-next.2 + - @backstage/plugin-gocd@0.1.37-next.2 + - @backstage/plugin-graphiql@0.3.4-next.2 + - @backstage/plugin-jenkins@0.9.6-next.2 + - @backstage/plugin-kafka@0.3.31-next.2 + - @backstage/plugin-kubernetes@0.11.6-next.2 + - @backstage/plugin-lighthouse@0.4.16-next.2 + - @backstage/plugin-microsoft-calendar@0.1.13-next.2 + - @backstage/plugin-newrelic@0.3.46-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.2 + - @backstage/plugin-octopus-deploy@0.2.13-next.2 + - @backstage/plugin-org@0.6.21-next.2 + - @backstage/plugin-pagerduty@0.7.3-next.2 + - @backstage/plugin-playlist@0.2.5-next.2 + - @backstage/plugin-puppetdb@0.1.14-next.2 + - @backstage/plugin-rollbar@0.4.31-next.2 + - @backstage/plugin-scaffolder-react@1.8.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/plugin-sentry@0.5.16-next.2 + - @backstage/plugin-shortcuts@0.3.20-next.2 + - @backstage/plugin-stackstorm@0.1.12-next.2 + - @backstage/plugin-tech-insights@0.3.23-next.2 + - @backstage/plugin-todo@0.2.35-next.2 + - @backstage/plugin-user-settings@0.8.2-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## app-next-example-plugin@0.0.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + +## example-backend@0.2.93-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.22.0-next.2 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.31-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.11-next.2 + - @backstage/plugin-catalog-backend@1.18.0-next.2 + - @backstage/plugin-code-coverage-backend@0.2.28-next.2 + - @backstage/plugin-devtools-backend@0.3.0-next.2 + - @backstage/plugin-jenkins-backend@0.4.0-next.2 + - @backstage/plugin-search-backend@1.5.4-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-backend@1.10.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0-next.2 + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/plugin-linguist-backend@0.5.11-next.2 + - @backstage/plugin-kubernetes-backend@0.16.0-next.2 + - @backstage/plugin-todo-backend@0.3.12-next.2 + - @backstage/plugin-signals-backend@0.1.0-next.2 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.15-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-adr-backend@0.4.11-next.2 + - @backstage/plugin-azure-devops-backend@0.6.0-next.2 + - example-app@0.2.93-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.2 + - @backstage/plugin-auth-backend@0.22.0-next.2 + - @backstage/plugin-app-backend@0.3.62-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-badges-backend@0.3.11-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/plugin-entity-feedback-backend@0.2.11-next.2 + - @backstage/plugin-lighthouse-backend@0.4.6-next.2 + - @backstage/plugin-playlist-backend@0.3.18-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.18-next.2 + - @backstage/plugin-tech-insights-backend@0.5.28-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-azure-sites-common@0.1.3-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.2 + - @backstage/plugin-events-backend@0.3.0-next.2 + - @backstage/plugin-events-node@0.3.0-next.2 + - @backstage/plugin-explore-backend@0.0.24-next.2 + - @backstage/plugin-kafka-backend@0.3.12-next.2 + - @backstage/plugin-nomad-backend@0.1.16-next.2 + - @backstage/plugin-permission-backend@0.5.37-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-proxy-backend@0.4.12-next.2 + - @backstage/plugin-rollbar-backend@0.1.59-next.2 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.17-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.18-next.2 + - @backstage/plugin-search-backend-module-pg@0.5.23-next.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.46-next.2 + - @backstage/plugin-tech-insights-node@0.5.0-next.2 + +## example-backend-next@0.0.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.22.0-next.2 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.7-next.2 + - @backstage/plugin-catalog-backend-module-unprocessed@0.3.11-next.2 + - @backstage/plugin-catalog-backend@1.18.0-next.2 + - @backstage/plugin-devtools-backend@0.3.0-next.2 + - @backstage/plugin-jenkins-backend@0.4.0-next.2 + - @backstage/plugin-search-backend@1.5.4-next.2 + - @backstage/plugin-techdocs-backend@1.10.0-next.2 + - @backstage/plugin-notifications-backend@0.1.0-next.2 + - @backstage/plugin-linguist-backend@0.5.11-next.2 + - @backstage/plugin-kubernetes-backend@0.16.0-next.2 + - @backstage/plugin-todo-backend@0.3.12-next.2 + - @backstage/plugin-signals-backend@0.1.0-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.2 + - @backstage/plugin-catalog-backend-module-openapi@0.1.31-next.2 + - @backstage/plugin-adr-backend@0.4.11-next.2 + - @backstage/plugin-azure-devops-backend@0.6.0-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.2 + - @backstage/plugin-auth-backend@0.22.0-next.2 + - @backstage/backend-defaults@0.2.14-next.2 + - @backstage/plugin-app-backend@0.3.62-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-badges-backend@0.3.11-next.2 + - @backstage/plugin-entity-feedback-backend@0.2.11-next.2 + - @backstage/plugin-lighthouse-backend@0.4.6-next.2 + - @backstage/plugin-playlist-backend@0.3.18-next.2 + - @backstage/plugin-search-backend-module-catalog@0.1.18-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.11-next.2 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.0-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.2 + - @backstage/plugin-nomad-backend@0.1.16-next.2 + - @backstage/plugin-permission-backend@0.5.37-next.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.11-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-proxy-backend@0.4.12-next.2 + - @backstage/plugin-search-backend-module-explore@0.1.18-next.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-sonarqube-backend@0.2.16-next.2 + +## e2e-test@0.2.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.12-next.2 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4-next.0 + +## techdocs-cli-embedded-app@0.2.92-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/cli@0.25.3-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/app-defaults@1.5.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/theme@0.5.2-next.0 + +## @internal/plugin-todo-list@1.0.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## @internal/plugin-todo-list-backend@1.0.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/errors@1.2.4-next.0 diff --git a/docs/releases/v1.24.0.md b/docs/releases/v1.24.0.md new file mode 100644 index 0000000000..7bb8b174e1 --- /dev/null +++ b/docs/releases/v1.24.0.md @@ -0,0 +1,90 @@ +--- +id: v1.24.0 +title: v1.24.0 +description: Backstage Release v1.24.0 +--- + +These are the release notes for the v1.24.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 + +### BREAKING: Auth improvements + +This release is a big milestone for the authentication system of Backstage and includes a large collection of new APIs and services. The full proposal can be found in [BEP-0003](https://github.com/backstage/backstage/blob/master/beps/0003-auth-architecture-evolution/README.md), including the motivation for this change. The main highlight of these changes is that we’re adding security by default to Backstage, meaning that you will no longer be forced to protect your Backstage instance from unauthorized access. It also brings several other improvements, such as slimmer user tokens and better handling of user credentials. + +The majority of these improvements only apply to the new backend system, but the new service interfaces have backwards compatibility layers that allow them to be used in the old backend system too. + +This is the first phase of the rollout of these changes, and includes all breaking changes that we are expecting. The new service interfaces introduced in this release set us up for the ability to add further improvements to the system without the need for additional breaking changes. + +For information on how to migrate existing Backstage projects and plugins, refer to the [migration documentation](https://backstage.io/docs/tutorials/auth-service-migration). + +Due to this change, some backend plugins now require the `discovery` service to be forwarded from the plugin environment in the old backend system. + +As part of this change, the `getBearerTokenFromAuthorizationHeader` export from `@backstage/plugin-auth-node` has been deprecated and we discourage any usage of it. + +### BREAKING: Events system improvements + +The events system has been changed to have better compatibility with the new backend system, by handling all communication through a new events service. + +Existing modules have been refactored to accept the new `EventsService` as input, rather than implementing the `EventSubscriber` interface. Refer to the changesets for each module for information on how to migrate. + +For information on how to wire up the events service in the old backend system, see the [`events-node` README](https://github.com/backstage/backstage/tree/master/plugins/events-node#legacy-backend-system). + +This has also affected how the events backend is installed in the old backend system, see the [`events-backend` README](https://github.com/backstage/backstage/tree/master/plugins/events-backend#legacy-backend-system) and [`events-backend` CHANGELOG](https://github.com/backstage/backstage/blob/master/plugins/events-backend/CHANGELOG.md#030) for details. + +Contributed by [@pjungermann](https://github.com/pjungermann) in [#22344](https://github.com/backstage/backstage/pull/22344). + +### New backend system by default + +When creating a new project with `@backstage/create-app` you now get a backend built on top of the new backend system. Plugins created with the `@backstage/cli` now also support the new system. + +### Auth backend guest module + +A new guest auth provider is now available for use in local development and testing. In contrast to the existing guest auth, this provider lets you get a valid session and Backstage user token. + +Contributed by [@aramissennyeydd](https://github.com/aramissennyeydd) in [#22565](https://github.com/backstage/backstage/pull/22565) + +### Accepting `null` in configuration + +A `null` value is now treated as an explicitly undefined value, and does not fall back to other configuration files. This means that you can use a `null` value in configuration to reset or unset parts of configuration, such as disabling an auth provider. + +### Scaffolder actions testing utilities + +A new `@backstage/plugin-scaffolder-node-test-utils` package has been published, which provides `createMockActionContext` to make it easier to write tests for scaffolder actions, and avoid breakages as additions to the actions context is made. More details can be found in the documentation for [writing tests for actions](https://backstage.io/docs/features/software-templates/writing-tests-for-actions). + +We encourage you to migrate existing tests to use this new utility, in order to avoid breaking changes in the future. + +### New backend plugin extension points + +The `catalogModelExtensionPoint` from `@backstage/plugin-catalog-node/alpha` can now be used to replace the default entity data parser and field validation rules in the new backend system. + +The `techdocsGeneratorExtensionPoint` from `@backstage/plugin-techdocs-node` can now be used to set a custom TechDocs generator. + +### I18n for core components + +The majority of components from `@backstage/core-components` now support internationalization. Message customizations are available through the `coreComponentsTranslationRef` export from `@backstage/core-components/alpha`. See the [internationalization documentation](https://backstage.io/docs/plugins/internationalization/#for-an-application-developer-overwrite-plugin-messages) for details on how to customize these messages in your application. + +Contributed by [@mario-mui](https://github.com/mario-mui) in [#20932](https://github.com/backstage/backstage/pull/20932) + +## 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/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.24.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://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.25.0-changelog.md b/docs/releases/v1.25.0-changelog.md new file mode 100644 index 0000000000..d1df9dccc7 --- /dev/null +++ b/docs/releases/v1.25.0-changelog.md @@ -0,0 +1,3178 @@ +# Release v1.25.0 + +## @backstage/plugin-catalog-backend@1.21.0 + +### Minor Changes + +- f3e2e86: Added the ability to inject custom permissions from modules, on `CatalogBuilder` and `CatalogPermissionExtensionPoint` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-search-backend-module-catalog@0.1.21 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-node@0.3.2 + - @backstage/backend-openapi-utils@0.1.9 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-node@1.11.0 + +### Minor Changes + +- f3e2e86: Added the ability to inject custom permissions from modules, on `CatalogBuilder` and `CatalogPermissionExtensionPoint` + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-cloudbuild@0.5.0 + +### Minor Changes + +- 5a78b73: Added a new column to `EntityCloudbuildContent` displaying the trigger name for each build. + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-github-issues@0.4.0 + +### Minor Changes + +- bc97524: Added ESLint rule `no-top-level-material-ui-4-imports` in the `github-issues` plugin to migrate the Material UI imports. + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/app-defaults@1.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/backend-app-api@0.6.2 + +### Patch Changes + +- e848644: Temporarily revert the rate limiting +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/backend-tasks@0.5.21 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-common@0.21.6 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-app-api@0.6.2 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.2 + - @backstage/backend-common@0.21.6 + +## @backstage/backend-dynamic-feature-service@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.0 + - @backstage/backend-app-api@0.6.2 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-backend@0.3.2 + - @backstage/plugin-events-node@0.3.2 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.16 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/backend-openapi-utils@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.6.16 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-tasks@0.5.21 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/backend-tasks@0.5.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.2 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.3 + +### Patch Changes + +- 7e8a7c8: Added missing commas to the example of `queryEntities` +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.26.2 + +### Patch Changes + +- eeb226a: Updated dependency `rollup` to `^4.0.0`. + +- 91192f4: Updated backend plugin template to work better with new backend system + +- cc371d6: Ignore transforming only on `react-use/lib`, not whole `react-use` in jest. + + ** POTENTIAL BREAKAGE ** + If your tests fail, please change to use path import from `react-use/esm/`. It is also recommended to migrate from `react-user/lib` imports to `react-use/esm` + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.6 + - @backstage/integration@1.9.1 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.12.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.13 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.30 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/app-defaults@1.5.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + +## @backstage/frontend-app-api@0.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/test-utils@1.5.3 + - @backstage/types@1.1.1 + +## @backstage/integration-aws-node@0.1.12 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- 823cf8e: Updated dependency `aws-sdk-client-mock-jest` to `^4.0.0`. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/repo-tools@0.7.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.8 + +### Patch Changes + +- 8caf2f7: Fix how the cli server mocks the new auth cookie endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-adr@0.6.16 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-adr-common@0.2.21 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-adr-backend@0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-adr-common@0.2.21 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-airbrake@0.3.33 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/dev-utils@1.0.30 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.3 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-airbrake-backend@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + +## @backstage/plugin-allure@0.1.49 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-analytics-module-ga@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-analytics-module-ga4@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-apache-airflow@0.2.23 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-api-docs@0.11.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-catalog@1.18.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-apollo-explorer@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-app-backend@0.3.64 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.7.0 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.16 + +## @backstage/plugin-app-node@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config-loader@1.7.0 + +## @backstage/plugin-app-visualizer@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-auth-backend@0.22.3 + +### Patch Changes + +- 038b2e6: Only consider entities of kind `User` when using `findCatalogUser` with a filter query, unless an explicit `kind` filter is provided. +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.8 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.8 + - @backstage/plugin-auth-backend-module-github-provider@0.1.13 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.13 + - @backstage/plugin-auth-backend-module-google-provider@0.1.13 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.11 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.13 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.7 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.9 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.11 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.9 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.22.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.2 + +### Patch Changes + +- 4cc8279: Add installation instructions +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.22.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-auth-node@0.4.11 + +### Patch Changes + +- 038b2e6: Only consider entities of kind `User` when using `findCatalogUser` with a filter query, unless an explicit `kind` filter is provided. +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-azure-devops@0.4.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-azure-devops-common@0.4.0 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-devops-backend@0.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-azure-devops-common@0.4.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-azure-sites@0.1.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-sites-backend@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-badges@0.2.57 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-badges-backend@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bazaar@0.2.25 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bazaar-backend@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + +## @backstage/plugin-bitrise@0.1.60 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog@1.18.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- bbbd510: `CatalogIndexPage` now uses `EntitySearchBar` for text-based filtering of entities, saving the search text in the query parameters and debouncing the server requests. +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-catalog-backend-module-aws@0.3.11 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- 823cf8e: Updated dependency `aws-sdk-client-mock-jest` to `^4.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-azure@0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/config@1.2.0 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/backend-openapi-utils@0.1.9 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-node@0.3.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.9.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.17 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.30 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.33 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-catalog-backend-module-github@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.0 + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-node@0.3.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-catalog-backend-module-github@0.5.7 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.9.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.0 + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-node@0.3.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.32 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.34 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.0 + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.3 + +### Patch Changes + +- f3e2e86: Internal update that injects custom permissions into the catalog using its extension point +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-graph@0.4.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.9 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-react@1.11.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- b5cbbb6: `EntitySearchBar` and `EntityTextFilter` have been updated accordingly to persist the status as query params, following the same pattern as the other server side +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-cicd-statistics@0.1.35 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-cicd-statistics@0.1.35 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-circleci@0.3.33 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-code-climate@0.1.33 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-code-coverage@0.2.26 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-code-coverage-backend@0.2.30 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-codescene@0.1.25 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + +## @backstage/plugin-config-schema@0.1.53 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.12 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-devtools-backend@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.7.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-dynatrace@10.0.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-entity-feedback@0.2.16 + +### Patch Changes + +- 12610b4: Added ESLint rule `no-top-level-material-ui-4-imports` in the `entity-feedback` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.18 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 2ec4a8d: Added ESLint rule `no-top-level-material-ui-4-imports` in the `entity-validation` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-events-backend@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.2 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + +## @backstage/plugin-events-backend-module-gerrit@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + +## @backstage/plugin-events-backend-module-github@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.26 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.2 + +## @backstage/plugin-events-node@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-explore@0.4.19 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-explore-backend@0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-search-backend-module-explore@0.1.20 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.17 + +### Patch Changes + +- 157c7ae: Added ESLint rule `no-top-level-material-ui-4-imports` in the `firehydrant` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-fossa@0.2.65 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-gcalendar@0.3.26 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-gcp-projects@0.3.49 + +### Patch Changes + +- 7dad59c: Added ESLint rule `no-top-level-material-ui-4-imports` in the `gcp-projects` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-git-release-manager@0.3.45 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration@1.9.1 + +## @backstage/plugin-github-actions@0.6.14 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/integration@1.9.1 + +## @backstage/plugin-github-deployments@0.1.64 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- a1ddc8d: Added ESLint rule `no-top-level-material-ui-4-imports` in the `github-deployments` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-github-pull-requests-board@0.1.27 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/integration@1.9.1 + +## @backstage/plugin-gitops-profiles@0.3.48 + +### Patch Changes + +- 1a22254: Added ESLint rule `no-top-level-material-ui-4-imports` in the `gitops-profiles` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-gocd@0.1.39 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 4166b10: Added an optional ESLint rule - no-top-level-material-ui-4-imports - which has an auto fix function to migrate the imports and used it to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-graphiql@0.3.6 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-graphql-voyager@0.1.15 + +### Patch Changes + +- 813f99d: Added ESLint rule `no-top-level-material-ui-4-imports` in the `graphql-voyager` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-home@0.7.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/plugin-home-react@0.1.11 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.2 + +## @backstage/plugin-home-react@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-ilert@0.2.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-jenkins@0.9.8 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-jenkins-common@0.1.25 + +## @backstage/plugin-jenkins-backend@0.4.3 + +### Patch Changes + +- 836247c: Fixed an issue where the `httpAuth` service turned out to be undefined +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-jenkins-common@0.1.25 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-kafka@0.3.33 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-kafka-backend@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-kubernetes@0.11.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-kubernetes-react@0.3.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-backend@0.16.3 + +### Patch Changes + +- 9b1abac: Added a new service locator `CatalogRelationServiceLocator` that only returns clusters an entity lists in `relations.dependsOn`. +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-kubernetes-node@0.1.10 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-kubernetes-cluster@0.0.9 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 1c1140e: Added ESLint rule `no-top-level-material-ui-4-imports` in the `kubernetes-cluster` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-kubernetes-react@0.3.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-node@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-react@0.3.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-lighthouse@0.4.18 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-lighthouse-backend@0.4.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-linguist@0.1.18 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.15 + +### Patch Changes + +- 4bba771: Added ESLint rule `no-top-level-material-ui-4-imports` in the `microsoft-calender` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-newrelic@0.3.48 + +### Patch Changes + +- f38f7d8: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in cloudbuild plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/newrelic. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-newrelic-dashboard@0.3.8 + +### Patch Changes + +- 1d81cdd: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in new relic plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/newrelic-dashboard +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-nomad@0.1.14 + +### Patch Changes + +- c116096: Added an optional ESLint rule - no-top-level-material-ui-4-imports -in nomad plugin which has an auto fix function to migrate the imports and used it to migrate the Material UI imports for plugins/nomad. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-nomad-backend@0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-notifications@0.1.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 6a2fe4b: Added ESLint rule `no-top-level-material-ui-4-imports` in the `notifications` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-react@0.0.2 + +## @backstage/plugin-notifications-backend@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-notifications-node@0.1.2 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/plugin-events-node@0.3.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.2 + +## @backstage/plugin-notifications-node@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + +## @backstage/plugin-octopus-deploy@0.2.15 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 004ce71: Added ESLint rule `no-top-level-material-ui-4-imports` in the `octopus-deploy` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-scaffolder-react@1.8.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-opencost@0.2.8 + +### Patch Changes + +- f21ef8c: Added ESLint rule `no-top-level-material-ui-4-imports` in the `opencost` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-org@0.6.23 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 0df5c60: Added ESLint rule `no-top-level-material-ui-4-imports` in the `org` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-org-react@0.1.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-pagerduty@0.7.5 + +### Patch Changes + +- 2b43144: Added ESLint rule `no-top-level-material-ui-4-imports` in the `pagerduty` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-home-react@0.1.11 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-periskop@0.1.31 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-periskop-backend@0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + +## @backstage/plugin-permission-backend@0.5.40 + +### Patch Changes + +- f3e2e86: Properly forward causes of errors from upstream backends in the `PermissionIntegrationClient` +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-node@0.7.27 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-playlist@0.2.7 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-playlist-backend@0.3.20 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-proxy-backend@0.4.14 + +### Patch Changes + +- eae097c: Allow unauthenticated requests. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + +## @backstage/plugin-puppetdb@0.1.16 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 8754b0e: Added ESLint rule `no-top-level-material-ui-4-imports` in the `puppetdb` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-rollbar@0.4.33 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-rollbar-backend@0.1.61 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/config@1.2.0 + +## @backstage/plugin-scaffolder@1.19.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-scaffolder-react@1.8.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend@1.22.3 + +### Patch Changes + +- c74c2de: Fixed an issue causing actions to fail when retrieving auth credentials +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.14 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.2 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-scaffolder-backend-module-github@0.2.6 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.8 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.6 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.8 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.6 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.6 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.40 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.33 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.37 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/plugin-scaffolder-node-test-utils@0.1.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-test-utils@0.3.6 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-search@1.4.9 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend@1.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/backend-openapi-utils@0.1.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-catalog@0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-explore@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-pg@0.5.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-techdocs@0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-node@1.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-react@1.7.9 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-sentry@0.5.18 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-shortcuts@0.3.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## @backstage/plugin-signals-backend@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.15 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-sonarqube-react@0.1.14 + +## @backstage/plugin-sonarqube-backend@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-splunk-on-call@0.4.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-stack-overflow@0.1.28 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/plugin-home-react@0.1.11 + - @backstage/core-plugin-api@1.9.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-stack-overflow-backend@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.9 + +## @backstage/plugin-stackstorm@0.1.14 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-tech-insights@0.3.25 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.30 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-tech-insights-node@0.5.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.48 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-tech-insights-node@0.5.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-node@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.7.2 + +### Patch Changes + +- 89b093f: Added ESLint rule `no-top-level-material-ui-4-imports` in the `tech-radar` plugin to migrate the Material UI imports. +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-techdocs@1.10.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.30 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/plugin-techdocs@1.10.3 + - @backstage/plugin-catalog@1.18.2 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.3 + +## @backstage/plugin-techdocs-backend@1.10.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.21 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration@1.9.1 + +## @backstage/plugin-techdocs-node@1.12.2 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-techdocs-react@1.2.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.37 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-todo-backend@0.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-openapi-utils@0.1.9 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## @backstage/plugin-user-settings@0.8.4 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.28 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-vault-backend@0.4.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-vault-node@0.1.9 + +## @backstage/plugin-vault-node@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + +## @backstage/plugin-xcmetrics@0.2.51 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## example-app@0.2.95 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-nomad@0.1.14 + - @backstage/plugin-newrelic@0.3.48 + - @backstage/plugin-tech-radar@0.7.2 + - @backstage/plugin-entity-feedback@0.2.16 + - @backstage/plugin-pagerduty@0.7.5 + - @backstage/plugin-microsoft-calendar@0.1.15 + - @backstage/plugin-gcp-projects@0.3.49 + - @backstage/plugin-newrelic-dashboard@0.3.8 + - @backstage/plugin-catalog-unprocessed-entities@0.2.2 + - @backstage/plugin-kubernetes-cluster@0.0.9 + - @backstage/core-components@0.14.3 + - @backstage/plugin-scaffolder-react@1.8.3 + - @backstage/plugin-apache-airflow@0.2.23 + - @backstage/plugin-catalog-import@0.10.9 + - @backstage/plugin-github-actions@0.6.14 + - @backstage/plugin-octopus-deploy@0.2.15 + - @backstage/plugin-stack-overflow@0.1.28 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-graph@0.4.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-code-coverage@0.2.26 + - @backstage/plugin-cost-insights@0.12.22 + - @backstage/plugin-notifications@0.1.2 + - @backstage/plugin-tech-insights@0.3.25 + - @backstage/plugin-user-settings@0.8.4 + - @backstage/plugin-azure-devops@0.4.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/plugin-azure-sites@0.1.22 + - @backstage/plugin-cloudbuild@0.5.0 + - @backstage/plugin-lighthouse@0.4.18 + - @backstage/plugin-scaffolder@1.19.2 + - @backstage/plugin-stackstorm@0.1.14 + - @backstage/plugin-dynatrace@10.0.2 + - @backstage/plugin-gcalendar@0.3.26 + - @backstage/plugin-shortcuts@0.3.22 + - @backstage/plugin-airbrake@0.3.33 + - @backstage/plugin-devtools@0.1.12 + - @backstage/plugin-graphiql@0.3.6 + - @backstage/plugin-linguist@0.1.18 + - @backstage/plugin-playlist@0.2.7 + - @backstage/plugin-puppetdb@0.1.16 + - @backstage/plugin-techdocs@1.10.3 + - @backstage/plugin-catalog@1.18.2 + - @backstage/plugin-explore@0.4.19 + - @backstage/plugin-jenkins@0.9.8 + - @backstage/plugin-rollbar@0.4.33 + - @backstage/plugin-badges@0.2.57 + - @backstage/plugin-search@1.4.9 + - @backstage/plugin-sentry@0.5.18 + - @backstage/plugin-kafka@0.3.33 + - @backstage/plugin-gocd@0.1.39 + - @backstage/plugin-home@0.7.2 + - @backstage/plugin-adr@0.6.16 + - @backstage/plugin-org@0.6.23 + - @backstage/cli@0.26.2 + - @backstage/app-defaults@1.5.3 + - @backstage/frontend-app-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-api-docs@0.11.3 + - @backstage/plugin-github-pull-requests-board@0.1.27 + - @backstage/plugin-kubernetes@0.11.8 + - @backstage/plugin-signals@0.0.4 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.8 + - @backstage/plugin-todo@0.2.37 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-search-common@1.2.11 + +## example-app-next@0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-newrelic@0.3.48 + - @backstage/plugin-tech-radar@0.7.2 + - @backstage/plugin-entity-feedback@0.2.16 + - @backstage/plugin-pagerduty@0.7.5 + - @backstage/plugin-microsoft-calendar@0.1.15 + - @backstage/plugin-gcp-projects@0.3.49 + - @backstage/plugin-newrelic-dashboard@0.3.8 + - @backstage/plugin-catalog-unprocessed-entities@0.2.2 + - @backstage/core-components@0.14.3 + - @backstage/plugin-scaffolder-react@1.8.3 + - @backstage/plugin-apache-airflow@0.2.23 + - @backstage/plugin-catalog-import@0.10.9 + - @backstage/plugin-github-actions@0.6.14 + - @backstage/plugin-octopus-deploy@0.2.15 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-graph@0.4.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-code-coverage@0.2.26 + - @backstage/plugin-cost-insights@0.12.22 + - @backstage/plugin-tech-insights@0.3.25 + - @backstage/plugin-user-settings@0.8.4 + - @backstage/plugin-azure-devops@0.4.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/plugin-azure-sites@0.1.22 + - @backstage/plugin-cloudbuild@0.5.0 + - @backstage/plugin-lighthouse@0.4.18 + - @backstage/plugin-scaffolder@1.19.2 + - @backstage/plugin-stackstorm@0.1.14 + - @backstage/plugin-dynatrace@10.0.2 + - @backstage/plugin-gcalendar@0.3.26 + - @backstage/plugin-shortcuts@0.3.22 + - @backstage/plugin-airbrake@0.3.33 + - @backstage/plugin-devtools@0.1.12 + - @backstage/plugin-graphiql@0.3.6 + - @backstage/plugin-linguist@0.1.18 + - @backstage/plugin-playlist@0.2.7 + - @backstage/plugin-puppetdb@0.1.16 + - @backstage/plugin-techdocs@1.10.3 + - @backstage/plugin-catalog@1.18.2 + - @backstage/plugin-explore@0.4.19 + - @backstage/plugin-jenkins@0.9.8 + - @backstage/plugin-rollbar@0.4.33 + - @backstage/plugin-badges@0.2.57 + - @backstage/plugin-search@1.4.9 + - @backstage/plugin-sentry@0.5.18 + - @backstage/plugin-kafka@0.3.33 + - @backstage/plugin-gocd@0.1.39 + - @backstage/plugin-home@0.7.2 + - @backstage/plugin-adr@0.6.16 + - @backstage/plugin-org@0.6.23 + - @backstage/cli@0.26.2 + - @backstage/app-defaults@1.5.3 + - app-next-example-plugin@0.0.9 + - @backstage/frontend-app-api@0.6.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-api-docs@0.11.3 + - @backstage/plugin-app-visualizer@0.1.4 + - @backstage/plugin-kubernetes@0.11.8 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.8 + - @backstage/plugin-todo@0.2.37 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-search-common@1.2.11 + +## app-next-example-plugin@0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + +## example-backend@0.2.96 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.0 + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/plugin-kubernetes-backend@0.16.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.3 + - @backstage/plugin-permission-backend@0.5.40 + - @backstage/plugin-proxy-backend@0.4.14 + - @backstage/plugin-scaffolder-backend@1.22.3 + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-jenkins-backend@0.4.3 + - @backstage/plugin-auth-backend@0.22.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-azure-devops-backend@0.6.3 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.14 + - @backstage/plugin-lighthouse-backend@0.4.9 + - @backstage/plugin-linguist-backend@0.5.14 + - @backstage/plugin-search-backend-module-catalog@0.1.21 + - @backstage/plugin-search-backend-module-techdocs@0.1.21 + - @backstage/plugin-todo-backend@0.3.15 + - example-app@0.2.95 + - @backstage/plugin-app-backend@0.3.64 + - @backstage/plugin-adr-backend@0.4.13 + - @backstage/plugin-badges-backend@0.3.13 + - @backstage/plugin-code-coverage-backend@0.2.30 + - @backstage/plugin-entity-feedback-backend@0.2.13 + - @backstage/plugin-playlist-backend@0.3.20 + - @backstage/plugin-tech-insights-backend@0.5.30 + - @backstage/plugin-techdocs-backend@1.10.3 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.2 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/plugin-signals-backend@0.1.2 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-devtools-backend@0.3.2 + - @backstage/plugin-events-backend@0.3.2 + - @backstage/plugin-events-node@0.3.2 + - @backstage/plugin-explore-backend@0.0.26 + - @backstage/plugin-kafka-backend@0.3.14 + - @backstage/plugin-nomad-backend@0.1.18 + - @backstage/plugin-rollbar-backend@0.1.61 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.17 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.33 + - @backstage/plugin-search-backend@1.5.6 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.19 + - @backstage/plugin-search-backend-module-explore@0.1.20 + - @backstage/plugin-search-backend-module-pg@0.5.25 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.48 + - @backstage/plugin-tech-insights-node@0.5.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.9.1 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-permission-common@0.7.13 + +## example-backend-next@0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.0 + - @backstage/plugin-kubernetes-backend@0.16.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.3 + - @backstage/plugin-permission-backend@0.5.40 + - @backstage/plugin-proxy-backend@0.4.14 + - @backstage/plugin-scaffolder-backend@1.22.3 + - @backstage/plugin-jenkins-backend@0.4.3 + - @backstage/plugin-auth-backend@0.22.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.2 + - @backstage/plugin-catalog-backend-module-openapi@0.1.34 + - @backstage/plugin-azure-devops-backend@0.6.3 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.10 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.14 + - @backstage/plugin-lighthouse-backend@0.4.9 + - @backstage/plugin-linguist-backend@0.5.14 + - @backstage/plugin-search-backend-module-catalog@0.1.21 + - @backstage/plugin-search-backend-module-techdocs@0.1.21 + - @backstage/plugin-todo-backend@0.3.15 + - @backstage/backend-defaults@0.2.16 + - @backstage/plugin-app-backend@0.3.64 + - @backstage/plugin-adr-backend@0.4.13 + - @backstage/plugin-badges-backend@0.3.13 + - @backstage/plugin-entity-feedback-backend@0.2.13 + - @backstage/plugin-notifications-backend@0.1.2 + - @backstage/plugin-playlist-backend@0.3.20 + - @backstage/plugin-techdocs-backend@1.10.3 + - @backstage/plugin-auth-backend-module-github-provider@0.1.13 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.13 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/plugin-signals-backend@0.1.2 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-devtools-backend@0.3.2 + - @backstage/plugin-nomad-backend@0.1.18 + - @backstage/plugin-scaffolder-backend-module-github@0.2.6 + - @backstage/plugin-search-backend@1.5.6 + - @backstage/plugin-search-backend-module-explore@0.1.20 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/plugin-sonarqube-backend@0.2.18 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-permission-common@0.7.13 + +## e2e-test@0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.13 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.94 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-techdocs@1.10.3 + - @backstage/plugin-catalog@1.18.2 + - @backstage/cli@0.26.2 + - @backstage/app-defaults@1.5.3 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.2 + +## @internal/plugin-todo-list@1.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + +## @internal/plugin-todo-list-backend@1.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.25.0.md b/docs/releases/v1.25.0.md new file mode 100644 index 0000000000..afb765b447 --- /dev/null +++ b/docs/releases/v1.25.0.md @@ -0,0 +1,47 @@ +--- +id: v1.25.0 +title: v1.25.0 +description: Backstage Release v1.25.0 +--- + +These are the release notes for the v1.25.0 release of [Backstage](https://backstage.io/). This is an unscheduled release that replaces what would’ve otherwise been the `v1.25.0-next.1` release, due to a problem with the patch releases for `1.24.0`. The next main line release will still be released on April 16th as scheduled, but will now instead be `1.26.0`. + +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 + +### Auth service fixes + +A number of fixes have been made to various plugins related to the new auth system: + +Rate limiting has been disabled as it was a bit too aggressive and didn’t interact well with proxies. +Fixes an issue in the TechDocs CLI related to cookie auth +Fixes an integration issue of the new auth services in the Jenkins backend plugin +Fixed an issue in the scaffolder were credentials weren’t forwarded correctly to the action context. +Fixed an issue where the proxy backend blocked unauthenticated requests. + +### Catalog + +The catalog backend can now be extended with additional permissions through new `addPermissions` methods of the `CatalogBuilder` and `catalogPermissionExtensionPoint`. +The paginated catalog table now saves the search text in the query parameters and debounces the server requests. + +## 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/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.25.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://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.26.0-changelog.md b/docs/releases/v1.26.0-changelog.md new file mode 100644 index 0000000000..f40867febe --- /dev/null +++ b/docs/releases/v1.26.0-changelog.md @@ -0,0 +1,3762 @@ +# Release v1.26.0 + +## @backstage/backend-app-api@0.7.0 + +### Minor Changes + +- 3256f14: **BREAKING**: Modules are no longer loaded unless the plugin that they extend is present. + +### Patch Changes + +- 10327fb: Deprecate the `getPath` option for the `httpRouterServiceFactory` and more generally the ability to configure plugin API paths to be anything else than `/api/:pluginId/`. Requests towards `/api/*` that do not match an installed plugin will also no longer be handled by the index router, typically instead returning a 404. + +- 2c50516: Fix auth cookie issuance for split backend deployments by preferring to set it against the request target host instead of origin + +- 7e584d6: Fixed a bug where expired cookies would not be refreshed. + +- 1a20b12: Make the auth service create and validate dedicated OBO tokens, containing the user identity proof. + +- 00fca28: Implemented support for external access using both the legacy token form and static tokens. + +- d5a1fe1: Replaced winston logger with `LoggerService` + +- bce0879: Service-to-service authentication has been improved. + + Each plugin now has the capability to generate its own signing keys for token issuance. The generated public keys are stored in a database, and they are made accessible through a newly created endpoint: `/.backstage/auth/v1/jwks.json`. + + `AuthService` can now issue tokens with a reduced scope using the `getPluginRequestToken` method. This improvement enables plugins to identify the plugin originating the request. + +- 54f2ac8: Added `initialization` option to `createServiceFactory` which defines the initialization strategy for the service. The default strategy mimics the current behavior where plugin scoped services are initialized lazily by default and root scoped services are initialized eagerly. + +- 56f81b5: Improved error message thrown by `AuthService` when requesting a token for plugins that don't support the new authentication tokens. + +- 25ea3d2: Minor internal restructuring + +- d62bc51: Add support for limited user tokens by using user identity proof provided by the auth backend. + +- c884b9a: Automatically creates a get and delete cookie endpoint when a `user-cookie` policy is added. + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/config-loader@1.8.0 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/cli-node@0.2.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/config-loader@1.8.0 + +### Minor Changes + +- 2ce31b3: The default environment variable substitution function will now trim whitespace characters from the substituted value. This alleviates bugs where whitespace characters are mistakenly included in environment variables. + + If you depend on the old behavior, you can override the default substitution function with your own, for example: + + ```ts + ConfigSources.default({ + substitutionFunc: async name => process.env[name], + }); + ``` + +- 99bab65: Support parameter substitution for environment variables + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/integration@1.10.0 + +### Minor Changes + +- 7b11422: Add AWS CodeCommit URL Reader/Integration + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/repo-tools@0.8.0 + +### Minor Changes + +- 2bd291e: Adds a lint rule to `repo schema openapi lint` to enforce `allowReserved` for all parameters. To fix this, simply add `allowReserved: true` to your parameters, like so + + ```diff + /v1/todos: + get: + operationId: ListTodos + # ... + parameters: + - name: entity + in: query + + allowReserved: true + schema: + type: string + ``` + +- cfdc5e7: Adds two new commands, `repo schema openapi fuzz` and `package schema openapi fuzz` for fuzzing your plugins documented with OpenAPI. This can help find bugs in your application code through the use of auto-generated schema-compliant inputs. For more information on the underlying library this leverages, take a look at [the docs](https://schemathesis.readthedocs.io/en/stable/index.html). + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/config-loader@1.8.0 + - @backstage/cli-node@0.2.5 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + +## @backstage/plugin-apollo-explorer@0.2.0 + +### Minor Changes + +- c664b15: feat(apollo-explorer): allow callbacks using apiholder + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.0 + +### Minor Changes + +- 06a6725: New auth backend module to add `azure-easyauth` provider. Note that as part of this change the default provider ID has been changed from `easyAuth` to `azureEasyAuth`, which means that if you switch to this new module you need to update your app config as well as the `provider` prop of the `ProxiedSignInPage` in the frontend. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.0 + +### Minor Changes + +- ba763b6: Migrate the Bitbucket auth provider to the new `@backstage/plugin-auth-backend-module-bitbucket-provider` module package. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.0 + +### Minor Changes + +- c26218d: Created a separate module for the Cloudflare Access auth provider + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-react@0.1.0 + +### Minor Changes + +- c884b9a: **BREAKING**: Removed the path option from `CookieAuthRefreshProvider` and `useCookieAuthRefresh`. + + A new `CookieAuthRedirect` component has been added to redirect a public app bundle to the protected one when using the `app-backend` with a separate public entry point. + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-badges-backend@0.4.0 + +### Minor Changes + +- 88d4769: Fix unauthorized requests by allowing unauthenticated requests. + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog@1.19.0 + +### Minor Changes + +- 18c7f12: Add `isApiType()` to EntitySwitch routing functions. + +### Patch Changes + +- bcb2674: Added a "create something similar" button to the `<AboutCard>` that is visible and links to the scaffolder template corresponding to the entity's `backstage.io/source-template` annotation, if present. +- 4ef0dcf: Fixed a bug that prevented the default `entityPresentationApi` from being set in apps using the new frontend system. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 7495b36: Fixed sorting of columns created with `CatalogTable.columns.createLabelColumn`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.0 + +### Minor Changes + +- 2e2167a: The name and title of the returned openapi doc entity are now configurable + +### Patch Changes + +- 58763e8: Use direct access of openapi.json files and not external route +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/backend-openapi-utils@0.1.10 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github@0.6.0 + +### Minor Changes + +- 29c3898: Remove use of `EventBroker` and `EventSubscriber` for the GitHub org data providers. + + BREAKING CHANGE: + + - `GithubOrgEntityProvider.onEvent` made private + - `GithubOrgEntityProvider.supportsEventTopics` removed + - `eventBroker` option was removed from `GithubMultiOrgEntityProvider.fromConfig` + - `GithubMultiOrgEntityProvider.supportsEventTopics` removed + + This change only impacts users who still use the legacy backend system + **and** who still use `eventBroker` as option when creating these + entity providers. + + Please pass the `EventsService` instance as option `events` instead. + You can find more information at the [installation documentation](https://backstage.io/docs/integrations/github/org/#legacy-backend-system). + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- 469e87f: Properly instantiate `GithubMultiOrgEntityProvider` and `GithubOrgEntityProvider` with `EventsService` if defined +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-catalog-backend@1.21.1 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-github-pull-requests-board@0.2.0 + +### Minor Changes + +- c6cafe6: Fixed bug in CardHeader not expecting commit status as an array as returned by GraphQL + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 617faf0: Handle null values returned from GitHub for the statusCheckRollup value on the commit object +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-kubernetes-backend@0.17.0 + +### Minor Changes + +- 6c19c14: **BREAKING**: `KubernetesProxy` now requires the `DiscoveryService` to be passed to the constuctor +- 5dd8177: **BREAKING** Winston logger has been replaced with `LoggerService` + +### Patch Changes + +- f5cec55: Fixing issue where `BackstageCredentials` were not properly forwarded for all calls +- dd269e9: Fixed a bug where the proxy handler did not properly handle a missing header +- 9d89aed: Fixed a crash reading `credentials` from `undefined`. +- e5a2ccc: Updated dependency `@types/http-proxy-middleware` to `^1.0.0`. +- Updated dependencies + - @backstage/plugin-kubernetes-node@0.1.11 + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-notifications@0.2.0 + +### Minor Changes + +- 939b4ec: Notifications-backend URL query parameter changed from `minimal_severity` to `minimumSeverity`. +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- 939b4ec: The severity icons now get their colors from the theme. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-signals-react@0.0.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications-backend@0.2.0 + +### Minor Changes + +- 939b4ec: Notifications-backend URL query parameter changed from `minimal_severity` to `minimumSeverity`. +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- 0d99528: Notification processor functions are now renamed to `preProcess` and `postProcess`. + Additionally, processor name is now required to be returned by `getName`. + A new processor functionality `processOptions` was added to process options before sending the notification. +- e003e0e: The ordered list of notifications' severities is exported by notifications-common for reusability. +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- 9987066: fix: retrieve relations and children when mapping group entities for notifications +- 6206039: Fix entity owner resolution in notifications +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-notifications-node@0.1.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.0 + +### Minor Changes + +- fae9638: Add examples for `run:yeoman` scaffolder action. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/plugin-scaffolder-node-test-utils@0.1.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.4.0 + +### Minor Changes + +- 4d754e3: When using the New Backend System, the Elasticsearch provider will only be added if the `search.elasticsearch` config section exists. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/integration-aws-node@0.1.12 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-tech-insights-node@0.6.0 + +### Minor Changes + +- 5dd8177: **BREAKING** Winston logger has been replaced with `LoggerService` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/app-defaults@1.5.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/backend-common@0.21.7 + +### Patch Changes + +- 007e7ea: Added placeholder for `listPublicServiceKeys()` in the `AuthService` returned by `createLegacyAuthAdapters`. +- 00fca28: Ensure that `ServerTokenManager` also reads the new `backend.auth.externalAccess` settings +- 25ea3d2: Minor internal restructuring +- e31bacc: Added `pullOptions` to `DockerContainerRunner#runContainer` method to pass down options when pulling an image. +- 7b11422: Add AWS CodeCommit URL Reader/Integration +- 75a53b8: KubernetesContainerRunner.runContainer no longer closes the `logStream` it receives as input. +- Updated dependencies + - @backstage/config-loader@1.8.0 + - @backstage/backend-app-api@0.7.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-app-api@0.7.0 + +## @backstage/backend-dynamic-feature-service@0.2.9 + +### Patch Changes + +- 82ff03e: Use `PackageRole` type explicitly +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/config-loader@1.8.0 + - @backstage/backend-app-api@0.7.0 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/plugin-catalog-backend@1.21.1 + - @backstage/plugin-events-backend@0.3.4 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/cli-node@0.2.5 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/plugin-app-node@0.1.17 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/backend-openapi-utils@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.6.17 + +### Patch Changes + +- 007e7ea: Added a new required `listPublicServiceKeys` to `AuthService`. +- 54f2ac8: Added `initialization` option to `createServiceFactory` which defines the initialization strategy for the service. The default strategy mimics the current behavior where plugin scoped services are initialized lazily by default and root scoped services are initialized eagerly. +- 4fecffc: The credentials passed to the `issueUserCookie` method of the `HttpAuthService` are no longer required to represent a user principal. +- Updated dependencies + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/backend-tasks@0.5.22 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.7 + +### Patch Changes + +- 3256f14: `startTestBackend` will now add placeholder plugins when a modules are provided without their parent plugin. +- 007e7ea: Added mock of the new `listPublicServiceKeys` method for `AuthService`. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-app-api@0.7.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.4 + +### Patch Changes + +- dad7505: Fix the `CatalogClient::getEntities` method to only sort the resulting entities in case no `order`-parameter is provided. +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.26.3 + +### Patch Changes + +- c884b9a: Fix the bundle public subpath configuration. + +- e3c213e: Add the deprecation plugin to the default linter setup, switched off. + + This allows to disable deprecation warnings for `backstage-cli repo list-deprecations` with inline comments. + +- 4946f03: Updated dependency `webpack-dev-server` to `^5.0.0`. + +- 6b5ddbe: Fix the backend plugin to use correct plugin id + +- 4fecffc: When building the frontend app public assets are now also copied to the public dist directory when in use. + +- ed9260f: Added `versions:migrate` command to help move packages to the new `@backstage-community` namespace + +- Updated dependencies + - @backstage/eslint-plugin@0.1.7 + - @backstage/config-loader@1.8.0 + - @backstage/integration@1.10.0 + - @backstage/cli-node@0.2.5 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/cli-node@0.2.5 + +### Patch Changes + +- ed9260f: Added `versions:migrate` command to help move packages to the new `@backstage-community` namespace +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.12.4 + +### Patch Changes + +- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.4 + +### Patch Changes + +- d05d4bd: Moved `@backstage/core-app-api` to dev dependencies. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/version-bridge@1.0.8 + +## @backstage/core-components@0.14.4 + +### Patch Changes + +- ed5c901: No `undefined` class name used at `MarkdownContent` if no custom class name was provided. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- f546e38: Added Link component in `TabUI` providing functionality like copy link or open in new tab. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/version-bridge@1.0.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/core-plugin-api@1.9.2 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/version-bridge@1.0.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/create-app@0.5.14 + +### Patch Changes + +- 366cf07: Bumped create-app version. +- 036b9b3: Bumped create-app version. +- 2e1218c: Fix docs reference +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.31 + +### Patch Changes + +- 9a41a7b: Allow defining custom sidebar item for page and login for the development app +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 995f66b: add @backstage/no-top-level-material-ui-4-imports lint rule +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/app-defaults@1.5.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-model@1.4.5 + +## @backstage/eslint-plugin@0.1.7 + +### Patch Changes + +- 9ef572d: fix lint rule fixer for more than one `Component + Prop` +- 3a7eee7: eslint autofix for mui ThemeProvider +- d55828d: add fixer logic for import aliases + +## @backstage/frontend-app-api@0.6.4 + +### Patch Changes + +- 83f24f6: add `@backstage/no-top-level-material-ui-4-imports` lint rule +- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. +- 7ef7cc8: Fix duplicated subpath on routes resolved by the `useRouteRef` hook. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/version-bridge@1.0.8 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/frontend-plugin-api@0.6.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 35452b3: Fixed the type for `useRouteRef`, which wasn't handling optional external route refs correctly. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + - @backstage/types@1.1.1 + +## @backstage/frontend-test-utils@0.1.6 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/frontend-app-api@0.6.4 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/test-utils@1.5.4 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.26 + +### Patch Changes + +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration@1.10.0 + - @backstage/config@1.2.0 + +## @techdocs/cli@1.8.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/theme@0.5.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. + +## @backstage/version-bridge@1.0.8 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. + +## @backstage/plugin-adr@0.6.17 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-adr-common@0.2.22 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-adr-backend@0.4.14 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-adr-common@0.2.22 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-adr-common@0.2.22 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-airbrake@0.3.34 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/dev-utils@1.0.31 + - @backstage/core-plugin-api@1.9.2 + - @backstage/test-utils@1.5.4 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-airbrake-backend@0.3.14 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- e5a2ccc: Updated dependency `@types/http-proxy-middleware` to `^1.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + +## @backstage/plugin-allure@0.1.50 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-analytics-module-ga@0.2.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/config@1.2.0 + +## @backstage/plugin-analytics-module-ga4@0.2.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/config@1.2.0 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/config@1.2.0 + +## @backstage/plugin-apache-airflow@0.2.24 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-api-docs@0.11.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-app-backend@0.3.65 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- c884b9a: Track assets namespace in the cache store, implement a cookie authentication for when the public entry is enabled and used with the new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/config-loader@1.8.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-app-node@0.1.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.8.0 + - @backstage/backend-plugin-api@0.6.17 + +## @backstage/plugin-app-visualizer@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + +## @backstage/plugin-auth-backend@0.22.4 + +### Patch Changes + +- f02fe79: Refactored the `azure-easyauth` provider to use the implementation from `@backstage/plugin-auth-backend-module-azure-easyauth-provider`. +- d62bc51: Added token type header parameter and user identity proof to issued user tokens. +- ba763b6: Migrate the Bitbucket auth provider to the new `@backstage/plugin-auth-backend-module-bitbucket-provider` module package. +- bf4d71a: Initial implementation of the `/v1/userinfo` endpoint, which is now able to parse and return the `sub` and `ent` claims from a Backstage user token. +- c26218d: Deprecated some of the Cloudflare Access types and used the implementation from `@backstage/plugin-auth-backend-module-cloudflare-access-provider` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.9 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.9 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.8 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.12 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.14 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.14 + - @backstage/plugin-auth-backend-module-google-provider@0.1.14 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.12 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.14 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.10 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.10 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.9 + +### Patch Changes + +- 269b4c1: Read scopes from config and pass to AtlassianProvider as they are required +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.9 + +### Patch Changes + +- f286d59: Added support for AWS GovCloud (US) regions + +- 30f5a51: Added `authModuleAwsAlbProvider` as a default export. + + It can now be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider'));` + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-auth-backend@0.22.4 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.12 + +### Patch Changes + +- e0ed31c: Add user id annotation sign-in resolver +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.8 + +### Patch Changes + +- 28eb473: Support revoke refresh token to oidc logout function +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-auth-backend@0.22.4 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-auth-node@0.4.12 + +### Patch Changes + +- d62bc51: Add `tokenTypes` export with constants for various Backstage token types. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.4.3 + +### Patch Changes + +- 95b0573: `getAllTeams` now accepts an optional `limit` parameter which can be used to return more than the default limit of 100 teams from the Azure DevOps API + + `pullRequestOptions` have been equipped with `teamsLimit` so that the property can be used with `getAllTeams` + +- 4d895b3: Fixed bug in EntityPageAzurePipeline component where build definition annotation used for viewing pipelines + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. + +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. + +- Updated dependencies + - @backstage/plugin-azure-devops-common@0.4.1 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-azure-devops-backend@0.6.4 + +### Patch Changes + +- 95b0573: `getAllTeams` now accepts an optional `limit` parameter which can be used to return more than the default limit of 100 teams from the Azure DevOps API + + `pullRequestOptions` have been equipped with `teamsLimit` so that the property can be used with `getAllTeams` + +- d5a1fe1: Replaced winston logger with `LoggerService` + +- c7c4053: Fixed a bug where the `azureDevOps.token` was not truly optional + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-azure-devops-common@0.4.1 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-azure-devops-common@0.4.1 + +### Patch Changes + +- 95b0573: `getAllTeams` now accepts an optional `limit` parameter which can be used to return more than the default limit of 100 teams from the Azure DevOps API + + `pullRequestOptions` have been equipped with `teamsLimit` so that the property can be used with `getAllTeams` + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-azure-sites@0.1.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- cdb5ffa: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-azure-sites-backend@0.3.4 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-badges@0.2.58 + +### Patch Changes + +- 93c1d9c: Update README to fix invalid import command +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bazaar@0.2.26 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bazaar-backend@0.3.15 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + +## @backstage/plugin-bitbucket-cloud-common@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0 + +## @backstage/plugin-bitrise@0.1.61 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-catalog-backend@1.21.1 + +### Patch Changes + +- cfdc5e7: Fixes an issue where `/analyze-location` would incorrectly throw a 500 error on an invalid url. + +- d5a1fe1: Replaced winston logger with `LoggerService` + +- c52f7ac: Make entity collection errors a little quieter in the logs. + + Instead of logging a warning line when an entity has an error + during processing, it will now instead emit an event on the event + broker. + + This only removes a single log line, however it is possible to + add the log line back if it is required by subscribing to the + `CATALOG_ERRORS_TOPIC` as shown below. + + ```typescript + env.eventBroker.subscribe({ + supportsEventTopics(): string[] { + return [CATALOG_ERRORS_TOPIC]; + }, + + async onEvent( + params: EventParams<{ + entity: string; + location?: string; + errors: Array<Error>; + }>, + ): Promise<void> { + const { entity, location, errors } = params.eventPayload; + for (const error of errors) { + env.logger.warn(error.message, { + entity, + location, + }); + } + }, + }); + ``` + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-search-backend-module-catalog@0.1.22 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/backend-openapi-utils@0.1.10 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-aws@0.3.12 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-azure@0.1.37 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.18 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.31 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.18 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.34 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.12 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-catalog-backend-module-github@0.6.0 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.15 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.22 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-catalog-backend@1.21.1 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.33 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.25 + +### Patch Changes + +- 9b6320f: Retry msgraph API calls, due to frequent ETIMEDOUT errors. Also allow disabling fetching user photos. +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-catalog-backend@1.21.1 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.23 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-graph@0.4.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.10 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-catalog-node@1.11.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-react@1.11.3 + +### Patch Changes + +- 47dec6f: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- b863830: Change behavior in EntityAutoCompletePicker to only hide filter if there are no available options. Previously the filter was hidden if there were <= 1 available options. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-cicd-statistics@0.1.36 + +### Patch Changes + +- 72f0622: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.30 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-cicd-statistics@0.1.36 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-circleci@0.3.34 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-cloudbuild@0.5.1 + +### Patch Changes + +- 4be6335: Changed the column that serves as a hyperlink from SOURCE to BUILD. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-code-climate@0.1.34 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-code-coverage@0.2.27 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-code-coverage-backend@0.2.31 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-codescene@0.1.26 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.54 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- c43315a: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 43ca784: Updated dependency `@types/yup` to `^0.32.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.9 + +## @backstage/plugin-devtools-backend@0.3.3 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/config-loader@1.8.0 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-dynatrace@10.0.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-entity-feedback@0.2.17 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.14 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.19 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-events-backend@0.3.4 + +### Patch Changes + +- 7899e55: Allow unauthenticated requests for HTTP ingress. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-events-node@0.3.3 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-events-node@0.3.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-events-node@0.3.3 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-events-node@0.3.3 + +## @backstage/plugin-events-backend-module-gerrit@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-events-node@0.3.3 + +## @backstage/plugin-events-backend-module-github@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-events-node@0.3.3 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-events-node@0.3.3 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.27 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.3 + +## @backstage/plugin-events-node@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + +## @backstage/plugin-explore@0.4.20 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/plugin-explore-react@0.0.38 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-explore-backend@0.0.27 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-module-explore@0.1.21 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-explore-react@0.0.38 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.18 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-fossa@0.2.66 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-gcalendar@0.3.27 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-gcp-projects@0.3.50 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-git-release-manager@0.3.46 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration@1.10.0 + +## @backstage/plugin-github-actions@0.6.15 + +### Patch Changes + +- 76320a7: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-github-deployments@0.1.65 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-github-issues@0.4.1 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-gitops-profiles@0.3.49 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-gocd@0.1.40 + +### Patch Changes + +- b9d7c57: Updated README +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-graphiql@0.3.7 + +### Patch Changes + +- d137034: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + +## @backstage/plugin-graphql-voyager@0.1.16 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-home@0.7.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/plugin-home-react@0.1.12 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + +## @backstage/plugin-home-react@0.1.12 + +### Patch Changes + +- 293347f: Added ESLint rule `no-top-level-material-ui-4-imports` in the `home-react` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-ilert@0.2.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 7a3789a: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-jenkins@0.9.9 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 20f01d6: Updated dependency `@types/testing-library__jest-dom` to `^6.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-jenkins-common@0.1.25 + +## @backstage/plugin-jenkins-backend@0.4.4 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-jenkins-common@0.1.25 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-kafka@0.3.34 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-kafka-backend@0.3.15 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-kubernetes@0.11.9 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.3.4 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-cluster@0.0.10 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.3.4 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-node@0.1.11 + +### Patch Changes + +- f5cec55: Fixing issue where `BackstageCredentials` were not properly forwarded for all calls +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-react@0.3.4 + +### Patch Changes + +- e6d474f: Fixed ResourceUtilization component for POD Memory Limits +- 58800ba: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-lighthouse@0.4.19 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-lighthouse-backend@0.4.10 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-linguist@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.15 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.16 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-newrelic@0.3.49 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-newrelic-dashboard@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-nomad@0.1.15 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-nomad-backend@0.1.19 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-notifications-common@0.0.3 + +### Patch Changes + +- 0d99528: Notification processor functions are now renamed to `preProcess` and `postProcess`. + Additionally, processor name is now required to be returned by `getName`. + A new processor functionality `processOptions` was added to process options before sending the notification. +- e003e0e: The ordered list of notifications' severities is exported by notifications-common for reusability. + +## @backstage/plugin-notifications-node@0.1.3 + +### Patch Changes + +- 0d99528: Notification processor functions are now renamed to `preProcess` and `postProcess`. + Additionally, processor name is now required to be returned by `getName`. + A new processor functionality `processOptions` was added to process options before sending the notification. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-octopus-deploy@0.2.16 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/plugin-scaffolder-react@1.8.4 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-opencost@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-org@0.6.24 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## @backstage/plugin-org-react@0.1.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- cfb2b78: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-pagerduty@0.7.6 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/plugin-home-react@0.1.12 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-periskop@0.1.32 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-periskop-backend@0.2.15 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + +## @backstage/plugin-permission-backend@0.5.41 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-node@0.7.28 + +### Patch Changes + +- 29fa05b: Fixed an issue causing `ServerPermissionClient` to generate an invalid token for authorizing permissions against the permission backend. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-react@0.4.22 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-playlist@0.2.8 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-playlist-backend@0.3.21 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-proxy-backend@0.4.15 + +### Patch Changes + +- e5a2ccc: Updated dependency `@types/http-proxy-middleware` to `^1.0.0`. +- 43ca784: Updated dependency `@types/yup` to `^0.32.0`. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + +## @backstage/plugin-puppetdb@0.1.17 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-rollbar@0.4.34 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-rollbar-backend@0.1.62 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/config@1.2.0 + +## @backstage/plugin-scaffolder@1.19.3 + +### Patch Changes + +- 4f1f6ca: Use default value for `MyGroupsPicker` if provided +- 605c971: Allow the task list search to work on the Scaffolder template title. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 87d2eb8: Updated dependency `json-schema-library` to `^9.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 419e948: Don't show login prompt if token is set in the state +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-scaffolder-react@1.8.4 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend@1.22.4 + +### Patch Changes + +- f34a9b1: The `catalog:write` action now automatically adds a `backstage.io/template-source` annotation, indicating which Scaffolder template was used to create the entity. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.9 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.7 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.9 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7 + +### Patch Changes + +- 8dd33a1: Added examples for publish:bitbucketCloud actions +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7 + +### Patch Changes + +- 4a15c86: Add examples for `publish:bitbucketServer` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.41 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9 + +### Patch Changes + +- 0fb178e: Add examples for `publish:gerrit:review` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.7 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.7 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3 + +### Patch Changes + +- aa514d1: Add examples for `publish:gitlab:merge-request` scaffolder action & improve related tests +- 52f40ea: Add examples for `gitlab:group:ensureExists` scaffolder action & improve related tests +- 33f958a: Improve examples to ensure consistency across all publish actions +- d112225: Add examples for `gitlab:projectDeployToken:create` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.34 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-node@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-test-utils@0.3.7 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. + +- 87d2eb8: Updated dependency `json-schema-library` to `^9.0.0`. + +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. + +- 0e692cf: Added ESLint rule `no-top-level-material-ui-4-imports` to migrate the Material UI imports. + +- df99f62: The `value` sent on the `create` analytics event (fired when a Scaffolder template is executed) is now set to the number of minutes saved by executing the template. This value is derived from the `backstage.io/time-saved` annotation on the template entity, if available. + + Note: the `create` event is now captured in the `<Workflow>` component. If you are directly making use of the alpha-exported `<Stepper>` component, an analytics `create` event will no longer be captured on your behalf. + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/version-bridge@1.0.8 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-search@1.4.10 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/version-bridge@1.0.8 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend@1.5.7 + +### Patch Changes + +- 2bd291e: Allow reserved characters in requests. +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/repo-tools@0.8.0 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-openapi-utils@0.1.10 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-catalog@0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-explore@0.1.21 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-pg@0.5.26 + +### Patch Changes + +- cf163a5: Enable module only on supported databases + + Also pass logger to the service + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.10 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-techdocs@0.1.22 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-node@1.2.21 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-react@1.7.10 + +### Patch Changes + +- 8d50bd3: add mui imports eslint rule +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/version-bridge@1.0.8 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-sentry@0.5.19 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-shortcuts@0.3.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.5 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-signals-react@0.0.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-backend@0.1.3 + +### Patch Changes + +- 5f9877b: Fix unauthorized signals connection by allowing unauthenticated requests +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-events-node@0.3.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.16 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-sonarqube-react@0.1.15 + +## @backstage/plugin-sonarqube-backend@0.2.19 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-sonarqube-react@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-splunk-on-call@0.4.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-stack-overflow@0.1.29 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-home-react@0.1.12 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-stack-overflow-backend@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.10 + +## @backstage/plugin-stackstorm@0.1.15 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-tech-insights@0.3.26 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.31 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-tech-insights-node@0.6.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.49 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-tech-insights-node@0.6.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.7.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + +## @backstage/plugin-techdocs@1.10.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-auth-react@0.1.0 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.31 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/test-utils@1.5.4 + - @backstage/plugin-techdocs@1.10.4 + - @backstage/integration-react@1.1.26 + +## @backstage/plugin-techdocs-backend@1.10.4 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- c884b9a: Use the default cookie endpoints added automatically when a cookie policy is set. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-module-techdocs@0.1.22 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.9 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + +## @backstage/plugin-techdocs-node@1.12.3 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-techdocs-react@1.2.3 + +### Patch Changes + +- b450af3: Added ESLint rule `no-top-level-material-ui-4-imports` in the Techdocs-react plugin to migrate the Material UI imports. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + +## @backstage/plugin-todo@0.2.38 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-todo-backend@0.3.16 + +### Patch Changes + +- 2bd291e: Allow reserved characters in requests. +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/backend-openapi-utils@0.1.10 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-user-settings@0.8.5 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.29 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-vault-backend@0.4.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-vault-node@0.1.10 + +## @backstage/plugin-vault-node@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + +## @backstage/plugin-xcmetrics@0.2.52 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## example-app@0.2.96 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-github-pull-requests-board@0.2.0 + - @backstage/plugin-azure-devops@0.4.3 + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-notifications@0.2.0 + - @backstage/plugin-github-actions@0.6.15 + - @backstage/cli@0.26.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-auth-react@0.1.0 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/plugin-gocd@0.1.40 + - @backstage/frontend-app-api@0.6.4 + - @backstage/plugin-scaffolder@1.19.3 + - @backstage/plugin-graphiql@0.3.7 + - @backstage/core-components@0.14.4 + - @backstage/plugin-cloudbuild@0.5.1 + - @backstage/core-app-api@1.12.4 + - @backstage/app-defaults@1.5.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-adr@0.6.17 + - @backstage/plugin-airbrake@0.3.34 + - @backstage/plugin-apache-airflow@0.2.24 + - @backstage/plugin-api-docs@0.11.4 + - @backstage/plugin-azure-sites@0.1.23 + - @backstage/plugin-catalog-graph@0.4.4 + - @backstage/plugin-catalog-import@0.10.10 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3 + - @backstage/plugin-code-coverage@0.2.27 + - @backstage/plugin-cost-insights@0.12.23 + - @backstage/plugin-dynatrace@10.0.3 + - @backstage/plugin-entity-feedback@0.2.17 + - @backstage/plugin-explore@0.4.20 + - @backstage/plugin-gcalendar@0.3.27 + - @backstage/plugin-gcp-projects@0.3.50 + - @backstage/plugin-home@0.7.3 + - @backstage/plugin-jenkins@0.9.9 + - @backstage/plugin-kafka@0.3.34 + - @backstage/plugin-kubernetes-cluster@0.0.10 + - @backstage/plugin-kubernetes@0.11.9 + - @backstage/plugin-lighthouse@0.4.19 + - @backstage/plugin-microsoft-calendar@0.1.16 + - @backstage/plugin-newrelic@0.3.49 + - @backstage/plugin-nomad@0.1.15 + - @backstage/plugin-octopus-deploy@0.2.16 + - @backstage/plugin-org@0.6.24 + - @backstage/plugin-pagerduty@0.7.6 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-playlist@0.2.8 + - @backstage/plugin-puppetdb@0.1.17 + - @backstage/plugin-rollbar@0.4.34 + - @backstage/plugin-scaffolder-react@1.8.4 + - @backstage/plugin-search@1.4.10 + - @backstage/plugin-sentry@0.5.19 + - @backstage/plugin-shortcuts@0.3.23 + - @backstage/plugin-signals@0.0.5 + - @backstage/plugin-stack-overflow@0.1.29 + - @backstage/plugin-stackstorm@0.1.15 + - @backstage/plugin-tech-insights@0.3.26 + - @backstage/plugin-tech-radar@0.7.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9 + - @backstage/plugin-techdocs@1.10.4 + - @backstage/plugin-todo@0.2.38 + - @backstage/plugin-user-settings@0.8.5 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-badges@0.2.58 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-devtools@0.1.13 + - @backstage/plugin-linguist@0.1.19 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-newrelic-dashboard@0.3.9 + - @backstage/plugin-search-common@1.2.11 + +## example-app-next@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.4.3 + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-github-actions@0.6.15 + - @backstage/cli@0.26.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/plugin-gocd@0.1.40 + - @backstage/frontend-app-api@0.6.4 + - @backstage/plugin-scaffolder@1.19.3 + - @backstage/plugin-graphiql@0.3.7 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/plugin-cloudbuild@0.5.1 + - @backstage/core-app-api@1.12.4 + - @backstage/app-defaults@1.5.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/plugin-adr@0.6.17 + - @backstage/plugin-airbrake@0.3.34 + - @backstage/plugin-apache-airflow@0.2.24 + - @backstage/plugin-api-docs@0.11.4 + - @backstage/plugin-azure-sites@0.1.23 + - @backstage/plugin-catalog-graph@0.4.4 + - @backstage/plugin-catalog-import@0.10.10 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3 + - @backstage/plugin-code-coverage@0.2.27 + - @backstage/plugin-cost-insights@0.12.23 + - @backstage/plugin-dynatrace@10.0.3 + - @backstage/plugin-entity-feedback@0.2.17 + - @backstage/plugin-explore@0.4.20 + - @backstage/plugin-gcalendar@0.3.27 + - @backstage/plugin-gcp-projects@0.3.50 + - @backstage/plugin-home@0.7.3 + - @backstage/plugin-jenkins@0.9.9 + - @backstage/plugin-kafka@0.3.34 + - @backstage/plugin-kubernetes@0.11.9 + - @backstage/plugin-lighthouse@0.4.19 + - @backstage/plugin-microsoft-calendar@0.1.16 + - @backstage/plugin-newrelic@0.3.49 + - @backstage/plugin-octopus-deploy@0.2.16 + - @backstage/plugin-org@0.6.24 + - @backstage/plugin-pagerduty@0.7.6 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-playlist@0.2.8 + - @backstage/plugin-puppetdb@0.1.17 + - @backstage/plugin-rollbar@0.4.34 + - @backstage/plugin-scaffolder-react@1.8.4 + - @backstage/plugin-search@1.4.10 + - @backstage/plugin-sentry@0.5.19 + - @backstage/plugin-shortcuts@0.3.23 + - @backstage/plugin-stackstorm@0.1.15 + - @backstage/plugin-tech-insights@0.3.26 + - @backstage/plugin-tech-radar@0.7.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9 + - @backstage/plugin-techdocs@1.10.4 + - @backstage/plugin-todo@0.2.38 + - @backstage/plugin-user-settings@0.8.5 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-badges@0.2.58 + - app-next-example-plugin@0.0.10 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-app-visualizer@0.1.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-devtools@0.1.13 + - @backstage/plugin-linguist@0.1.19 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-newrelic-dashboard@0.3.9 + - @backstage/plugin-search-common@1.2.11 + +## app-next-example-plugin@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/frontend-plugin-api@0.6.4 + +## example-backend@0.2.97 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-pg@0.5.26 + - @backstage/plugin-badges-backend@0.4.0 + - @backstage/plugin-kubernetes-backend@0.17.0 + - @backstage/backend-common@0.21.7 + - @backstage/plugin-azure-devops-backend@0.6.4 + - @backstage/plugin-techdocs-backend@1.10.4 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/plugin-auth-backend@0.22.4 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3 + - @backstage/plugin-catalog-backend@1.21.1 + - @backstage/plugin-events-backend@0.3.4 + - @backstage/plugin-tech-insights-node@0.6.0 + - @backstage/plugin-search-backend@1.5.7 + - @backstage/plugin-todo-backend@0.3.16 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.49 + - @backstage/plugin-search-backend-module-techdocs@0.1.22 + - @backstage/plugin-search-backend-module-explore@0.1.21 + - @backstage/plugin-entity-feedback-backend@0.2.14 + - @backstage/plugin-code-coverage-backend@0.2.31 + - @backstage/plugin-tech-insights-backend@0.5.31 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/plugin-lighthouse-backend@0.4.10 + - @backstage/plugin-permission-backend@0.5.41 + - @backstage/plugin-devtools-backend@0.3.3 + - @backstage/plugin-linguist-backend@0.5.15 + - @backstage/plugin-playlist-backend@0.3.21 + - @backstage/plugin-explore-backend@0.0.27 + - @backstage/plugin-jenkins-backend@0.4.4 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-kafka-backend@0.3.15 + - @backstage/plugin-nomad-backend@0.1.19 + - @backstage/plugin-adr-backend@0.4.14 + - @backstage/plugin-app-backend@0.3.65 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-signals-backend@0.1.3 + - @backstage/plugin-proxy-backend@0.4.15 + - @backstage/plugin-scaffolder-backend@1.22.4 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.4.0 + - example-app@0.2.96 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.4 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-rollbar-backend@0.1.62 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.18 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.34 + - @backstage/plugin-search-backend-module-catalog@0.1.22 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15 + - @backstage/plugin-permission-common@0.7.13 + +## example-backend-next@0.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-badges-backend@0.4.0 + - @backstage/plugin-kubernetes-backend@0.17.0 + - @backstage/plugin-azure-devops-backend@0.6.4 + - @backstage/plugin-techdocs-backend@1.10.4 + - @backstage/plugin-notifications-backend@0.2.0 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/plugin-auth-backend@0.22.4 + - @backstage/plugin-catalog-backend@1.21.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.0 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend@1.5.7 + - @backstage/plugin-todo-backend@0.3.16 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7 + - @backstage/plugin-search-backend-module-techdocs@0.1.22 + - @backstage/plugin-search-backend-module-explore@0.1.21 + - @backstage/plugin-entity-feedback-backend@0.2.14 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/plugin-lighthouse-backend@0.4.10 + - @backstage/plugin-permission-backend@0.5.41 + - @backstage/plugin-sonarqube-backend@0.2.19 + - @backstage/plugin-devtools-backend@0.3.3 + - @backstage/plugin-linguist-backend@0.5.15 + - @backstage/plugin-playlist-backend@0.3.21 + - @backstage/plugin-jenkins-backend@0.4.4 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-nomad-backend@0.1.19 + - @backstage/plugin-adr-backend@0.4.14 + - @backstage/plugin-app-backend@0.3.65 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-signals-backend@0.1.3 + - @backstage/plugin-proxy-backend@0.4.15 + - @backstage/plugin-scaffolder-backend@1.22.4 + - @backstage/backend-defaults@0.2.17 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.3 + - @backstage/plugin-catalog-backend-module-openapi@0.1.35 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.4 + - @backstage/plugin-search-backend-module-catalog@0.1.22 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.14 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-auth-backend-module-github-provider@0.1.14 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15 + - @backstage/plugin-permission-common@0.7.13 + +## e2e-test@0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.14 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.95 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/cli@0.26.3 + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/app-defaults@1.5.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/test-utils@1.5.4 + - @backstage/theme@0.5.3 + - @backstage/plugin-techdocs@1.10.4 + - @backstage/integration-react@1.1.26 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + +## @internal/plugin-todo-list@1.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + +## @internal/plugin-todo-list-backend@1.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.26.0-next.0-changelog.md b/docs/releases/v1.26.0-next.0-changelog.md new file mode 100644 index 0000000000..3b4dcf8a28 --- /dev/null +++ b/docs/releases/v1.26.0-next.0-changelog.md @@ -0,0 +1,3074 @@ +# Release v1.26.0-next.0 + +## @backstage/config-loader@1.8.0-next.0 + +### Minor Changes + +- 99bab65: Support parameter substitution for environment variables + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/integration@1.10.0-next.0 + +### Minor Changes + +- 7b11422: Add AWS CodeCommit URL Reader/Integration + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/repo-tools@0.8.0-next.0 + +### Minor Changes + +- cfdc5e7: Adds two new commands, `repo schema openapi fuzz` and `package schema openapi fuzz` for fuzzing your plugins documented with OpenAPI. This can help find bugs in your application code through the use of auto-generated schema-compliant inputs. For more information on the underlying library this leverages, take a look at [the docs](https://schemathesis.readthedocs.io/en/stable/index.html). + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog@1.19.0-next.0 + +### Minor Changes + +- 18c7f12: Add `isApiType()` to EntitySwitch routing functions. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + +## @backstage/app-defaults@1.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/backend-app-api@0.6.3-next.0 + +### Patch Changes + +- 7e584d6: Fixed a bug where expired cookies would not be refreshed. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/backend-common@0.21.7-next.0 + +### Patch Changes + +- 7b11422: Add AWS CodeCommit URL Reader/Integration +- Updated dependencies + - @backstage/backend-app-api@0.6.3-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/backend-defaults@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + +## @backstage/backend-dynamic-feature-service@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.1-next.0 + - @backstage/backend-app-api@0.6.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-backend@0.3.3-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/backend-openapi-utils@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.6.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/backend-tasks@0.5.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.6.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/cli@0.26.3-next.0 + +### Patch Changes + +- e3c213e: Add the deprecation plugin to the default linter setup, switched off. + + This allows to disable deprecation warnings for `backstage-cli repo list-deprecations` with inline comments. + +- 4946f03: Updated dependency `webpack-dev-server` to `^5.0.0`. + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.6 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-components@0.14.4-next.0 + +### Patch Changes + +- f546e38: Added Link component in `TabUI` providing functionality like copy link or open in new tab. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.14-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/app-defaults@1.5.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/frontend-app-api@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/test-utils@1.5.3 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + +## @techdocs/cli@1.8.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## @backstage/plugin-adr@0.6.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-adr-common@0.2.22-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + +## @backstage/plugin-adr-backend@0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-adr-common@0.2.22-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-adr-common@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-airbrake@0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/dev-utils@1.0.31-next.0 + - @backstage/test-utils@1.5.3 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-airbrake-backend@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-allure@0.1.50-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-analytics-module-ga@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## @backstage/plugin-analytics-module-ga4@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## @backstage/plugin-apache-airflow@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-api-docs@0.11.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-apollo-explorer@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-app-backend@0.3.65-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.17-next.0 + +## @backstage/plugin-app-node@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.8.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + +## @backstage/plugin-app-visualizer@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## @backstage/plugin-auth-backend@0.22.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.9-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.9-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.12-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.14-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.14-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.14-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.12-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.14-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.8-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.10-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.22.4-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-backend@0.22.4-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-auth-node@0.4.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-azure-devops@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-azure-devops-common@0.4.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-devops-backend@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-azure-devops-common@0.4.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-azure-sites@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-sites-backend@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-badges@0.2.58-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-badges-backend@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-bazaar@0.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-bazaar-backend@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-bitbucket-cloud-common@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-bitrise@0.1.61-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-catalog-backend@1.21.1-next.0 + +### Patch Changes + +- cfdc5e7: Fixes an issue where `/analyze-location` would incorrectly throw a 500 error on an invalid url. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-openapi-utils@0.1.10-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.22-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-azure@0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.11-next.0 + +### Patch Changes + +- 58763e8: Use direct access of openapi.json files and not external route +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.10-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.18-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.1-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/plugin-catalog-backend-module-github@0.5.8-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.1-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.21.1-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-graph@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-catalog-import@0.10.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-catalog-node@1.11.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-catalog-react@1.11.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-cicd-statistics@0.1.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-cicd-statistics@0.1.36-next.0 + +## @backstage/plugin-circleci@0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-cloudbuild@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-code-climate@0.1.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-code-coverage@0.2.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-code-coverage-backend@0.2.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-codescene@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-config-schema@0.1.54-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-cost-insights@0.12.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-devtools-backend@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-dynatrace@10.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-entity-feedback@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-events-backend@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-events-node@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + +## @backstage/plugin-explore@0.4.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + +## @backstage/plugin-explore-backend@0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-module-explore@0.1.21-next.0 + +## @backstage/plugin-firehydrant@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-fossa@0.2.66-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-gcalendar@0.3.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-gcp-projects@0.3.50-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-git-release-manager@0.3.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-github-actions@0.6.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-github-deployments@0.1.65-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-github-issues@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-github-pull-requests-board@0.1.28-next.0 + +### Patch Changes + +- 617faf0: Handle null values returned from GitHub for the statusCheckRollup value on the commit object +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-gitops-profiles@0.3.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-gocd@0.1.40-next.0 + +### Patch Changes + +- b9d7c57: Updated README +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-graphiql@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## @backstage/plugin-graphql-voyager@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-home@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-home-react@0.1.12-next.0 + +## @backstage/plugin-home-react@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-ilert@0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-jenkins@0.9.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-jenkins-common@0.1.25 + +## @backstage/plugin-jenkins-backend@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-jenkins-common@0.1.25 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-kafka@0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-kafka-backend@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-kubernetes@0.11.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-kubernetes-react@0.3.4-next.0 + +## @backstage/plugin-kubernetes-backend@0.16.4-next.0 + +### Patch Changes + +- 9d89aed: Fixed a crash reading `credentials` from `undefined`. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/plugin-kubernetes-node@0.1.11-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-kubernetes-react@0.3.4-next.0 + +## @backstage/plugin-kubernetes-node@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-react@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-lighthouse@0.4.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-lighthouse-backend@0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-linguist@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-microsoft-calendar@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-newrelic@0.3.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-newrelic-dashboard@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-nomad@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-nomad-backend@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-notifications@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-react@0.0.2 + +## @backstage/plugin-notifications-backend@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-notifications-node@0.1.3-next.0 + - @backstage/plugin-signals-node@0.1.3-next.0 + +## @backstage/plugin-notifications-node@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-node@0.1.3-next.0 + +## @backstage/plugin-octopus-deploy@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-scaffolder-react@1.8.4-next.0 + +## @backstage/plugin-opencost@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-org@0.6.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-org-react@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-pagerduty@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-home-react@0.1.12-next.0 + +## @backstage/plugin-periskop@0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-periskop-backend@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-permission-backend@0.5.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + +## @backstage/plugin-permission-node@0.7.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-playlist@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist-common@0.1.15 + - @backstage/plugin-search-react@1.7.10-next.0 + +## @backstage/plugin-playlist-backend@0.3.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-proxy-backend@0.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-puppetdb@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-rollbar@0.4.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-rollbar-backend@0.1.62-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-scaffolder@1.19.3-next.0 + +### Patch Changes + +- 4f1f6ca: Use default value for `MyGroupsPicker` if provided +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-scaffolder-react@1.8.4-next.0 + +## @backstage/plugin-scaffolder-backend@1.22.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.9-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.7-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.0 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.0 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.0 + +### Patch Changes + +- 8dd33a1: Added examples for publish:bitbucketCloud actions +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.3-next.0 + +## @backstage/plugin-scaffolder-node@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-test-utils@0.3.7-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## @backstage/plugin-scaffolder-react@1.8.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-search@1.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + +## @backstage/plugin-search-backend@1.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/repo-tools@0.8.0-next.0 + - @backstage/backend-openapi-utils@0.1.10-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-catalog@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-explore@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-pg@0.5.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-techdocs@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-node@1.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-react@1.7.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-sentry@0.5.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-shortcuts@0.3.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals@0.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## @backstage/plugin-signals-backend@0.1.3-next.0 + +### Patch Changes + +- 5f9877b: Fix unauthorized signals connection by allowing unauthenticated requests +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-signals-node@0.1.3-next.0 + +## @backstage/plugin-signals-node@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## @backstage/plugin-sonarqube@0.7.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-sonarqube-react@0.1.14 + +## @backstage/plugin-sonarqube-backend@0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-splunk-on-call@0.4.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-stack-overflow@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-home-react@0.1.12-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + +## @backstage/plugin-stack-overflow-backend@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.10-next.0 + +## @backstage/plugin-stackstorm@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-tech-insights@0.3.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.5.3-next.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + - @backstage/plugin-tech-insights-node@0.5.3-next.0 + +## @backstage/plugin-tech-insights-node@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## @backstage/plugin-techdocs@1.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-auth-react@0.0.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/test-utils@1.5.3 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-techdocs@1.10.4-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @backstage/plugin-techdocs-backend@1.10.4-next.0 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @backstage/plugin-techdocs-node@1.12.3-next.0 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-techdocs-react@1.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/plugin-todo@0.2.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-todo-backend@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-openapi-utils@0.1.10-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.0 + +## @backstage/plugin-user-settings@0.8.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-user-settings-backend@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## @backstage/plugin-vault@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## @backstage/plugin-vault-backend@0.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-vault-node@0.1.10-next.0 + +## @backstage/plugin-vault-node@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + +## @backstage/plugin-xcmetrics@0.2.52-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## example-app@0.2.96-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-gocd@0.1.40-next.0 + - @backstage/plugin-scaffolder@1.19.3-next.0 + - @backstage/cli@0.26.3-next.0 + - @backstage/plugin-github-pull-requests-board@0.1.28-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/app-defaults@1.5.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-app-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-adr@0.6.17-next.0 + - @backstage/plugin-airbrake@0.3.34-next.0 + - @backstage/plugin-apache-airflow@0.2.24-next.0 + - @backstage/plugin-api-docs@0.11.4-next.0 + - @backstage/plugin-azure-devops@0.4.3-next.0 + - @backstage/plugin-azure-sites@0.1.23-next.0 + - @backstage/plugin-badges@0.2.58-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-graph@0.4.4-next.0 + - @backstage/plugin-catalog-import@0.10.10-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + - @backstage/plugin-cloudbuild@0.5.1-next.0 + - @backstage/plugin-code-coverage@0.2.27-next.0 + - @backstage/plugin-cost-insights@0.12.23-next.0 + - @backstage/plugin-devtools@0.1.13-next.0 + - @backstage/plugin-dynatrace@10.0.3-next.0 + - @backstage/plugin-entity-feedback@0.2.17-next.0 + - @backstage/plugin-explore@0.4.20-next.0 + - @backstage/plugin-gcalendar@0.3.27-next.0 + - @backstage/plugin-gcp-projects@0.3.50-next.0 + - @backstage/plugin-github-actions@0.6.15-next.0 + - @backstage/plugin-graphiql@0.3.7-next.0 + - @backstage/plugin-home@0.7.3-next.0 + - @backstage/plugin-jenkins@0.9.9-next.0 + - @backstage/plugin-kafka@0.3.34-next.0 + - @backstage/plugin-kubernetes@0.11.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.10-next.0 + - @backstage/plugin-lighthouse@0.4.19-next.0 + - @backstage/plugin-linguist@0.1.19-next.0 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.16-next.0 + - @backstage/plugin-newrelic@0.3.49-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.9-next.0 + - @backstage/plugin-nomad@0.1.15-next.0 + - @backstage/plugin-notifications@0.1.3-next.0 + - @backstage/plugin-octopus-deploy@0.2.16-next.0 + - @backstage/plugin-org@0.6.24-next.0 + - @backstage/plugin-pagerduty@0.7.6-next.0 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist@0.2.8-next.0 + - @backstage/plugin-puppetdb@0.1.17-next.0 + - @backstage/plugin-rollbar@0.4.34-next.0 + - @backstage/plugin-scaffolder-react@1.8.4-next.0 + - @backstage/plugin-search@1.4.10-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-sentry@0.5.19-next.0 + - @backstage/plugin-shortcuts@0.3.23-next.0 + - @backstage/plugin-signals@0.0.5-next.0 + - @backstage/plugin-stack-overflow@0.1.29-next.0 + - @backstage/plugin-stackstorm@0.1.15-next.0 + - @backstage/plugin-tech-insights@0.3.26-next.0 + - @backstage/plugin-tech-radar@0.7.3-next.0 + - @backstage/plugin-techdocs@1.10.4-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + - @backstage/plugin-todo@0.2.38-next.0 + - @backstage/plugin-user-settings@0.8.5-next.0 + +## example-app-next@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-gocd@0.1.40-next.0 + - @backstage/plugin-scaffolder@1.19.3-next.0 + - @backstage/cli@0.26.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/app-defaults@1.5.4-next.0 + - app-next-example-plugin@0.0.10-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.3 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-app-api@0.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-adr@0.6.17-next.0 + - @backstage/plugin-airbrake@0.3.34-next.0 + - @backstage/plugin-apache-airflow@0.2.24-next.0 + - @backstage/plugin-api-docs@0.11.4-next.0 + - @backstage/plugin-app-visualizer@0.1.5-next.0 + - @backstage/plugin-azure-devops@0.4.3-next.0 + - @backstage/plugin-azure-sites@0.1.23-next.0 + - @backstage/plugin-badges@0.2.58-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-graph@0.4.4-next.0 + - @backstage/plugin-catalog-import@0.10.10-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + - @backstage/plugin-cloudbuild@0.5.1-next.0 + - @backstage/plugin-code-coverage@0.2.27-next.0 + - @backstage/plugin-cost-insights@0.12.23-next.0 + - @backstage/plugin-devtools@0.1.13-next.0 + - @backstage/plugin-dynatrace@10.0.3-next.0 + - @backstage/plugin-entity-feedback@0.2.17-next.0 + - @backstage/plugin-explore@0.4.20-next.0 + - @backstage/plugin-gcalendar@0.3.27-next.0 + - @backstage/plugin-gcp-projects@0.3.50-next.0 + - @backstage/plugin-github-actions@0.6.15-next.0 + - @backstage/plugin-graphiql@0.3.7-next.0 + - @backstage/plugin-home@0.7.3-next.0 + - @backstage/plugin-jenkins@0.9.9-next.0 + - @backstage/plugin-kafka@0.3.34-next.0 + - @backstage/plugin-kubernetes@0.11.9-next.0 + - @backstage/plugin-lighthouse@0.4.19-next.0 + - @backstage/plugin-linguist@0.1.19-next.0 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.16-next.0 + - @backstage/plugin-newrelic@0.3.49-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.9-next.0 + - @backstage/plugin-octopus-deploy@0.2.16-next.0 + - @backstage/plugin-org@0.6.24-next.0 + - @backstage/plugin-pagerduty@0.7.6-next.0 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist@0.2.8-next.0 + - @backstage/plugin-puppetdb@0.1.17-next.0 + - @backstage/plugin-rollbar@0.4.34-next.0 + - @backstage/plugin-scaffolder-react@1.8.4-next.0 + - @backstage/plugin-search@1.4.10-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-sentry@0.5.19-next.0 + - @backstage/plugin-shortcuts@0.3.23-next.0 + - @backstage/plugin-stackstorm@0.1.15-next.0 + - @backstage/plugin-tech-insights@0.3.26-next.0 + - @backstage/plugin-tech-radar@0.7.3-next.0 + - @backstage/plugin-techdocs@1.10.4-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + - @backstage/plugin-todo@0.2.38-next.0 + - @backstage/plugin-user-settings@0.8.5-next.0 + +## app-next-example-plugin@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## example-backend@0.2.97-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.4-next.0 + - @backstage/plugin-catalog-backend@1.21.1-next.0 + - @backstage/plugin-kubernetes-backend@0.16.4-next.0 + - @backstage/plugin-signals-backend@0.1.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.0 + - @backstage/plugin-scaffolder-backend@1.22.4-next.0 + - @backstage/plugin-app-backend@0.3.65-next.0 + - example-app@0.2.96-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-adr-backend@0.4.14-next.0 + - @backstage/plugin-auth-backend@0.22.4-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-azure-devops-backend@0.6.4-next.0 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-badges-backend@0.3.14-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.4-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-code-coverage-backend@0.2.31-next.0 + - @backstage/plugin-devtools-backend@0.3.3-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.14-next.0 + - @backstage/plugin-events-backend@0.3.3-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-explore-backend@0.0.27-next.0 + - @backstage/plugin-jenkins-backend@0.4.4-next.0 + - @backstage/plugin-kafka-backend@0.3.15-next.0 + - @backstage/plugin-lighthouse-backend@0.4.10-next.0 + - @backstage/plugin-linguist-backend@0.5.15-next.0 + - @backstage/plugin-nomad-backend@0.1.19-next.0 + - @backstage/plugin-permission-backend@0.5.41-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-playlist-backend@0.3.21-next.0 + - @backstage/plugin-proxy-backend@0.4.15-next.0 + - @backstage/plugin-rollbar-backend@0.1.62-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.18-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.34-next.0 + - @backstage/plugin-search-backend@1.5.7-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.22-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.20-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.21-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.26-next.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-signals-node@0.1.3-next.0 + - @backstage/plugin-tech-insights-backend@0.5.31-next.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.49-next.0 + - @backstage/plugin-tech-insights-node@0.5.3-next.0 + - @backstage/plugin-todo-backend@0.3.16-next.0 + +## example-backend-next@0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.4-next.0 + - @backstage/plugin-catalog-backend@1.21.1-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.11-next.0 + - @backstage/plugin-kubernetes-backend@0.16.4-next.0 + - @backstage/plugin-signals-backend@0.1.3-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.0 + - @backstage/plugin-scaffolder-backend@1.22.4-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.35-next.0 + - @backstage/backend-defaults@0.2.17-next.0 + - @backstage/plugin-app-backend@0.3.65-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-adr-backend@0.4.14-next.0 + - @backstage/plugin-auth-backend@0.22.4-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.14-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.3-next.0 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-azure-devops-backend@0.6.4-next.0 + - @backstage/plugin-badges-backend@0.3.14-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.4-next.0 + - @backstage/plugin-devtools-backend@0.3.3-next.0 + - @backstage/plugin-entity-feedback-backend@0.2.14-next.0 + - @backstage/plugin-jenkins-backend@0.4.4-next.0 + - @backstage/plugin-lighthouse-backend@0.4.10-next.0 + - @backstage/plugin-linguist-backend@0.5.15-next.0 + - @backstage/plugin-nomad-backend@0.1.19-next.0 + - @backstage/plugin-notifications-backend@0.1.3-next.0 + - @backstage/plugin-permission-backend@0.5.41-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.14-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-playlist-backend@0.3.21-next.0 + - @backstage/plugin-proxy-backend@0.4.15-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.0 + - @backstage/plugin-search-backend@1.5.7-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.22-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.21-next.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-sonarqube-backend@0.2.19-next.0 + - @backstage/plugin-todo-backend@0.3.16-next.0 + +## e2e-test@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.14-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.95-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.26.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/app-defaults@1.5.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/test-utils@1.5.3 + - @backstage/theme@0.5.2 + - @backstage/plugin-techdocs@1.10.4-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @internal/plugin-todo-list@1.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @internal/plugin-todo-list-backend@1.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 diff --git a/docs/releases/v1.26.0-next.1-changelog.md b/docs/releases/v1.26.0-next.1-changelog.md new file mode 100644 index 0000000000..9fb66191a3 --- /dev/null +++ b/docs/releases/v1.26.0-next.1-changelog.md @@ -0,0 +1,3016 @@ +# Release v1.26.0-next.1 + +## @backstage/backend-app-api@0.7.0-next.1 + +### Minor Changes + +- 3256f14: **BREAKING**: Modules are no longer loaded unless the plugin that they extend is present. + +### Patch Changes + +- 10327fb: Deprecate the `getPath` option for the `httpRouterServiceFactory` and more generally the ability to configure plugin API paths to be anything else than `/api/:pluginId/`. Requests towards `/api/*` that do not match an installed plugin will also no longer be handled by the index router, typically instead returning a 404. + +- 1a20b12: Make the auth service create and validate dedicated OBO tokens, containing the user identity proof. + +- bce0879: Service-to-service authentication has been improved. + + Each plugin now has the capability to generate its own signing keys for token issuance. The generated public keys are stored in a database, and they are made accessible through a newly created endpoint: `/.backstage/auth/v1/jwks.json`. + + `AuthService` can now issue tokens with a reduced scope using the `getPluginRequestToken` method. This improvement enables plugins to identify the plugin originating the request. + +- 54f2ac8: Added `initialization` option to `createServiceFactory` which defines the initialization strategy for the service. The default strategy mimics the current behavior where plugin scoped services are initialized lazily by default and root scoped services are initialized eagerly. + +- d62bc51: Add support for limited user tokens by using user identity proof provided by the auth backend. + +- c884b9a: Automatically creates a get and delete cookie endpoint when a `user-cookie` policy is added. + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.0-next.1 + +### Minor Changes + +- c884b9a: **BREAKING**: Removed the path option from `CookieAuthRefreshProvider` and `useCookieAuthRefresh`. + + A new `CookieAuthRedirect` component has been added to redirect a public app bundle to the protected one when using the `app-backend` with a separate public entry point. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-kubernetes-backend@0.17.0-next.1 + +### Minor Changes + +- 6c19c14: **BREAKING**: `KubernetesProxy` now requires the `DiscoveryService` to be passed to the constuctor + +### Patch Changes + +- f5cec55: Fixing issue where `BackstageCredentials` were not properly forwarded for all calls +- Updated dependencies + - @backstage/plugin-kubernetes-node@0.1.11-next.1 + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-kubernetes-common@0.7.5 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-notifications@0.2.0-next.1 + +### Minor Changes + +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-signals-react@0.0.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + +## @backstage/plugin-notifications-backend@0.2.0-next.1 + +### Minor Changes + +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- 9987066: fix: retrieve relations and children when mapping group entities for notifications +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-notifications-node@0.1.3-next.1 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.2 + +## @backstage/app-defaults@1.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/backend-common@0.21.7-next.1 + +### Patch Changes + +- 007e7ea: Added placeholder for `listPublicServiceKeys()` in the `AuthService` returned by `createLegacyAuthAdapters`. +- 75a53b8: KubernetesContainerRunner.runContainer no longer closes the `logStream` it receives as input. +- Updated dependencies + - @backstage/backend-app-api@0.7.0-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-app-api@0.7.0-next.1 + +## @backstage/backend-dynamic-feature-service@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-app-api@0.7.0-next.1 + - @backstage/plugin-events-backend@0.3.4-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-catalog-backend@1.21.1-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.17-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/backend-openapi-utils@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.6.17-next.1 + +### Patch Changes + +- 007e7ea: Added a new required `listPublicServiceKeys` to `AuthService`. +- 54f2ac8: Added `initialization` option to `createServiceFactory` which defines the initialization strategy for the service. The default strategy mimics the current behavior where plugin scoped services are initialized lazily by default and root scoped services are initialized eagerly. +- 4fecffc: The credentials passed to the `issueUserCookie` method of the `HttpAuthService` are no longer required to represent a user principal. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/backend-tasks@0.5.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.7-next.1 + +### Patch Changes + +- 3256f14: `startTestBackend` will now add placeholder plugins when a modules are provided without their parent plugin. +- 007e7ea: Added mock of the new `listPublicServiceKeys` method for `AuthService`. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-app-api@0.7.0-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.4-next.0 + +### Patch Changes + +- dad7505: Fix the `CatalogClient::getEntities` method to only sort the resulting entities in case no `order`-parameter is provided. +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.26.3-next.1 + +### Patch Changes + +- c884b9a: Fix the bundle public subpath configuration. +- 6b5ddbe: Fix the backend plugin to use correct plugin id +- 4fecffc: When building the frontend app public assets are now also copied to the public dist directory when in use. +- Updated dependencies + - @backstage/eslint-plugin@0.1.7-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-app-api@1.12.4-next.0 + +### Patch Changes + +- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/core-compat-api@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/create-app@0.5.14-next.1 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.31-next.1 + +### Patch Changes + +- 995f66b: add @backstage/no-top-level-material-ui-4-imports lint rule +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/app-defaults@1.5.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/eslint-plugin@0.1.7-next.0 + +### Patch Changes + +- 9ef572d: fix lint rule fixer for more than one `Component + Prop` +- 3a7eee7: eslint autofix for mui ThemeProvider + +## @backstage/frontend-app-api@0.6.4-next.1 + +### Patch Changes + +- c884b9a: The app is now aware of if it is being served from the `app-backend` with a separate public and protected bundles. When in protected mode the app will now continuously refresh the session cookie, as well as clear the cookie if the user signs out. +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-plugin-api@0.6.4-next.1 + +### Patch Changes + +- 35452b3: Fixed the type for `useRouteRef`, which wasn't handling optional external route refs correctly. +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## @backstage/frontend-test-utils@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.4-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/test-utils@1.5.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.8.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.4 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-adr@0.6.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-adr-common@0.2.22-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + +## @backstage/plugin-adr-backend@0.4.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-adr-common@0.2.22-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-airbrake@0.3.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/dev-utils@1.0.31-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-airbrake-backend@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-allure@0.1.50-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-analytics-module-ga@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-analytics-module-ga4@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-analytics-module-newrelic-browser@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-api-docs@0.11.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-app-backend@0.3.65-next.1 + +### Patch Changes + +- c884b9a: Track assets namespace in the cache store, implement a cookie authentication for when the public entry is enabled and used with the new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.17-next.1 + +## @backstage/plugin-app-node@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config-loader@1.8.0-next.0 + +## @backstage/plugin-app-visualizer@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-auth-backend@0.22.4-next.1 + +### Patch Changes + +- d62bc51: Added token type header parameter and user identity proof to issued user tokens. +- bf4d71a: Initial implementation of the `/v1/userinfo` endpoint, which is now able to parse and return the `sub` and `ent` claims from a Backstage user token. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.9-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.8-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.9-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.12-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.1.14-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.14-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.1.14-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.12-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.14-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.10-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.10-next.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.9-next.1 + +### Patch Changes + +- 30f5a51: Added `authModuleAwsAlbProvider` as a default export. + + It can now be used like this in your backend: `backend.add(import('@backstage/plugin-auth-backend-module-aws-alb-provider'));` + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-auth-backend@0.22.4-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.8-next.1 + +### Patch Changes + +- 28eb473: Support revoke refresh token to oidc logout function +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-auth-backend@0.22.4-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-model@1.4.5 + +## @backstage/plugin-auth-node@0.4.12-next.1 + +### Patch Changes + +- d62bc51: Add `tokenTypes` export with constants for various Backstage token types. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-azure-devops@0.4.3-next.1 + +### Patch Changes + +- 95b0573: `getAllTeams` now accepts an optional `limit` parameter which can be used to return more than the default limit of 100 teams from the Azure DevOps API + + `pullRequestOptions` have been equipped with `teamsLimit` so that the property can be used with `getAllTeams` + +- 4d895b3: Fixed bug in EntityPageAzurePipeline component where build definition annotation used for viewing pipelines + +- Updated dependencies + - @backstage/plugin-azure-devops-common@0.4.1-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-devops-backend@0.6.4-next.1 + +### Patch Changes + +- 95b0573: `getAllTeams` now accepts an optional `limit` parameter which can be used to return more than the default limit of 100 teams from the Azure DevOps API + + `pullRequestOptions` have been equipped with `teamsLimit` so that the property can be used with `getAllTeams` + +- c7c4053: Fixed a bug where the `azureDevOps.token` was not truly optional + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-azure-devops-common@0.4.1-next.0 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-azure-devops-common@0.4.1-next.0 + +### Patch Changes + +- 95b0573: `getAllTeams` now accepts an optional `limit` parameter which can be used to return more than the default limit of 100 teams from the Azure DevOps API + + `pullRequestOptions` have been equipped with `teamsLimit` so that the property can be used with `getAllTeams` + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-azure-sites@0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-azure-sites-backend@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-badges@0.2.58-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-badges-backend@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bazaar@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-bazaar-backend@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-bitrise@0.1.61-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-catalog@1.19.0-next.1 + +### Patch Changes + +- bcb2674: Added a "create something similar" button to the `<AboutCard>` that is visible and links to the scaffolder template corresponding to the entity's `backstage.io/source-template` annotation, if present. +- 4ef0dcf: Fixed a bug that prevented the default `entityPresentationApi` from being set in apps using the new frontend system. +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + +## @backstage/plugin-catalog-backend@1.21.1-next.1 + +### Patch Changes + +- c52f7ac: Make entity collection errors a little quieter in the logs. + + Instead of logging a warning line when an entity has an error + during processing, it will now instead emit an event on the event + broker. + + This only removes a single log line, however it is possible to + add the log line back if it is required by subscribing to the + `CATALOG_ERRORS_TOPIC` as shown below. + + ```typescript + env.eventBroker.subscribe({ + supportsEventTopics(): string[] { + return [CATALOG_ERRORS_TOPIC]; + }, + + async onEvent( + params: EventParams<{ + entity: string; + location?: string; + errors: Array<Error>; + }>, + ): Promise<void> { + const { entity, location, errors } = params.eventPayload; + for (const error of errors) { + env.logger.warn(error.message, { + entity, + location, + }); + } + }, + }); + ``` + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.22-next.1 + - @backstage/backend-openapi-utils@0.1.10-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-aws@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-azure@0.1.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/backend-openapi-utils@0.1.10-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.18-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.5.8-next.1 + +### Patch Changes + +- 469e87f: Properly instantiate `GithubMultiOrgEntityProvider` and `GithubOrgEntityProvider` with `EventsService` if defined +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-catalog-backend@1.21.1-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-catalog-backend-module-github@0.5.8-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-catalog-backend@1.21.1-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.33-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.25-next.1 + +### Patch Changes + +- 9b6320f: Retry msgraph API calls, due to frequent ETIMEDOUT errors. Also allow disabling fetching user photos. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-catalog-backend@1.21.1-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-graph@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-catalog-import@0.10.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-catalog-node@1.11.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-react@1.11.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-cicd-statistics@0.1.36-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-cicd-statistics@0.1.36-next.1 + +## @backstage/plugin-circleci@0.3.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-cloudbuild@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-code-climate@0.1.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-code-coverage@0.2.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-code-coverage-backend@0.2.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-codescene@0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-cost-insights@0.12.23-next.1 + +### Patch Changes + +- 43ca784: Updated dependency `@types/yup` to `^0.32.0`. +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-cost-insights-common@0.1.2 + +## @backstage/plugin-devtools@0.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-react@0.4.21 + +## @backstage/plugin-devtools-backend@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-dynatrace@10.0.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-entity-feedback@0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-feedback-backend@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-entity-feedback-common@0.1.3 + +## @backstage/plugin-entity-validation@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-events-backend@0.3.4-next.1 + +### Patch Changes + +- 7899e55: Allow unauthenticated requests for HTTP ingress. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + +## @backstage/plugin-events-backend-module-github@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.3-next.1 + +## @backstage/plugin-events-node@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + +## @backstage/plugin-explore@0.4.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-explore-react@0.0.37 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + +## @backstage/plugin-explore-backend@0.0.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.21-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + +## @backstage/plugin-firehydrant@0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-fossa@0.2.66-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-github-actions@0.6.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-github-deployments@0.1.65-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-github-issues@0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-github-pull-requests-board@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-gocd@0.1.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-graphiql@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-home@0.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-home-react@0.1.12-next.0 + +## @backstage/plugin-ilert@0.2.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-jenkins@0.9.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-jenkins-common@0.1.25 + +## @backstage/plugin-jenkins-backend@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-jenkins-common@0.1.25 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-kafka@0.3.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-kafka-backend@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-kubernetes@0.11.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.3.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-cluster@0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.3.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-node@0.1.11-next.1 + +### Patch Changes + +- f5cec55: Fixing issue where `BackstageCredentials` were not properly forwarded for all calls +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-kubernetes-react@0.3.4-next.1 + +### Patch Changes + +- e6d474f: Fixed ResourceUtilization component for POD Memory Limits +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.7.5 + +## @backstage/plugin-lighthouse@0.4.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-lighthouse-backend@0.4.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-lighthouse-common@0.1.5 + +## @backstage/plugin-linguist@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-linguist-backend@0.5.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-linguist-common@0.1.2 + +## @backstage/plugin-newrelic-dashboard@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-nomad@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-nomad-backend@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-notifications-node@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + +## @backstage/plugin-octopus-deploy@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.8.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-org@0.6.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-org-react@0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-pagerduty@0.7.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-home-react@0.1.12-next.0 + +## @backstage/plugin-periskop@0.1.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-periskop-backend@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-permission-backend@0.5.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-permission-node@0.7.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-playlist@0.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist-common@0.1.15 + - @backstage/plugin-search-react@1.7.10-next.1 + +## @backstage/plugin-playlist-backend@0.3.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-playlist-common@0.1.15 + +## @backstage/plugin-proxy-backend@0.4.15-next.1 + +### Patch Changes + +- 43ca784: Updated dependency `@types/yup` to `^0.32.0`. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-puppetdb@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-rollbar@0.4.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-rollbar-backend@0.1.62-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-scaffolder@1.19.3-next.1 + +### Patch Changes + +- 605c971: Allow the task list search to work on the Scaffolder template title. +- 87d2eb8: Updated dependency `json-schema-library` to `^9.0.0`. +- 419e948: Don't show login prompt if token is set in the state +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.8.4-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend@1.22.4-next.1 + +### Patch Changes + +- f34a9b1: The `catalog:write` action now automatically adds a `backstage.io/template-source` annotation, indicating which Scaffolder template was used to create the entity. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.9-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.7-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9-next.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.9-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.1 + +### Patch Changes + +- 4a15c86: Add examples for `publish:bitbucketServer` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.3-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-test-utils@0.3.7-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.4-next.1 + +### Patch Changes + +- 87d2eb8: Updated dependency `json-schema-library` to `^9.0.0`. + +- df99f62: The `value` sent on the `create` analytics event (fired when a Scaffolder template is executed) is now set to the number of minutes saved by executing the template. This value is derived from the `backstage.io/time-saved` annotation on the template entity, if available. + + Note: the `create` event is now captured in the `<Workflow>` component. If you are directly making use of the alpha-exported `<Stepper>` component, an analytics `create` event will no longer be captured on your behalf. + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## @backstage/plugin-search@1.4.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + +## @backstage/plugin-search-backend@1.5.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/repo-tools@0.8.0-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/backend-openapi-utils@0.1.10-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-catalog@0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-elasticsearch@1.3.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-explore@0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-pg@0.5.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-techdocs@0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-node@1.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-react@1.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-sentry@0.5.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-signals@0.0.5-next.1 + +### Patch Changes + +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/plugin-signals-react@0.0.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-backend@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.3-next.0 + +### Patch Changes + +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## @backstage/plugin-sonarqube@0.7.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-sonarqube-react@0.1.14 + +## @backstage/plugin-sonarqube-backend@0.2.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-splunk-on-call@0.4.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-stack-overflow@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-home-react@0.1.12-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + +## @backstage/plugin-stack-overflow-backend@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.10-next.1 + +## @backstage/plugin-tech-insights@0.3.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend@0.5.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-tech-insights-node@0.5.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.49-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-tech-insights-node@0.5.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-insights-node@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-tech-insights-common@0.2.12 + +## @backstage/plugin-tech-radar@0.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + +## @backstage/plugin-techdocs@1.10.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/test-utils@1.5.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-techdocs@1.10.4-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @backstage/plugin-techdocs-backend@1.10.4-next.1 + +### Patch Changes + +- c884b9a: Use the default cookie endpoints added automatically when a cookie policy is set. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-techdocs-node@1.12.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-todo@0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-todo-backend@0.3.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-openapi-utils@0.1.10-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.1 + +## @backstage/plugin-user-settings@0.8.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-user-settings-backend@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-vault@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## @backstage/plugin-vault-backend@0.4.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-vault-node@0.1.10-next.1 + +## @backstage/plugin-vault-node@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + +## example-app@0.2.96-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.4.3-next.1 + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/cli@0.26.3-next.1 + - @backstage/plugin-auth-react@0.1.0-next.1 + - @backstage/plugin-scaffolder@1.19.3-next.1 + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-app-api@0.6.4-next.1 + - @backstage/plugin-scaffolder-react@1.8.4-next.1 + - @backstage/plugin-cost-insights@0.12.23-next.1 + - @backstage/plugin-signals@0.0.5-next.1 + - @backstage/plugin-notifications@0.2.0-next.1 + - @backstage/plugin-api-docs@0.11.4-next.1 + - @backstage/plugin-catalog-graph@0.4.4-next.1 + - @backstage/plugin-explore@0.4.20-next.1 + - @backstage/plugin-org@0.6.24-next.1 + - @backstage/plugin-user-settings@0.8.5-next.1 + - @backstage/plugin-kubernetes@0.11.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.10-next.1 + - @backstage/app-defaults@1.5.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-adr@0.6.17-next.1 + - @backstage/plugin-airbrake@0.3.34-next.1 + - @backstage/plugin-apache-airflow@0.2.24-next.0 + - @backstage/plugin-azure-sites@0.1.23-next.1 + - @backstage/plugin-badges@0.2.58-next.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-import@0.10.10-next.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + - @backstage/plugin-cloudbuild@0.5.1-next.1 + - @backstage/plugin-code-coverage@0.2.27-next.1 + - @backstage/plugin-devtools@0.1.13-next.1 + - @backstage/plugin-dynatrace@10.0.3-next.1 + - @backstage/plugin-entity-feedback@0.2.17-next.1 + - @backstage/plugin-gcalendar@0.3.27-next.0 + - @backstage/plugin-gcp-projects@0.3.50-next.0 + - @backstage/plugin-github-actions@0.6.15-next.1 + - @backstage/plugin-github-pull-requests-board@0.1.28-next.1 + - @backstage/plugin-gocd@0.1.40-next.1 + - @backstage/plugin-graphiql@0.3.7-next.1 + - @backstage/plugin-home@0.7.3-next.1 + - @backstage/plugin-jenkins@0.9.9-next.1 + - @backstage/plugin-kafka@0.3.34-next.1 + - @backstage/plugin-lighthouse@0.4.19-next.1 + - @backstage/plugin-linguist@0.1.19-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.16-next.0 + - @backstage/plugin-newrelic@0.3.49-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.9-next.1 + - @backstage/plugin-nomad@0.1.15-next.1 + - @backstage/plugin-octopus-deploy@0.2.16-next.1 + - @backstage/plugin-pagerduty@0.7.6-next.1 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist@0.2.8-next.1 + - @backstage/plugin-puppetdb@0.1.17-next.1 + - @backstage/plugin-rollbar@0.4.34-next.1 + - @backstage/plugin-search@1.4.10-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-sentry@0.5.19-next.1 + - @backstage/plugin-shortcuts@0.3.23-next.0 + - @backstage/plugin-stack-overflow@0.1.29-next.1 + - @backstage/plugin-stackstorm@0.1.15-next.0 + - @backstage/plugin-tech-insights@0.3.26-next.1 + - @backstage/plugin-tech-radar@0.7.3-next.1 + - @backstage/plugin-techdocs@1.10.4-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + - @backstage/plugin-todo@0.2.38-next.1 + +## example-app-next@0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.4.3-next.1 + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/cli@0.26.3-next.1 + - @backstage/plugin-scaffolder@1.19.3-next.1 + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-app-api@0.6.4-next.1 + - @backstage/plugin-scaffolder-react@1.8.4-next.1 + - @backstage/plugin-cost-insights@0.12.23-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/plugin-api-docs@0.11.4-next.1 + - @backstage/plugin-catalog-graph@0.4.4-next.1 + - @backstage/plugin-explore@0.4.20-next.1 + - @backstage/plugin-org@0.6.24-next.1 + - @backstage/plugin-user-settings@0.8.5-next.1 + - @backstage/plugin-kubernetes@0.11.9-next.1 + - @backstage/app-defaults@1.5.4-next.1 + - app-next-example-plugin@0.0.10-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-adr@0.6.17-next.1 + - @backstage/plugin-airbrake@0.3.34-next.1 + - @backstage/plugin-apache-airflow@0.2.24-next.0 + - @backstage/plugin-app-visualizer@0.1.5-next.1 + - @backstage/plugin-azure-sites@0.1.23-next.1 + - @backstage/plugin-badges@0.2.58-next.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-import@0.10.10-next.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + - @backstage/plugin-cloudbuild@0.5.1-next.1 + - @backstage/plugin-code-coverage@0.2.27-next.1 + - @backstage/plugin-devtools@0.1.13-next.1 + - @backstage/plugin-dynatrace@10.0.3-next.1 + - @backstage/plugin-entity-feedback@0.2.17-next.1 + - @backstage/plugin-gcalendar@0.3.27-next.0 + - @backstage/plugin-gcp-projects@0.3.50-next.0 + - @backstage/plugin-github-actions@0.6.15-next.1 + - @backstage/plugin-gocd@0.1.40-next.1 + - @backstage/plugin-graphiql@0.3.7-next.1 + - @backstage/plugin-home@0.7.3-next.1 + - @backstage/plugin-jenkins@0.9.9-next.1 + - @backstage/plugin-kafka@0.3.34-next.1 + - @backstage/plugin-lighthouse@0.4.19-next.1 + - @backstage/plugin-linguist@0.1.19-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.16-next.0 + - @backstage/plugin-newrelic@0.3.49-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.9-next.1 + - @backstage/plugin-octopus-deploy@0.2.16-next.1 + - @backstage/plugin-pagerduty@0.7.6-next.1 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist@0.2.8-next.1 + - @backstage/plugin-puppetdb@0.1.17-next.1 + - @backstage/plugin-rollbar@0.4.34-next.1 + - @backstage/plugin-search@1.4.10-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-sentry@0.5.19-next.1 + - @backstage/plugin-shortcuts@0.3.23-next.0 + - @backstage/plugin-stackstorm@0.1.15-next.0 + - @backstage/plugin-tech-insights@0.3.26-next.1 + - @backstage/plugin-tech-radar@0.7.3-next.1 + - @backstage/plugin-techdocs@1.10.4-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + - @backstage/plugin-todo@0.2.38-next.1 + +## app-next-example-plugin@0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-components@0.14.4-next.0 + +## example-backend@0.2.97-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-backend@0.17.0-next.1 + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-azure-devops-backend@0.6.4-next.1 + - @backstage/plugin-techdocs-backend@1.10.4-next.1 + - @backstage/plugin-events-backend@0.3.4-next.1 + - @backstage/plugin-auth-backend@0.22.4-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-proxy-backend@0.4.15-next.1 + - @backstage/plugin-scaffolder-backend@1.22.4-next.1 + - @backstage/plugin-catalog-backend@1.21.1-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.1 + - @backstage/plugin-app-backend@0.3.65-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-adr-backend@0.4.14-next.1 + - @backstage/plugin-badges-backend@0.3.14-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.4-next.1 + - @backstage/plugin-code-coverage-backend@0.2.31-next.1 + - @backstage/plugin-devtools-backend@0.3.3-next.1 + - @backstage/plugin-entity-feedback-backend@0.2.14-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-explore-backend@0.0.27-next.1 + - @backstage/plugin-jenkins-backend@0.4.4-next.1 + - @backstage/plugin-kafka-backend@0.3.15-next.1 + - @backstage/plugin-lighthouse-backend@0.4.10-next.1 + - @backstage/plugin-linguist-backend@0.5.15-next.1 + - @backstage/plugin-nomad-backend@0.1.19-next.1 + - @backstage/plugin-permission-backend@0.5.41-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-playlist-backend@0.3.21-next.1 + - @backstage/plugin-rollbar-backend@0.1.62-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.18-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.34-next.1 + - @backstage/plugin-search-backend@1.5.7-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.22-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.3.20-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.21-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.26-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/plugin-signals-backend@0.1.3-next.1 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/plugin-tech-insights-backend@0.5.31-next.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.49-next.1 + - @backstage/plugin-tech-insights-node@0.5.3-next.1 + - @backstage/plugin-todo-backend@0.3.16-next.1 + - example-app@0.2.96-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-azure-sites-common@0.1.3 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## example-backend-next@0.0.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-backend@0.17.0-next.1 + - @backstage/plugin-azure-devops-backend@0.6.4-next.1 + - @backstage/plugin-techdocs-backend@1.10.4-next.1 + - @backstage/plugin-auth-backend@0.22.4-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-proxy-backend@0.4.15-next.1 + - @backstage/plugin-scaffolder-backend@1.22.4-next.1 + - @backstage/plugin-catalog-backend@1.21.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.1 + - @backstage/plugin-app-backend@0.3.65-next.1 + - @backstage/plugin-notifications-backend@0.2.0-next.1 + - @backstage/backend-defaults@0.2.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-adr-backend@0.4.14-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.3-next.1 + - @backstage/plugin-badges-backend@0.3.14-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.1.35-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.4-next.1 + - @backstage/plugin-devtools-backend@0.3.3-next.1 + - @backstage/plugin-entity-feedback-backend@0.2.14-next.1 + - @backstage/plugin-jenkins-backend@0.4.4-next.1 + - @backstage/plugin-lighthouse-backend@0.4.10-next.1 + - @backstage/plugin-linguist-backend@0.5.15-next.1 + - @backstage/plugin-nomad-backend@0.1.19-next.1 + - @backstage/plugin-permission-backend@0.5.41-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-playlist-backend@0.3.21-next.1 + - @backstage/plugin-search-backend@1.5.7-next.1 + - @backstage/plugin-search-backend-module-catalog@0.1.22-next.1 + - @backstage/plugin-search-backend-module-explore@0.1.21-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/plugin-signals-backend@0.1.3-next.1 + - @backstage/plugin-sonarqube-backend@0.2.19-next.1 + - @backstage/plugin-todo-backend@0.3.16-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-auth-backend-module-github-provider@0.1.14-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.1.11-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.14-next.1 + - @backstage/plugin-permission-common@0.7.13 + +## e2e-test@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.14-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.95-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/cli@0.26.3-next.1 + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/app-defaults@1.5.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/test-utils@1.5.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-techdocs@1.10.4-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## @internal/plugin-todo-list-backend@1.0.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.26.0.md b/docs/releases/v1.26.0.md new file mode 100644 index 0000000000..38665ff7e5 --- /dev/null +++ b/docs/releases/v1.26.0.md @@ -0,0 +1,82 @@ +--- +id: v1.26.0 +title: v1.26.0 +description: Backstage Release v1.26.0 +--- + +These are the release notes for the v1.26.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 + +### Auth Improvements + +All of the main parts of [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution), and its efforts for making backends secure by default, are now in place! Our [BackstageCon lightning talk](https://www.youtube.com/watch?v=qQcVHbXjU2Q&list=FLzNMnHaDkW4h6Dpoi3K-cBQ&index=4) about auth gives some additional context and details. + +- Backstage user tokens issued by the `auth` backend will now have a new `uip` claim. This claim is a separate identity proof that is used internally for limited user identification needs such as cookies or service on-behalf-of tokens, without having to pass through the real user token and its full authorization power. +- Plugin to plugin auth is now properly scoped and backed by a zero-configuration public key signature scheme. We have also added on-behalf-of tokens to carry the user identity safely in upstream requests, thanks to the identity proof mechanism mentioned above. +- Plugins such as TechDocs that need to expose cookie based endpoints now issue their own private plugin scoped cookies by leveraging the same identity proof mechanism, making it impossible to abuse cookies for requests to other plugins that happened to be co-deployed on the same domain. +- Making requests to your backend plugins [from external callers](https://backstage.io/docs/auth/service-to-service-auth) has also been made easier than ever with a new configuration section that, in addition to the legacy service tokens, lets you configure static tokens as well. This system was made extensible so that more auth methods can be added going forward. + +Note that if you have scaled your Backstage deployment to three or more distinct backends, you must take care to update the backend with the most central plugins first, i.e the ones with fewest outbound calls. The new automated plugin service auth does use feature detection to determine the authentication method, but is only able to do so for a single hop. What this means in practice is that if you’re using the permission backend plugin you should update that instance first, followed by the catalog. + +Note also that the plugin service auth system uses the plugin database to store asymmetric keys. This means that any plugin that wants to make requests to other plugins now must have a database (and also accept incoming HTTP requests on the JWKS endpoint). For most adopters this will not require any action since the default setup auto-creates logical databases as needed. But if you have custom or locked-down setups, you may in rare cases encounter the need to create additional plugin databases. + +### App Backend + +The `app-backend` plugin is now able to protect the main application bundle and only serve a limited public bundle to unauthenticated users. This is enabled by adding a `src/index-public-experimental.tsx` entry point to your app package, which will only be used in production builds. This is still an experimental feature, but if you want to know more or try it out, check out the [pull request where it was added](https://github.com/backstage/backstage/pull/23719). + +### New Backend System + +- Modules are no longer loaded unless the associated plugin is present. +- A new initialization option for service factories has been added, allowing service creators to override whether the service is lazily or eagerly initialized. +- The `/api/:pluginId` path is now reserved for plugin traffic and can no longer be configured in the http router service. Requests towards `/api/:pluginId` that don’t match any registered plugin will now return a 404. +- A sweeping change has been made across all plugins to correctly use the `LoggerService` instead of the old Winston logger (Contributed by [@drodil](https://github.com/drodil) in [#24224](https://github.com/backstage/backstage/pull/24224)). For most users this will be transparent, but some users of the old backend system will notice, and will want to remove the winston compatibility wrapper. + +### New Auth Modules + +Several more auth providers have been migrated to be implemented as standalone modules, adding support for them in the [new backend system](https://backstage.io/docs/backend-system/building-backends/migrating#the-auth-plugin). The migrated providers are Cloudflare Access, Azure Easy Auth ([@yaegashi](https://github.com/yaegashi) in [#23909](https://github.com/backstage/backstage/pull/23909)), and Bitbucket ([@pjungermann](https://github.com/pjungermann) in [#24287](https://github.com/backstage/backstage/pull/24287)). If you detect any issues, please reach out on [Discord](https://discord.gg/backstage-687207715902193673) or [open an issue](https://github.com/backstage/backstage/issues). + +### OpenAPI Tooling + +A new lint rule has been added to the `@backstage/repo-tools repo schema openapi lint` command, which enforces that `allowReserved: true` is set for all URL parameters. This is because the default encoding is unnecessarily strict and doesn’t for example permit `+` as an encoding of spaces. + +Two new `fuzz` commands have also been added, for the `repo schema openapi` and `package schema openapi` group for fuzzing plugins. This can help find bugs in your application code through auto-generated schema-compliant inputs. For more information on the underlying library this leverages, take a look at [the docs](https://schemathesis.readthedocs.io/en/stable/index.html). + +### Events System Improvement for the New Backend System + +The events system should now be accessed via a dependency on the exported `eventsServiceRef` instead of the old `EventBroker` and `EventSubscriber` patterns, in the new backend system. Because of this, if you are still on the old backend system, you may note some minor changes in how the GitHub catalog providers are constructed. See the pull request for more details and links to the updated installation instructions. + +Contributed by [@pjungermann](https://github.com/pjungermann) in [#24260](https://github.com/backstage/backstage/pull/24260) + +### Catalog Error Events + +Entity processing errors that happen in the catalog used to be sent to the local logger. This led to sometimes large amounts of noise, and the logs often aren’t easy to inspect in production. In this release, they are instead sent to the events system. If you want to retain the logging behavior, you can do so by subscribing to the topic; see the pull request for details. + +Contributed by [@punkle](https://github.com/punkle) in [#23022](https://github.com/backstage/backstage/pull/23022) + +### Kubernetes Proxy breaking change + +The `KubernetesProxy` now requires the `DiscoveryService` to be passed to its constructor if you are on the old backend system. + +## 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/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.26.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://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.27.0-next.0-changelog.md b/docs/releases/v1.27.0-next.0-changelog.md new file mode 100644 index 0000000000..04ef3c3c2f --- /dev/null +++ b/docs/releases/v1.27.0-next.0-changelog.md @@ -0,0 +1,2064 @@ +# Release v1.27.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.27.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.27.0-next.0) + +## @backstage/catalog-model@1.5.0-next.0 + +### Minor Changes + +- 79025f3: Introduce a domain attribute to the domain entity to allow a hierarchy of domains to exist. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend@1.22.0-next.0 + +### Minor Changes + +- 8d14475: Emit well known relationships for the Domain entity kind. + +### Patch Changes + +- c6cb568: Add lifecycle monitoring for the catalog processing +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.23-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-openapi-utils@0.1.11-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/app-defaults@1.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/backend-app-api@0.7.1-next.0 + +### Patch Changes + +- 4cd5ff0: Add ability to configure the Node.js HTTP Server when configuring the root HTTP Router service +- e8199b1: Move the JWKS registration outside of the lifecycle middleware +- dc8c5dd: The default `TokenManager` implementation no longer requires keys to be configured in production, but it will throw an errors when generating or authenticating tokens. The default `AuthService` implementation will now also provide additional context if such an error is throw when falling back to using the `TokenManager` service to generate tokens for outgoing requests. +- 025641b: Redact `meta` fields too with the logger +- 5863e02: Internal refactor to only create one external token handler +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.5 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/backend-common@0.21.8-next.0 + +### Patch Changes + +- ba0b8b4: Added option to `ServerTokenManager.fromConfig` that allows it to be instantiated in production without any configured keys. +- Updated dependencies + - @backstage/backend-app-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.7.1-next.0 + - @backstage/backend-common@0.21.8-next.0 + +## @backstage/backend-dynamic-feature-service@0.2.10-next.0 + +### Patch Changes + +- b611fd0: Updates the `scanRoot` method in the `PluginScanner` class to specifically ignore the `lost+found` directory, which is a system-generated directory used for file recovery on Unix-like systems. Skipping this directory avoids unnecessary errors. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.22.0-next.0 + - @backstage/backend-app-api@0.7.1-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.5 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.18-next.0 + - @backstage/plugin-events-backend@0.3.5-next.0 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/backend-openapi-utils@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.6.18-next.0 + +### Patch Changes + +- 1fedf0c: Removed explicit `toString()` method from `ServiceRef` type. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/backend-tasks@0.5.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-test-utils@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.7.1-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/catalog-client@1.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.26.5-next.0 + +### Patch Changes + +- fcd3462: Both the target and types library have been bumped from ES2021 to ES2022 in `@backstage/cli/config/tsconfig.json`. +- 0cc5ed3: Add support for `versions:migrate` to do code changes. Can be skipped with `--no-code-changes` +- f97ad04: Add preserveModules to rollup, which allows better async loading and tree-shaking in webpack +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.5 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.7 + - @backstage/integration@1.10.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.5-next.0 + +### Patch Changes + +- 5d99272: Update local development dependencies. +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/version-bridge@1.0.8 + +## @backstage/core-components@0.14.5-next.0 + +### Patch Changes + +- 71e4229: Added optional `initialShowDropDown` prop to `SidebarSubmenuItem` to internally manage the initial display state of the dropdown items. +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.15-next.0 + +### Patch Changes + +- c066c88: Removed `packages/backend/src/types.ts` from the template as it is unused. It was mistakenly left in after moving the template to the new backend system. +- 5d99272: Update local development dependencies. +- 8105aad: Removed the Tech Radar and GitHub Actions plugins from the template, which have been moved to the community plugins repository. +- Updated dependencies + - @backstage/cli-common@0.1.13 + +## @backstage/dev-utils@1.0.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/app-defaults@1.5.5-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + +## @backstage/frontend-app-api@0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-plugin-api@0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.6.5-next.0 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/test-utils@1.5.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/cli-node@0.2.5 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.10-next.0 + +### Patch Changes + +- 1a0e009: Fix cookie endpoint mock for `serve` +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/theme@0.5.4-next.0 + +### Patch Changes + +- f1462df: Fixed bug where scrollbars don't pick up the theme when in dark mode + +## @backstage/plugin-api-docs@0.11.5-next.0 + +### Patch Changes + +- 5d99272: Update local development dependencies. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/plugin-app-backend@0.3.66-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.18-next.0 + +## @backstage/plugin-app-node@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config-loader@1.8.0 + +## @backstage/plugin-app-visualizer@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-auth-backend@0.22.5-next.0 + +### Patch Changes + +- ea9262b: Allow overriding default ownership resolving with the new `AuthOwnershipResolutionExtensionPoint` +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.1.9-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.10-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.1-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.13-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.15-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.15-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.15-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.13-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.15-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.11-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.11-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.22.5-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.4-next.0 + +### Patch Changes + +- 07d8cca: Error if used outside of a development environment without explicit allowance +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.1.9-next.0 + +### Patch Changes + +- dd53bf3: Add nonce to authorize request to be added in ID token +- Updated dependencies + - @backstage/plugin-auth-backend@0.22.5-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-auth-node@0.4.13-next.0 + +### Patch Changes + +- ea9262b: Allow overriding default ownership resolving with the new `AuthOwnershipResolutionExtensionPoint` +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.1-next.0 + +### Patch Changes + +- c297afd: When using `CookieAuthRefreshProvider` or `useCookieAuthRefresh`, a 404 response from the cookie endpoint will now be treated as if cookie auth is disabled and is not needed. +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog@1.19.1-next.0 + +### Patch Changes + +- 5d99272: Update local development dependencies. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration-react@1.1.26 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + +## @backstage/plugin-catalog-backend-module-azure@0.1.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.1-next.0 + +### Patch Changes + +- f3f0281: Fix incorrect dependency import. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-openapi-utils@0.1.11-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.18 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.32-next.0 + +### Patch Changes + +- 062ffb1: Allow skipping archived repositories (`skipArchivedRepos` flag) on Bitbucket. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-catalog-backend-module-github@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.22.0-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-backend-module-github@0.6.1-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.15-next.2 + +### Patch Changes + +- a70377d: Added events support for `GitlabDiscoveryEntityProvider` and `GitlabOrgDiscoveryEntityProvider`. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.0.1-next.0 + +### Patch Changes + +- a70377d: Added a new `catalog-backend-module-gitlab-org` module which adds the `GitlabOrgDiscoveryEntityProvider` to the catalog's providers using the new backend system. +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.3.15-next.2 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.23-next.0 + +### Patch Changes + +- 8c1ab9e: Fix plugin/incremental-ingestion 'Maximum call stack size exceeded' error when ingest large entities. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.22.0-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.22.0-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-catalog-common@1.0.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-catalog-graph@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.10.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + +## @backstage/plugin-catalog-node@1.11.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/plugin-catalog-react@1.11.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration-react@1.1.26 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.55-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/plugin-devtools-backend@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.9 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/plugin-events-backend@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-events-node@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + +## @backstage/plugin-home@0.7.4-next.0 + +### Patch Changes + +- 2196d3e: Use relative time when displaying visits from the same day +- 0040ec2: Updated dependency `@rjsf/utils` to `5.18.2`. + Updated dependency `@rjsf/core` to `5.18.2`. + Updated dependency `@rjsf/material-ui` to `5.18.2`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.2`. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-home-react@0.1.13-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-home-react@0.1.13-next.0 + +### Patch Changes + +- 0040ec2: Updated dependency `@rjsf/utils` to `5.18.2`. + Updated dependency `@rjsf/core` to `5.18.2`. + Updated dependency `@rjsf/material-ui` to `5.18.2`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.2`. +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-kubernetes@0.11.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/plugin-kubernetes-react@0.3.5-next.0 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-kubernetes-backend@0.17.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-kubernetes-node@0.1.12-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/plugin-kubernetes-react@0.3.5-next.0 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-kubernetes-common@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-kubernetes-node@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-kubernetes-react@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-kubernetes-common@0.7.6-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-notifications@0.2.1-next.0 + +### Patch Changes + +- e6bf85f: Allow overriding `NotificationsPage` page properties +- a42a19b: Empty descriptions are not rendered to improve the look&feel. +- 1bc3b86: Fix to show web notifications even when browser is on foreground. Fix duplicate notifications with multiple tabs. +- f793112: Allow defining `className` and additional properties for `NotificationsSideBarItem` +- e1c7d6e: Fix infinite loop in the notification title counter +- fcda449: The rendered size of a notification is limited for very long descriptions. +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-signals-react@0.0.3 + +## @backstage/plugin-notifications-backend@0.2.1-next.0 + +### Patch Changes + +- ee09dfc: Updated documentation for sending messages by external services. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-notifications-node@0.1.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## @backstage/plugin-notifications-node@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## @backstage/plugin-org@0.6.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + +## @backstage/plugin-org-react@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + +## @backstage/plugin-permission-backend@0.5.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + +## @backstage/plugin-permission-node@0.7.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-proxy-backend@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-scaffolder@1.19.4-next.0 + +### Patch Changes + +- 0040ec2: Updated dependency `@rjsf/utils` to `5.18.2`. + Updated dependency `@rjsf/core` to `5.18.2`. + Updated dependency `@rjsf/material-ui` to `5.18.2`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.2`. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-scaffolder-react@1.8.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-react@0.4.22 + +## @backstage/plugin-scaffolder-backend@1.22.5-next.0 + +### Patch Changes + +- 025641b: Fix issue with the log format not being respected when logging from actions +- 025641b: Redact `meta` fields too with the logger +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.2.8-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.8-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.4-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.8-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.16-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.10-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.8-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.8-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.10-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.8-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.8-next.0 + +### Patch Changes + +- 24dd655: Add examples for `publish:bitbucketServer:pull-request` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.8-next.0 + +### Patch Changes + +- 554af73: Allow defining `repoVisibility` field for the action `publish:gitea` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.2.8-next.0 + +### Patch Changes + +- 5d99272: Update local development dependencies. +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.3.4-next.0 + +### Patch Changes + +- ffc73ec: Add examples for `gitlab:repo:push` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.4-next.0 + +## @backstage/plugin-scaffolder-common@1.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-scaffolder-node@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-test-utils@0.3.8-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-react@1.8.5-next.0 + +### Patch Changes + +- 0040ec2: Updated dependency `@rjsf/utils` to `5.18.2`. + Updated dependency `@rjsf/core` to `5.18.2`. + Updated dependency `@rjsf/material-ui` to `5.18.2`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.2`. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-search@1.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## @backstage/plugin-search-backend@1.5.8-next.0 + +### Patch Changes + +- c6cb568: Add lifecycle monitoring for the search index registry +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/repo-tools@0.8.1-next.0 + - @backstage/backend-openapi-utils@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-catalog@0.1.23-next.0 + +### Patch Changes + +- d5fff66: Fix wiring of the module exported at the `/alpha` path, which was causing authentication failures. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-elasticsearch@1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-explore@0.1.23-next.0 + +### Patch Changes + +- ca6e2e0: Migrate search collator to use the new auth services. +- 5d99272: Update README.md to point to explore plugin in community-plugins repository. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-pg@0.5.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-module-techdocs@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-backend-node@1.2.22-next.0 + +### Patch Changes + +- c6cb568: Add lifecycle monitoring for the search index registry +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-search-react@1.7.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-signals@0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.3 + +## @backstage/plugin-signals-backend@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## @backstage/plugin-signals-node@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.4-next.0 + +## @backstage/plugin-techdocs@1.10.5-next.0 + +### Patch Changes + +- d2cc139: Update path in Readme for Plugin Techdocs to show the correct setup information. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.32-next.0 + +### Patch Changes + +- 2f13862: Fix bug in TechDocsAddonTester when jest.resetAllMocks is called between tests +- Updated dependencies + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/plugin-techdocs@1.10.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/test-utils@1.5.5-next.0 + - @backstage/plugin-search-react@1.7.11-next.0 + +## @backstage/plugin-techdocs-backend@1.10.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.23-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-permission-common@0.7.13 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + +## @backstage/plugin-techdocs-node@1.12.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## @backstage/plugin-techdocs-react@1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-user-settings@0.8.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-user-settings-backend@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## example-app@0.2.97-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications@0.2.1-next.0 + - @backstage/plugin-api-docs@0.11.5-next.0 + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/plugin-home@0.7.4-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-techdocs@1.10.5-next.0 + - @backstage/cli@0.26.5-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-scaffolder-react@1.8.5-next.0 + - @backstage/plugin-scaffolder@1.19.4-next.0 + - @backstage/plugin-catalog-graph@0.4.5-next.0 + - @backstage/plugin-catalog-import@0.10.11-next.0 + - @backstage/plugin-devtools@0.1.14-next.0 + - @backstage/plugin-org@0.6.25-next.0 + - @backstage/plugin-search@1.4.11-next.0 + - @backstage/plugin-user-settings@0.8.6-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.4-next.0 + - @backstage/plugin-kubernetes@0.11.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.11-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/app-defaults@1.5.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-app-api@0.6.5-next.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + - @backstage/plugin-signals@0.0.6-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.10-next.0 + +## example-app-next@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications@0.2.1-next.0 + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/plugin-api-docs@0.11.5-next.0 + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/plugin-home@0.7.4-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-techdocs@1.10.5-next.0 + - @backstage/cli@0.26.5-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-scaffolder-react@1.8.5-next.0 + - @backstage/plugin-scaffolder@1.19.4-next.0 + - @backstage/plugin-catalog-graph@0.4.5-next.0 + - @backstage/plugin-catalog-import@0.10.11-next.0 + - @backstage/plugin-org@0.6.25-next.0 + - @backstage/plugin-search@1.4.11-next.0 + - @backstage/plugin-user-settings@0.8.6-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.4-next.0 + - @backstage/plugin-kubernetes@0.11.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.11-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/app-defaults@1.5.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-app-api@0.6.5-next.0 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-app-visualizer@0.1.6-next.0 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + - @backstage/plugin-signals@0.0.6-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.10-next.0 + +## app-next-example-plugin@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/frontend-plugin-api@0.6.5-next.0 + +## example-backend@0.2.98-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.22.0-next.0 + - @backstage/plugin-scaffolder-backend@1.22.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/plugin-search-backend@1.5.8-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.4-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.23-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.23-next.0 + - @backstage/plugin-auth-backend@0.22.5-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - example-app@0.2.97-next.0 + - @backstage/plugin-app-backend@0.3.66-next.0 + - @backstage/plugin-kubernetes-backend@0.17.1-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.16-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.5-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.23-next.0 + - @backstage/plugin-techdocs-backend@1.10.5-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.10.0 + - @backstage/plugin-devtools-backend@0.3.4-next.0 + - @backstage/plugin-events-backend@0.3.5-next.0 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-permission-backend@0.5.42-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-proxy-backend@0.4.16-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.19-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.35-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.4.1-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.27-next.0 + - @backstage/plugin-signals-backend@0.1.4-next.0 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## example-backend-next@0.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.2.8-next.0 + - @backstage/plugin-catalog-backend@1.22.0-next.0 + - @backstage/plugin-scaffolder-backend@1.22.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/plugin-search-backend@1.5.8-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.23-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.1-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.4-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.23-next.0 + - @backstage/plugin-auth-backend@0.22.5-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/plugin-notifications-backend@0.2.1-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.36-next.0 + - @backstage/backend-defaults@0.2.18-next.0 + - @backstage/plugin-app-backend@0.3.66-next.0 + - @backstage/plugin-kubernetes-backend@0.17.1-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.16-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.5-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.23-next.0 + - @backstage/plugin-techdocs-backend@1.10.5-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.15-next.0 + - @backstage/plugin-devtools-backend@0.3.4-next.0 + - @backstage/plugin-permission-backend@0.5.42-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.15-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-proxy-backend@0.4.16-next.0 + - @backstage/plugin-signals-backend@0.1.4-next.0 + +## e2e-test@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.15-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.96-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-techdocs@1.10.5-next.0 + - @backstage/cli@0.26.5-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/app-defaults@1.5.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/test-utils@1.5.5-next.0 + +## @internal/plugin-todo-list@1.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + +## @internal/plugin-todo-list-backend@1.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.5.0-changelog.md b/docs/releases/v1.5.0-changelog.md index 6e4d251ef7..d17aae7d48 100644 --- a/docs/releases/v1.5.0-changelog.md +++ b/docs/releases/v1.5.0-changelog.md @@ -326,7 +326,7 @@ 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. + Then head to the [README in sonarqube-backend plugin page](https://github.com/backstage/backstage/tree/v1.5.0/plugins/sonarqube-backend/README.md) to learn how to set-up the link to your Sonarqube instances. ### Patch Changes diff --git a/docs/releases/v1.5.0-next.1-changelog.md b/docs/releases/v1.5.0-next.1-changelog.md index deedd1dc44..8c8e039541 100644 --- a/docs/releases/v1.5.0-next.1-changelog.md +++ b/docs/releases/v1.5.0-next.1-changelog.md @@ -60,7 +60,7 @@ 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. + Then head to the [README in sonarqube-backend plugin page](https://github.com/backstage/backstage/tree/v1.5.0-next.1/plugins/sonarqube-backend/README.md) to learn how to set-up the link to your Sonarqube instances. ### Patch Changes diff --git a/docs/releases/v1.5.0.md b/docs/releases/v1.5.0.md index d7bbfa62a2..325bee378d 100644 --- a/docs/releases/v1.5.0.md +++ b/docs/releases/v1.5.0.md @@ -32,7 +32,7 @@ This new plugin can be used to display GitHub issues for your entities. Contribu ### 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) +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/v1.5.0/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` diff --git a/docs/releases/v1.6.0-changelog.md b/docs/releases/v1.6.0-changelog.md index 4172c19244..0308c5fd3d 100644 --- a/docs/releases/v1.6.0-changelog.md +++ b/docs/releases/v1.6.0-changelog.md @@ -980,7 +980,7 @@ If you were overriding the `getScorecardsDefinition` method to adjust the rendering of check results, you should now provide a custom renderer using `renderers` parameter in the `TechInsightsClient` class. - See the [README](https://github.com/backstage/backstage/tree/master/plugins/tech-insights/README.md) for more details. + See the [README](https://github.com/backstage/backstage/tree/v1.6.0/plugins/tech-insights/README.md) for more details. ### Patch Changes diff --git a/docs/releases/v1.6.0-next.1-changelog.md b/docs/releases/v1.6.0-next.1-changelog.md index ba5d032ead..3a1dc8f1b7 100644 --- a/docs/releases/v1.6.0-next.1-changelog.md +++ b/docs/releases/v1.6.0-next.1-changelog.md @@ -104,7 +104,7 @@ If you were overriding the `getScorecardsDefinition` method to adjust the rendering of check results, you should now provide a custom renderer using `renderers` parameter in the `TechInsightsClient` class. - See the [README](https://github.com/backstage/backstage/tree/master/plugins/tech-insights/README.md) for more details. + See the [README](https://github.com/backstage/backstage/tree/v1.6.0-next.1/plugins/tech-insights/README.md) for more details. ### Patch Changes diff --git a/docs/releases/v1.8.0-changelog.md b/docs/releases/v1.8.0-changelog.md index 4b36b01abf..54447a3960 100644 --- a/docs/releases/v1.8.0-changelog.md +++ b/docs/releases/v1.8.0-changelog.md @@ -872,7 +872,7 @@ - f1c3cdfb2d: Bumped create-app version. -- df21bbd4ad: The [Analytics API](https://backstage.io/docs/plugins/analytics) is the recommended way to track usage in Backstage; an optionally installable [Google Analytics module](https://github.com/backstage/backstage/tree/master/plugins/analytics-module-ga#installation) has superseded the old app.googleAnalyticsTrackingId config and its corresponding script tags in packages/app/public/index.html. +- df21bbd4ad: The [Analytics API](https://backstage.io/docs/plugins/analytics) is the recommended way to track usage in Backstage; an optionally installable [Google Analytics module](https://github.com/backstage/backstage/tree/v1.8.0/plugins/analytics-module-ga#installation) has superseded the old app.googleAnalyticsTrackingId config and its corresponding script tags in packages/app/public/index.html. For an existing installation where you want to remove the redundant app.googleAnalyticsTrackingId, you should make the following adjustment to `packages/app/public/index.html`: diff --git a/docs/releases/v1.8.0.md b/docs/releases/v1.8.0.md index 78cc5ab7cd..eb7857dc6c 100644 --- a/docs/releases/v1.8.0.md +++ b/docs/releases/v1.8.0.md @@ -32,7 +32,7 @@ Contributed by [@atoko](https://github.com/atoko) in [#14056](https://github.com ### Azure Sites -There's a new Azure Sites (Apps & Functions) plugin. It lets you view the current status of the site, and quickly jump to the site's Overview or Log Stream pages. Please check out [the plugin README](https://github.com/backstage/backstage/tree/master/plugins/azure-sites) for more information. +There's a new Azure Sites (Apps & Functions) plugin. It lets you view the current status of the site, and quickly jump to the site's Overview or Log Stream pages. Please check out [the plugin README](https://github.com/backstage/backstage/tree/v1.8.0/plugins/azure-sites) for more information. Contributed by [@wesley-pattison](https://github.com/wesley-pattison) in [#13634](https://github.com/backstage/backstage/pull/13634) diff --git a/docs/releases/v1.9.0-changelog.md b/docs/releases/v1.9.0-changelog.md index 07451f6d2c..f5b809522d 100644 --- a/docs/releases/v1.9.0-changelog.md +++ b/docs/releases/v1.9.0-changelog.md @@ -785,7 +785,7 @@ - isSonarQubeAvailable - SONARQUBE_PROJECT_KEY_ANNOTATION - Exports that been introduced to plugin-sonarqube-react are documented in the [API report](https://github.com/backstage/backstage/blob/master/plugins/sonarqube-react/api-report.md). + Exports that been introduced to plugin-sonarqube-react are documented in the [API report](https://github.com/backstage/backstage/blob/v1.9.0/plugins/sonarqube-react/api-report.md). ### Patch Changes @@ -820,7 +820,7 @@ - isSonarQubeAvailable - SONARQUBE_PROJECT_KEY_ANNOTATION - Exports that been introduced to plugin-sonarqube-react are documented in the [API report](https://github.com/backstage/backstage/blob/master/plugins/sonarqube-react/api-report.md). + Exports that been introduced to plugin-sonarqube-react are documented in the [API report](https://github.com/backstage/backstage/blob/v1.9.0/plugins/sonarqube-react/api-report.md). ### Patch Changes @@ -1299,7 +1299,7 @@ - d3fea4ae0a: Internal fixes to avoid implicit usage of globals - 3280711113: Updated dependency `msw` to `^0.49.0`. - 9516b0c355: Added support for sending virtual pageviews on `search` events in order to enable - Site Search functionality in GA. For more information consult [README](https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md#enabling-site-search) + Site Search functionality in GA. For more information consult [README](https://github.com/backstage/backstage/blob/v1.9.0/plugins/analytics-module-ga/README.md#enabling-site-search) - Updated dependencies - @backstage/core-plugin-api@1.2.0 - @backstage/core-components@0.12.1 @@ -2023,7 +2023,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. @@ -2047,7 +2047,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. @@ -2065,7 +2065,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. @@ -2079,7 +2079,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. diff --git a/docs/releases/v1.9.0-next.1-changelog.md b/docs/releases/v1.9.0-next.1-changelog.md index 862734131a..0716dba0cd 100644 --- a/docs/releases/v1.9.0-next.1-changelog.md +++ b/docs/releases/v1.9.0-next.1-changelog.md @@ -1133,7 +1133,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0-next.1/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. @@ -1157,7 +1157,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0-next.1/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. @@ -1175,7 +1175,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0-next.1/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. @@ -1187,7 +1187,7 @@ - 4dec6f16be: Added new `@backstage/plugin-explore-backend` & `@backstage/plugin-explore-common` packages. - This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/master/plugins/explore-backend/README.md) for full details. + This deprecates the `ExploreToolsConfig` API (in `@backstage/plugin-explore-react`) which is replaced by the `ExploreApi` & `ExploreClient`. The list of `ExploreTool` data can now be provided on the backend by either using the supplied `StaticExploreToolProvider` or by implementing a custom `ExploreToolProvider`. See the [explore-backend README](https://github.com/backstage/backstage/blob/v1.9.0-next.1/plugins/explore-backend/README.md) for full details. NOTE: Existing installations that have customized the `ExploreToolConfig` will continue to work through the new `ExploreClient`. However, existing data should be migrated over to new `explore-backend` plugin as `ExploreToolConfig` will be removed in the future. diff --git a/docs/releases/v1.9.0-next.2-changelog.md b/docs/releases/v1.9.0-next.2-changelog.md index 2c6d495641..65c3b43b24 100644 --- a/docs/releases/v1.9.0-next.2-changelog.md +++ b/docs/releases/v1.9.0-next.2-changelog.md @@ -525,7 +525,7 @@ ### Patch Changes - 9516b0c355: Added support for sending virtual pageviews on `search` events in order to enable - Site Search functionality in GA. For more information consult [README](https://github.com/backstage/backstage/blob/master/plugins/analytics-module-ga/README.md#enabling-site-search) + Site Search functionality in GA. For more information consult [README](https://github.com/backstage/backstage/blob/v1.9.0-next.2/plugins/analytics-module-ga/README.md#enabling-site-search) - Updated dependencies - @backstage/core-plugin-api@1.2.0-next.2 - @backstage/core-components@0.12.1-next.2 diff --git a/docs/tutorials/auth-service-migration.md b/docs/tutorials/auth-service-migration.md new file mode 100644 index 0000000000..9e2633a12a --- /dev/null +++ b/docs/tutorials/auth-service-migration.md @@ -0,0 +1,318 @@ +--- +id: auth-service-migration +title: Migrating to New Auth Services +description: A guide for how to migrate Backstage backend plugins and modules to use the new auth services +--- + +The auth services for the Backstage backend system have been reworked in the 1.24 release. Among other improvements, this brings protection by default for Backstage backends, replacing the [authenticate-api-requests.md](https://github.com/backstage/backstage/blob/9aac2b0d36bdb8095ea747fe5e5490cfea1c9f16/contrib/docs/tutorials/authenticate-api-requests.md) guide in contrib. This guide will help you migrate your existing backend setup as well as backend _plugins and modules_ to use the new auth services. + +The change with the most impact that accompanies the new auth services is the default behavior of all plugins running in the new backend system to block all requests that are not authenticated as a user or service, also known as the _default auth policy_. This is the only breaking production change introduced as part of this update, and may require action to be taken on both backend installations and plugins. More on that in the individual sections below. + +## Backend migration + +In order to use these new services your backend needs to be using the [new backend system](../backend-system/building-backends/01-index.md). If your backend is running the old system, you will need to [migrate it to the new system first](../backend-system/building-backends/08-migrating.md). + +If you have [authenticate-api-requests.md](https://github.com/backstage/backstage/blob/9aac2b0d36bdb8095ea747fe5e5490cfea1c9f16/contrib/docs/tutorials/authenticate-api-requests.md) installed in your backend, you should generally remove it and rely on the new auth services instead. If you do not wish to make that change yet but still want to upgrade to the latest release of Backstage, you can also leave it in place and instead disable the default auth policy as described in the next section. + +### Disabling the default auth policy + +If you do not want to enforce authentication of requests by default, you can disable the default auth policy. This is done using the following configuration: + +```yaml +backend: + auth: + dangerouslyDisableDefaultAuthPolicy: true +``` + +In short, this will allow requests through to plugins in your backend, even if they do not include any credentials. The requests will still be treated as unauthenticated however, which not all plugin endpoints may accept. For more information on the impact of this configuration, see the [auth service documentation](../backend-system/core-services/auth.md). + +### Migrating the backend + +If you do want to keep the default auth policy in effect, there is some minor action needed to migrate the backend itself. Be sure to upgrade all plugins to their latest versions to pick up any updates that may be needed for the new auth services. If you have any internal plugins or modules, refer to the plugin migration section below. + +With the default auth policy in effect you will now need to ensure that the requests to your backend are authenticated, also during local development. If you already have a setup where you use an auth provider for local development, you can keep using that. But, if you rely on the `'guest'` access for local development we recommend that you install the new guest provider module in your auth backend: + +```sh +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-guest-provider +``` + +Add it to your backend: + +```ts title="packages/backend/src/index.ts" +// highlight-add-next-line +backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); +``` + +Lastly, add the following to your development configuration: + +```yaml +auth: + providers: + guest: {} +``` + +Make sure that you only enable the guest provider for local development, and not in production. It will refuse to be enabled in production by default, but it is still best to avoid it entirely. If you do not have a separate development configuration, add the following to your production configuration: + +```yaml +auth: + providers: + guest: null +``` + +If you still want to enable guest login in non-development environments, you can use this config snippet: + +```yaml +auth: + providers: + guest: + dangerouslyAllowOutsideDevelopment: true +``` + +That's all you need for guest authentication! The default `SignInPage` from `@backstage/core-components` will detect and use the guest provider if it's enabled. + +Since the default auth policy is in effect for all plugins running in the new backend system, you do not need to worry about whether individual plugins are protected or not. The impact of plugins not yet being migrated is that they may have endpoints that should allow unauthenticated requests, but are now blocked by the default auth policy. If you want to temporarily work around this for individual plugins, you can install a module for the plugin that adds the required policy via the [http router service](../backend-system/core-services/http-router.md). + +If you have a custom [identity](../backend-system/core-services/identity.md) or [token manager](../backend-system/core-services/token-manager.md) service implementations you can use the `createLegacyAuthAdapters` helper from `@backstage/backend-common` to adapt them for the new auth services. + +## Plugin & Module migration + +This part of the guide will help you migrate your backend plugin or module to using the new auth APIs. It is split into two main sections: the first is to add any required auth policies to your plugin for the new backend system, and the second is to migrate to use the new auth services. This first step more urgent and may be required for your plugin to keep functioning in the new backend system, while the second step is less urgent and won't be required until support for the old auth services is removed. + +### Adding auth policies + +If your plugin supports the [new backend system](../backend-system/index.md) you may need to add exceptions to the default auth policy. If your plugins is supposed to accept unauthenticated requests or requests authenticated with a user cookie, then you need to add a policy for that. This is done using the `httpRouter` service. For example, the following allows unauthenticated requests to the `/health` endpoint: + +```ts +export default createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + config: coreServices.rootConfig, + logger: coreServices.logger, + httpRouter: coreServices.httpRouter, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + }, + async init({ config, logger, httpRouter, auth, httpAuth }) { + httpRouter.use(await createRouter({ config, logger, auth, httpAuth })); + + // highlight-add-start + httpRouter.addAuthPolicy({ + path: '/health', + allow: 'unauthenticated', + }); + // highlight-add-end + }, + }); + }, +}); +``` + +### Using the new auth services + +The goal in this section is to completely remove usages of the existing [identity](../backend-system/core-services/identity.md) and [token manager](../backend-system/core-services/token-manager.md) services from inside your plugin, and instead use the new [auth](../backend-system/core-services/auth.md) and [http auth](../backend-system/core-services/http-auth.md) services. You plugin may still accept the `identity` and `tokenManager` services as optional dependencies from the plugin environment though, in order to avoid breaking the setup for existing users. + +If your plugin does not currently rely on the `identity` or `tokenManager` services or uses the `DefaultIdentityClient` internally, then this step is not required and no further action is needed. + +This guide assumes that your plugin uses the `createRouter` pattern as its external API for the old backend system. If you have different and/or other external API surfaces they should be treated in the same way, but you may need to adapt these examples to fit your implementation. + +#### Updating dependencies in the new backend system + +If your plugin supports the new backend system, the first step of the migration is to make sure that we use the new auth services. For now we will add both `AuthService` and `HttpAuthService`, but it may be that you only need one of them in the end, in which case you can remove the other. + +```ts +export default createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + config: coreServices.rootConfig, + logger: coreServices.logger, + discovery: coreServices.discovery, + httpRouter: coreServices.httpRouter, + // highlight-remove-start + identity: coreServices.identity, + tokenManager: coreServices.tokenManager, + // highlight-remove-end + // highlight-add-start + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + // highlight-add-end + }, + async init({ + config, + logger, + discovery, + httpRouter, + // highlight-remove-start + identity, + tokenManager, + // highlight-remove-end + // highlight-add-start + auth, + httpAuth, + // highlight-add-end + }) { + const router = await createRouter({ + config, + logger, + discovery, + // highlight-remove-start + identity, + tokenManager, + // highlight-remove-end + // highlight-add-start + auth, + httpAuth, + // highlight-add-end + }); + httpRouter.use(); + }, + }); + }, +}); +``` + +Don't worry if your plugin doesn't currently depend on the `identity` or `tokenManager` service, that can be ignored. However, if your plugin doesn't already depend on the `discovery` service you will need to add that as a required dependence, as it is needed for the compatibility layer that we will introduce. + +#### Making the new auth services available in `createRouter` + +In order to make the new auth services available to the plugin implementation in a backwards compatible way, we use the `createLegacyAuthAdapters` helper from `@backstage/backend-common`. This helper accepts both the old and new auth services, and returns implementations for the new ones. If provided with implementations for the new services it will pass them through directly, which is what we want for the new backend system. If the new services are not provide it will instead create fallback implementations using the old services, falling back to default implementations of the old services if they are not available either. + +In practice, this is what it might look like to apply this change to the `createRouter` function: + +```ts +export interface RouterOptions { + config: RootConfigService; + logger: LoggerService; + discovery: DiscoveryService; + identity?: IdentityService; + // highlight-add-start + auth?: AuthService; + httpAuth?: HttpAuthService; + // highlight-add-end +} + +export function createRouter(options: RouterOptions) { + // highlight-add-next-line + const { auth, httpAuth } = createLegacyAuthAdapters(options); + + // ... the rest of the implementation +} +``` + +Note that if your `createRouter` function doesn't already accept the `identity` or `tokenManager` services, you should **not** add them. Likewise, if there is any default implementation used by your plugin for either of those services, then that implementation **must** be passed on to `createLegacyAuthAdapters`. Both of these constraints ensure that your plugin will continue to behave in the same way as before. + +As mentioned earlier, you may end up not needing both `auth` and `httpAuth` in the implementation. If that is the case you should remove the unused one from the router options. + +#### Replacing old auth service calls + +Once the `auth` and `httpAuth` services are available in the plugin implementation, what's left is to replace existing usage of the `identity` and `tokenManager` services. In this section we'll walk through and explain the most common usages of the existing services, and how to migrate those to use the new services instead. + +##### Example 1: Making a standalone service-to-service request + +To generate a new service token for a service-to-service request that is not in a request path or needs elevated privileges, you would previously use the following: + +```ts +const { token } = await tokenManager.getToken(); +``` + +The equivalent using the new auth services is the following: + +```ts +const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: '<plugin-id>', // e.g. 'catalog' +}); +``` + +The `onBehalfOf` option provides the credentials we want to use for the request. Here we use the plugin's own credentials, but in other places you'll see how it is also used to forward the credentials from incoming requests. + +The `targetPluginId` is a new requirement that allows for a more fine-grained control of service-to-service auth. When generating a new token for a service-to-service request, you must now specify the ID of the plugin that you want to make the request towards. + +##### Example 2: Forwarding credentials from an incoming request + +Reading the credentials from an incoming request typically looked like this: + +```ts +router.get('/example/:entityRef', async (req, _res) => { + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + + // Some followup call using the token, for example using the catalog client + const entity = await catalogClient.getEntityByRef(req.params.entityRef, { + token, + }); + + // Or forwarding the token to evaluate permissions + await permissions.authorize( + [{ permission: examplePermission, resourceRef: entityRef }], + { token }, + ); +}); +``` + +The new auth services intentionally add an additional step to this process, in order to avoid direct forwarding of both user and service tokens in upstream requests. You now instead first extract the credentials from the incoming requests, and then use those credentials to generate new tokens for upstream requests. + +With the new auth services, the above example now looks like this: + +```ts +router.get('/example/:entityRef', async (req, _res) => { + const credentials = await httpAuth.credentials(req); + + // The catalog client only accepts tokens right now, it will be updated + // to accept credentials directly in the future. + // For now we will need to issue a new token to pass to the catalog client. + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + const entity = await catalogClient.getEntityByRef(req.params.entityRef, { + token, + }); + + // The permissions service accepts credentials directly + await permissions.authorize( + [{ permission: examplePermission, resourceRef: entityRef }], + { credentials }, + ); +}); +``` + +Note that for the above `permissions` call to work you will need to update your plugin to depend on the `PermissionsService` from `@backstage/backend-plugin-api`, rather than `PermissionEvaluator`. + +As a general pattern you will want to refactor your plugin so that it forwards the `BackstageCredentials` objects as far as possible, only generating tokens immediately before they are used. + +##### Example 3: Getting the user identity from a request + +To get the user identity from an incoming request you would previously use the `identity` service: + +```ts +router.get('/example/by-user', async (req, _res) => { + const user = await identity.getIdentity({ request: req }); + + if (!user) { + throw new AuthenticationError(); + } + + console.log(`User ${user.identity.userEntityRef} is making a request`); +}); +``` + +The equivalent using the new auth services is the following: + +```ts +router.get('/example/by-user', async (req, _res) => { + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); + + console.log( + `User ${credentials.principal.userEntityRef} is making a request`, + ); +}); +``` + +In the above code the `allow` option of the `credentials` call is used to narrow down the accepted user credentials. If the incoming requests is not authenticated as a user, the `credentials` call will throw an error. + +If your existing code do not require an authenticated user but only uses it if available, you can instead pass `allow: ['user', 'service', 'none']` to the `credentials` call and then check the `credentials.principal.type`. diff --git a/docs/tutorials/enable-public-entry.md b/docs/tutorials/enable-public-entry.md new file mode 100644 index 0000000000..6282f66418 --- /dev/null +++ b/docs/tutorials/enable-public-entry.md @@ -0,0 +1,102 @@ +--- +id: enable-public-entry +title: Enabling a public entry point +description: A guide for how to experiment with public and protected Backstage app bundles +--- + +# Enable Public Entry (Experimental) + +In this tutorial, you will learn how to restrict access to your main Backstage app bundle to authenticated users only. + +It is expected that the protected bundle feature will be refined in future development iterations, but for now, here is a simplified explanation of how it works: + +Your Backstage app bundle is split into two code entries: + +- Public entry point containing login pages; +- There is also a protected main entry point that contains the code for what you see after signing in. + +With that, Backstage's cli and backend will detect public entry point and serve it to unauthenticated users, while serving the main, protected entry point only to authenticated users. + +## Requirements + +- The app needs to be served by the `app-backend` plugin, or this won't work; +- Also it will only work for those using `backstage-cli` to build and serve their Backstage app. + +## Step-by-step + +1. Create a `index-public-experimental.tsx` in your app `src` folder. + :::note + The filename is a convention, so it is not currently configurable. + ::: + +2. This file is the public entry point for your application, and it should only contain what unauthenticated users should see: + + ```tsx title="in packages/app/src/index-public-experimental.tsx" + import React from 'react'; + import ReactDOM from 'react-dom/client'; + import { createApp } from '@backstage/app-defaults'; + import { AppRouter } from '@backstage/core-app-api'; + import { + AlertDisplay, + OAuthRequestDialog, + SignInPage, + } from '@backstage/core-components'; + import { + configApiRef, + discoveryApiRef, + createApiFactory, + } from '@backstage/core-plugin-api'; + import { CookieAuthRedirect } from '@backstage/plugin-auth-react'; + + // Notice that this is only setting up what is needed by the sign-in pages + const app = createApp({ + // If you have any custom APIs that your sign-in page depends on, you need to add them here + apis: [], + components: { + SignInPage: props => { + return ( + <SignInPage + {...props} + providers={['guest']} + title="Select a sign-in method" + /> + ); + }, + }, + }); + + const App = app.createRoot( + <> + <AlertDisplay transientTimeoutMs={2500} /> + <OAuthRequestDialog /> + <AppRouter> + {/* This component triggers an authenticated redirect to the main app, while staying on the same URL */} + <CookieAuthRedirect /> + </AppRouter> + </>, + ); + + ReactDOM.createRoot(document.getElementById('root')!).render(<App />); + ``` + + :::note + The frontend will handle cookie refreshing automatically, so you don't have to worry about it. + ::: + +3. Let's verify that everything is working locally. From your project root folder, run the following commands to build the app and start the backend: + + ```sh + # building the app package + yarn workspace app start + # starting the backend api + yarn start-backend + ``` + +4. Visit http://localhost:7007 to see the public app and validate that the _index.html_ response only contains a minimal application. + :::note + Regular app serving will always serve protected apps without authenticating. + ::: + +5. Finally, as soon as you log in, you will be redirected to the main app home page (inspect the page and see that the protected bundle was served from the app backend after the redirect). + +That's it! diff --git a/docs/tutorials/setup-opentelemetry.md b/docs/tutorials/setup-opentelemetry.md index aa96e2ad40..976ba4ccfb 100644 --- a/docs/tutorials/setup-opentelemetry.md +++ b/docs/tutorials/setup-opentelemetry.md @@ -24,16 +24,18 @@ yarn --cwd packages/backend add @opentelemetry/sdk-node \ ## Configure -In your `packages/backend/src` folder, create an `instrumentation.ts` file. +In your `packages/backend` folder, create an `instrumentation.js` file. ```typescript -import { NodeSDK } from '@opentelemetry/sdk-node'; -import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node'; -import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; -import { +const { NodeSDK } = require('@opentelemetry/sdk-node'); +const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node'); +const { + getNodeAutoInstrumentations, +} = require('@opentelemetry/auto-instrumentations-node'); +const { PeriodicExportingMetricReader, ConsoleMetricExporter, -} from '@opentelemetry/sdk-metrics'; +} = require('@opentelemetry/sdk-metrics'); const sdk = new NodeSDK({ traceExporter: new ConsoleSpanExporter(), @@ -46,23 +48,47 @@ const sdk = new NodeSDK({ sdk.start(); ``` -In the `index.ts`, import this file **at the beginning**: - -```typescript -import './instrumentation'; // Setup the OpenTelemetry instrumentation - -// other imports and backend init... -``` +You probably won't need all of the instrumentation inside `getNodeAutoInstrumentations()` so make sure to +check the [documentation](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) and tweak it properly. It's important to setup the NodeSDK and the automatic instrumentation **before** importing any library. +This is why we will use the nodejs [`--require`](https://nodejs.org/api/cli.html#-r---require-module) +flag when we start up the application. + +In your `Dockerfile` add the `--require` flag which points to the `instrumentation.js` file + +```Dockerfile + +# We need the instrumentation file inside the Docker image so we can use it with --require +// highlight-add-next-line +COPY --chown=node:node packages/backend/instrumentation.js ./ + +// highlight-remove-next-line +CMD ["node", "packages/backend", "--config", "app-config.yaml"] +// highlight-add-next-line +CMD ["node", "--require", "./instrumentation.js", "packages/backend", "--config", "app-config.yaml"] +``` + ## Run Backstage +The above configuration will only work in production once your start a Docker container from the image. + +To be able to test locally you can import the `./instrumentation.js` file at the top (before all imports) of your backend `index.ts` file + +```ts +import '../instrumentation.js' +// Other imports +... +``` + You can now start your Backstage instance as usual, using `yarn dev`. When the backend is started, you should see in your console traces and metrics emitted by OpenTelemetry. -Of course in production you probably won't use the console exporters but instead send traces and metrics to an OpenTelemetry Collector using [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/). +Of course in production you probably won't use the console exporters but instead send traces and metrics to an OpenTelemetry Collector or other exporter using [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/). + +If you need to disable/configure some OpenTelemetry feature there are lots of [environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) which you can tweak. ## References diff --git a/docs/tutorials/yarn-migration.md b/docs/tutorials/yarn-migration.md index 204829b093..bc5980b2f5 100644 --- a/docs/tutorials/yarn-migration.md +++ b/docs/tutorials/yarn-migration.md @@ -41,7 +41,7 @@ And this to `.dockerignore`: Let's move on to the actual installation. We'd recommend making separate Git commits of most of these steps, in case you need to go back and debug anything. To install Yarn 3, run the following command in the project root: ```bash -yarn set version stable +yarn set version 3.x ``` We'll need the Yarn workspace tools plugin later on, so let's install that too: diff --git a/knexfile.js b/knexfile.js new file mode 100644 index 0000000000..d7c91e0348 --- /dev/null +++ b/knexfile.js @@ -0,0 +1,39 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// To create a new migration in a plugin, run: +// +// yarn workspace <package> knex migrate:make <name_with_underscores> +// +// for example: +// +// yarn workspace @backstage/plugin-catalog-backend knex migrate:make add_feature_foo +// +// This creates a file similar to +// +// plugins/catalog-backend/migrations/20240206160252_add_feature_foo.js + +module.exports = { + client: 'better-sqlite3', + connection: ':memory:', + useNullAsDefault: true, + migrations: { + // unfortunately this needs to be relative to the TARGET, not this file, and + // it just so happens to work to make it go up two steps due to our repo + // layout + stub: '../../scripts/templates/knex-migration.stub.js', + }, +}; diff --git a/lighthouserc.js b/lighthouserc.js index 70136ee158..49595068ca 100644 --- a/lighthouserc.js +++ b/lighthouserc.js @@ -52,7 +52,7 @@ module.exports = { outputPath: './.lighthouseci/reports', preset: 'desktop', }, - startServerCommand: 'yarn dev', + startServerCommand: 'yarn start:lighthouse', startServerReadyPattern: 'webpack compiled successfully', startServerReadyTimeout: 600000, numberOfRuns: 1, diff --git a/microsite/README.md b/microsite/README.md index 26c25dc175..5bd20254b6 100644 --- a/microsite/README.md +++ b/microsite/README.md @@ -233,3 +233,9 @@ Full documentation can be found on the [Docusaurus website](https://docusaurus.i - `highlight-remove-next-line` - `highlight-remove-start` - `highlight-remove-end` + +## Feedback widget + +A feedback widget is provided by the `docusaurus-pushfeedback` plugin, which connects to the https://pushfeedback.com service. Styling of the button is configured in `microsite/src/theme/customTheme.scss`, while the plugin itself is configured in `microsite/docusaurus.config.js`. + +Feedback submissions are connected to an account owned by @Rugvip and are available on request, reach out to @Rugvip on [Discord](https://discord.gg/backstage-687207715902193673). diff --git a/microsite/blog/2020-04-06-lighthouse-plugin.mdx b/microsite/blog/2020-04-06-lighthouse-plugin.mdx index d94ec8bd8d..0027d0521c 100644 --- a/microsite/blog/2020-04-06-lighthouse-plugin.mdx +++ b/microsite/blog/2020-04-06-lighthouse-plugin.mdx @@ -33,7 +33,7 @@ Trigger an audit directly from Backstage, or trigger audits programmatically wit ## Using Lighthouse in Backstage -To learn how you can enable Lighthouse auditing within Backstage, head over to the [README](https://github.com/backstage/backstage/tree/master/plugins/lighthouse) for the plugin to get started. +To learn how you can enable Lighthouse auditing within Backstage, head over to the [README](https://github.com/backstage/community-plugins/tree/main/workspaces/lighthouse/plugins/lighthouse) for the plugin to get started. ## A personal note diff --git a/microsite/blog/2020-05-22-phase-2-service-catalog.mdx b/microsite/blog/2020-05-22-phase-2-service-catalog.mdx index 3b556bbd3d..81c99c7c07 100644 --- a/microsite/blog/2020-05-22-phase-2-service-catalog.mdx +++ b/microsite/blog/2020-05-22-phase-2-service-catalog.mdx @@ -40,7 +40,7 @@ On top of that, we have found that the service catalog is a great way to organis ![img](assets/20-05-20/tabs.png) -More concretely, having this structure in place will allow plugins such as [CircleCI](https://github.com/backstage/backstage/tree/master/plugins/circleci) to show only the builds for the specific service you are viewing, or a [Spinnaker](https://github.com/backstage/backstage/issues/631) plugin to show running deployments, or an Open API plugin to [show documentation](https://github.com/backstage/backstage/issues/627) for endpoints exposed by the service, or the [Lighthouse](https://github.com/backstage/backstage/tree/master/plugins/lighthouse) plugin to show audit reports for your website. You get the point. +More concretely, having this structure in place will allow plugins such as [CircleCI](https://github.com/backstage/backstage/tree/master/plugins/circleci) to show only the builds for the specific service you are viewing, or a [Spinnaker](https://github.com/backstage/backstage/issues/631) plugin to show running deployments, or an Open API plugin to [show documentation](https://github.com/backstage/backstage/issues/627) for endpoints exposed by the service, or the [Lighthouse](https://github.com/backstage/community-plugins/tree/main/workspaces/lighthouse/plugins/lighthouse) plugin to show audit reports for your website. You get the point. ## Timeline diff --git a/microsite/blog/2020-08-05-announcing-backstage-software-templates.mdx b/microsite/blog/2020-08-05-announcing-backstage-software-templates.mdx index b8f787d630..af606dc8da 100644 --- a/microsite/blog/2020-08-05-announcing-backstage-software-templates.mdx +++ b/microsite/blog/2020-08-05-announcing-backstage-software-templates.mdx @@ -7,7 +7,7 @@ authorURL: https://twitter.com/stalund **TL;DR** Today we are announcing a new Backstage feature: Software Templates. Simplify setup, standardize tooling, and deploy with the click of a button. Using automated templates, your engineers can spin up a new microservice, website, or other software component with your organization’s best practices built-in, right from the start. <video width="100%" height="100%" controls> - <source src="/blog/assets/2020-08-05/feature.mp4" type="video/mp4" /> + <source src="/video/software-templates.mp4" type="video/mp4" /> </video> {/* truncate */} diff --git a/microsite/blog/2020-09-30-plugin-marketplace.mdx b/microsite/blog/2020-09-30-plugin-marketplace.mdx index 2f74b0200e..f97c744263 100644 --- a/microsite/blog/2020-09-30-plugin-marketplace.mdx +++ b/microsite/blog/2020-09-30-plugin-marketplace.mdx @@ -34,7 +34,7 @@ This grand vision is actually not that far off. Already today there is a growing Not all plugins you need will be open source. Every company has their own homegrown tooling. Building internal plugins lets you tailor your version of Backstage to be a perfect fit for your infrastructure and software development needs. If you end up [building plugins](https://backstage.io/docs/plugins/create-a-plugin) that could be useful for other companies, please consider releasing them as open source and [add them to the Marketplace](https://backstage.io/docs/plugins/add-to-marketplace). -If you start developing a plugin that you aim to release as open source, we suggest that you create a [new plugin Issue](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME). This helps the community know what plugins are in development and opens up opportunities for collaboration. You can also use this process if you have an idea for a good plugin, but you need help building it. +If you start developing a plugin that you aim to release as open source, we suggest that you create a [new plugin Issue on the community plugins repo](https://github.com/backstage/community-plugins/issues/new/choose). This helps the community know what plugins are in development and opens up opportunities for collaboration. You can also use this process if you have an idea for a good plugin, but you need help building it. We are really excited to see all the amazing plugins that have already been built, and look forward to seeing even more ideas and collaboration as the Backstage community continues to grow. diff --git a/microsite/blog/2020-10-22-cost-insights-plugin.mdx b/microsite/blog/2020-10-22-cost-insights-plugin.mdx index 98bca88477..1ffddd3303 100644 --- a/microsite/blog/2020-10-22-cost-insights-plugin.mdx +++ b/microsite/blog/2020-10-22-cost-insights-plugin.mdx @@ -5,7 +5,7 @@ author: Janisa Anandamohan, Spotify authorURL: https://twitter.com/janisa_a --- -How did Spotify save millions on cloud costs within a matter of months?? We made cost optimization just another part of the daily development process. Our newly open sourced [Cost Insights plugin](https://github.com/backstage/backstage/tree/master/plugins/cost-insights) makes a team’s cloud costs visible — and actionable — right inside Backstage. So engineers can see the impact of their cloud usage (down to a product and resource level) and make optimizations wherever and whenever it makes sense. By managing cloud costs from the ground up, you can make smarter decisions that let you continue to build and scale quickly, without wasting resources. +How did Spotify save millions on cloud costs within a matter of months?? We made cost optimization just another part of the daily development process. Our newly open sourced [Cost Insights plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/cost-insights/plugins/cost-insights) makes a team’s cloud costs visible — and actionable — right inside Backstage. So engineers can see the impact of their cloud usage (down to a product and resource level) and make optimizations wherever and whenever it makes sense. By managing cloud costs from the ground up, you can make smarter decisions that let you continue to build and scale quickly, without wasting resources. <iframe width="780" @@ -67,7 +67,7 @@ Engineers can then determine for themselves if the time invested in an optimizat ## Getting started -You can begin working with the Cost Insights plugin today on [GitHub](https://github.com/backstage/backstage/tree/master/plugins/cost-insights). We include an example client with static data in the expected format. The `CostInsightsApi` should talk with a cloud billing backend that aggregates billing data from your cloud provider. +You can begin working with the Cost Insights plugin today on [GitHub](https://github.com/backstage/community-plugins/tree/main/workspaces/cost-insights/plugins/cost-insights). We include an example client with static data in the expected format. The `CostInsightsApi` should talk with a cloud billing backend that aggregates billing data from your cloud provider. The current release of Cost Insights includes: @@ -84,4 +84,4 @@ And if you’re interested in contributing to our outstanding issues, you can fi ## Ready for DevSecCostOpsPlus (and whatever’s next) -There’s DevOps, there’s DevSecOps, and then there’s Backstage: one frontend for all your infrastructure. From building, testing, and deploying to monitoring and security — Backstage helps you manage your entire tech organization and provides a seamless developer experience for engineers, from end to end to end. And now that also extends to cost management for your cloud infrastructure and tooling. Happy building and [happy optimizing](https://github.com/backstage/backstage/tree/master/plugins/cost-insights). +There’s DevOps, there’s DevSecOps, and then there’s Backstage: one frontend for all your infrastructure. From building, testing, and deploying to monitoring and security — Backstage helps you manage your entire tech organization and provides a seamless developer experience for engineers, from end to end to end. And now that also extends to cost management for your cloud infrastructure and tooling. Happy building and [happy optimizing](https://github.com/backstage/community-plugins/tree/main/workspaces/cost-insights/plugins/cost-insights). diff --git a/microsite/blog/2024-02-28-security-notice.mdx b/microsite/blog/2024-02-28-security-notice.mdx new file mode 100644 index 0000000000..6d174bdb3c --- /dev/null +++ b/microsite/blog/2024-02-28-security-notice.mdx @@ -0,0 +1,24 @@ +--- +title: 'CVE-2024-26150: Keeping Backstage safe and secure' +author: Ben Lambert, Spotify & Sam Nixon, Roadie +--- + +**TL;DR**: For the Backstage maintainers, ensuring that the project is secure for every adopter and end user is one of our top priorities. +With the recent discovery of [CVE-2024-26150](https://www.cve.org/CVERecord?id=CVE-2024-26150), we've shipped fixes for versions > v1.15.0. +Please update your Backstage instance. + +![Backstage Security Audit & Updates](assets/22-08-23/backstage-security-audit.png) + +{/* truncate */} + +Last week we were notified by [Roadie](https://roadie.io/) of a potential security vulnerability in the scaffolder that they had discovered during a third-party security audit. +Roadie are running their scaffolder tasks in an isolated, ephemeral container to mitigate these kinds of issues, but as good citizens of the Backstage community, they alerted the Backstage maintainer team to make sure a fix was applied to the upstream project. +Upon further investigation, it turned out that this was a more widespread issue with the `resolveSafeChildPath` utility from the `@backstage/backend-common` package, which is used to prevent path traversal exploits. +This issue has now been fixed, and also backported to cover releases up to almost a year old. + +Please make sure that you have updated your Backstage instance to the latest v.1.23.2, or that you are using `@backstage/backend-common` `v0.21.1`, `v0.19.10`, or `v0.20.2`. +If you are building backend plugins for Backstage and do any local file operations, make sure you use the `resolveSafeChildPath` utility, as this check is quite tricky to implement correctly 😊 + +Thanks to Roadie and the team for reporting this issue, and making the Backstage community safe! + +For more information you can check out the [security advisory](https://github.com/backstage/backstage/security/advisories/GHSA-2fc9-xpp8-2g9h). diff --git a/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx b/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx new file mode 100644 index 0000000000..2164a8732e --- /dev/null +++ b/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx @@ -0,0 +1,63 @@ +--- +# prettier-ignore +title: "Backstage in Paris: Wrapping up BackstageCon and KubeCon + CloudNativeCon Europe 2024" +author: André Wanlin, Spotify +authorURL: https://github.com/awanlin +authorImageURL: https://avatars.githubusercontent.com/u/67169551?v=4 +--- + +**tl;dr**: And with that the first BackstageCon Europe comes to an end! The City of Light was good to Backstage with many great conversations at both BackstageCon and KubeCon + CloudNativeCon Europe 2024. If you weren't able to join, the CNCF has a great playlist of all the [BackstageCon talks](https://www.youtube.com/playlist?list=PLj6h78yzYM2P4KPyeDFexAVm6ZvfAWMU8) ready to go on YouTube. Check out some of the highlights below — then grab your popcorn and settle in! + +{/* truncate */} + +## Celebrating Four Years of Backstage + +<iframe + src="https://www.youtube.com/embed/NgYrweEbFNE" + width="100%" + height="440" + allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" + allowFullScreen +></iframe> + +Wow! Has it already been four years since we open sourced Backstage? What an amazing run it's been so far. We continue to see the rate of pull requests steadily increase, the attendance and number of [special interest groups](https://github.com/backstage/community/tree/main/sigs) (SIGs) has grown, and more people are dedicating their time to new [project areas](https://github.com/backstage/community/tree/main/project-areas)! + +## Day 1: BackstageCon arrives in Europe + +This was the third BackstageCon and the first to take place outside North America. As you can see, it started with a bang. + +![BackstageCon Europe 2024](assets/2024-03-27/backstagecon-europe-2024.jpg) +Via [Cloud Native Computing Foundation](https://www.flickr.com/photos/143247548@N03/albums/72177720315561784/) on Flickr + +With hosts like [Balaji Sivasubramanian](https://www.linkedin.com/in/balajisiva) (Head of Product Management, Red Hat) and [Helen Greul](https://se.linkedin.com/in/elenagreul) (Head of Engineering for Backstage, Spotify) [kicking things off](https://www.youtube.com/watch?v=PwVUW8is_WY&list=PLj6h78yzYM2P4KPyeDFexAVm6ZvfAWMU8&index=2), how could BackstageCon Europe not be a smashing success! + +More highlights from the day: + +- **Happy alignment:** Do you know when teams really need to be aligned? When they're working at a bank. [Thomas Grønbæk](https://www.linkedin.com/in/thomas-grønbæk/) (Senior Manager, Bankdata) gave an exciting talk about how “[Backstage Made 500+ Developers Happy](https://www.youtube.com/playlist?list=PLj6h78yzYM2P4KPyeDFexAVm6ZvfAWMU8)” in the highly regulated banking industry. +- **Scaling up:** On the topic of scaling Backstage — a frequent subject on our [Discord](https://discord.com/invite/backstage-687207715902193673) — [Vincenzo Scamporlino](https://se.linkedin.com/in/vincenzoscamporlino) (Senior Software Engineer, Spotify) gave us [his recommendations](https://www.youtube.com/playlist?list=PLj6h78yzYM2P4KPyeDFexAVm6ZvfAWMU8) that will be helpful for many adopters who want to bring their instance to the next level. +- **Lightning round:** There were several awesome [lightning talks](https://www.youtube.com/playlist?list=PLj6h78yzYM2P4KPyeDFexAVm6ZvfAWMU8) on varying topics — dynamic plugins, accessibility, OpenAPI tooling, and localization — that left you running to your laptop to learn more! +- **Bonus:** Next door at Platform Engineering Day, [Samantha Coffman](https://uk.linkedin.com/in/samanthacoffman) (Senior Product Manager, Spotify) was representing Backstage in her talk "[Boosting Developer Platform Teams with Product Thinking](https://www.youtube.com/watch?v=Z_KCOcoliLI&list=PLj6h78yzYM2Me-TpMQFvCphDu_xm71ed_&index=12)". + +Beyond the talks, it was great to meet so many different members of the community, both those who've been using Backstage since the beginning as well as people who are just learning about internal developer portals and the open source platform. I had so many great conversations, I started to lose my voice — and it was only the first day. + +## Day 2: Onward to KubeCon + CloudNativeCon + +Backstage also took the spotlight at KubeCon. On Wednesday, project maintainers [Patrik Oldsberg](https://github.com/Rugvip) (Senior Engineer, Spotify) and [Ben Lambert](https://github.com/benjdlambert) (Senior Engineer, Spotify) gave us a great overview on “[The State of Backstage in 2024](https://www.youtube.com/watch?v=jBf3g79xcf4)” to a packed audience. Highlights from their talk include: + +- **New project areas:** There are now project areas for Community Plugins, Notifications, and the Scaffolder +- **BEPs (Backstage enhancement proposals):** This is a new formal proposal process that allows a more iterative approach then trying to use GitHub Issues as RFCs +- **Core framework:** They gave updates on the new auth changes to be secure by default, as well as updates on the New Backend System and New Frontend System +- **The future:** Dynamic features! This allows you to install new plugins without having to rebuild + +## Day 3: Community, community, community! + +To top things off, during his [CNCF Keynote](https://www.youtube.com/watch?v=MICHGBAe8gc&list=PLj6h78yzYM2N8nw1YcqqKveySH6_0VnI0&index=161) on Thursday morning, [Taylor Dolezal](https://www.cncf.io/people/staff/?p=taylor-dolezal) (Head of Ecosystem, The Linux Foundation) shared what should be an unsurprising stat for members of the community: Backstage is the top CNCF project by end user commits! + +![CNCF Keynote, KubeCon + CloudNativeCon Europe 2024](assets/2024-03-27/cncf-keynote-kubecon-2024.jpg) +Top 10 CNCF Projects by Number of End User Commits + +## Day 4: Au revoir! See you at the next one! + +![BackstageCon and KubeCon + CloudNativeCon Europe 2024](assets/2024-03-27/backstagecon-kubecon-europe-2024.gif) + +You can catch up on all the talks from [BackstageCon](https://www.youtube.com/playlist?list=PLj6h78yzYM2P4KPyeDFexAVm6ZvfAWMU8) and the rest of the week on the [CNCF's YouTube channel](https://www.youtube.com/@cncf/playlists). See you in Salt Lake City in November at KubeCon + CloudNativeCon North America! diff --git a/microsite/blog/2024-04-19-community-plugins.mdx b/microsite/blog/2024-04-19-community-plugins.mdx new file mode 100644 index 0000000000..bb8b9c2313 --- /dev/null +++ b/microsite/blog/2024-04-19-community-plugins.mdx @@ -0,0 +1,280 @@ +--- +# prettier-ignore +title: "Introducing the Backstage Community Plugins Repository" +author: Ben Lambert, Spotify +authorURL: https://github.com/benjdlambert +authorImageURL: https://avatars.githubusercontent.com/u/3645856?v=4 +--- + +**tl;dr**: We've set up the new [community plugins repository](https://github.com/backstage/community-plugins), and have migrated most of the packages in the `plugins` directory of the main Backstage repository to their new home! + +For those who depended on these plugins, migrating is as simple as `yarn backstage-cli versions:bump` then `yarn backstage-cli versions:migrate`. If you're already on `1.26.1`, then be sure to run `yarn backstage-cli versions:bump --skip-migrate` then `yarn backstage-cli versions:migrate` to take advantage of the code reference replacement helpers. + +{/* truncate */} + +## The community plugins repo + +Some of you who have been around a while, or have seen our [Maintainer Track talks](https://www.youtube.com/watch?v=ONMBYnhxnNU) at KubeCon, might have seen [this RFC](https://github.com/backstage/backstage/issues/20266) which outlines some issues with the scale of the `backstage/backstage` monorepo, and us as maintainers being the de facto owners of all plugins without a [project area](https://github.com/backstage/backstage/blob/master/GOVERNANCE.md#project-area) or [plugin maintainer](https://github.com/backstage/backstage/blob/master/GOVERNANCE.md#project-area-maintainer). + +There was some great discussion in this issue, and some great ideas. One of the ideas was to create a dedicated home for community plugins, with all the burden of release tooling and workspace tooling already set up, which is a pretty big barrier for people wanting to create plugins for Backstage in their own organization or personal account. These plugins would then have the ability to release independently of the main monorepo, and have their own release cadence, which is something that we've been looking at exploring for a while. + +With Red Hat wanting to join forces and help get this set up, this is the path that we picked, and the last few months have been a lot of hard work from both sides getting this repository in shape and coming up with a deprecation plan for these plugins in the main repository. + +Would also like to give a shoutout to all the [Community Plugins project area](https://github.com/backstage/backstage/blob/master/OWNERS.md#community-plugins) maintainers, who have been helping get us to this state! [@vinzscam](https://github.com/vinzscam) [@tudi2d](https://github.com/tudi2d) [@bethgriggs](https://github.com/BethGriggs) [@kadel](https://github.com/kadel) [@awanlin](https://github.com/awanlin) 👏 + +And now with the release of `1.26.3` there's a large amount of plugins from the main monorepo that have been migrated over to the new [community plugins repository](https://github.com/backstage/community-plugins). :tada: + +## The migration + +With the moving of these plugins, we thought it would also be a good time to move the `npm` scope, so that end users can differentiate between Backstage packages, and community-maintained packages. So the `@backstage-community` namespace was born! + +This makes migration a little tricky for end users, as there's going to be code references and `package.json` dependencies pointing to the older packages which are no longer going to be published. + +We've added some tooling into the `@backstage/cli` which is going to smooth the transition here. The last versions which are published under the `@backstage/` scope from the monorepo, will have a special field in the `package.json` with a hint to the CLI as to what this package is now called. + +The CLI will then be able to replace these references inside the `./src` folder of your codebase, and update your `package.json` dependencies to the new `@backstage-community` scope. + +You can migrate today by running the following: + +```bash +# < 1.26.1 +yarn backstage-cli versions:bump +yarn backstage-cli versions:migrate + +# 1.26.1 +yarn backstage-cli versions:bump --skip-migrate +yarn backstage-cli versions:migrate +``` + +From this latest `1.26.3` release and onwards, the `backstage-cli versions:bump` command will automatically check for moved packages, so you shouldn't have to worry about running this every time. + +## Help! My plugin has been moved! + +No stress! If you were a `CODEOWNER` of the code in the monorepo, these permissions will be migrated over to the [community plugins repository](https://github.com/backstage/community-plugins) so you should still have access to the code. And now you're in charge of releasing your own plugin! 🚀 You can do that by following the same flow from the monorepo, with changesets and merging the `Version Packages (My Plugin)` PR. + +Please reach out to us on [Discord](https://discord.com/invite/backstage-687207715902193673) if you have any issues! We're looking forward to working together in the new space! + +## What's moved? + +We've taken a pretty big chunk of the plugins from the main monorepo and moved them over to the new repository. There could be more plugins over time that are moved, or even ones that we promote back to the main monorepo. + +<details> + <summary> + Here's a list of plugins that have been moved with this release + </summary> + +- `@backstage/plugin-adr-backend` + +- `@backstage/plugin-adr-common` + +- `@backstage/plugin-adr` + +- `@backstage/plugin-airbrake-backend` + +- `@backstage/plugin-airbrake` + +- `@backstage/plugin-allure` + +- `@backstage/plugin-analytics-module-ga` + +- `@backstage/plugin-analytics-module-ga4` + +- `@backstage/plugin-analytics-module-newrelic-browser` + +- `@backstage/plugin-apache-airflow` + +- `@backstage/plugin-apollo-explorer` + +- `@backstage/plugin-azure-devops-backend` + +- `@backstage/plugin-azure-devops-common` + +- `@backstage/plugin-azure-devops` + +- `@backstage/plugin-azure-sites-backend` + +- `@backstage/plugin-azure-sites-common` + +- `@backstage/plugin-azure-sites` + +- `@backstage/plugin-badges-backend` + +- `@backstage/plugin-badges` + +- `@backstage/plugin-bazaar-backend` + +- `@backstage/plugin-bazaar` + +- `@backstage/plugin-bitrise` + +- `@backstage/plugin-cicd-statistics-module-gitlab` + +- `@backstage/plugin-cicd-statistics` + +- `@backstage/plugin-circleci` + +- `@backstage/plugin-cloudbuild` + +- `@backstage/plugin-code-climate` + +- `@backstage/plugin-code-coverage-backend` + +- `@backstage/plugin-code-coverage` + +- `@backstage/plugin-codescene` + +- `@backstage/plugin-cost-insights-common` + +- `@backstage/plugin-cost-insights` + +- `@backstage/plugin-dynatrace` + +- `@backstage/plugin-entity-feedback-backend` + +- `@backstage/plugin-entity-feedback-common` + +- `@backstage/plugin-entity-feedback` + +- `@backstage/plugin-entity-validation` + +- `@backstage/plugin-explore-backend` + +- `@backstage/plugin-explore-common` + +- `@backstage/plugin-explore-react` + +- `@backstage/plugin-explore` + +- `@backstage/plugin-firehydrant` + +- `@backstage/plugin-fossa` + +- `@backstage/plugin-gcalendar` + +- `@backstage/plugin-gcp-projects` + +- `@backstage/plugin-git-release-manager` + +- `@backstage/plugin-github-actions` + +- `@backstage/plugin-github-deployments` + +- `@backstage/plugin-github-issues` + +- `@backstage/plugin-github-pull-requests-board` + +- `@backstage/plugin-gitops-profiles` + +- `@backstage/plugin-gocd` + +- `@backstage/plugin-graphiql` + +- `@backstage/plugin-graphql-voyager` + +- `@backstage/plugin-ilert` + +- `@backstage/plugin-jenkins-backend` + +- `@backstage/plugin-jenkins-common` + +- `@backstage/plugin-jenkins` + +- `@backstage/plugin-kafka-backend` + +- `@backstage/plugin-kafka` + +- `@backstage/plugin-lighthouse-backend` + +- `@backstage/plugin-lighthouse-common` + +- `@backstage/plugin-lighthouse` + +- `@backstage/plugin-linguist` + +- `@backstage/plugin-linguist-common` + +- `@backstage/plugin-linguist-backend` + +- `@backstage/plugin-microsoft-calendar` + +- `@backstage/plugin-newrelic-dashboard` + +- `@backstage/plugin-newrelic` + +- `@backstage/plugin-nomad` + +- `@backstage/plugin-nomad-backend` + +- `@backstage/plugin-octopus-deploy` + +- `@backstage/plugin-opencost` + +- `@backstage/plugin-periskop-backend` + +- `@backstage/plugin-periskop` + +- `@backstage/plugin-playlist-backend` + +- `@backstage/plugin-playlist-common` + +- `@backstage/plugin-playlist` + +- `@backstage/plugin-puppetdb` + +- `@backstage/plugin-rollbar-backend` + +- `@backstage/plugin-rollbar` + +- `@backstage/plugin-sentry` + +- `@backstage/plugin-shortcuts` + +- `@backstage/plugin-sonarqube-backend` + +- `@backstage/plugin-sonarqube-react` + +- `@backstage/plugin-sonarqube` + +- `@backstage/plugin-splunk-on-call` + +- `@backstage/plugin-stack-overflow-backend` + +- `@backstage/plugin-stack-overflow` + +- `@backstage/plugin-stackstorm` + +- `@backstage/plugin-tech-insights-backend-module-jsonfc` + +- `@backstage/plugin-tech-insights-backend` + +- `@backstage/plugin-tech-insights-common` + +- `@backstage/plugin-tech-insights-node` + +- `@backstage/plugin-tech-insights` + +- `@backstage/plugin-tech-radar` + +- `@backstage/plugin-vault-backend` + +- `@backstage/plugin-vault-node` + +- `@backstage/plugin-vault` + +- `@backstage/plugin-xcmetrics` + +</details> + +## What's next? + +There's going to be a little bit of time now in this migration period where there's going to be issues and pull requests not in the right place, and we're going to do our best to transfer issues to the community plugins repository instead. We will shortly be removing the code for these plugins from the main monorepo as it now has a new home in the community plugins repository. + +We're also going to be looking at bringing in some more of the great tooling from the `backstage/backstage` monorepo into the community plugins repository to help out with more automation for dependency bumps, etc. + +## How can I get involved? + +If you're interested in getting involved with the community and helping us maintain this repository, please reach out either on [Discord](https://discord.com/invite/backstage-687207715902193673) or in an issue on the [community repository](https://github.com/backstage/community). + +If you're wanting to contribute some plugins to Backstage, the community plugin repository is open for business :tada: and we're looking forward to seeing what you come up with! Head over to the [community plugins docs](https://github.com/backstage/community-plugins/tree/main/README.md) to get started creating your own workspace! + +Thanks! diff --git a/microsite/blog/assets/2024-03-27/backstagecon-europe-2024.jpg b/microsite/blog/assets/2024-03-27/backstagecon-europe-2024.jpg new file mode 100644 index 0000000000..b949af964f Binary files /dev/null and b/microsite/blog/assets/2024-03-27/backstagecon-europe-2024.jpg differ diff --git a/microsite/blog/assets/2024-03-27/backstagecon-kubecon-europe-2024.gif b/microsite/blog/assets/2024-03-27/backstagecon-kubecon-europe-2024.gif new file mode 100644 index 0000000000..d64a6a8b15 Binary files /dev/null and b/microsite/blog/assets/2024-03-27/backstagecon-kubecon-europe-2024.gif differ diff --git a/microsite/blog/assets/2024-03-27/cncf-keynote-kubecon-2024.jpg b/microsite/blog/assets/2024-03-27/cncf-keynote-kubecon-2024.jpg new file mode 100644 index 0000000000..f5b1cb93f9 Binary files /dev/null and b/microsite/blog/assets/2024-03-27/cncf-keynote-kubecon-2024.jpg differ diff --git a/microsite/data/plugins/adr.yaml b/microsite/data/plugins/adr.yaml index e6b7b0cccb..003ae22e7b 100644 --- a/microsite/data/plugins/adr.yaml +++ b/microsite/data/plugins/adr.yaml @@ -4,7 +4,7 @@ author: Phil Kuang authorUrl: https://github.com/kuangp category: Discovery description: Browse your project's ADRs. -documentation: https://github.com/backstage/backstage/tree/master/plugins/adr +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/adr/plugins/adr iconUrl: /img/adr-logo.png -npmPackageName: '@backstage/plugin-adr' +npmPackageName: '@backstage-community/plugin-adr' addedDate: '2022-04-13' diff --git a/microsite/data/plugins/ai-assistant.yaml b/microsite/data/plugins/ai-assistant.yaml new file mode 100644 index 0000000000..997846c14b --- /dev/null +++ b/microsite/data/plugins/ai-assistant.yaml @@ -0,0 +1,10 @@ +--- +title: AI Assistant - RAG AI +author: RoadieHQ +authorUrl: https://roadie.io +category: Search +description: Query LLMs with contextual information from your catalog. +documentation: https://roadie.io/backstage/plugins/ai-assistant-rag-ai/ +iconUrl: https://roadie.io/images/logos/roadie-racks-ai.png +npmPackageName: '@roadiehq/rag-ai' +addedDate: '2024-03-12' diff --git a/microsite/data/plugins/allure.yaml b/microsite/data/plugins/allure.yaml index fc21849268..cbcd0ec435 100644 --- a/microsite/data/plugins/allure.yaml +++ b/microsite/data/plugins/allure.yaml @@ -4,7 +4,7 @@ author: Deepak Bhardwaj authorUrl: https://github.com/deepak-bhardwaj-ps category: Reporting description: View Allure reports for your components in Backstage. -documentation: https://github.com/backstage/backstage/tree/master/plugins/allure +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/allure/plugins/allure iconUrl: https://avatars.githubusercontent.com/u/5879127 -npmPackageName: '@backstage/plugin-allure' +npmPackageName: '@backstage-community/plugin-allure' addedDate: '2021-09-02' diff --git a/microsite/data/plugins/analytics-module-qm.yaml b/microsite/data/plugins/analytics-module-qm.yaml new file mode 100644 index 0000000000..df2ae3e935 --- /dev/null +++ b/microsite/data/plugins/analytics-module-qm.yaml @@ -0,0 +1,10 @@ +--- +title: 'Analytics Module: Quantum Metric' +author: Quantum Metric +authorUrl: https://github.com/quantummetric +category: Monitoring +description: Track usage of your Backstage instance using Quantum Metric. +documentation: https://github.com/quantummetric/analytics-module-qm/blob/main/README.md +iconUrl: /img/qm-icon.png +npmPackageName: '@quantum-metric/plugin-analytics-module-qm' +addedDate: '2024-03-15' diff --git a/microsite/data/plugins/aws-amazon-ecs.yaml b/microsite/data/plugins/aws-amazon-ecs.yaml new file mode 100644 index 0000000000..a94779babd --- /dev/null +++ b/microsite/data/plugins/aws-amazon-ecs.yaml @@ -0,0 +1,10 @@ +--- +title: Amazon Elastic Container Service +author: Amazon Web Services +authorUrl: https://aws.amazon.com/ +category: Infrastructure +description: View resources related to Amazon Elastic Container Service for your components in Backstage. +documentation: https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/ecs#readme +iconUrl: https://raw.githubusercontent.com/awslabs/backstage-plugins-for-aws/main/docs/images/logos/amazon-ecs-logo.png +npmPackageName: 'https://www.npmjs.com/package/@aws/amazon-ecs-plugin-for-backstage' +addedDate: '2024-04-22' diff --git a/microsite/data/plugins/aws-codebuild.yaml b/microsite/data/plugins/aws-codebuild.yaml new file mode 100644 index 0000000000..2c12f92dce --- /dev/null +++ b/microsite/data/plugins/aws-codebuild.yaml @@ -0,0 +1,10 @@ +--- +title: AWS CodeBuild +author: Amazon Web Services +authorUrl: https://aws.amazon.com/ +category: CI/CD +description: View resources related to AWS CodeBuild for your components in Backstage. +documentation: https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/codebuild#readme +iconUrl: https://raw.githubusercontent.com/awslabs/backstage-plugins-for-aws/main/docs/images/logos/aws-codebuild-logo.png +npmPackageName: 'https://www.npmjs.com/package/@aws/aws-codebuild-plugin-for-backstage' +addedDate: '2024-04-22' diff --git a/microsite/data/plugins/aws-codepipeline.yaml b/microsite/data/plugins/aws-codepipeline.yaml new file mode 100644 index 0000000000..16986b6718 --- /dev/null +++ b/microsite/data/plugins/aws-codepipeline.yaml @@ -0,0 +1,10 @@ +--- +title: AWS CodePipeline +author: Amazon Web Services +authorUrl: https://aws.amazon.com/ +category: CI/CD +description: View resources related to AWS CodePipeline for your components in Backstage. +documentation: https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/codepipeline#readme +iconUrl: https://raw.githubusercontent.com/awslabs/backstage-plugins-for-aws/main/docs/images/logos/aws-codepipeline-logo.png +npmPackageName: 'https://www.npmjs.com/package/@aws/aws-codepipeline-plugin-for-backstage' +addedDate: '2024-04-22' diff --git a/microsite/data/plugins/aws-codeservices.yaml b/microsite/data/plugins/aws-codeservices.yaml deleted file mode 100644 index 34fa335923..0000000000 --- a/microsite/data/plugins/aws-codeservices.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: AWS Code Services -author: Amazon Web Services -authorUrl: https://aws.amazon.com/ -category: CI/CD -description: View resources related to AWS CodePipeline, AWS CodeBuild and AWS CodeDeploy for your components in Backstage. -documentation: https://github.com/awslabs/aws-codeservices-plugins-for-backstage#readme -iconUrl: https://github.com/awslabs/aws-codeservices-plugins-for-backstage/blob/main/docs/images/codepipeline-logo.png?raw=true -npmPackageName: '@aws/aws-codeservices-plugin-for-backstage' -addedDate: '2023-01-17' diff --git a/microsite/data/plugins/aws-proton.yaml b/microsite/data/plugins/aws-proton.yaml deleted file mode 100644 index f66b556d42..0000000000 --- a/microsite/data/plugins/aws-proton.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: AWS Proton -author: Amazon Web Services -authorUrl: https://aws.amazon.com/ -category: Infrastructure -description: Create and view AWS Proton services for your components in Backstage. -documentation: https://github.com/awslabs/aws-proton-plugins-for-backstage#readme -iconUrl: https://github.com/awslabs/aws-proton-plugins-for-backstage/blob/main/docs/images/proton-logo.png?raw=true -npmPackageName: '@aws/aws-proton-plugin-for-backstage' -addedDate: '2022-06-21' diff --git a/microsite/data/plugins/azure-sites.yaml b/microsite/data/plugins/azure-sites.yaml index 70e586f30e..03b61b9614 100644 --- a/microsite/data/plugins/azure-sites.yaml +++ b/microsite/data/plugins/azure-sites.yaml @@ -4,6 +4,6 @@ author: FRISS authorUrl: https://friss.com category: Infrastructure description: Azure Sites (Apps & Functions) support for a given entity. View the current status of the site, quickly jump to site's Overview page, or Log Stream page. -documentation: https://github.com/backstage/backstage/tree/master/plugins/azure-sites -npmPackageName: '@backstage/plugin-azure-sites' +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/azure-sites/plugins/azure-sites +npmPackageName: '@backstage-community/plugin-azure-sites' addedDate: '2022-10-18' diff --git a/microsite/data/plugins/changelog.yaml b/microsite/data/plugins/changelog.yaml index 1b4684db7f..a1ee12feea 100644 --- a/microsite/data/plugins/changelog.yaml +++ b/microsite/data/plugins/changelog.yaml @@ -3,7 +3,7 @@ title: Changelog viewer author: RSC Labs authorUrl: https://rsoftcon.com/ category: Discovery -description: View changelogs for your components in Backstage. Built-in support of "Keep the changelog" format. +description: View changelogs for your components in Backstage. Built-in support of "Keep the changelog" and "Semver" formats. documentation: https://github.com/RSC-Labs/backstage-changelog-plugin/blob/main/README.md iconUrl: https://raw.githubusercontent.com/RSC-Labs/backstage-changelog-plugin/main/docs/plugin_icon.png npmPackageName: '@rsc-labs/backstage-changelog-plugin' diff --git a/microsite/data/plugins/cicd-statistics.yaml b/microsite/data/plugins/cicd-statistics.yaml index ff5c2cccf3..ea745b1129 100644 --- a/microsite/data/plugins/cicd-statistics.yaml +++ b/microsite/data/plugins/cicd-statistics.yaml @@ -4,9 +4,9 @@ author: Spotify authorUrl: https://github.com/spotify category: CI/CD description: Visualize CI/CD pipeline statistics such as build time or success and error rates. -documentation: https://github.com/backstage/backstage/tree/master/plugins/cicd-statistics +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/cicd-statistics/plugins/cicd-statistics iconUrl: /img/cicd-statistics.svg -npmPackageName: '@backstage/plugin-cicd-statistics' +npmPackageName: '@backstage-community/plugin-cicd-statistics' tags: - ci - cd diff --git a/microsite/data/plugins/cloud-build.yaml b/microsite/data/plugins/cloud-build.yaml index 67ef13011b..b63b29a559 100644 --- a/microsite/data/plugins/cloud-build.yaml +++ b/microsite/data/plugins/cloud-build.yaml @@ -4,9 +4,9 @@ author: Trivago authorUrl: https://www.trivago.com category: CI/CD description: Build, test, and deploy on Google's serverless CI/CD platform. -documentation: https://github.com/backstage/backstage/tree/master/plugins/cloudbuild +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/cloudbuild/plugins/cloudbuild iconUrl: https://avatars2.githubusercontent.com/u/38220399?s=400&v=4 -npmPackageName: '@backstage/plugin-cloudbuild' +npmPackageName: '@backstage-community/plugin-cloudbuild' tags: - ci - cd diff --git a/microsite/data/plugins/codacy-repo-adder.yaml b/microsite/data/plugins/codacy-repo-adder.yaml new file mode 100644 index 0000000000..a479a45ecf --- /dev/null +++ b/microsite/data/plugins/codacy-repo-adder.yaml @@ -0,0 +1,10 @@ +--- +title: Codacy Repo Adder +author: Codacy +authorUrl: https://www.codacy.com/ +category: Quality +description: A Template Action to automatically add a Repository to Codacy +documentation: https://github.com/codacy/backstage-plugin/blob/main/README.md +iconUrl: /img/codacy-icon.svg +npmPackageName: '@codacy/backstage-plugin' +addedDate: '2024-04-19' diff --git a/microsite/data/plugins/coder.yaml b/microsite/data/plugins/coder.yaml new file mode 100644 index 0000000000..71d32b5ce4 --- /dev/null +++ b/microsite/data/plugins/coder.yaml @@ -0,0 +1,10 @@ +--- +title: Coder +author: Coder +authorUrl: https://www.coder.com +category: Development +description: Create and manage Coder workspaces from Backstage! +documentation: https://github.com/coder/backstage-plugins/blob/main/plugins/backstage-plugin-coder/README.md +iconUrl: /img/coder.png +npmPackageName: '@coder/backstage-plugin-coder' +addedDate: '2024-03-15' diff --git a/microsite/data/plugins/codescene.yaml b/microsite/data/plugins/codescene.yaml index 734e575282..b69124aecc 100644 --- a/microsite/data/plugins/codescene.yaml +++ b/microsite/data/plugins/codescene.yaml @@ -4,7 +4,7 @@ author: CodeScene authorUrl: https://codescene.com/ category: Quality description: CodeScene is a multi-purpose tool bridging code, business and people. See hidden risks and social patterns in your code. Prioritize and reduce technical debt. -documentation: https://github.com/backstage/backstage/tree/master/plugins/codescene +documentation: https://github.com/backstage/community-plugins/blob/main/workspaces/codescene/plugins/codescene iconUrl: /img/codescene_logo.svg -npmPackageName: '@backstage/plugin-codescene' +npmPackageName: '@backstage-community/plugin-codescene' addedDate: '2022-04-12' diff --git a/microsite/data/plugins/cost-insights.yaml b/microsite/data/plugins/cost-insights.yaml index 603cd18416..625b3f1c2c 100644 --- a/microsite/data/plugins/cost-insights.yaml +++ b/microsite/data/plugins/cost-insights.yaml @@ -4,9 +4,9 @@ author: Spotify authorUrl: https://github.com/spotify category: Discovery description: Visualize, understand and optimize your team's cloud costs. -documentation: https://github.com/backstage/backstage/tree/master/plugins/cost-insights +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/cost-insights/plugins/cost-insights iconUrl: /img/cost-insights.png -npmPackageName: '@backstage/plugin-cost-insights' +npmPackageName: '@backstage-community/plugin-cost-insights' tags: - web addedDate: '2021-04-28' diff --git a/microsite/data/plugins/dev-friends-day.yaml b/microsite/data/plugins/dev-friends-day.yaml new file mode 100644 index 0000000000..9cbcd5b42f --- /dev/null +++ b/microsite/data/plugins/dev-friends-day.yaml @@ -0,0 +1,10 @@ +--- +title: Dev Friends Days +author: Piotr Piątkiewicz +authorUrl: https://piatkiewicz.com +category: Humor +description: Be informed if there is a Programmer, Tester or SysAdmin day today so you will know when to celebrate that special day with your team! +documentation: https://github.com/piatkiewicz/backstage-plugins/tree/main/dev-friends-days +iconUrl: /img/dev-friends-days.jpeg +npmPackageName: '@piatkiewicz/backstage-dev-friends-days' +addedDate: '2024-02-28' diff --git a/microsite/data/plugins/devcontainers.yaml b/microsite/data/plugins/devcontainers.yaml new file mode 100644 index 0000000000..427c44b4c6 --- /dev/null +++ b/microsite/data/plugins/devcontainers.yaml @@ -0,0 +1,10 @@ +--- +title: Dev Containers +author: Coder +authorUrl: https://www.coder.com +category: Development +description: Automatically launch fully-contained dev environments with Dev Containers, right from Backstage! +documentation: https://github.com/coder/backstage-plugins/blob/main/plugins/backstage-plugin-devcontainers-react/README.md +iconUrl: /img/devcontainers.png +npmPackageName: '@coder/backstage-plugin-devcontainers-react' +addedDate: '2024-03-15' diff --git a/microsite/data/plugins/dx.yaml b/microsite/data/plugins/dx.yaml new file mode 100644 index 0000000000..6fbcb93f76 --- /dev/null +++ b/microsite/data/plugins/dx.yaml @@ -0,0 +1,10 @@ +--- +title: DX +author: DX +authorUrl: https://getdx.com +category: Services +description: DX Plugin for syncing Backstage data to DX and adding DX reports to Backstage. +documentation: https://github.com/get-dx/backstage-plugin +iconUrl: /img/dx-icon.png +npmPackageName: '@get-dx/backstage-plugin' +addedDate: '2024-03-05' diff --git a/microsite/data/plugins/dynatrace-managed.yaml b/microsite/data/plugins/dynatrace-managed.yaml new file mode 100644 index 0000000000..94793e254d --- /dev/null +++ b/microsite/data/plugins/dynatrace-managed.yaml @@ -0,0 +1,16 @@ +--- +title: Dynatrace for Managed +author: Dynatrace +authorUrl: https://github.com/dynatrace +category: Monitoring +description: View problem and synthetic information for services in your software catalog. +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/dynatrace/plugins/dynatrace +iconUrl: /img/dynatrace.svg +npmPackageName: '@backstage-community/plugin-dynatrace' +tags: + - monitoring + - observability + - alerting + - problem + - synthetic +addedDate: '2022-06-23' diff --git a/microsite/data/plugins/dynatrace.yaml b/microsite/data/plugins/dynatrace.yaml index 94a2e423a6..15331bb08a 100644 --- a/microsite/data/plugins/dynatrace.yaml +++ b/microsite/data/plugins/dynatrace.yaml @@ -3,13 +3,13 @@ title: Dynatrace author: Dynatrace authorUrl: https://github.com/dynatrace category: Monitoring -description: View monitoring info from Dynatrace for services in your software catalog. -documentation: https://github.com/backstage/backstage/tree/master/plugins/dynatrace +description: Provide customizable context-rich observability and security insights for services in your software catalog. +documentation: https://github.com/Dynatrace/backstage-plugin iconUrl: /img/dynatrace.svg -npmPackageName: '@backstage/plugin-dynatrace' +npmPackageName: '@dynatrace/backstage-plugin-dql' tags: - monitoring - observability - - alerting - - problems -addedDate: '2022-06-23' + - security + - problem +addedDate: '2024-03-22' diff --git a/microsite/data/plugins/entity-feedback.yaml b/microsite/data/plugins/entity-feedback.yaml index 3630eddb73..a03537b4f7 100644 --- a/microsite/data/plugins/entity-feedback.yaml +++ b/microsite/data/plugins/entity-feedback.yaml @@ -4,7 +4,7 @@ author: Phil Kuang authorUrl: https://github.com/kuangp category: Quality description: Give and view feedback on entities available in the Backstage catalog. -documentation: https://github.com/backstage/backstage/tree/master/plugins/entity-feedback +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/entity-feedback/plugins/entity-feedback iconUrl: /img/entity-feedback-logo.png -npmPackageName: '@backstage/plugin-entity-feedback' +npmPackageName: '@backstage-community/plugin-entity-feedback' addedDate: '2023-01-20' diff --git a/microsite/data/plugins/entity-validation.yaml b/microsite/data/plugins/entity-validation.yaml index bc341a4221..2ccb6deced 100644 --- a/microsite/data/plugins/entity-validation.yaml +++ b/microsite/data/plugins/entity-validation.yaml @@ -4,7 +4,7 @@ author: Spreadgroup authorUrl: https://github.com/spreadshirt category: Quality description: Interface for validating entities. -documentation: https://github.com/backstage/backstage/tree/master/plugins/entity-validation -npmPackageName: '@backstage/plugin-entity-validation' +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/entity-validation/plugins/entity-validation +npmPackageName: '@backstage-community/plugin-entity-validation' iconUrl: /img/entity-validation.svg addedDate: '2023-09-13' diff --git a/microsite/data/plugins/feedback.yaml b/microsite/data/plugins/feedback.yaml new file mode 100644 index 0000000000..8e8e00165e --- /dev/null +++ b/microsite/data/plugins/feedback.yaml @@ -0,0 +1,10 @@ +--- +title: Feedback +author: Red Hat +authorUrl: https://redhat.com +category: Quality +description: A plugin for collecting user feedbacks for your application. # Max 170 characters +documentation: https://github.com/janus-idp/backstage-plugins/tree/main/plugins/feedback#readme +iconUrl: /img/plugin-feedback-logo.svg +npmPackageName: '@janus-idp/backstage-plugin-feedback' +addedDate: '2024-04-09' diff --git a/microsite/data/plugins/gcp-projects.yaml b/microsite/data/plugins/gcp-projects.yaml index 02e66db27e..7902724c96 100644 --- a/microsite/data/plugins/gcp-projects.yaml +++ b/microsite/data/plugins/gcp-projects.yaml @@ -4,9 +4,9 @@ author: Trivago authorUrl: https://www.trivago.com category: Infrastructure description: Create, list and manage your Google Cloud Projects. -documentation: https://github.com/backstage/backstage/tree/master/plugins/gcp-projects +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/gcp-projects/plugins/gcp-projects iconUrl: https://avatars1.githubusercontent.com/u/2810941?s=280&v=4 -npmPackageName: '@backstage/plugin-gcp-projects' +npmPackageName: '@backstage-community/plugin-gcp-projects' tags: - cloud - project diff --git a/microsite/data/plugins/git-release-manager.yaml b/microsite/data/plugins/git-release-manager.yaml index 947209e6d5..244c88b981 100644 --- a/microsite/data/plugins/git-release-manager.yaml +++ b/microsite/data/plugins/git-release-manager.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Source Control Mgmt description: Manage releases without having to juggle git commands. -documentation: https://github.com/backstage/backstage/tree/master/plugins/git-release-manager +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/git-release-manager/plugins/git-release-manager iconUrl: /img/git-release-manager-logo.svg -npmPackageName: '@backstage/plugin-git-release-manager' +npmPackageName: '@backstage-community/plugin-git-release-manager' addedDate: '2021-10-04' diff --git a/microsite/data/plugins/github-actions.yaml b/microsite/data/plugins/github-actions.yaml index 82611c3933..f496e7c15d 100644 --- a/microsite/data/plugins/github-actions.yaml +++ b/microsite/data/plugins/github-actions.yaml @@ -4,9 +4,9 @@ author: Spotify authorUrl: https://github.com/spotify category: CI/CD description: GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. -documentation: https://github.com/backstage/backstage/tree/master/plugins/github-actions +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/github-actions/plugins/github-actions iconUrl: https://avatars2.githubusercontent.com/u/44036562?s=400&v=4 -npmPackageName: '@backstage/plugin-github-actions' +npmPackageName: '@backstage-community/plugin-github-actions' tags: - ci - cd diff --git a/microsite/data/plugins/github-pull-requests-board.yaml b/microsite/data/plugins/github-pull-requests-board.yaml index 9fe2570f91..51c9f1a2e4 100644 --- a/microsite/data/plugins/github-pull-requests-board.yaml +++ b/microsite/data/plugins/github-pull-requests-board.yaml @@ -4,7 +4,7 @@ author: DAZN authorUrl: https://engineering.dazn.com category: Source Control Mgmt description: View all open GitHub pull requests owned by your team in Backstage. -documentation: https://github.com/backstage/backstage/tree/master/plugins/github-pull-requests-board +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/github-pull-requests-board/plugins/github-pull-requests-board iconUrl: /img/github-pull-requests-board-logo.svg -npmPackageName: '@backstage/plugin-github-pull-requests-board' +npmPackageName: '@backstage-community/plugin-github-pull-requests-board' addedDate: '2022-05-10' diff --git a/microsite/data/plugins/gitops-cluster.yaml b/microsite/data/plugins/gitops-cluster.yaml index 1ebe4c40f8..8e67c9c25d 100644 --- a/microsite/data/plugins/gitops-cluster.yaml +++ b/microsite/data/plugins/gitops-cluster.yaml @@ -4,9 +4,9 @@ author: Weaveworks authorUrl: https://www.weave.works/ category: Kubernetes description: Create GitOps-managed Kubernetes clusters. Currently, it supports provisioning EKS clusters on GitHub via GitHub Actions. -documentation: https://github.com/backstage/backstage/tree/master/plugins/gitops-profiles +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/gitops-profiles/plugins/gitops-profiles iconUrl: https://res-5.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_256,w_256,f_auto,q_auto:eco/v1462316670/i9d3delzvx1erzjhmcws.png -npmPackageName: '@backstage/plugin-gitops-profiles' +npmPackageName: '@backstage-community/plugin-gitops-profiles' tags: - kubernetes - gitops diff --git a/microsite/data/plugins/gocd.yaml b/microsite/data/plugins/gocd.yaml index 1e5f4c3acb..2924ef9b41 100644 --- a/microsite/data/plugins/gocd.yaml +++ b/microsite/data/plugins/gocd.yaml @@ -4,9 +4,9 @@ author: SoundCloud authorUrl: https://github.com/soundcloud category: CI/CD description: GoCD is an open-source tool which is used in software development to help teams and organizations automate the continuous delivery of software. -documentation: https://github.com/backstage/backstage/tree/master/plugins/gocd +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/gocd/plugins/gocd iconUrl: https://www.gocd.org/assets/images/go_logo-5b5ca9e1.svg -npmPackageName: '@backstage/plugin-gocd' +npmPackageName: '@backstage-community/plugin-gocd' tags: - ci - cd diff --git a/microsite/data/plugins/graphiql.yaml b/microsite/data/plugins/graphiql.yaml index 4cff5ca8ba..4b5aee5161 100644 --- a/microsite/data/plugins/graphiql.yaml +++ b/microsite/data/plugins/graphiql.yaml @@ -4,9 +4,9 @@ author: Spotify authorUrl: https://github.com/spotify category: Debugging description: Integrates GraphiQL as a tool to browse GraphQL API endpoints inside Backstage. -documentation: https://github.com/backstage/backstage/tree/master/plugins/graphiql +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/graphiql/plugins/graphiql iconUrl: https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/1024px-GraphQL_Logo.svg.png -npmPackageName: '@backstage/plugin-graphiql' +npmPackageName: '@backstage-community/plugin-graphiql' tags: - graphql - graphiql diff --git a/microsite/data/plugins/graphql-voyager.yaml b/microsite/data/plugins/graphql-voyager.yaml index c6ebf5e412..e9c5a95e45 100644 --- a/microsite/data/plugins/graphql-voyager.yaml +++ b/microsite/data/plugins/graphql-voyager.yaml @@ -4,9 +4,9 @@ author: PostNL authorUrl: https://github.com/postnl category: Debugging description: Integrates the GraphQL Voyager tool inside Backstage as a plugin. -documentation: https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/graphql-voyager/plugins/graphql-voyager iconUrl: https://res.cloudinary.com/apideck/image/upload/v1612724234/icons/graphql-voyager.png -npmPackageName: '@backstage/plugin-graphql-voyager' +npmPackageName: '@backstage-community/plugin-graphql-voyager' tags: - graphql - graphql-voyager diff --git a/microsite/data/plugins/ibm-apic-backend.yaml b/microsite/data/plugins/ibm-apic-backend.yaml new file mode 100644 index 0000000000..9228524a2d --- /dev/null +++ b/microsite/data/plugins/ibm-apic-backend.yaml @@ -0,0 +1,12 @@ +--- +title: IBM APIC EntityProvider +author: croz.net +authorUrl: https://croz.net/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=backstage-ibm-apic-backend +category: API Management +description: Bring IBM APIC to Backstage. +documentation: https://github.com/croz-ltd/apic-backend-plugin?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=backstage-ibm-apic-backend +iconUrl: https://croz.net/wp-content/uploads/2024/02/croz_large-o.png +npmPackageName: '@croz/plugin-ibm-apic-backend' +tags: + - openapic +addedDate: '2024-03-01' diff --git a/microsite/data/plugins/ilert.yaml b/microsite/data/plugins/ilert.yaml index feb54e2d6e..c410084e8c 100644 --- a/microsite/data/plugins/ilert.yaml +++ b/microsite/data/plugins/ilert.yaml @@ -4,9 +4,9 @@ author: iLert authorUrl: https://www.ilert.com category: Monitoring description: iLert is a platform for alerting, on-call management and uptime monitoring targeted at DevOps and IT teams. -documentation: https://github.com/backstage/backstage/tree/master/plugins/ilert +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/ilert/plugins/ilert iconUrl: https://avatars.githubusercontent.com/u/13230510?s=200&v=4 -npmPackageName: '@backstage/plugin-ilert' +npmPackageName: '@backstage-community/plugin-ilert' tags: - monitoring - errors diff --git a/microsite/data/plugins/jenkins.yaml b/microsite/data/plugins/jenkins.yaml index 0b1c4d3bf4..e57a7e9e7b 100644 --- a/microsite/data/plugins/jenkins.yaml +++ b/microsite/data/plugins/jenkins.yaml @@ -4,9 +4,9 @@ author: '@timja' authorUrl: https://github.com/timja category: CI/CD description: Jenkins offers a simple way to set up a continuous integration and continuous delivery environment. -documentation: https://github.com/backstage/backstage/tree/master/plugins/jenkins +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/jenkins/plugins/jenkins iconUrl: https://img.icons8.com/color/1600/jenkins.png -npmPackageName: '@backstage/plugin-jenkins' +npmPackageName: '@backstage-community/plugin-jenkins' tags: - ci - cd diff --git a/microsite/data/plugins/kafka.yaml b/microsite/data/plugins/kafka.yaml index 9546f8e2fc..7529add2ee 100644 --- a/microsite/data/plugins/kafka.yaml +++ b/microsite/data/plugins/kafka.yaml @@ -4,9 +4,9 @@ author: '@nirga' authorUrl: https://github.com/nirga category: Monitoring description: Observability for Apache Kafka clusters and async API of components. -documentation: https://github.com/backstage/backstage/tree/master/plugins/kafka +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/kafka/plugins/kafka iconUrl: https://kafka.apache.org/images/apache-kafka.png -npmPackageName: '@backstage/plugin-kafka' +npmPackageName: '@backstage-community/plugin-kafka' tags: - monitoring addedDate: '2021-01-21' diff --git a/microsite/data/plugins/library-check.yaml b/microsite/data/plugins/library-check.yaml new file mode 100644 index 0000000000..68489d676f --- /dev/null +++ b/microsite/data/plugins/library-check.yaml @@ -0,0 +1,10 @@ +--- +title: Library Check +author: anakzr +authorUrl: https://github.com/anakzr +category: Services +description: Check the status of project package or library based on main registries +documentation: https://github.com/anakzr/backstage-plugin-library-check +iconUrl: /img/library-check-logo.png +npmPackageName: '@anakz/backstage-plugin-library-check' +addedDate: '2024-03-11' diff --git a/microsite/data/plugins/lighthouse.yaml b/microsite/data/plugins/lighthouse.yaml index 4f302cdb3b..a29e48406a 100644 --- a/microsite/data/plugins/lighthouse.yaml +++ b/microsite/data/plugins/lighthouse.yaml @@ -4,9 +4,9 @@ author: Spotify authorUrl: https://github.com/spotify category: Quality description: Google's Lighthouse tool is a great resource for benchmarking and improving the accessibility, performance, SEO, and best practices of your website. -documentation: https://github.com/backstage/backstage/tree/master/plugins/lighthouse +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/lighthouse/plugins/lighthouse iconUrl: https://seeklogo.com/images/G/google-lighthouse-logo-1C7FA08580-seeklogo.com.png -npmPackageName: '@backstage/plugin-lighthouse' +npmPackageName: '@backstage-community/plugin-lighthouse' tags: - web - seo diff --git a/microsite/data/plugins/microsoft-calendar.yaml b/microsite/data/plugins/microsoft-calendar.yaml index a1eb981dd1..b09493a865 100644 --- a/microsite/data/plugins/microsoft-calendar.yaml +++ b/microsite/data/plugins/microsoft-calendar.yaml @@ -5,8 +5,8 @@ category: Productivity description: | The plugin integrates with your Microsoft Calendar. It displays all your calendars and events in it. -documentation: https://github.com/backstage/backstage/tree/master/plugins/microsoft-calendar -npmPackageName: '@backstage/plugin-microsoft-calendar' +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/microsoft-calendar/plugins/microsoft-calendar +npmPackageName: '@backstage-community/plugin-microsoft-calendar' tags: - Microsoft - calendar diff --git a/microsite/data/plugins/new-relic.yaml b/microsite/data/plugins/new-relic.yaml index a68cc90314..57b2db00ec 100644 --- a/microsite/data/plugins/new-relic.yaml +++ b/microsite/data/plugins/new-relic.yaml @@ -4,9 +4,9 @@ author: '@timwheelercom' authorUrl: https://github.com/timwheelercom category: Monitoring description: Observability platform built to help engineers create and monitor their software. -documentation: https://github.com/backstage/backstage/tree/master/plugins/newrelic +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/newrelic/plugins/newrelic iconUrl: https://www.mulesoft.com/sites/default/files/2018-10/New_relic.png -npmPackageName: '@backstage/plugin-newrelic' +npmPackageName: '@backstage-community/plugin-newrelic' tags: - performance - monitoring diff --git a/microsite/data/plugins/newrelic-dashboard.yaml b/microsite/data/plugins/newrelic-dashboard.yaml index cd68a63165..420c506b35 100644 --- a/microsite/data/plugins/newrelic-dashboard.yaml +++ b/microsite/data/plugins/newrelic-dashboard.yaml @@ -4,9 +4,9 @@ author: '@mufaddal7' authorUrl: https://github.com/mufaddal7 category: Monitoring description: Easily view your New Relic Dashboards in Backstage, via real-time snapshots of your dashboards -documentation: https://github.com/backstage/backstage/tree/master/plugins/newrelic-dashboard +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/newrelic-dashboard/plugins/newrelic-dashboard iconUrl: https://newrelic.com/themes/custom/erno/assets/mediakit/new_relic_logo_vertical_white.svg -npmPackageName: '@backstage/plugin-newrelic-dashboard' +npmPackageName: '@backstage-community/plugin-newrelic-dashboard' tags: - performance - monitoring diff --git a/microsite/data/plugins/opa-permissions-wrapper.yaml b/microsite/data/plugins/opa-permissions-wrapper.yaml new file mode 100644 index 0000000000..64af859dbc --- /dev/null +++ b/microsite/data/plugins/opa-permissions-wrapper.yaml @@ -0,0 +1,10 @@ +--- +title: OPA Permissions Wrapper +author: Peter Macdonald +authorUrl: https://github.com/Parsifal-M +category: Authentication/Authorization +description: Manage your Backstage permissions with OPA (Open Policy Agent)! +documentation: https://github.com/Parsifal-M/backstage-opa-plugins/blob/main/plugins/permission-backend-module-opa-wrapper/README.md +iconUrl: /img/opapermlogo.png +npmPackageName: '@parsifal-m/plugin-permission-backend-module-opa-wrapper' +addedDate: '2024-02-26' diff --git a/microsite/data/plugins/periskop.yaml b/microsite/data/plugins/periskop.yaml index 6b6693b3ef..51e9c37103 100644 --- a/microsite/data/plugins/periskop.yaml +++ b/microsite/data/plugins/periskop.yaml @@ -4,7 +4,7 @@ author: Periskop authorUrl: https://periskop.io/ category: Monitoring description: Periskop is a pull-based, language agnostic exception aggregator for microservice environments. -documentation: https://github.com/backstage/backstage/tree/master/plugins/periskop +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/periskop/plugins/periskop iconUrl: https://raw.githubusercontent.com/periskop-dev/periskop/master/docs/assets/periskop-logo.png -npmPackageName: '@backstage/plugin-periskop' +npmPackageName: '@backstage-community/plugin-periskop' addedDate: '2022-02-25' diff --git a/microsite/data/plugins/playlist.yaml b/microsite/data/plugins/playlist.yaml index 4e7f442e03..2871fb904e 100644 --- a/microsite/data/plugins/playlist.yaml +++ b/microsite/data/plugins/playlist.yaml @@ -4,7 +4,7 @@ author: Phil Kuang authorUrl: https://github.com/kuangp category: Discovery description: Create, share, and follow custom collections of entities available in the Backstage catalog. -documentation: https://github.com/backstage/backstage/tree/master/plugins/playlist +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/playlist/plugins/playlist iconUrl: /img/playlist-logo.png -npmPackageName: '@backstage/plugin-playlist' +npmPackageName: '@backstage-community/plugin-playlist' addedDate: '2022-07-02' diff --git a/microsite/data/plugins/rollbar.yaml b/microsite/data/plugins/rollbar.yaml index 7742e6a231..0dd39d5fe9 100644 --- a/microsite/data/plugins/rollbar.yaml +++ b/microsite/data/plugins/rollbar.yaml @@ -4,7 +4,7 @@ author: '@andrewthauer' authorUrl: https://github.com/andrewthauer category: Monitoring description: View Rollbar errors for your services in Backstage. -documentation: https://github.com/backstage/backstage/tree/master/plugins/rollbar +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/rollbar/plugins/rollbar iconUrl: https://rollbar.com/assets/media/rollbar-mark-color.png -npmPackageName: '@backstage/plugin-rollbar' +npmPackageName: '@backstage-community/plugin-rollbar' addedDate: '2020-11-03' diff --git a/microsite/data/plugins/sentry.yaml b/microsite/data/plugins/sentry.yaml index 7bffdcfd4d..06fb9a5d95 100644 --- a/microsite/data/plugins/sentry.yaml +++ b/microsite/data/plugins/sentry.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Monitoring description: View Sentry issues in Backstage. -documentation: https://github.com/backstage/backstage/tree/master/plugins/sentry +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/sentry/plugins/sentry iconUrl: https://sentry-brand.storage.googleapis.com/sentry-glyph-white.png -npmPackageName: '@backstage/plugin-sentry' +npmPackageName: '@backstage-community/plugin-sentry' addedDate: '2020-11-03' diff --git a/microsite/data/plugins/splunk-on-call.yaml b/microsite/data/plugins/splunk-on-call.yaml index b9021a337d..0eb0ad14da 100644 --- a/microsite/data/plugins/splunk-on-call.yaml +++ b/microsite/data/plugins/splunk-on-call.yaml @@ -4,9 +4,9 @@ author: ayshiff authorUrl: https://github.com/ayshiff category: Monitoring description: Splunk On-Call offers a simple way to identify incidents and escalation policies. -documentation: https://github.com/backstage/backstage/tree/master/plugins/splunk-on-call +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/splunk/plugins/splunk-on-call iconUrl: /img/splunk-black-white-bg.png -npmPackageName: '@backstage/plugin-splunk-on-call' +npmPackageName: '@backstage-community/plugin-splunk-on-call' tags: - monitoring - errors diff --git a/microsite/data/plugins/stackstorm.yaml b/microsite/data/plugins/stackstorm.yaml index ade6ca860f..d264f530f9 100644 --- a/microsite/data/plugins/stackstorm.yaml +++ b/microsite/data/plugins/stackstorm.yaml @@ -4,9 +4,9 @@ author: ExpediaGroup authorUrl: https://github.com/ExpediaGroup category: Automation description: Manage StackStorm workflow executions from within Backstage. -documentation: https://github.com/backstage/backstage/tree/master/plugins/stackstorm +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/stackstorm/plugins/stackstorm iconUrl: /img/stackstorm.png -npmPackageName: '@backstage/plugin-stackstorm' +npmPackageName: '@backstage-community/plugin-stackstorm' tags: - stackstorm - st2 diff --git a/microsite/data/plugins/sysdig.yaml b/microsite/data/plugins/sysdig.yaml new file mode 100644 index 0000000000..220f4468b2 --- /dev/null +++ b/microsite/data/plugins/sysdig.yaml @@ -0,0 +1,10 @@ +--- +title: Sysdig +author: Sysdig +authorUrl: https://sysdig.com/ +category: Security +description: Generate security reports using Sysdig Secure +documentation: https://github.com/sysdiglabs/backstage-plugin-sysdig/blob/main/README.md +iconUrl: https://sysdig.com/wp-content/uploads/sysdig-logo-new-white.svg +npmPackageName: '@sysdig/backstage-plugin-sysdig' +addedDate: '2024-03-06' diff --git a/microsite/data/plugins/tech-radar.yaml b/microsite/data/plugins/tech-radar.yaml index 3187a33d42..37f4e02b92 100644 --- a/microsite/data/plugins/tech-radar.yaml +++ b/microsite/data/plugins/tech-radar.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Discovery description: Visualize the your company's official guidelines of different areas of software development. -documentation: https://github.com/backstage/backstage/tree/master/plugins/tech-radar +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/tech-radar/plugins/tech-radar iconUrl: https://www.materialui.co/materialIcons/action/track_changes_white_192x192.png -npmPackageName: '@backstage/plugin-tech-radar' +npmPackageName: '@backstage-community/plugin-tech-radar' addedDate: '2020-11-03' diff --git a/microsite/data/plugins/todo.yaml b/microsite/data/plugins/todo.yaml index 67a5151a89..ab353e8150 100644 --- a/microsite/data/plugins/todo.yaml +++ b/microsite/data/plugins/todo.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Discovery description: Browse TODO comments in your project's source code. -documentation: https://github.com/backstage/backstage/tree/master/plugins/todo +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/todo/plugins/todo iconUrl: https://backstage.io/img/todo-logo.png -npmPackageName: '@backstage/plugin-todo' +npmPackageName: '@backstage-community/plugin-todo' addedDate: '2021-03-16' diff --git a/microsite/data/plugins/vault.yaml b/microsite/data/plugins/vault.yaml index 37d474371b..1ee14c4bd3 100644 --- a/microsite/data/plugins/vault.yaml +++ b/microsite/data/plugins/vault.yaml @@ -4,9 +4,9 @@ author: Spread Group authorUrl: https://github.com/ivangonzalezacuna category: Security description: Visualize a list of the secrets stored in your HashiCorp Vault instance. -documentation: https://github.com/backstage/backstage/tree/master/plugins/vault +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/vault/plugins/vault iconUrl: /img/vault.png -npmPackageName: '@backstage/plugin-vault' +npmPackageName: '@backstage-community/plugin-vault' tags: - vault addedDate: '2022-06-03' diff --git a/microsite/docusaurus.config.js b/microsite/docusaurus.config.js index 34d882c110..1866deda5c 100644 --- a/microsite/docusaurus.config.js +++ b/microsite/docusaurus.config.js @@ -24,7 +24,7 @@ prismTheme.plain.backgroundColor = '#232323'; /** @type {import('@docusaurus/types').Config} */ module.exports = { title: 'Backstage Software Catalog and Developer Platform', - tagline: 'An open platform for building developer portals', + tagline: 'An open source framework for building developer portals', url: 'https://backstage.io', baseUrl: '/', organizationName: 'Spotify', @@ -70,10 +70,10 @@ module.exports = { ], markdown: { preprocessor({ fileContent }) { - // Replace all HTML comments with emtpy strings as these are not supported by MDXv2. + // Replace all HTML comments with empty strings as these are not supported by MDXv2. return fileContent.replace(/<!--.*?-->/gs, ''); }, - format: 'md', + format: 'detect', }, webpack: { jsLoader: isServer => ({ @@ -95,6 +95,7 @@ module.exports = { plugins: [ 'docusaurus-plugin-sass', () => ({ + name: 'yaml-loader', configureWebpack() { return { module: { @@ -152,9 +153,26 @@ module.exports = { from: '/docs/overview/glossary', to: '/docs/references/glossary', }, + { + from: '/docs/getting-started/create-an-app', + to: '/docs/getting-started/', + }, + { + from: '/docs/getting-started/configuration', + to: '/docs/getting-started/#next-steps', + }, ], }, ], + [ + 'docusaurus-pushfeedback', + { + project: 'q8w1i6cair', + hideIcon: true, + customFont: true, + buttonStyle: 'dark', + }, + ], ], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ @@ -190,7 +208,7 @@ module.exports = { position: 'left', }, { - to: 'docs/releases/v1.22.0', + to: 'docs/releases/v1.26.0', label: 'Releases', position: 'left', }, diff --git a/microsite/package.json b/microsite/package.json index dadc06518d..1be5272286 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -1,32 +1,21 @@ { - "version": "0.0.0", "name": "backstage-microsite", - "license": "Apache-2.0", + "version": "0.0.0", "private": true, + "license": "Apache-2.0", "scripts": { - "start": "node scripts/pre-build.js && docusaurus start", "build": "node scripts/pre-build.js && docusaurus build", - "prettier:fix": "prettier --write .", - "prettier:check": "prettier --check .", - "publish-gh-pages": "docusaurus-publish", - "write-translations": "docusaurus-write-translations", - "version": "docusaurus-version", - "rename-version": "docusaurus-rename-version", - "verify:sidebars": "node ./scripts/verify-sidebars", - "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", - "docusaurus": "docusaurus" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "^3.1.1", - "@spotify/prettier-config": "^14.0.0", - "@tsconfig/docusaurus": "^2.0.0", - "@types/luxon": "^3.0.0", - "@types/webpack-env": "^1.18.0", - "js-yaml": "^4.1.0", - "prettier": "^2.6.2", - "typescript": "~5.1.0", - "yaml-loader": "^0.8.0" + "docusaurus": "docusaurus", + "prettier:check": "prettier --check .", + "prettier:fix": "prettier --write .", + "publish-gh-pages": "docusaurus-publish", + "rename-version": "docusaurus-rename-version", + "start": "node scripts/pre-build.js && docusaurus start", + "swizzle": "docusaurus swizzle", + "verify:sidebars": "node ./scripts/verify-sidebars", + "version": "docusaurus-version", + "write-translations": "docusaurus-write-translations" }, "prettier": "@spotify/prettier-config", "dependencies": { @@ -36,11 +25,23 @@ "@swc/core": "^1.3.46", "clsx": "^2.0.0", "docusaurus-plugin-sass": "^0.2.3", + "docusaurus-pushfeedback": "^1.0.0", "luxon": "^3.0.0", "prism-react-renderer": "^1.3.5", "react": "^18.0.0", "react-dom": "^18.0.0", "sass": "^1.57.1", "swc-loader": "^0.2.3" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "^3.1.1", + "@spotify/prettier-config": "^15.0.0", + "@tsconfig/docusaurus": "^2.0.0", + "@types/luxon": "^3.0.0", + "@types/webpack-env": "^1.18.0", + "js-yaml": "^4.1.0", + "prettier": "^2.6.2", + "typescript": "~5.1.0", + "yaml-loader": "^0.8.0" } } diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 146d8db059..32863c61db 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,10 @@ { "releases": { "Release Notes": [ + "releases/v1.26.0", + "releases/v1.25.0", + "releases/v1.24.0", + "releases/v1.23.0", "releases/v1.22.0", "releases/v1.21.0", "releases/v1.20.0", @@ -41,22 +45,28 @@ ], "Getting Started": [ "getting-started/index", - "getting-started/configuration", - "getting-started/create-an-app", { "type": "category", - "label": "App configuration", + "label": "Configuring Backstage", "items": [ + "getting-started/config/database", + "getting-started/config/authentication", "getting-started/configure-app-with-plugins", "getting-started/app-custom-theme", "getting-started/homepage" ] }, + { + "type": "category", + "label": "Using Backstage", + "items": [ + "getting-started/logging-in", + "getting-started/register-a-component", + "getting-started/create-a-component" + ] + }, "getting-started/keeping-backstage-updated", - "getting-started/concepts", - "getting-started/contributors", - "getting-started/getting-involved", - "getting-started/project-structure" + "getting-started/concepts" ], "Local Development": [ { @@ -100,6 +110,7 @@ "features/kubernetes/installation", "features/kubernetes/configuration", "features/kubernetes/authentication", + "features/kubernetes/authentication-strategies", "features/kubernetes/troubleshooting", "features/kubernetes/proxy" ] @@ -115,6 +126,7 @@ "features/software-templates/input-examples", "features/software-templates/builtin-actions", "features/software-templates/writing-custom-actions", + "features/software-templates/writing-tests-for-actions", "features/software-templates/writing-custom-field-extensions", "features/software-templates/writing-custom-step-layouts", "features/software-templates/authorizing-parameters-steps-and-actions", @@ -306,6 +318,7 @@ "auth/gitlab/provider", "auth/google/provider", "auth/google/gcp-iap-auth", + "auth/guest/provider", "auth/okta/provider", "auth/oauth2-proxy/provider", "auth/onelogin/provider", @@ -387,7 +400,28 @@ { "type": "category", "label": "Core Services", - "items": ["backend-system/core-services/index"] + "items": [ + "backend-system/core-services/index", + "backend-system/core-services/auth", + "backend-system/core-services/cache", + "backend-system/core-services/database", + "backend-system/core-services/discovery", + "backend-system/core-services/http-auth", + "backend-system/core-services/http-router", + "backend-system/core-services/identity", + "backend-system/core-services/lifecycle", + "backend-system/core-services/logger", + "backend-system/core-services/permissions", + "backend-system/core-services/plugin-metadata", + "backend-system/core-services/root-config", + "backend-system/core-services/root-http-router", + "backend-system/core-services/root-lifecycle", + "backend-system/core-services/root-logger", + "backend-system/core-services/scheduler", + "backend-system/core-services/token-manager", + "backend-system/core-services/url-reader", + "backend-system/core-services/user-info" + ] } ], "New Frontend System": [ @@ -414,7 +448,8 @@ "frontend-system/building-plugins/index", "frontend-system/building-plugins/testing", "frontend-system/building-plugins/extension-types", - "frontend-system/building-plugins/built-in-data-refs" + "frontend-system/building-plugins/built-in-data-refs", + "frontend-system/building-plugins/migrating" ] }, { @@ -422,7 +457,9 @@ "label": "Building Apps", "items": [ "frontend-system/building-apps/index", - "frontend-system/building-apps/built-in-extensions" + "frontend-system/building-apps/configuring-extensions", + "frontend-system/building-apps/built-in-extensions", + "frontend-system/building-apps/migrating" ] }, { @@ -432,8 +469,7 @@ "frontend-system/utility-apis/index", "frontend-system/utility-apis/creating", "frontend-system/utility-apis/consuming", - "frontend-system/utility-apis/configuring", - "frontend-system/utility-apis/migrating" + "frontend-system/utility-apis/configuring" ] } ], @@ -468,6 +504,8 @@ "tutorials/using-backstage-proxy-within-plugin", "tutorials/yarn-migration", "tutorials/migrate-to-mui5", + "tutorials/auth-service-migration", + "tutorials/enable-public-entry", "tutorials/setup-opentelemetry" ], "Architecture Decision Records (ADRs)": [ @@ -488,6 +526,11 @@ ], "FAQ": ["faq/index", "faq/product", "faq/technical"], "Accessibility": ["accessibility/index"], + "Contribute": [ + "contribute/index", + "contribute/getting-involved", + "contribute/project-structure" + ], "References": ["references/glossary"] } } diff --git a/microsite/src/pages/community/index.tsx b/microsite/src/pages/community/index.tsx index 42c42ae0c3..c331638c78 100644 --- a/microsite/src/pages/community/index.tsx +++ b/microsite/src/pages/community/index.tsx @@ -73,7 +73,7 @@ const Community = () => { }, { name: 'RedHat', - url: 'https://www.redhat.com/', + url: 'https://developers.redhat.com/rhdh', logo: 'img/partner-logo-redhat.png', }, { @@ -81,14 +81,19 @@ const Community = () => { url: 'https://roadie.io/', logo: 'img/partner-logo-roadie.png', }, + { + name: 'solo.io', + url: 'https://www.solo.io/spotlight/', + logo: 'img/partner-logo-solo.png', + }, { name: 'ThoughtWorks', - url: 'https://www.thoughtworks.com', + url: 'https://www.thoughtworks.com/about-us/partnerships/technology/backstage-by-spotify', logo: 'img/partner-logo-thoughtworks.png', }, { name: 'VMWare', - url: 'https://tanzu.vmware.com/', + url: 'https://tanzu.vmware.com/developer-portal', logo: 'img/partner-logo-tanzubybroadcom.png', }, ]; diff --git a/microsite/src/pages/demos/index.tsx b/microsite/src/pages/demos/index.tsx index e3b4b7dbfd..9f4a4c28c3 100644 --- a/microsite/src/pages/demos/index.tsx +++ b/microsite/src/pages/demos/index.tsx @@ -62,7 +62,7 @@ const Demos = () => { { title: 'Introduction to Backstage', content: - 'Backstage is an open source platform for building developer portals. We’ve been using our homegrown version at Spotify for years — so it’s already packed with features. (We have over 120 internal plugins, built by 60 different teams.) In this live demo recording, Stefan Ålund, product manager for Backstage, tells the origin story of Backstage and gives you a tour of how we use it here at Spotify.', + 'Backstage is an open source framework for building developer portals. We’ve been using our homegrown version at Spotify for years — so it’s already packed with features. (We have over 120 internal plugins, built by 60 different teams.) In this live demo recording, Stefan Ålund, product manager for Backstage, tells the origin story of Backstage and gives you a tour of how we use it here at Spotify.', actionItemLink: 'https://www.youtube.com/watch?v=1XtJ5FAOjPk', media: { type: 'video', diff --git a/microsite/src/pages/home/_home.tsx b/microsite/src/pages/home/_home.tsx index 5cf0f85072..c0cf39ad9c 100644 --- a/microsite/src/pages/home/_home.tsx +++ b/microsite/src/pages/home/_home.tsx @@ -74,7 +74,9 @@ const HomePage = () => { > <ContentBlock className={homeStyles.openPlatformBanner} - title={<h1> An open platform for building developer portals</h1>} + title={ + <h1>An open source framework for building developer portals</h1> + } actionButtons={[ { link: 'https://github.com/backstage/backstage#getting-started', diff --git a/microsite/src/theme/customTheme.scss b/microsite/src/theme/customTheme.scss index b29f76d3c0..51615ed0dc 100644 --- a/microsite/src/theme/customTheme.scss +++ b/microsite/src/theme/customTheme.scss @@ -121,3 +121,26 @@ } /* #endregion */ + +/* For the docusaurus-pushfeedback plugin */ +:root { + --feedback-primary-color: var(--ifm-color-primary); + --feedback-button-dark-text-color: var(--ifm-color-black); + + --feedback-modal-button-submit-bg-color: var(--ifm-color-primary); + --feedback-modal-button-submit-bg-color-hover: var(--ifm-color-primary-dark); + + --feedback-modal-button-submit-text-color: var(--ifm-color-black); + --feedback-modal-button-submit-text-color-hover: var(--ifm-color-black); + + --feedback-button-text-font-size: 1rem; + --feedback-button-text-font-weight: 600; +} + +/* Hide feedback button unless we're in docs */ +feedback-button { + display: none; +} +html.plugin-docs feedback-button { + display: initial; +} diff --git a/microsite/static/img/codacy-icon.svg b/microsite/static/img/codacy-icon.svg new file mode 100644 index 0000000000..ef65004330 --- /dev/null +++ b/microsite/static/img/codacy-icon.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35" color="white" class="css-om3no"><title>codacy-white \ No newline at end of file diff --git a/microsite/static/img/coder.png b/microsite/static/img/coder.png new file mode 100644 index 0000000000..d714ac4190 Binary files /dev/null and b/microsite/static/img/coder.png differ diff --git a/microsite/static/img/dev-friends-days.jpeg b/microsite/static/img/dev-friends-days.jpeg new file mode 100644 index 0000000000..ed864aee53 Binary files /dev/null and b/microsite/static/img/dev-friends-days.jpeg differ diff --git a/microsite/static/img/devcontainers.png b/microsite/static/img/devcontainers.png new file mode 100644 index 0000000000..1e3115d12c Binary files /dev/null and b/microsite/static/img/devcontainers.png differ diff --git a/microsite/static/img/dx-icon.png b/microsite/static/img/dx-icon.png new file mode 100644 index 0000000000..83e4557ffd Binary files /dev/null and b/microsite/static/img/dx-icon.png differ diff --git a/microsite/static/img/dynatrace.svg b/microsite/static/img/dynatrace.svg index de114c0005..863f93c123 100644 --- a/microsite/static/img/dynatrace.svg +++ b/microsite/static/img/dynatrace.svg @@ -1,68 +1,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite/static/img/library-check-logo.png b/microsite/static/img/library-check-logo.png new file mode 100644 index 0000000000..299b1a01e8 Binary files /dev/null and b/microsite/static/img/library-check-logo.png differ diff --git a/microsite/static/img/opapermlogo.png b/microsite/static/img/opapermlogo.png new file mode 100644 index 0000000000..703e53dbf2 Binary files /dev/null and b/microsite/static/img/opapermlogo.png differ diff --git a/microsite/static/img/partner-logo-solo.png b/microsite/static/img/partner-logo-solo.png new file mode 100644 index 0000000000..f4d36ec61a Binary files /dev/null and b/microsite/static/img/partner-logo-solo.png differ diff --git a/microsite/static/img/plugin-feedback-logo.svg b/microsite/static/img/plugin-feedback-logo.svg new file mode 100644 index 0000000000..bd8014f9c7 --- /dev/null +++ b/microsite/static/img/plugin-feedback-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/microsite/static/img/qm-icon.png b/microsite/static/img/qm-icon.png new file mode 100644 index 0000000000..021d24388b Binary files /dev/null and b/microsite/static/img/qm-icon.png differ diff --git a/microsite/blog/assets/2020-08-05/feature.mp4 b/microsite/static/video/software-templates.mp4 similarity index 100% rename from microsite/blog/assets/2020-08-05/feature.mp4 rename to microsite/static/video/software-templates.mp4 diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 6b522f9cf8..259bbca7b0 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -509,7 +509,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.22.7, @babel/parser@npm:^7.23.9": +"@babel/parser@npm:^7.23.9": version: 7.23.9 resolution: "@babel/parser@npm:7.23.9" bin: @@ -1689,9 +1689,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:3.1.1, @docusaurus/core@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/core@npm:3.1.1" +"@docusaurus/core@npm:3.2.1, @docusaurus/core@npm:^3.1.1": + version: 3.2.1 + resolution: "@docusaurus/core@npm:3.2.1" dependencies: "@babel/core": ^7.23.3 "@babel/generator": ^7.23.3 @@ -1703,14 +1703,13 @@ __metadata: "@babel/runtime": ^7.22.6 "@babel/runtime-corejs3": ^7.22.6 "@babel/traverse": ^7.22.8 - "@docusaurus/cssnano-preset": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 + "@docusaurus/cssnano-preset": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 - "@slorber/static-site-generator-webpack-plugin": ^4.0.7 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@svgr/webpack": ^6.5.1 autoprefixer: ^10.4.14 babel-loader: ^9.1.3 @@ -1731,6 +1730,7 @@ __metadata: detect-port: ^1.5.1 escape-html: ^1.0.3 eta: ^2.2.0 + eval: ^0.1.8 file-loader: ^6.2.0 fs-extra: ^11.1.1 html-minifier-terser: ^7.2.0 @@ -1739,6 +1739,7 @@ __metadata: leven: ^3.1.0 lodash: ^4.17.21 mini-css-extract-plugin: ^2.7.6 + p-map: ^4.0.0 postcss: ^8.4.26 postcss-loader: ^7.3.3 prompts: ^2.4.2 @@ -1767,41 +1768,39 @@ __metadata: react-dom: ^18.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: a35851dd6dc5ff5d2c8a8efb36b9875dc33a9e067a4677e5c9437a8635970e55a3cf14bb6eba9c9e356f4189283fb401b39423d497eb17bb09a16dd0ed84b1da + checksum: 9267f08b41240cb9d399abbd8a41ff66e0082551284325db3f17fcce9643bef81d06564797a7cc4c528fe8bde2858c20666e74a0308f3ecc80f3be1dbee14bb5 languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/cssnano-preset@npm:3.1.1" +"@docusaurus/cssnano-preset@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/cssnano-preset@npm:3.2.1" dependencies: cssnano-preset-advanced: ^5.3.10 postcss: ^8.4.26 postcss-sort-media-queries: ^4.4.1 tslib: ^2.6.0 - checksum: 562d96c2ff60826459c255831cd57b12393e6f41b3827c499d43d00ec1887fbeebfea7c68aa72d9e56a5d64419847d11a5d66021acb4f1e3ce4c87b781f33954 + checksum: ee23a1229d23732d936fe1d68732d1305abf0132b43a398336fee500504a3e7566d3b0c6222f89f565e24e68e00e353765e0cbbab5611a3b35ecf88305558b6d languageName: node linkType: hard -"@docusaurus/logger@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/logger@npm:3.1.1" +"@docusaurus/logger@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/logger@npm:3.2.1" dependencies: chalk: ^4.1.2 tslib: ^2.6.0 - checksum: d9673035a7eff14c1820b6c07a07e92a21e7f8e824305a784250d025c79bf9cfc51d0e6007b7660da4f810b78793572d382db48033201902c335c916d735433b + checksum: 9d5db5253eda98871563faddb5318bcb6b17ddf5882ababad4803d526917844819751e84ee8028e794fd5507646db6409f9041fd7f41b7f7971015df11cc6376 languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/mdx-loader@npm:3.1.1" +"@docusaurus/mdx-loader@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/mdx-loader@npm:3.2.1" dependencies: - "@babel/parser": ^7.22.7 - "@babel/traverse": ^7.22.8 - "@docusaurus/logger": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@mdx-js/mdx": ^3.0.0 "@slorber/remark-comment": ^1.0.0 escape-html: ^1.0.3 @@ -1826,16 +1825,16 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: e6b2483b20db41c8264c47edc42e2a738239fbad9b69eb520c7dab421dc2cde4f73f6ec871ccf277dfbc285ae9b202af892771ce800c4ce56739bff6c4c3c231 + checksum: 4609faf2d8b76085a3aa86ac5ca4ac3b3420e3cfd796f1b39c46f368c82b3db0db5b1308646cf35fdad0a1f6f088d367116eb0e2a8c3fa728ed886ee37516476 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:3.1.1, @docusaurus/module-type-aliases@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/module-type-aliases@npm:3.1.1" +"@docusaurus/module-type-aliases@npm:3.2.1, @docusaurus/module-type-aliases@npm:^3.1.1": + version: 3.2.1 + resolution: "@docusaurus/module-type-aliases@npm:3.2.1" dependencies: "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 3.1.1 + "@docusaurus/types": 3.2.1 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -1845,19 +1844,19 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: 937e52b57af5e459df26621dba57a1e399c48ebb1bc0fe10450c0238a79ef76d26a69ba9a42317e236d50bbd6c3e0fbb10fe97f8153373331947b90125aeee38 + checksum: 37b4a40f9afebbe76e350c10c857737b544c141a988462436904ae16993a52e4429018d406e2f55ad57a533e5a108dd7cdb903434abb84721deeec0d5f195d80 languageName: node linkType: hard "@docusaurus/plugin-client-redirects@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-client-redirects@npm:3.1.1" + version: 3.2.1 + resolution: "@docusaurus/plugin-client-redirects@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 eta: ^2.2.0 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -1865,21 +1864,21 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 48a101b88e0f537323cb54c0de6d0a711f7987358699929f0bba17ae60038205a154b2ce179e1a1e065d2732186d23b53f4a1922ca8d875f6aea364abf77bdd7 + checksum: 84f031a9f660028cf745ad4f3b8ea8820e34fdabed75321b06a8145078b3b8c496369c902dc3f46a2bb973cfaaa433474a9891bd836494ff72c65258fa67b64c languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-content-blog@npm:3.1.1" +"@docusaurus/plugin-content-blog@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-content-blog@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 cheerio: ^1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^11.1.1 @@ -1893,21 +1892,22 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 8680e47cc1250cd0c0987c7471e8679860d867de5bf3917e0088185cfa4f5abdb7a847f652cea7c61afbce9dad8bb3cd9f8924b13b064087eab4f9654a9de05d + checksum: d95147a28aad832cd2dc39af634e1902a8a36f958dd2ff5fa6eaa47b574b58df42609a64da823951826f647337ad35c1f1c8be8a0a085913e192936f38839413 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-content-docs@npm:3.1.1" +"@docusaurus/plugin-content-docs@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-content-docs@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/module-type-aliases": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/module-type-aliases": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@types/react-router-config": ^5.0.7 combine-promises: ^1.1.0 fs-extra: ^11.1.1 @@ -1919,133 +1919,133 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 1d96477ca575e01e3e2de080075f07a7f35da7a839632d2ad2d06bf3b651fbd91dd4e70861bb16e1ccb8b2a99f0602461f4c181c04557e0a98ece1b5e5ba61de + checksum: c182466c3ff513b36a8975a3899b07ffc4b227ab45ef69eacc0a77119d6f0cd6a0727a3e886cfcf4a56e4f522f64e1e6a2647ddc57eb8493b93c03240b1d9b39 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-content-pages@npm:3.1.1" +"@docusaurus/plugin-content-pages@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-content-pages@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 fs-extra: ^11.1.1 tslib: ^2.6.0 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ccb9c58802b56c79f2b9bc4445dad316e50438fea995c2a6543637c472c4c2ccfbe3984abb462a1359bce3e3dfad84fecf6e4faab8e242dac4182146043ea005 + checksum: 3cce99f8aa863b97cbb54a50b448073222a0678528b09f5bec2196e73ec4740f412f8675ed05d283ff672756a5d3005f7a1e4d8c8f882cd0d6d5691cbccb604c languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-debug@npm:3.1.1" +"@docusaurus/plugin-debug@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-debug@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 fs-extra: ^11.1.1 react-json-view-lite: ^1.2.0 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 843780bf7eb57d41d198832ad9a7a53e45302c2a10f0221a77c4340e3b1c1dd4e92f77f2ecae3fdb8eef0aed1b7314f2ce1c8323fe25eec759bcde10e0e50149 + checksum: b3fb1c8935463afb97f233042692c247d4147c03e18ef9fb37fbf0c46d4adaefa4af0d5c357025992dadfe7b83a9fd3754946b8947bfb8b9535dca390a3668d0 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-google-analytics@npm:3.1.1" +"@docusaurus/plugin-google-analytics@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-google-analytics@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 4efcaf9f95353485965e299a971e761b3dadac1370d6d8a6582d653535ce76e36b6788283aa1a6dfd7f55ac64fca3d7e97239f94a5163e4cf192a5c2854b1d61 + checksum: e1e881fd6adbe408029257d526759b9217f7d70e5e068c7e9241a5f0c3050b0fa46acfeb4f8a23c3f36e1739d0a3d810642d69c6648ff6801ce13b646e44e6c1 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-google-gtag@npm:3.1.1" +"@docusaurus/plugin-google-gtag@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-google-gtag@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@types/gtag.js": ^0.0.12 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 65ede5352fa16492b23ac37343eb62f4855c4e306ce07552f3257894ddc2329a6244d371bf989bd034cd685965ef8c667d87322497e475d1e54f014fa44225f1 + checksum: b7758289d8453e98baf95d41e754c1e4c8fd5b1c000ba444c4bdf13fc97674a3cddf3215b6406266729e23898641b5bae297c5422c5bd079ef04773fa5a15c1b languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-google-tag-manager@npm:3.1.1" +"@docusaurus/plugin-google-tag-manager@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-google-tag-manager@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 9a1a014a39da0e5ef234c0eb427b7d97b59fd797152c24e05c13a6a11db4269a0223ad474d17714d02a3ad14a97a9072b6757554b3f274b5f0480d7409749a7c + checksum: 82355aed046b12ce0fead68339e24a3c6f2f517bc2b80c9c26c502cc49d86c1b6d0f797d5269d1d5e73ac78fd748c8a2f4528f7f3feee1137ae8e73876426426 languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/plugin-sitemap@npm:3.1.1" +"@docusaurus/plugin-sitemap@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/plugin-sitemap@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 fs-extra: ^11.1.1 sitemap: ^7.1.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 69b584dc9143b816a06eac7bbd13501c201c24dadd339dfd18179f7a7ddcabfe76640fd87ab14f73f624916e74b7192eee5f3aca7e745f2d6a92b5754c8d7bb3 + checksum: b2e4c4fddd0fbdd4a6a4c93a0f9c16b1294162146eb9911ce378f33d70396f08dfa98d92aed133bba2a8df2b1710c257bf00c0657933ee6cd9c5edb36c8054dc languageName: node linkType: hard "@docusaurus/preset-classic@npm:^3.1.1": - version: 3.1.1 - resolution: "@docusaurus/preset-classic@npm:3.1.1" + version: 3.2.1 + resolution: "@docusaurus/preset-classic@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/plugin-content-blog": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/plugin-content-pages": 3.1.1 - "@docusaurus/plugin-debug": 3.1.1 - "@docusaurus/plugin-google-analytics": 3.1.1 - "@docusaurus/plugin-google-gtag": 3.1.1 - "@docusaurus/plugin-google-tag-manager": 3.1.1 - "@docusaurus/plugin-sitemap": 3.1.1 - "@docusaurus/theme-classic": 3.1.1 - "@docusaurus/theme-common": 3.1.1 - "@docusaurus/theme-search-algolia": 3.1.1 - "@docusaurus/types": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/plugin-content-blog": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/plugin-content-pages": 3.2.1 + "@docusaurus/plugin-debug": 3.2.1 + "@docusaurus/plugin-google-analytics": 3.2.1 + "@docusaurus/plugin-google-gtag": 3.2.1 + "@docusaurus/plugin-google-tag-manager": 3.2.1 + "@docusaurus/plugin-sitemap": 3.2.1 + "@docusaurus/theme-classic": 3.2.1 + "@docusaurus/theme-common": 3.2.1 + "@docusaurus/theme-search-algolia": 3.2.1 + "@docusaurus/types": 3.2.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: c0fba593e9d1670ea21b6caefe297ee35ca22f6b8bc63037d8f3fa652d62516494d0a557f8949520424d01a4e92b563800599ec16a1a33655324b42d5f15c55a + checksum: 343c896f22bffbda9db4af7d652588f353c5f60336e545eb07be0dfe9bc29ca04a3978d88d5a8b3fa7caafc56a48b341349ffd08006885fa0d4de216cfdc5401 languageName: node linkType: hard @@ -2061,22 +2061,22 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-classic@npm:3.1.1" +"@docusaurus/theme-classic@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-classic@npm:3.2.1" dependencies: - "@docusaurus/core": 3.1.1 - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/module-type-aliases": 3.1.1 - "@docusaurus/plugin-content-blog": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/plugin-content-pages": 3.1.1 - "@docusaurus/theme-common": 3.1.1 - "@docusaurus/theme-translations": 3.1.1 - "@docusaurus/types": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/module-type-aliases": 3.2.1 + "@docusaurus/plugin-content-blog": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/plugin-content-pages": 3.2.1 + "@docusaurus/theme-common": 3.2.1 + "@docusaurus/theme-translations": 3.2.1 + "@docusaurus/types": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 "@mdx-js/react": ^3.0.0 clsx: ^2.0.0 copy-text-to-clipboard: ^3.2.0 @@ -2093,21 +2093,21 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 8d64676351408e0a378bf9b226cb9cc8f52c8b1f1e03811431de0c7af2aa80445a825267933a4c44ee92d6a975a549c47f4d28798d99cfc0b731f4c4e38f0ba3 + checksum: 7b38e47e9334ba6ad84f6432ec9ae81caad7f6c630b2a332617b0f32f1559b0e56f3d8857c732da62d1d7213ad0f493853bf18b1707a2f8d8bcccef32f1d81a1 languageName: node linkType: hard -"@docusaurus/theme-common@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-common@npm:3.1.1" +"@docusaurus/theme-common@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-common@npm:3.2.1" dependencies: - "@docusaurus/mdx-loader": 3.1.1 - "@docusaurus/module-type-aliases": 3.1.1 - "@docusaurus/plugin-content-blog": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/plugin-content-pages": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-common": 3.1.1 + "@docusaurus/mdx-loader": 3.2.1 + "@docusaurus/module-type-aliases": 3.2.1 + "@docusaurus/plugin-content-blog": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/plugin-content-pages": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -2119,22 +2119,22 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: ba7d2c4032c8d7f822e77bd39a77f712f258e9d4aa44aac75a72ad27c0eaa7400746025ba59e445c9c1b083d2ae02802a759361d67e80b9f7295521520ada1bc + checksum: 13de70293476e05f1b52c2d99a1b26c73bf99ac92aba3c8ddc413b5336725d2b54c56c167d12244fdb0b518ee9cdecbbfb3258fb8cc91272e9b795361b131fbb languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-search-algolia@npm:3.1.1" +"@docusaurus/theme-search-algolia@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-search-algolia@npm:3.2.1" dependencies: "@docsearch/react": ^3.5.2 - "@docusaurus/core": 3.1.1 - "@docusaurus/logger": 3.1.1 - "@docusaurus/plugin-content-docs": 3.1.1 - "@docusaurus/theme-common": 3.1.1 - "@docusaurus/theme-translations": 3.1.1 - "@docusaurus/utils": 3.1.1 - "@docusaurus/utils-validation": 3.1.1 + "@docusaurus/core": 3.2.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/plugin-content-docs": 3.2.1 + "@docusaurus/theme-common": 3.2.1 + "@docusaurus/theme-translations": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-validation": 3.2.1 algoliasearch: ^4.18.0 algoliasearch-helper: ^3.13.3 clsx: ^2.0.0 @@ -2146,23 +2146,23 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 42686e29faf14c482161eb399b1bc9960322f61298b2e6694d1b89374b2f4c352147b2299cf830abb0db8a9eba0bf5d342adfd1ad71101d1aad17f0955856145 + checksum: befbb86bf309f2b770ae21bc1d5c91eb6e840a5a72858cdfd3b21dbabadd1738d6d427ada7745f9d3424bb1a6e01839e20bf35c15a4c13d59b63d259e52de5df languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/theme-translations@npm:3.1.1" +"@docusaurus/theme-translations@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/theme-translations@npm:3.2.1" dependencies: fs-extra: ^11.1.1 tslib: ^2.6.0 - checksum: 4fbf12aef4b6e49182b5fd6ee0c357b4cd1811490713a7cddeb7714eacebf1972dac10f3bb4ee56f6c5e62c297a9a7a17f4e3724e56ad28fa8125073e0c3258e + checksum: 43bdb90d143576d2e8eb56bfe2c9daa0e4250cdb2dcfd10096b86466e6ee253548ac5ef2f9a4986a5bc9a573d118fe4695ee5004f0ef00b57b720dac7f124337 languageName: node linkType: hard -"@docusaurus/types@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/types@npm:3.1.1" +"@docusaurus/types@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/types@npm:3.2.1" dependencies: "@mdx-js/mdx": ^3.0.0 "@types/history": ^4.7.11 @@ -2176,13 +2176,13 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 5041bca00cc887cc3ac8dd8c0895cc778dced2943b2d026fe7d1b8828756257093ad3df05706f344e91710b054f9df0e56d2d369a448472ec173bd81c4a8956f + checksum: 4f19e162bff627675df160ae5c33c6063646050c4de5c9698018fbd9d198300b9ce7a7333e4d1b369b42cfa42296dc9fb36547e4e37664d594deb08639e6b620 languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/utils-common@npm:3.1.1" +"@docusaurus/utils-common@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/utils-common@npm:3.2.1" dependencies: tslib: ^2.6.0 peerDependencies: @@ -2190,28 +2190,30 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 787d930456e4034f7f57186172ad5d214c2473d135ec8c12cf19af8fc64e87eb35a684137e8b813f61e224243c7e3d122c6c646cb20e12ef216048be6a817f44 + checksum: bc0b7e74bc29134dbdb7fbc2e8f9f39f0f460923a07d0ccd7f0542088e92c47faf06bdbd253b7ba2b9250b0869118a3b7bf3faa3a075a2a35f5f8545eb3345f2 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/utils-validation@npm:3.1.1" +"@docusaurus/utils-validation@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/utils-validation@npm:3.2.1" dependencies: - "@docusaurus/logger": 3.1.1 - "@docusaurus/utils": 3.1.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils": 3.2.1 + "@docusaurus/utils-common": 3.2.1 joi: ^17.9.2 js-yaml: ^4.1.0 tslib: ^2.6.0 - checksum: 57d348a4bb2ecac34d84676674c3dc78d6e2821487d5c8a0b9945cab7a4362db5ee2ad084e4bb031b5c4ea674c5136c35090abea2272f57f3b25473c3b1680de + checksum: c7b5142083c8e4798c7f6aa1f7a06bc2e93e8e08a8a7a2c5eaf24aa6939e12e401f180f02164764805c40ec0f7179479e0ee98a935c2cb77037ca73ab33d80fd languageName: node linkType: hard -"@docusaurus/utils@npm:3.1.1": - version: 3.1.1 - resolution: "@docusaurus/utils@npm:3.1.1" +"@docusaurus/utils@npm:3.2.1": + version: 3.2.1 + resolution: "@docusaurus/utils@npm:3.2.1" dependencies: - "@docusaurus/logger": 3.1.1 + "@docusaurus/logger": 3.2.1 + "@docusaurus/utils-common": 3.2.1 "@svgr/webpack": ^6.5.1 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 @@ -2223,6 +2225,7 @@ __metadata: js-yaml: ^4.1.0 lodash: ^4.17.21 micromatch: ^4.0.5 + prompts: ^2.4.2 resolve-pathname: ^3.0.0 shelljs: ^0.8.5 tslib: ^2.6.0 @@ -2233,7 +2236,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 45c39767d1adcc793515109edcb6cfbecd9cf5f979d5dda95a729809b9c30f6288fa5adba757ce131b91b3d77ff24bb7e06ad1b0011d37b45be0035b76ed7ba3 + checksum: ea862b178e303b49e644e77a663df6e42909632022918b77dc1ee69c4de46dde3f210052b1063e96a820e1443141f70e44aa51372f2bf9cfde65e080ea639889 languageName: node linkType: hard @@ -2521,23 +2524,12 @@ __metadata: languageName: node linkType: hard -"@slorber/static-site-generator-webpack-plugin@npm:^4.0.7": - version: 4.0.7 - resolution: "@slorber/static-site-generator-webpack-plugin@npm:4.0.7" - dependencies: - eval: ^0.1.8 - p-map: ^4.0.0 - webpack-sources: ^3.2.2 - checksum: a1e1d8b22dd51059524993f3fdd6861db10eb950debc389e5dd650702287fa2004eace03e6bc8f25b977bd7bc01d76a50aa271cbb73c58a8ec558945d728f307 - languageName: node - linkType: hard - -"@spotify/prettier-config@npm:^14.0.0": - version: 14.1.3 - resolution: "@spotify/prettier-config@npm:14.1.3" +"@spotify/prettier-config@npm:^15.0.0": + version: 15.0.0 + resolution: "@spotify/prettier-config@npm:15.0.0" peerDependencies: prettier: 2.x - checksum: 0c64ec0de9be5ae24a9b2a8f5c3af6c02306a47f54fffbd014852b00245fc939f3131eeeac8e906dfbb6aa86a5c0213b7f35623badad072979068f8cd69c316f + checksum: aa5ec5739427f9acdb9d62ae6c04f04a344898567239f7ee45c75c6205ebdffbc61747ea8de6e83baf0bc3785359967de4b7097a8723c4b4063ff57dc5cb6c44 languageName: node linkType: hard @@ -2697,90 +2689,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-darwin-arm64@npm:1.4.1" +"@swc/core-darwin-arm64@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-darwin-arm64@npm:1.5.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-darwin-x64@npm:1.4.1" +"@swc/core-darwin-x64@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-darwin-x64@npm:1.5.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.4.1" +"@swc/core-linux-arm-gnueabihf@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm64-gnu@npm:1.4.1" +"@swc/core-linux-arm64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm64-gnu@npm:1.5.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm64-musl@npm:1.4.1" +"@swc/core-linux-arm64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm64-musl@npm:1.5.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-x64-gnu@npm:1.4.1" +"@swc/core-linux-x64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-x64-gnu@npm:1.5.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-x64-musl@npm:1.4.1" +"@swc/core-linux-x64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-x64-musl@npm:1.5.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-arm64-msvc@npm:1.4.1" +"@swc/core-win32-arm64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-arm64-msvc@npm:1.5.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-ia32-msvc@npm:1.4.1" +"@swc/core-win32-ia32-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-ia32-msvc@npm:1.5.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-x64-msvc@npm:1.4.1" +"@swc/core-win32-x64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-x64-msvc@npm:1.5.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.4.1 - resolution: "@swc/core@npm:1.4.1" + version: 1.5.0 + resolution: "@swc/core@npm:1.5.0" dependencies: - "@swc/core-darwin-arm64": 1.4.1 - "@swc/core-darwin-x64": 1.4.1 - "@swc/core-linux-arm-gnueabihf": 1.4.1 - "@swc/core-linux-arm64-gnu": 1.4.1 - "@swc/core-linux-arm64-musl": 1.4.1 - "@swc/core-linux-x64-gnu": 1.4.1 - "@swc/core-linux-x64-musl": 1.4.1 - "@swc/core-win32-arm64-msvc": 1.4.1 - "@swc/core-win32-ia32-msvc": 1.4.1 - "@swc/core-win32-x64-msvc": 1.4.1 + "@swc/core-darwin-arm64": 1.5.0 + "@swc/core-darwin-x64": 1.5.0 + "@swc/core-linux-arm-gnueabihf": 1.5.0 + "@swc/core-linux-arm64-gnu": 1.5.0 + "@swc/core-linux-arm64-musl": 1.5.0 + "@swc/core-linux-x64-gnu": 1.5.0 + "@swc/core-linux-x64-musl": 1.5.0 + "@swc/core-win32-arm64-msvc": 1.5.0 + "@swc/core-win32-ia32-msvc": 1.5.0 + "@swc/core-win32-x64-msvc": 1.5.0 "@swc/counter": ^0.1.2 "@swc/types": ^0.1.5 peerDependencies: @@ -2809,7 +2801,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 3549b4a0ba8201be2dd39954ef8375df5d028da5688a68211dc5cbf69ff7a43533e9ffd36f629095f51555552f4df52116384ef779d5ec45c2b9de938e651d57 + checksum: 1abab0b57755020b60ebf2557629c23c65c3546e4cd80f9d02fbdf208d4169c9300a0229c088081b43a01e630c9d86d02f8c240c9fc2842eaed2a517770fcd1d languageName: node linkType: hard @@ -2851,9 +2843,9 @@ __metadata: linkType: hard "@tsconfig/docusaurus@npm:^2.0.0": - version: 2.0.2 - resolution: "@tsconfig/docusaurus@npm:2.0.2" - checksum: 129f2532172496c108f53a15082e410b418e664c1761902664558059541a6cf7faff2b3d2953e2d507a7e3688afacf2479e17adcb35b89cae04ddb0415d0397a + version: 2.0.3 + resolution: "@tsconfig/docusaurus@npm:2.0.3" + checksum: d8245a64bf131daa0c287649cb9c37ad8fecb2aedea18e15047e0df6463916e5012af3755bd73ecf90999ace1f14a3748a8b3e041d5158e2a85c22a539c649c9 languageName: node linkType: hard @@ -3855,13 +3847,14 @@ __metadata: "@docusaurus/module-type-aliases": ^3.1.1 "@docusaurus/plugin-client-redirects": ^3.1.1 "@docusaurus/preset-classic": ^3.1.1 - "@spotify/prettier-config": ^14.0.0 + "@spotify/prettier-config": ^15.0.0 "@swc/core": ^1.3.46 "@tsconfig/docusaurus": ^2.0.0 "@types/luxon": ^3.0.0 "@types/webpack-env": ^1.18.0 clsx: ^2.0.0 docusaurus-plugin-sass: ^0.2.3 + docusaurus-pushfeedback: ^1.0.0 js-yaml: ^4.1.0 luxon: ^3.0.0 prettier: ^2.6.2 @@ -3910,12 +3903,12 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.1": - version: 1.20.1 - resolution: "body-parser@npm:1.20.1" +"body-parser@npm:1.20.2": + version: 1.20.2 + resolution: "body-parser@npm:1.20.2" dependencies: bytes: 3.1.2 - content-type: ~1.0.4 + content-type: ~1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 @@ -3923,10 +3916,10 @@ __metadata: iconv-lite: 0.4.24 on-finished: 2.4.1 qs: 6.11.0 - raw-body: 2.5.1 + raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: f1050dbac3bede6a78f0b87947a8d548ce43f91ccc718a50dd774f3c81f2d8b04693e52acf62659fad23101827dd318da1fb1363444ff9a8482b886a3e4a5266 + checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 languageName: node linkType: hard @@ -4554,10 +4547,10 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4": - version: 1.0.4 - resolution: "content-type@npm:1.0.4" - checksum: 3d93585fda985d1554eca5ebd251994327608d2e200978fdbfba21c0c679914d5faf266d17027de44b34a72c7b0745b18584ecccaa7e1fdfb6a68ac7114f12e0 +"content-type@npm:~1.0.4, content-type@npm:~1.0.5": + version: 1.0.5 + resolution: "content-type@npm:1.0.5" + checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 languageName: node linkType: hard @@ -4575,10 +4568,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.5.0": - version: 0.5.0 - resolution: "cookie@npm:0.5.0" - checksum: 1f4bd2ca5765f8c9689a7e8954183f5332139eb72b6ff783d8947032ec1fdf43109852c178e21a953a30c0dd42257828185be01b49d1eb1a67fd054ca588a180 +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 languageName: node linkType: hard @@ -5115,6 +5108,15 @@ __metadata: languageName: node linkType: hard +"docusaurus-pushfeedback@npm:^1.0.0": + version: 1.0.0 + resolution: "docusaurus-pushfeedback@npm:1.0.0" + peerDependencies: + "@docusaurus/core": 3.x + checksum: 5f119fac4b18198ecab7ca3892b8d19ea21c1f4147b7500de0f2a341651630ff090e38ac4984e33d87729f1b00d621ae8945efe2a2ea37b9a74b76c7f468f21e + languageName: node + linkType: hard + "dom-converter@npm:^0.2.0": version: 0.2.0 resolution: "dom-converter@npm:0.2.0" @@ -5561,15 +5563,15 @@ __metadata: linkType: hard "express@npm:^4.17.3": - version: 4.18.2 - resolution: "express@npm:4.18.2" + version: 4.19.2 + resolution: "express@npm:4.19.2" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.1 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: ~1.0.4 - cookie: 0.5.0 + cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 @@ -5595,7 +5597,7 @@ __metadata: type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 3c4b9b076879442f6b968fe53d85d9f1eeacbb4f4c41e5f16cc36d77ce39a2b0d81b3f250514982110d815b2f7173f5561367f9110fcc541f9371948e8c8b037 + checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 languageName: node linkType: hard @@ -5770,12 +5772,12 @@ __metadata: linkType: hard "follow-redirects@npm:^1.0.0": - version: 1.15.4 - resolution: "follow-redirects@npm:1.15.4" + version: 1.15.6 + resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: debug: optional: true - checksum: e178d1deff8b23d5d24ec3f7a94cde6e47d74d0dc649c35fc9857041267c12ec5d44650a0c5597ef83056ada9ea6ca0c30e7c4f97dbf07d035086be9e6a5b7b6 + checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5 languageName: node linkType: hard @@ -5903,7 +5905,7 @@ __metadata: "fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 - resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" dependencies: node-gyp: latest conditions: os=darwin @@ -6757,9 +6759,9 @@ __metadata: linkType: hard "ip@npm:^2.0.0": - version: 2.0.0 - resolution: "ip@npm:2.0.0" - checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349 + version: 2.0.1 + resolution: "ip@npm:2.0.1" + checksum: d765c9fd212b8a99023a4cde6a558a054c298d640fec1020567494d257afd78ca77e37126b1a3ef0e053646ced79a816bf50621d38d5e768cdde0431fa3b0d35 languageName: node linkType: hard @@ -8484,12 +8486,10 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^4.0.0": - version: 4.0.0 - resolution: "minipass@npm:4.0.0" - dependencies: - yallist: ^4.0.0 - checksum: 7a609afbf394abfcf9c48e6c90226f471676c8f2a67f07f6838871afb03215ede431d1433feffe1b855455bcb13ef0eb89162841b9796109d6fed8d89790f381 +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea languageName: node linkType: hard @@ -9758,15 +9758,15 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.1": - version: 2.5.1 - resolution: "raw-body@npm:2.5.1" +"raw-body@npm:2.5.2": + version: 2.5.2 + resolution: "raw-body@npm:2.5.2" dependencies: bytes: 3.1.2 http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 - checksum: 5362adff1575d691bb3f75998803a0ffed8c64eabeaa06e54b4ada25a0cd1b2ae7f4f5ec46565d1bec337e08b5ac90c76eaa0758de6f72a633f025d754dec29e + checksum: ba1583c8d8a48e8fbb7a873fdbb2df66ea4ff83775421bfe21ee120140949ab048200668c47d9ae3880012f6e217052690628cf679ddfbd82c9fc9358d574676 languageName: node linkType: hard @@ -10263,7 +10263,7 @@ __metadata: "resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin": version: 1.22.1 - resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b" + resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=c3c19d" dependencies: is-core-module: ^2.9.0 path-parse: ^1.0.7 @@ -10392,15 +10392,15 @@ __metadata: linkType: hard "sass@npm:^1.57.1": - version: 1.71.0 - resolution: "sass@npm:1.71.0" + version: 1.75.0 + resolution: "sass@npm:1.75.0" dependencies: chokidar: ">=3.0.0 <4.0.0" immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 5ba6b4b994c7ae94286919d8be8a3692038c27175b4ad3a3ac43f51a91188590d3ddd3a0ef1022135503b9d70d0732efdbedfd56f3ee1a4651549f5b13f8942f + checksum: bfb9f5ddb6a2e1fe0c1ba6191cdb17afa7b40c1eb892c7152f6a29ff2b06dc7a510bdb648f8cca0179dcb3965920ebeb8894f0710b0b450a99db563831345033 languageName: node linkType: hard @@ -11112,16 +11112,16 @@ __metadata: linkType: hard "tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.1.13 - resolution: "tar@npm:6.1.13" + version: 6.2.1 + resolution: "tar@npm:6.2.1" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 - minipass: ^4.0.0 + minipass: ^5.0.0 minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: 8a278bed123aa9f53549b256a36b719e317c8b96fe86a63406f3c62887f78267cea9b22dc6f7007009738509800d4a4dccc444abd71d762287c90f35b002eb1c + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c languageName: node linkType: hard @@ -11285,11 +11285,11 @@ __metadata: "typescript@patch:typescript@~5.1.0#~builtin": version: 5.1.6 - resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=a1c5e5" + resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=5da071" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 21e88b0a0c0226f9cb9fd25b9626fb05b4c0f3fddac521844a13e1f30beb8f14e90bd409a9ac43c812c5946d714d6e0dee12d5d02dfc1c562c5aacfa1f49b606 + checksum: f53bfe97f7c8b2b6d23cf572750d4e7d1e0c5fff1c36d859d0ec84556a827b8785077bc27676bf7e71fae538e517c3ecc0f37e7f593be913d884805d931bc8be languageName: node linkType: hard @@ -11652,8 +11652,8 @@ __metadata: linkType: hard "webpack-dev-middleware@npm:^5.3.1": - version: 5.3.3 - resolution: "webpack-dev-middleware@npm:5.3.3" + version: 5.3.4 + resolution: "webpack-dev-middleware@npm:5.3.4" dependencies: colorette: ^2.0.10 memfs: ^3.4.3 @@ -11662,7 +11662,7 @@ __metadata: schema-utils: ^4.0.0 peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: dd332cc6da61222c43d25e5a2155e23147b777ff32fdf1f1a0a8777020c072fbcef7756360ce2a13939c3f534c06b4992a4d659318c4a7fe2c0530b52a8a6621 + checksum: 90cf3e27d0714c1a745454a1794f491b7076434939340605b9ee8718ba2b85385b120939754e9fdbd6569811e749dee53eec319e0d600e70e0b0baffd8e3fb13 languageName: node linkType: hard @@ -11723,7 +11723,7 @@ __metadata: languageName: node linkType: hard -"webpack-sources@npm:^3.2.2, webpack-sources@npm:^3.2.3": +"webpack-sources@npm:^3.2.3": version: 3.2.3 resolution: "webpack-sources@npm:3.2.3" checksum: 989e401b9fe3536529e2a99dac8c1bdc50e3a0a2c8669cbafad31271eadd994bc9405f88a3039cd2e29db5e6d9d0926ceb7a1a4e7409ece021fe79c37d9c4607 @@ -11939,13 +11939,13 @@ __metadata: linkType: hard "yaml-loader@npm:^0.8.0": - version: 0.8.0 - resolution: "yaml-loader@npm:0.8.0" + version: 0.8.1 + resolution: "yaml-loader@npm:0.8.1" dependencies: javascript-stringify: ^2.0.1 loader-utils: ^2.0.0 yaml: ^2.0.0 - checksum: d12dd264666b80baec23cea9f81cb677a9102d6f34ab45d8b6c085ace4d05b7285db9ce317db57264c3317af01128ce6e5b754e6866d15ccd75e8141902fb529 + checksum: 2969eb7d6083a95a8d95369906bbc73d124125be5f61556506d230a57b7acc872abe836bf631f89aa97d9e8198bee8d100fa68d5a6524be84cd8eb5062cf76d3 languageName: node linkType: hard diff --git a/mkdocs.yml b/mkdocs.yml index 2a17613672..7ba6fdfefa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,5 @@ site_name: 'Backstage' -site_description: 'Main documentation for Backstage features and platform APIs' +site_description: 'Main documentation for Backstage features and framework APIs' repo_url: https://github.com/backstage/backstage edit_uri: edit/master/docs @@ -20,14 +20,19 @@ nav: - Support and community: 'overview/support.md' - Logo assets: 'overview/logos.md' - Getting Started: - - Getting Started: 'getting-started/index.md' - - Create an App: 'getting-started/create-an-app.md' - - App configuration: + - Installing a standalone server: 'getting-started/index.md' + - Configuring Backstage: + - Database: 'getting-started/config/database.md' + - Authentication: 'getting-started/config/authentication.md' - Configuring App with plugins: 'getting-started/configure-app-with-plugins.md' - Customize the look-and-feel of your App: 'getting-started/app-custom-theme.md' + - Customizing your Homepage: 'getting-started/homepage.md' + - Using Backstage: + - Logging in: 'getting-started/logging-in.md' + - Register a component: 'getting-started/register-a-component.md' + - Create a component: 'getting-started/create-a-component.md' - Keeping Backstage Updated: 'getting-started/keeping-backstage-updated.md' - Key Concepts: 'getting-started/concepts.md' - - Project Structure: 'getting-started/project-structure.md' - Local Development: - CLI: - Overview: 'local-dev/cli-overview.md' @@ -90,6 +95,8 @@ nav: - AWS S3: - Locations: 'integrations/aws-s3/locations.md' - Discovery: 'integrations/aws-s3/discovery.md' + - AWS CodeCommit: + - Locations: 'integrations/aws-codecommit/locations.md' - Azure: - Locations: 'integrations/azure/locations.md' - Discovery: 'integrations/azure/discovery.md' @@ -161,6 +168,7 @@ nav: - GitLab: 'auth/gitlab/provider.md' - Google: 'auth/google/provider.md' - Google IAP: 'auth/google/gcp-iap-auth.md' + - Guest: 'auth/guest/provider.md' - OAuth2Proxy: 'auth/oauth2-proxy/provider.md' - Okta: 'auth/okta/provider.md' - OneLogin: 'auth/onelogin/provider.md' @@ -210,11 +218,14 @@ nav: - ADR009 - Entity References: 'architecture-decisions/adr009-entity-references.md' - ADR010 - Luxon Date Library: 'architecture-decisions/adr010-luxon-date-library.md' - ADR011 - Plugin Package Structure: 'architecture-decisions/adr011-plugin-package-structure.md' - - ADR012 - Plugin Package Structure: 'architecture-decisions/adr012-use-luxon-locale-and-date-presets.md' - - ADR013 - Plugin Package Structure: 'architecture-decisions/adr013-use-node-fetch.md' + - ADR012 - Use Luxon Locale: 'architecture-decisions/adr012-use-luxon-locale-and-date-presets.md' + - ADR013 - Use node-fetch: 'architecture-decisions/adr013-use-node-fetch.md' - FAQ: - Overview: 'faq/index.md' - Product FAQ: 'faq/product.md' - Technical FAQ: 'faq/technical.md' + - Contribute: + - Contributions: 'contribute/index.md' + - Project Structure: 'contribute/project-structure.md' - References: - Glossary: 'references/glossary.md' diff --git a/package.json b/package.json index e224d1e58a..abae1b54ec 100644 --- a/package.json +++ b/package.json @@ -1,50 +1,7 @@ { "name": "root", + "version": "1.27.0-next.0", "private": true, - "engines": { - "node": "18 || 20" - }, - "scripts": { - "dev": "concurrently 'yarn start' 'yarn start-backend'", - "dev:next": "concurrently 'yarn start:next' 'yarn start-backend:next'", - "start": "yarn workspace example-app start", - "start-backend": "yarn workspace example-backend start", - "start:next": "yarn workspace example-app-next start", - "start-backend:next": "yarn workspace example-backend-next start", - "start:microsite": "cd microsite/ && yarn start", - "build:backend": "yarn workspace example-backend build", - "build:all": "backstage-cli repo build --all", - "build:api-reports": "yarn build:api-reports:only --tsc", - "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", - "build:knip-reports": "backstage-repo-tools knip-reports", - "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", - "build:plugins-report": "node ./scripts/build-plugins-report", - "tsc": "tsc", - "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false", - "clean": "backstage-cli repo clean", - "test": "backstage-cli repo test", - "test:all": "backstage-cli repo test --coverage", - "test:e2e": "playwright test", - "fix": "backstage-cli repo fix", - "lint": "backstage-cli repo lint --since origin/master", - "lint:docs": "node ./scripts/check-docs-quality", - "lint:all": "backstage-cli repo lint", - "lint:type-deps": "backstage-repo-tools type-deps", - "docker-build": "yarn tsc && yarn workspace example-backend build && yarn workspace example-backend build-image", - "new": "backstage-cli new --scope backstage --baseVersion 0.0.0 --no-private", - "create-plugin": "echo \"use 'yarn new' instead\"", - "release": "node scripts/prepare-release.js && changeset version && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' '.changeset/*.json' && yarn install --no-immutable", - "prettier:check": "prettier --check .", - "prettier:fix": "prettier --write .", - "storybook": "yarn ./storybook run start", - "snyk:test": "npx snyk test --yarn-workspaces --strict-out-of-sync=false", - "snyk:test:package": "yarn snyk:test --include", - "build-storybook": "yarn ./storybook run build-storybook", - "techdocs-cli": "node scripts/techdocs-cli.js", - "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", - "prepare": "husky", - "postinstall": "husky || true" - }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage" @@ -55,14 +12,84 @@ "plugins/*" ] }, + "scripts": { + "build-storybook": "yarn ./storybook run build-storybook", + "build:all": "backstage-cli repo build --all", + "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", + "build:api-reports": "yarn build:api-reports:only --tsc", + "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", + "build:backend": "yarn workspace example-backend build", + "build:knip-reports": "backstage-repo-tools knip-reports", + "build:plugins-report": "node ./scripts/build-plugins-report", + "clean": "backstage-cli repo clean", + "create-plugin": "echo \"use 'yarn new' instead\"", + "dev": "yarn workspaces foreach -A --include example-backend --include example-app --parallel -v -i run start", + "dev:next": "yarn workspaces foreach -A --include example-backend-next --include example-app-next --parallel -v -i run start", + "docker-build": "yarn tsc && yarn workspace example-backend build && yarn workspace example-backend build-image", + "fix": "backstage-cli repo fix", + "postinstall": "husky || true", + "lint": "backstage-cli repo lint --since origin/master", + "lint:all": "backstage-cli repo lint", + "lint:docs": "node ./scripts/check-docs-quality", + "lint:type-deps": "backstage-repo-tools type-deps", + "new": "backstage-cli new --scope backstage --baseVersion 0.0.0 --no-private", + "prepare": "husky", + "prettier:check": "prettier --check .", + "prettier:fix": "prettier --write .", + "release": "node scripts/prepare-release.js && changeset version && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' '.changeset/*.json' && yarn install --no-immutable", + "snyk:test": "npx snyk test --yarn-workspaces --strict-out-of-sync=false", + "snyk:test:package": "yarn snyk:test --include", + "start": "yarn workspace example-app start", + "start-backend": "yarn workspace example-backend start", + "start-backend:next": "yarn workspace example-backend-next start", + "start:lighthouse": "yarn workspaces foreach -A --include example-backend-next --include example-app --parallel -v -i run start", + "start:microsite": "cd microsite/ && yarn start", + "start:next": "yarn workspace example-app-next start", + "storybook": "yarn --cwd storybook && yarn --cwd storybook start", + "techdocs-cli": "node scripts/techdocs-cli.js", + "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", + "test": "backstage-cli repo test", + "test:all": "backstage-cli repo test --coverage", + "test:e2e": "playwright test", + "tsc": "tsc", + "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx,mjs,cjs}": [ + "eslint --fix", + "prettier --write" + ], + "*.json": [ + "prettier --write" + ], + "*.md": [ + "prettier --write", + "node ./scripts/check-docs-quality" + ], + "{plugins,packages}/*/catalog-info.yaml": [ + "yarn backstage-repo-tools generate-catalog-info --ci" + ], + ".github/CODEOWNERS": [ + "yarn backstage-repo-tools generate-catalog-info", + "git add */catalog-info.yaml" + ], + "package.json": [ + "yarn backstage-repo-tools generate-catalog-info", + "git add */catalog-info.yaml", + "node ./scripts/sort-package-json.mjs" + ], + "yarn.lock": [ + "node ./scripts/verify-lockfile-duplicates --fix" + ] + }, + "prettier": "@spotify/prettier-config", "resolutions": { + "@material-ui/pickers@^3.2.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", + "@material-ui/pickers@^3.3.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", "@types/react": "^18", "@types/react-dom": "^18", - "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch", - "@material-ui/pickers@^3.3.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch", - "@material-ui/pickers@^3.2.10": "patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch" + "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch" }, - "version": "1.23.0-next.3", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", @@ -77,13 +104,13 @@ "@changesets/cli": "^2.14.0", "@octokit/rest": "^19.0.3", "@playwright/test": "^1.32.3", - "@spotify/eslint-plugin": "^14.1.3", - "@spotify/prettier-config": "^14.0.0", + "@spotify/eslint-plugin": "^15.0.0", + "@spotify/prettier-config": "^15.0.0", "@techdocs/cli": "workspace:*", "@types/node": "^18.17.8", "@types/webpack": "^5.28.0", + "array-to-table": "^1.0.1", "command-exists": "^1.2.9", - "concurrently": "^8.0.0", "cross-env": "^7.0.0", "e2e-test": "workspace:*", "eslint": "^8.6.0", @@ -100,34 +127,11 @@ "semver": "^7.5.3", "shx": "^0.3.2", "sloc": "^0.3.1", - "ts-node": "^10.4.0", + "sort-package-json": "^2.8.0", "typescript": "~5.1.0" }, - "prettier": "@spotify/prettier-config", - "lint-staged": { - "*.{js,jsx,ts,tsx,mjs,cjs}": [ - "eslint --fix", - "prettier --write" - ], - "*.{json,md}": [ - "prettier --write" - ], - "*.md": [ - "node ./scripts/check-docs-quality" - ], - "{plugins,packages}/*/catalog-info.yaml": [ - "yarn backstage-repo-tools generate-catalog-info --ci" - ], - "{.github/CODEOWNERS,package.json}": [ - "yarn backstage-repo-tools generate-catalog-info", - "git add */catalog-info.yaml" - ], - "./yarn.lock": [ - "node ./scripts/verify-lockfile-duplicates --fix" - ], - "*/yarn.lock": [ - "node ./scripts/verify-lockfile-duplicates --fix" - ] - }, - "packageManager": "yarn@3.2.3" + "packageManager": "yarn@3.8.1", + "engines": { + "node": "18 || 20" + } } diff --git a/packages/app-defaults/.eslintrc.js b/packages/app-defaults/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/packages/app-defaults/.eslintrc.js +++ b/packages/app-defaults/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 0d6ad6c66f..9efa40b6cc 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,139 @@ # @backstage/app-defaults +## 1.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/plugin-permission-react@0.4.22 + +## 1.5.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-permission-react@0.4.22 + +## 1.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## 1.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## 1.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## 1.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/core-app-api@1.12.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-permission-react@0.4.21 + +## 1.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-permission-react@0.4.21 + +## 1.5.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-permission-react@0.4.21-next.1 + +## 1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/theme@0.5.2-next.0 + +## 1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## 1.5.0 + +### Minor Changes + +- f919be9: Added a utility API for VMware Cloud auth; the API ref is available in the + `@backstage/core-plugin-api` and `@backstage/frontend-plugin-api` packages, the + implementation is in `@backstage/core-app-api` and a factory has been added to + `@backstage/app-defaults`. +- 7f11009: Added stack trace display to `ErrorPage` and updated existing refs + +### Patch Changes + +- f899eec: Change default icon for `kind:resource` to the storage icon. +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 7da67ce: Change `defaultScopes` for Bitbucket auth from invalid `team` to `account`. +- 214f2da: Fix invalid HTTP status code 501 in Error Page +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-permission-react@0.4.20 + ## 1.5.0-next.3 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 4f5d76829b..ad9986a29a 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/app-defaults", + "version": "1.5.5-next.0", "description": "Provides the default wiring of a Backstage App", - "version": "1.5.0-next.3", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/app-defaults" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-app-api": "workspace:^", @@ -41,19 +44,16 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/app-next-example-plugin/.eslintrc.js b/packages/app-next-example-plugin/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/packages/app-next-example-plugin/.eslintrc.js +++ b/packages/app-next-example-plugin/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index 4945a70bd6..33f564936a 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,93 @@ # app-next-example-plugin +## 0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/frontend-plugin-api@0.6.5-next.0 + +## 0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/frontend-plugin-api@0.6.4 + +## 0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-components@0.14.4-next.0 + +## 0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.0 + +## 0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + +## 0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/frontend-plugin-api@0.6.2 + +## 0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/frontend-plugin-api@0.6.1 + +## 0.0.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + +## 0.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + +## 0.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + +## 0.0.6 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + ## 0.0.6-next.3 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 1a095ea511..acd85fc7cb 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,54 +1,54 @@ { "name": "app-next-example-plugin", + "version": "0.0.11-next.0", "description": "Backstage internal example plugin", - "version": "0.0.6-next.3", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, "private": true, - "backstage": { - "role": "frontend-plugin" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "packages/app-next-example-plugin" }, - "keywords": [ - "backstage" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@material-ui/icons": "^4.9.1" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "cross-fetch": "^4.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/packages/app-next/.eslintrc.js b/packages/app-next/.eslintrc.js index e2a53a6ad2..6f6668b53d 100644 --- a/packages/app-next/.eslintrc.js +++ b/packages/app-next/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 8c03638e13..1188aff451 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,808 @@ # example-app-next +## 0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications@0.2.1-next.0 + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/plugin-api-docs@0.11.5-next.0 + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/plugin-home@0.7.4-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-techdocs@1.10.5-next.0 + - @backstage/cli@0.26.5-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-scaffolder-react@1.8.5-next.0 + - @backstage/plugin-scaffolder@1.19.4-next.0 + - @backstage/plugin-catalog-graph@0.4.5-next.0 + - @backstage/plugin-catalog-import@0.10.11-next.0 + - @backstage/plugin-org@0.6.25-next.0 + - @backstage/plugin-search@1.4.11-next.0 + - @backstage/plugin-user-settings@0.8.6-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.4-next.0 + - @backstage/plugin-kubernetes@0.11.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.11-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/app-defaults@1.5.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-app-api@0.6.5-next.0 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-app-visualizer@0.1.6-next.0 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + - @backstage/plugin-signals@0.0.6-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.10-next.0 + +## 0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.4.3 + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-github-actions@0.6.15 + - @backstage/cli@0.26.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/plugin-gocd@0.1.40 + - @backstage/frontend-app-api@0.6.4 + - @backstage/plugin-scaffolder@1.19.3 + - @backstage/plugin-graphiql@0.3.7 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/plugin-cloudbuild@0.5.1 + - @backstage/core-app-api@1.12.4 + - @backstage/app-defaults@1.5.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/plugin-adr@0.6.17 + - @backstage/plugin-airbrake@0.3.34 + - @backstage/plugin-apache-airflow@0.2.24 + - @backstage/plugin-api-docs@0.11.4 + - @backstage/plugin-azure-sites@0.1.23 + - @backstage/plugin-catalog-graph@0.4.4 + - @backstage/plugin-catalog-import@0.10.10 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3 + - @backstage/plugin-code-coverage@0.2.27 + - @backstage/plugin-cost-insights@0.12.23 + - @backstage/plugin-dynatrace@10.0.3 + - @backstage/plugin-entity-feedback@0.2.17 + - @backstage/plugin-explore@0.4.20 + - @backstage/plugin-gcalendar@0.3.27 + - @backstage/plugin-gcp-projects@0.3.50 + - @backstage/plugin-home@0.7.3 + - @backstage/plugin-jenkins@0.9.9 + - @backstage/plugin-kafka@0.3.34 + - @backstage/plugin-kubernetes@0.11.9 + - @backstage/plugin-lighthouse@0.4.19 + - @backstage/plugin-microsoft-calendar@0.1.16 + - @backstage/plugin-newrelic@0.3.49 + - @backstage/plugin-octopus-deploy@0.2.16 + - @backstage/plugin-org@0.6.24 + - @backstage/plugin-pagerduty@0.7.6 + - @backstage/plugin-permission-react@0.4.22 + - @backstage/plugin-playlist@0.2.8 + - @backstage/plugin-puppetdb@0.1.17 + - @backstage/plugin-rollbar@0.4.34 + - @backstage/plugin-scaffolder-react@1.8.4 + - @backstage/plugin-search@1.4.10 + - @backstage/plugin-sentry@0.5.19 + - @backstage/plugin-shortcuts@0.3.23 + - @backstage/plugin-stackstorm@0.1.15 + - @backstage/plugin-tech-insights@0.3.26 + - @backstage/plugin-tech-radar@0.7.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9 + - @backstage/plugin-techdocs@1.10.4 + - @backstage/plugin-todo@0.2.38 + - @backstage/plugin-user-settings@0.8.5 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-badges@0.2.58 + - app-next-example-plugin@0.0.10 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-app-visualizer@0.1.5 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-devtools@0.1.13 + - @backstage/plugin-linguist@0.1.19 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-newrelic-dashboard@0.3.9 + - @backstage/plugin-search-common@1.2.11 + +## 0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.4.3-next.1 + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/cli@0.26.3-next.1 + - @backstage/plugin-scaffolder@1.19.3-next.1 + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-app-api@0.6.4-next.1 + - @backstage/plugin-scaffolder-react@1.8.4-next.1 + - @backstage/plugin-cost-insights@0.12.23-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/plugin-api-docs@0.11.4-next.1 + - @backstage/plugin-catalog-graph@0.4.4-next.1 + - @backstage/plugin-explore@0.4.20-next.1 + - @backstage/plugin-org@0.6.24-next.1 + - @backstage/plugin-user-settings@0.8.5-next.1 + - @backstage/plugin-kubernetes@0.11.9-next.1 + - @backstage/app-defaults@1.5.4-next.1 + - app-next-example-plugin@0.0.10-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-adr@0.6.17-next.1 + - @backstage/plugin-airbrake@0.3.34-next.1 + - @backstage/plugin-apache-airflow@0.2.24-next.0 + - @backstage/plugin-app-visualizer@0.1.5-next.1 + - @backstage/plugin-azure-sites@0.1.23-next.1 + - @backstage/plugin-badges@0.2.58-next.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-import@0.10.10-next.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + - @backstage/plugin-cloudbuild@0.5.1-next.1 + - @backstage/plugin-code-coverage@0.2.27-next.1 + - @backstage/plugin-devtools@0.1.13-next.1 + - @backstage/plugin-dynatrace@10.0.3-next.1 + - @backstage/plugin-entity-feedback@0.2.17-next.1 + - @backstage/plugin-gcalendar@0.3.27-next.0 + - @backstage/plugin-gcp-projects@0.3.50-next.0 + - @backstage/plugin-github-actions@0.6.15-next.1 + - @backstage/plugin-gocd@0.1.40-next.1 + - @backstage/plugin-graphiql@0.3.7-next.1 + - @backstage/plugin-home@0.7.3-next.1 + - @backstage/plugin-jenkins@0.9.9-next.1 + - @backstage/plugin-kafka@0.3.34-next.1 + - @backstage/plugin-lighthouse@0.4.19-next.1 + - @backstage/plugin-linguist@0.1.19-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.16-next.0 + - @backstage/plugin-newrelic@0.3.49-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.9-next.1 + - @backstage/plugin-octopus-deploy@0.2.16-next.1 + - @backstage/plugin-pagerduty@0.7.6-next.1 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist@0.2.8-next.1 + - @backstage/plugin-puppetdb@0.1.17-next.1 + - @backstage/plugin-rollbar@0.4.34-next.1 + - @backstage/plugin-search@1.4.10-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-sentry@0.5.19-next.1 + - @backstage/plugin-shortcuts@0.3.23-next.0 + - @backstage/plugin-stackstorm@0.1.15-next.0 + - @backstage/plugin-tech-insights@0.3.26-next.1 + - @backstage/plugin-tech-radar@0.7.3-next.1 + - @backstage/plugin-techdocs@1.10.4-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + - @backstage/plugin-todo@0.2.38-next.1 + +## 0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-gocd@0.1.40-next.0 + - @backstage/plugin-scaffolder@1.19.3-next.0 + - @backstage/cli@0.26.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/app-defaults@1.5.4-next.0 + - app-next-example-plugin@0.0.10-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.3 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-app-api@0.6.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-adr@0.6.17-next.0 + - @backstage/plugin-airbrake@0.3.34-next.0 + - @backstage/plugin-apache-airflow@0.2.24-next.0 + - @backstage/plugin-api-docs@0.11.4-next.0 + - @backstage/plugin-app-visualizer@0.1.5-next.0 + - @backstage/plugin-azure-devops@0.4.3-next.0 + - @backstage/plugin-azure-sites@0.1.23-next.0 + - @backstage/plugin-badges@0.2.58-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-graph@0.4.4-next.0 + - @backstage/plugin-catalog-import@0.10.10-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.3-next.0 + - @backstage/plugin-cloudbuild@0.5.1-next.0 + - @backstage/plugin-code-coverage@0.2.27-next.0 + - @backstage/plugin-cost-insights@0.12.23-next.0 + - @backstage/plugin-devtools@0.1.13-next.0 + - @backstage/plugin-dynatrace@10.0.3-next.0 + - @backstage/plugin-entity-feedback@0.2.17-next.0 + - @backstage/plugin-explore@0.4.20-next.0 + - @backstage/plugin-gcalendar@0.3.27-next.0 + - @backstage/plugin-gcp-projects@0.3.50-next.0 + - @backstage/plugin-github-actions@0.6.15-next.0 + - @backstage/plugin-graphiql@0.3.7-next.0 + - @backstage/plugin-home@0.7.3-next.0 + - @backstage/plugin-jenkins@0.9.9-next.0 + - @backstage/plugin-kafka@0.3.34-next.0 + - @backstage/plugin-kubernetes@0.11.9-next.0 + - @backstage/plugin-lighthouse@0.4.19-next.0 + - @backstage/plugin-linguist@0.1.19-next.0 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.16-next.0 + - @backstage/plugin-newrelic@0.3.49-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.9-next.0 + - @backstage/plugin-octopus-deploy@0.2.16-next.0 + - @backstage/plugin-org@0.6.24-next.0 + - @backstage/plugin-pagerduty@0.7.6-next.0 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-playlist@0.2.8-next.0 + - @backstage/plugin-puppetdb@0.1.17-next.0 + - @backstage/plugin-rollbar@0.4.34-next.0 + - @backstage/plugin-scaffolder-react@1.8.4-next.0 + - @backstage/plugin-search@1.4.10-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-sentry@0.5.19-next.0 + - @backstage/plugin-shortcuts@0.3.23-next.0 + - @backstage/plugin-stackstorm@0.1.15-next.0 + - @backstage/plugin-tech-insights@0.3.26-next.0 + - @backstage/plugin-tech-radar@0.7.3-next.0 + - @backstage/plugin-techdocs@1.10.4-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.9-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + - @backstage/plugin-todo@0.2.38-next.0 + - @backstage/plugin-user-settings@0.8.5-next.0 + +## 0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-newrelic@0.3.48 + - @backstage/plugin-tech-radar@0.7.2 + - @backstage/plugin-entity-feedback@0.2.16 + - @backstage/plugin-pagerduty@0.7.5 + - @backstage/plugin-microsoft-calendar@0.1.15 + - @backstage/plugin-gcp-projects@0.3.49 + - @backstage/plugin-newrelic-dashboard@0.3.8 + - @backstage/plugin-catalog-unprocessed-entities@0.2.2 + - @backstage/core-components@0.14.3 + - @backstage/plugin-scaffolder-react@1.8.3 + - @backstage/plugin-apache-airflow@0.2.23 + - @backstage/plugin-catalog-import@0.10.9 + - @backstage/plugin-github-actions@0.6.14 + - @backstage/plugin-octopus-deploy@0.2.15 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-graph@0.4.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-code-coverage@0.2.26 + - @backstage/plugin-cost-insights@0.12.22 + - @backstage/plugin-tech-insights@0.3.25 + - @backstage/plugin-user-settings@0.8.4 + - @backstage/plugin-azure-devops@0.4.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/plugin-azure-sites@0.1.22 + - @backstage/plugin-cloudbuild@0.5.0 + - @backstage/plugin-lighthouse@0.4.18 + - @backstage/plugin-scaffolder@1.19.2 + - @backstage/plugin-stackstorm@0.1.14 + - @backstage/plugin-dynatrace@10.0.2 + - @backstage/plugin-gcalendar@0.3.26 + - @backstage/plugin-shortcuts@0.3.22 + - @backstage/plugin-airbrake@0.3.33 + - @backstage/plugin-devtools@0.1.12 + - @backstage/plugin-graphiql@0.3.6 + - @backstage/plugin-linguist@0.1.18 + - @backstage/plugin-playlist@0.2.7 + - @backstage/plugin-puppetdb@0.1.16 + - @backstage/plugin-techdocs@1.10.3 + - @backstage/plugin-catalog@1.18.2 + - @backstage/plugin-explore@0.4.19 + - @backstage/plugin-jenkins@0.9.8 + - @backstage/plugin-rollbar@0.4.33 + - @backstage/plugin-badges@0.2.57 + - @backstage/plugin-search@1.4.9 + - @backstage/plugin-sentry@0.5.18 + - @backstage/plugin-kafka@0.3.33 + - @backstage/plugin-gocd@0.1.39 + - @backstage/plugin-home@0.7.2 + - @backstage/plugin-adr@0.6.16 + - @backstage/plugin-org@0.6.23 + - @backstage/cli@0.26.2 + - @backstage/app-defaults@1.5.3 + - app-next-example-plugin@0.0.9 + - @backstage/frontend-app-api@0.6.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-api-docs@0.11.3 + - @backstage/plugin-app-visualizer@0.1.4 + - @backstage/plugin-kubernetes@0.11.8 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.8 + - @backstage/plugin-todo@0.2.37 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-search-common@1.2.11 + +## 0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-newrelic@0.3.47 + - @backstage/plugin-tech-radar@0.7.1 + - @backstage/plugin-entity-feedback@0.2.15 + - @backstage/plugin-pagerduty@0.7.4 + - @backstage/plugin-microsoft-calendar@0.1.14 + - @backstage/plugin-gcp-projects@0.3.48 + - @backstage/plugin-newrelic-dashboard@0.3.7 + - @backstage/plugin-catalog-unprocessed-entities@0.2.1 + - @backstage/core-components@0.14.2 + - @backstage/plugin-scaffolder-react@1.8.2 + - @backstage/plugin-apache-airflow@0.2.22 + - @backstage/plugin-catalog-import@0.10.8 + - @backstage/plugin-github-actions@0.6.13 + - @backstage/plugin-octopus-deploy@0.2.14 + - @backstage/plugin-techdocs-react@1.2.1 + - @backstage/core-app-api@1.12.2 + - @backstage/plugin-catalog-graph@0.4.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/plugin-code-coverage@0.2.25 + - @backstage/plugin-cost-insights@0.12.21 + - @backstage/plugin-tech-insights@0.3.24 + - @backstage/plugin-user-settings@0.8.3 + - @backstage/plugin-azure-devops@0.4.1 + - @backstage/plugin-search-react@1.7.8 + - @backstage/plugin-azure-sites@0.1.21 + - @backstage/plugin-cloudbuild@0.4.2 + - @backstage/plugin-lighthouse@0.4.17 + - @backstage/plugin-scaffolder@1.19.1 + - @backstage/plugin-stackstorm@0.1.13 + - @backstage/plugin-dynatrace@10.0.1 + - @backstage/plugin-gcalendar@0.3.25 + - @backstage/plugin-shortcuts@0.3.21 + - @backstage/plugin-airbrake@0.3.32 + - @backstage/plugin-devtools@0.1.11 + - @backstage/plugin-graphiql@0.3.5 + - @backstage/plugin-linguist@0.1.17 + - @backstage/plugin-playlist@0.2.6 + - @backstage/plugin-puppetdb@0.1.15 + - @backstage/plugin-techdocs@1.10.2 + - @backstage/plugin-catalog@1.18.1 + - @backstage/plugin-explore@0.4.18 + - @backstage/plugin-jenkins@0.9.7 + - @backstage/plugin-rollbar@0.4.32 + - @backstage/plugin-badges@0.2.56 + - @backstage/plugin-search@1.4.8 + - @backstage/plugin-sentry@0.5.17 + - @backstage/plugin-kafka@0.3.32 + - @backstage/plugin-gocd@0.1.38 + - @backstage/plugin-home@0.7.1 + - @backstage/plugin-adr@0.6.15 + - @backstage/plugin-org@0.6.22 + - @backstage/cli@0.26.1 + - @backstage/app-defaults@1.5.2 + - app-next-example-plugin@0.0.8 + - @backstage/frontend-app-api@0.6.2 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-api-docs@0.11.2 + - @backstage/plugin-app-visualizer@0.1.3 + - @backstage/plugin-kubernetes@0.11.7 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.7 + - @backstage/plugin-todo@0.2.36 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-search-common@1.2.11 + +## 0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-apache-airflow@0.2.21 + - @backstage/plugin-catalog-import@0.10.7 + - @backstage/cli@0.26.0 + - @backstage/plugin-shortcuts@0.3.20 + - @backstage/plugin-techdocs@1.10.1 + - @backstage/plugin-adr@0.6.14 + - @backstage/plugin-api-docs@0.11.1 + - @backstage/core-components@0.14.1 + - @backstage/plugin-rollbar@0.4.31 + - @backstage/plugin-search@1.4.7 + - @backstage/theme@0.5.2 + - @backstage/plugin-explore@0.4.17 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-github-actions@0.6.12 + - @backstage/plugin-dynatrace@10.0.0 + - @backstage/plugin-scaffolder@1.19.0 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-gcalendar@0.3.24 + - @backstage/plugin-airbrake@0.3.31 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-azure-devops@0.4.0 + - @backstage/plugin-user-settings@0.8.2 + - @backstage/plugin-org@0.6.21 + - @backstage/plugin-linguist@0.1.16 + - @backstage/plugin-badges@0.2.55 + - @backstage/plugin-cloudbuild@0.4.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.0 + - @backstage/plugin-tech-radar@0.7.0 + - @backstage/frontend-app-api@0.6.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-devtools@0.1.10 + - @backstage/plugin-cost-insights@0.12.20 + - @backstage/plugin-entity-feedback@0.2.14 + - @backstage/plugin-kubernetes@0.11.6 + - @backstage/plugin-stackstorm@0.1.12 + - @backstage/plugin-scaffolder-react@1.8.1 + - @backstage/plugin-azure-sites@0.1.20 + - @backstage/plugin-playlist@0.2.5 + - @backstage/plugin-home@0.7.0 + - @backstage/plugin-lighthouse@0.4.16 + - @backstage/plugin-sentry@0.5.16 + - @backstage/plugin-tech-insights@0.3.23 + - @backstage/plugin-octopus-deploy@0.2.13 + - @backstage/plugin-catalog-graph@0.4.1 + - @backstage/plugin-kafka@0.3.31 + - @backstage/plugin-jenkins@0.9.6 + - @backstage/plugin-code-coverage@0.2.24 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6 + - @backstage/app-defaults@1.5.1 + - app-next-example-plugin@0.0.7 + - @backstage/catalog-model@1.4.5 + - @backstage/core-app-api@1.12.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-app-visualizer@0.1.2 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-gcp-projects@0.3.47 + - @backstage/plugin-gocd@0.1.37 + - @backstage/plugin-graphiql@0.3.4 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-microsoft-calendar@0.1.13 + - @backstage/plugin-newrelic@0.3.46 + - @backstage/plugin-newrelic-dashboard@0.3.6 + - @backstage/plugin-pagerduty@0.7.3 + - @backstage/plugin-permission-react@0.4.21 + - @backstage/plugin-puppetdb@0.1.14 + - @backstage/plugin-search-react@1.7.7 + - @backstage/plugin-todo@0.2.35 + +## 0.0.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1-next.2 + - @backstage/plugin-search@1.4.7-next.2 + - @backstage/plugin-scaffolder@1.19.0-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-tech-radar@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-azure-devops@0.4.0-next.2 + - @backstage/plugin-devtools@0.1.10-next.2 + - @backstage/plugin-azure-sites@0.1.20-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/plugin-linguist@0.1.16-next.2 + - @backstage/plugin-catalog-import@0.10.7-next.2 + - @backstage/plugin-home@0.7.0-next.2 + - @backstage/plugin-github-actions@0.6.12-next.2 + - @backstage/cli@0.25.3-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/app-defaults@1.5.1-next.2 + - app-next-example-plugin@0.0.7-next.2 + - @backstage/frontend-app-api@0.6.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-adr@0.6.14-next.2 + - @backstage/plugin-airbrake@0.3.31-next.2 + - @backstage/plugin-apache-airflow@0.2.21-next.2 + - @backstage/plugin-api-docs@0.11.1-next.2 + - @backstage/plugin-app-visualizer@0.1.2-next.2 + - @backstage/plugin-badges@0.2.55-next.2 + - @backstage/plugin-catalog-graph@0.4.1-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.2 + - @backstage/plugin-cloudbuild@0.4.1-next.2 + - @backstage/plugin-code-coverage@0.2.24-next.2 + - @backstage/plugin-cost-insights@0.12.20-next.2 + - @backstage/plugin-dynatrace@10.0.0-next.2 + - @backstage/plugin-entity-feedback@0.2.14-next.2 + - @backstage/plugin-explore@0.4.17-next.2 + - @backstage/plugin-gcalendar@0.3.24-next.2 + - @backstage/plugin-gcp-projects@0.3.47-next.2 + - @backstage/plugin-gocd@0.1.37-next.2 + - @backstage/plugin-graphiql@0.3.4-next.2 + - @backstage/plugin-jenkins@0.9.6-next.2 + - @backstage/plugin-kafka@0.3.31-next.2 + - @backstage/plugin-kubernetes@0.11.6-next.2 + - @backstage/plugin-lighthouse@0.4.16-next.2 + - @backstage/plugin-microsoft-calendar@0.1.13-next.2 + - @backstage/plugin-newrelic@0.3.46-next.2 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.2 + - @backstage/plugin-octopus-deploy@0.2.13-next.2 + - @backstage/plugin-org@0.6.21-next.2 + - @backstage/plugin-pagerduty@0.7.3-next.2 + - @backstage/plugin-playlist@0.2.5-next.2 + - @backstage/plugin-puppetdb@0.1.14-next.2 + - @backstage/plugin-rollbar@0.4.31-next.2 + - @backstage/plugin-scaffolder-react@1.8.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/plugin-sentry@0.5.16-next.2 + - @backstage/plugin-shortcuts@0.3.20-next.2 + - @backstage/plugin-stackstorm@0.1.12-next.2 + - @backstage/plugin-tech-insights@0.3.23-next.2 + - @backstage/plugin-todo@0.2.35-next.2 + - @backstage/plugin-user-settings@0.8.2-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-github-actions@0.6.12-next.1 + - @backstage/cli@0.25.3-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-entity-feedback@0.2.14-next.1 + - @backstage/plugin-api-docs@0.11.1-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/plugin-azure-devops@0.4.0-next.1 + - @backstage/plugin-org@0.6.21-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-app-api@0.6.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-catalog-import@0.10.7-next.1 + - @backstage/plugin-cost-insights@0.12.20-next.1 + - @backstage/plugin-home@0.6.3-next.1 + - @backstage/plugin-permission-react@0.4.21-next.1 + - @backstage/plugin-techdocs@1.10.1-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/app-defaults@1.5.1-next.1 + - app-next-example-plugin@0.0.7-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-adr@0.6.14-next.1 + - @backstage/plugin-airbrake@0.3.31-next.1 + - @backstage/plugin-apache-airflow@0.2.21-next.1 + - @backstage/plugin-app-visualizer@0.1.2-next.1 + - @backstage/plugin-azure-sites@0.1.20-next.1 + - @backstage/plugin-badges@0.2.55-next.1 + - @backstage/plugin-catalog-graph@0.4.1-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.1 + - @backstage/plugin-cloudbuild@0.4.1-next.1 + - @backstage/plugin-code-coverage@0.2.24-next.1 + - @backstage/plugin-devtools@0.1.10-next.1 + - @backstage/plugin-dynatrace@9.0.1-next.1 + - @backstage/plugin-explore@0.4.17-next.1 + - @backstage/plugin-gcalendar@0.3.24-next.1 + - @backstage/plugin-gcp-projects@0.3.47-next.1 + - @backstage/plugin-gocd@0.1.37-next.1 + - @backstage/plugin-graphiql@0.3.4-next.1 + - @backstage/plugin-jenkins@0.9.6-next.1 + - @backstage/plugin-kafka@0.3.31-next.1 + - @backstage/plugin-kubernetes@0.11.6-next.1 + - @backstage/plugin-lighthouse@0.4.16-next.1 + - @backstage/plugin-linguist@0.1.16-next.1 + - @backstage/plugin-microsoft-calendar@0.1.13-next.1 + - @backstage/plugin-newrelic@0.3.46-next.1 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.1 + - @backstage/plugin-octopus-deploy@0.2.13-next.1 + - @backstage/plugin-pagerduty@0.7.3-next.1 + - @backstage/plugin-playlist@0.2.5-next.1 + - @backstage/plugin-puppetdb@0.1.14-next.1 + - @backstage/plugin-rollbar@0.4.31-next.1 + - @backstage/plugin-scaffolder@1.18.1-next.1 + - @backstage/plugin-scaffolder-react@1.8.1-next.1 + - @backstage/plugin-search@1.4.7-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/plugin-sentry@0.5.16-next.1 + - @backstage/plugin-shortcuts@0.3.20-next.1 + - @backstage/plugin-stackstorm@0.1.12-next.1 + - @backstage/plugin-tech-insights@0.3.23-next.1 + - @backstage/plugin-tech-radar@0.6.14-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.1 + - @backstage/plugin-todo@0.2.35-next.1 + - @backstage/plugin-user-settings@0.8.2-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr@0.6.14-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/cli@0.25.3-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-azure-devops@0.4.0-next.0 + - @backstage/plugin-linguist@0.1.16-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/plugin-org@0.6.21-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search@1.4.7-next.0 + - @backstage/plugin-devtools@0.1.10-next.0 + - @backstage/plugin-tech-radar@0.6.14-next.0 + - @backstage/plugin-scaffolder-react@1.8.1-next.0 + - @backstage/plugin-api-docs@0.11.1-next.0 + - @backstage/plugin-cost-insights@0.12.20-next.0 + - @backstage/plugin-home@0.6.3-next.0 + - @backstage/plugin-scaffolder@1.18.1-next.0 + - @backstage/plugin-shortcuts@0.3.20-next.0 + - @backstage/plugin-catalog-import@0.10.7-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-app-api@0.6.1-next.0 + - @backstage/plugin-badges@0.2.55-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.1.9-next.0 + - @backstage/plugin-code-coverage@0.2.24-next.0 + - @backstage/plugin-entity-feedback@0.2.14-next.0 + - @backstage/plugin-explore@0.4.17-next.0 + - @backstage/plugin-gcalendar@0.3.24-next.0 + - @backstage/plugin-gocd@0.1.37-next.0 + - @backstage/plugin-jenkins@0.9.6-next.0 + - @backstage/plugin-microsoft-calendar@0.1.13-next.0 + - @backstage/plugin-newrelic-dashboard@0.3.6-next.0 + - @backstage/plugin-pagerduty@0.7.3-next.0 + - @backstage/plugin-playlist@0.2.5-next.0 + - @backstage/plugin-puppetdb@0.1.14-next.0 + - @backstage/plugin-stackstorm@0.1.12-next.0 + - @backstage/plugin-tech-insights@0.3.23-next.0 + - @backstage/plugin-techdocs@1.10.1-next.0 + - @backstage/plugin-todo@0.2.35-next.0 + - @backstage/plugin-user-settings@0.8.2-next.0 + - @backstage/app-defaults@1.5.1-next.0 + - @backstage/plugin-azure-sites@0.1.20-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - app-next-example-plugin@0.0.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/plugin-airbrake@0.3.31-next.0 + - @backstage/plugin-apache-airflow@0.2.21-next.0 + - @backstage/plugin-app-visualizer@0.1.2-next.0 + - @backstage/plugin-catalog-graph@0.4.1-next.0 + - @backstage/plugin-cloudbuild@0.4.1-next.0 + - @backstage/plugin-dynatrace@9.0.1-next.0 + - @backstage/plugin-gcp-projects@0.3.47-next.0 + - @backstage/plugin-github-actions@0.6.12-next.0 + - @backstage/plugin-graphiql@0.3.4-next.0 + - @backstage/plugin-kafka@0.3.31-next.0 + - @backstage/plugin-kubernetes@0.11.6-next.0 + - @backstage/plugin-lighthouse@0.4.16-next.0 + - @backstage/plugin-newrelic@0.3.46-next.0 + - @backstage/plugin-octopus-deploy@0.2.13-next.0 + - @backstage/plugin-rollbar@0.4.31-next.0 + - @backstage/plugin-sentry@0.5.16-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.6-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-permission-react@0.4.21-next.0 + +## 0.0.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-azure-devops@0.3.12 + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/frontend-app-api@0.6.0 + - @backstage/plugin-scaffolder-react@1.8.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-catalog-import@0.10.6 + - @backstage/plugin-catalog-graph@0.4.0 + - @backstage/plugin-catalog@1.17.0 + - @backstage/plugin-azure-sites@0.1.19 + - @backstage/plugin-api-docs@0.11.0 + - @backstage/plugin-adr@0.6.13 + - @backstage/app-defaults@1.5.0 + - @backstage/plugin-gcp-projects@0.3.46 + - @backstage/plugin-airbrake@0.3.30 + - @backstage/plugin-scaffolder@1.18.0 + - @backstage/plugin-devtools@0.1.9 + - @backstage/cli@0.25.2 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.5 + - @backstage/plugin-kubernetes@0.11.5 + - @backstage/plugin-catalog-unprocessed-entities@0.1.8 + - @backstage/plugin-microsoft-calendar@0.1.12 + - @backstage/plugin-github-actions@0.6.11 + - @backstage/plugin-octopus-deploy@0.2.12 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/core-app-api@1.12.0 + - @backstage/plugin-code-coverage@0.2.23 + - @backstage/plugin-cost-insights@0.12.19 + - @backstage/plugin-tech-insights@0.3.22 + - @backstage/plugin-lighthouse@0.4.15 + - @backstage/plugin-tech-radar@0.6.13 + - @backstage/plugin-dynatrace@9.0.0 + - @backstage/plugin-shortcuts@0.3.19 + - @backstage/plugin-graphiql@0.3.3 + - @backstage/plugin-linguist@0.1.15 + - @backstage/plugin-newrelic@0.3.45 + - @backstage/plugin-jenkins@0.9.5 + - @backstage/plugin-rollbar@0.4.30 + - @backstage/plugin-badges@0.2.54 + - @backstage/plugin-sentry@0.5.15 + - @backstage/plugin-home@0.6.2 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-explore@0.4.16 + - @backstage/plugin-user-settings@0.8.1 + - @backstage/plugin-techdocs@1.10.0 + - @backstage/plugin-search@1.4.6 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-playlist@0.2.4 + - @backstage/plugin-apache-airflow@0.2.20 + - @backstage/plugin-cloudbuild@0.4.0 + - @backstage/plugin-entity-feedback@0.2.13 + - @backstage/plugin-gcalendar@0.3.23 + - @backstage/plugin-kafka@0.3.30 + - @backstage/plugin-newrelic-dashboard@0.3.5 + - @backstage/plugin-org@0.6.20 + - @backstage/plugin-pagerduty@0.7.2 + - @backstage/plugin-permission-react@0.4.20 + - @backstage/plugin-puppetdb@0.1.13 + - @backstage/plugin-search-react@1.7.6 + - @backstage/plugin-stackstorm@0.1.11 + - @backstage/plugin-app-visualizer@0.1.1 + - app-next-example-plugin@0.0.6 + - @backstage/plugin-gocd@0.1.36 + - @backstage/plugin-todo@0.2.34 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-linguist-common@0.1.2 + - @backstage/plugin-search-common@1.2.10 + ## 0.0.6-next.3 ### Patch Changes diff --git a/packages/app-next/README.md b/packages/app-next/README.md index 21645609a9..360e5d5545 100644 --- a/packages/app-next/README.md +++ b/packages/app-next/README.md @@ -1,3 +1,7 @@ # example-app-next -This package is an example of a Backstage application. +This package is an example of a Backstage application using the [new frontend](../../docs/frontend-system/index.md). + +To play with it, open a terminal and run the command: `yarn start` + +**NOTE:** Don't forget to open a second terminal and to launch the backend or [backend-next](../../docs/backend-system/index.md) there, using `yarn start`! The frontend requires a backend to connect to. diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 408b08acee..271040ecec 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -10,7 +10,7 @@ app: extensions: # - apis.plugin.graphiql.browse.gitlab: true - - graphiql-endpoint:graphiql/gitlab: true + # - graphiql-endpoint:graphiql/gitlab: true # Entity page cards - entity-card:catalog/about @@ -18,11 +18,10 @@ app: - entity-card:catalog/links: config: filter: kind:component has:links - - entity-card:linguist/languages + # - entity-card:linguist/languages - entity-card:catalog-graph/relations: config: height: 300 - - entity-card:azure-devops/readme - entity-card:api-docs/has-apis - entity-card:api-docs/consumed-apis - entity-card:api-docs/provided-apis diff --git a/packages/app-next/package.json b/packages/app-next/package.json index b5eaea967a..065aa43322 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.6-next.3", + "version": "0.0.11-next.0", "private": true, "repository": { "type": "git", @@ -15,6 +15,7 @@ "@backstage/app-defaults": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/config": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/core-compat-api": "workspace:^", "@backstage/core-components": "workspace:^", @@ -22,90 +23,53 @@ "@backstage/frontend-app-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/integration-react": "workspace:^", - "@backstage/plugin-adr": "workspace:^", - "@backstage/plugin-airbrake": "workspace:^", - "@backstage/plugin-apache-airflow": "workspace:^", "@backstage/plugin-api-docs": "workspace:^", "@backstage/plugin-app-visualizer": "workspace:^", - "@backstage/plugin-azure-devops": "workspace:^", - "@backstage/plugin-azure-sites": "workspace:^", - "@backstage/plugin-badges": "workspace:^", + "@backstage/plugin-auth-react": "workspace:^", "@backstage/plugin-catalog": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-graph": "workspace:^", "@backstage/plugin-catalog-import": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-catalog-unprocessed-entities": "workspace:^", - "@backstage/plugin-cloudbuild": "workspace:^", - "@backstage/plugin-code-coverage": "workspace:^", - "@backstage/plugin-cost-insights": "workspace:^", - "@backstage/plugin-devtools": "workspace:^", - "@backstage/plugin-dynatrace": "workspace:^", - "@backstage/plugin-entity-feedback": "workspace:^", - "@backstage/plugin-explore": "workspace:^", - "@backstage/plugin-gcalendar": "workspace:^", - "@backstage/plugin-gcp-projects": "workspace:^", - "@backstage/plugin-github-actions": "workspace:^", - "@backstage/plugin-gocd": "workspace:^", - "@backstage/plugin-graphiql": "workspace:^", "@backstage/plugin-home": "workspace:^", - "@backstage/plugin-jenkins": "workspace:^", - "@backstage/plugin-kafka": "workspace:^", "@backstage/plugin-kubernetes": "workspace:^", - "@backstage/plugin-lighthouse": "workspace:^", - "@backstage/plugin-linguist": "workspace:^", - "@backstage/plugin-linguist-common": "workspace:^", - "@backstage/plugin-microsoft-calendar": "workspace:^", - "@backstage/plugin-newrelic": "workspace:^", - "@backstage/plugin-newrelic-dashboard": "workspace:^", - "@backstage/plugin-octopus-deploy": "workspace:^", + "@backstage/plugin-kubernetes-cluster": "workspace:^", + "@backstage/plugin-notifications": "workspace:^", "@backstage/plugin-org": "workspace:^", - "@backstage/plugin-pagerduty": "workspace:^", "@backstage/plugin-permission-react": "workspace:^", - "@backstage/plugin-playlist": "workspace:^", - "@backstage/plugin-puppetdb": "workspace:^", - "@backstage/plugin-rollbar": "workspace:^", "@backstage/plugin-scaffolder": "workspace:^", "@backstage/plugin-scaffolder-react": "workspace:^", "@backstage/plugin-search": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-search-react": "workspace:^", - "@backstage/plugin-sentry": "workspace:^", - "@backstage/plugin-shortcuts": "workspace:^", - "@backstage/plugin-stackstorm": "workspace:^", - "@backstage/plugin-tech-insights": "workspace:^", - "@backstage/plugin-tech-radar": "workspace:^", + "@backstage/plugin-signals": "workspace:^", "@backstage/plugin-techdocs": "workspace:^", "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^", "@backstage/plugin-techdocs-react": "workspace:^", - "@backstage/plugin-todo": "workspace:^", "@backstage/plugin-user-settings": "workspace:^", "@backstage/theme": "workspace:^", - "@circleci/backstage-plugin": "^0.1.1", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@octokit/rest": "^19.0.3", - "@oriflame/backstage-plugin-score-card": "^0.8.0", - "@roadiehq/backstage-plugin-buildkite": "^2.0.8", - "@roadiehq/backstage-plugin-github-insights": "^2.0.5", - "@roadiehq/backstage-plugin-github-pull-requests": "^2.2.7", - "@roadiehq/backstage-plugin-travis-ci": "^2.0.5", - "app-next-example-plugin": "workspace:^", + "@vitejs/plugin-react": "^4.0.4", "history": "^5.0.0", - "lodash": "^4.17.21", "react": "^18.0.2", "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-use": "^17.2.4", + "vite": "^4.4.9", + "vite-plugin-html": "^3.2.0", + "vite-plugin-node-polyfills": "^0.21.0", "zen-observable": "^0.10.0" }, "devDependencies": { "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "@types/jquery": "^3.3.34", "@types/react": "*", diff --git a/packages/app-next/public/index.html b/packages/app-next/public/index.html index a3c3ef19b8..1bbfda590d 100644 --- a/packages/app-next/public/index.html +++ b/packages/app-next/public/index.html @@ -6,7 +6,7 @@ accepted - - red --> declined - - nothing --> not responded yet - -## Setup - -The following sections will help you set up the Microsoft calendar plugin. - -### Microsoft azure authentication provider - -> You need to setup [Microsoft Azure authentication provider](https://backstage.io/docs/auth/microsoft/provider), before you move forward with any of the below step if you haven't already. - -1. Install the plugin by running this command - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-microsoft-calendar -``` - -2. Import the Microsoft calendar React component from `@backstage/plugin-microsoft-calendar`. -3. You can then use the provided React component `MicrosoftCalendar` in the backstage frontend where ever you want - -```tsx -import { MicrosoftCalendarCard } from '@backstage/plugin-microsoft-calendar'; - -// ... - - -; -// ... -``` - -If your homepage is not static JSX add `microsoftCalendarApiRef` to the App's `apis.ts`: - -```ts -import { - MicrosoftCalendarApiClient, - microsoftCalendarApiRef, -} from '@backstage/plugin-microsoft-calendar'; -import { - // ... - fetchApiRef, - // ... -} from '@backstage/core-plugin-api'; - -export const apis = [ - // ... - createApiFactory({ - api: microsoftCalendarApiRef, - deps: { authApi: microsoftAuthApiRef, fetchApi: fetchApiRef }, - factory: deps => new MicrosoftCalendarApiClient(deps), - }), -]; -``` - -![Microsoft Calendar plugin demo](https://user-images.githubusercontent.com/23618736/215717491-25db5fa6-b237-487f-8c00-28f572e8da05.mp4) - -![Sample](./docs/microsoft-calendar-plugin.png) - -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/microsoft-calendar/api-report.md b/plugins/microsoft-calendar/api-report.md deleted file mode 100644 index fad48e5de0..0000000000 --- a/plugins/microsoft-calendar/api-report.md +++ /dev/null @@ -1,40 +0,0 @@ -## API Report File for "@backstage/plugin-microsoft-calendar" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { Calendar } from '@microsoft/microsoft-graph-types'; -import { Event as Event_2 } from '@microsoft/microsoft-graph-types'; -import { FetchApi } from '@backstage/core-plugin-api'; -import { JSX as JSX_2 } from 'react'; -import { OAuthApi } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export class MicrosoftCalendarApiClient { - constructor(options: { authApi: OAuthApi; fetchApi: FetchApi }); - // (undocumented) - getCalendars(): Promise; - // (undocumented) - getEvents( - calendarId: string, - params: { - startDateTime: string; - endDateTime: string; - }, - headers: { - [key in string]: any; - }, - ): Promise; -} - -// @public (undocumented) -export const microsoftCalendarApiRef: ApiRef; - -// @public (undocumented) -export const MicrosoftCalendarCard: () => JSX_2.Element; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/microsoft-calendar/catalog-info.yaml b/plugins/microsoft-calendar/catalog-info.yaml deleted file mode 100644 index 82c3c82b49..0000000000 --- a/plugins/microsoft-calendar/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-microsoft-calendar - title: '@backstage/plugin-microsoft-calendar' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/microsoft-calendar/dev/index.tsx b/plugins/microsoft-calendar/dev/index.tsx deleted file mode 100644 index d611bca20c..0000000000 --- a/plugins/microsoft-calendar/dev/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { createDevApp } from '@backstage/dev-utils'; -import { microsoftCalendarPlugin, MicrosoftCalendarCard } from '../src/plugin'; -import { microsoftCalendarApiRef } from '../src'; -import responseMock from './mock.json'; -import { microsoftAuthApiRef } from '@backstage/core-plugin-api'; -import { Content, Page } from '@backstage/core-components'; -import { Grid } from '@material-ui/core'; - -createDevApp() - .registerPlugin(microsoftCalendarPlugin) - .registerApi({ - api: microsoftAuthApiRef, - deps: {}, - factory: () => - ({ - async getAccessToken() { - return Promise.resolve('token'); - }, - } as unknown as typeof microsoftAuthApiRef.T), - }) - .registerApi({ - api: microsoftCalendarApiRef, - deps: {}, - factory: () => - ({ - async getCalendars() { - return Promise.resolve(responseMock.calendars); - }, - async getEvents() { - return Promise.resolve(responseMock.events); - }, - } as unknown as typeof microsoftCalendarApiRef.T), - }) - .addPage({ - element: ( - - - - - - - - ), - title: 'Microsoft-Calendar Plugin Demo', - path: '/microsoft-calendar', - }) - .render(); diff --git a/plugins/microsoft-calendar/dev/mock.json b/plugins/microsoft-calendar/dev/mock.json deleted file mode 100644 index b305e187eb..0000000000 --- a/plugins/microsoft-calendar/dev/mock.json +++ /dev/null @@ -1,305 +0,0 @@ -{ - "calendars": [ - { - "id": "AQMkADQyMDdlODU1AC05OGNiLTRhZmItOGM2Mi1kODZhMzJkYWU2OTAARgAAAwWXy9axQ31DtBuHDIFwgtYHAKRSO4MUJXZDi1hwzpYLetAAAAIBBgAAAKRSO4MUJXZDi1hwzpYLetAAAAIyswAAAA==", - "name": "Calendar", - "color": "lightBlue", - "hexColor": "#9fe1e7", - "isDefaultCalendar": true, - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAAAADYw==", - "canShare": true, - "canViewPrivateItems": true, - "canEdit": true, - "allowedOnlineMeetingProviders": ["teamsForBusiness"], - "defaultOnlineMeetingProvider": "teamsForBusiness", - "isTallyingResponses": true, - "isRemovable": false, - "owner": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - { - "id": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAEGAACkUjuDFCV2Q4tYcM6WC3rQAAAZs65BAAA=", - "name": "United Kingdom holidays", - "color": "auto", - "hexColor": "", - "isDefaultCalendar": false, - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAGanqjg==", - "canShare": false, - "canViewPrivateItems": true, - "canEdit": false, - "allowedOnlineMeetingProviders": [], - "defaultOnlineMeetingProvider": "unknown", - "isTallyingResponses": false, - "isRemovable": true, - "owner": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - { - "id": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAEGAACkUjuDFCV2Q4tYcM6WC3rQAAAZs65CAAA=", - "name": "Birthdays1", - "color": "auto", - "hexColor": "", - "isDefaultCalendar": false, - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAGanrfQ==", - "canShare": false, - "canViewPrivateItems": true, - "canEdit": false, - "allowedOnlineMeetingProviders": [], - "defaultOnlineMeetingProvider": "unknown", - "isTallyingResponses": false, - "isRemovable": true, - "owner": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - { - "id": "AQMkADQyMDdlODU1AC05OGNiLTRhZmItOGM2Mi1kODZhMzJkYWU2OTAARgAAAwWXy9axQ31DtBuHDIFwgtYHAKRSO4MUJXZDi1hwzpYLetAAAAIBBgAAAKRSO4MUJXZDi1hwzpYLetAAAAIytQAAAA==", - "name": "Birthdays", - "color": "auto", - "hexColor": "#92e1c0", - "isDefaultCalendar": false, - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAAAADdw==", - "canShare": false, - "canViewPrivateItems": true, - "canEdit": false, - "allowedOnlineMeetingProviders": [], - "defaultOnlineMeetingProvider": "unknown", - "isTallyingResponses": false, - "isRemovable": true, - "owner": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - { - "id": "AQMkADQyMDdlODU1AC05OGNiLTRhZmItOGM2Mi1kODZhMzJkYWU2OTAARgAAAwWXy9axQ31DtBuHDIFwgtYHAKRSO4MUJXZDi1hwzpYLetAAAAIBBgAAAKRSO4MUJXZDi1hwzpYLetAAAAIytgAAAA==", - "name": "Holidays in India", - "color": "auto", - "hexColor": "#16a765", - "isDefaultCalendar": false, - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAAAADug==", - "canShare": false, - "canViewPrivateItems": true, - "canEdit": false, - "allowedOnlineMeetingProviders": [], - "defaultOnlineMeetingProvider": "unknown", - "isTallyingResponses": false, - "isRemovable": true, - "owner": { - "name": "Abhay Soni", - "address": "abhay.s@statusneo.com" - } - } - ], - "events": [ - { - "id": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MAFRAAgI2vdUnGxAAEYAAAAABZfL1rFDfUO0G4cMgXCC1gcApFI7gxQldkOLWHDOlgt60AAAAAABDQAApFI7gxQldkOLWHDOlgt60AAAYl_I0AAAEA==", - "createdDateTime": "2022-12-22T08:28:36.6131501Z", - "lastModifiedDateTime": "2023-01-20T05:24:31.9666518Z", - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAd5KhaA==", - "categories": [], - "transactionId": null, - "originalStartTimeZone": "India Standard Time", - "originalEndTimeZone": "India Standard Time", - "iCalUId": "040000008200E00074C5B7101A82E00807E7011006D3A5A92DC7D80100000000000000001000000002BB709705E28C4493E46124FF07DD89", - "reminderMinutesBeforeStart": 15, - "isReminderOn": true, - "hasAttachments": false, - "subject": "Abhay Soni", - "bodyPreview": "", - "importance": "normal", - "sensitivity": "normal", - "isAllDay": false, - "isCancelled": false, - "isOrganizer": false, - "responseRequested": true, - "seriesMasterId": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=", - "showAs": "tentative", - "type": "occurrence", - "webLink": "", - "onlineMeetingUrl": "", - "isOnlineMeeting": true, - "onlineMeetingProvider": "teamsForBusiness", - "allowNewTimeProposals": true, - "occurrenceId": "OID.AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=.2023-01-16", - "isDraft": false, - "hideAttendees": false, - "responseStatus": { - "response": "notResponded", - "time": "0001-01-01T00:00:00Z" - }, - "body": { - "contentType": "html", - "content": "" - }, - "start": { - "dateTime": "2023-01-16T11:00:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "end": { - "dateTime": "2023-01-16T11:30:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "location": { - "displayName": "", - "locationType": "default", - "uniqueIdType": "unknown", - "address": {}, - "coordinates": {} - }, - "locations": [], - "recurrence": null, - "attendees": [ - { - "type": "required", - "status": { - "response": "none", - "time": "0001-01-01T00:00:00Z" - }, - "emailAddress": { - "name": "Nishkarsh Raj", - "address": "nishkarshraj@nishkarsh.com" - } - }, - { - "type": "required", - "status": { - "response": "accepted", - "time": "0001-01-01T00:00:00Z" - }, - "emailAddress": { - "name": "Hakam Ram", - "address": "hakam_ram@ram.com" - } - }, - { - "type": "required", - "status": { - "response": "declined", - "time": "0001-01-01T00:00:00Z" - }, - "emailAddress": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - } - ], - "organizer": { - "emailAddress": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - "onlineMeeting": { - "joinUrl": "https://abhay-soni-developer.github.io/MyReusme/" - } - }, - { - "id": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MAFRAAgI2vdUnGxAAEYAAAAABZfL1rFDfUO0G4cMgXCC1gcApFI7gxQldkOLWHDOlgt60AAAAAABDQAApFI7gxQldkOLWHDOlgt60AAAYl_I0AAAEA==", - "createdDateTime": "2022-12-22T08:28:36.6131501Z", - "lastModifiedDateTime": "2023-01-20T05:24:31.9666518Z", - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAd5KhaA==", - "categories": [], - "transactionId": null, - "originalStartTimeZone": "India Standard Time", - "originalEndTimeZone": "India Standard Time", - "iCalUId": "040000008200E00074C5B7101A82E00807E7011006D3A5A92DC7D80100000000000000001000000002BB709705E28C4493E46124FF07DD89", - "reminderMinutesBeforeStart": 15, - "isReminderOn": true, - "hasAttachments": false, - "subject": "https://abhay-soni-developer.github.io/MyReusme/", - "bodyPreview": "", - "importance": "normal", - "sensitivity": "normal", - "isAllDay": false, - "isCancelled": false, - "isOrganizer": false, - "responseRequested": true, - "seriesMasterId": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=", - "showAs": "tentative", - "type": "occurrence", - "webLink": "", - "onlineMeetingUrl": "", - "isOnlineMeeting": true, - "onlineMeetingProvider": "teamsForBusiness", - "allowNewTimeProposals": true, - "occurrenceId": "OID.AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=.2023-01-16", - "isDraft": false, - "hideAttendees": false, - "responseStatus": { - "response": "notResponded", - "time": "0001-01-01T00:00:00Z" - }, - "attendees": [ - { - "type": "required", - "status": { - "response": "none", - "time": "0001-01-01T00:00:00Z" - }, - "emailAddress": { - "name": "Nishkarsh Raj", - "address": "nishkarshraj@nishkarsh.com" - } - }, - { - "type": "required", - "status": { - "response": "accepted", - "time": "0001-01-01T00:00:00Z" - }, - "emailAddress": { - "name": "Hakam Ram", - "address": "hakam_ram@ram.com" - } - }, - { - "type": "required", - "status": { - "response": "declined", - "time": "0001-01-01T00:00:00Z" - }, - "emailAddress": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - } - ], - "body": { - "contentType": "html", - "content": "" - }, - "start": { - "dateTime": "2023-01-16T11:00:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "end": { - "dateTime": "2023-01-16T11:30:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "location": { - "displayName": "", - "locationType": "default", - "uniqueIdType": "unknown", - "address": {}, - "coordinates": {} - }, - "locations": [], - "recurrence": null, - "organizer": { - "emailAddress": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - "onlineMeeting": { - "joinUrl": "https://abhay-soni-developer.github.io/MyReusme/" - } - } - ] -} diff --git a/plugins/microsoft-calendar/docs/microsoft-calendar-plugin.png b/plugins/microsoft-calendar/docs/microsoft-calendar-plugin.png deleted file mode 100644 index 376ae73717..0000000000 Binary files a/plugins/microsoft-calendar/docs/microsoft-calendar-plugin.png and /dev/null differ diff --git a/plugins/microsoft-calendar/knip-report.md b/plugins/microsoft-calendar/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/microsoft-calendar/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/microsoft-calendar/package.json b/plugins/microsoft-calendar/package.json deleted file mode 100644 index 031115d5f0..0000000000 --- a/plugins/microsoft-calendar/package.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "@backstage/plugin-microsoft-calendar", - "version": "0.1.12-next.2", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/microsoft-calendar" - }, - "author": { - "name": "Statusneo", - "email": "reach@statusneo.com", - "url": "https://statusneo.com/" - }, - "contributors": [ - { - "email": "abhaysoni.developer@gmail.com", - "url": "https://github.com/Abhay-soni-developer", - "name": "abhaysoni" - } - ], - "maintainers": [ - { - "email": "abhaysoni.developer@gmail.com", - "url": "https://github.com/Abhay-soni-developer", - "name": "abhaysoni" - } - ], - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@microsoft/microsoft-graph-types": "^2.25.0", - "@tanstack/react-query": "^4.1.3", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "classnames": "^2.3.1", - "dompurify": "^3.0.0", - "lodash": "^4.17.21", - "luxon": "^3.0.0", - "material-ui-popup-state": "^1.9.3", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/microsoft-calendar/src/api/client.ts b/plugins/microsoft-calendar/src/api/client.ts deleted file mode 100644 index fe842b5aef..0000000000 --- a/plugins/microsoft-calendar/src/api/client.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 { OAuthApi, createApiRef, FetchApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { MicrosoftCalendarEvent, MicrosoftCalendar } from './types'; - -/** @public */ -export const microsoftCalendarApiRef = createApiRef( - { - id: 'plugin.microsoft-calendar.service', - }, -); - -/** @public */ -export class MicrosoftCalendarApiClient { - private readonly authApi: OAuthApi; - private readonly fetchApi: FetchApi; - - constructor(options: { authApi: OAuthApi; fetchApi: FetchApi }) { - this.authApi = options.authApi; - this.fetchApi = options.fetchApi; - } - - private async get( - path: string, - params: { [key in string]: any } = {}, - headers?: any, - ): Promise { - const query = new URLSearchParams(params); - const url = new URL( - `${path}?${query.toString()}`, - 'https://graph.microsoft.com', - ); - const token = await this.authApi.getAccessToken(); - let temp: any = {}; - - if (headers && typeof headers === 'object') { - temp = { - ...headers, - }; - } - - if (token) { - temp.Authorization = `Bearer ${token}`; - } - - const response = await this.fetchApi.fetch(url.toString(), { - headers: temp, - }); - - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } - - return response.json() as Promise; - } - - public async getCalendars(): Promise { - const data = await this.get<{ - id: string; - value: MicrosoftCalendar[]; - }>('v1.0/me/calendars'); - - return data.value; - } - - public async getEvents( - calendarId: string, - params: { - startDateTime: string; - endDateTime: string; - }, - headers: { [key in string]: any }, - ): Promise { - const data = await this.get<{ - id: string; - value: [MicrosoftCalendarEvent]; - }>(`v1.0/me/calendars/${calendarId}/calendarview`, params, headers); - return data.value; - } -} diff --git a/plugins/microsoft-calendar/src/api/index.ts b/plugins/microsoft-calendar/src/api/index.ts deleted file mode 100644 index db4616b586..0000000000 --- a/plugins/microsoft-calendar/src/api/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export * from './client'; -export * from './types'; diff --git a/plugins/microsoft-calendar/src/api/types.ts b/plugins/microsoft-calendar/src/api/types.ts deleted file mode 100644 index f4cb2811c7..0000000000 --- a/plugins/microsoft-calendar/src/api/types.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - Calendar as MicrosoftCalendar, - Event as MicrosoftCalendarEvent, - Attendee, - ResponseStatus, - DateTimeTimeZone, - EmailAddress, -} from '@microsoft/microsoft-graph-types'; - -export type { - MicrosoftCalendar, - MicrosoftCalendarEvent, - Attendee, - ResponseStatus, - DateTimeTimeZone, - EmailAddress, -}; - -export const ResponseStatusMap = { - needsAction: 'none', - accepted: 'accepted', - declined: 'declined', - maybe: 'tentativelyAccepted', - notResponded: 'notResponded', -}; diff --git a/plugins/microsoft-calendar/src/components/AttendeeChip.tsx b/plugins/microsoft-calendar/src/components/AttendeeChip.tsx deleted file mode 100644 index 25358519e6..0000000000 --- a/plugins/microsoft-calendar/src/components/AttendeeChip.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 { Badge, Chip, makeStyles } from '@material-ui/core'; -import CancelIcon from '@material-ui/icons/Cancel'; -import CheckIcon from '@material-ui/icons/CheckCircle'; -import { Attendee, ResponseStatusMap } from '../api'; - -const useStyles = makeStyles(theme => { - const getIconColor = (responseStatus?: string) => { - if (!responseStatus) return theme.palette.primary.light; - - return { - [ResponseStatusMap.accepted]: theme.palette.status.ok, - [ResponseStatusMap.declined]: theme.palette.status.error, - }[responseStatus]; - }; - - return { - responseStatus: { - color: ({ responseStatus }: { responseStatus?: string }) => - getIconColor(responseStatus), - }, - badge: { - right: 10, - top: 5, - '& svg': { - height: 16, - width: 16, - background: theme.palette.common.white, - }, - }, - }; -}); - -const ResponseIcon = ({ responseStatus }: { responseStatus: string }) => { - if (responseStatus === ResponseStatusMap.accepted) { - return ; - } - if (responseStatus === ResponseStatusMap.declined) { - return ; - } - - return null; -}; - -type AttendeeChipProps = { - user: Attendee; -}; - -export const AttendeeChip = ({ user }: AttendeeChipProps) => { - const classes = useStyles({ responseStatus: user.status?.response || '' }); - - return ( - - } - > - - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/CalendarCard.tsx b/plugins/microsoft-calendar/src/components/CalendarCard.tsx deleted file mode 100644 index 57c520ad0f..0000000000 --- a/plugins/microsoft-calendar/src/components/CalendarCard.tsx +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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 { sortBy } from 'lodash'; -import { DateTime } from 'luxon'; -import React, { useState } from 'react'; - -import { InfoCard, Progress } from '@backstage/core-components'; - -import { Box, IconButton, Typography } from '@material-ui/core'; -import PrevIcon from '@material-ui/icons/NavigateBefore'; -import NextIcon from '@material-ui/icons/NavigateNext'; - -import { useCalendarsQuery, useEventsQuery, useSignIn } from '../hooks'; -import calendarIcon from '../icons/calendar.svg'; -import { CalendarEvent } from './CalendarEvent'; -import { CalendarSelect } from './CalendarSelect'; -import { SignInContent } from './SignInContent'; -import { getStartDate } from './util'; -import useAsync from 'react-use/lib/useAsync'; - -export const CalendarCard = () => { - const [date, setDate] = useState(DateTime.now()); - const [selectedCalendarId, setSelectedCalendarId] = useState(''); - - const changeDay = (offset = 1) => { - setDate(prev => prev.plus({ day: offset })); - }; - - const { isSignedIn, isInitialized, signIn } = useSignIn(); - - useAsync(async () => signIn(true), [signIn]); - - const { - isLoading: isCalendarLoading, - isFetching: isCalendarFetching, - data: calendars = [], - } = useCalendarsQuery({ - enabled: isSignedIn, - }); - - const defaultCalendarId = calendars.find(c => c.isDefaultCalendar)?.id; - - const { data: events, isLoading: isEventLoading } = useEventsQuery({ - calendarId: selectedCalendarId || defaultCalendarId || '', - enabled: isSignedIn && calendars.length > 0, - timeMin: date.startOf('day').toISO()!, - timeMax: date.endOf('day').toISO()!, - timeZone: date.zoneName ?? undefined, - }); - - const showLoader = - (isCalendarLoading && isCalendarFetching) || - isEventLoading || - !isInitialized; - - return ( - - - Microsoft Calendar - - {isSignedIn ? ( - <> - changeDay(-1)} size="small"> - - - changeDay(1)} size="small"> - - - - - {date.toLocaleString({ - weekday: 'short', - month: 'short', - day: 'numeric', - })} - - - - - - - ) : ( - Agenda - )} - - } - deepLink={{ - link: 'https://outlook.office.com/calendar/', - title: 'Go to Calendar', - }} - > - - {showLoader && ( - - - - )} - {!isSignedIn && isInitialized && ( - signIn(false)} /> - )} - {!isEventLoading && !isCalendarLoading && isSignedIn && ( - - {events?.length === 0 && ( - - - No events - - - )} - {sortBy(events, [getStartDate]).map(event => ( - - ))} - - )} - - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/CalendarEvent.tsx b/plugins/microsoft-calendar/src/components/CalendarEvent.tsx deleted file mode 100644 index e56e25a09b..0000000000 --- a/plugins/microsoft-calendar/src/components/CalendarEvent.tsx +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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 classnames from 'classnames'; -import { - bindPopover, - bindTrigger, - usePopupState, -} from 'material-ui-popup-state/hooks'; -import React, { useState } from 'react'; - -import { Link } from '@backstage/core-components'; - -import { - Box, - Paper, - Popover, - Tooltip, - Typography, - makeStyles, -} from '@material-ui/core'; - -import webcamIcon from '../icons/webcam.svg'; -import { CalendarEventPopoverContent } from './CalendarEventPopoverContent'; -import { MicrosoftCalendarEvent } from '../api'; -import { - getOnlineMeetingLink, - getTimePeriod, - isAllDay, - isPassed, -} from './util'; - -const useStyles = makeStyles( - theme => ({ - event: { - display: 'flex', - alignItems: 'center', - marginBottom: theme.spacing(1), - cursor: 'pointer', - paddingRight: 12, - }, - declined: { - textDecoration: 'line-through', - }, - passed: { - opacity: 0.6, - transition: 'opacity 0.15s ease-in-out', - '&:hover': { - opacity: 1, - }, - }, - link: { - width: 48, - height: 48, - display: 'inline-block', - padding: 8, - borderRadius: '50%', - '&:hover': { - backgroundColor: theme.palette.grey[100], - }, - }, - calendarColor: { - width: 8, - borderTopLeftRadius: 4, - borderBottomLeftRadius: 4, - }, - }), - { - name: 'MicrosoftCalendarEvent', - }, -); - -export const CalendarEvent = ({ event }: { event: MicrosoftCalendarEvent }) => { - const classes = useStyles(); - const popoverState = usePopupState({ - variant: 'popover', - popupId: event.id, - disableAutoFocus: true, - }); - const [hovered, setHovered] = useState(false); - const onlineMeetingLink = getOnlineMeetingLink(event); - - const { onClick, ...restBindProps } = bindTrigger(popoverState); - - return ( - <> - { - onClick(e); - }} - {...restBindProps} - onMouseEnter={() => setHovered(true)} - onMouseLeave={() => setHovered(false)} - elevation={hovered ? 4 : 1} - className={classnames(classes.event, { - [classes.passed]: isPassed(event), - })} - data-testid="microsoft-calendar-event" - > - - - - {event.subject} - - {!isAllDay(event) && ( - - {getTimePeriod(event)} - - )} - - - {event.isOnlineMeeting && ( - - { - e.stopPropagation(); - }} - noTrack - > - {/* we can use onlineMeetingProvider to show icon accordingly */} - Online Meeting link - - - )} - - - - - - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/CalendarEventPopoverContent.tsx b/plugins/microsoft-calendar/src/components/CalendarEventPopoverContent.tsx deleted file mode 100644 index 715a1ad276..0000000000 --- a/plugins/microsoft-calendar/src/components/CalendarEventPopoverContent.tsx +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 { sortBy } from 'lodash'; -import React from 'react'; -import DOMPurify from 'dompurify'; - -import { Link } from '@backstage/core-components'; -import { - Box, - Divider, - IconButton, - Tooltip, - Typography, - makeStyles, -} from '@material-ui/core'; -import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; - -import { AttendeeChip } from './AttendeeChip'; -import { MicrosoftCalendarEvent } from '../api'; -import { getTimePeriod, getOnlineMeetingLink } from './util'; - -const useStyles = makeStyles( - theme => ({ - description: { - wordBreak: 'break-word', - '& a': { - color: theme.palette.primary.main, - fontWeight: 500, - }, - }, - divider: { - marginTop: theme.spacing(2), - marginBottom: theme.spacing(2), - }, - }), - { - name: 'MicrosoftCalendarEventPopoverContent', - }, -); - -type CalendarEventPopoverProps = { - event: MicrosoftCalendarEvent; -}; - -export const CalendarEventPopoverContent = ({ - event, -}: CalendarEventPopoverProps) => { - const classes = useStyles(); - const onlineMeetingLink = getOnlineMeetingLink(event); - - return ( - - - - {event.subject} - {getTimePeriod(event)} - - {event.webLink && ( - - {}} - noTrack - > - - - - - - )} - - {onlineMeetingLink && ( - {}} noTrack> - Join Online Meeting - - )} - - {event.bodyPreview && ( - <> - - - - )} - - {event.attendees && ( - <> - - - Attendees - - {sortBy(event.attendees || [], 'emailAddress').map(user => ( - - ))} - - - )} - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/CalendarSelect.tsx b/plugins/microsoft-calendar/src/components/CalendarSelect.tsx deleted file mode 100644 index 59e2376079..0000000000 --- a/plugins/microsoft-calendar/src/components/CalendarSelect.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 { sortBy } from 'lodash'; -import React from 'react'; - -import { - Checkbox, - FormControl, - Input, - ListItemText, - MenuItem, - Select, - Typography, - makeStyles, -} from '@material-ui/core'; -import { MicrosoftCalendar } from '../api'; - -const useStyles = makeStyles( - { - formControl: { - width: 120, - }, - selectedCalendars: { - textOverflow: 'ellipsis', - overflow: 'hidden', - }, - }, - { - name: 'MicrosoftCalendarSelect', - }, -); - -type CalendarSelectProps = { - disabled: boolean; - selectedCalendarId?: string; - setSelectedCalendarId: (value: string) => void; - calendars: MicrosoftCalendar[]; -}; - -export const CalendarSelect = ({ - disabled, - selectedCalendarId, - setSelectedCalendarId, - calendars, -}: CalendarSelectProps) => { - const classes = useStyles(); - return ( - - } - renderValue={selected => { - return ( - - {calendars.find(c => c.id === selected)?.name} - - ); - }} - MenuProps={{ - PaperProps: { - style: { - width: 350, - }, - }, - }} - > - {sortBy(calendars, 'name').map(c => ( - - - - - ))} - - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/MicrosoftCalendar.tsx b/plugins/microsoft-calendar/src/components/MicrosoftCalendar.tsx deleted file mode 100644 index 3bb15f7762..0000000000 --- a/plugins/microsoft-calendar/src/components/MicrosoftCalendar.tsx +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 { QueryClient, QueryClientProvider } from '@tanstack/react-query'; - -import { CalendarCard } from './CalendarCard'; - -const queryClient = new QueryClient(); - -export const MicrosoftCalendar = () => { - return ( - - - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/SignInContent.tsx b/plugins/microsoft-calendar/src/components/SignInContent.tsx deleted file mode 100644 index d33698f68c..0000000000 --- a/plugins/microsoft-calendar/src/components/SignInContent.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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, Button, styled } from '@material-ui/core'; -import { CalendarEvent } from './CalendarEvent'; -import mockEvents from './eventMock.json'; -import { MicrosoftCalendarEvent } from '../api'; - -type Props = { - handleAuthClick: React.MouseEventHandler; -}; - -const TransparentBox = styled(Box)({ - opacity: 0.3, - filter: 'blur(1.5px)', -}); - -export const SignInContent = ({ handleAuthClick }: Props) => { - return ( - - - {(mockEvents as MicrosoftCalendarEvent[]).map(event => ( - - ))} - - - - - - - ); -}; diff --git a/plugins/microsoft-calendar/src/components/eventMock.json b/plugins/microsoft-calendar/src/components/eventMock.json deleted file mode 100644 index b648d1b486..0000000000 --- a/plugins/microsoft-calendar/src/components/eventMock.json +++ /dev/null @@ -1,138 +0,0 @@ -[ - { - "id": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MAFRAAgI2vdUnGxAAEYAAAAABZfL1rFDfUO0G4cMgXCC1gcApFI7gxQldkOLWHDOlgt60AAAAAABDQAApFI7gxQldkOLWHDOlgt60AAAYl_I0AAAEA==", - "createdDateTime": "2022-12-22T08:28:36.6131501Z", - "lastModifiedDateTime": "2023-01-20T05:24:31.9666518Z", - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAd5KhaA==", - "categories": [], - "transactionId": null, - "originalStartTimeZone": "India Standard Time", - "originalEndTimeZone": "India Standard Time", - "iCalUId": "040000008200E00074C5B7101A82E00807E7011006D3A5A92DC7D80100000000000000001000000002BB709705E28C4493E46124FF07DD89", - "reminderMinutesBeforeStart": 15, - "isReminderOn": true, - "hasAttachments": false, - "subject": "Abhay Soni", - "bodyPreview": "", - "importance": "normal", - "sensitivity": "normal", - "isAllDay": false, - "isCancelled": false, - "isOrganizer": false, - "responseRequested": true, - "seriesMasterId": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=", - "showAs": "tentative", - "type": "occurrence", - "webLink": "", - "onlineMeetingUrl": "", - "isOnlineMeeting": true, - "onlineMeetingProvider": "teamsForBusiness", - "allowNewTimeProposals": true, - "occurrenceId": "OID.AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=.2023-01-16", - "isDraft": false, - "hideAttendees": false, - "responseStatus": { - "response": "notResponded", - "time": "0001-01-01T00:00:00Z" - }, - "body": { - "contentType": "html", - "content": "" - }, - "start": { - "dateTime": "2023-01-16T11:00:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "end": { - "dateTime": "2023-01-16T11:30:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "location": { - "displayName": "", - "locationType": "default", - "uniqueIdType": "unknown", - "address": {}, - "coordinates": {} - }, - "locations": [], - "recurrence": null, - "attendees": [], - "organizer": { - "emailAddress": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - "onlineMeeting": { - "joinUrl": "https://abhay-soni-developer.github.io/MyReusme/" - } - }, - { - "id": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MAFRAAgI2vdUnGxAAEYAAAAABZfL1rFDfUO0G4cMgXCC1gcApFI7gxQldkOLWHDOlgt60AAAAAABDQAApFI7gxQldkOLWHDOlgt60AAAYl_I0AAAEA==", - "createdDateTime": "2022-12-22T08:28:36.6131501Z", - "lastModifiedDateTime": "2023-01-20T05:24:31.9666518Z", - "changeKey": "pFI7gxQldkOLWHDOlgt60AAAd5KhaA==", - "categories": [], - "transactionId": null, - "originalStartTimeZone": "India Standard Time", - "originalEndTimeZone": "India Standard Time", - "iCalUId": "040000008200E00074C5B7101A82E00807E7011006D3A5A92DC7D80100000000000000001000000002BB709705E28C4493E46124FF07DD89", - "reminderMinutesBeforeStart": 15, - "isReminderOn": true, - "hasAttachments": false, - "subject": "https://abhay-soni-developer.github.io/MyReusme/", - "bodyPreview": "", - "importance": "normal", - "sensitivity": "normal", - "isAllDay": false, - "isCancelled": false, - "isOrganizer": false, - "responseRequested": true, - "seriesMasterId": "AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=", - "showAs": "tentative", - "type": "occurrence", - "webLink": "", - "onlineMeetingUrl": "", - "isOnlineMeeting": true, - "onlineMeetingProvider": "teamsForBusiness", - "allowNewTimeProposals": true, - "occurrenceId": "OID.AAMkADQyMDdlODU1LTk4Y2ItNGFmYi04YzYyLWQ4NmEzMmRhZTY5MABGAAAAAAAFl8vWsUN9Q7QbhwyBcILWBwCkUjuDFCV2Q4tYcM6WC3rQAAAAAAENAACkUjuDFCV2Q4tYcM6WC3rQAABiX4jQAAA=.2023-01-16", - "isDraft": false, - "hideAttendees": false, - "responseStatus": { - "response": "notResponded", - "time": "0001-01-01T00:00:00Z" - }, - "body": { - "contentType": "html", - "content": "" - }, - "start": { - "dateTime": "2023-01-16T11:00:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "end": { - "dateTime": "2023-01-16T11:30:00.0000000", - "timeZone": "Asia/Calcutta" - }, - "location": { - "displayName": "", - "locationType": "default", - "uniqueIdType": "unknown", - "address": {}, - "coordinates": {} - }, - "locations": [], - "recurrence": null, - "attendees": [], - "organizer": { - "emailAddress": { - "name": "Abhay Soni", - "address": "abhaysoni.developer@gmail.com" - } - }, - "onlineMeeting": { - "joinUrl": "https://abhay-soni-developer.github.io/MyReusme/" - } - } -] diff --git a/plugins/microsoft-calendar/src/components/index.ts b/plugins/microsoft-calendar/src/components/index.ts deleted file mode 100644 index 8149695804..0000000000 --- a/plugins/microsoft-calendar/src/components/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 { MicrosoftCalendar } from './MicrosoftCalendar'; diff --git a/plugins/microsoft-calendar/src/components/util.ts b/plugins/microsoft-calendar/src/components/util.ts deleted file mode 100644 index dd52402d9d..0000000000 --- a/plugins/microsoft-calendar/src/components/util.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 { DateTime } from 'luxon'; - -import { MicrosoftCalendarEvent } from '../api'; - -export function getOnlineMeetingLink(event: MicrosoftCalendarEvent) { - const onlineEntrypoint = - event.onlineMeeting?.joinUrl || event.onlineMeetingUrl; - if (onlineEntrypoint) { - return onlineEntrypoint; - } - return ''; -} - -export function getTimePeriod(event: MicrosoftCalendarEvent) { - if (isAllDay(event)) { - return getAllDayTimePeriod(event); - } - - const format: Intl.DateTimeFormatOptions = { - hour: '2-digit', - minute: '2-digit', - }; - - const startTime = DateTime.fromISO(event.start?.dateTime || ''); - const endTime = DateTime.fromISO(event.end?.dateTime || ''); - - return `${startTime.toLocaleString(format)} - ${endTime.toLocaleString( - format, - )}`; -} - -function getAllDayTimePeriod(event: MicrosoftCalendarEvent) { - const format: Intl.DateTimeFormatOptions = { month: 'long', day: 'numeric' }; - const startTime = DateTime.fromISO(event.start?.dateTime || ''); - const endTime = DateTime.fromISO(event.end?.dateTime || '').minus({ day: 1 }); - - if (startTime.toISO() === endTime.toISO()) { - return startTime.toLocaleString(format); - } - - return `${startTime.toLocaleString(format)} - ${endTime.toLocaleString( - format, - )}`; -} - -export function isPassed(event: MicrosoftCalendarEvent) { - if (!event.end?.dateTime) return false; - const eventDate = DateTime.fromISO(event.end?.dateTime!); - return DateTime.now() >= eventDate; -} - -export function isAllDay(event: MicrosoftCalendarEvent) { - const startTime = DateTime.fromISO(event.start?.dateTime || ''); - const endTime = DateTime.fromISO(event.end?.dateTime || ''); - - return endTime.diff(startTime, 'day').days >= 1; -} - -export function getStartDate(event: MicrosoftCalendarEvent) { - return DateTime.fromISO(event.start?.dateTime || ''); -} diff --git a/plugins/microsoft-calendar/src/hooks/index.ts b/plugins/microsoft-calendar/src/hooks/index.ts deleted file mode 100644 index a10f6a6c3a..0000000000 --- a/plugins/microsoft-calendar/src/hooks/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 { useCalendarsQuery } from './useCalendarsQuery'; -export { useEventsQuery } from './useEventsQuery'; -export { useSignIn } from './useSignIn'; diff --git a/plugins/microsoft-calendar/src/hooks/useCalendarsQuery.ts b/plugins/microsoft-calendar/src/hooks/useCalendarsQuery.ts deleted file mode 100644 index 47a7990b58..0000000000 --- a/plugins/microsoft-calendar/src/hooks/useCalendarsQuery.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 { useQuery } from '@tanstack/react-query'; - -import { errorApiRef, useApi } from '@backstage/core-plugin-api'; - -import { microsoftCalendarApiRef } from '../api'; - -type Options = { - enabled: boolean; - refreshTime?: number; -}; - -export const useCalendarsQuery = ({ enabled }: Options) => { - const calendarApi = useApi(microsoftCalendarApiRef); - const errorApi = useApi(errorApiRef); - - return useQuery( - ['calendars-list'], - async () => { - const calendars = []; - const value = await calendarApi.getCalendars(); - calendars.push(...value); - return calendars; - }, - { - enabled, - // old data will be returned if last request was made within 3 mins. - staleTime: 180000, - refetchInterval: 3600000, - onError: () => { - errorApi.post({ - name: 'API error', - message: 'Failed to fetch calendars.', - }); - }, - }, - ); -}; diff --git a/plugins/microsoft-calendar/src/hooks/useEventsQuery.ts b/plugins/microsoft-calendar/src/hooks/useEventsQuery.ts deleted file mode 100644 index 5e9dc76812..0000000000 --- a/plugins/microsoft-calendar/src/hooks/useEventsQuery.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 { useQuery } from '@tanstack/react-query'; - -import { useApi } from '@backstage/core-plugin-api'; - -import { microsoftCalendarApiRef } from '../api'; - -type Options = { - calendarId: string; - timeMin: string; - timeMax: string; - enabled?: boolean; - timeZone?: string; - refreshTime?: number; -}; - -export const useEventsQuery = ({ - calendarId, - enabled, - timeMin, - timeMax, - timeZone, -}: Options) => { - const calendarApi = useApi(microsoftCalendarApiRef); - return useQuery( - ['calendarEvents', calendarId, timeMin, timeMax, timeZone], - async () => { - const data = await calendarApi.getEvents( - calendarId, - { - startDateTime: timeMin, - endDateTime: timeMax, - }, - { - Prefer: `outlook.timezone="${timeZone}"`, - }, - ); - return data; - }, - { - cacheTime: 300000, - enabled, - refetchInterval: 60000, - refetchIntervalInBackground: true, - }, - ); -}; diff --git a/plugins/microsoft-calendar/src/hooks/useSignIn.ts b/plugins/microsoft-calendar/src/hooks/useSignIn.ts deleted file mode 100644 index 8b3ac54f92..0000000000 --- a/plugins/microsoft-calendar/src/hooks/useSignIn.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 { useCallback, useState } from 'react'; - -import { microsoftAuthApiRef, useApi } from '@backstage/core-plugin-api'; - -export const useSignIn = () => { - const [isSignedIn, setSignedIn] = useState(false); - const [isInitialized, setInitialized] = useState(false); - const authApi = useApi(microsoftAuthApiRef); - - const signIn = useCallback( - async (optional = false) => { - const token = await authApi.getAccessToken('Calendars.Read', { - optional, - instantPopup: !optional, - }); - - setSignedIn(!!token); - setInitialized(true); - }, - [authApi, setSignedIn], - ); - - return { isSignedIn, isInitialized, signIn }; -}; diff --git a/plugins/microsoft-calendar/src/icons/calendar.svg b/plugins/microsoft-calendar/src/icons/calendar.svg deleted file mode 100644 index 79895da87a..0000000000 --- a/plugins/microsoft-calendar/src/icons/calendar.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/microsoft-calendar/src/icons/webcam.svg b/plugins/microsoft-calendar/src/icons/webcam.svg deleted file mode 100644 index 356bb69215..0000000000 --- a/plugins/microsoft-calendar/src/icons/webcam.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/plugins/microsoft-calendar/src/index.ts b/plugins/microsoft-calendar/src/index.ts deleted file mode 100644 index 6867ca31ac..0000000000 --- a/plugins/microsoft-calendar/src/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { MicrosoftCalendarCard } from './plugin'; -export { MicrosoftCalendarApiClient, microsoftCalendarApiRef } from './api'; diff --git a/plugins/microsoft-calendar/src/plugin.test.ts b/plugins/microsoft-calendar/src/plugin.test.ts deleted file mode 100644 index 7da86e176b..0000000000 --- a/plugins/microsoft-calendar/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { microsoftCalendarPlugin } from './plugin'; - -describe('microsoft-calendar', () => { - it('should export plugin', () => { - expect(microsoftCalendarPlugin).toBeDefined(); - }); -}); diff --git a/plugins/microsoft-calendar/src/plugin.ts b/plugins/microsoft-calendar/src/plugin.ts deleted file mode 100644 index 644d368d97..0000000000 --- a/plugins/microsoft-calendar/src/plugin.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - createPlugin, - microsoftAuthApiRef, - fetchApiRef, - createApiFactory, - createComponentExtension, -} from '@backstage/core-plugin-api'; -import { - microsoftCalendarApiRef, - MicrosoftCalendarApiClient, -} from './api/index'; - -export const microsoftCalendarPlugin = createPlugin({ - id: 'microsoft-calendar', - apis: [ - createApiFactory({ - api: microsoftCalendarApiRef, - deps: { authApi: microsoftAuthApiRef, fetchApi: fetchApiRef }, - factory(deps) { - return new MicrosoftCalendarApiClient(deps); - }, - }), - ], -}); - -/** @public */ -export const MicrosoftCalendarCard = microsoftCalendarPlugin.provide( - createComponentExtension({ - name: 'MicrosoftCalendarCard', - component: { - lazy: () => import('./components').then(m => m.MicrosoftCalendar), - }, - }), -); diff --git a/plugins/microsoft-calendar/src/setupTests.ts b/plugins/microsoft-calendar/src/setupTests.ts deleted file mode 100644 index 865308e634..0000000000 --- a/plugins/microsoft-calendar/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import '@testing-library/jest-dom'; diff --git a/plugins/newrelic-dashboard/.eslintrc.js b/plugins/newrelic-dashboard/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/newrelic-dashboard/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md deleted file mode 100644 index df9df9709e..0000000000 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ /dev/null @@ -1,1204 +0,0 @@ -# @backstage/plugin-newrelic-dashboard - -## 0.3.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.3.5-next.2 - -### Patch Changes - -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.3.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/errors@1.2.3 - -## 0.3.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.3.4 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.3.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.4-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.3-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.3.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.3.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.1 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.1-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.3.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - -## 0.3.1-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.0 - -### Minor Changes - -- d7eba6cab4: Changes in `newrelic-dashboard` plugin: - - - Make DashboardSnapshotList component public - - Settle discrepancies in the exported API - - Deprecate DashboardSnapshotComponent - -- e605ea4906: Add storybook for newrelic-dashboard plugin. - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- 61d55942ae: Fix the styles for NewRelicDashboard, add more responsiveness -- 5194a51a1c: Fixed React Warning: "Each child in a list should have a unique 'key' prop" during the rendering of `EntityNewRelicDashboardCard` -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.3.0-next.2 - -### Minor Changes - -- d7eba6cab4: Changes in `newrelic-dashboard` plugin: - - - Make DashboardSnapshotList component public - - Settle discrepancies in the exported API - - Deprecate DashboardSnapshotComponent - -### Patch Changes - -- 5194a51a1c: Fixed React Warning: "Each child in a list should have a unique 'key' prop" during the rendering of `EntityNewRelicDashboardCard` -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - -## 0.2.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - -## 0.2.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - -## 0.2.17 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - -## 0.2.17-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - -## 0.2.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - -## 0.2.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - -## 0.2.16-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.2.14 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - -## 0.2.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.2.14-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/catalog-model@1.4.1 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.1-next.0 - -## 0.2.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - -## 0.2.13 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.2.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - -## 0.2.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.2.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.2.12 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - -## 0.2.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.2.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.2.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.2.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.2.11 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.2.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.2.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.2.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.2.10 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.2.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - -## 0.2.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.2.10-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.2.10-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.2.9 - -### Patch Changes - -- cb8ec97cdeb: Change black & white colors to be theme aware -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - -## 0.2.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.2.9-next.1 - -### Patch Changes - -- cb8ec97cdeb: Change black & white colors to be theme aware -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - -## 0.2.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/errors@1.1.4 - -## 0.2.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.2.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - -## 0.2.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - -## 0.2.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.2.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.2.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - -## 0.2.5-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.2.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/errors@1.1.4-next.0 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/errors@1.1.3 - -## 0.2.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.2.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - -## 0.2.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/errors@1.1.2-next.1 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - -## 0.2.2 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - - @backstage/errors@1.1.1 - -## 0.2.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.2.2-next.1 - -### Patch Changes - -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.2.2-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- 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 - -## 0.2.0-next.3 - -### 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-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.1.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.1.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.1.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.1.14 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.1.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.1.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.1.13 - -### Patch Changes - -- 5fa2fb2553: Add `FetchApi` and related `fetchApiRef` which implement fetch. in order to included the Authorization Token to New Relic Dashboard Plugin, so that frontend can send an authenticated proxy call to backend -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.1.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.1.13-next.0 - -### Patch Changes - -- 5fa2fb2553: Add `FetchApi` and related `fetchApiRef` which implement fetch. in order to included the Authorization Token to New Relic Dashboard Plugin, so that frontend can send an authenticated proxy call to backend -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.1.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.1.11 - -### Patch Changes - -- f24ef7864e: Minor typo fixes -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - - @backstage/errors@1.0.0 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.1.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.1.7 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/errors@0.2.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - -## 0.1.6 - -### Patch Changes - -- 5ca42462b7: Export DashboardSnapshotComponent from new-relic-dashboard-plugin -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.1.6-next.0 - -### Patch Changes - -- 5ca42462b7: Export DashboardSnapshotComponent from new-relic-dashboard-plugin -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.1.4 - -### Patch Changes - -- afe1bd78d2: Newrelic Dashboards will render single page dashboards, meaning dashboards which do not have a parent GUID -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/errors@0.2.0 - - @backstage/catalog-model@0.9.9 - -## 0.1.2 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.1.1 - -### Patch Changes - -- c38a47cd08: Created a New Plugin , which imports dashboard links and snapshots from New Relic -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 diff --git a/plugins/newrelic-dashboard/README.md b/plugins/newrelic-dashboard/README.md deleted file mode 100644 index a31042b3fe..0000000000 --- a/plugins/newrelic-dashboard/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# New Relic Dashboard Plugin - -Welcome to the newrelic-dashboard plugin! - -## Features - -- Adds New Relic Dashboard Pages Links to Overview section of the catalog -- Shows Snapshots of dashboards in New Relic - -## Getting started - -This plugin uses the Backstage proxy to securely communicate with New Relic's APIs. We use NerdGraph (New Relic's GraphQL API) - -To generate a New Relic API Key , you can visit this [link](https://one.newrelic.com/launcher/api-keys-ui.api-keys-launcher) - -1. Add the following to your app-config.yaml to enable this configuration: - -``` -// app-config.yaml -proxy: - '/newrelic/api': - target: https://api.newrelic.com - headers: - X-Api-Key: ${NEW_RELIC_USER_KEY} -``` - -2. Add the following to `EntityPage.tsx` to display New Relic Dashboard Tab - -``` -// In packages/app/src/components/catalog/EntityPage.tsx -import { - isNewRelicDashboardAvailable, - EntityNewRelicDashboardContent, - EntityNewRelicDashboardCard, -} from '@backstage/plugin-newrelic-dashboard'; - -const serviceEntityPage = ( - - {/* other tabs... */} - - - -``` - -3. Add the following in `EntityPage.tsx` to display dashboard links in overview page - -``` -const overviewContent = ( - {/* other tabs... */} - - - - - - - -``` - -4. Add `newrelic.com/dashboard-guid` annotation in catalog descriptor file - -To Obtain the dashboard's GUID: Click the info icon by the dashboard's name to access the See metadata and manage tags modal and see the dashboard's GUID. - -``` -// catalog-info.yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - # ... - annotations: - newrelic.com/dashboard-guid: -spec: - type: service -``` - -All set , you will be able to see the plugin in action! diff --git a/plugins/newrelic-dashboard/api-report.md b/plugins/newrelic-dashboard/api-report.md deleted file mode 100644 index 283523d781..0000000000 --- a/plugins/newrelic-dashboard/api-report.md +++ /dev/null @@ -1,48 +0,0 @@ -## API Report File for "@backstage/plugin-newrelic-dashboard" - -> 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 { Entity } from '@backstage/catalog-model'; -import { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public -export const DashboardSnapshot: (props: { - guid: string; - name: string; - permalink: string; -}) => JSX_2.Element; - -// @public @deprecated -export const DashboardSnapshotComponent: (props: { - guid: string; - name: string; - permalink: string; -}) => JSX_2.Element; - -// @public -export const DashboardSnapshotList: (props: { guid: string }) => JSX_2.Element; - -// @public (undocumented) -export const EntityNewRelicDashboardCard: () => JSX_2.Element; - -// @public (undocumented) -export const EntityNewRelicDashboardContent: () => JSX_2.Element; - -// @public (undocumented) -export const isNewRelicDashboardAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export const newRelicDashboardPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/newrelic-dashboard/catalog-info.yaml b/plugins/newrelic-dashboard/catalog-info.yaml deleted file mode 100644 index d944c9cb6b..0000000000 --- a/plugins/newrelic-dashboard/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-newrelic-dashboard - title: '@backstage/plugin-newrelic-dashboard' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/newrelic-dashboard/dev/index.tsx b/plugins/newrelic-dashboard/dev/index.tsx deleted file mode 100644 index bb5f5b92d7..0000000000 --- a/plugins/newrelic-dashboard/dev/index.tsx +++ /dev/null @@ -1,19 +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 { createDevApp } from '@backstage/dev-utils'; -import { newRelicDashboardPlugin } from '../src/plugin'; - -createDevApp().registerPlugin(newRelicDashboardPlugin).render(); diff --git a/plugins/newrelic-dashboard/knip-report.md b/plugins/newrelic-dashboard/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/newrelic-dashboard/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json deleted file mode 100644 index 3209dfdc26..0000000000 --- a/plugins/newrelic-dashboard/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.3.5-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/newrelic-dashboard" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/newrelic-dashboard/src/Router.tsx b/plugins/newrelic-dashboard/src/Router.tsx deleted file mode 100644 index 82f20a4a29..0000000000 --- a/plugins/newrelic-dashboard/src/Router.tsx +++ /dev/null @@ -1,49 +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 { Entity } from '@backstage/catalog-model'; -import React from 'react'; -import { Button } from '@material-ui/core'; -import { NewRelicDashboard } from './components/NewRelicDashboard'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import { NEWRELIC_GUID_ANNOTATION } from './constants'; - -/** @public */ -export const isNewRelicDashboardAvailable = (entity: Entity) => - Boolean(entity?.metadata?.annotations?.[NEWRELIC_GUID_ANNOTATION]); - -export const Router = () => { - const { entity } = useEntity(); - - if (isNewRelicDashboardAvailable(entity)) { - return ; - } - - return ( - <> - - - - ); -}; diff --git a/plugins/newrelic-dashboard/src/api/NewRelicDashboardApi.ts b/plugins/newrelic-dashboard/src/api/NewRelicDashboardApi.ts deleted file mode 100644 index 48c7a44c3a..0000000000 --- a/plugins/newrelic-dashboard/src/api/NewRelicDashboardApi.ts +++ /dev/null @@ -1,42 +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 { createApiRef } from '@backstage/core-plugin-api'; -import { DashboardEntity } from '../types/DashboardEntity'; -import { DashboardSnapshot } from '../types/DashboardSnapshot'; -import { SnapshotDetails } from '../types/SnapshotDetails'; - -export interface DashboardEntitySummary { - getDashboardEntity: DashboardEntity; -} - -export interface DashboardSnapshotSummary { - getDashboardSnapshot: DashboardSnapshot; -} - -export interface SnapshotDetailsSummary { - getSnapshotDetails: SnapshotDetails[]; -} -export const newRelicDashboardApiRef = createApiRef({ - id: 'plugin.newrelicdashboard.service', -}); - -export type NewRelicDashboardApi = { - getDashboardEntity(guid: string): Promise; - getDashboardSnapshot( - guid: string, - duration: number, - ): Promise; -}; diff --git a/plugins/newrelic-dashboard/src/api/NewRelicDashboardClient.ts b/plugins/newrelic-dashboard/src/api/NewRelicDashboardClient.ts deleted file mode 100644 index 63b33056e1..0000000000 --- a/plugins/newrelic-dashboard/src/api/NewRelicDashboardClient.ts +++ /dev/null @@ -1,113 +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 { - DashboardEntitySummary, - DashboardSnapshotSummary, - NewRelicDashboardApi, -} from './NewRelicDashboardApi'; -import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; -import { DashboardEntity } from '../types/DashboardEntity'; -import { DashboardSnapshot } from '../types/DashboardSnapshot'; -import { getDashboardParentGuidQuery } from '../queries/getDashboardParentGuidQuery'; -import { getDashboardSnapshotQuery } from '../queries/getDashboardSnapshotQuery'; -import { ResponseError } from '@backstage/errors'; - -export class NewRelicDashboardClient implements NewRelicDashboardApi { - private readonly discoveryApi: DiscoveryApi; - private readonly fetchApi: FetchApi; - - constructor({ - discoveryApi, - fetchApi, - }: { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - baseUrl?: string; - }) { - this.discoveryApi = discoveryApi; - this.fetchApi = fetchApi; - } - - private async callApi( - query: string, - variables: { [key in string]: string | number }, - ): Promise { - const myHeaders = new Headers(); - myHeaders.append('Content-Type', 'application/json'); - const graphql = JSON.stringify({ - query: query, - variables: variables, - }); - const requestOptions: RequestInit = { - method: 'POST', - headers: myHeaders, - body: graphql, - redirect: 'follow', - }; - - const apiUrl = `${await this.discoveryApi.getBaseUrl( - 'proxy', - )}/newrelic/api/graphql`; - const response = await this.fetchApi.fetch(apiUrl, requestOptions); - if (response.status === 200) { - return (await response.json()) as T; - } - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } else { - return undefined; - } - } - - async getDashboardEntity( - guid: string, - ): Promise { - const DashboardEntityList = await this.callApi( - getDashboardParentGuidQuery, - { - query: `id ='${guid}' OR parentId ='${guid}'`, - }, - ); - if ( - DashboardEntityList && - DashboardEntityList?.data?.actor.entitySearch.results.entities?.length > 1 - ) { - DashboardEntityList.data.actor.entitySearch.results.entities = - DashboardEntityList?.data.actor.entitySearch.results.entities.filter( - entity => entity?.dashboardParentGuid !== null, - ); - } - return { - getDashboardEntity: DashboardEntityList!, - }; - } - - async getDashboardSnapshot( - guid: string, - duration: number, - ): Promise { - const DashboardSnapshotValue = await this.callApi( - getDashboardSnapshotQuery, - { - guid: guid, - duration: duration, - }, - ); - return { - getDashboardSnapshot: DashboardSnapshotValue!, - }; - } -} diff --git a/plugins/newrelic-dashboard/src/api/index.ts b/plugins/newrelic-dashboard/src/api/index.ts deleted file mode 100644 index 9b14160bcf..0000000000 --- a/plugins/newrelic-dashboard/src/api/index.ts +++ /dev/null @@ -1,18 +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. - */ -export type { NewRelicDashboardApi } from './NewRelicDashboardApi'; -export { newRelicDashboardApiRef } from './NewRelicDashboardApi'; -export { NewRelicDashboardClient } from './NewRelicDashboardClient'; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardEntityList.tsx b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardEntityList.tsx deleted file mode 100644 index 8d87a54ca0..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardEntityList.tsx +++ /dev/null @@ -1,89 +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 { Box, makeStyles, Typography } from '@material-ui/core'; -import { newRelicDashboardApiRef } from '../../api'; -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { - Progress, - InfoCard, - Link, - ErrorPanel, -} from '@backstage/core-components'; -import DesktopMac from '@material-ui/icons/DesktopMac'; -import { DashboardEntitySummary } from '../../api/NewRelicDashboardApi'; -import { ResultEntity } from '../../types/DashboardEntity'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { NEWRELIC_GUID_ANNOTATION } from '../../constants'; - -const useStyles = makeStyles({ - svgIcon: { - display: 'inline-block', - '& svg': { - display: 'inline-block', - fontSize: 'inherit', - verticalAlign: 'baseline', - }, - }, -}); -export const DashboardEntityList = () => { - const { entity } = useEntity(); - const classes = useStyles(); - const newRelicDashboardAPI = useApi(newRelicDashboardApiRef); - const { value, loading, error } = useAsync(async (): Promise< - DashboardEntitySummary | undefined - > => { - const dashboardObject: Promise = - newRelicDashboardAPI.getDashboardEntity( - String(entity.metadata.annotations?.[NEWRELIC_GUID_ANNOTATION]), - ); - return dashboardObject; - }, [entity.metadata.annotations?.[NEWRELIC_GUID_ANNOTATION]]); - if (loading) { - return ; - } - if (error) { - return ; - } - return ( - - {value?.getDashboardEntity === undefined && - 'Unauthorized Request , please check API Key'} - {value?.getDashboardEntity !== undefined && - value?.getDashboardEntity?.data.actor.entitySearch.results?.entities - ?.length <= 0 && ( - <>No Dashboard Pages found with the specified Dashboard GUID - )} - {value?.getDashboardEntity?.data.actor.entitySearch.results.entities?.map( - (entityResult: ResultEntity, index: number) => { - return ( - - - - - - - - {entityResult.name} - - - ); - }, - )} - - ); -}; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshot.tsx b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshot.tsx deleted file mode 100644 index c19697a4f0..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshot.tsx +++ /dev/null @@ -1,130 +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 { Box, makeStyles, MenuItem, Select } from '@material-ui/core'; -import { useApi, storageApiRef } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { - InfoCard, - Progress, - ErrorPanel, - Link, -} from '@backstage/core-components'; -import { newRelicDashboardApiRef } from '../../../api'; -import { DashboardSnapshotSummary } from '../../../api/NewRelicDashboardApi'; -import useObservable from 'react-use/lib/useObservable'; - -const useStyles = makeStyles( - theme => ({ - cardSelect: { - margin: theme.spacing(2, 1, 0, 0), - }, - img: { - width: '100%', - height: 'auto', - border: `solid 1px ${theme.palette.common.black}`, - }, - }), - { name: 'BackstageNewRelicDashboardSnapshot' }, -); - -/** - * @public - */ -export const DashboardSnapshot = (props: { - guid: string; - name: string; - permalink: string; -}) => { - const classes = useStyles(); - const { guid, name, permalink } = props; - const newRelicDashboardAPI = useApi(newRelicDashboardApiRef); - const storageApi = useApi(storageApiRef).forBucket('newrelic-dashboard'); - const setStorageValue = (value: number) => { - storageApi.set(guid, value); - }; - const storageSnapshot = useObservable( - storageApi.observe$(guid), - storageApi.snapshot(guid), - ); - - const { value, loading, error } = useAsync(async (): Promise< - DashboardSnapshotSummary | undefined - > => { - const dashboardObject: Promise = - newRelicDashboardAPI.getDashboardSnapshot( - guid, - storageSnapshot.value || 2592000000, - ); - return dashboardObject; - }, [guid, storageSnapshot.value]); - - if (loading) { - return ; - } - if (error) { - return ; - } - - const url = - value?.getDashboardSnapshot?.data?.dashboardCreateSnapshotUrl?.replace( - /\pdf$/i, - 'png', - ); - - return ( - - - - } - > - - - - {url ? ( - {`${name} - ) : ( - 'Dashboard loading... , click here to open if it did not render correctly' - )} - - - - - ); -}; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshotList.tsx b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshotList.tsx deleted file mode 100644 index 81686d10c9..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshotList.tsx +++ /dev/null @@ -1,158 +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, { useState } from 'react'; -import { Tab, Tabs, makeStyles, Box } from '@material-ui/core'; -import { newRelicDashboardApiRef } from '../../../api'; -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { Progress, ErrorPanel } from '@backstage/core-components'; -import { DashboardSnapshot } from './DashboardSnapshot'; -import { DashboardEntitySummary } from '../../../api/NewRelicDashboardApi'; -import { ResultEntity } from '../../../types/DashboardEntity'; - -interface TabPanelProps { - children?: React.ReactNode; - index: number; - value1: number; -} - -const tabPanelStyles = makeStyles( - theme => ({ - tabPanel: { - marginTop: theme.spacing(0.5), - }, - }), - { name: 'BackstageNewRelicDashboardTabPanel' }, -); - -function TabPanel(props: TabPanelProps) { - const { children, value1, index, ...other } = props; - const classes = tabPanelStyles(tabPanelStyles); - - return ( - - ); -} - -function a11yProps(index: number) { - return { - id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, - }; -} - -const useStyles = makeStyles( - theme => ({ - tabsWrapper: { - gridArea: 'pageSubheader', - backgroundColor: theme.palette.background.paper, - paddingLeft: theme.spacing(3), - }, - defaultTab: { - padding: theme.spacing(3, 3), - ...theme.typography.caption, - textTransform: 'uppercase', - fontWeight: 'bold', - color: theme.palette.text.secondary, - }, - selected: { - color: theme.palette.text.primary, - }, - tabRoot: { - '&:hover': { - backgroundColor: theme.palette.background.default, - color: theme.palette.text.primary, - }, - }, - }), - { name: 'DashboardHeaderTabs' }, -); - -export const DashboardSnapshotList = (props: { guid: string }) => { - const { guid } = props; - const styles = useStyles(); - const newRelicDashboardAPI = useApi(newRelicDashboardApiRef); - const { value, loading, error } = useAsync(async (): Promise< - DashboardEntitySummary | undefined - > => { - const dashboardObject: Promise = - newRelicDashboardAPI.getDashboardEntity(guid); - return dashboardObject; - }, [guid]); - const [value1, setValue1] = useState(0); - const handleChange = ({}: React.ChangeEvent<{}>, newValue: number) => { - setValue1(newValue); - }; - - if (loading) { - return ; - } - if (error) { - return ; - } - return ( - - - {value?.getDashboardEntity?.data?.actor.entitySearch.results.entities?.map( - (Entity: ResultEntity, index: number) => { - return ( - - ); - }, - )} - - {value?.getDashboardEntity?.data?.actor.entitySearch.results.entities?.map( - (Entity: ResultEntity, index: number) => { - return ( - - - - ); - }, - )} - - ); -}; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/index.ts b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/index.ts deleted file mode 100644 index 6d6ba5666b..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/DashboardSnapshotList/index.ts +++ /dev/null @@ -1,18 +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. - */ - -export { DashboardSnapshot } from './DashboardSnapshot'; -export { DashboardSnapshotList } from './DashboardSnapshotList'; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/NewRelicDashboard.stories.tsx b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/NewRelicDashboard.stories.tsx deleted file mode 100644 index a15a4c573c..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/NewRelicDashboard.stories.tsx +++ /dev/null @@ -1,131 +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 { NewRelicDashboard } from './NewRelicDashboard'; -import { MockStorageApi, TestApiProvider } from '@backstage/test-utils'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { newRelicDashboardApiRef } from '../../api'; -import { NEWRELIC_GUID_ANNOTATION } from '../../constants'; -import { storageApiRef } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; - -function createImage( - width: number, - height: number, - bgColor: string, - text: string, -): HTMLCanvasElement { - const canvas = document.createElement('canvas'); - canvas.width = width; - canvas.height = height; - const ctx = canvas.getContext('2d'); - if (ctx !== null) { - ctx.fillStyle = bgColor; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = '#000'; // text color - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.font = '20px sans-serif'; - ctx.fillText(text, canvas.width / 2, canvas.height / 2); - } - return canvas; -} - -const entity: Entity = { - apiVersion: '1', - kind: 'Component', - metadata: { - name: 'mocked entity with newrelic service', - title: 'app with newrelic', - annotations: { - [NEWRELIC_GUID_ANNOTATION]: 'some-cool-guid', - }, - }, -}; - -const newRelicApiMockEmpty = { - getDashboardEntity: () => Promise.resolve(undefined), -}; - -export const EmptyNewRelicDashboard = () => ( - - - - - -); - -const resultEntities = [ - { - dashboardParentGuid: 'parent guid', - guid: 'guid', - permalink: 'http://example.com', - name: 'Production metrics', - }, -]; - -const dashboardEntity = { - data: { - actor: { - entitySearch: { - results: { - entities: resultEntities, - }, - }, - }, - }, -}; - -const entitySummary = { - getDashboardEntity: dashboardEntity, -}; - -const dashboardSnapshot = { - getDashboardSnapshot: { - data: { - dashboardCreateSnapshotUrl: createImage( - 1000, - 600, - '#ddd', - 'Example snapshot, imagine NewRelic panels here', - ).toDataURL(), - }, - }, -}; - -const newRelicApiMockFull = { - getDashboardEntity: () => Promise.resolve(entitySummary), - getDashboardSnapshot: () => Promise.resolve(dashboardSnapshot), -}; - -export const NewRelicDashboardWithSnapshots = () => ( - - - - - -); - -export default { - title: 'NewRelic Dashboard', - component: EmptyNewRelicDashboard, -}; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/NewRelicDashboard.tsx b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/NewRelicDashboard.tsx deleted file mode 100644 index c9cc9bf611..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/NewRelicDashboard.tsx +++ /dev/null @@ -1,44 +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 { Grid } from '@material-ui/core'; -import { Page, Content } from '@backstage/core-components'; -import { DashboardEntityList } from './DashboardEntityList'; -import { DashboardSnapshotList } from './DashboardSnapshotList'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { NEWRELIC_GUID_ANNOTATION } from '../../constants'; - -export const NewRelicDashboard = () => { - const { entity } = useEntity(); - return ( - - - - - - - - - - - - - ); -}; diff --git a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/index.ts b/plugins/newrelic-dashboard/src/components/NewRelicDashboard/index.ts deleted file mode 100644 index 668d76a059..0000000000 --- a/plugins/newrelic-dashboard/src/components/NewRelicDashboard/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { NewRelicDashboard } from './NewRelicDashboard'; diff --git a/plugins/newrelic-dashboard/src/constants.ts b/plugins/newrelic-dashboard/src/constants.ts deleted file mode 100644 index dd0dcff2d8..0000000000 --- a/plugins/newrelic-dashboard/src/constants.ts +++ /dev/null @@ -1,16 +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. - */ -export const NEWRELIC_GUID_ANNOTATION = 'newrelic.com/dashboard-guid'; diff --git a/plugins/newrelic-dashboard/src/index.ts b/plugins/newrelic-dashboard/src/index.ts deleted file mode 100644 index bbdfb70190..0000000000 --- a/plugins/newrelic-dashboard/src/index.ts +++ /dev/null @@ -1,25 +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. - */ - -export { - newRelicDashboardPlugin, - EntityNewRelicDashboardCard, - EntityNewRelicDashboardContent, - DashboardSnapshot, - DashboardSnapshotList, - DashboardSnapshotComponent, -} from './plugin'; -export { isNewRelicDashboardAvailable } from './Router'; diff --git a/plugins/newrelic-dashboard/src/plugin.test.ts b/plugins/newrelic-dashboard/src/plugin.test.ts deleted file mode 100644 index e5eccd930b..0000000000 --- a/plugins/newrelic-dashboard/src/plugin.test.ts +++ /dev/null @@ -1,22 +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 { newRelicDashboardPlugin } from './plugin'; - -describe('new-relic-dashboard', () => { - it('should export plugin', () => { - expect(newRelicDashboardPlugin).toBeDefined(); - }); -}); diff --git a/plugins/newrelic-dashboard/src/plugin.ts b/plugins/newrelic-dashboard/src/plugin.ts deleted file mode 100644 index 360f1cb911..0000000000 --- a/plugins/newrelic-dashboard/src/plugin.ts +++ /dev/null @@ -1,123 +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 { - createPlugin, - configApiRef, - createApiFactory, - discoveryApiRef, - createComponentExtension, - fetchApiRef, -} from '@backstage/core-plugin-api'; -import { newRelicDashboardApiRef, NewRelicDashboardClient } from './api'; -import { rootRouteRef } from './routes'; - -/** @public */ -export const newRelicDashboardPlugin = createPlugin({ - id: 'new-relic-dashboard', - routes: { - root: rootRouteRef, - }, - apis: [ - createApiFactory({ - api: newRelicDashboardApiRef, - deps: { - configApi: configApiRef, - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ configApi, discoveryApi, fetchApi }) => - new NewRelicDashboardClient({ - discoveryApi, - fetchApi, - baseUrl: configApi.getOptionalString('newrelicdashboard.baseUrl'), - }), - }), - ], -}); - -/** @public */ -export const EntityNewRelicDashboardContent = newRelicDashboardPlugin.provide( - createComponentExtension({ - name: 'EntityNewRelicDashboardContent', - component: { - lazy: () => import('./Router').then(m => m.Router), - }, - }), -); - -/** @public */ -export const EntityNewRelicDashboardCard = newRelicDashboardPlugin.provide( - createComponentExtension({ - name: 'EntityNewRelicDashboardCard', - component: { - lazy: () => - import('./components/NewRelicDashboard/DashboardEntityList').then( - m => m.DashboardEntityList, - ), - }, - }), -); - -/** - * Render dashboard snapshots from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true` - * - * @remarks - * This can be helpful for rendering dashboards outside of Entity Catalog. - * - * @public - */ -export const DashboardSnapshot = newRelicDashboardPlugin.provide( - createComponentExtension({ - name: 'DashboardSnapshot', - component: { - lazy: () => - import( - './components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshot' - ).then(m => m.DashboardSnapshot), - }, - }), -); - -/** - * Render dashboard snapshots from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true` - * - * @deprecated - * Use DashboardSnapshot export name instead - * - * @public - */ -export const DashboardSnapshotComponent = DashboardSnapshot; - -/** - * Render a dashboard snapshots list from Newrelic in backstage. Use dashboards which have the tag `isDashboardPage: true` - * - * @remarks - * This can be helpful for rendering dashboards outside of Entity Catalog. - * - * @public - */ -export const DashboardSnapshotList = newRelicDashboardPlugin.provide( - createComponentExtension({ - name: 'DashboardSnapshotList', - component: { - lazy: () => - import( - './components/NewRelicDashboard/DashboardSnapshotList/DashboardSnapshotList' - ).then(m => m.DashboardSnapshotList), - }, - }), -); diff --git a/plugins/newrelic-dashboard/src/queries/getDashboardParentGuidQuery.ts b/plugins/newrelic-dashboard/src/queries/getDashboardParentGuidQuery.ts deleted file mode 100644 index bc7c0b072b..0000000000 --- a/plugins/newrelic-dashboard/src/queries/getDashboardParentGuidQuery.ts +++ /dev/null @@ -1,17 +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. - */ -export const getDashboardParentGuidQuery = - 'query ($query: String) {\n actor {\n entitySearch(query: $query) {\n results {\n entities {\n name\n ... on DashboardEntityOutline {\n name\n dashboardParentGuid\n guid\n }\n permalink\n }\n }\n }\n }\n}\n'; diff --git a/plugins/newrelic-dashboard/src/queries/getDashboardSnapshotQuery.ts b/plugins/newrelic-dashboard/src/queries/getDashboardSnapshotQuery.ts deleted file mode 100644 index be683ecd7b..0000000000 --- a/plugins/newrelic-dashboard/src/queries/getDashboardSnapshotQuery.ts +++ /dev/null @@ -1,17 +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. - */ -export const getDashboardSnapshotQuery = - 'mutation($guid: EntityGuid! , ,$duration: Milliseconds) {\n dashboardCreateSnapshotUrl(guid: $guid , params: {timeWindow: {duration: $duration}})\n}'; diff --git a/plugins/newrelic-dashboard/src/routes.ts b/plugins/newrelic-dashboard/src/routes.ts deleted file mode 100644 index 5bc8b24457..0000000000 --- a/plugins/newrelic-dashboard/src/routes.ts +++ /dev/null @@ -1,20 +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 { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'new-relic-dashboard', -}); diff --git a/plugins/newrelic-dashboard/src/setupTests.ts b/plugins/newrelic-dashboard/src/setupTests.ts deleted file mode 100644 index 7435872609..0000000000 --- a/plugins/newrelic-dashboard/src/setupTests.ts +++ /dev/null @@ -1,16 +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 '@testing-library/jest-dom'; diff --git a/plugins/newrelic-dashboard/src/types/DashboardEntity.ts b/plugins/newrelic-dashboard/src/types/DashboardEntity.ts deleted file mode 100644 index 0c4fbb7a90..0000000000 --- a/plugins/newrelic-dashboard/src/types/DashboardEntity.ts +++ /dev/null @@ -1,34 +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. - */ - -export type DashboardEntity = { - data: { - actor: { - entitySearch: { - results: { - entities: Array; - }; - }; - }; - }; -}; - -export type ResultEntity = { - dashboardParentGuid: string; - guid: string; - permalink: string; - name: string; -}; diff --git a/plugins/newrelic-dashboard/src/types/DashboardSnapshot.ts b/plugins/newrelic-dashboard/src/types/DashboardSnapshot.ts deleted file mode 100644 index 6c11c6f6d7..0000000000 --- a/plugins/newrelic-dashboard/src/types/DashboardSnapshot.ts +++ /dev/null @@ -1,21 +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. - */ - -export type DashboardSnapshot = { - data: { - dashboardCreateSnapshotUrl: string; - }; -}; diff --git a/plugins/newrelic-dashboard/src/types/SnapshotDetails.ts b/plugins/newrelic-dashboard/src/types/SnapshotDetails.ts deleted file mode 100644 index e189ac52c4..0000000000 --- a/plugins/newrelic-dashboard/src/types/SnapshotDetails.ts +++ /dev/null @@ -1,20 +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. - */ - -export type SnapshotDetails = { - dashboardSnapshotUrl: string; - permalink: string; -}; diff --git a/plugins/newrelic/.eslintrc.js b/plugins/newrelic/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/newrelic/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md deleted file mode 100644 index 7b7ed068b6..0000000000 --- a/plugins/newrelic/CHANGELOG.md +++ /dev/null @@ -1,1170 +0,0 @@ -# @backstage/plugin-newrelic - -## 0.3.45-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.3.45-next.1 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.3.45-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - -## 0.3.44 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - -## 0.3.44-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - -## 0.3.44-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/core-plugin-api@1.8.1 - -## 0.3.43 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - -## 0.3.43-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - -## 0.3.43-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.3.43-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.0 - -## 0.3.43-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - -## 0.3.42 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - -## 0.3.42-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - -## 0.3.42-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.3.42-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.3.41 - -### Patch Changes - -- ce50a15506: Fixed sorting and searching in the NewRelic table. -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/theme@0.4.3 - -## 0.3.41-next.2 - -### Patch Changes - -- ce50a15506: Fixed sorting and searching in the NewRelic table. -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/theme@0.4.3-next.0 - -## 0.3.41-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/theme@0.4.2 - -## 0.3.41-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/theme@0.4.2 - -## 0.3.40 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 55cb7061e072: Fixed bug in NewRelicComponent component where table would not sort correctly for numerical values. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.3.40-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 55cb7061e072: Fixed bug in NewRelicComponent component where table would not sort correctly for numerical values. -- Updated dependencies - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.3.40-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/theme@0.4.1 - -## 0.3.40-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.3.40-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/theme@0.4.1 - -## 0.3.39 - -### Patch Changes - -- 2167b7eab09b: The newrelic plugin now supports pagination when retrieving results from newrelic. It will no longer truncate results. To see all applications, the link header will need to be allowed through the proxy (see the newrelic plugin readme). -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - -## 0.3.39-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - -## 0.3.38 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - -## 0.3.38-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - -## 0.3.38-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - -## 0.3.38-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - -## 0.3.37 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - -## 0.3.37-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - -## 0.3.37-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.3.37-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.3.37-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.36 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/core-components@0.13.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.36-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.36-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.35 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.35-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.3.35-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.3.35-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/theme@0.2.19-next.0 - -## 0.3.35-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - -## 0.3.34 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 66fdf05a1ef: Updated installation instructions -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - -## 0.3.34-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.3.34-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 66fdf05a1ef: Updated installation instructions -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - -## 0.3.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - -## 0.3.33 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - -## 0.3.33-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.3.33-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.3.32 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.3.32-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - -## 0.3.32-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - -## 0.3.32-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - -## 0.3.31 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - -## 0.3.30 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/theme@0.2.16 - -## 0.3.30-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.3.30-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.3.30-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/theme@0.2.16 - -## 0.3.30-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/theme@0.2.16 - -## 0.3.30-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/theme@0.2.16 - -## 0.3.29 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/theme@0.2.16 - -## 0.3.29-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - -## 0.3.29-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - -## 0.3.28 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - -## 0.3.28-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - -## 0.3.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/theme@0.2.16 - -## 0.3.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - -## 0.3.27 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - -## 0.3.27-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.3.27-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.3.27-next.1 - -### Patch Changes - -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - -## 0.3.27-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - -## 0.3.26 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.0 - - @backstage/core-plugin-api@1.0.5 - -## 0.3.26-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.0-next.2 - -## 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 - -## 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 - -## 0.3.25-next.3 - -### Patch Changes - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - -## 0.3.25-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/theme@0.2.16-next.1 - -## 0.3.25-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/theme@0.2.16-next.0 - -## 0.3.25-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.0 - -## 0.3.24 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - -## 0.3.24-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - -## 0.3.24-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.0 - -## 0.3.23 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - -## 0.3.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - -## 0.3.22 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.3.22-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - -## 0.3.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.3-next.0 - -## 0.3.21 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - -## 0.3.20 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.1 - -## 0.3.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.1-next.0 - -## 0.3.19 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.3.18 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/core-plugin-api@0.7.0 - -## 0.3.17 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/theme@0.2.15 - -## 0.3.16 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - -## 0.3.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - -## 0.3.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - -## 0.3.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - -## 0.3.14 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - -## 0.3.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - -## 0.3.13 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - -## 0.3.12 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/core-components@0.8.3 - -## 0.3.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/core-components@0.8.2 - -## 0.3.10 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - -## 0.3.9 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.3.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.3.7 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - -## 0.3.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - -## 0.3.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - -## 0.3.4 - -### Patch Changes - -- 52a5a46372: Added pagination and searching to the table -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/core-plugin-api@0.1.8 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.4.0 - -## 0.3.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - -## 0.3.1 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.3.0 - -### Minor Changes - -- d719926d2: **BREAKING CHANGE** Remove deprecated route registrations, meaning that it is no longer enough to only import the plugin in the app and the exported page extension must be used instead. - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - -## 0.2.7 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [889d89b6e] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies [40c0fdbaa] -- Updated dependencies [2a271d89e] -- Updated dependencies [bece09057] -- Updated dependencies [169f48deb] -- Updated dependencies [8a1566719] -- Updated dependencies [4c049a1a1] - - @backstage/core@0.7.0 - -## 0.2.5 - -### Patch Changes - -- c5ab91ce3: Migrate to new composability API, exporting the plugin instance as `newRelicPlugin`, and the root page as `NewRelicPage`. -- Updated dependencies [b51ee6ece] - - @backstage/core@0.6.1 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies [12ece98cd] -- Updated dependencies [d82246867] -- Updated dependencies [c810082ae] -- Updated dependencies [5fa3bdb55] -- Updated dependencies [21e624ba9] -- Updated dependencies [da9f53c60] -- Updated dependencies [32c95605f] -- Updated dependencies [54c7d02f7] - - @backstage/core@0.6.0 - - @backstage/theme@0.2.3 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies [efd6ef753] -- Updated dependencies [a187b8ad0] - - @backstage/core@0.5.0 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies [2527628e1] -- Updated dependencies [1c69d4716] -- Updated dependencies [1665ae8bb] -- Updated dependencies [04f26f88d] -- Updated dependencies [ff243ce96] - - @backstage/core@0.4.0 - - @backstage/theme@0.2.2 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [7b37d65fd] -- Updated dependencies [4aca74e08] -- Updated dependencies [e8f69ba93] -- Updated dependencies [0c0798f08] -- Updated dependencies [0c0798f08] -- Updated dependencies [199237d2f] -- Updated dependencies [6627b626f] -- Updated dependencies [4577e377b] - - @backstage/core@0.3.0 - - @backstage/theme@0.2.1 - -## 0.2.0 - -### Minor Changes - -- 28edd7d29: Create backend plugin through CLI -- 4512b9967: The New Relic plugin now uses the Backstage proxy to communicate with New Relic's API. - - Please update your `app-config.yaml` as follows: - - ```yaml - # Old Config - newrelic: - api: - baseUrl: 'https://api.newrelic.com/v2' - key: NEW_RELIC_REST_API_KEY - ``` - - ```yaml - # New Config - proxy: - '/newrelic/apm/api': - target: https://api.newrelic.com/v2 - headers: - X-Api-Key: - $env: NEW_RELIC_REST_API_KEY - ``` - -### Patch Changes - -- Updated dependencies [819a70229] -- Updated dependencies [ae5983387] -- Updated dependencies [0d4459c08] -- Updated dependencies [482b6313d] -- Updated dependencies [1c60f716e] -- Updated dependencies [144c66d50] -- Updated dependencies [b79017fd3] -- Updated dependencies [6d97d2d6f] -- Updated dependencies [93a3fa3ae] -- Updated dependencies [782f3b354] -- Updated dependencies [2713f28f4] -- Updated dependencies [406015b0d] -- Updated dependencies [82759d3e4] -- Updated dependencies [ac8d5d5c7] -- Updated dependencies [ebca83d48] -- Updated dependencies [aca79334f] -- Updated dependencies [c0d5242a0] -- Updated dependencies [3beb5c9fc] -- Updated dependencies [754e31db5] -- Updated dependencies [1611c6dbc] - - @backstage/core@0.2.0 - - @backstage/theme@0.2.0 diff --git a/plugins/newrelic/README.md b/plugins/newrelic/README.md deleted file mode 100644 index 14e2c0005d..0000000000 --- a/plugins/newrelic/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# New Relic Plugin (Alpha) - -Website: [https://newrelic.com](https://newrelic.com) - -New Relic Plugin APM -New Relic Plugin Tools - -## Getting Started - -This plugin uses the Backstage proxy to securely communicate with New Relic's -APIs. - -1. Add the following to your `app-config.yaml` to enable this configuration: - - ```yaml - proxy: - '/newrelic/apm/api': - target: https://api.newrelic.com/v2 - headers: - X-Api-Key: ${NEW_RELIC_REST_API_KEY} - allowedHeaders: - - link - ``` - - There is some types of api key on new relic, to this use must be `User` type of key, In your production deployment of Backstage, you would also need to ensure that - you've set the `NEW_RELIC_REST_API_KEY` environment variable before starting - the backend. - - While working locally, you may wish to hard-code your API key in your - `app-config.local.yaml` like this: - - ```yaml - # app-config.local.yaml - proxy: - '/newrelic/apm/api': - headers: - X-Api-Key: NRRA-YourActualApiKey - allowedHeaders: - - link - ``` - - Read more about how to find or generate this key in - [New Relic's Documentation](https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#rest-api-key). - - See if it's working by visiting the New Relic Plugin Path: - [/newrelic](http://localhost:3000/newrelic) - -2. Add a dependency to your `packages/app/package.json`: - ```sh - # From your Backstage root directory - yarn --cwd packages/app add @backstage/plugin-newrelic - ``` -3. Add the `NewRelicPage` to your `packages/app/src/App.tsx`: - - ```tsx - - … - } /> - - ``` - -4. Add link to New Relic to your sidebar - - ```typescript - // packages/app/src/components/Root/Root.tsx - import ExtensionIcon from '@material-ui/icons/ExtensionOutlined'; - - ... - - export const Root = ({ children }: PropsWithChildren<{}>) => ( - - - ... - - ... - - - ); - - ``` - -5. Navigate to your.domain.com/newrelic. - - At this step you must be able to see a page like that - New Relic Plugin APM - -## Features - -- View New Relic Application Performance Monitoring (APM) data such as: - - Application Name - - Response Time (ms) - - Throughput (rpm) - - Error Rate - - Instance Count - - Apdex Score - -## Limitations - -- Currently only supports New Relic APM data - ---- - -You can also serve the plugin in isolation by running `yarn start` in the plugin directory. -This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. -It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/plugins/newrelic/api-report.md b/plugins/newrelic/api-report.md deleted file mode 100644 index a77b80c862..0000000000 --- a/plugins/newrelic/api-report.md +++ /dev/null @@ -1,24 +0,0 @@ -## API Report File for "@backstage/plugin-newrelic" - -> 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 { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export const NewRelicPage: () => JSX_2.Element; - -// @public (undocumented) -const newRelicPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -export { newRelicPlugin }; -export { newRelicPlugin as plugin }; -``` diff --git a/plugins/newrelic/catalog-info.yaml b/plugins/newrelic/catalog-info.yaml deleted file mode 100644 index bdf6aa5757..0000000000 --- a/plugins/newrelic/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-newrelic - title: '@backstage/plugin-newrelic' - description: A Backstage plugin that integrates towards New Relic -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/newrelic/dev/index.tsx b/plugins/newrelic/dev/index.tsx deleted file mode 100644 index 7eac496f8b..0000000000 --- a/plugins/newrelic/dev/index.tsx +++ /dev/null @@ -1,27 +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 { createDevApp } from '@backstage/dev-utils'; -import { newRelicPlugin, NewRelicPage } from '../src/plugin'; - -createDevApp() - .registerPlugin(newRelicPlugin) - .addPage({ - title: 'New Relic', - element: , - }) - .render(); diff --git a/plugins/newrelic/knip-report.md b/plugins/newrelic/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/newrelic/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json deleted file mode 100644 index 42c43b52b1..0000000000 --- a/plugins/newrelic/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@backstage/plugin-newrelic", - "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.45-next.2", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/newrelic" - }, - "keywords": [ - "backstage", - "newrelic" - ], - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "parse-link-header": "^2.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@types/parse-link-header": "^2.0.1", - "msw": "^1.2.3" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/newrelic/src/api/index.test.ts b/plugins/newrelic/src/api/index.test.ts deleted file mode 100644 index d4ed4a1691..0000000000 --- a/plugins/newrelic/src/api/index.test.ts +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { NewRelicApplication, NewRelicClient } from '.'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; - -const mockedDiscoveryApi: DiscoveryApi = { - getBaseUrl: async () => 'https://test.test', -}; - -beforeEach(() => { - jest.resetAllMocks(); -}); - -describe('NewRelicClient', () => { - const server = setupServer(); - setupRequestMockHandlers(server); - - beforeEach(() => { - server.resetHandlers(); - }); - - test.each([ - ['https://test.test/BASEPATH/apm/api/applications.json', '/BASEPATH'], - ['https://test.test/BASEPATH2/apm/api/applications.json', '/BASEPATH2'], - ['https://test.testBASEPATH3/apm/api/applications.json', 'BASEPATH3'], - ['https://test.test/newrelic/apm/api/applications.json', undefined], - ])( - 'It correctly forms the request url (%p) when proxyPathBase is %p', - async (expectedUrl, basePathOverride) => { - server.use( - rest.get(expectedUrl, (_, res, ctx) => - res(ctx.status(200), ctx.json({ applications: [] })), - ), - ); - - const mockedFetchApi = new MockFetchApi(); - const fetchSpy = jest.spyOn(mockedFetchApi, 'fetch'); - - const client = new NewRelicClient({ - discoveryApi: mockedDiscoveryApi, - fetchApi: mockedFetchApi, - proxyPathBase: basePathOverride, - }); - await client.getApplications(); - - expect(fetchSpy).toHaveBeenCalledWith(expectedUrl); - }, - ); - - it('Correctly reads all pages of results and returns the expected results', async () => { - const mockedApplicationOne: NewRelicApplication = { - id: 1, - application_summary: { - apdex_score: 0, - error_rate: 100, - host_count: 500, - instance_count: 5000, - response_time: 20, - throughput: 500000, - }, - name: 'Testing Application #1', - language: 'en-us', - health_status: 'Failing', - reporting: true, - settings: { - app_apdex_threshold: 0, - end_user_apdex_threshold: 0, - enable_real_user_monitoring: true, - use_server_side_config: true, - }, - }; - - const mockedApplicationTwo: NewRelicApplication = { - id: 2, - application_summary: { - apdex_score: -900, - error_rate: 0, - host_count: 0, - instance_count: 0, - response_time: 0, - throughput: 0, - }, - name: 'Testing Application #2', - language: 'en-us', - health_status: 'Working', - reporting: true, - settings: { - app_apdex_threshold: 0, - end_user_apdex_threshold: 0, - enable_real_user_monitoring: true, - use_server_side_config: true, - }, - }; - - const mockedApplicationThree: NewRelicApplication = { - id: 3, - application_summary: { - apdex_score: -900, - error_rate: 0, - host_count: 0, - instance_count: 0, - response_time: 0, - throughput: 0, - }, - name: 'Testing Application #3', - language: 'en-us', - health_status: 'Waiting', - reporting: false, - settings: { - app_apdex_threshold: 1000, - end_user_apdex_threshold: 500, - enable_real_user_monitoring: false, - use_server_side_config: false, - }, - }; - - const queryToRequestData = new Map< - string | null, - { link?: string | string[]; apps: NewRelicApplication[] } - >([ - [ - null, - { - link: [ - '; rel="next"', - '; rel="bad"', - ], - apps: [mockedApplicationOne], - }, - ], - [ - '2', - { - link: '; rel="next",', - apps: [], - }, - ], - [ - '3', - { - apps: [mockedApplicationTwo, mockedApplicationThree], - }, - ], - ]); - - const mockedFetchApi = new MockFetchApi(); - const fetchSpy = jest.spyOn(mockedFetchApi, 'fetch'); - - server.use( - rest.get( - 'https://test.test/newrelic/apm/api/applications.json', - (req, res, ctx) => { - const nextPageNumber = req.url.searchParams.get('page'); - const requestData = queryToRequestData.get(nextPageNumber) ?? { - apps: [], - }; - - const { link, apps: applications } = requestData; - const statusTransform = ctx.status(200); - const responseBody = ctx.json({ applications }); - - if (!!link) { - return res(statusTransform, ctx.set({ link }), responseBody); - } - - return res(statusTransform, responseBody); - }, - ), - ); - - const client = new NewRelicClient({ - discoveryApi: mockedDiscoveryApi, - fetchApi: mockedFetchApi, - }); - - const actual = await client.getApplications(); - const expected = { - applications: [ - mockedApplicationOne, - mockedApplicationTwo, - mockedApplicationThree, - ], - }; - - expect(fetchSpy).toHaveBeenCalledTimes(3); - expect(fetchSpy).toHaveBeenCalledWith( - 'https://test.test/newrelic/apm/api/applications.json', - ); - expect(fetchSpy).toHaveBeenCalledWith( - 'https://test.test/newrelic/apm/api/applications.json?page=2', - ); - expect(fetchSpy).toHaveBeenCalledWith( - 'https://test.test/newrelic/apm/api/applications.json?page=3', - ); - expect(actual).toStrictEqual(expected); - }); - - test.each([['Link'], ['LINK'], ['lINK']])( - 'It does not attempt pagination when the link header name is invalid (%p)', - async linkHeaderName => { - const mockedFetchApi = new MockFetchApi(); - const fetchSpy = jest.spyOn(mockedFetchApi, 'fetch'); - - server.use( - rest.get( - 'https://test.test/newrelic/apm/api/applications.json', - (_, res, ctx) => - res( - ctx.status(200), - ctx.set( - linkHeaderName, - '; rel="next"', - ), - ctx.json({ applications: [] }), - ), - ), - rest.get('https://test.test/badroute', () => { - throw new Error( - 'NewRelicClient attempted to paginate when it should not have', - ); - }), - ); - - const client = new NewRelicClient({ - discoveryApi: mockedDiscoveryApi, - fetchApi: mockedFetchApi, - }); - await client.getApplications(); - - expect(fetchSpy).toHaveBeenCalledTimes(1); - expect(fetchSpy).toHaveBeenCalledWith( - 'https://test.test/newrelic/apm/api/applications.json', - ); - }, - ); - - test.each([ - [''], - ['<> rel=""'], - ['<>; rel=""'], - ['; rel=""'], - ['<>; rel:"value"'], - ['; rel: "next"'], - ['ABCDE'], - ['; rel="next",'], - ])( - 'It does not attempt pagination when the link header value is invalid (%p)', - async linkHeaderValue => { - const mockedFetchApi = new MockFetchApi(); - const fetchSpy = jest.spyOn(mockedFetchApi, 'fetch'); - - server.use( - rest.get( - 'https://test.test/newrelic/apm/api/applications.json', - (_, res, ctx) => - res( - ctx.status(200), - ctx.set('link', linkHeaderValue), - ctx.json({ applications: [] }), - ), - ), - rest.get('https://test.test/badroute', () => { - throw new Error( - 'NewRelicClient attempted to paginate when it should not have', - ); - }), - ); - - const client = new NewRelicClient({ - discoveryApi: mockedDiscoveryApi, - fetchApi: mockedFetchApi, - }); - await client.getApplications(); - - expect(fetchSpy).toHaveBeenCalledTimes(1); - expect(fetchSpy).toHaveBeenCalledWith( - 'https://test.test/newrelic/apm/api/applications.json', - ); - }, - ); - - test.each([ - ['Error communicating with New Relic: Not Found', 404, JSON.stringify({})], - [ - 'Error communicating with New Relic: ERROR TITLE', - 404, - JSON.stringify({ - error: { - title: 'ERROR TITLE', - }, - }), - ], - [ - 'Error communicating with New Relic: Internal Server Error', - 500, - JSON.stringify(undefined), - ], - [ - 'Error communicating with New Relic: Internal Server Error', - 500, - JSON.stringify(null), - ], - [ - 'Error communicating with New Relic: Internal Server Error', - 500, - ' { - server.use( - rest.get( - 'https://test.test/newrelic/apm/api/applications.json', - (_, res, ctx) => res(ctx.status(statusCode), ctx.body(body)), - ), - ); - - const client = new NewRelicClient({ - discoveryApi: mockedDiscoveryApi, - fetchApi: new MockFetchApi(), - }); - - await expect(client.getApplications()).rejects.toThrow( - expectedErrorMessage, - ); - }, - ); - - it('Throws an error when the body is invalid json but the status code is 200', async () => { - server.use( - rest.get( - 'https://test.test/newrelic/apm/api/applications.json', - (_, res, ctx) => res(ctx.status(200), ctx.body(' { - const getBaseUrlSpy = jest.spyOn(mockedDiscoveryApi, 'getBaseUrl'); - - server.use( - rest.get( - 'https://test.test/newrelic/apm/api/applications.json', - (_, res, ctx) => res(ctx.status(200), ctx.json({ applications: [] })), - ), - ); - - const client = new NewRelicClient({ - discoveryApi: mockedDiscoveryApi, - fetchApi: new MockFetchApi(), - }); - - await client.getApplications(); - await client.getApplications(); - await client.getApplications(); - await client.getApplications(); - - expect(getBaseUrlSpy).toHaveBeenCalledTimes(1); - }); -}); diff --git a/plugins/newrelic/src/api/index.ts b/plugins/newrelic/src/api/index.ts deleted file mode 100644 index b37575b163..0000000000 --- a/plugins/newrelic/src/api/index.ts +++ /dev/null @@ -1,149 +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 { - createApiRef, - DiscoveryApi, - FetchApi, -} from '@backstage/core-plugin-api'; - -import parseLinkHeader from 'parse-link-header'; - -export type NewRelicApplication = { - id: number; - application_summary: NewRelicApplicationSummary; - name: string; - language: string; - health_status: string; - reporting: boolean; - settings: NewRelicApplicationSettings; - links?: NewRelicApplicationLinks; -}; - -export type NewRelicApplicationSummary = { - apdex_score: number; - error_rate: number; - host_count: number; - instance_count: number; - response_time: number; - throughput: number; -}; - -export type NewRelicApplicationSettings = { - app_apdex_threshold: number; - end_user_apdex_threshold: number; - enable_real_user_monitoring: boolean; - use_server_side_config: boolean; -}; - -export type NewRelicApplicationLinks = { - application_instances: Array; - servers: Array; - application_hosts: Array; -}; - -export type NewRelicApplications = { - applications: NewRelicApplication[]; -}; - -export const newRelicApiRef = createApiRef({ - id: 'plugin.newrelic.service', -}); - -const DEFAULT_PROXY_PATH_BASE = '/newrelic'; - -type Options = { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - /** - * Path to use for requests via the proxy, defaults to /newrelic - */ - proxyPathBase?: string; -}; - -export interface NewRelicApi { - getApplications(): Promise; -} - -interface NewRelicPageReadResult { - nextPageUrl: string | undefined; - applicationsFromReadPage: NewRelicApplication[]; -} - -export class NewRelicClient implements NewRelicApi { - private readonly discoveryApi: DiscoveryApi; - private readonly fetchApi: FetchApi; - private readonly proxyPathBase: string; - private baseUrl: string; - - constructor(options: Options) { - this.discoveryApi = options.discoveryApi; - this.fetchApi = options.fetchApi; - this.proxyPathBase = options.proxyPathBase ?? DEFAULT_PROXY_PATH_BASE; - this.baseUrl = ''; - } - - async getApplications(): Promise { - if (!this.baseUrl) { - const proxyUrl = await this.discoveryApi.getBaseUrl('proxy'); - this.baseUrl = `${proxyUrl}${this.proxyPathBase}/apm/api/applications.json`; - } - - const applications: NewRelicApplication[] = []; - let targetUrl = this.baseUrl; - - do { - const { nextPageUrl, applicationsFromReadPage } = - await this.fetchNewRelic(targetUrl); - - targetUrl = nextPageUrl ?? ''; - applications.push(...applicationsFromReadPage); - } while (!!targetUrl); - - return { applications }; - } - - private async fetchNewRelic( - targetUrl: string, - ): Promise { - const response = await this.fetchApi.fetch(targetUrl); - - if (!response.ok) { - let specificErrorTitle = undefined; - try { - specificErrorTitle = (await response.json())?.error?.title; - } catch (e) { - /* empty */ - } - - throw new Error( - `Error communicating with New Relic: ${ - specificErrorTitle || response.statusText - }`, - ); - } - - const readResponse = (await response.json()) as NewRelicApplications; - const linkHeader = response.headers.get('link'); - const parseResult = parseLinkHeader(linkHeader); - const nextPageNumber = parseResult?.next?.page; - - return { - nextPageUrl: nextPageNumber && `${this.baseUrl}?page=${nextPageNumber}`, - applicationsFromReadPage: readResponse.applications, - }; - } -} diff --git a/plugins/newrelic/src/assets/img/newrelic-plugin-apm.png b/plugins/newrelic/src/assets/img/newrelic-plugin-apm.png deleted file mode 100644 index 88661830d0..0000000000 Binary files a/plugins/newrelic/src/assets/img/newrelic-plugin-apm.png and /dev/null differ diff --git a/plugins/newrelic/src/assets/img/newrelic-plugin-tools.png b/plugins/newrelic/src/assets/img/newrelic-plugin-tools.png deleted file mode 100644 index dc35d05dca..0000000000 Binary files a/plugins/newrelic/src/assets/img/newrelic-plugin-tools.png and /dev/null differ diff --git a/plugins/newrelic/src/assets/img/newrelic.jpg b/plugins/newrelic/src/assets/img/newrelic.jpg deleted file mode 100644 index 914ad02280..0000000000 Binary files a/plugins/newrelic/src/assets/img/newrelic.jpg and /dev/null differ diff --git a/plugins/newrelic/src/components/NewRelicComponent/NewRelicComponent.tsx b/plugins/newrelic/src/components/NewRelicComponent/NewRelicComponent.tsx deleted file mode 100644 index e11649e520..0000000000 --- a/plugins/newrelic/src/components/NewRelicComponent/NewRelicComponent.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { Grid } from '@material-ui/core'; -import NewRelicFetchComponent from '../NewRelicFetchComponent'; -import { - Header, - Page, - Content, - ContentHeader, - HeaderLabel, - SupportButton, -} from '@backstage/core-components'; - -const NewRelicComponent = () => ( - -
- -
- - - - New Relic Application Performance Monitoring - - - - - - - - -
-); - -export default NewRelicComponent; diff --git a/plugins/newrelic/src/components/NewRelicComponent/index.ts b/plugins/newrelic/src/components/NewRelicComponent/index.ts deleted file mode 100644 index ef3e47b580..0000000000 --- a/plugins/newrelic/src/components/NewRelicComponent/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './NewRelicComponent'; diff --git a/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx b/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx deleted file mode 100644 index 85183916bd..0000000000 --- a/plugins/newrelic/src/components/NewRelicFetchComponent/NewRelicFetchComponent.tsx +++ /dev/null @@ -1,123 +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 Alert from '@material-ui/lab/Alert'; -import useAsync from 'react-use/lib/useAsync'; -import { newRelicApiRef, NewRelicApplications } from '../../api'; - -import { Progress, Table, TableColumn } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; - -const sortNumeric = - (field: F) => - (a: { [key in F]: number }, b: { [key in F]: number }) => { - return a[field] - b[field]; - }; - -type NewRelicTableData = { - name: string; - responseTime: number; - throughput: number; - errorRate: number; - instanceCount: number; - apdexScore: number; -}; - -export const NewRelicAPMTable = ({ applications }: NewRelicApplications) => { - const columns: TableColumn[] = [ - { title: 'Application', field: 'name', searchable: true }, - { - title: 'Response Time (ms)', - field: 'responseTime', - customSort: sortNumeric('responseTime'), - searchable: false, - }, - { - title: 'Throughput (rpm)', - field: 'throughput', - customSort: sortNumeric('throughput'), - searchable: false, - }, - { - title: 'Error Rate (%)', - field: 'errorRate', - customSort: sortNumeric('errorRate'), - searchable: false, - }, - { - title: 'Instance Count', - field: 'instanceCount', - customSort: sortNumeric('instanceCount'), - searchable: false, - }, - { - title: 'Apdex', - field: 'apdexScore', - customSort: sortNumeric('apdexScore'), - searchable: false, - }, - ]; - const data: Array = applications.map(app => { - const { name, application_summary: applicationSummary } = app; - const { - response_time: responseTime, - throughput, - error_rate: errorRate, - instance_count: instanceCount, - apdex_score: apdexScore, - } = applicationSummary; - - return { - name, - responseTime, - throughput, - errorRate, - instanceCount, - apdexScore, - }; - }); - - return ( - - ); -}; - -const NewRelicFetchComponent = () => { - const api = useApi(newRelicApiRef); - - const { value, loading, error } = useAsync(async () => { - const data = await api.getApplications(); - return data.applications.filter(application => { - return application.hasOwnProperty('application_summary'); - }); - }, []); - - if (loading) { - return ; - } else if (error) { - return {error.message}; - } - - return ; -}; - -export default NewRelicFetchComponent; diff --git a/plugins/newrelic/src/components/NewRelicFetchComponent/index.ts b/plugins/newrelic/src/components/NewRelicFetchComponent/index.ts deleted file mode 100644 index 3138f1cb8f..0000000000 --- a/plugins/newrelic/src/components/NewRelicFetchComponent/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './NewRelicFetchComponent'; diff --git a/plugins/newrelic/src/index.ts b/plugins/newrelic/src/index.ts deleted file mode 100644 index 20183d22a0..0000000000 --- a/plugins/newrelic/src/index.ts +++ /dev/null @@ -1,27 +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. - */ - -/** - * A Backstage plugin that integrates towards New Relic - * - * @packageDocumentation - */ - -export { - newRelicPlugin, - newRelicPlugin as plugin, - NewRelicPage, -} from './plugin'; diff --git a/plugins/newrelic/src/plugin.test.ts b/plugins/newrelic/src/plugin.test.ts deleted file mode 100644 index 6f1b9c808a..0000000000 --- a/plugins/newrelic/src/plugin.test.ts +++ /dev/null @@ -1,23 +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 { newRelicPlugin } from './plugin'; - -describe('newrelic', () => { - it('should export plugin', () => { - expect(newRelicPlugin).toBeDefined(); - }); -}); diff --git a/plugins/newrelic/src/plugin.ts b/plugins/newrelic/src/plugin.ts deleted file mode 100644 index da7cae9b93..0000000000 --- a/plugins/newrelic/src/plugin.ts +++ /dev/null @@ -1,58 +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 { NewRelicClient, newRelicApiRef } from './api'; -import { - createApiFactory, - createPlugin, - createRouteRef, - discoveryApiRef, - fetchApiRef, - createRoutableExtension, -} from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'newrelic', -}); - -/** @public */ -export const newRelicPlugin = createPlugin({ - id: 'newrelic', - apis: [ - createApiFactory({ - api: newRelicApiRef, - deps: { - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ discoveryApi, fetchApi }) => - new NewRelicClient({ discoveryApi, fetchApi }), - }), - ], - routes: { - root: rootRouteRef, - }, -}); - -/** @public */ -export const NewRelicPage = newRelicPlugin.provide( - createRoutableExtension({ - name: 'NewRelicPage', - component: () => - import('./components/NewRelicComponent').then(m => m.default), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/newrelic/src/setupTests.ts b/plugins/newrelic/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/newrelic/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/nomad-backend/.eslintrc.js b/plugins/nomad-backend/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/nomad-backend/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/nomad-backend/CHANGELOG.md b/plugins/nomad-backend/CHANGELOG.md deleted file mode 100644 index 75d731eb87..0000000000 --- a/plugins/nomad-backend/CHANGELOG.md +++ /dev/null @@ -1,322 +0,0 @@ -# @backstage/plugin-nomad-backend - -## 0.1.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.12-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.1 - - @backstage/backend-common@0.21.0-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/backend-plugin-api@0.6.10-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.11 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/backend-plugin-api@0.6.9 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - - @backstage/backend-common@0.20.1-next.2 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/backend-plugin-api@0.6.9-next.1 - - @backstage/errors@1.2.3 - -## 0.1.11-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/backend-plugin-api@0.6.9-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/backend-plugin-api@0.6.8 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-plugin-api@0.6.8-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/backend-plugin-api@0.6.8-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-plugin-api@0.6.8-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-plugin-api@0.6.8-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/backend-plugin-api@0.6.7 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - - @backstage/backend-common@0.19.9-next.2 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-plugin-api@0.6.7-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.1.8 - -### Patch Changes - -- 6822918c50: Added support for the [new backend system](https://backstage.io/docs/backend-system/) -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/errors@1.2.3 - - @backstage/backend-plugin-api@0.6.6 - - @backstage/config@1.1.1 - -## 0.1.8-next.2 - -### Patch Changes - -- 6822918c50: Added support for the [new backend system](https://backstage.io/docs/backend-system/) -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/backend-plugin-api@0.6.6-next.2 - - @backstage/config@1.1.1-next.0 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.1.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/backend-common@0.19.5-next.3 - -## 0.1.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/errors@1.2.1 - -## 0.1.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/errors@1.2.1 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.1.2 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.1.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.2 - -## 0.1.2-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/config@1.0.8 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/config@1.0.8 - -## 0.1.0 - -### Minor Changes - -- 05bf04ca6863: Initialize Nomad plugin with frontend and backend. List jobs/allocations - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/errors@1.2.0 - - @backstage/config@1.0.8 diff --git a/plugins/nomad-backend/README.md b/plugins/nomad-backend/README.md deleted file mode 100644 index 9f530bd943..0000000000 --- a/plugins/nomad-backend/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @backstage/plugin-nomad-backend - -A backend for [Nomad](https://www.nomadproject.io/), this plugin exposes a service with routes that are used by the `@backstage/plugin-nomad-backend` plugin to query Job and Group information from a Nomad API. - -## New Backend System - -The Nomad backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: - -In your `packages/backend/src/index.ts` make the following changes: - -```diff - import { createBackend } from '@backstage/backend-defaults'; - const backend = createBackend(); - // ... other feature additions - backend.add(import('@backstage/plugin-nomad-backend')); - backend.start(); -``` - -## Set Up - -1. Install the plugin using: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-nomad-backend -``` - -2. Create a `nomad.ts` file inside `packages/backend/src/plugins/`: - -```typescript -import { createRouter } from '@backstage/plugin-nomad-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - props: PluginEnvironment, -): Promise { - return await createRouter(props); -} -``` - -3. Modify your `packages/backend/src/index.ts` to include: - -```diff - ... - - import { Config } from '@backstage/config'; - import app from './plugins/app'; -+import nomad from './plugins/nomad'; - ... - - async function main() { - ... - - const authEnv = useHotMemoize(module, () => createEnv('auth')); -+ const nomadEnv = useHotMemoize(module, () => createEnv('nomad')); - ... - - const apiRouter = Router(); - apiRouter.use('/catalog', await catalog(catalogEnv)); -+ apiRouter.use('/nomad', await nomad(nomadEnv)); -``` - -Note: for this backend to work, the `nomad` configuration described in the README of `@backstage/plugin-nomad` must be implemented. diff --git a/plugins/nomad-backend/api-report.md b/plugins/nomad-backend/api-report.md deleted file mode 100644 index 82bb823d2d..0000000000 --- a/plugins/nomad-backend/api-report.md +++ /dev/null @@ -1,27 +0,0 @@ -## API Report File for "@backstage/plugin-nomad-backend" - -> 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 { Config } from '@backstage/config'; -import express from 'express'; -import { Logger } from 'winston'; - -// @public (undocumented) -export function createRouter(options: RouterOptions): Promise; - -// @public -const nomadPlugin: () => BackendFeature; -export default nomadPlugin; - -// @public (undocumented) -export interface RouterOptions { - // (undocumented) - config: Config; - // (undocumented) - logger: Logger; -} - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/nomad-backend/catalog-info.yaml b/plugins/nomad-backend/catalog-info.yaml deleted file mode 100644 index 7364d1920e..0000000000 --- a/plugins/nomad-backend/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-nomad-backend - title: '@backstage/plugin-nomad-backend' -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: maintainers diff --git a/plugins/nomad-backend/knip-report.md b/plugins/nomad-backend/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/nomad-backend/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/nomad-backend/package.json b/plugins/nomad-backend/package.json deleted file mode 100644 index 50df75e738..0000000000 --- a/plugins/nomad-backend/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@backstage/plugin-nomad-backend", - "version": "0.1.12-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/nomad-backend" - }, - "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": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@types/express": "*", - "express": "^4.17.1", - "express-promise-router": "^4.1.0", - "node-fetch": "^2.6.7", - "winston": "^3.2.1", - "yn": "^4.0.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/supertest": "^2.0.8", - "supertest": "^6.2.4" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/nomad-backend/src/index.ts b/plugins/nomad-backend/src/index.ts deleted file mode 100644 index 21aa299d6d..0000000000 --- a/plugins/nomad-backend/src/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export * from './service/router'; -export { nomadPlugin as default } from './plugin'; diff --git a/plugins/nomad-backend/src/plugin.test.ts b/plugins/nomad-backend/src/plugin.test.ts deleted file mode 100644 index 6ed8d2b194..0000000000 --- a/plugins/nomad-backend/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { nomadPlugin } from './plugin'; - -describe('nomad', () => { - it('should export the nomad plugin', () => { - expect(nomadPlugin).toBeDefined(); - }); -}); diff --git a/plugins/nomad-backend/src/plugin.ts b/plugins/nomad-backend/src/plugin.ts deleted file mode 100644 index f3a43c4a91..0000000000 --- a/plugins/nomad-backend/src/plugin.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - createBackendPlugin, - coreServices, -} from '@backstage/backend-plugin-api'; -import { createRouter } from './service/router'; - -/** - * Nomad backend plugin - * - * @public - */ -export const nomadPlugin = createBackendPlugin({ - pluginId: 'nomad', - register(env) { - env.registerInit({ - deps: { - logger: coreServices.logger, - config: coreServices.rootConfig, - httpRouter: coreServices.httpRouter, - }, - async init({ logger, config, httpRouter }) { - const winstonLogger = loggerToWinstonLogger(logger); - httpRouter.use( - await createRouter({ - /** - * Logger for logging purposes - */ - logger: winstonLogger, - config, - }), - ); - }, - }); - }, -}); diff --git a/plugins/nomad-backend/src/run.ts b/plugins/nomad-backend/src/run.ts deleted file mode 100644 index 711bdcc46c..0000000000 --- a/plugins/nomad-backend/src/run.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { getRootLogger } from '@backstage/backend-common'; -import yn from 'yn'; -import { startStandaloneServer } from './service/standaloneServer'; -import { ConfigReader } from '@backstage/config'; - -const config = new ConfigReader({}); -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({ config, 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/nomad-backend/src/service/router.test.ts b/plugins/nomad-backend/src/service/router.test.ts deleted file mode 100644 index 11c3834ed6..0000000000 --- a/plugins/nomad-backend/src/service/router.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { getVoidLogger } from '@backstage/backend-common'; -import express from 'express'; -import request from 'supertest'; - -import { createRouter } from './router'; -import { ConfigReader } from '@backstage/config'; - -describe('createRouter', () => { - let app: express.Express; - - beforeAll(async () => { - const router = await createRouter({ - config: new ConfigReader({ - nomad: { - addr: 'http://localhost.com', - token: 'asdf', - }, - }), - logger: getVoidLogger(), - }); - app = express().use(router); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('GET /health', () => { - it('returns ok', async () => { - const response = await request(app).get('/health'); - - expect(response.status).toEqual(200); - expect(response.body).toEqual({ status: 'ok' }); - }); - }); -}); diff --git a/plugins/nomad-backend/src/service/router.ts b/plugins/nomad-backend/src/service/router.ts deleted file mode 100644 index d6b5aa1fc6..0000000000 --- a/plugins/nomad-backend/src/service/router.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import fetch from 'node-fetch'; -import { errorHandler, requestLoggingHandler } from '@backstage/backend-common'; -import { Config } from '@backstage/config'; -import { InputError } from '@backstage/errors'; -import express from 'express'; -import Router from 'express-promise-router'; -import { Logger } from 'winston'; - -/** @public */ -export interface RouterOptions { - logger: Logger; - config: Config; -} - -/** @public */ -export async function createRouter( - options: RouterOptions, -): Promise { - const { config, logger } = options; - - // Get Nomad addr and token from config - const addr = config.getString('nomad.addr'); - const token = config.getOptionalString('nomad.token'); - - const router = Router(); - router.use(express.json()); - - router.get('/health', (_, resp) => { - resp.json({ status: 'ok' }); - }); - - router.get('/v1/allocations', async (req, res) => { - // Check namespace argument - const namespace = (req.query.namespace as string) ?? ''; - if (!namespace || namespace === '') { - throw new InputError(`Missing "namespace" query parameter`); - } - - // Check filter argument - const filter = (req.query.filter as string) ?? ''; - logger.debug(`request headers: namespace=${namespace} filter=${filter}`); - - // Issue the request - const endpoint = `${addr}/v1/allocations?namespace=${encodeURIComponent( - namespace, - )}&filter=${encodeURIComponent(filter)}`; - const allocationsResp = await fetch(endpoint, { - method: 'GET', - headers: { - Accept: 'application/json', - 'X-Nomad-Token': token || '', - }, - }); - - // Check response - if (allocationsResp.status !== 200) { - const body = await allocationsResp.text(); - logger.error(`failed to call /v1/allocations endpoint: ${body}`); - res.status(allocationsResp.status).json({ message: body }); - return; - } - - // Deserialize and return - const allocationsBody = await allocationsResp.json(); - logger.debug(`/v1/allocations response: ${allocationsBody}`); - res.json(allocationsBody); - }); - - router.get('/v1/job/:job_id/versions', async (req, resp) => { - // Check namespace argument - const namespace = (req.query.namespace as string) ?? ''; - if (!namespace || namespace === '') { - throw new InputError(`Missing "namespace" query parameter`); - } - - // Get job ID - const jobID = (req.params.job_id as string) ?? ''; - - // Issue the request - const apiResp = await fetch( - `${addr}/v1/job/${jobID}/versions?namespace=${encodeURIComponent( - namespace, - )}`, - { - method: 'GET', - headers: { - Accept: 'application/json', - 'X-Nomad-Token': token || '', - }, - }, - ); - - // Check response - if (apiResp.status !== 200) { - const body = await apiResp.text(); - logger.error(`failed to call /v1/job/:job_id/versions endpoint: ${body}`); - resp.status(apiResp.status).json({ message: body }); - return; - } - - // Deserialize and return - const versionsBody = await apiResp.json(); - logger.debug(`/v1/job/:job_id/versions response: ${versionsBody}`); - resp.json(versionsBody); - }); - - router.use(requestLoggingHandler()); - router.use(errorHandler()); - return router; -} diff --git a/plugins/nomad-backend/src/service/standaloneServer.ts b/plugins/nomad-backend/src/service/standaloneServer.ts deleted file mode 100644 index 133577ffc2..0000000000 --- a/plugins/nomad-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createServiceBuilder } from '@backstage/backend-common'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; -import { Config } from '@backstage/config'; - -export interface ServerOptions { - config: Config; - enableCors: boolean; - logger: Logger; - port: number; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'nomad' }); - logger.debug('Starting application server...'); - const router = await createRouter({ - logger, - config: options.config, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/nomad', 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/nomad-backend/src/setupTests.ts b/plugins/nomad-backend/src/setupTests.ts deleted file mode 100644 index 4b9026cde5..0000000000 --- a/plugins/nomad-backend/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export {}; diff --git a/plugins/nomad/.eslintrc.js b/plugins/nomad/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/nomad/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/nomad/CHANGELOG.md b/plugins/nomad/CHANGELOG.md deleted file mode 100644 index bafa9bb7a2..0000000000 --- a/plugins/nomad/CHANGELOG.md +++ /dev/null @@ -1,418 +0,0 @@ -# @backstage/plugin-nomad - -## 0.1.11-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.1.11-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - -## 0.1.10 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - -## 0.1.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - -## 0.1.10-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - -## 0.1.9-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.1.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/theme@0.5.0-next.0 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - -## 0.1.7 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - -## 0.1.7-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.1.7-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - -## 0.1.6 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.4.3 - - @backstage/config@1.1.1 - -## 0.1.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/theme@0.4.3-next.0 - - @backstage/config@1.1.1-next.0 - -## 0.1.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/config@1.1.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/config@1.1.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.1.5 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/config@1.1.0 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.1.5-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/config@1.1.0-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.1.5-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/config@1.1.0-next.1 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/theme@0.4.1 - -## 0.1.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/config@1.1.0-next.0 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.1.4-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.1.2 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/theme@0.4.1 - -## 0.1.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.1.2-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.1-next.0 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/theme@0.4.1 - -## 0.1.1 - -### Patch Changes - -- 68531cc70e1f: Break some internal circular import chains -- e6f50426333b: update some peer dependencies to silence yarn install -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/config@1.0.8 - -## 0.1.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - - @backstage/config@1.0.8 - -## 0.1.1-next.0 - -### Patch Changes - -- 68531cc70e1f: Break some internal circular import chains -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/config@1.0.8 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.1.0 - -### Minor Changes - -- 05bf04ca6863: Initialize Nomad plugin with frontend and backend. List jobs/allocations - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/config@1.0.8 diff --git a/plugins/nomad/README.md b/plugins/nomad/README.md deleted file mode 100644 index 443669b71a..0000000000 --- a/plugins/nomad/README.md +++ /dev/null @@ -1,167 +0,0 @@ -# @backstage/plugin-nomad - -This is a frontend plugin is for viewing [Nomad](https://www.nomadproject.io/) [job versions](https://developer.hashicorp.com/nomad/docs/concepts/architecture#job) and [task group allocations](https://developer.hashicorp.com/nomad/docs/concepts/architecture#allocation). - -This plugin has a corresponding backend plugin required to call the Nomad cluster's API: ` @backstage/plugin-nomad-backend`. - -## Introduction - -### [Nomad](https://www.nomadproject.io/) - -> A simple and flexible scheduler and orchestrator to deploy and manage containers and non-containerized applications across on-prem and clouds at scale. - -### Features - -This plugin provides two components: - -- a table to view recent [job versions](https://developer.hashicorp.com/nomad/docs/commands/job/history) -- a table to view [allocations for a job and/or group](https://developer.hashicorp.com/nomad/tutorials/manage-jobs/jobs-inspect) - -## Getting Started - -### Requirements - -You will need to have the backend Nomad plugin, `@backstage/plugin-nomad-backend`, installed and running. See its README for set up instructions. - -You will need a running Nomad cluster with an API address that is reachable from the `@backstage/plugin-nomad/backend` plugin [running in the back end](https://backstage.io/docs/overview/architecture-overview/#third-party-backed-plugins). You can follow [this tutorial](https://developer.hashicorp.com/nomad/tutorials/enterprise/production-deployment-guide-vm-with-consul) to learn how to deploy one. - -If your Nomad cluster has ACLs enabled, you will need a `token` with at least the [`list-jobs`capability](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-policies#namespace-rules). You can check [this tutorial](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-create-policy) for more info or the minimal [example below](#example-policy). - -### Installation - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-nomad -``` - -### Configuration - -Add configuration to your [`app-config.yaml`](https://github.com/backstage/backstage/blob/master/app-config.yaml). For example: - -```yaml -nomad: - addr: 'http://localhost:4646' - token: '93e034ad-e504-42f9-129d-5d81be9f13d3' -``` - -The `token` can be excluded if [ACLs are not enabled](https://developer.hashicorp.com/nomad/api-docs#authentication). - -### Annotate Components - -Several annotations are available for Components that make use of this plugin: - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - annotations: - nomad.io/namespace: default - nomad.io/job-id: redis - nomad.io/group: 'redis|prometheus-collector' -``` - -- `nomad.io/job-id` annotation's value is matched exactly and corresponds to `JobID` in the Nomad API. It is required for the Job Versions Card but optional for the Allocations Table -- `nomad.io/group` annotation's value is used as a regex pattern against `TaskGroup` using [Nomad's server-side filtering](https://developer.hashicorp.com/nomad/api-docs#filtering). It is optional for the [Allocations Table](#allocations-table) -- `nomad.io/namespace` is the Namespace of the Job and Allocations of the Component. If omitted, it defaults to `default` - -### Job Versions Card - -The snippet below adds a card to the overview tab on the EntityPage. It shows versions of a Nomad job associated with a Component in the Catalog. - -```typescript -// In packages/app/src/components/catalog/EntityPage.tsx - -import { EntityNomadJobVersionListCard, isNomadJobIDAvailable } from '@backstage/plugin-nomad'; - -const overviewContent = ( - ... - - - - - - - -); -``` - -
- -
- -#### Requirements - -- the `nomad.io/job-id` annotation must be set - -### Allocations Table - -The snippet below adds a `/nomad` tab to the EntityPage that displays all allocations associated the `nomad.io/job-id` and/or `nomad.io/group` of Component's annotations. - -```typescript -// In packages/app/src/components/catalog/EntityPage.tsx - -import { EntityNomadAllocationListTable, isNomadAllocationsAvailable } from '@backstage/plugin-nomad'; - -const serviceEntityPage = ( - ... - - - -) -``` - -
- -
- -#### Requirements - -- `nomad.io/job-id` and/or `nomad.io/group` annotations must be set - -## ACL Policy Example - -Because this plugin uses API endpoints that require the `list-jobs` capability, the token you provide to the plugin's [`nomad` configuration](#configuration) needs at least that. - -To create such a token you can create a policy like below. This policy applies to all namespaces: - -```hcl -# backstage.policy.hcl -namespace "*" { - policy = "read" -} - -node { - policy = "read" -} -``` - -And create a policy for it: - -```bash -nomad acl policy apply backstage backstage.policy.hcl -``` - -Then create a client token for it: - -```bash -nomad acl token create -name=backstage -policy=backstage -Accessor ID = 5e9fe97b-76c5-8803-21b8-083308dc6c11 -Secret ID = 93e034ad-e504-42f9-129d-5d81be9f13d3 -Name = backstage -Type = client -Global = false -Create Time = 2023-06-05 00:45:20.51905 +0000 UTC -Expiry Time = -Create Index = 54 -Modify Index = 54 -Policies = [backstage] - -Roles - -``` - -In the example above, the `Secret ID` is the `token` to use in the [configuration](#configuration). diff --git a/plugins/nomad/api-report.md b/plugins/nomad/api-report.md deleted file mode 100644 index 68cc47c33d..0000000000 --- a/plugins/nomad/api-report.md +++ /dev/null @@ -1,35 +0,0 @@ -## API Report File for "@backstage/plugin-nomad" - -> 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 { Entity } from '@backstage/catalog-model'; -import { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public -export const EntityNomadAllocationListTable: () => JSX_2.Element; - -// @public -export const EntityNomadJobVersionListCard: () => JSX_2.Element | null; - -// @public (undocumented) -export const isNomadAllocationsAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export const isNomadJobIDAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export const nomadPlugin: BackstagePlugin< - { - root: RouteRef; - entityContent: RouteRef; - }, - {} ->; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/nomad/catalog-info.yaml b/plugins/nomad/catalog-info.yaml deleted file mode 100644 index d704846059..0000000000 --- a/plugins/nomad/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-nomad - title: '@backstage/plugin-nomad' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/nomad/dev/index.tsx b/plugins/nomad/dev/index.tsx deleted file mode 100644 index 73eaffb8e0..0000000000 --- a/plugins/nomad/dev/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createDevApp } from '@backstage/dev-utils'; -import { nomadPlugin } from '../src/plugin'; - -createDevApp().registerPlugin(nomadPlugin).render(); diff --git a/plugins/nomad/img/allocations-component.png b/plugins/nomad/img/allocations-component.png deleted file mode 100644 index fb1e9768af..0000000000 Binary files a/plugins/nomad/img/allocations-component.png and /dev/null differ diff --git a/plugins/nomad/img/job-versions-component.png b/plugins/nomad/img/job-versions-component.png deleted file mode 100644 index d6c9746bcb..0000000000 Binary files a/plugins/nomad/img/job-versions-component.png and /dev/null differ diff --git a/plugins/nomad/knip-report.md b/plugins/nomad/knip-report.md deleted file mode 100644 index ccda99cbfb..0000000000 --- a/plugins/nomad/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | - diff --git a/plugins/nomad/package.json b/plugins/nomad/package.json deleted file mode 100644 index 76410b0b00..0000000000 --- a/plugins/nomad/package.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "name": "@backstage/plugin-nomad", - "version": "0.1.11-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/nomad" - }, - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.9.13", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "luxon": "^3.3.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "cross-fetch": "^4.0.0" - }, - "files": [ - "dist" - ], - "configSchema": { - "$schema": "https://backstage.io/schema/config-v1", - "title": "@backstage/plugin-nomad", - "type": "object", - "properties": { - "nomad": { - "type": "object", - "properties": { - "addr": { - "type": "string", - "description": "The address of the Nomad API. See: https://developer.hashicorp.com/nomad/api-docs#addressing-and-ports", - "visibility": "frontend" - }, - "token": { - "type": "string", - "description": "The token to call the Nomad API with. See: https://developer.hashicorp.com/nomad/api-docs#authentication", - "visibility": "secret" - } - }, - "required": [ - "addr" - ] - } - } - } -} diff --git a/plugins/nomad/src/Router.tsx b/plugins/nomad/src/Router.tsx deleted file mode 100644 index aa872bae70..0000000000 --- a/plugins/nomad/src/Router.tsx +++ /dev/null @@ -1,46 +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 { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import { Route, Routes } from 'react-router-dom'; -import { EntityNomadAllocationListTable } from './components/EntityNomadAllocationListTable/EntityNomadAllocationListTable'; -import { - NOMAD_GROUP_ANNOTATION, - NOMAD_JOB_ID_ANNOTATION, - isNomadAllocationsAvailable, -} from './annotations'; - -export const EmbeddedRouter = () => { - const { entity } = useEntity(); - - if (!isNomadAllocationsAvailable(entity)) { - return ( - - ); - } - - return ( - - } /> - - ); -}; diff --git a/plugins/nomad/src/annotations.ts b/plugins/nomad/src/annotations.ts deleted file mode 100644 index 9854288e5d..0000000000 --- a/plugins/nomad/src/annotations.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Entity } from '@backstage/catalog-model'; - -/** @public */ -export const NOMAD_NAMESPACE_ANNOTATION = 'nomad.io/namespace'; - -/** @public */ -export const NOMAD_JOB_ID_ANNOTATION = 'nomad.io/job-id'; - -/** @public */ -export const NOMAD_GROUP_ANNOTATION = 'nomad.io/group'; - -/** @public */ -export const isNomadJobIDAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]); - -/** @public */ -export const isNomadAllocationsAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]) || - Boolean(entity.metadata.annotations?.[NOMAD_GROUP_ANNOTATION]); diff --git a/plugins/nomad/src/api.ts b/plugins/nomad/src/api.ts deleted file mode 100644 index 44aa5d48d2..0000000000 --- a/plugins/nomad/src/api.ts +++ /dev/null @@ -1,160 +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 { - DiscoveryApi, - FetchApi, - createApiRef, -} from '@backstage/core-plugin-api'; - -/** @public */ -export const nomadApiRef = createApiRef({ - id: 'plugin.nomad.service', -}); - -/** @public */ -export type NomadApi = { - /** - * listAllocations is for listing all allocations matching some part of 'filter'. - * - * See: https://developer.hashicorp.com/nomad/api-docs/allocations#list-allocations - */ - listAllocations: ( - options: ListAllocationsRequest, - ) => Promise; - - /** - * listJobVersions is for listing all deployments matching some part of 'filter'. - * - * See: https://developer.hashicorp.com/nomad/api-docs/deployments#list-deployments - */ - listJobVersions: ( - options: ListJobVersionsRequest, - ) => Promise; -}; - -/** @public */ -export interface ListAllocationsRequest { - namespace: string; - filter: string; -} - -/** @public */ -export interface ListAllocationsResponse { - allocations: Allocation[]; -} - -/** @public */ -export interface Allocation { - ClientStatus: string; - CreateTime: number; - DeploymentStatus: DeploymentStatus; - ID: string; - JobID: string; - JobVersion: string; - ModifyTime: number; - Name: string; - Namespace: string; - NodeID: string; - TaskGroup: string; -} - -/** @public */ -export interface DeploymentStatus { - Healthy: boolean; - Timestamp: string; -} - -/** @public */ -export interface ListJobVersionsRequest { - namespace: string; - jobID: string; -} - -/** @public */ -export interface ListJobVersionsResponse { - versions: Version[]; -} - -/** @public */ -export interface Version { - ID: string; - SubmitTime: number; - Stable: boolean; - Version: number; -} - -/** @public */ -export class FetchError extends Error { - get name(): string { - return this.constructor.name; - } - - static async forResponse(resp: Response): Promise { - return new FetchError( - `Request failed with status code ${ - resp.status - }.\nReason: ${await resp.text()}`, - ); - } -} - -/** @public */ -export class NomadHttpApi implements NomadApi { - static create(discoveryApi: DiscoveryApi, fetchApi: FetchApi) { - return new NomadHttpApi(discoveryApi, fetchApi); - } - - constructor(private discoveryApi: DiscoveryApi, private fetchApi: FetchApi) {} - - // TODO: pagination - async listAllocations( - options: ListAllocationsRequest, - ): Promise { - const apiUrl = await this.discoveryApi.getBaseUrl('nomad'); - - const resp = await this.fetchApi.fetch( - `${apiUrl}/v1/allocations?namespace=${encodeURIComponent( - options.namespace, - )}&filter=${encodeURIComponent(options.filter)}`, - ); - if (!resp.ok) throw await FetchError.forResponse(resp); - - return { - allocations: await resp.json(), - }; - } - - // TODO: pagination - async listJobVersions( - options: ListJobVersionsRequest, - ): Promise { - const apiUrl = await this.discoveryApi.getBaseUrl('nomad'); - - const resp = await this.fetchApi.fetch( - `${apiUrl}/v1/job/${ - options.jobID - }/versions?namespace=${encodeURIComponent(options.namespace)}`, - ); - if (!resp.ok) throw await FetchError.forResponse(resp); - - const respJson = await resp.json(); - - return { - versions: respJson.Versions, - }; - } -} diff --git a/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx b/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx deleted file mode 100644 index ea4f2836fe..0000000000 --- a/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx +++ /dev/null @@ -1,203 +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 { DateTime } from 'luxon'; -import { - Link, - ResponseErrorPanel, - StatusError, - StatusOK, - StatusPending, - StatusRunning, - Table, - TableColumn, -} from '@backstage/core-components'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import React, { useState } from 'react'; -import { Allocation, nomadApiRef } from '../../api'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; -import { - NOMAD_GROUP_ANNOTATION, - NOMAD_JOB_ID_ANNOTATION, - NOMAD_NAMESPACE_ANNOTATION, - isNomadAllocationsAvailable, -} from '../../annotations'; -import useAsync from 'react-use/lib/useAsync'; - -type rowType = Allocation & { nomadAddr: string }; - -const columns: TableColumn[] = [ - { - title: 'ID', - field: 'ID', - render: row => ( - - {row.ID.split('-')[0]} - - ), - }, - { - title: 'Task Group', - field: 'TaskGroup', - render: row => ( - - {row.TaskGroup} - - ), - }, - { - title: 'Created', - field: 'CreateTime', - render: row => - DateTime.fromMillis(row.CreateTime / 1000000).toLocaleString( - DateTime.DATETIME_MED_WITH_SECONDS, - ), - }, - { - title: 'Status', - field: 'ClientStatus', - render: row => - ({ - pending: pending, - running: running, - failed: failed, - complete: complete, - }[row.ClientStatus] || {row.ClientStatus}), - }, - { - title: 'Version', - field: 'JobVersion', - render: row => row.JobVersion, - }, - { - title: 'Client', - field: 'NodeID', - render: row => ( - - {row.ID.split('-')[0]} - - ), - }, -]; - -/** - * EntityNomadAllocationListTable is roughly based off Nomad's Allocations tab's view. - */ -export const EntityNomadAllocationListTable = () => { - // Wait on entity - const { entity } = useEntity(); - - // Get ref to the backend API - const [init, setInit] = useState(true); - const configApi = useApi(configApiRef); - const nomadApi = useApi(nomadApiRef); - const nomadAddr = configApi.getString('nomad.addr'); - - // Store results of calling API - const [allocations, setAllocations] = useState([]); - const [err, setErr] = useState(); - - // Check that attributes are available - if (!isNomadAllocationsAvailable(entity)) { - ; - } - - // Get plugin attributes - const namespace = - entity.metadata.annotations?.[NOMAD_NAMESPACE_ANNOTATION] ?? 'default'; - const job = entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION] ?? ''; - const group = entity.metadata.annotations?.[NOMAD_GROUP_ANNOTATION] ?? ''; - - // Make filter from attributes - const filter: string[] = []; - if (job) { - filter.push(`(JobID == "${job}")`); - } - if (group) { - filter.push(`(TaskGroup matches "${group}")`); - } - - // Create a query to update allocations - const query = async () => { - try { - // Make call to nomad-backend - const resp = await nomadApi.listAllocations({ - namespace, - filter: filter.join(' and '), - }); - - // Sort results - const results = resp.allocations - .sort((a, b) => a.CreateTime - b.CreateTime) - .sort(({ ClientStatus: a }, { ClientStatus: b }) => { - if (a === 'running' || b !== 'running') { - return -1; - } - return 0; - }); - - setAllocations(results.map(row => ({ ...row, id: row.ID, nomadAddr }))); - setErr(undefined); - } catch (e) { - setAllocations([]); - setErr(e); - } - }; - - // Start querying for allocations every 5s - useAsync(async () => { - if (init) { - setInit(false); - query(); - } - - const interval = setTimeout(() => { - query(); - }, 5_000); - - return () => clearTimeout(interval); - }, [allocations, entity]); - - // Store a ref to a potential error - if (err) { - return ; - } - - return ( - - title="Allocations" - options={{ - search: true, - padding: 'dense', - sorting: true, - draggable: false, - paging: false, - debounceInterval: 500, - filterCellStyle: { padding: '0 16px 0 20px' }, - }} - columns={columns} - data={allocations} - /> - ); -}; diff --git a/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx b/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx deleted file mode 100644 index d7d200bce4..0000000000 --- a/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx +++ /dev/null @@ -1,154 +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 { DateTime } from 'luxon'; -import { - InfoCard, - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import React, { useEffect, useState } from 'react'; -import { Version, nomadApiRef } from '../../api'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; -import { - NOMAD_JOB_ID_ANNOTATION, - NOMAD_NAMESPACE_ANNOTATION, - isNomadJobIDAvailable, -} from '../../annotations'; -import OpenInNewIcon from '@material-ui/icons/OpenInNew'; -import { Chip } from '@material-ui/core'; - -type rowType = Version & { nomadAddr: string }; - -const columns: TableColumn[] = [ - { - title: 'Version', - field: 'Version', - render: row => row.Version, - }, - { - title: 'Stable', - field: 'Stable', - render: row => , - }, - { - title: 'Submitted', - field: 'SubmitTime', - render: row => - DateTime.fromMillis(row.SubmitTime / 1000000).toLocaleString( - DateTime.DATETIME_MED_WITH_SECONDS, - ), - }, -]; - -/** - * EntityNomadJobVersionListCard is roughly based on the Nomad UI's versions tab. - */ -export const EntityNomadJobVersionListCard = () => { - // Wait on entity - const { entity } = useEntity(); - - // Get ref to the backend API - const configApi = useApi(configApiRef); - const nomadApi = useApi(nomadApiRef); - const nomadAddr = configApi.getString('nomad.addr'); - - // Store results of calling API - const [init, setInit] = useState(true); - const [versions, setVersions] = useState([]); - const [err, setErr] = useState(); - - // Get plugin attributes - const namespace = - entity.metadata.annotations?.[NOMAD_NAMESPACE_ANNOTATION] ?? 'default'; - const jobID = entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION] ?? ''; - - // Start querying for allocations every 10s - useEffect(() => { - // Create a query to update allocations - const query = async () => { - try { - // Make call to nomad-backend - const resp = await nomadApi.listJobVersions({ namespace, jobID }); - - setVersions( - resp.versions.map(row => ({ ...row, id: row.ID, nomadAddr })), - ); - setErr(undefined); - } catch (e) { - setVersions([]); - setErr(e); - } - }; - - if (init) { - setInit(false); - query(); - } - - const interval = setTimeout(() => { - query(); - }, 10_000); - - return () => clearTimeout(interval); - }, [init, jobID, namespace, nomadAddr, nomadApi]); - - // Store a ref to a potential error - if (err) { - return ; - } - - if (!entity) return null; - - // Check that job ID is set - if (!isNomadJobIDAvailable(entity)) { - return ( - - - - ); - } - - return ( - - title="Job versions" - actions={[ - { - icon: () => , - tooltip: 'Open in Nomad UI', - isFreeAction: true, - onClick: () => window.open(`${nomadAddr}/ui/jobs/${jobID}/versions`), - }, - ]} - options={{ - search: false, - padding: 'dense', - sorting: true, - draggable: false, - paging: false, - debounceInterval: 500, - filterCellStyle: { padding: '0 16px 0 20px' }, - }} - columns={columns} - data={versions} - /> - ); -}; diff --git a/plugins/nomad/src/components/index.ts b/plugins/nomad/src/components/index.ts deleted file mode 100644 index dcdae8cc99..0000000000 --- a/plugins/nomad/src/components/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { EntityNomadJobVersionListCard } from './EntityNomadJobVersionListCard/EntityNomadJobVersionListCard'; -export { EntityNomadAllocationListTable } from './EntityNomadAllocationListTable/EntityNomadAllocationListTable'; diff --git a/plugins/nomad/src/index.ts b/plugins/nomad/src/index.ts deleted file mode 100644 index d139935f1f..0000000000 --- a/plugins/nomad/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { - nomadPlugin, - EntityNomadJobVersionListCard, - EntityNomadAllocationListTable, -} from './plugin'; -export { - isNomadAllocationsAvailable, - isNomadJobIDAvailable, -} from './annotations'; diff --git a/plugins/nomad/src/plugin.test.ts b/plugins/nomad/src/plugin.test.ts deleted file mode 100644 index def0f8ab89..0000000000 --- a/plugins/nomad/src/plugin.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - nomadPlugin, - entityContentRouteRef, - EntityNomadContent, -} from './plugin'; - -describe('nomad', () => { - it('should export plugin', () => { - expect(nomadPlugin).toBeDefined(); - }); - - it('should export Nomad entity ref', () => { - expect(entityContentRouteRef).toBeDefined(); - }); - - it('should export Nomad entity', () => { - expect(EntityNomadContent).toBeDefined(); - }); -}); diff --git a/plugins/nomad/src/plugin.ts b/plugins/nomad/src/plugin.ts deleted file mode 100644 index df89785941..0000000000 --- a/plugins/nomad/src/plugin.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - discoveryApiRef, - fetchApiRef, - createApiFactory, - createPlugin, - createRouteRef, - createRoutableExtension, - createComponentExtension, -} from '@backstage/core-plugin-api'; - -import { rootRouteRef } from './routes'; -import { NomadHttpApi, nomadApiRef } from './api'; - -export const entityContentRouteRef = createRouteRef({ - id: 'nomad:entity-content', -}); - -/** @public */ -export const nomadPlugin = createPlugin({ - id: 'nomad', - apis: [ - createApiFactory({ - api: nomadApiRef, - deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, - factory: ({ discoveryApi, fetchApi }) => - NomadHttpApi.create(discoveryApi, fetchApi), - }), - ], - routes: { - root: rootRouteRef, - entityContent: entityContentRouteRef, - }, -}); - -/** @public */ -export const EntityNomadContent = nomadPlugin.provide( - createRoutableExtension({ - name: 'EntityNomadContent', - component: () => import('./Router').then(m => m.EmbeddedRouter), - mountPoint: entityContentRouteRef, - }), -); - -/** - * Card used to show the list of Nomad job versions. - * - * @public - */ -export const EntityNomadJobVersionListCard = nomadPlugin.provide( - createComponentExtension({ - name: 'EntityNomadJobVersionListCard', - component: { - lazy: () => - import('./components').then(m => m.EntityNomadJobVersionListCard), - }, - }), -); - -/** - * Table used to show the list of Nomad allocations for a job and/or task-group. - * - * @public - */ -export const EntityNomadAllocationListTable = nomadPlugin.provide( - createComponentExtension({ - name: 'EntityNomadAllocationListTable', - component: { - lazy: () => - import('./components').then(m => m.EntityNomadAllocationListTable), - }, - }), -); diff --git a/plugins/nomad/src/routes.ts b/plugins/nomad/src/routes.ts deleted file mode 100644 index 12e8caf4eb..0000000000 --- a/plugins/nomad/src/routes.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'nomad', -}); diff --git a/plugins/nomad/src/setupTests.ts b/plugins/nomad/src/setupTests.ts deleted file mode 100644 index 73dd8dce47..0000000000 --- a/plugins/nomad/src/setupTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import '@testing-library/jest-dom'; -import 'cross-fetch/polyfill'; diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index 22aae168fa..b3fbe6ae69 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,255 @@ # @backstage/plugin-notifications-backend +## 0.2.1-next.0 + +### Patch Changes + +- ee09dfc: Updated documentation for sending messages by external services. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-notifications-node@0.1.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## 0.2.0 + +### Minor Changes + +- 939b4ec: Notifications-backend URL query parameter changed from `minimal_severity` to `minimumSeverity`. +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- 0d99528: Notification processor functions are now renamed to `preProcess` and `postProcess`. + Additionally, processor name is now required to be returned by `getName`. + A new processor functionality `processOptions` was added to process options before sending the notification. +- e003e0e: The ordered list of notifications' severities is exported by notifications-common for reusability. +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- 9987066: fix: retrieve relations and children when mapping group entities for notifications +- 6206039: Fix entity owner resolution in notifications +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-notifications-node@0.1.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.2.0-next.1 + +### Minor Changes + +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- 9987066: fix: retrieve relations and children when mapping group entities for notifications +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-notifications-node@0.1.3-next.1 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-notifications-node@0.1.3-next.0 + - @backstage/plugin-signals-node@0.1.3-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-notifications-node@0.1.2 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/plugin-events-node@0.3.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.2 + - @backstage/backend-common@0.21.5 + - @backstage/plugin-auth-node@0.4.10 + - @backstage/plugin-notifications-node@0.1.1 + - @backstage/plugin-events-node@0.3.1 + - @backstage/plugin-signals-node@0.1.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.0 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options +- cd96173: Notifications-backend URL query parameters changed from `sort/sortOrder` to `orderField` and `created_after` to `createdAfter` to unify with other plugins. +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- ba14c0e: Support for broadcast notifications +- dff7a7e: All notifications can be marked and filtered by severity critical, high, normal or low, the default is 'normal' +- 4467036: Allow unauthenticated access to health check endpoint. +- 6c1547a: **BREAKING** Type definition added to signal recipients + + Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}` + instead string entity references + +- 75f2d84: the user can newly mark notifications as "Saved" for their better visibility in the future +- a790a3d: Move notification origin resolving to backend with new auth +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 84af361: Migrated to using the new auth services. +- 6d84ee6: Changed to use the refactored signal service naming +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-notifications-node@0.1.0 + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## 0.1.0-next.2 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options + +### Patch Changes + +- 6d84ee6: Changed to use the refactored signal service naming +- Updated dependencies + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-notifications-node@0.1.0-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-events-node@0.3.0-next.2 + - @backstage/plugin-notifications-common@0.0.2-next.1 + +## 0.1.0-next.1 + +### Minor Changes + +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- a790a3d: Move notification origin resolving to backend with new auth +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/plugin-notifications-node@0.1.0-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-events-node@0.3.0-next.1 + +## 0.1.0-next.0 + +### Minor Changes + +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 84af361: Migrated to using the new auth services. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-notifications-node@0.1.0-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + +## 0.0.1 + +### Patch Changes + +- 9873c44: Add support for signal type in notifications +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/plugin-notifications-common@0.0.1 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-notifications-node@0.0.1 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-events-node@0.2.19 + ## 0.0.1-next.1 ### Patch Changes diff --git a/plugins/notifications-backend/README.md b/plugins/notifications-backend/README.md index 233d0e5e21..60c9a4e078 100644 --- a/plugins/notifications-backend/README.md +++ b/plugins/notifications-backend/README.md @@ -71,7 +71,19 @@ export const myPlugin = createBackendPlugin({ }); ``` -## Sending notifications +## Sending Notifications By Backend Plugins -To be able to send notifications to users, you have to integrate the `@backstage/plugin-notifications-node` -to your application and plugins. +To be able to send notifications to users by other plugins, you have to integrate the `@backstage/plugin-notifications-node` +to your application and plugins. For the API, please refer documentation there. + +## Sending Notifications By External Services + +External services can create new messages by sending POST request to the REST API. + +To be able to do so, `external access` needs to be enabled as described in the [documentation](https://backstage.io/docs/auth/service-to-service-auth), e.g. via the `static tokens`. + +Once the API can be accessed, the request can look like: + +``` +curl -X POST [YOUR_SERVER_URL]/api/notifications -H "Content-Type: application/json" -H "Authorization: Bearer [BASE64_ENCODED_ACCESS_TOKEN]" -d '{"recipients":{"type":"entity","entityRef":"user:development/guest"},"payload": {"title": "Title of user-targeted external message","description": "The description","link": "http://foo.com/bar","severity": "high","topic": "The topic"}}' +``` diff --git a/plugins/notifications-backend/dev/index.ts b/plugins/notifications-backend/dev/index.ts new file mode 100644 index 0000000000..fe35606dd2 --- /dev/null +++ b/plugins/notifications-backend/dev/index.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { notificationService } from '@backstage/plugin-notifications-node'; + +const notificationsDebug = createBackendPlugin({ + pluginId: 'notifications-debug', + register(env) { + env.registerInit({ + deps: { + notifications: notificationService, + lifecycle: coreServices.lifecycle, + }, + async init({ notifications, lifecycle }) { + let interval: NodeJS.Timeout | undefined; + lifecycle.addStartupHook(async () => { + interval = setInterval(async () => { + await notifications.send({ + recipients: { + type: 'broadcast', + }, + payload: { title: 'Test notification' }, + }); + }, 5000); + }); + + lifecycle.addShutdownHook(async () => { + if (interval) { + clearInterval(interval); + } + }); + }, + }); + }, +}); + +const backend = createBackend(); +backend.add(import('@backstage/plugin-events-backend/alpha')); +backend.add(import('@backstage/plugin-signals-backend')); +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); +backend.add(import('../src')); +backend.add(notificationsDebug); + +backend.start(); diff --git a/plugins/notifications-backend/migrations/20240221_removeDone.js b/plugins/notifications-backend/migrations/20240221_removeDone.js new file mode 100644 index 0000000000..d67ac81825 --- /dev/null +++ b/plugins/notifications-backend/migrations/20240221_removeDone.js @@ -0,0 +1,29 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +exports.up = async function up(knex) { + await knex.schema.alterTable('notification', table => { + table.text('link').nullable().alter(); + table.dropColumn('done'); + }); +}; + +exports.down = async function down(knex) { + await knex.schema.alterTable('notification', table => { + table.text('link').notNullable().alter(); + table.datetime('done').nullable(); + }); +}; diff --git a/plugins/notifications-backend/migrations/20240313_broadcast.js b/plugins/notifications-backend/migrations/20240313_broadcast.js new file mode 100644 index 0000000000..8b9ddeb24d --- /dev/null +++ b/plugins/notifications-backend/migrations/20240313_broadcast.js @@ -0,0 +1,55 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +exports.up = async function up(knex) { + await knex.schema.createTable('broadcast', table => { + table.uuid('id').primary(); + table.string('title').notNullable(); + table.text('description').nullable(); + table.string('severity', 8).notNullable(); + table.text('link').nullable(); + table.string('origin', 255).notNullable(); + table.string('scope', 255).nullable(); + table.string('topic', 255).nullable(); + table.datetime('created').defaultTo(knex.fn.now()).notNullable(); + table.datetime('updated').nullable(); + table.index(['scope', 'origin'], 'broadcast_cope_origin_idx'); + }); + + await knex.schema.createTable('broadcast_user_status', table => { + table.uuid('broadcast_id').notNullable(); + table.string('user', 255).notNullable(); + table.datetime('read').nullable(); + table.datetime('saved').nullable(); + + table + .foreign('broadcast_id') + .references(['id']) + .inTable('broadcast') + .onDelete('CASCADE'); + table.unique(['broadcast_id', 'user'], { + indexName: 'broadcast_user_idx', + }); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.dropTable('broadcast_user_status'); + await knex.schema.dropTable('broadcast'); +}; diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index df3cf3a8a0..1a16996e90 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.0.1-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "0.2.1-next.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -14,17 +14,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/notifications-backend" }, - "backstage": { - "role": "backend-plugin" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "migrations/**/*.{js,d.ts}" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -42,19 +46,21 @@ "express-promise-router": "^4.1.0", "knex": "^3.0.0", "node-fetch": "^2.6.7", - "uuid": "^8.0.0", + "uuid": "^9.0.0", "winston": "^3.2.1", "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^", + "@backstage/plugin-events-backend": "workspace:^", + "@backstage/plugin-signals-backend": "workspace:^", "@types/express": "^4.17.6", "@types/supertest": "^2.0.8", "msw": "^1.0.0", "supertest": "^6.2.4" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts index 35964ff582..6204629821 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts @@ -16,8 +16,10 @@ import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { DatabaseNotificationsStore } from './DatabaseNotificationsStore'; import { Knex } from 'knex'; -import { v4 as uuid } from 'uuid'; -import { Notification } from '@backstage/plugin-notifications-common'; +import { + Notification, + NotificationSeverity, +} from '@backstage/plugin-notifications-common'; jest.setTimeout(60_000); @@ -37,21 +39,115 @@ async function createStore(databaseId: TestDatabaseId) { }; } +const idOnly = (notification: Notification) => notification.id; + const user = 'user:default/john.doe'; -const testNotification: Partial = { + +const id0 = '08e0871e-e60a-4f68-8110-5ae3513f992e'; +const id1 = '01e0871e-e60a-4f68-8110-5ae3513f992e'; +const id2 = '02e0871e-e60a-4f68-8110-5ae3513f992e'; +const id3 = '03e0871e-e60a-4f68-8110-5ae3513f992e'; +const id4 = '04e0871e-e60a-4f68-8110-5ae3513f992e'; +const id5 = '05e0871e-e60a-4f68-8110-5ae3513f992e'; +const id6 = '06e0871e-e60a-4f68-8110-5ae3513f992e'; +const id7 = '07e0871e-e60a-4f68-8110-5ae3513f992e'; +const ids = [id1, id2, id3, id4, id5, id6, id7]; + +const now = Date.now(); +const timeDelay = 5 * 1000; /* 5 secs */ + +const testNotification1: Notification = { + id: id1, user, - created: new Date(), - origin: 'plugin-test', + created: new Date(now - 1 * 60 * 60 * 1000 /* an hour ago */), + origin: 'abcd-origin', payload: { - title: 'Notification 1', + title: 'Notification 1 - please find me', + description: 'a description of the notification', + topic: 'efgh-topic', + link: '/catalog', + severity: 'critical', + }, +}; +const testNotification2: Notification = { + id: id2, + user, + created: new Date(now), + origin: 'cd-origin', + payload: { + title: 'Notification 2', + topic: 'gh-topic', + link: '/catalog', + severity: 'normal', + scope: 'scaffolder-1234', + }, +}; +const testNotification3: Notification = { + id: id3, + user, + created: new Date(now - 5 * timeDelay), + origin: 'bcd-origin', + payload: { + title: 'Notification 3', + topic: 'fgh-topic', link: '/catalog', severity: 'normal', }, }; - -const otherUserNotification: Partial = { - ...testNotification, +const testNotification4: Notification = { + id: id4, + user, + created: new Date(now - 4 * timeDelay), + origin: 'plugin-test', + payload: { + title: 'Notification 4', + link: '/catalog', + severity: 'normal', + }, +}; +const testNotification5: Notification = { + id: id5, + user, + created: new Date(now - 3 * timeDelay), + origin: 'plugin-test', + payload: { + title: 'Notification 5', + link: '/catalog', + severity: 'normal', + }, +}; +const testNotification6: Notification = { + id: id6, + user, + created: new Date(now - 2 * timeDelay), + origin: 'plugin-test', + payload: { + title: 'Notification 6', + link: '/catalog', + severity: 'normal', + }, +}; +const testNotification7: Notification = { + id: id7, + user, + created: new Date(now - 1 * timeDelay), + origin: 'plugin-test', + payload: { + title: 'Notification 7', + link: '/catalog', + severity: 'normal', + }, +}; +const otherUserNotification: Notification = { + id: id0, user: 'user:default/jane.doe', + created: new Date(now), + origin: 'plugin-test', + payload: { + title: 'Notification Other - please do not find me', + link: '/catalog', + severity: 'normal', + }, }; describe.each(databases.eachSupportedId())( @@ -59,31 +155,6 @@ describe.each(databases.eachSupportedId())( databaseId => { let storage: DatabaseNotificationsStore; let knex: Knex; - const insertNotification = async ( - notification: Partial & { - id: string; - done?: Date; - saved?: Date; - read?: Date; - }, - ) => - ( - await knex('notification') - .insert({ - id: notification.id, - user: notification.user, - origin: notification.origin, - created: notification.created, - link: notification.payload?.link, - title: notification.payload?.title, - severity: notification.payload?.severity, - scope: notification.payload?.scope, - done: notification.done, - saved: notification.saved, - read: notification.read, - }) - .returning('id') - )[0].id ?? -1; beforeAll(async () => { ({ storage, knex } = await createStore(databaseId)); @@ -92,146 +163,373 @@ describe.each(databases.eachSupportedId())( afterEach(async () => { jest.resetAllMocks(); await knex('notification').del(); + await knex('broadcast').del(); + }); + + describe('saveNotification', () => { + it('should store a notification', async () => { + await storage.saveNotification(testNotification1); + const notification = await storage.getNotification({ id: id1 }); + expect(notification?.id).toBe(id1); + expect(notification?.user).toBe(user); + expect(notification?.origin).toBe('abcd-origin'); + expect(notification?.payload?.title).toBe( + 'Notification 1 - please find me', + ); + expect(notification?.payload?.description).toBe( + 'a description of the notification', + ); + expect(notification?.payload?.topic).toBe('efgh-topic'); + expect(notification?.payload?.link).toBe('/catalog'); + expect(notification?.payload?.severity).toBe('critical'); + }); }); describe('getNotifications', () => { it('should return all notifications for user', async () => { - const id1 = uuid(); - const id2 = uuid(); - await insertNotification({ id: id1, ...testNotification }); - await insertNotification({ id: id2, ...testNotification }); - await insertNotification({ id: uuid(), ...otherUserNotification }); + await storage.saveNotification(testNotification1); + await storage.saveNotification(testNotification2); + await storage.saveBroadcast(testNotification3); + await storage.saveNotification(otherUserNotification); const notifications = await storage.getNotifications({ user }); - expect(notifications.length).toBe(2); + expect(notifications.map(idOnly)).toEqual([ + /* default sorting from new to old */ + id2, + id3, + id1, + ]); }); - it('should return undone notifications for user', async () => { - const id1 = uuid(); - const id2 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, - done: new Date(), - }); - await insertNotification({ id: id2, ...testNotification }); - await insertNotification({ id: uuid(), ...otherUserNotification }); + it('should return read notifications for user', async () => { + await storage.saveNotification(testNotification1); + await storage.saveBroadcast(testNotification2); + await storage.saveNotification(testNotification3); + await storage.saveNotification(otherUserNotification); + + await storage.markRead({ ids: [id1, id3], user }); const notifications = await storage.getNotifications({ user, - type: 'undone', + read: true, }); - expect(notifications.length).toBe(1); + expect(notifications.map(idOnly)).toEqual([id3, id1]); + }); + + it('should return unread notifications for user', async () => { + await storage.saveNotification(testNotification1); + await storage.saveBroadcast(testNotification2); + await storage.saveNotification(testNotification3); + await storage.saveNotification(otherUserNotification); + + await storage.markRead({ ids: [id1, id3], user }); + + const notifications = await storage.getNotifications({ + user, + read: false, + }); + expect(notifications).toHaveLength(1); expect(notifications.at(0)?.id).toEqual(id2); }); - it('should return done notifications for user', async () => { - const id1 = uuid(); - const id2 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, - done: new Date(), - }); - await insertNotification({ id: id2, ...testNotification }); - await insertNotification({ id: uuid(), ...otherUserNotification }); + it('should return both read and unread notifications for user', async () => { + await storage.saveNotification(testNotification1); + await storage.saveBroadcast(testNotification2); + await storage.saveNotification(testNotification3); + + await storage.markRead({ ids: [id1, id3], user }); const notifications = await storage.getNotifications({ user, - type: 'done', + read: undefined, }); - expect(notifications.length).toBe(1); - expect(notifications.at(0)?.id).toEqual(id1); + expect(notifications.map(idOnly)).toEqual([id2, id3, id1]); }); it('should allow searching for notifications', async () => { - const id1 = uuid(); - const id2 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, - payload: { - link: '/catalog', - severity: 'normal', - title: 'Please find me', - }, - }); - await insertNotification({ id: id2, ...testNotification }); - await insertNotification({ id: uuid(), ...otherUserNotification }); + await storage.saveNotification(testNotification2); + await storage.saveBroadcast(testNotification1); + await storage.saveNotification(otherUserNotification); const notifications = await storage.getNotifications({ user, search: 'find me', }); - expect(notifications.length).toBe(1); + expect(notifications).toHaveLength(1); expect(notifications.at(0)?.id).toEqual(id1); }); + + it('should filter notifications based on created date', async () => { + await storage.saveNotification(testNotification1); + await storage.saveBroadcast(testNotification2); + await storage.saveNotification(otherUserNotification); + + const notifications = await storage.getNotifications({ + user, + createdAfter: new Date(Date.now() - 5 * 60 * 1000 /* 5mins */), + }); + expect(notifications.length).toBe(1); + expect(notifications.at(0)?.id).toEqual(id2); + }); + }); + + describe('getNotifications filters on severity', () => { + beforeEach(async () => { + const severities: (NotificationSeverity | undefined)[] = [ + 'normal', + undefined, + 'critical', + 'high', + 'low', + ]; + await Promise.all( + severities.map((severity, idx) => + storage.saveNotification({ + id: ids[idx], + user, + origin: 'test-origin', + created: new Date(now - idx * timeDelay), + payload: { + title: severity || 'default', + severity, + }, + }), + ), + ); + }); + it('normal', async () => { + const normal = await storage.getNotifications({ + user, + minimumSeverity: 'normal', + }); + expect(normal.map(idOnly)).toEqual([id1, id2, id3, id4]); + }); + + it('critical', async () => { + const critical = await storage.getNotifications({ + user, + minimumSeverity: 'critical', + }); + expect(critical.length).toBe(1); + expect(critical.at(0)?.id).toEqual(id3); + }); + + it('high', async () => { + const high = await storage.getNotifications({ + user, + minimumSeverity: 'high', + }); + expect(high.map(idOnly)).toEqual([id3, id4]); + }); + + it('low', async () => { + const low = await storage.getNotifications({ + user, + minimumSeverity: 'low', + }); + expect(low.map(idOnly)).toEqual([id1, id2, id3, id4, id5]); + }); + }); + + describe('getNotifications pagination', () => { + beforeEach(async () => { + await storage.saveNotification(testNotification1); + await storage.saveNotification(testNotification2); + await storage.saveNotification(testNotification3); + await storage.saveNotification(testNotification4); + await storage.saveNotification(testNotification5); + await storage.saveBroadcast(testNotification6); + await storage.saveNotification(testNotification7); + await storage.saveNotification(otherUserNotification); + }); + + it('should not apply by default', async () => { + const allUserNotifications = await storage.getNotifications({ + user, + }); + expect(allUserNotifications).toHaveLength(7); + + const correctMySqlPrecision = 1000; + const notifications = await storage.getNotifications({ + user, + createdAfter: new Date( + new Date(now - 1 * 60 * 60 * 1000 - correctMySqlPrecision), + ), + // so far no pagination + }); + expect(notifications.map(idOnly)).toEqual([ + id2, + id7, + id6, + id5, + id4, + id3, + id1, + ]); + }); + + it('should get first page', async () => { + const allUserNotificationsPageOne = await storage.getNotifications({ + user, + limit: 3, + offset: 0, + }); + expect(allUserNotificationsPageOne.map(idOnly)).toEqual([ + id2, + id7, + id6, + ]); + }); + + it('should get second page', async () => { + const allUserNotificationsPageTwo = await storage.getNotifications({ + user, + limit: 3, + offset: 3, + }); + expect(allUserNotificationsPageTwo.map(idOnly)).toEqual([ + id5, + id4, + id3, + ]); + }); + }); + + describe('getNotifications sorting', () => { + beforeEach(async () => { + await storage.saveNotification(testNotification1); + await storage.saveBroadcast(testNotification2); + await storage.saveNotification(testNotification3); + }); + + it('should sort created asc', async () => { + const notificationsCreatedAsc = await storage.getNotifications({ + user, + orderField: [{ field: 'created', order: 'asc' }], + }); + expect(notificationsCreatedAsc.map(idOnly)).toEqual([id1, id3, id2]); + }); + + it('should sort created desc', async () => { + const notificationsCreatedDesc = await storage.getNotifications({ + user, + orderField: [{ field: 'created', order: 'desc' }], + }); + expect(notificationsCreatedDesc.map(idOnly)).toEqual([id2, id3, id1]); + }); + + it('should sort topic asc', async () => { + const notificationsTopicAsc = await storage.getNotifications({ + user, + orderField: [{ field: 'topic', order: 'asc' }], + }); + expect(notificationsTopicAsc.map(idOnly)).toEqual([id1, id3, id2]); + }); + + it('should sort topic desc', async () => { + const notificationsTopicDesc = await storage.getNotifications({ + user, + orderField: [{ field: 'topic', order: 'desc' }], + }); + expect(notificationsTopicDesc.map(idOnly)).toEqual([id2, id3, id1]); + }); + + it('should sort origin asc', async () => { + const notificationsOrigin = await storage.getNotifications({ + user, + orderField: [{ field: 'origin', order: 'asc' }], + limit: 2, + offset: 0, + }); + expect(notificationsOrigin.map(idOnly)).toEqual([id1, id3]); + }); + + it('should sort origin desc', async () => { + const notificationsOriginNext = await storage.getNotifications({ + user, + orderField: [{ field: 'origin', order: 'desc' }], + limit: 2, + offset: 2, + }); + expect(notificationsOriginNext).toHaveLength(1); + expect(notificationsOriginNext.at(0)?.id).toEqual(id1); + }); }); describe('getStatus', () => { it('should return status for user', async () => { - const id1 = uuid(); - const id2 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, + await storage.saveNotification({ + ...testNotification1, read: new Date(), }); - await insertNotification({ id: id2, ...testNotification }); - await insertNotification({ id: uuid(), ...otherUserNotification }); + await storage.saveNotification(testNotification2); + await storage.saveBroadcast({ ...testNotification3, read: new Date() }); + await storage.saveBroadcast(testNotification4); + await storage.saveNotification(otherUserNotification); const status = await storage.getStatus({ user }); - expect(status.read).toEqual(1); - expect(status.unread).toEqual(1); + expect(status.read).toEqual(2); + expect(status.unread).toEqual(2); }); }); describe('getExistingScopeNotification', () => { it('should return existing scope notification', async () => { - const id1 = uuid(); - const notification: any = { - ...testNotification, - id: id1, - payload: { - title: 'Notification', - link: '/scaffolder/task/1234', - severity: 'normal', - scope: 'scaffolder-1234', - }, - }; - await insertNotification(notification); + await storage.saveNotification(testNotification1); + await storage.saveNotification(testNotification2); const existing = await storage.getExistingScopeNotification({ user, - origin: 'plugin-test', + origin: 'cd-origin', scope: 'scaffolder-1234', }); expect(existing).not.toBeNull(); - expect(existing?.id).toEqual(id1); + expect(existing?.id).toEqual(id2); + }); + + it('should return existing scope broadcast', async () => { + await storage.saveBroadcast(testNotification1); + await storage.saveBroadcast(testNotification2); + const existing = await storage.getExistingScopeBroadcast({ + origin: 'cd-origin', + scope: 'scaffolder-1234', + }); + expect(existing).not.toBeNull(); + expect(existing?.id).toEqual(id2); }); }); describe('restoreExistingNotification', () => { it('should return restore existing scope notification', async () => { - const id1 = uuid(); - const notification: any = { - ...testNotification, - id: id1, - read: new Date(), - done: new Date(), - payload: { - title: 'Notification', - link: '/scaffolder/task/1234', - severity: 'normal', - scope: 'scaffolder-1234', - }, - }; - await insertNotification(notification); + await storage.saveNotification(testNotification1); + await storage.saveNotification(testNotification2); const existing = await storage.restoreExistingNotification({ - id: id1, + id: id2, notification: { - user: notification.user, + user: testNotification2.user, + payload: { + title: 'New notification', + link: '/scaffolder/task/1234', + severity: 'low', + }, + } as any, + }); + expect(existing).not.toBeNull(); + expect(existing?.id).toEqual(id2); + expect(existing?.payload.title).toEqual('New notification'); + expect(existing?.payload.severity).toEqual('low'); + expect(existing?.read).toBeNull(); + }); + + it('should return restore existing scope broadcast', async () => { + await storage.saveBroadcast(testNotification1); + await storage.saveBroadcast(testNotification2); + + const existing = await storage.restoreExistingNotification({ + id: id2, + notification: { + user: testNotification2.user, payload: { title: 'New notification', link: '/scaffolder/task/1234', @@ -240,28 +538,41 @@ describe.each(databases.eachSupportedId())( } as any, }); expect(existing).not.toBeNull(); - expect(existing?.id).toEqual(id1); + expect(existing?.id).toEqual(id2); expect(existing?.payload.title).toEqual('New notification'); - expect(existing?.done).toBeNull(); expect(existing?.read).toBeNull(); }); }); describe('getNotification', () => { it('should return notification by id', async () => { - const id1 = uuid(); - await insertNotification({ id: id1, ...testNotification }); - + await storage.saveNotification(testNotification1); const notification = await storage.getNotification({ id: id1 }); expect(notification?.id).toEqual(id1); }); + + it('should return broadcast by id', async () => { + await storage.saveNotification(testNotification1); + await storage.saveBroadcast(testNotification2); + const notification = await storage.getNotification({ id: id2 }); + expect(notification?.id).toEqual(id2); + }); }); describe('markRead', () => { it('should mark notification read', async () => { - const id1 = uuid(); - await insertNotification({ id: id1, ...testNotification }); + await storage.saveNotification(testNotification1); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.read).toBeNull(); + await storage.markRead({ ids: [id1], user }); + const notification = await storage.getNotification({ id: id1 }); + expect(notification?.read).not.toBeNull(); + }); + it('should mark broadcast read', async () => { + await storage.saveBroadcast(testNotification1); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.read).toBeNull(); await storage.markRead({ ids: [id1], user }); const notification = await storage.getNotification({ id: id1 }); expect(notification?.read).not.toBeNull(); @@ -270,50 +581,44 @@ describe.each(databases.eachSupportedId())( describe('markUnread', () => { it('should mark notification unread', async () => { - const id1 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, + await storage.saveNotification({ + ...testNotification1, read: new Date(), }); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.read).not.toBeNull(); + await storage.markUnread({ ids: [id1], user }); + const notification = await storage.getNotification({ id: id1 }); + expect(notification?.read).toBeNull(); + }); + it('should mark broadcast unread', async () => { + await storage.saveBroadcast({ + ...testNotification1, + read: new Date(), + }); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.read).not.toBeNull(); await storage.markUnread({ ids: [id1], user }); const notification = await storage.getNotification({ id: id1 }); expect(notification?.read).toBeNull(); }); }); - describe('markDone', () => { - it('should mark notification done', async () => { - const id1 = uuid(); - await insertNotification({ id: id1, ...testNotification }); - - await storage.markDone({ ids: [id1], user }); - const notification = await storage.getNotification({ id: id1 }); - expect(notification?.done).not.toBeNull(); - }); - }); - - describe('markUndone', () => { - it('should mark notification undone', async () => { - const id1 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, - done: new Date(), - }); - - await storage.markUndone({ ids: [id1], user }); - const notification = await storage.getNotification({ id: id1 }); - expect(notification?.done).toBeNull(); - }); - }); - describe('markSaved', () => { it('should mark notification saved', async () => { - const id1 = uuid(); - await insertNotification({ id: id1, ...testNotification }); + await storage.saveNotification(testNotification1); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.saved).toBeNull(); + await storage.markSaved({ ids: [id1], user }); + const notification = await storage.getNotification({ id: id1 }); + expect(notification?.saved).not.toBeNull(); + }); + it('should mark broadcast saved', async () => { + await storage.saveBroadcast(testNotification1); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.saved).toBeNull(); await storage.markSaved({ ids: [id1], user }); const notification = await storage.getNotification({ id: id1 }); expect(notification?.saved).not.toBeNull(); @@ -322,13 +627,24 @@ describe.each(databases.eachSupportedId())( describe('markUnsaved', () => { it('should mark notification not saved', async () => { - const id1 = uuid(); - await insertNotification({ - id: id1, - ...testNotification, + await storage.saveNotification({ + ...testNotification1, saved: new Date(), }); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.saved).not.toBeNull(); + await storage.markUnsaved({ ids: [id1], user }); + const notification = await storage.getNotification({ id: id1 }); + expect(notification?.saved).toBeNull(); + }); + it('should mark broadcast not saved', async () => { + await storage.saveBroadcast({ + ...testNotification1, + saved: new Date(), + }); + const notificationBefore = await storage.getNotification({ id: id1 }); + expect(notificationBefore?.saved).not.toBeNull(); await storage.markUnsaved({ ids: [id1], user }); const notification = await storage.getNotification({ id: id1 }); expect(notification?.saved).toBeNull(); diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts index 7e5060106b..ae548a9892 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts @@ -22,7 +22,11 @@ import { NotificationModifyOptions, NotificationsStore, } from './NotificationsStore'; -import { Notification } from '@backstage/plugin-notifications-common'; +import { + Notification, + NotificationSeverity, + notificationSeverities, +} from '@backstage/plugin-notifications-common'; import { Knex } from 'knex'; const migrationsDir = resolvePackagePath( @@ -30,9 +34,37 @@ const migrationsDir = resolvePackagePath( 'migrations', ); +const NOTIFICATION_COLUMNS = [ + 'id', + 'title', + 'description', + 'severity', + 'link', + 'origin', + 'scope', + 'topic', + 'created', + 'updated', + 'user', + 'read', + 'saved', +]; + +export const normalizeSeverity = (input?: string): NotificationSeverity => { + let lower = (input ?? 'normal').toLowerCase() as NotificationSeverity; + if (notificationSeverities.indexOf(lower) < 0) { + lower = 'normal'; + } + return lower; +}; + /** @internal */ export class DatabaseNotificationsStore implements NotificationsStore { - private constructor(private readonly db: Knex) {} + private readonly isSQLite = false; + + private constructor(private readonly db: Knex) { + this.isSQLite = this.db.client.config.client.includes('sqlite3'); + } static async create({ database, @@ -60,8 +92,7 @@ export class DatabaseNotificationsStore implements NotificationsStore { return rows.map(row => ({ id: row.id, user: row.user, - created: row.created, - done: row.done, + created: new Date(row.created), saved: row.saved, read: row.read, updated: row.updated, @@ -78,24 +109,76 @@ export class DatabaseNotificationsStore implements NotificationsStore { })); }; + private mapNotificationToDbRow = (notification: Notification) => { + return { + id: notification.id, + user: notification.user, + origin: notification.origin, + created: notification.created, + topic: notification.payload?.topic, + link: notification.payload?.link, + title: notification.payload?.title, + description: notification.payload?.description, + severity: normalizeSeverity(notification.payload?.severity), + scope: notification.payload?.scope, + saved: notification.saved, + read: notification.read, + }; + }; + + private mapBroadcastToDbRow = (notification: Notification) => { + return { + id: notification.id, + origin: notification.origin, + created: notification.created, + topic: notification.payload?.topic, + link: notification.payload?.link, + title: notification.payload?.title, + description: notification.payload?.description, + severity: normalizeSeverity(notification.payload?.severity), + scope: notification.payload?.scope, + }; + }; + + private getBroadcastUnion = () => { + return this.db('broadcast') + .leftJoin( + 'broadcast_user_status', + 'id', + '=', + 'broadcast_user_status.broadcast_id', + ) + .select(NOTIFICATION_COLUMNS); + }; + private getNotificationsBaseQuery = ( options: NotificationGetOptions | NotificationModifyOptions, ) => { - const { user, type } = options; - const query = this.db('notification').where('user', user); + const { user, orderField } = options; - if (options.sort !== undefined && options.sort !== null) { - query.orderBy(options.sort, options.sortOrder ?? 'desc'); - } else if (options.sort !== null) { - query.orderBy('created', options.sortOrder ?? 'desc'); + const subQuery = this.db('notification') + .select(NOTIFICATION_COLUMNS) + .unionAll([this.getBroadcastUnion()]) + .as('notifications'); + + const query = this.db.from(subQuery).where(q => { + q.where('user', user).orWhereNull('user'); + }); + + if (orderField && orderField.length > 0) { + orderField.forEach(orderBy => { + query.orderBy(orderBy.field, orderBy.order); + }); + } else if (!orderField) { + query.orderBy('created', 'desc'); } - if (type === 'undone') { - query.whereNull('done'); - } else if (type === 'done') { - query.whereNotNull('done'); - } else if (type === 'saved') { - query.whereNotNull('saved'); + if (options.createdAfter) { + if (this.isSQLite) { + query.where('created', '>=', options.createdAfter.valueOf()); + } else { + query.where('created', '>=', options.createdAfter.toISOString()); + } } if (options.limit) { @@ -108,13 +191,31 @@ export class DatabaseNotificationsStore implements NotificationsStore { if (options.search) { query.whereRaw( - `(LOWER(notification.title) LIKE LOWER(?) OR LOWER(notification.description) LIKE LOWER(?))`, + `(LOWER(title) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?))`, [`%${options.search}%`, `%${options.search}%`], ); } if (options.ids) { - query.whereIn('notification.id', options.ids); + query.whereIn('id', options.ids); + } + + if (options.read) { + query.whereNotNull('read'); + } else if (options.read === false) { + query.whereNull('read'); + } // or match both if undefined + + if (options.saved) { + query.whereNotNull('saved'); + } else if (options.saved === false) { + query.whereNull('saved'); + } // or match both if undefined + + if (options.minimumSeverity !== undefined) { + const idx = notificationSeverities.indexOf(options.minimumSeverity); + const equalOrHigher = notificationSeverities.slice(0, idx + 1); + query.whereIn('severity', equalOrHigher); } return query; @@ -122,18 +223,46 @@ export class DatabaseNotificationsStore implements NotificationsStore { async getNotifications(options: NotificationGetOptions) { const notificationQuery = this.getNotificationsBaseQuery(options); - const notifications = await notificationQuery.select(); + const notifications = await notificationQuery.select(NOTIFICATION_COLUMNS); return this.mapToNotifications(notifications); } + async getNotificationsCount(options: NotificationGetOptions) { + const countOptions: NotificationGetOptions = { ...options }; + countOptions.limit = undefined; + countOptions.offset = undefined; + countOptions.orderField = []; + const notificationQuery = this.getNotificationsBaseQuery(countOptions); + const response = await notificationQuery.count('id as CNT'); + return Number(response[0].CNT); + } + async saveNotification(notification: Notification) { - await this.db.insert(notification).into('notification'); + await this.db + .insert(this.mapNotificationToDbRow(notification)) + .into('notification'); + } + + async saveBroadcast(notification: Notification) { + await this.db + .insert(this.mapBroadcastToDbRow(notification)) + .into('broadcast'); + if (notification.saved || notification.read) { + await this.db + .insert({ + user: notification.user, + broadcast_id: notification.id, + saved: notification.saved, + read: notification.read, + }) + .into('broadcast_user_status'); + } } async getStatus(options: NotificationGetOptions) { const notificationQuery = this.getNotificationsBaseQuery({ ...options, - sort: null, + orderField: [], }); const readSubQuery = notificationQuery .clone() @@ -165,7 +294,6 @@ export class DatabaseNotificationsStore implements NotificationsStore { .where('user', options.user) .where('scope', options.scope) .where('origin', options.origin) - .select() .limit(1); const rows = await query; @@ -175,32 +303,59 @@ export class DatabaseNotificationsStore implements NotificationsStore { return rows[0] as Notification; } - async restoreExistingNotification(options: { + async getExistingScopeBroadcast(options: { scope: string; origin: string }) { + const query = this.db('broadcast') + .where('scope', options.scope) + .where('origin', options.origin) + .limit(1); + + const rows = await query; + if (!rows || rows.length === 0) { + return null; + } + return rows[0] as Notification; + } + + async restoreExistingNotification({ + id, + notification, + }: { id: string; notification: Notification; }) { - const query = this.db('notification') - .where('id', options.id) - .where('user', options.notification.user); - - await query.update({ - title: options.notification.payload.title, - description: options.notification.payload.description, - link: options.notification.payload.link, - topic: options.notification.payload.topic, - updated: options.notification.created, - severity: options.notification.payload.severity, + const updateColumns = { + title: notification.payload.title, + description: notification.payload.description, + link: notification.payload.link, + topic: notification.payload.topic, + updated: new Date(), + severity: normalizeSeverity(notification.payload?.severity), read: null, - done: null, - }); + }; - return await this.getNotification(options); + const notificationQuery = this.db('notification') + .where('id', id) + .where('user', notification.user); + const broadcastQuery = this.db('broadcast').where('id', id); + + await Promise.all([ + notificationQuery.update(updateColumns), + broadcastQuery.update({ ...updateColumns, read: undefined }), + ]); + + return await this.getNotification({ id }); } async getNotification(options: { id: string }): Promise { - const rows = await this.db('notification') + const rows = await this.db + .select('*') + .from( + this.db('notification') + .select(NOTIFICATION_COLUMNS) + .unionAll([this.getBroadcastUnion()]) + .as('notifications'), + ) .where('id', options.id) - .select() .limit(1); if (!rows || rows.length === 0) { return null; @@ -208,33 +363,65 @@ export class DatabaseNotificationsStore implements NotificationsStore { return this.mapToNotifications(rows)[0]; } + private markReadSaved = async ( + ids: string[], + user: string, + read?: Date | null, + saved?: Date | null, + ) => { + await this.db('notification') + .whereIn('id', ids) + .where('user', user) + .update({ read, saved }); + + const broadcasts = this.mapToNotifications( + await this.db('broadcast').whereIn('id', ids).select(), + ); + + if (broadcasts.length > 0) + if (!this.isSQLite) { + await this.db('broadcast_user_status') + .insert( + broadcasts.map(b => ({ + broadcast_id: b.id, + user, + read, + saved, + })), + ) + .onConflict(['broadcast_id', 'user']) + .merge(['read', 'saved']); + } else { + // SQLite does not support upsert so fall back to this (mostly for tests and local dev) + for (const b of broadcasts) { + const baseQuery = this.db('broadcast_user_status') + .where('broadcast_id', b.id) + .where('user', user); + const exists = await baseQuery.clone().limit(1).select().first(); + if (exists) { + await baseQuery.clone().update({ read, saved }); + } else { + await baseQuery + .clone() + .insert({ broadcast_id: b.id, user, read, saved }); + } + } + } + }; + async markRead(options: NotificationModifyOptions): Promise { - const notificationQuery = this.getNotificationsBaseQuery(options); - await notificationQuery.update({ read: new Date() }); + await this.markReadSaved(options.ids, options.user, new Date(), undefined); } async markUnread(options: NotificationModifyOptions): Promise { - const notificationQuery = this.getNotificationsBaseQuery(options); - await notificationQuery.update({ read: null }); - } - - async markDone(options: NotificationModifyOptions): Promise { - const notificationQuery = this.getNotificationsBaseQuery(options); - await notificationQuery.update({ done: new Date(), read: new Date() }); - } - - async markUndone(options: NotificationModifyOptions): Promise { - const notificationQuery = this.getNotificationsBaseQuery(options); - await notificationQuery.update({ done: null, read: null }); + await this.markReadSaved(options.ids, options.user, null, undefined); } async markSaved(options: NotificationModifyOptions): Promise { - const notificationQuery = this.getNotificationsBaseQuery(options); - await notificationQuery.update({ saved: new Date() }); + await this.markReadSaved(options.ids, options.user, undefined, new Date()); } async markUnsaved(options: NotificationModifyOptions): Promise { - const notificationQuery = this.getNotificationsBaseQuery(options); - await notificationQuery.update({ saved: null }); + await this.markReadSaved(options.ids, options.user, undefined, null); } } diff --git a/plugins/notifications-backend/src/database/NotificationsStore.ts b/plugins/notifications-backend/src/database/NotificationsStore.ts index 4e3a2fa547..901ea1695d 100644 --- a/plugins/notifications-backend/src/database/NotificationsStore.ts +++ b/plugins/notifications-backend/src/database/NotificationsStore.ts @@ -16,20 +16,29 @@ import { Notification, + NotificationSeverity, NotificationStatus, - NotificationType, } from '@backstage/plugin-notifications-common'; +/** @internal */ +export type EntityOrder = { + field: string; + order: 'asc' | 'desc'; +}; + +// TODO: reuse the common part of the type with front-end /** @internal */ export type NotificationGetOptions = { user: string; ids?: string[]; - type?: NotificationType; offset?: number; limit?: number; search?: string; - sort?: 'created' | 'read' | 'updated' | null; - sortOrder?: 'asc' | 'desc'; + orderField?: EntityOrder[]; + read?: boolean; + saved?: boolean; + createdAfter?: Date; + minimumSeverity?: NotificationSeverity; }; /** @internal */ @@ -40,15 +49,23 @@ export type NotificationModifyOptions = { /** @internal */ export interface NotificationsStore { getNotifications(options: NotificationGetOptions): Promise; + getNotificationsCount(options: NotificationGetOptions): Promise; saveNotification(notification: Notification): Promise; + saveBroadcast(notification: Notification): Promise; + getExistingScopeNotification(options: { user: string; scope: string; origin: string; }): Promise; + getExistingScopeBroadcast(options: { + scope: string; + origin: string; + }): Promise; + restoreExistingNotification(options: { id: string; notification: Notification; @@ -62,10 +79,6 @@ export interface NotificationsStore { markUnread(options: NotificationModifyOptions): Promise; - markDone(options: NotificationModifyOptions): Promise; - - markUndone(options: NotificationModifyOptions): Promise; - markSaved(options: NotificationModifyOptions): Promise; markUnsaved(options: NotificationModifyOptions): Promise; diff --git a/plugins/notifications-backend/src/plugin.ts b/plugins/notifications-backend/src/plugin.ts index 1d8806cf49..c0344fb06f 100644 --- a/plugins/notifications-backend/src/plugin.ts +++ b/plugins/notifications-backend/src/plugin.ts @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; import { createRouter } from './service/router'; -import { signalService } from '@backstage/plugin-signals-node'; +import { signalsServiceRef } from '@backstage/plugin-signals-node'; import { NotificationProcessor, notificationsProcessingExtensionPoint, @@ -58,34 +59,41 @@ export const notificationsPlugin = createBackendPlugin({ env.registerInit({ deps: { + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + userInfo: coreServices.userInfo, httpRouter: coreServices.httpRouter, logger: coreServices.logger, - identity: coreServices.identity, database: coreServices.database, - tokenManager: coreServices.tokenManager, discovery: coreServices.discovery, - signals: signalService, + signals: signalsServiceRef, }, async init({ + auth, + httpAuth, + userInfo, httpRouter, logger, - identity, database, - tokenManager, discovery, signals, }) { httpRouter.use( await createRouter({ + auth, + httpAuth, + userInfo, logger, - identity, database, - tokenManager, discovery, - signalService: signals, + signals, processors: processingExtensions.processors, }), ); + httpRouter.addAuthPolicy({ + path: '/health', + allow: 'unauthenticated', + }); }, }); }, diff --git a/plugins/notifications-backend/src/run.ts b/plugins/notifications-backend/src/run.ts deleted file mode 100644 index d299ed23e9..0000000000 --- a/plugins/notifications-backend/src/run.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { getRootLogger } from '@backstage/backend-common'; -import yn from 'yn'; -import { startStandaloneServer } from './service/standaloneServer'; - -const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; -const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); -const logger = getRootLogger(); - -startStandaloneServer({ port, enableCors, logger }).catch(err => { - logger.error(err); - process.exit(1); -}); - -process.on('SIGINT', () => { - logger.info('CTRL+C pressed; exiting.'); - process.exit(0); -}); diff --git a/plugins/notifications-backend/src/service/parseEntityOrderFieldParams.test.ts b/plugins/notifications-backend/src/service/parseEntityOrderFieldParams.test.ts new file mode 100644 index 0000000000..1d494df0ca --- /dev/null +++ b/plugins/notifications-backend/src/service/parseEntityOrderFieldParams.test.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams'; + +describe('parseEntityOrderFieldParams', () => { + it('supports no order fields', () => { + const result = parseEntityOrderFieldParams({}); + expect(result).toEqual(undefined); + }); + + it('supports single orderField', () => { + const result = parseEntityOrderFieldParams({ + orderField: ['metadata.name,desc'], + })!; + expect(result).toEqual([{ field: 'metadata.name', order: 'desc' }]); + }); + + it('supports single orderField without order', () => { + const result = parseEntityOrderFieldParams({ + orderField: ['metadata.name'], + })!; + expect(result).toEqual([{ field: 'metadata.name' }]); + }); + + it('supports multiple order fields', () => { + const result = parseEntityOrderFieldParams({ + orderField: ['metadata.name,desc', 'metadata.uid,asc'], + }); + + expect(result).toEqual([ + { field: 'metadata.name', order: 'desc' }, + { field: 'metadata.uid', order: 'asc' }, + ]); + }); + + it('throws if orderField order is not valid', () => { + expect(() => + parseEntityOrderFieldParams({ + orderField: ['metadata.name,desc', 'metadata.uid,invalid'], + }), + ).toThrow(/Invalid order field order/); + }); +}); diff --git a/plugins/notifications-backend/src/service/parseEntityOrderFieldParams.ts b/plugins/notifications-backend/src/service/parseEntityOrderFieldParams.ts new file mode 100644 index 0000000000..913e04993c --- /dev/null +++ b/plugins/notifications-backend/src/service/parseEntityOrderFieldParams.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file is based on the plugins/catalog-backend + +import { InputError } from '@backstage/errors'; +import { EntityOrder } from '../database'; + +/** + * Takes a single unknown parameter and makes sure that it's a single string or + * an array of strings, and returns as an array. + */ +export function parseStringsParam( + param: unknown, + ctx: string, +): string[] | undefined { + if (param === undefined) { + return undefined; + } + + const array = [param].flat(); + if (array.some(p => typeof p !== 'string')) { + throw new InputError(`Invalid ${ctx}, not a string`); + } + + return array as string[]; +} + +export function parseEntityOrderFieldParams( + params: Record, +): EntityOrder[] | undefined { + const orderFieldStrings = parseStringsParam(params.orderField, 'orderField'); + if (!orderFieldStrings) { + return undefined; + } + + return orderFieldStrings.map(orderFieldString => { + const [field, order] = orderFieldString.split(','); + + if (order !== undefined && !isOrder(order)) { + throw new InputError('Invalid order field order, must be asc or desc'); + } + return { field, order }; + }); +} + +export function isOrder(order: string): order is 'asc' | 'desc' { + return ['asc', 'desc'].includes(order); +} diff --git a/plugins/notifications-backend/src/service/router.test.ts b/plugins/notifications-backend/src/service/router.test.ts index 3152b1b07f..3f091bac4b 100644 --- a/plugins/notifications-backend/src/service/router.test.ts +++ b/plugins/notifications-backend/src/service/router.test.ts @@ -17,16 +17,14 @@ import { DatabaseManager, getVoidLogger, PluginDatabaseManager, - PluginEndpointDiscovery, - TokenManager, } from '@backstage/backend-common'; import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; -import { IdentityApi } from '@backstage/plugin-auth-node'; import { ConfigReader } from '@backstage/config'; -import { SignalService } from '@backstage/plugin-signals-node'; +import { SignalsService } from '@backstage/plugin-signals-node'; +import { mockServices } from '@backstage/backend-test-utils'; function createDatabase(): PluginDatabaseManager { return DatabaseManager.fromConfig( @@ -44,40 +42,24 @@ function createDatabase(): PluginDatabaseManager { describe('createRouter', () => { let app: express.Express; - const identityMock: IdentityApi = { - async getIdentity() { - return { - identity: { - type: 'user', - ownershipEntityRefs: [], - userEntityRef: 'user:default/guest', - }, - token: 'no-token', - }; - }, - }; - const mockedTokenManager: jest.Mocked = { - getToken: jest.fn(), - authenticate: jest.fn(), - }; - - const discovery: jest.Mocked = { - getBaseUrl: jest.fn(), - getExternalBaseUrl: jest.fn(), - }; - - const signalService: jest.Mocked = { + const signalService: jest.Mocked = { publish: jest.fn(), }; + const discovery = mockServices.discovery(); + const userInfo = mockServices.userInfo(); + const httpAuth = mockServices.httpAuth(); + const auth = mockServices.auth(); + beforeAll(async () => { const router = await createRouter({ logger: getVoidLogger(), - identity: identityMock, database: createDatabase(), - tokenManager: mockedTokenManager, discovery, - signalService, + signals: signalService, + userInfo, + httpAuth, + auth, }); app = express().use(router); }); diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index 6c745e158e..585b1ad104 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -13,19 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - errorHandler, - PluginDatabaseManager, - TokenManager, -} from '@backstage/backend-common'; +import { errorHandler, PluginDatabaseManager } from '@backstage/backend-common'; import express, { Request } from 'express'; import Router from 'express-promise-router'; -import { - getBearerTokenFromAuthorizationHeader, - IdentityApi, -} from '@backstage/plugin-auth-node'; import { DatabaseNotificationsStore, + normalizeSeverity, NotificationGetOptions, } from '../database'; import { v4 as uuid } from 'uuid'; @@ -35,27 +28,40 @@ import { isGroupEntity, isUserEntity, RELATION_HAS_MEMBER, + RELATION_OWNED_BY, + RELATION_PARENT_OF, stringifyEntityRef, } from '@backstage/catalog-model'; -import { NotificationProcessor } from '@backstage/plugin-notifications-node'; -import { AuthenticationError, InputError } from '@backstage/errors'; -import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api'; -import { SignalService } from '@backstage/plugin-signals-node'; +import { + NotificationProcessor, + NotificationSendOptions, +} from '@backstage/plugin-notifications-node'; +import { InputError } from '@backstage/errors'; +import { + AuthService, + DiscoveryService, + HttpAuthService, + LoggerService, + UserInfoService, +} from '@backstage/backend-plugin-api'; +import { SignalsService } from '@backstage/plugin-signals-node'; import { NewNotificationSignal, Notification, NotificationReadSignal, - NotificationType, + NotificationStatus, } from '@backstage/plugin-notifications-common'; +import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams'; /** @internal */ export interface RouterOptions { logger: LoggerService; - identity: IdentityApi; database: PluginDatabaseManager; - tokenManager: TokenManager; discovery: DiscoveryService; - signalService?: SignalService; + auth: AuthService; + httpAuth: HttpAuthService; + userInfo: UserInfoService; + signals?: SignalsService; catalog?: CatalogApi; processors?: NotificationProcessor[]; } @@ -67,12 +73,13 @@ export async function createRouter( const { logger, database, - identity, + auth, + httpAuth, + userInfo, discovery, catalog, - tokenManager, - processors, - signalService, + processors = [], + signals, } = options; const catalogClient = @@ -80,59 +87,64 @@ export async function createRouter( const store = await DatabaseNotificationsStore.create({ database }); const getUser = async (req: Request) => { - const user = await identity.getIdentity({ request: req }); - if (!user) { - throw new AuthenticationError(); - } - return user.identity.userEntityRef; - }; - - const authenticateService = async (req: Request) => { - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); - if (!token) { - throw new AuthenticationError(); - } - await tokenManager.authenticate(token); + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); + const info = await userInfo.getUserInfo(credentials); + return info.userEntityRef; }; const getUsersForEntityRef = async ( entityRef: string | string[] | null, + excludeEntityRefs: string | string[], ): Promise => { - const { token } = await tokenManager.getToken(); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); - // TODO: Support for broadcast if (entityRef === null) { return []; } + const fields = ['kind', 'metadata.name', 'metadata.namespace', 'relations']; + const refs = Array.isArray(entityRef) ? entityRef : [entityRef]; const entities = await catalogClient.getEntitiesByRefs( { entityRefs: refs, - fields: ['kind', 'metadata.name', 'metadata.namespace'], + fields, }, { token }, ); + + const excluded = Array.isArray(excludeEntityRefs) + ? excludeEntityRefs + : [excludeEntityRefs]; + const mapEntity = async (entity: Entity | undefined): Promise => { if (!entity) { return []; } + const currentEntityRef = stringifyEntityRef(entity); + if (excluded.includes(currentEntityRef)) { + return []; + } + if (isUserEntity(entity)) { - return [stringifyEntityRef(entity)]; + return [currentEntityRef]; } else if (isGroupEntity(entity) && entity.relations) { const users = entity.relations - .filter( - relation => - relation.type === RELATION_HAS_MEMBER && relation.targetRef, - ) + .filter(relation => relation.type === RELATION_HAS_MEMBER) .map(r => r.targetRef); + + const childGroupRefs = entity.relations + .filter(relation => relation.type === RELATION_PARENT_OF) + .map(r => r.targetRef); + const childGroups = await catalogClient.getEntitiesByRefs( { - entityRefs: entity.spec.children, - fields: ['kind', 'metadata.name', 'metadata.namespace'], + entityRefs: childGroupRefs, + fields, }, { token }, ); @@ -140,13 +152,16 @@ export async function createRouter( childGroups.items.map(mapEntity), ); return [...users, ...childGroupUsers.flat(2)]; - } else if (!isGroupEntity(entity) && entity.spec?.owner) { - const owner = await catalogClient.getEntityByRef( - entity.spec.owner as string, - { token }, - ); - if (owner) { - return mapEntity(owner); + } else if (entity.relations) { + const ownerRef = entity.relations.find( + relation => relation.type === RELATION_OWNED_BY, + )?.targetRef; + + if (ownerRef) { + const owner = await catalogClient.getEntityByRef(ownerRef, { token }); + if (owner) { + return mapEntity(owner); + } } } @@ -158,21 +173,58 @@ export async function createRouter( const u = await mapEntity(entity); users.push(...u); } + return users; }; - const decorateNotification = async (notification: Notification) => { - let ret: Notification = notification; - for (const processor of processors ?? []) { - ret = processor.decorate ? await processor.decorate(ret) : ret; + const processOptions = async (opts: NotificationSendOptions) => { + let ret = opts; + for (const processor of processors) { + try { + ret = processor.processOptions + ? await processor.processOptions(ret) + : ret; + } catch (e) { + logger.error( + `Error while processing notification options with ${processor.getName()}: ${e}`, + ); + } } return ret; }; - const processorSendNotification = async (notification: Notification) => { - for (const processor of processors ?? []) { - if (processor.send) { - processor.send(notification); + const preProcessNotification = async ( + notification: Notification, + opts: NotificationSendOptions, + ) => { + let ret = notification; + for (const processor of processors) { + try { + ret = processor.preProcess + ? await processor.preProcess(ret, opts) + : ret; + } catch (e) { + logger.error( + `Error while pre processing notification with ${processor.getName()}: ${e}`, + ); + } + } + return ret; + }; + + const postProcessNotification = async ( + notification: Notification, + opts: NotificationSendOptions, + ) => { + for (const processor of processors) { + if (processor.postProcess) { + try { + await processor.postProcess(notification, opts); + } catch (e) { + logger.error( + `Error while post processing notification with ${processor.getName()}: ${e}`, + ); + } } } }; @@ -191,23 +243,60 @@ export async function createRouter( const opts: NotificationGetOptions = { user: user, }; - if (req.query.type) { - opts.type = req.query.type.toString() as NotificationType; - } if (req.query.offset) { opts.offset = Number.parseInt(req.query.offset.toString(), 10); } if (req.query.limit) { opts.limit = Number.parseInt(req.query.limit.toString(), 10); } + if (req.query.orderField) { + opts.orderField = parseEntityOrderFieldParams(req.query); + } if (req.query.search) { opts.search = req.query.search.toString(); } + if (req.query.read === 'true') { + opts.read = true; + } else if (req.query.read === 'false') { + opts.read = false; + // or keep undefined + } + if (req.query.saved === 'true') { + opts.saved = true; + } else if (req.query.saved === 'false') { + opts.saved = false; + // or keep undefined + } + if (req.query.createdAfter) { + const sinceEpoch = Date.parse(String(req.query.createdAfter)); + if (isNaN(sinceEpoch)) { + throw new InputError('Unexpected date format'); + } + opts.createdAfter = new Date(sinceEpoch); + } + if (req.query.minimumSeverity) { + opts.minimumSeverity = normalizeSeverity( + req.query.minimumSeverity.toString(), + ); + } - const notifications = await store.getNotifications(opts); - res.send(notifications); + const [notifications, totalCount] = await Promise.all([ + store.getNotifications(opts), + store.getNotificationsCount(opts), + ]); + res.send({ + totalCount, + notifications, + }); }); + router.get('/status', async (req: Request, res) => { + const user = await getUser(req); + const status = await store.getStatus({ user }); + res.send(status); + }); + + // Make sure this is the last "GET" handler router.get('/:id', async (req, res) => { const user = await getUser(req); const opts: NotificationGetOptions = { @@ -223,12 +312,6 @@ export async function createRouter( res.send(notifications[0]); }); - router.get('/status', async (req, res) => { - const user = await getUser(req); - const status = await store.getStatus({ user, type: 'undone' }); - res.send(status); - }); - router.post('/update', async (req, res) => { const user = await getUser(req); const { ids, read, saved } = req.body; @@ -239,9 +322,9 @@ export async function createRouter( if (read === true) { await store.markRead({ user, ids }); - if (signalService) { - await signalService.publish({ - recipients: [user], + if (signals) { + await signals.publish({ + recipients: { type: 'user', entityRef: [user] }, message: { action: 'notification_read', notification_ids: ids }, channel: 'notifications', }); @@ -249,9 +332,9 @@ export async function createRouter( } else if (read === false) { await store.markUnread({ user: user, ids }); - if (signalService) { - await signalService.publish({ - recipients: [user], + if (signals) { + await signals.publish({ + recipients: { type: 'user', entityRef: [user] }, message: { action: 'notification_unread', notification_ids: ids }, channel: 'notifications', }); @@ -268,48 +351,62 @@ export async function createRouter( res.status(200).send(notifications); }); - // Add new notification - // Allowed only for service-to-service authentication, uses `getUsersForEntityRef` to retrieve recipients for - // specific entity reference - router.post('/', async (req, res) => { - const { recipients, origin, payload } = req.body; - const notifications = []; - let users = []; - - try { - await authenticateService(req); - } catch (e) { - throw new AuthenticationError(); - } - - const { title, link, scope } = payload; - - if (!recipients || !title || !origin || !link) { - logger.error(`Invalid notification request received`); - throw new InputError(); - } - - let entityRef = null; - // TODO: Support for broadcast notifications - if (recipients.entityRef && recipients.type === 'entity') { - entityRef = recipients.entityRef; - } - - try { - users = await getUsersForEntityRef(entityRef); - } catch (e) { - throw new InputError(); - } - - const baseNotification: Omit = { - payload: { - ...payload, - severity: payload.severity ?? 'normal', - }, - origin, - created: new Date(), + const sendBroadcastNotification = async ( + baseNotification: Omit, + opts: NotificationSendOptions, + origin: string, + ) => { + const { scope } = opts.payload; + const broadcastNotification = { + ...baseNotification, + user: null, + id: uuid(), }; + const notification = await preProcessNotification( + broadcastNotification, + opts, + ); + let existingNotification; + if (scope) { + existingNotification = await store.getExistingScopeBroadcast({ + scope, + origin, + }); + } + let ret = notification; + if (existingNotification) { + const restored = await store.restoreExistingNotification({ + id: existingNotification.id, + notification: { ...notification, user: '' }, + }); + ret = restored ?? notification; + } else { + await store.saveBroadcast(notification); + } + + if (signals) { + await signals.publish({ + recipients: { type: 'broadcast' }, + message: { + action: 'new_notification', + notification_id: ret.id, + }, + channel: 'notifications', + }); + postProcessNotification(ret, opts); + } + return notification; + }; + + const sendUserNotifications = async ( + baseNotification: Omit, + users: string[], + opts: NotificationSendOptions, + origin: string, + ) => { + const notifications = []; + const { scope } = opts.payload; const uniqueUsers = [...new Set(users)]; for (const user of uniqueUsers) { const userNotification = { @@ -317,7 +414,7 @@ export async function createRouter( id: uuid(), user, }; - const notification = await decorateNotification(userNotification); + const notification = await preProcessNotification(userNotification, opts); let existingNotification; if (scope) { @@ -339,12 +436,11 @@ export async function createRouter( await store.saveNotification(notification); } - processorSendNotification(ret); notifications.push(ret); - if (signalService) { - await signalService.publish({ - recipients: user, + if (signals) { + await signals.publish({ + recipients: { type: 'user', entityRef: [user] }, message: { action: 'new_notification', notification_id: ret.id, @@ -352,10 +448,73 @@ export async function createRouter( channel: 'notifications', }); } + postProcessNotification(ret, opts); } + return notifications; + }; - res.json(notifications); - }); + // Add new notification + router.post( + '/', + async (req: Request, res) => { + const opts = await processOptions(req.body); + const { recipients, payload } = opts; + const notifications: Notification[] = []; + let users = []; + + const credentials = await httpAuth.credentials(req, { + allow: ['service'], + }); + + const { title } = payload; + + if (!recipients || !title) { + logger.error(`Invalid notification request received`); + throw new InputError(`Invalid notification request received`); + } + + const origin = credentials.principal.subject; + const baseNotification = { + payload: { + ...payload, + severity: payload.severity ?? 'normal', + }, + origin, + created: new Date(), + }; + + if (recipients.type === 'broadcast') { + const broadcast = await sendBroadcastNotification( + baseNotification, + opts, + origin, + ); + notifications.push(broadcast); + } else { + const entityRef = recipients.entityRef; + + try { + users = await getUsersForEntityRef( + entityRef, + recipients.excludeEntityRef ?? [], + ); + } catch (e) { + logger.error(`Failed to resolve notification receivers: ${e}`); + throw new InputError('Failed to resolve notification receivers', e); + } + + const userNotifications = await sendUserNotifications( + baseNotification, + users, + opts, + origin, + ); + notifications.push(...userNotifications); + } + + res.json(notifications); + }, + ); router.use(errorHandler()); return router; diff --git a/plugins/notifications-backend/src/service/standaloneServer.ts b/plugins/notifications-backend/src/service/standaloneServer.ts deleted file mode 100644 index e2841543b1..0000000000 --- a/plugins/notifications-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - createServiceBuilder, - HostDiscovery, - loadBackendConfig, - PluginDatabaseManager, - ServerTokenManager, -} from '@backstage/backend-common'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; -import Knex from 'knex'; -import { IdentityApi } from '@backstage/plugin-auth-node'; -import { Request } from 'express'; -import { - CatalogApi, - CatalogRequestOptions, - GetEntitiesByRefsRequest, -} from '@backstage/catalog-client'; -import { DefaultSignalService } from '@backstage/plugin-signals-node'; -import { - EventBroker, - EventParams, - EventSubscriber, -} from '@backstage/plugin-events-node'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'notifications-backend' }); - logger.debug('Starting application server...'); - - const config = await loadBackendConfig({ logger, argv: process.argv }); - const db = Knex(config.get('backend.database')); - - const tokenManager = ServerTokenManager.fromConfig(config, { - logger, - }); - const discovery = HostDiscovery.fromConfig(config); - - const dbMock: PluginDatabaseManager = { - async getClient() { - return db; - }, - }; - - const catalogApi = { - async getEntitiesByRefs( - _request: GetEntitiesByRefsRequest, - __options?: CatalogRequestOptions, - ) { - return { - items: [ - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'User', - metadata: { name: 'user', namespace: 'default' }, - spec: {}, - }, - ], - }; - }, - } as Partial as CatalogApi; - - const identityMock: IdentityApi = { - async getIdentity({ request }: { request: Request }) { - const token = request.headers.authorization?.split(' ')[1]; - return { - identity: { - type: 'user', - ownershipEntityRefs: [], - userEntityRef: 'user:default/guest', - }, - token: token || 'no-token', - }; - }, - }; - - const mockSubscribers: EventSubscriber[] = []; - const eventBroker: EventBroker = { - async publish(params: EventParams): Promise { - mockSubscribers.forEach(sub => sub.onEvent(params)); - }, - subscribe(...subscribers: EventSubscriber[]) { - subscribers.flat().forEach(subscriber => { - mockSubscribers.push(subscriber); - }); - }, - }; - - const signalService = DefaultSignalService.create({ eventBroker }); - - const router = await createRouter({ - logger, - identity: identityMock, - database: dbMock, - catalog: catalogApi, - discovery, - tokenManager, - signalService, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/notifications', router); - if (options.enableCors) { - service = service.enableCors({ origin: 'http://localhost:3000' }); - } - - return await service.start().catch(err => { - logger.error(err); - process.exit(1); - }); -} - -module.hot?.accept(); diff --git a/plugins/notifications-common/CHANGELOG.md b/plugins/notifications-common/CHANGELOG.md index d26ed7f589..571f253c34 100644 --- a/plugins/notifications-common/CHANGELOG.md +++ b/plugins/notifications-common/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-notifications-common +## 0.0.3 + +### Patch Changes + +- 0d99528: Notification processor functions are now renamed to `preProcess` and `postProcess`. + Additionally, processor name is now required to be returned by `getName`. + A new processor functionality `processOptions` was added to process options before sending the notification. +- e003e0e: The ordered list of notifications' severities is exported by notifications-common for reusability. + +## 0.0.2 + +### Patch Changes + +- ba14c0e: Support for broadcast notifications +- a790a3d: Move notification origin resolving to backend with new auth +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +## 0.0.2-next.1 + +### Patch Changes + +- a790a3d: Move notification origin resolving to backend with new auth + +## 0.0.2-next.0 + +### Patch Changes + +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +## 0.0.1 + +### Patch Changes + +- 9873c44: Add support for signal type in notifications +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage + ## 0.0.1-next.1 ### Patch Changes diff --git a/plugins/notifications-common/api-report.md b/plugins/notifications-common/api-report.md index 6f40c76e58..3ddce24393 100644 --- a/plugins/notifications-common/api-report.md +++ b/plugins/notifications-common/api-report.md @@ -12,11 +12,10 @@ export type NewNotificationSignal = { // @public (undocumented) type Notification_2 = { id: string; - user: string; + user: string | null; created: Date; saved?: Date; read?: Date; - done?: Date; updated?: Date; origin: string; payload: NotificationPayload; @@ -27,8 +26,8 @@ export { Notification_2 as Notification }; export type NotificationPayload = { title: string; description?: string; - link: string; - severity: NotificationSeverity; + link?: string; + severity?: NotificationSeverity; topic?: string; scope?: string; icon?: string; @@ -40,6 +39,9 @@ export type NotificationReadSignal = { notification_ids: string[]; }; +// @public +export const notificationSeverities: NotificationSeverity[]; + // @public (undocumented) export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; @@ -51,7 +53,4 @@ export type NotificationStatus = { unread: number; read: number; }; - -// @public (undocumented) -export type NotificationType = 'undone' | 'done' | 'saved'; ``` diff --git a/plugins/notifications-common/package.json b/plugins/notifications-common/package.json index 0213a46690..2745230a4a 100644 --- a/plugins/notifications-common/package.json +++ b/plugins/notifications-common/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-notifications-common", + "version": "0.0.3", "description": "Common functionalities for the notifications plugin", - "version": "0.0.1-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -16,25 +16,25 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/notifications-common" }, - "backstage": { - "role": "common-library" - }, + "license": "Apache-2.0", "sideEffects": false, - "scripts": { - "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" - }, - "devDependencies": { - "@backstage/cli": "workspace:^" - }, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" + }, "dependencies": { "@material-ui/icons": "^4.9.1" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" } } diff --git a/plugins/notifications-common/src/constants.ts b/plugins/notifications-common/src/constants.ts new file mode 100644 index 0000000000..3c0610737c --- /dev/null +++ b/plugins/notifications-common/src/constants.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { NotificationSeverity } from './types'; + +/** Ordered list of severities used by the Notifications. + * + * @public */ +export const notificationSeverities: NotificationSeverity[] = [ + 'critical', + 'high', + 'normal', + 'low', +]; diff --git a/plugins/notifications-common/src/index.ts b/plugins/notifications-common/src/index.ts index 8d9f26f07a..7d74c75be8 100644 --- a/plugins/notifications-common/src/index.ts +++ b/plugins/notifications-common/src/index.ts @@ -21,3 +21,4 @@ */ export * from './types'; +export * from './constants'; diff --git a/plugins/notifications-common/src/types.ts b/plugins/notifications-common/src/types.ts index 4d71004265..b9c9f63489 100644 --- a/plugins/notifications-common/src/types.ts +++ b/plugins/notifications-common/src/types.ts @@ -14,41 +14,91 @@ * limitations under the License. */ -/** @public */ -export type NotificationType = 'undone' | 'done' | 'saved'; - /** @public */ export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; /** @public */ export type NotificationPayload = { + /** + * Notification title + */ title: string; + /** + * Optional longer description for the notification + */ description?: string; - link: string; + /** + * Optional link where the notification is pointing to + */ + link?: string; // TODO: Add support for additional links // additionalLinks?: string[]; - severity: NotificationSeverity; + /** + * Notification severity, defaults to 'normal' + */ + severity?: NotificationSeverity; + /** + * Optional notification topic + */ topic?: string; + /** + * Notification scope, can be used to re-send same notifications in case + * the scope and origin matches. + */ scope?: string; + /** + * Optional notification icon + */ icon?: string; }; /** @public */ export type Notification = { + /** + * Unique identifier for the notification + */ id: string; - user: string; + /** + * The user entity reference that the notification is targeted to or null + * for broadcast notifications + */ + user: string | null; + /** + * Notification creation date + */ created: Date; + /** + * If user has saved the notification, the date when it was saved + */ saved?: Date; + /** + * If user has read the notification, the date when it was read + */ read?: Date; - done?: Date; + /** + * If the notification has been updated due to it being in the same scope + * and from same origin as previous notification, the date when it was updated + */ updated?: Date; + /** + * Origin of the notification as in the reference to sender + */ origin: string; + /** + * Actual notification payload + */ payload: NotificationPayload; }; /** @public */ export type NotificationStatus = { + /** + * Total number of unread notifications for the user + */ unread: number; + /** + * Total number of read notifications for the user + */ read: number; }; diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index d540dcda27..867ea0a79f 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,157 @@ # @backstage/plugin-notifications-node +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## 0.1.3 + +### Patch Changes + +- 0d99528: Notification processor functions are now renamed to `preProcess` and `postProcess`. + Additionally, processor name is now required to be returned by `getName`. + A new processor functionality `processOptions` was added to process options before sending the notification. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/catalog-model@1.4.5 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-node@0.1.3-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.2 + - @backstage/backend-common@0.21.5 + - @backstage/plugin-signals-node@0.1.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.0 + +### Minor Changes + +- 84af361: Migrated to using the new auth services. + +### Patch Changes + +- ba14c0e: Support for broadcast notifications +- a790a3d: Move notification origin resolving to backend with new auth +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + +## 0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.1 + +## 0.1.0-next.1 + +### Patch Changes + +- a790a3d: Move notification origin resolving to backend with new auth +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## 0.1.0-next.0 + +### Minor Changes + +- 84af361: Migrated to using the new auth services. + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## 0.0.1 + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/plugin-notifications-common@0.0.1 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + ## 0.0.1-next.1 ### Patch Changes diff --git a/plugins/notifications-node/api-report.md b/plugins/notifications-node/api-report.md index 75a0fb68fd..1914b562d1 100644 --- a/plugins/notifications-node/api-report.md +++ b/plugins/notifications-node/api-report.md @@ -3,36 +3,49 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { Notification as Notification_2 } from '@backstage/plugin-notifications-common'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; import { ServiceRef } from '@backstage/backend-plugin-api'; -import { TokenManager } from '@backstage/backend-common'; // @public (undocumented) export class DefaultNotificationService implements NotificationService { // (undocumented) - static create({ - tokenManager, - discovery, - pluginId, - }: NotificationServiceOptions): DefaultNotificationService; + static create( + options: NotificationServiceOptions, + ): DefaultNotificationService; // (undocumented) send(notification: NotificationSendOptions): Promise; } -// @public (undocumented) +// @public export interface NotificationProcessor { - decorate?(notification: Notification_2): Promise; - send?(notification: Notification_2): Promise; + getName(): string; + postProcess?( + notification: Notification_2, + options: NotificationSendOptions, + ): Promise; + preProcess?( + notification: Notification_2, + options: NotificationSendOptions, + ): Promise; + processOptions?( + options: NotificationSendOptions, + ): Promise; } // @public (undocumented) -export type NotificationRecipients = { - type: 'entity'; - entityRef: string | string[]; -}; +export type NotificationRecipients = + | { + type: 'entity'; + entityRef: string | string[]; + excludeEntityRef?: string | string[]; + } + | { + type: 'broadcast'; + }; // @public (undocumented) export type NotificationSendOptions = { @@ -51,9 +64,8 @@ export const notificationService: ServiceRef; // @public (undocumented) export type NotificationServiceOptions = { + auth: AuthService; discovery: DiscoveryService; - tokenManager: TokenManager; - pluginId: string; }; // @public (undocumented) diff --git a/plugins/notifications-node/knip-report.md b/plugins/notifications-node/knip-report.md index 1206fc9c3b..ab82a40e51 100644 --- a/plugins/notifications-node/knip-report.md +++ b/plugins/notifications-node/knip-report.md @@ -1,10 +1,11 @@ # Knip report -## Unused dependencies (5) +## Unused dependencies (6) | Name | Location | Severity | | :----------------------------- | :----------- | :------- | | @backstage/plugin-signals-node | package.json | error | +| @backstage/backend-common | package.json | error | | @backstage/catalog-client | package.json | error | | @backstage/catalog-model | package.json | error | | knex | package.json | error | diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index 5eaa07a886..9d72b695a3 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-notifications-node", + "version": "0.1.4-next.0", "description": "Node.js library for the notifications plugin", - "version": "0.0.1-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", @@ -15,25 +15,20 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/notifications-node" }, - "backstage": { - "role": "node-library" - }, - "scripts": { - "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" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/test-utils": "workspace:^", - "msw": "^1.0.0" - }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" + }, "dependencies": { "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", @@ -42,6 +37,12 @@ "@backstage/plugin-notifications-common": "workspace:^", "@backstage/plugin-signals-node": "workspace:^", "knex": "^3.0.0", - "uuid": "^8.0.0" + "uuid": "^9.0.0" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/test-utils": "workspace:^", + "msw": "^1.0.0" } } diff --git a/plugins/notifications-node/src/extensions.ts b/plugins/notifications-node/src/extensions.ts index f8ab26462d..6461c3dc89 100644 --- a/plugins/notifications-node/src/extensions.ts +++ b/plugins/notifications-node/src/extensions.ts @@ -15,25 +15,81 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { Notification } from '@backstage/plugin-notifications-common'; +import { NotificationSendOptions } from './service'; /** + * Notification processors are used to modify the notification parameters or sending the notifications + * to external systems. + * + * Notification modules should utilize the `notificationsProcessingExtensionPoint` to add new processors + * to the system. + * + * Notification processing flow: + * + * 1. New notification send request is received + * 2. For all notification processors registered, processOptions function is called to process the notification options + * 3. Notification recipients are resolved from the options + * 4. For each recipient, preProcess function is called to pre-process the notification + * 5. Notification is saved to the database and sent to the Backstage UI + * 6. For each recipient, postProcess function is called to post-process the notification + * * @public */ export interface NotificationProcessor { /** - * Decorate notification before sending it - * - * @param notification - The notification to decorate - * @returns The same notification or a modified version of it + * Human-readable name of this processor like Email, Slack, etc. */ - decorate?(notification: Notification): Promise; + getName(): string; /** - * Send notification using this processor. + * Process the notification options. + * + * Can be used to override the default recipient resolving, sending the notification to an + * external service or modify other notification options necessary. + * + * processOptions functions are called only once for each notification before the recipient resolving, + * pre-process, sending and post-process of the notification. + * + * @param options - The original options to send the notification + */ + processOptions?( + options: NotificationSendOptions, + ): Promise; + + /** + * Pre-process notification before sending it to Backstage UI. + * + * Can be used to send the notification to external services or to decorate the notification with additional + * information. The notification is saved to database and sent to Backstage UI after all pre-process functions + * have run. The notification options passed here are already processed by processOptions functionality. + * + * preProcess functions are called for each notification recipient individually or once for broadcast + * notification BEFORE the notification has been sent to the Backstage UI. * * @param notification - The notification to send + * @param options - The options to send the notification + * @returns The same notification or a modified version of it */ - send?(notification: Notification): Promise; + preProcess?( + notification: Notification, + options: NotificationSendOptions, + ): Promise; + + /** + * Post process notification after sending it to Backstage UI. + * + * Can be used to send the notification to external services. + * + * postProcess functions are called for each notification recipient individually or once for + * broadcast notification AFTER the notification has been sent to the Backstage UI. + * + * @param notification - The notification to send + * @param options - The options to send the notification + */ + postProcess?( + notification: Notification, + options: NotificationSendOptions, + ): Promise; } /** diff --git a/plugins/notifications-node/src/lib.ts b/plugins/notifications-node/src/lib.ts index c79d871ff8..3e0095f72c 100644 --- a/plugins/notifications-node/src/lib.ts +++ b/plugins/notifications-node/src/lib.ts @@ -29,15 +29,13 @@ export const notificationService = createServiceRef({ createServiceFactory({ service, deps: { + auth: coreServices.auth, discovery: coreServices.discovery, - tokenManager: coreServices.tokenManager, - pluginMetadata: coreServices.pluginMetadata, }, - factory({ discovery, tokenManager, pluginMetadata }) { + factory({ auth, discovery }) { return DefaultNotificationService.create({ + auth, discovery, - tokenManager, - pluginId: pluginMetadata.getId(), }); }, }), diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts index a9b204ca7f..4711f3de18 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.test.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.test.ts @@ -22,6 +22,7 @@ import { DefaultNotificationService, NotificationSendOptions, } from './DefaultNotificationService'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; const server = setupServer(); @@ -33,22 +34,14 @@ const testNotification: NotificationPayload = { describe('DefaultNotificationService', () => { setupRequestMockHandlers(server); - const mockBaseUrl = 'http://backstage/api/notifications'; - const discoveryApi = { - getBaseUrl: async () => mockBaseUrl, - getExternalBaseUrl: async () => mockBaseUrl, - }; - const tokenManager = { - getToken: async () => ({ token: '1234' }), - authenticate: jest.fn(), - }; + const discovery = mockServices.discovery(); + const auth = mockServices.auth(); let service: DefaultNotificationService; - beforeEach(() => { + beforeEach(async () => { service = DefaultNotificationService.create({ - discovery: discoveryApi, - tokenManager, - pluginId: 'test', + auth, + discovery, }); }); @@ -60,14 +53,22 @@ describe('DefaultNotificationService', () => { }; server.use( - rest.post(`${mockBaseUrl}/`, async (req, res, ctx) => { - const json = await req.json(); - expect(json).toEqual({ ...body, origin: 'plugin-test' }); - expect(req.headers.get('Authorization')).toEqual('Bearer 1234'); - return res(ctx.status(200)); - }), + rest.post( + `${await discovery.getBaseUrl('notifications')}/`, + async (req, res, ctx) => { + const json = await req.json(); + expect(json).toEqual(body); + expect(req.headers.get('Authorization')).toBe( + mockCredentials.service.header({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'notifications', + }), + ); + return res(ctx.status(200)); + }, + ), ); - await expect(service.send(body)).resolves.not.toThrow(); + await expect(service.send(body)).resolves.toBeUndefined(); }); it('should throw error if failing', async () => { @@ -77,14 +78,24 @@ describe('DefaultNotificationService', () => { }; server.use( - rest.post(`${mockBaseUrl}/`, async (req, res, ctx) => { - const json = await req.json(); - expect(json).toEqual({ ...body, origin: 'plugin-test' }); - expect(req.headers.get('Authorization')).toEqual('Bearer 1234'); - return res(ctx.status(400)); - }), + rest.post( + `${await discovery.getBaseUrl('notifications')}/`, + async (req, res, ctx) => { + const json = await req.json(); + expect(json).toEqual(body); + expect(req.headers.get('Authorization')).toBe( + mockCredentials.service.header({ + onBehalfOf: await auth.getOwnServiceCredentials(), + targetPluginId: 'notifications', + }), + ); + return res(ctx.status(400)); + }, + ), + ); + await expect(service.send(body)).rejects.toThrow( + 'Request failed with status 400', ); - await expect(service.send(body)).rejects.toThrow(); }); }); }); diff --git a/plugins/notifications-node/src/service/DefaultNotificationService.ts b/plugins/notifications-node/src/service/DefaultNotificationService.ts index 7e5cf58f53..950f42ae83 100644 --- a/plugins/notifications-node/src/service/DefaultNotificationService.ts +++ b/plugins/notifications-node/src/service/DefaultNotificationService.ts @@ -13,26 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { TokenManager } from '@backstage/backend-common'; + import { NotificationService } from './NotificationService'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api'; import { NotificationPayload } from '@backstage/plugin-notifications-common'; /** @public */ export type NotificationServiceOptions = { + auth: AuthService; discovery: DiscoveryService; - tokenManager: TokenManager; - pluginId: string; }; /** @public */ -export type NotificationRecipients = { - type: 'entity'; - entityRef: string | string[]; -}; - -// TODO: Support for broadcast messages -// | { type: 'broadcast' }; +export type NotificationRecipients = + | { + type: 'entity'; + /** + * Entity references to send the notifications to + */ + entityRef: string | string[]; + /** + * Optional entity reference(s) to filter out of the resolved recipients. + * Usually the currently logged-in user for preventing sending notification + * of user action to him/herself. + */ + excludeEntityRef?: string | string[]; + } + | { type: 'broadcast' }; /** @public */ export type NotificationSendOptions = { @@ -44,29 +51,26 @@ export type NotificationSendOptions = { export class DefaultNotificationService implements NotificationService { private constructor( private readonly discovery: DiscoveryService, - private readonly tokenManager: TokenManager, - private readonly pluginId: string, + private readonly auth: AuthService, ) {} - static create({ - tokenManager, - discovery, - pluginId, - }: NotificationServiceOptions): DefaultNotificationService { - return new DefaultNotificationService(discovery, tokenManager, pluginId); + static create( + options: NotificationServiceOptions, + ): DefaultNotificationService { + return new DefaultNotificationService(options.discovery, options.auth); } async send(notification: NotificationSendOptions): Promise { try { const baseUrl = await this.discovery.getBaseUrl('notifications'); - const { token } = await this.tokenManager.getToken(); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'notifications', + }); + const response = await fetch(`${baseUrl}/`, { method: 'POST', - body: JSON.stringify({ - ...notification, - // TODO: Should retrieve this in the backend from service auth instead - origin: `plugin-${this.pluginId}`, - }), + body: JSON.stringify(notification), headers: { 'Content-Type': 'application/json', Accept: 'application/json', diff --git a/plugins/notifications/.eslintrc.js b/plugins/notifications/.eslintrc.js index e2a53a6ad2..a2d8179106 100644 --- a/plugins/notifications/.eslintrc.js +++ b/plugins/notifications/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index 4efd6134f5..eb0e44064e 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,196 @@ # @backstage/plugin-notifications +## 0.2.1-next.0 + +### Patch Changes + +- e6bf85f: Allow overriding `NotificationsPage` page properties +- a42a19b: Empty descriptions are not rendered to improve the look&feel. +- 1bc3b86: Fix to show web notifications even when browser is on foreground. Fix duplicate notifications with multiple tabs. +- f793112: Allow defining `className` and additional properties for `NotificationsSideBarItem` +- e1c7d6e: Fix infinite loop in the notification title counter +- fcda449: The rendered size of a notification is limited for very long descriptions. +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/plugin-signals-react@0.0.3 + +## 0.2.0 + +### Minor Changes + +- 939b4ec: Notifications-backend URL query parameter changed from `minimal_severity` to `minimumSeverity`. +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- 939b4ec: The severity icons now get their colors from the theme. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-signals-react@0.0.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.0-next.1 + +### Minor Changes + +- ec40998: On the Notifications page, the user can trigger "Save" or "Mark as read" actions once for multiple selected notifications. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-signals-react@0.0.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-react@0.0.2 + +## 0.1.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 6a2fe4b: Added ESLint rule `no-top-level-material-ui-4-imports` in the `notifications` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-react@0.0.2 + +## 0.1.1 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 6a2fe4b: Added ESLint rule `no-top-level-material-ui-4-imports` in the `notifications` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/plugin-signals-react@0.0.2 + +## 0.1.0 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options +- cd96173: Notifications-backend URL query parameters changed from `sort/sortOrder` to `orderField` and `created_after` to `createdAfter` to unify with other plugins. +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- dff7a7e: All notifications can be marked and filtered by severity critical, high, normal or low, the default is 'normal' +- 75f2d84: the user can newly mark notifications as "Saved" for their better visibility in the future +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.2 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## 0.1.0-next.2 + +### Minor Changes + +- 6e6d096: notifications can be newly sorted by list of predefined options + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## 0.1.0-next.1 + +### Minor Changes + +- 07abfe1: The NotificationsPage newly uses pagination implemented on the backend layer to avoid large dataset transfers + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-notifications-common@0.0.2-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## 0.1.0-next.0 + +### Minor Changes + +- 758f2a4: The Notifications frontend has been redesigned towards list view with condensed row details. The 'done' attribute has been removed to keep the Notifications aligned with the idea of a messaging system instead of a task manager. + +### Patch Changes + +- 5d9c5ba: The Notifications can be newly filtered based on the Created Date. +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-notifications-common@0.0.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.0 + +## 0.0.1 + +### Patch Changes + +- 9873c44: Add support for signal type in notifications +- 8472188: Added or fixed the `repository` field in `package.json`. +- fb8fc24: Initial notifications system for backstage +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-signals-react@0.0.1 + - @backstage/plugin-notifications-common@0.0.1 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.0.1-next.1 ### Patch Changes diff --git a/plugins/notifications/api-report.md b/plugins/notifications/api-report.md index 0f5d7a0049..9ffcf0d727 100644 --- a/plugins/notifications/api-report.md +++ b/plugins/notifications/api-report.md @@ -9,19 +9,32 @@ 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 { IconComponent } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react'; import { Notification as Notification_2 } from '@backstage/plugin-notifications-common'; +import { NotificationSeverity } from '@backstage/plugin-notifications-common'; import { NotificationStatus } from '@backstage/plugin-notifications-common'; -import { NotificationType } from '@backstage/plugin-notifications-common'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; +import { TableProps } from '@backstage/core-components'; // @public (undocumented) export type GetNotificationsOptions = { - type?: NotificationType; offset?: number; limit?: number; search?: string; + read?: boolean; + saved?: boolean; + createdAfter?: Date; + sort?: 'created' | 'topic' | 'origin'; + sortOrder?: 'asc' | 'desc'; + minimumSeverity?: NotificationSeverity; +}; + +// @public (undocumented) +export type GetNotificationsResponse = { + notifications: Notification_2[]; + totalCount: number; }; // @public (undocumented) @@ -31,7 +44,7 @@ export interface NotificationsApi { // (undocumented) getNotifications( options?: GetNotificationsOptions, - ): Promise; + ): Promise; // (undocumented) getStatus(): Promise; // (undocumented) @@ -51,7 +64,7 @@ export class NotificationsClient implements NotificationsApi { // (undocumented) getNotifications( options?: GetNotificationsOptions, - ): Promise; + ): Promise; // (undocumented) getStatus(): Promise; // (undocumented) @@ -61,7 +74,19 @@ export class NotificationsClient implements NotificationsApi { } // @public (undocumented) -export const NotificationsPage: () => JSX_2.Element; +export const NotificationsPage: ( + props?: NotificationsPageProps | undefined, +) => JSX_2.Element; + +// @public (undocumented) +export type NotificationsPageProps = { + title?: string; + themeId?: string; + subtitle?: string; + tooltip?: string; + type?: string; + typeLink?: string; +}; // @public (undocumented) export const notificationsPlugin: BackstagePlugin< @@ -75,19 +100,42 @@ export const notificationsPlugin: BackstagePlugin< export const NotificationsSidebarItem: (props?: { webNotificationsEnabled?: boolean; titleCounterEnabled?: boolean; + snackbarEnabled?: boolean; + className?: string; + icon?: IconComponent; + text?: string; + disableHighlight?: boolean; + noTrack?: boolean; }) => React_2.JSX.Element; // @public (undocumented) -export const NotificationsTable: (props: { - onUpdate: () => void; - type: NotificationType; +export const NotificationsTable: ({ + isLoading, + notifications, + onUpdate, + setContainsText, + onPageChange, + onRowsPerPageChange, + page, + pageSize, + totalCount, +}: NotificationsTableProps) => React_2.JSX.Element; + +// @public (undocumented) +export type NotificationsTableProps = Pick< + TableProps, + 'onPageChange' | 'onRowsPerPageChange' | 'page' | 'totalCount' +> & { + isLoading?: boolean; notifications?: Notification_2[]; -}) => React_2.JSX.Element; + onUpdate: () => void; + setContainsText: (search: string) => void; + pageSize: number; +}; // @public (undocumented) export type UpdateNotificationsOptions = { ids: string[]; - done?: boolean; read?: boolean; saved?: boolean; }; @@ -128,8 +176,9 @@ export function useTitleCounter(): { }; // @public (undocumented) -export function useWebNotifications(): { +export function useWebNotifications(enabled: boolean): { sendWebNotification: (options: { + id: string; title: string; description: string; link?: string; diff --git a/plugins/notifications/dev/index.tsx b/plugins/notifications/dev/index.tsx index f4ea31f4ab..a21170aec0 100644 --- a/plugins/notifications/dev/index.tsx +++ b/plugins/notifications/dev/index.tsx @@ -15,13 +15,24 @@ */ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { notificationsPlugin } from '../src/plugin'; +import { + NotificationsPage, + notificationsPlugin, + NotificationsSidebarItem, +} from '../src'; +import { signalsPlugin } from '@backstage/plugin-signals'; createDevApp() .registerPlugin(notificationsPlugin) + .registerPlugin(signalsPlugin) .addPage({ - element:
, - title: 'Root Page', + element: ( + + ), path: '/notifications', }) + .addSidebarItem() .render(); diff --git a/plugins/notifications/knip-report.md b/plugins/notifications/knip-report.md index a3ac626d40..0dd3947f6a 100644 --- a/plugins/notifications/knip-report.md +++ b/plugins/notifications/knip-report.md @@ -1,9 +1,10 @@ # Knip report -## Unused dependencies (1) +## Unused dependencies (2) | Name | Location | Severity | | :--------------- | :----------- | :------- | +| @backstage/types | package.json | error | | @material-ui/lab | package.json | error | ## Unused devDependencies (3) diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index 2bd5dee4f4..9832871023 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-notifications", - "version": "0.0.1-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "0.2.1-next.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,18 +14,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/notifications" }, - "backstage": { - "role": "frontend-plugin" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -39,24 +42,24 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", "@types/react": "^16.13.1 || ^17.0.0", + "lodash": "^4.17.21", + "notistack": "^3.0.1", "react-relative-time": "^0.0.9", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/dev-utils": "workspace:^", + "@backstage/plugin-signals": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/notifications/src/api/NotificationsApi.ts b/plugins/notifications/src/api/NotificationsApi.ts index 266c8a1ee5..234e86ff13 100644 --- a/plugins/notifications/src/api/NotificationsApi.ts +++ b/plugins/notifications/src/api/NotificationsApi.ts @@ -16,8 +16,8 @@ import { createApiRef } from '@backstage/core-plugin-api'; import { Notification, + NotificationSeverity, NotificationStatus, - NotificationType, } from '@backstage/plugin-notifications-common'; /** @public */ @@ -27,23 +27,35 @@ export const notificationsApiRef = createApiRef({ /** @public */ export type GetNotificationsOptions = { - type?: NotificationType; offset?: number; limit?: number; search?: string; + read?: boolean; + saved?: boolean; + createdAfter?: Date; + sort?: 'created' | 'topic' | 'origin'; + sortOrder?: 'asc' | 'desc'; + minimumSeverity?: NotificationSeverity; }; /** @public */ export type UpdateNotificationsOptions = { ids: string[]; - done?: boolean; read?: boolean; saved?: boolean; }; +/** @public */ +export type GetNotificationsResponse = { + notifications: Notification[]; + totalCount: number; +}; + /** @public */ export interface NotificationsApi { - getNotifications(options?: GetNotificationsOptions): Promise; + getNotifications( + options?: GetNotificationsOptions, + ): Promise; getNotification(id: string): Promise; diff --git a/plugins/notifications/src/api/NotificationsClient.test.ts b/plugins/notifications/src/api/NotificationsClient.test.ts index 1312b99cf4..e9acd04fc9 100644 --- a/plugins/notifications/src/api/NotificationsClient.test.ts +++ b/plugins/notifications/src/api/NotificationsClient.test.ts @@ -60,16 +60,31 @@ describe('NotificationsClient', () => { server.use( rest.get(`${mockBaseUrl}/`, (req, res, ctx) => { expect(req.url.search).toBe( - '?type=undone&limit=10&offset=0&search=find+me', + '?limit=10&offset=0&search=find+me&read=true&createdAfter=1970-01-01T00%3A00%3A00.005Z', ); return res(ctx.json(expectedResp)); }), ); const response = await client.getNotifications({ - type: 'undone', limit: 10, offset: 0, search: 'find me', + read: true, + createdAfter: new Date(5), + }); + expect(response).toEqual(expectedResp); + }); + + it('should omit unselected fetch options', async () => { + server.use( + rest.get(`${mockBaseUrl}/`, (req, res, ctx) => { + expect(req.url.search).toBe('?limit=10'); + return res(ctx.json(expectedResp)); + }), + ); + const response = await client.getNotifications({ + limit: 10, + // do not put more options here }); expect(response).toEqual(expectedResp); }); @@ -103,14 +118,12 @@ describe('NotificationsClient', () => { rest.post(`${mockBaseUrl}/update`, async (req, res, ctx) => { expect(await req.json()).toEqual({ ids: ['acdaa8ca-262b-43c1-b74b-de06e5f3b3c7'], - done: true, }); return res(ctx.json(expectedResp)); }), ); const response = await client.updateNotifications({ ids: ['acdaa8ca-262b-43c1-b74b-de06e5f3b3c7'], - done: true, }); expect(response).toEqual(expectedResp); }); diff --git a/plugins/notifications/src/api/NotificationsClient.ts b/plugins/notifications/src/api/NotificationsClient.ts index 9ef7b287ab..10ad58bd92 100644 --- a/plugins/notifications/src/api/NotificationsClient.ts +++ b/plugins/notifications/src/api/NotificationsClient.ts @@ -15,6 +15,7 @@ */ import { GetNotificationsOptions, + GetNotificationsResponse, NotificationsApi, UpdateNotificationsOptions, } from './NotificationsApi'; @@ -40,24 +41,38 @@ export class NotificationsClient implements NotificationsApi { async getNotifications( options?: GetNotificationsOptions, - ): Promise { + ): Promise { const queryString = new URLSearchParams(); - if (options?.type) { - queryString.append('type', options.type); - } if (options?.limit !== undefined) { queryString.append('limit', options.limit.toString(10)); } if (options?.offset !== undefined) { queryString.append('offset', options.offset.toString(10)); } + if (options?.sort !== undefined) { + queryString.append( + 'orderField', + `${options.sort},${options?.sortOrder ?? 'desc'}`, + ); + } if (options?.search) { queryString.append('search', options.search); } - + if (options?.read !== undefined) { + queryString.append('read', options.read ? 'true' : 'false'); + } + if (options?.saved !== undefined) { + queryString.append('saved', options.saved ? 'true' : 'false'); + } + if (options?.createdAfter !== undefined) { + queryString.append('createdAfter', options.createdAfter.toISOString()); + } + if (options?.minimumSeverity !== undefined) { + queryString.append('minimumSeverity', options.minimumSeverity); + } const urlSegment = `?${queryString}`; - return await this.request(urlSegment); + return await this.request(urlSegment); } async getNotification(id: string): Promise { diff --git a/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx b/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx new file mode 100644 index 0000000000..3175af6f6f --- /dev/null +++ b/plugins/notifications/src/components/NotificationsFilters/NotificationsFilters.tsx @@ -0,0 +1,271 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; + +import Divider from '@material-ui/core/Divider'; +import FormControl from '@material-ui/core/FormControl'; +import Grid from '@material-ui/core/Grid'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; +import Typography from '@material-ui/core/Typography'; +import { GetNotificationsOptions } from '../../api'; +import { NotificationSeverity } from '@backstage/plugin-notifications-common'; + +export type SortBy = Required< + Pick +>; + +export type NotificationsFiltersProps = { + unreadOnly?: boolean; + onUnreadOnlyChanged: (checked: boolean | undefined) => void; + createdAfter?: string; + onCreatedAfterChanged: (value: string) => void; + sorting: SortBy; + onSortingChanged: (sortBy: SortBy) => void; + saved?: boolean; + onSavedChanged: (checked: boolean | undefined) => void; + severity: NotificationSeverity; + onSeverityChanged: (severity: NotificationSeverity) => void; +}; + +export const CreatedAfterOptions: { + [key: string]: { label: string; getDate: () => Date }; +} = { + last24h: { + label: 'Last 24h', + getDate: () => new Date(Date.now() - 24 * 3600 * 1000), + }, + lastWeek: { + label: 'Last week', + getDate: () => new Date(Date.now() - 7 * 24 * 3600 * 1000), + }, + all: { + label: 'Any time', + getDate: () => new Date(0), + }, +}; + +export const SortByOptions: { + [key: string]: { + label: string; + sortBy: SortBy; + }; +} = { + newest: { + label: 'Newest on top', + sortBy: { + sort: 'created', + sortOrder: 'desc', + }, + }, + oldest: { + label: 'Oldest on top', + sortBy: { + sort: 'created', + sortOrder: 'asc', + }, + }, + topic: { + label: 'Topic', + sortBy: { + sort: 'topic', + sortOrder: 'asc', + }, + }, + origin: { + label: 'Origin', + sortBy: { + sort: 'origin', + sortOrder: 'asc', + }, + }, +}; + +const getSortByText = (sortBy?: SortBy): string => { + if (sortBy?.sort === 'created' && sortBy?.sortOrder === 'asc') { + return 'oldest'; + } + if (sortBy?.sort === 'topic') { + return 'topic'; + } + if (sortBy?.sort === 'origin') { + return 'origin'; + } + + return 'newest'; +}; + +const AllSeverityOptions: { [key in NotificationSeverity]: string } = { + critical: 'Critical', + high: 'High', + normal: 'Normal', + low: 'Low', +}; + +export const NotificationsFilters = ({ + sorting, + onSortingChanged, + unreadOnly, + onUnreadOnlyChanged, + createdAfter, + onCreatedAfterChanged, + saved, + onSavedChanged, + severity, + onSeverityChanged, +}: NotificationsFiltersProps) => { + const sortByText = getSortByText(sorting); + + const handleOnCreatedAfterChanged = ( + event: React.ChangeEvent<{ name?: string; value: unknown }>, + ) => { + onCreatedAfterChanged(event.target.value as string); + }; + + const handleOnViewChanged = ( + event: React.ChangeEvent<{ name?: string; value: unknown }>, + ) => { + if (event.target.value === 'unread') { + onUnreadOnlyChanged(true); + onSavedChanged(undefined); + } else if (event.target.value === 'read') { + onUnreadOnlyChanged(false); + onSavedChanged(undefined); + } else if (event.target.value === 'saved') { + onUnreadOnlyChanged(undefined); + onSavedChanged(true); + } else { + // All + onUnreadOnlyChanged(undefined); + onSavedChanged(undefined); + } + }; + + const handleOnSortByChanged = ( + event: React.ChangeEvent<{ name?: string; value: unknown }>, + ) => { + const idx = (event.target.value as string) || 'newest'; + const option = SortByOptions[idx]; + onSortingChanged({ ...option.sortBy }); + }; + + let viewValue = 'all'; + if (saved) { + viewValue = 'saved'; + } else if (unreadOnly) { + viewValue = 'unread'; + } else if (unreadOnly === false) { + viewValue = 'read'; + } + + const handleOnSeverityChanged = ( + event: React.ChangeEvent<{ name?: string; value: unknown }>, + ) => { + const value: NotificationSeverity = + (event.target.value as NotificationSeverity) || 'normal'; + onSeverityChanged(value); + }; + + return ( + <> + + + Filters + + + + + + View + + + + + + + + Created after + + + + + + + + + Sort by + + + + + + + + Severity + + + + + + + ); +}; diff --git a/plugins/notifications/src/components/NotificationsFilters/index.ts b/plugins/notifications/src/components/NotificationsFilters/index.ts new file mode 100644 index 0000000000..196aef61e0 --- /dev/null +++ b/plugins/notifications/src/components/NotificationsFilters/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './NotificationsFilters'; diff --git a/plugins/notifications/src/components/NotificationsPage/NotificationsPage.tsx b/plugins/notifications/src/components/NotificationsPage/NotificationsPage.tsx index 85e0937ca3..539db4f61e 100644 --- a/plugins/notifications/src/components/NotificationsPage/NotificationsPage.tsx +++ b/plugins/notifications/src/components/NotificationsPage/NotificationsPage.tsx @@ -14,95 +14,159 @@ * limitations under the License. */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; +import throttle from 'lodash/throttle'; import { Content, - ErrorPanel, PageWithHeader, + ResponseErrorPanel, } from '@backstage/core-components'; -import { NotificationsTable } from '../NotificationsTable'; -import { useNotificationsApi } from '../../hooks'; -import { Button, Grid, makeStyles } from '@material-ui/core'; -import Bookmark from '@material-ui/icons/Bookmark'; -import Check from '@material-ui/icons/Check'; -import Inbox from '@material-ui/icons/Inbox'; -import { NotificationType } from '@backstage/plugin-notifications-common'; +import Grid from '@material-ui/core/Grid'; import { useSignal } from '@backstage/plugin-signals-react'; -const useStyles = makeStyles(_theme => ({ - filterButton: { - width: '100%', - justifyContent: 'start', - }, -})); +import { NotificationsTable } from '../NotificationsTable'; +import { useNotificationsApi } from '../../hooks'; +import { + CreatedAfterOptions, + NotificationsFilters, + SortBy, + SortByOptions, +} from '../NotificationsFilters'; +import { GetNotificationsOptions } from '../../api'; +import { NotificationSeverity } from '@backstage/plugin-notifications-common'; + +const ThrottleDelayMs = 2000; + +/** @public */ +export type NotificationsPageProps = { + title?: string; + themeId?: string; + subtitle?: string; + tooltip?: string; + type?: string; + typeLink?: string; +}; + +export const NotificationsPage = (props?: NotificationsPageProps) => { + const { + title = 'Notifications', + themeId = 'tool', + subtitle, + tooltip, + type, + typeLink, + } = props ?? {}; -export const NotificationsPage = () => { - const [type, setType] = useState('undone'); const [refresh, setRefresh] = React.useState(false); + const { lastSignal } = useSignal('notifications'); + const [unreadOnly, setUnreadOnly] = React.useState(true); + const [saved, setSaved] = React.useState(undefined); + const [pageNumber, setPageNumber] = React.useState(0); + const [pageSize, setPageSize] = React.useState(5); + const [containsText, setContainsText] = React.useState(); + const [createdAfter, setCreatedAfter] = React.useState('lastWeek'); + const [sorting, setSorting] = React.useState( + SortByOptions.newest.sortBy, + ); + const [severity, setSeverity] = React.useState('low'); - const { error, value, retry } = useNotificationsApi( - api => api.getNotifications({ type }), - [type], + const { error, value, retry, loading } = useNotificationsApi( + api => { + const options: GetNotificationsOptions = { + search: containsText, + limit: pageSize, + offset: pageNumber * pageSize, + minimumSeverity: severity, + ...(sorting || {}), + }; + if (unreadOnly !== undefined) { + options.read = !unreadOnly; + } + if (saved !== undefined) { + options.saved = saved; + } + + const createdAfterDate = CreatedAfterOptions[createdAfter].getDate(); + if (createdAfterDate.valueOf() > 0) { + options.createdAfter = createdAfterDate; + } + + return api.getNotifications(options); + }, + [ + containsText, + unreadOnly, + createdAfter, + pageNumber, + pageSize, + sorting, + saved, + severity, + ], + ); + + const throttledSetRefresh = React.useMemo( + () => throttle(setRefresh, ThrottleDelayMs), + [setRefresh], ); useEffect(() => { - if (refresh) { + if (refresh && !loading) { retry(); setRefresh(false); } - }, [refresh, setRefresh, retry]); + }, [refresh, setRefresh, retry, loading]); - const { lastSignal } = useSignal('notifications'); useEffect(() => { if (lastSignal && lastSignal.action) { - setRefresh(true); + throttledSetRefresh(true); } - }, [lastSignal]); + }, [lastSignal, throttledSetRefresh]); const onUpdate = () => { - setRefresh(true); + throttledSetRefresh(true); }; - const styles = useStyles(); if (error) { - return ; + return ; } return ( - + - - - + diff --git a/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx b/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx index 2163c6660f..000eabcae6 100644 --- a/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx +++ b/plugins/notifications/src/components/NotificationsSideBarItem/NotificationsSideBarItem.tsx @@ -13,38 +13,149 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { useNotificationsApi } from '../../hooks'; -import { SidebarItem } from '@backstage/core-components'; +import { Link, SidebarItem } from '@backstage/core-components'; import NotificationsIcon from '@material-ui/icons/Notifications'; -import { useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { + alertApiRef, + IconComponent, + useApi, + useRouteRef, +} from '@backstage/core-plugin-api'; import { rootRouteRef } from '../../routes'; import { useSignal } from '@backstage/plugin-signals-react'; -import { NotificationSignal } from '@backstage/plugin-notifications-common'; +import { + Notification, + NotificationSignal, +} from '@backstage/plugin-notifications-common'; import { useWebNotifications } from '../../hooks/useWebNotifications'; import { useTitleCounter } from '../../hooks/useTitleCounter'; import { notificationsApiRef } from '../../api'; +import { + closeSnackbar, + enqueueSnackbar, + MaterialDesignContent, + OptionsWithExtraProps, + SnackbarKey, + SnackbarProvider, + VariantType, +} from 'notistack'; +import { SeverityIcon } from '../NotificationsTable/SeverityIcon'; +import OpenInNew from '@material-ui/icons/OpenInNew'; +import MarkAsReadIcon from '@material-ui/icons/CheckCircle'; +import IconButton from '@material-ui/core/IconButton'; +import { styled } from '@material-ui/core/styles'; + +const StyledMaterialDesignContent = styled(MaterialDesignContent)( + ({ theme }) => ({ + '&.notistack-MuiContent-low': { + backgroundColor: theme.palette.background.default, + color: theme.palette.text.primary, + }, + '&.notistack-MuiContent-normal': { + backgroundColor: theme.palette.background.default, + color: theme.palette.text.primary, + }, + '&.notistack-MuiContent-high': { + backgroundColor: theme.palette.background.default, + color: theme.palette.text.primary, + }, + '&.notistack-MuiContent-critical': { + backgroundColor: theme.palette.background.default, + color: theme.palette.text.primary, + }, + }), +); + +declare module 'notistack' { + interface VariantOverrides { + // Custom variants for the snackbar + low: true; + normal: true; + high: true; + critical: true; + } +} /** @public */ export const NotificationsSidebarItem = (props?: { webNotificationsEnabled?: boolean; titleCounterEnabled?: boolean; + snackbarEnabled?: boolean; + className?: string; + icon?: IconComponent; + text?: string; + disableHighlight?: boolean; + noTrack?: boolean; }) => { - const { webNotificationsEnabled = false, titleCounterEnabled = true } = - props ?? { webNotificationsEnabled: false, titleCounterEnabled: true }; + const { + webNotificationsEnabled = false, + titleCounterEnabled = true, + snackbarEnabled = true, + icon = NotificationsIcon, + text = 'Notifications', + ...restProps + } = props ?? { + webNotificationsEnabled: false, + titleCounterEnabled: true, + snackbarEnabled: true, + }; const { loading, error, value, retry } = useNotificationsApi(api => api.getStatus(), ); const notificationsApi = useApi(notificationsApiRef); + const alertApi = useApi(alertApiRef); const [unreadCount, setUnreadCount] = React.useState(0); const notificationsRoute = useRouteRef(rootRouteRef); // TODO: Do we want to add long polling in case signals are not available const { lastSignal } = useSignal('notifications'); - const { sendWebNotification } = useWebNotifications(); + const { sendWebNotification } = useWebNotifications(webNotificationsEnabled); const [refresh, setRefresh] = React.useState(false); const { setNotificationCount } = useTitleCounter(); + const getSnackbarProperties = useCallback( + (notification: Notification) => { + const action = (snackBarId: SnackbarKey) => ( + <> + { + closeSnackbar(snackBarId); + }} + > + + + { + notificationsApi + .updateNotifications({ + ids: [notification.id], + read: true, + }) + .then(() => { + closeSnackbar(snackBarId); + }) + .catch(() => { + alertApi.post({ + message: 'Failed to mark notification as read', + severity: 'error', + }); + }); + }} + > + + + + ); + + return { action }; + }, + [notificationsRoute, notificationsApi, alertApi], + ); + useEffect(() => { if (refresh) { retry(); @@ -53,8 +164,11 @@ export const NotificationsSidebarItem = (props?: { }, [refresh, retry]); useEffect(() => { - const handleWebNotification = (signal: NotificationSignal) => { - if (!webNotificationsEnabled || signal.action !== 'new_notification') { + const handleNotificationSignal = (signal: NotificationSignal) => { + if ( + (!webNotificationsEnabled && !snackbarEnabled) || + signal.action !== 'new_notification' + ) { return; } @@ -64,41 +178,87 @@ export const NotificationsSidebarItem = (props?: { if (!notification) { return; } - sendWebNotification({ - title: notification.payload.title, - description: notification.payload.description ?? '', - link: notification.payload.link, + if (webNotificationsEnabled) { + sendWebNotification({ + id: notification.id, + title: notification.payload.title, + description: notification.payload.description ?? '', + link: notification.payload.link, + }); + } + if (snackbarEnabled) { + const { action } = getSnackbarProperties(notification); + const snackBarText = + notification.payload.title.length > 50 + ? `${notification.payload.title.substring(0, 50)}...` + : notification.payload.title; + enqueueSnackbar(snackBarText, { + variant: notification.payload.severity, + anchorOrigin: { vertical: 'bottom', horizontal: 'right' }, + action, + } as OptionsWithExtraProps); + } + }) + .catch(() => { + alertApi.post({ + message: 'Failed to fetch notification', + severity: 'error', }); }); }; if (lastSignal && lastSignal.action) { - handleWebNotification(lastSignal); + handleNotificationSignal(lastSignal); setRefresh(true); } }, [ lastSignal, sendWebNotification, webNotificationsEnabled, + snackbarEnabled, notificationsApi, + alertApi, + getSnackbarProperties, ]); useEffect(() => { if (!loading && !error && value) { setUnreadCount(value.unread); - if (titleCounterEnabled) { - setNotificationCount(value.unread); - } } - }, [loading, error, value, titleCounterEnabled, setNotificationCount]); + }, [loading, error, value]); + + useEffect(() => { + if (titleCounterEnabled) { + setNotificationCount(unreadCount); + } + }, [titleCounterEnabled, unreadCount, setNotificationCount]); // TODO: Figure out if the count can be added to hasNotifications return ( - + <> + {snackbarEnabled && ( + , + critical: , + high: , + low: , + }} + Components={{ + normal: StyledMaterialDesignContent, + critical: StyledMaterialDesignContent, + high: StyledMaterialDesignContent, + low: StyledMaterialDesignContent, + }} + /> + )} + + ); }; diff --git a/plugins/notifications/src/components/NotificationsTable/BulkActions.tsx b/plugins/notifications/src/components/NotificationsTable/BulkActions.tsx new file mode 100644 index 0000000000..034da7c93c --- /dev/null +++ b/plugins/notifications/src/components/NotificationsTable/BulkActions.tsx @@ -0,0 +1,93 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Notification } from '@backstage/plugin-notifications-common'; +import Grid from '@material-ui/core/Grid'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; +import MarkAsUnreadIcon from '@material-ui/icons/Markunread' /* TODO: use Drafts and MarkAsUnread once we have mui 5 icons */; +import MarkAsReadIcon from '@material-ui/icons/CheckCircle'; +import MarkAsUnsavedIcon from '@material-ui/icons/LabelOff' /* TODO: use BookmarkRemove and BookmarkAdd once we have mui 5 icons */; +import MarkAsSavedIcon from '@material-ui/icons/Label'; + +export const BulkActions = ({ + selectedNotifications, + notifications, + onSwitchReadStatus, + onSwitchSavedStatus, +}: { + selectedNotifications: Set; + notifications: Notification[]; + onSwitchReadStatus: (ids: Notification['id'][], newStatus: boolean) => void; + onSwitchSavedStatus: (ids: Notification['id'][], newStatus: boolean) => void; +}) => { + const isDisabled = selectedNotifications.size === 0; + const bulkNotifications = notifications.filter(notification => + selectedNotifications.has(notification.id), + ); + + const isOneRead = !!bulkNotifications.find( + (notification: Notification) => !!notification.read, + ); + const isOneSaved = !!bulkNotifications.find( + (notification: Notification) => !!notification.saved, + ); + + const markAsReadText = isOneRead + ? 'Return selected among unread' + : 'Mark selected as read'; + const IconComponent = isOneRead ? MarkAsUnreadIcon : MarkAsReadIcon; + + const markAsSavedText = isOneSaved + ? 'Undo save for selected' + : 'Save selected for later'; + const SavedIconComponent = isOneSaved ? MarkAsUnsavedIcon : MarkAsSavedIcon; + + return ( + + + +
+ {/* The
here is a workaround for the Tooltip which does not work for a "disabled" child */} + { + onSwitchSavedStatus([...selectedNotifications], !isOneSaved); + }} + > + + +
+ + + + + +
+ { + onSwitchReadStatus([...selectedNotifications], !isOneRead); + }} + > + + +
+
+
+ + ); +}; diff --git a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx index 8328da1c6d..f1d6e58b51 100644 --- a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx +++ b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx @@ -13,296 +13,246 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect, useState } from 'react'; -import { - Box, - Button, - IconButton, - makeStyles, - Table, - TableBody, - TableCell, - TableHead, - TableRow, - Tooltip, - Typography, -} from '@material-ui/core'; -import { - Notification, - NotificationType, -} from '@backstage/plugin-notifications-common'; -import { useNavigate } from 'react-router-dom'; -import Checkbox from '@material-ui/core/Checkbox'; -import Check from '@material-ui/icons/Check'; -import Bookmark from '@material-ui/icons/Bookmark'; -import { notificationsApiRef } from '../../api'; -import { useApi } from '@backstage/core-plugin-api'; -import Inbox from '@material-ui/icons/Inbox'; -import CloseIcon from '@material-ui/icons/Close'; +import React from 'react'; +import throttle from 'lodash/throttle'; // @ts-ignore import RelativeTime from 'react-relative-time'; -import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; +import Box from '@material-ui/core/Box'; +import Grid from '@material-ui/core/Grid'; +import CheckBox from '@material-ui/core/Checkbox'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; +import { Notification } from '@backstage/plugin-notifications-common'; -const useStyles = makeStyles(theme => ({ - table: { - border: `1px solid ${theme.palette.divider}`, - }, - header: { - borderBottom: `1px solid ${theme.palette.divider}`, - }, +import { notificationsApiRef } from '../../api'; +import { useApi } from '@backstage/core-plugin-api'; +import { + Link, + Table, + TableProps, + TableColumn, +} from '@backstage/core-components'; - notificationRow: { - cursor: 'pointer', - '&.unread': { - border: '1px solid rgba(255, 255, 255, .3)', - }, - '& .hideOnHover': { - display: 'initial', - }, - '& .showOnHover': { - display: 'none', - }, - '&:hover': { - '& .hideOnHover': { - display: 'none', - }, - '& .showOnHover': { - display: 'initial', - }, - }, +import { SeverityIcon } from './SeverityIcon'; +import { SelectAll } from './SelectAll'; +import { BulkActions } from './BulkActions'; + +const ThrottleDelayMs = 1000; + +const useStyles = makeStyles({ + description: { + maxHeight: '5rem', + overflow: 'scroll', }, - actionButton: { - padding: '9px', + severityItem: { + alignContent: 'center', }, - checkBox: { - padding: '0 10px 10px 0', - }, -})); +}); /** @public */ -export const NotificationsTable = (props: { - onUpdate: () => void; - type: NotificationType; +export type NotificationsTableProps = Pick< + TableProps, + 'onPageChange' | 'onRowsPerPageChange' | 'page' | 'totalCount' +> & { + isLoading?: boolean; notifications?: Notification[]; -}) => { - const { notifications, type } = props; - const navigate = useNavigate(); - const styles = useStyles(); - const [selected, setSelected] = useState([]); + onUpdate: () => void; + setContainsText: (search: string) => void; + pageSize: number; +}; + +/** @public */ +export const NotificationsTable = ({ + isLoading, + notifications = [], + onUpdate, + setContainsText, + onPageChange, + onRowsPerPageChange, + page, + pageSize, + totalCount, +}: NotificationsTableProps) => { + const classes = useStyles(); const notificationsApi = useApi(notificationsApiRef); + const [selectedNotifications, setSelectedNotifications] = React.useState( + new Set(), + ); - const onCheckBoxClick = (id: string) => { - const index = selected.indexOf(id); - if (index !== -1) { - setSelected(selected.filter(s => s !== id)); - } else { - setSelected([...selected, id]); - } - }; + const onNotificationsSelectChange = React.useCallback( + (ids: Notification['id'][], checked: boolean) => { + let newSelect: Set; + if (checked) { + newSelect = new Set([...selectedNotifications, ...ids]); + } else { + newSelect = new Set(selectedNotifications); + ids.forEach(id => newSelect.delete(id)); + } + setSelectedNotifications(newSelect); + }, + [selectedNotifications, setSelectedNotifications], + ); - useEffect(() => { - setSelected([]); - }, [type]); + const onSwitchReadStatus = React.useCallback( + (ids: Notification['id'][], newStatus: boolean) => { + notificationsApi + .updateNotifications({ + ids, + read: newStatus, + }) + .then(onUpdate); + }, + [notificationsApi, onUpdate], + ); - const isChecked = (id: string) => { - return selected.indexOf(id) !== -1; - }; + const onSwitchSavedStatus = React.useCallback( + (ids: Notification['id'][], newStatus: boolean) => { + notificationsApi + .updateNotifications({ + ids, + saved: newStatus, + }) + .then(onUpdate); + }, + [notificationsApi, onUpdate], + ); - const isAllSelected = () => { - return ( - selected.length === notifications?.length && notifications.length > 0 + const throttledContainsTextHandler = React.useMemo( + () => throttle(setContainsText, ThrottleDelayMs), + [setContainsText], + ); + + React.useEffect(() => { + const allShownIds = new Set(notifications.map(n => n.id)); + const intersect = [...selectedNotifications].filter(id => + allShownIds.has(id), ); - }; + if (selectedNotifications.size !== intersect.length) { + setSelectedNotifications(new Set(intersect)); + } + }, [notifications, selectedNotifications]); + + const compactColumns = React.useMemo( + (): TableColumn[] => [ + { + /* selection column */ + width: '1rem', + title: ( + + onNotificationsSelectChange( + notifications.map(notification => notification.id), + selectedNotifications.size !== notifications.length, + ) + } + /> + ), + render: (notification: Notification) => ( + + onNotificationsSelectChange([notification.id], checked) + } + /> + ), + }, + { + /* compact-data column */ + customFilterAndSearch: () => + true /* Keep sorting&filtering on backend due to pagination. */, + render: (notification: Notification) => { + // Compact content + return ( + + + + + + + + {notification.payload.link ? ( + + {notification.payload.title} + + ) : ( + notification.payload.title + )} + + {notification.payload.description ? ( + + {notification.payload.description} + + ) : null} + + {notification.origin && ( + <>{notification.origin} •  + )} + {notification.payload.topic && ( + <>{notification.payload.topic} •  + )} + {notification.created && ( + + )} + + + + + ); + }, + }, + { + /* actions column */ + width: '1rem', + title: ( + + ), + render: (notification: Notification) => ( + + ), + }, + ], + [ + selectedNotifications, + notifications, + onSwitchReadStatus, + onSwitchSavedStatus, + onNotificationsSelectChange, + classes.severityItem, + classes.description, + ], + ); return ( -
- - - - {type !== 'saved' && !notifications?.length && 'No notifications'} - {type !== 'saved' && !!notifications?.length && ( - { - if (isAllSelected()) { - setSelected([]); - } else { - setSelected( - notifications ? notifications.map(n => n.id) : [], - ); - } - }} - /> - )} - {type === 'saved' && - `${notifications?.length ?? 0} saved notifications`} - {selected.length === 0 && - !!notifications?.length && - type !== 'saved' && - 'Select all'} - {selected.length > 0 && `${selected.length} selected`} - {type === 'done' && selected.length > 0 && ( - - )} - - {type === 'undone' && selected.length > 0 && ( - - )} - - - - - {props.notifications?.map(notification => { - return ( - - - onCheckBoxClick(notification.id)} - /> - - - notificationsApi - .updateNotifications({ ids: [notification.id], read: true }) - .then(() => navigate(notification.payload.link)) - } - style={{ paddingLeft: 0 }} - > - - {notification.payload.title} - - - {notification.payload.description} - - - - - - - - - - notificationsApi - .updateNotifications({ - ids: [notification.id], - read: true, - }) - .then(() => navigate(notification.payload.link)) - } - > - - - - - { - if (notification.read) { - notificationsApi - .updateNotifications({ - ids: [notification.id], - done: false, - }) - .then(() => { - props.onUpdate(); - }); - } else { - notificationsApi - .updateNotifications({ - ids: [notification.id], - done: true, - }) - .then(() => { - props.onUpdate(); - }); - } - }} - > - {notification.read ? ( - - ) : ( - - )} - - - - { - if (notification.saved) { - notificationsApi - .updateNotifications({ - ids: [notification.id], - saved: false, - }) - .then(() => { - props.onUpdate(); - }); - } else { - notificationsApi - .updateNotifications({ - ids: [notification.id], - saved: true, - }) - .then(() => { - props.onUpdate(); - }); - } - }} - > - {notification.saved ? ( - - ) : ( - - )} - - - - - - ); - })} - -
+ + isLoading={isLoading} + options={{ + padding: 'dense', + search: true, + paging: true, + pageSize, + header: true, + sorting: false, + }} + onPageChange={onPageChange} + onRowsPerPageChange={onRowsPerPageChange} + page={page} + totalCount={totalCount} + onSearchChange={throttledContainsTextHandler} + data={notifications} + columns={compactColumns} + /> ); }; diff --git a/plugins/notifications/src/components/NotificationsTable/SelectAll.tsx b/plugins/notifications/src/components/NotificationsTable/SelectAll.tsx new file mode 100644 index 0000000000..8f604779b7 --- /dev/null +++ b/plugins/notifications/src/components/NotificationsTable/SelectAll.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import Checkbox from '@material-ui/core/Checkbox'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles({ + label: { + marginLeft: '0px', + maxWidth: '2rem', + '& span': { + paddingRight: '0px', + }, + }, +}); + +export const SelectAll = ({ + count, + totalCount, + onSelectAll, +}: { + count: number; + totalCount: number; + onSelectAll: () => void; +}) => { + const classes = useStyles(); + + return ( + 0 ? `(${count})` : undefined} + className={classes.label} + control={ + 0} + indeterminate={count > 0 && totalCount !== count} + onChange={onSelectAll} + /> + } + /> + ); +}; diff --git a/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx b/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx new file mode 100644 index 0000000000..062c2ae5b7 --- /dev/null +++ b/plugins/notifications/src/components/NotificationsTable/SeverityIcon.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { NotificationSeverity } from '@backstage/plugin-notifications-common'; +import NormalIcon from '@material-ui/icons/CheckOutlined'; +import CriticalIcon from '@material-ui/icons/ErrorOutline'; +import HighIcon from '@material-ui/icons/WarningOutlined'; +import LowIcon from '@material-ui/icons/InfoOutlined'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles(theme => ({ + critical: { + color: theme.palette.status.error, + }, + high: { + color: theme.palette.status.warning, + }, + normal: { + color: theme.palette.status.ok, + }, + low: { + color: theme.palette.status.running, + }, +})); + +export const SeverityIcon = ({ + severity, +}: { + severity?: NotificationSeverity; +}) => { + const classes = useStyles(); + + switch (severity) { + case 'critical': + return ; + case 'high': + return ; + case 'low': + return ; + case 'normal': + default: + return ; + } +}; diff --git a/plugins/notifications/src/components/index.ts b/plugins/notifications/src/components/index.ts index 3bca70a215..022ae07198 100644 --- a/plugins/notifications/src/components/index.ts +++ b/plugins/notifications/src/components/index.ts @@ -15,3 +15,4 @@ */ export * from './NotificationsSideBarItem'; export * from './NotificationsTable'; +export type { NotificationsPageProps } from './NotificationsPage'; diff --git a/plugins/notifications/src/hooks/useNotificationsApi.ts b/plugins/notifications/src/hooks/useNotificationsApi.ts index e1afb54c8d..3acc406016 100644 --- a/plugins/notifications/src/hooks/useNotificationsApi.ts +++ b/plugins/notifications/src/hooks/useNotificationsApi.ts @@ -16,7 +16,7 @@ import { NotificationsApi, notificationsApiRef } from '../api'; import { useApi } from '@backstage/core-plugin-api'; -import useAsyncRetry from 'react-use/lib/useAsyncRetry'; +import useAsyncRetry from 'react-use/esm/useAsyncRetry'; /** @public */ export function useNotificationsApi( diff --git a/plugins/notifications/src/hooks/useTitleCounter.ts b/plugins/notifications/src/hooks/useTitleCounter.ts index d4ba22b946..d794678ea6 100644 --- a/plugins/notifications/src/hooks/useTitleCounter.ts +++ b/plugins/notifications/src/hooks/useTitleCounter.ts @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; /** @public */ export function useTitleCounter() { const [title, setTitle] = useState(document.title); const [count, setCount] = useState(0); + const titleTimer = useRef(undefined); const getPrefix = (value: number) => { return value === 0 ? '' : `(${value}) `; @@ -28,28 +29,43 @@ export function useTitleCounter() { return currentTitle.replace(/^\(\d+\)\s/, ''); }; - useEffect(() => { - document.title = title; - }, [title]); - useEffect(() => { const baseTitle = cleanTitle(title); - setTitle(`${getPrefix(count)}${baseTitle}`); + const shownTitle = `${getPrefix(count)}${baseTitle}`; + if (document.title !== shownTitle) { + window.clearTimeout(titleTimer.current); + document.title = shownTitle; + // Need to do this in timeout as the React Helmet overrides the title after this effect + titleTimer.current = window.setTimeout(() => { + document.title = shownTitle; + }, 50); + } return () => { + window.clearTimeout(titleTimer.current); document.title = cleanTitle(title); }; }, [title, count]); - const titleElement = document.querySelector('title'); - if (titleElement) { - new MutationObserver(() => { - setTitle(document.title); - }).observe(titleElement, { - subtree: true, - characterData: true, - childList: true, - }); - } + useEffect(() => { + const titleElement = document.querySelector('title'); + let observer: MutationObserver | undefined; + if (titleElement) { + observer = new MutationObserver(mutations => { + if (mutations?.[0]?.target?.textContent) { + setTitle(mutations[0].target.textContent); + } + }); + observer.observe(titleElement, { + characterData: true, + childList: true, + }); + } + return () => { + if (observer) { + observer.disconnect(); + } + }; + }, []); const setNotificationCount = useCallback( (newCount: number) => setCount(newCount), diff --git a/plugins/notifications/src/hooks/useWebNotifications.ts b/plugins/notifications/src/hooks/useWebNotifications.ts index bf3b5269f5..728d992130 100644 --- a/plugins/notifications/src/hooks/useWebNotifications.ts +++ b/plugins/notifications/src/hooks/useWebNotifications.ts @@ -14,49 +14,58 @@ * limitations under the License. */ import { useCallback, useEffect, useState } from 'react'; +import { rootRouteRef } from '../routes'; +import { useRouteRef } from '@backstage/core-plugin-api'; +import { useNavigate } from 'react-router-dom'; /** @public */ -export function useWebNotifications() { +export function useWebNotifications(enabled: boolean) { const [webNotificationPermission, setWebNotificationPermission] = useState('default'); - const [webNotifications, setWebNotifications] = useState([]); + const notificationsRoute = useRouteRef(rootRouteRef); + const navigate = useNavigate(); useEffect(() => { - if ('Notification' in window && webNotificationPermission === 'default') { + if ( + enabled && + 'Notification' in window && + webNotificationPermission === 'default' + ) { window.Notification.requestPermission().then(permission => { setWebNotificationPermission(permission); }); } - }, [webNotificationPermission]); - - document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') { - webNotifications.forEach(n => n.close()); - setWebNotifications([]); - } - }); + }, [enabled, webNotificationPermission]); const sendWebNotification = useCallback( - (options: { title: string; description: string; link?: string }) => { + (options: { + id: string; + title: string; + description: string; + link?: string; + }) => { if (webNotificationPermission !== 'granted') { return null; } const notification = new Notification(options.title, { body: options.description, + tag: options.id, // Prevent duplicates from multiple tabs }); notification.onclick = event => { event.preventDefault(); - notification.close(); if (options.link) { window.open(options.link, '_blank'); + } else { + navigate(notificationsRoute()); } + notification.close(); }; return notification; }, - [webNotificationPermission], + [webNotificationPermission, navigate, notificationsRoute], ); return { sendWebNotification }; diff --git a/plugins/octopus-deploy/.eslintrc.js b/plugins/octopus-deploy/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/octopus-deploy/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/octopus-deploy/CHANGELOG.md b/plugins/octopus-deploy/CHANGELOG.md deleted file mode 100644 index 6133d000c8..0000000000 --- a/plugins/octopus-deploy/CHANGELOG.md +++ /dev/null @@ -1,595 +0,0 @@ -# @backstage/plugin-octopus-deploy - -## 0.2.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.2.12-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.2.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - -## 0.2.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - -## 0.2.11 - -### Patch Changes - -- 7d96ba8: added install path and fixed import on plugin-octopus-deploy -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - -## 0.2.11-next.2 - -### Patch Changes - -- 7d96ba8: added install path and fixed import on plugin-octopus-deploy -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.2.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - -## 0.2.11-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - -## 0.2.10 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - -## 0.2.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.2.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.2.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.5.0-next.0 - -## 0.2.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.2.8 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4d2f72c572: Added Deep link into Octopus Deploy project from the Release Table. -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - -## 0.2.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.2.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.2.8-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.2.7 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.4.3 - -## 0.2.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/theme@0.4.3-next.0 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.2.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.2.6 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.2.6-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.2.6-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/theme@0.4.1 - -## 0.2.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.2.5-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.2.3 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.2.3-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/catalog-model@1.4.1 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.1-next.0 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.2.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - -## 0.2.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.2.1 - -### Patch Changes - -- 944a8ac6fcc0: Improved getting started documentation -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - -## 0.2.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.2.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.2.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.2.1-next.0 - -### Patch Changes - -- 944a8ac6fcc0: Improved getting started documentation -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.2.0 - -### Minor Changes - -- 87211bc2873: Added support for Octopus Deploy spaces. The octopus.com/project-id annotation can now (optionally) be prefixed by a space identifier, for example. Spaces-1/Projects-102. - Also note that some of this plugins exported API's have changed to accommodate this change, changing from separate arguments to a single object. - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.2.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.2.0-next.1 - -### Minor Changes - -- 87211bc2873: Added support for Octopus Deploy spaces. The octopus.com/project-id annotation can now (optionally) be prefixed by a space identifier, for example. Spaces-1/Projects-102. - Also note that some of this plugins exported API's have changed to accommodate this change, changing from separate arguments to a single object. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/theme@0.2.19 - -## 0.1.1 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.1.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.19-next.0 - -## 0.1.1-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - -## 0.1.1-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.1.0 - -### Minor Changes - -- b7fff1171f0: Initial version - -### Patch Changes - -- cb0fc15a992: Added Octopus Deploy logo -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.1.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.1.0-next.1 - -### Patch Changes - -- cb0fc15a992: Added Octopus Deploy logo -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.1.0-next.0 - -### Minor Changes - -- b7fff1171f: Initial version - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 diff --git a/plugins/octopus-deploy/README.md b/plugins/octopus-deploy/README.md deleted file mode 100644 index ee7d9d8543..0000000000 --- a/plugins/octopus-deploy/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# Octopus Deploy Plugin - -Welcome to the octopus-deploy plugin! - -## Features - -- Display the deployment status of the most recent releases for a project in Octopus Deploy straight from the Backstage catalog - -## Getting started - -### Installing - -To get started, first install the plugin with the following command: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-octopus-deploy -``` - -### Setup - -This plugin (currently) uses the Backstage proxy to securely communicate with the Octopus Deploy API. - -To use it, you will need to generate an [API Key](https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key) within Octopus Deploy. - -1. Add the following to your app-config.yaml to enable the proxy: - -``` -// app-config.yaml -proxy: - '/octopus-deploy': - target: 'https:///api' - headers: - X-Octopus-ApiKey: ${OCTOPUS_API_KEY} -``` - -Optionally, also add the following section to your app-config.yaml if you wish to enable linking to the Project Release page in the Octopus Deploy UI from the footer of the Backstage Release Table. Typically this will be the server URL above without the /api postfix. - -``` -octopusdeploy: - webBaseUrl: "" -``` - -2. Add the following to `EntityPage.tsx` to display Octopus Releases - -``` -// In packages/app/src/components/catalog/EntityPage.tsx -import { - isOctopusDeployAvailable, - EntityOctopusDeployContent -} from '@backstage/plugin-octopus-deploy'; - -const cicdContent = ( - - {/* other components... */} - - - - -) -``` - -3. Add `octopus.com/project-id` annotation in the catalog descriptor file. - -To obtain a projects ID you will have to query the Octopus API. In the future we'll add support for using a projects slug as well. - -``` -// catalog-info.yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - # ... - annotations: - octopus.com/project-id: Projects-102 -spec: - type: service -``` - -If your project is not part of the default space you can add the space ID to the annotation as a prefix. For example: - -``` -// catalog-info.yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - # ... - annotations: - octopus.com/project-id: Spaces-2/Projects-102 -spec: - type: service -``` - -You can get the ID of the space from the URL in the Octopus Deploy UI. - -All set, you will be able to see the plugin in action! diff --git a/plugins/octopus-deploy/api-report.md b/plugins/octopus-deploy/api-report.md deleted file mode 100644 index 094cc0a7b0..0000000000 --- a/plugins/octopus-deploy/api-report.md +++ /dev/null @@ -1,121 +0,0 @@ -## API Report File for "@backstage/plugin-octopus-deploy" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { ConfigApi } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { FetchApi } from '@backstage/core-plugin-api'; -import { JSX as JSX_2 } from 'react'; - -// @public (undocumented) -export const EntityOctopusDeployContent: (props: { - defaultLimit?: number | undefined; -}) => JSX_2.Element; - -// @public (undocumented) -export const isOctopusDeployAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export const OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION = 'octopus.com/project-id'; - -// @public (undocumented) -export interface OctopusDeployApi { - // (undocumented) - getConfig(): Promise; - // (undocumented) - getProjectInfo(projectReference: ProjectReference): Promise; - // (undocumented) - getReleaseProgression(opts: { - projectReference: ProjectReference; - releaseHistoryCount: number; - }): Promise; -} - -// @public (undocumented) -export const octopusDeployApiRef: ApiRef; - -// @public (undocumented) -export class OctopusDeployClient implements OctopusDeployApi { - constructor(options: { - configApi: ConfigApi; - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - proxyPathBase?: string; - }); - // (undocumented) - getConfig(): Promise; - // (undocumented) - getProjectInfo(projectReference: ProjectReference): Promise; - // (undocumented) - getReleaseProgression(opts: { - projectReference: ProjectReference; - releaseHistoryCount: number; - }): Promise; -} - -// @public (undocumented) -export type OctopusDeployment = { - State: string; -}; - -// @public (undocumented) -export const octopusDeployPlugin: BackstagePlugin<{}, {}>; - -// @public (undocumented) -export type OctopusEnvironment = { - Id: string; - Name: string; -}; - -// @public (undocumented) -export type OctopusLinks = { - Self: string; - Web: string; -}; - -// @public (undocumented) -export type OctopusPluginConfig = { - WebUiBaseUrl: string; -}; - -// @public (undocumented) -export type OctopusProgression = { - Environments: OctopusEnvironment[]; - Releases: OctopusReleaseProgression[]; -}; - -// @public (undocumented) -export type OctopusProject = { - Name: string; - Slug: string; - Links: OctopusLinks; -}; - -// @public (undocumented) -export type OctopusRelease = { - Id: string; - Version: string; -}; - -// @public (undocumented) -export type OctopusReleaseProgression = { - Release: OctopusRelease; - Deployments: { - [key: string]: OctopusDeployment[]; - }; -}; - -// @public (undocumented) -export type ProjectReference = { - projectId: string; - spaceId?: string; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/octopus-deploy/catalog-info.yaml b/plugins/octopus-deploy/catalog-info.yaml deleted file mode 100644 index 390b91f6e3..0000000000 --- a/plugins/octopus-deploy/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-octopus-deploy - title: '@backstage/plugin-octopus-deploy' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/octopus-deploy/config.d.ts b/plugins/octopus-deploy/config.d.ts deleted file mode 100644 index 81d14f2921..0000000000 --- a/plugins/octopus-deploy/config.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export interface Config { - octopusdeploy?: { - /** - * Frontend Web UI Base URL for deep links to UI - * @visibility frontend - */ - webBaseUrl?: string; - }; -} diff --git a/plugins/octopus-deploy/dev/index.tsx b/plugins/octopus-deploy/dev/index.tsx deleted file mode 100644 index d3d6cb3215..0000000000 --- a/plugins/octopus-deploy/dev/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { createDevApp } from '@backstage/dev-utils'; -import { octopusDeployPlugin } from '../src/plugin'; -import { EntityPageOctopusDeploy } from '../src/components/EntityPageOctopusDeploy'; - -createDevApp() - .registerPlugin(octopusDeployPlugin) - .addPage({ - element: , - title: 'Root Page', - path: '/octopus-deploy', - }) - .render(); diff --git a/plugins/octopus-deploy/knip-report.md b/plugins/octopus-deploy/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/octopus-deploy/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json deleted file mode 100644 index a4d69197e1..0000000000 --- a/plugins/octopus-deploy/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@backstage/plugin-octopus-deploy", - "version": "0.2.12-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/octopus-deploy" - }, - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.9.13", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/octopus-deploy/src/api/index.ts b/plugins/octopus-deploy/src/api/index.ts deleted file mode 100644 index cb5d428308..0000000000 --- a/plugins/octopus-deploy/src/api/index.ts +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - createApiRef, - DiscoveryApi, - FetchApi, - ConfigApi, -} from '@backstage/core-plugin-api'; -import { ProjectReference } from '../utils/getAnnotationFromEntity'; - -/** @public */ -export type OctopusProgression = { - Environments: OctopusEnvironment[]; - Releases: OctopusReleaseProgression[]; -}; - -/** @public */ -export type OctopusEnvironment = { - Id: string; - Name: string; -}; - -/** @public */ -export type OctopusReleaseProgression = { - Release: OctopusRelease; - Deployments: { [key: string]: OctopusDeployment[] }; -}; - -/** @public */ -export type OctopusRelease = { - Id: string; - Version: string; -}; - -/** @public */ -export type OctopusDeployment = { - State: string; -}; -/** @public */ -export type OctopusLinks = { - Self: string; - Web: string; -}; - -/** @public */ -export type OctopusProject = { - Name: string; - Slug: string; - Links: OctopusLinks; -}; - -/** @public */ -export type OctopusPluginConfig = { - WebUiBaseUrl: string; -}; - -/** @public */ -export const octopusDeployApiRef = createApiRef({ - id: 'plugin.octopusdeploy.service', -}); - -const DEFAULT_PROXY_PATH_BASE = '/octopus-deploy'; -const WEB_UI_BASE_URL_CONFIG_KEY = 'octopusdeploy.webBaseUrl'; - -/** @public */ -export interface OctopusDeployApi { - getReleaseProgression(opts: { - projectReference: ProjectReference; - releaseHistoryCount: number; - }): Promise; - getProjectInfo(projectReference: ProjectReference): Promise; - getConfig(): Promise; -} - -/** @public */ -export class OctopusDeployClient implements OctopusDeployApi { - private readonly configApi: ConfigApi; - private readonly discoveryApi: DiscoveryApi; - private readonly fetchApi: FetchApi; - private readonly proxyPathBase: string; - - constructor(options: { - configApi: ConfigApi; - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - proxyPathBase?: string; - }) { - this.configApi = options.configApi; - this.discoveryApi = options.discoveryApi; - this.fetchApi = options.fetchApi; - this.proxyPathBase = options.proxyPathBase ?? DEFAULT_PROXY_PATH_BASE; - } - - async getReleaseProgression(opts: { - projectReference: ProjectReference; - releaseHistoryCount: number; - }): Promise { - const url = await this.getProgressionApiUrl(opts); - - const response = await this.fetchApi.fetch(url); - - let responseJson; - - try { - responseJson = await response.json(); - } catch (e) { - responseJson = { releases: [] }; - } - - if (response.status !== 200) { - throw new Error( - `Error communicating with Octopus Deploy: ${ - responseJson?.error?.title || response.statusText - }`, - ); - } - - return responseJson; - } - - async getProjectInfo( - projectReference: ProjectReference, - ): Promise { - const url = await this.getProjectApiUrl(projectReference); - const response = await this.fetchApi.fetch(url); - - let responseJson; - - try { - responseJson = await response.json(); - } catch (e) { - responseJson = { releases: [] }; - } - - if (response.status !== 200) { - throw new Error( - `Error communicating with Octopus Deploy: ${ - responseJson?.error?.title || response.statusText - }`, - ); - } - - return responseJson; - } - - async getConfig(): Promise { - return { - WebUiBaseUrl: this.configApi.getString(WEB_UI_BASE_URL_CONFIG_KEY), - }; - } - - private async getProgressionApiUrl(opts: { - projectReference: ProjectReference; - releaseHistoryCount: number; - }) { - const queryParameters = new URLSearchParams({ - releaseHistoryCount: opts.releaseHistoryCount.toString(), - }); - - const projectUrl = await this.getProjectApiUrl(opts.projectReference); - - return `${projectUrl}/progression?${queryParameters}`; - } - - private async getProjectApiUrl(projectReference: ProjectReference) { - const proxyUrl = await this.discoveryApi.getBaseUrl('proxy'); - if (projectReference.spaceId !== undefined) - return `${proxyUrl}${this.proxyPathBase}/${encodeURIComponent( - projectReference.spaceId, - )}/projects/${encodeURIComponent(projectReference.projectId)}`; - return `${proxyUrl}${this.proxyPathBase}/projects/${encodeURIComponent( - projectReference.projectId, - )}`; - } -} diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx deleted file mode 100644 index d9352a414a..0000000000 --- a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { useConfig } from '../../hooks/useConfig'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { useProject } from '../../hooks/useProject'; -import { useReleases } from '../../hooks/useReleases'; -import { getProjectReferenceAnnotationFromEntity } from '../../utils/getAnnotationFromEntity'; -import React from 'react'; -import { ReleaseTable } from '../ReleaseTable'; - -export const EntityPageOctopusDeploy = (props: { defaultLimit?: number }) => { - const { entity } = useEntity(); - - const projectReference = getProjectReferenceAnnotationFromEntity(entity); - - const { environments, releases, loading, error } = useReleases( - projectReference.projectId, - props.defaultLimit ?? 3, - projectReference.spaceId, - ); - - const { - project, - loading: projectLoading, - error: projectError, - } = useProject(projectReference.projectId, projectReference.spaceId); - - const { config, loading: configLoading, error: configError } = useConfig(); - - return ( - - ); -}; diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts deleted file mode 100644 index e168735130..0000000000 --- a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { EntityPageOctopusDeploy } from './EntityPageOctopusDeploy'; diff --git a/plugins/octopus-deploy/src/components/OctopusDeployIcon/OctopusDeployIcon.tsx b/plugins/octopus-deploy/src/components/OctopusDeployIcon/OctopusDeployIcon.tsx deleted file mode 100644 index 626e61ccd8..0000000000 --- a/plugins/octopus-deploy/src/components/OctopusDeployIcon/OctopusDeployIcon.tsx +++ /dev/null @@ -1,31 +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 { SvgIcon, SvgIconProps } from '@material-ui/core'; - -import React from 'react'; - -export const OctopusDeployIcon = (props: SvgIconProps) => ( - - - - - - -); diff --git a/plugins/octopus-deploy/src/components/OctopusDeployIcon/index.ts b/plugins/octopus-deploy/src/components/OctopusDeployIcon/index.ts deleted file mode 100644 index d78e1bfc7f..0000000000 --- a/plugins/octopus-deploy/src/components/OctopusDeployIcon/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { OctopusDeployIcon } from './OctopusDeployIcon'; diff --git a/plugins/octopus-deploy/src/components/ReleaseTable/ReleaseTable.tsx b/plugins/octopus-deploy/src/components/ReleaseTable/ReleaseTable.tsx deleted file mode 100644 index b61b533667..0000000000 --- a/plugins/octopus-deploy/src/components/ReleaseTable/ReleaseTable.tsx +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Box, Typography } from '@material-ui/core'; -import { - OctopusEnvironment, - OctopusProject, - OctopusReleaseProgression, - OctopusPluginConfig, -} from '../../api'; - -import React from 'react'; -import { - BottomLink, - BottomLinkProps, - ResponseErrorPanel, - StatusAborted, - StatusError, - StatusOK, - StatusPending, - StatusRunning, - StatusWarning, - Table, - TableColumn, -} from '@backstage/core-components'; -import { OctopusDeployIcon } from '../OctopusDeployIcon'; - -type ReleaseTableProps = { - environments?: OctopusEnvironment[]; - releases?: OctopusReleaseProgression[]; - project?: OctopusProject; - config?: OctopusPluginConfig; - loading: boolean; - error?: Error; -}; - -export const getDeploymentStatusComponent = (state: string | undefined) => { - switch (state) { - case 'Success': - return ( - - Success - - ); - case 'Queued': - return ( - - Queued - - ); - case 'Executing': - return ( - - Executing - - ); - case 'Failed': - return ( - - Failed - - ); - case 'Cancelling': - return ( - - Cancelling - - ); - case 'Canceled': - return ( - - Canceled - - ); - case 'TimedOut': - return ( - - Timed Out - - ); - default: - return ( - - Unknown - - ); - } -}; - -export const ReleaseTable = ({ - environments, - releases, - project, - config, - loading, - error, -}: ReleaseTableProps) => { - if (error) { - return ; - } - - const columns: TableColumn[] = [ - { - title: 'Version', - field: 'Release.Version', - highlight: false, - width: 'auto', - }, - ...(environments?.map(env => ({ - title: env.Name, - width: 'auto', - render: (row: Partial) => { - const deploymentsForEnvironment = row.Deployments - ? row.Deployments[env.Id] - : null; - if (deploymentsForEnvironment) { - return ( - - - {getDeploymentStatusComponent( - deploymentsForEnvironment[0].State, - )} - - - ); - } - return ; - }, - })) ?? []), - ]; - - const deepLink: BottomLinkProps | null = - project?.Links?.Web && config?.WebUiBaseUrl - ? { - link: `${config.WebUiBaseUrl}${project.Links.Web}`, - title: 'Go to project', - onClick: e => { - e.preventDefault(); - window.open(`${config?.WebUiBaseUrl}${project?.Links.Web}`); - }, - } - : null; - - return ( - - - - - Octopus Deploy - Releases ({releases ? releases.length : 0}) - - } - data={releases ?? []} - /> - {deepLink !== null && } - - ); -}; diff --git a/plugins/octopus-deploy/src/components/ReleaseTable/index.ts b/plugins/octopus-deploy/src/components/ReleaseTable/index.ts deleted file mode 100644 index d0c679a48e..0000000000 --- a/plugins/octopus-deploy/src/components/ReleaseTable/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ReleaseTable } from './ReleaseTable'; diff --git a/plugins/octopus-deploy/src/constants.ts b/plugins/octopus-deploy/src/constants.ts deleted file mode 100644 index 3bdc48252f..0000000000 --- a/plugins/octopus-deploy/src/constants.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** @public */ -export const OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION = 'octopus.com/project-id'; diff --git a/plugins/octopus-deploy/src/hooks/useConfig.ts b/plugins/octopus-deploy/src/hooks/useConfig.ts deleted file mode 100644 index 7218bf1a2c..0000000000 --- a/plugins/octopus-deploy/src/hooks/useConfig.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { octopusDeployApiRef, OctopusPluginConfig } from '../api'; - -export function useConfig(): { - config?: OctopusPluginConfig; - loading: boolean; - error?: Error; -} { - const api = useApi(octopusDeployApiRef); - - const { value, loading, error } = useAsync(() => { - return api.getConfig(); - }, [api]); - - return { - config: value, - loading, - error, - }; -} diff --git a/plugins/octopus-deploy/src/hooks/useProject.ts b/plugins/octopus-deploy/src/hooks/useProject.ts deleted file mode 100644 index f4178fd3e0..0000000000 --- a/plugins/octopus-deploy/src/hooks/useProject.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { octopusDeployApiRef, OctopusProject } from '../api'; - -export function useProject( - projectId: string, - spaceId?: string, -): { - project?: OctopusProject; - loading: boolean; - error?: Error; -} { - const api = useApi(octopusDeployApiRef); - - const { value, loading, error } = useAsync(() => { - return api.getProjectInfo({ projectId: projectId, spaceId: spaceId }); - }, [api, projectId, spaceId]); - - return { - project: value, - loading, - error, - }; -} diff --git a/plugins/octopus-deploy/src/hooks/useReleases.ts b/plugins/octopus-deploy/src/hooks/useReleases.ts deleted file mode 100644 index 671a0a7e7f..0000000000 --- a/plugins/octopus-deploy/src/hooks/useReleases.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { - octopusDeployApiRef, - OctopusEnvironment, - OctopusReleaseProgression, -} from '../api'; - -export function useReleases( - projectId: string, - releaseHistoryCount: number, - spaceId?: string, -): { - environments?: OctopusEnvironment[]; - releases?: OctopusReleaseProgression[]; - loading: boolean; - error?: Error; -} { - const api = useApi(octopusDeployApiRef); - - const { value, loading, error } = useAsync(() => { - return api.getReleaseProgression({ - projectReference: { projectId, spaceId }, - releaseHistoryCount, - }); - }, [api, projectId, spaceId, releaseHistoryCount]); - - return { - environments: value?.Environments, - releases: value?.Releases, - loading, - error, - }; -} diff --git a/plugins/octopus-deploy/src/index.ts b/plugins/octopus-deploy/src/index.ts deleted file mode 100644 index 2b39431606..0000000000 --- a/plugins/octopus-deploy/src/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { - octopusDeployPlugin, - EntityOctopusDeployContent, - isOctopusDeployAvailable, -} from './plugin'; - -export * from './api'; - -export type { ProjectReference } from './utils/getAnnotationFromEntity'; - -export { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from './constants'; diff --git a/plugins/octopus-deploy/src/plugin.test.ts b/plugins/octopus-deploy/src/plugin.test.ts deleted file mode 100644 index a18e74f689..0000000000 --- a/plugins/octopus-deploy/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { octopusDeployPlugin } from './plugin'; - -describe('octopus-deploy', () => { - it('should export plugin', () => { - expect(octopusDeployPlugin).toBeDefined(); - }); -}); diff --git a/plugins/octopus-deploy/src/plugin.ts b/plugins/octopus-deploy/src/plugin.ts deleted file mode 100644 index 39b2b49fb7..0000000000 --- a/plugins/octopus-deploy/src/plugin.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from './constants'; -import { octopusDeployEntityContentRouteRef } from './routes'; - -import { OctopusDeployClient, octopusDeployApiRef } from './api'; - -import { - createApiFactory, - createPlugin, - createRoutableExtension, - discoveryApiRef, - fetchApiRef, - configApiRef, -} from '@backstage/core-plugin-api'; - -import { Entity } from '@backstage/catalog-model'; - -/** @public */ -export const isOctopusDeployAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION]); - -/** @public */ -export const octopusDeployPlugin = createPlugin({ - id: 'octopus-deploy', - apis: [ - createApiFactory({ - api: octopusDeployApiRef, - deps: { - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - configApi: configApiRef, - }, - factory: ({ discoveryApi, fetchApi, configApi }) => - new OctopusDeployClient({ discoveryApi, fetchApi, configApi }), - }), - ], -}); - -/** @public */ -export const EntityOctopusDeployContent = octopusDeployPlugin.provide( - createRoutableExtension({ - name: 'EntityOctopusDeployContent', - component: () => - import('./components/EntityPageOctopusDeploy').then( - m => m.EntityPageOctopusDeploy, - ), - mountPoint: octopusDeployEntityContentRouteRef, - }), -); diff --git a/plugins/octopus-deploy/src/routes.ts b/plugins/octopus-deploy/src/routes.ts deleted file mode 100644 index 824b6ae113..0000000000 --- a/plugins/octopus-deploy/src/routes.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createRouteRef } from '@backstage/core-plugin-api'; - -export const octopusDeployEntityContentRouteRef = createRouteRef({ - id: 'octopus-deploy-entity-content', -}); diff --git a/plugins/octopus-deploy/src/setupTests.ts b/plugins/octopus-deploy/src/setupTests.ts deleted file mode 100644 index 865308e634..0000000000 --- a/plugins/octopus-deploy/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import '@testing-library/jest-dom'; diff --git a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts deleted file mode 100644 index 80ebaab76a..0000000000 --- a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from '../constants'; - -import { Entity } from '@backstage/catalog-model'; - -/** @public */ -export type ProjectReference = { projectId: string; spaceId?: string }; - -export function getProjectReferenceAnnotationFromEntity( - entity: Entity, -): ProjectReference { - const annotation = - entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION]; - if (!annotation) { - throw new Error( - `Value for annotation ${OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION} was not found`, - ); - } - - const referencedProject = annotation.split('/', 2); - if (referencedProject.length === 2) { - return { projectId: referencedProject[1], spaceId: referencedProject[0] }; - } - return { projectId: referencedProject[0] }; -} diff --git a/plugins/opencost/.eslintrc.js b/plugins/opencost/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/opencost/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/opencost/CHANGELOG.md b/plugins/opencost/CHANGELOG.md deleted file mode 100644 index 2a98300a53..0000000000 --- a/plugins/opencost/CHANGELOG.md +++ /dev/null @@ -1,233 +0,0 @@ -# @backstage/plugin-opencost - -## 0.2.5-next.2 - -### Patch Changes - -- 8472188: Added or fixed the `repository` field in `package.json`. -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.2.5-next.1 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- 03c5bbe: Updated dependency `date-fns` to `^3.0.0`. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.2.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - -## 0.2.4 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - -## 0.2.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - -## 0.2.4-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/core-plugin-api@1.8.1 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - -## 0.2.3-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.2.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.0 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - -## 0.2.2 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - -## 0.2.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - -## 0.2.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.2.2-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.2.1 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- 777b9a16a4: Fix for broken image reference. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/theme@0.4.3 - -## 0.2.1-next.2 - -### Patch Changes - -- 777b9a16a4: Fix for broken image reference. -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/theme@0.4.3-next.0 - -## 0.2.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/theme@0.4.2 - -## 0.2.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/theme@0.4.2 - -## 0.2.0 - -### Minor Changes - -- 1380a689ab56: New OpenCost plugin provides an port of the latest OpenCost UI to Backstage with updated dependencies. The plugin's README covers installation and configuration - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/core-components@0.13.5 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.2.0-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.2.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/theme@0.4.1 - -## 0.2.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.2.0-next.0 - -### Minor Changes - -- 1380a689ab56: New OpenCost plugin provides an port of the latest OpenCost UI to Backstage with updated dependencies. The plugin's README covers installation and configuration - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/theme@0.4.1 diff --git a/plugins/opencost/README.md b/plugins/opencost/README.md deleted file mode 100644 index 1dec15dcc1..0000000000 --- a/plugins/opencost/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# OpenCost - -Welcome to the [OpenCost](https://opencost.io) plugin! - -Currently this is a port of the [OpenCost UI](https://github.com/opencost/opencost/tree/develop/ui), but we will continue to expand it to expose any relevant data or pre-configured views that may be preferred. - -All of the code was originally ported from https://github.com/opencost/opencost/blob/develop/ui/ which is under by the Apache v2 License and also managed by the CNCF. - -## Installation - -1. Add the OpenCost dependency to the `packages/app/package.json`: - ```sh - # From your Backstage root directory - yarn --cwd packages/app add @backstage/plugin-opencost - ``` -2. Add the `OpenCostPage` to your `packages/app/src/App.tsx`: - - ```tsx - import { OpenCostPage } from '@backstage/plugin-opencost'; - ``` - -and - - ```tsx - - … - } /> - - ``` - -3. Import the `MoneyIcon` and add link to OpenCost to your sidebar - - ```typescript - // packages/app/src/components/Root/Root.tsx - import MoneyIcon from '@material-ui/icons/MonetizationOn'; - - ... - - export const Root = ({ children }: PropsWithChildren<{}>) => ( - - - ... - - ... - - - ); - - ``` - -## Plugin Configuration - -Since OpenCost doesn't have any authentication at this point, you just need to give API access to the plugin to access your data. - -If you haven't set up an ingress rule, you can port-forward the API with - -``` -kubectl -n opencost port-forward deployment/opencost 9003 -``` - -Add the following to your `app-config.yaml`: - -```yaml -opencost: - baseUrl: http://localhost:9003 -``` - -## Ideas/Next Steps - -- More testing -- Use the OpenCost mascot for the sidebar logo -- Use the Backstage proxy to communicate with the OpenCost API if necessary for authentication -- Convert AllocationReport.js to use the [Backstage Table](https://backstage.io/storybook/?path=/story/data-display-table--default-table) -- Allow for user-provided default reports and/or disabling controls -- Support multiple hard-coded reports -- clean up deprecation warnings and upgrade to all the latest React components -- Fork(?) to support `Kubecost`, which could provide Alerts and Recommendations, similar to the Cost Explorer plugin - -![Screenshot](screenshot.png) diff --git a/plugins/opencost/api-report.md b/plugins/opencost/api-report.md deleted file mode 100644 index 996bcea6ac..0000000000 --- a/plugins/opencost/api-report.md +++ /dev/null @@ -1,22 +0,0 @@ -## API Report File for "@backstage/plugin-opencost" - -> 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 { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export const OpenCostPage: () => JSX_2.Element; - -// @public (undocumented) -export const openCostPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -``` diff --git a/plugins/opencost/catalog-info.yaml b/plugins/opencost/catalog-info.yaml deleted file mode 100644 index 277562bb32..0000000000 --- a/plugins/opencost/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-opencost - title: '@backstage/plugin-opencost' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/opencost/config.d.ts b/plugins/opencost/config.d.ts deleted file mode 100644 index 0070bec7b7..0000000000 --- a/plugins/opencost/config.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** - * Configurations for the OpenCost plugin - * - * @visibility frontend - */ - opencost?: { - /** - * The base URL for the OpenCost API - * @visibility frontend - */ - baseUrl: string; - }; -} diff --git a/plugins/opencost/dev/index.tsx b/plugins/opencost/dev/index.tsx deleted file mode 100644 index 41b2bd5346..0000000000 --- a/plugins/opencost/dev/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { createDevApp } from '@backstage/dev-utils'; -import { openCostPlugin, OpenCostPage } from '../src/plugin'; - -createDevApp() - .registerPlugin(openCostPlugin) - .addPage({ - element: , - title: 'Root Page', - path: '/opencost', - }) - .render(); diff --git a/plugins/opencost/knip-report.md b/plugins/opencost/knip-report.md deleted file mode 100644 index f59b3135f7..0000000000 --- a/plugins/opencost/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------------ | :----------- | :------- | -| @testing-library/jest-dom | package.json | error | - diff --git a/plugins/opencost/package.json b/plugins/opencost/package.json deleted file mode 100644 index 4d09c90d9c..0000000000 --- a/plugins/opencost/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@backstage/plugin-opencost", - "version": "0.2.5-next.2", - "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" - }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/opencost" - }, - "backstage": { - "role": "frontend-plugin" - }, - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@date-io/luxon": "1.x", - "@material-ui/core": "^4.9.13", - "@material-ui/icons": "^4.9.1", - "@material-ui/pickers": "^3.3.10", - "@material-ui/styles": "^4.11.5", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "axios": "^1.4.0", - "date-fns": "^3.0.0", - "lodash": "^4.17.21", - "recharts": "^2.5.0" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "*" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/opencost/screenshot.png b/plugins/opencost/screenshot.png deleted file mode 100644 index 432b525cb1..0000000000 Binary files a/plugins/opencost/screenshot.png and /dev/null differ diff --git a/plugins/opencost/src/components/AllocationChart/RangeChart.jsx b/plugins/opencost/src/components/AllocationChart/RangeChart.jsx deleted file mode 100644 index b1ce5a34ee..0000000000 --- a/plugins/opencost/src/components/AllocationChart/RangeChart.jsx +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { - BarChart, - Bar, - XAxis, - YAxis, - CartesianGrid, - Tooltip, - ResponsiveContainer, -} from 'recharts'; -import { makeStyles } from '@material-ui/styles'; -import { reverse } from 'lodash'; -import { primary, greyscale, browns } from '../../constants/colors'; -import { toCurrency } from '../../util'; - -const useStyles = makeStyles({ - tooltip: { - borderRadius: 2, - background: 'rgba(255, 255, 255, 0.95)', - padding: 12, - }, - tooltipLineItem: { - fontSize: '1rem', - margin: 0, - marginBottom: 4, - padding: 0, - }, -}); - -function toBarLabels(allocationRange) { - const keyToFill = {}; - let p = 0; - let g = 0; - let b = 0; - - for (const { idle } of allocationRange) { - for (const allocation of idle) { - const key = allocation.name; - if (keyToFill[key] === undefined) { - // idle allocations are assigned grey - keyToFill[key] = greyscale[g]; - g = (g + 1) % greyscale.length; - } - } - } - - for (const { top } of allocationRange) { - for (const allocation of top) { - const key = allocation.name; - if (keyToFill[key] === undefined) { - if (key === '__unallocated__') { - // unallocated gets black (clean up) - keyToFill[key] = '#212121'; - } else { - // non-idle allocations get the next available color - keyToFill[key] = primary[p]; - p = (p + 1) % primary.length; - } - } - } - } - - for (const { other } of allocationRange) { - for (const allocation of other) { - const key = allocation.name; - if (keyToFill[key] === undefined) { - // idle allocations are assigned grey - keyToFill[key] = browns[b]; - b = (b + 1) % browns.length; - } - } - } - - const labels = []; - for (const key in keyToFill) { - if (Object.hasOwn(keyToFill, key)) { - labels.push({ - dataKey: key, - fill: keyToFill[key], - }); - } - } - - return reverse(labels); -} - -function toBar(datum) { - const { top, other, idle } = datum; - const bar = {}; - - for (const key in top) { - if (Object.hasOwn(top, key)) { - const allocation = top[key]; - const start = new Date(allocation.start); - bar.start = `${start.getUTCFullYear()}-${ - start.getUTCMonth() + 1 - }-${start.getUTCDate()}`; - bar[allocation.name] = allocation.totalCost; - } - } - - for (const key in other) { - if (Object.hasOwn(other, key)) { - const allocation = other[key]; - const start = new Date(allocation.start); - bar.start = `${start.getUTCFullYear()}-${ - start.getUTCMonth() + 1 - }-${start.getUTCDate()}`; - bar[allocation.name] = allocation.totalCost; - } - } - - for (const key in idle) { - if (Object.hasOwn(idle, key)) { - const allocation = idle[key]; - const start = new Date(allocation.start); - bar.start = `${start.getUTCFullYear()}-${ - start.getUTCMonth() + 1 - }-${start.getUTCDate()}`; - bar[allocation.name] = allocation.totalCost; - } - } - - return bar; -} - -const RangeChart = ({ data, currency, height }) => { - const classes = useStyles(); - - const barData = data.map(toBar); - const barLabels = toBarLabels(data); - - const CustomTooltip = params => { - const { active, payload } = params; - - if (!payload || payload.length === 0) { - return null; - } - - const total = payload.reduce((sum, item) => sum + item.value, 0.0); - if (active) { - /* eslint react/forbid-elements: [0, { allow: ["warning"] }] */ - return ( -
-

{`Total: ${toCurrency(total, currency)}`}

- {reverse(payload).map((item, i) => ( -

{`${item.name}: ${toCurrency(item.value, currency)}`}

- ))} -
- ); - } - - return null; - }; - - return ( - - - - - - } /> - {barLabels.map((barLabel, i) => ( - - ))} - - - ); -}; - -export default RangeChart; diff --git a/plugins/opencost/src/components/AllocationChart/SummaryChart.jsx b/plugins/opencost/src/components/AllocationChart/SummaryChart.jsx deleted file mode 100644 index 53c0842845..0000000000 --- a/plugins/opencost/src/components/AllocationChart/SummaryChart.jsx +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'; -import { primary, greyscale, browns } from '../../constants/colors'; -import { toCurrency } from '../../util'; - -function toPieData(top, other, idle) { - const slices = []; - - for (const i in top) { - if (Object.hasOwn(top, i)) { - const allocation = top[i]; - const fill = - allocation.name === '__unallocated__' - ? '#212121' - : primary[i % primary.length]; - - slices.push({ - name: allocation.name, - value: allocation.totalCost, - fill: fill, - }); - } - } - - for (const i in other) { - if (Object.hasOwn(other, i)) { - const allocation = other[i]; - const fill = browns[i % browns.length]; - slices.push({ - name: allocation.name, - value: allocation.totalCost, - fill: fill, - }); - } - } - - for (const i in idle) { - if (Object.hasOwn(idle, i)) { - const allocation = idle[i]; - const fill = greyscale[i % greyscale.length]; - slices.push({ - name: allocation.name, - value: allocation.totalCost, - fill: fill, - }); - } - } - - return slices; -} - -const SummaryChart = ({ top, other, idle, currency, height }) => { - const pieData = toPieData(top, other, idle); - - const renderLabel = params => { - const { cx, cy, midAngle, outerRadius, percent, name, fill, value } = - params; - - const RADIAN = Math.PI / 180; - const radius = outerRadius * 1.1; - let x = cx + radius * Math.cos(-midAngle * RADIAN); - x += x > cx ? 2 : -2; - const y = cy + radius * Math.sin(-midAngle * RADIAN); - // y -= Math.min(Math.abs(2 / Math.cos(-midAngle * RADIAN)), 8) - - if (percent < 0.02) { - return undefined; - } - - return ( - cx ? 'start' : 'end'} - dominantBaseline="central" - > - {`${name}: ${toCurrency(value, currency)} (${(percent * 100).toFixed( - 1, - )}%)`} - - ); - }; - - return ( - - - - {pieData.map((datum, i) => ( - - ))} - - - - ); -}; - -export default SummaryChart; diff --git a/plugins/opencost/src/components/AllocationChart/index.jsx b/plugins/opencost/src/components/AllocationChart/index.jsx deleted file mode 100644 index 9fec3e296f..0000000000 --- a/plugins/opencost/src/components/AllocationChart/index.jsx +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { isArray, filter, map, reduce, reverse, sortBy } from 'lodash'; - -import Typography from '@material-ui/core/Typography'; - -import RangeChart from './RangeChart'; -import SummaryChart from './SummaryChart'; - -// TODO niko/etl -/* eslint @typescript-eslint/no-shadow: ["error", { "allow": ["agg"] }]*/ -function agg(allocationSet, name) { - if (allocationSet.length === 0) { - return null; - } - - return reduce( - allocationSet, - (agg, cur) => ({ - name: agg.name, - aggregatedBy: cur.aggregatedBy, - properties: agg.properties, - start: cur.start, - end: cur.end, - cpuCost: agg.cpuCost + cur.cpuCost, - gpuCost: agg.gpuCost + cur.gpuCost, - ramCost: agg.ramCost + cur.ramCost, - pvCost: agg.pvCost + cur.pvCost, - totalCost: agg.totalCost + cur.totalCost, - count: agg.count + 1, - }), - { - name: name, - properties: null, - cpuCost: 0.0, - gpuCost: 0.0, - ramCost: 0.0, - pvCost: 0.0, - totalCost: 0.0, - count: 0, - }, - ); -} - -function isIdle(allocation) { - return allocation.name.indexOf('__idle__') >= 0; -} - -function top(n, by) { - return allocations => { - if (isArray(allocations[0])) { - return map(allocations, top(n, by)); - } - - const sorted = reverse(sortBy(allocations, by)); - const active = filter(sorted, a => !isIdle(a)); - const idle = filter(sorted, a => isIdle(a)); - const topn = active.slice(0, n); - const other = []; - if (active.length > n) { - other.push(agg(active.slice(n), 'other')); - } - - return { - top: topn, - other: other, - idle: idle, - }; - }; -} - -const AllocationChart = ({ allocationRange, currency, n, height }) => { - if (allocationRange.length === 0) { - return No data; - } - - if (allocationRange.length === 1) { - const datum = top(n, alloc => alloc.totalCost)(allocationRange[0]); - return ( - - ); - } - - const data = top(n, alloc => alloc.totalCost)(allocationRange); - return ; -}; - -export default React.memo(AllocationChart); diff --git a/plugins/opencost/src/components/AllocationReport.jsx b/plugins/opencost/src/components/AllocationReport.jsx deleted file mode 100644 index 52686a741c..0000000000 --- a/plugins/opencost/src/components/AllocationReport.jsx +++ /dev/null @@ -1,261 +0,0 @@ -/* not changing the working code at this point */ -/* eslint no-nested-ternary: 0 */ -/* eslint react-hooks/rules-of-hooks: 0 */ - -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useEffect, useState } from 'react'; -import { get, round } from 'lodash'; -import { makeStyles } from '@material-ui/styles'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableContainer from '@material-ui/core/TableContainer'; -import TableHead from '@material-ui/core/TableHead'; -import TablePagination from '@material-ui/core/TablePagination'; -import TableRow from '@material-ui/core/TableRow'; -import TableSortLabel from '@material-ui/core/TableSortLabel'; -import Typography from '@material-ui/core/Typography'; -import AllocationChart from './AllocationChart'; -import { toCurrency } from '../util'; - -const useStyles = makeStyles({ - noResults: { - padding: 24, - }, -}); - -function descendingComparator(a, b, orderBy) { - if (get(b, orderBy) < get(a, orderBy)) { - return -1; - } - if (get(b, orderBy) > get(a, orderBy)) { - return 1; - } - return 0; -} - -function getComparator(order, orderBy) { - return order === 'desc' - ? (a, b) => descendingComparator(a, b, orderBy) - : (a, b) => -descendingComparator(a, b, orderBy); -} - -function stableSort(array, comparator) { - const stabilizedThis = array.map((el, index) => [el, index]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) return order; - return a[1] - b[1]; - }); - return stabilizedThis.map(el => el[0]); -} - -const headCells = [ - { id: 'name', numeric: false, label: 'Name', width: 'auto' }, - { id: 'cpuCost', numeric: true, label: 'CPU', width: 100 }, - { id: 'ramCost', numeric: true, label: 'RAM', width: 100 }, - { id: 'pvCost', numeric: true, label: 'PV', width: 100 }, - { id: 'totalEfficiency', numeric: true, label: 'Efficiency', width: 130 }, - { id: 'totalCost', numeric: true, label: 'Total cost', width: 130 }, -]; - -const AllocationReport = ({ - allocationData, - cumulativeData, - totalData, - currency, -}) => { - const classes = useStyles(); - - if (allocationData.length === 0) { - return ( - - No results - - ); - } - - const [order, setOrder] = React.useState('desc'); - const [orderBy, setOrderBy] = React.useState('totalCost'); - const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(25); - const numData = cumulativeData.length; - - useEffect(() => { - setPage(0); - }, [numData]); - - const lastPage = Math.floor(numData / rowsPerPage); - - const handleChangePage = (event, newPage) => setPage(newPage); - - const handleChangeRowsPerPage = event => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - const handleRequestSort = (event, property) => { - const isDesc = orderBy === property && order === 'desc'; - setOrder(isDesc ? 'asc' : 'desc'); - setOrderBy(property); - }; - - const createSortHandler = property => event => - handleRequestSort(event, property); - - const orderedRows = stableSort(cumulativeData, getComparator(order, orderBy)); - const pageRows = orderedRows.slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage, - ); - - return ( -
- - -
- - - {headCells.map(cell => ( - - - {cell.label} - - - ))} - - - - - {headCells.map(cell => { - return ( - - {cell.numeric - ? cell.label === 'Efficiency' - ? totalData.totalEfficiency === 1.0 && - totalData.cpuReqCoreHrs === 0 && - totalData.ramReqByteHrs === 0 - ? 'Inf%' - : `${round(totalData.totalEfficiency * 100, 1)}%` - : toCurrency(totalData[cell.id], currency) - : totalData[cell.id]} - - ); - })} - - {pageRows.map((row, key) => { - if (row.name === '__unmounted__') { - row.name = 'Unmounted PVs'; - } - - const isIdle = row.name.indexOf('__idle__') >= 0; - const isUnallocated = row.name.indexOf('__unallocated__') >= 0; - const isUnmounted = row.name.indexOf('Unmounted PVs') >= 0; - - // Replace "efficiency" with Inf if there is usage w/o request - let efficiency = round(row.totalEfficiency * 100, 1); - if ( - row.totalEfficiency === 1.0 && - row.cpuReqCoreHrs === 0 && - row.ramReqByteHrs === 0 - ) { - efficiency = 'Inf'; - } - - // Do not allow drill-down for idle and unallocated rows - if (isIdle || isUnallocated || isUnmounted) { - return ( - - {row.name} - - {toCurrency(row.cpuCost, currency)} - - - {toCurrency(row.ramCost, currency)} - - - {toCurrency(row.pvCost, currency)} - - {isIdle ? ( - - ) : ( - {efficiency}% - )} - - {toCurrency(row.totalCost, currency)} - - - ); - } - - return ( - - {row.name} - - {toCurrency(row.cpuCost, currency)} - - - {toCurrency(row.ramCost, currency)} - - - {toCurrency(row.pvCost, currency)} - - {efficiency}% - - {toCurrency(row.totalCost, currency)} - - - ); - })} - -
- - - - ); -}; - -export default React.memo(AllocationReport); diff --git a/plugins/opencost/src/components/Controls/Download.jsx b/plugins/opencost/src/components/Controls/Download.jsx deleted file mode 100644 index 727188e5c1..0000000000 --- a/plugins/opencost/src/components/Controls/Download.jsx +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { get, forEach, reverse, round, sortBy } from 'lodash'; -import ExportIcon from '@material-ui/icons/GetApp'; -import IconButton from '@material-ui/core/IconButton'; -import Tooltip from '@material-ui/core/Tooltip'; - -const columns = [ - { - head: 'Name', - prop: 'name', - currency: false, - }, - { - head: 'CPU', - prop: 'cpuCost', - currency: true, - }, - { - head: 'GPU', - prop: 'gpuCost', - currency: true, - }, - { - head: 'RAM', - prop: 'ramCost', - currency: true, - }, - { - head: 'PV', - prop: 'pvCost', - currency: true, - }, - { - head: 'Network', - prop: 'networkCost', - currency: true, - }, - { - head: 'Shared', - prop: 'sharedCost', - currency: true, - }, - { - head: 'Total', - prop: 'totalCost', - currency: true, - }, -]; - -const toCSVLine = datum => { - const cols = []; - - forEach(columns, c => { - if (c.currency) { - cols.push(round(get(datum, c.prop, 0.0), 2)); - } else { - cols.push(`"${get(datum, c.prop, '')}"`); - } - }); - - return cols.join(','); -}; - -const DownloadControl = ({ cumulativeData, title }) => { - // downloadReport downloads a CSV of the cumulative allocation data - function downloadReport() { - // Build CSV - const head = columns.map(c => c.head).join(','); - const body = reverse(sortBy(cumulativeData, 'totalCost')) - .map(toCSVLine) - .join('\r\n'); - const csv = `${head}\r\n${body}`; - - // Create download link - const a = document.createElement('a'); - a.href = URL.createObjectURL(new Blob([csv], { type: 'text/csv' })); - const filename = title.toLocaleLowerCase('en-US').replace(/\s/gi, '-'); - a.setAttribute('download', `${filename}-${Date.now()}.csv`); - - // Click the link - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - } - - return ( - - - - - - ); -}; - -export default React.memo(DownloadControl); diff --git a/plugins/opencost/src/components/Controls/Edit.jsx b/plugins/opencost/src/components/Controls/Edit.jsx deleted file mode 100644 index f02f8cc111..0000000000 --- a/plugins/opencost/src/components/Controls/Edit.jsx +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { makeStyles } from '@material-ui/styles'; -import FormControl from '@material-ui/core/FormControl'; -import InputLabel from '@material-ui/core/InputLabel'; -import MenuItem from '@material-ui/core/MenuItem'; -import Select from '@material-ui/core/Select'; - -import React from 'react'; - -import SelectWindow from '../SelectWindow'; - -const useStyles = makeStyles({ - wrapper: { - display: 'inline-flex', - }, - formControl: { - margin: 8, - minWidth: 120, - }, -}); - -function EditControl({ - windowOptions, - window, - setWindow, - aggregationOptions, - aggregateBy, - setAggregateBy, - accumulateOptions, - accumulate, - setAccumulate, - currencyOptions, - currency, - setCurrency, -}) { - const classes = useStyles(); - return ( -
- - - Breakdown - - - - Resolution - - - - Currency - - -
- ); -} - -export default React.memo(EditControl); diff --git a/plugins/opencost/src/components/Controls/index.jsx b/plugins/opencost/src/components/Controls/index.jsx deleted file mode 100644 index c63833a6ab..0000000000 --- a/plugins/opencost/src/components/Controls/index.jsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import DownloadControl from './Download'; -import EditControl from './Edit'; - -const Controls = ({ - windowOptions, - window, - setWindow, - aggregationOptions, - aggregateBy, - setAggregateBy, - accumulateOptions, - accumulate, - setAccumulate, - title, - cumulativeData, - currency, - currencyOptions, - setCurrency, -}) => { - return ( -
- - -
- ); -}; - -export default React.memo(Controls); diff --git a/plugins/opencost/src/components/Details.jsx b/plugins/opencost/src/components/Details.jsx deleted file mode 100644 index 5245c9e9fa..0000000000 --- a/plugins/opencost/src/components/Details.jsx +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { memo, useEffect, useState } from 'react'; -import { forEach, get, reverse, round, sortBy } from 'lodash'; -import CircularProgress from '@material-ui/core/CircularProgress'; -import ClusterIcon from '@material-ui/icons/GroupWork'; -import NodeIcon from '@material-ui/icons/Memory'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableContainer from '@material-ui/core/TableContainer'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; -import Warnings from './Warnings'; -import AllocationService from '../services/allocation'; -import { bytesToString, toCurrency } from '../util'; - -const Details = ({ - window, - namespace, - controllerKind, - controller, - pod, - currency, -}) => { - const [cluster, setCluster] = useState(''); - const [node, setNode] = useState(''); - - const [fetch, setFetch] = useState(true); - const [loading, setLoading] = useState(false); - const [errors, setErrors] = useState([]); - const [rows, setRows] = useState([]); - - useEffect(() => { - if (fetch) { - setCluster(''); - setNode(''); - fetchData(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [fetch]); - - async function fetchData() { - setLoading(true); - setErrors([]); - - try { - const filters = []; - - if (cluster) { - filters.push({ - property: 'cluster', - value: cluster, - }); - } - - if (node) { - filters.push({ - property: 'node', - value: node, - }); - } - - if (namespace) { - filters.push({ - property: 'namespace', - value: namespace, - }); - } - - if (controllerKind) { - filters.push({ - property: 'controllerKind', - value: controllerKind, - }); - } - - if (controller) { - filters.push({ - property: 'controller', - value: controller, - }); - } - - if (pod) { - filters.push({ - property: 'pod', - value: pod, - }); - } - - const resp = await AllocationService.fetchAllocation(window, '', { - accumulate: true, - }); - - let data = []; - forEach(resp.data[0], datum => { - if (datum.name === '__idle__') { - return; - } - - if (!cluster) { - setCluster(get(datum, 'properties.cluster', '')); - } - - if (!node) { - setNode(get(datum, 'properties.node', '')); - } - - // TODO can we get pod, container back in properties? - const names = datum.name.split('/'); - datum.pod = names[names.length - 2]; - datum.container = names[names.length - 1]; - - datum.hours = round(get(datum, 'minutes', 0.0) / 60.0, 2); - - if (datum.hours > 0) { - datum.cpu = round(get(datum, 'cpuCoreHours', 0.0) / datum.hours, 2); - datum.cpuCostPerCoreHr = datum.cpuCost / (datum.cpu * datum.hours); - if (datum.cpu === 0) { - datum.cpuCostPerCoreHr = 0.0; - } - - datum.ram = round(get(datum, 'ramByteHours', 0.0) / datum.hours, 2); - const ramGiB = datum.ram / 1024 / 1024 / 1024; - datum.ramCostPerGiBHr = datum.ramCost / (ramGiB * datum.hours); - if (ramGiB === 0) { - datum.ramCostPerGiBHr = 0.0; - } - } else { - datum.cpu = 0.0; - datum.cpuCostPerCoreHr = 0.0; - datum.ram = 0.0; - datum.ramCostPerGiBHr = 0.0; - } - - data.push(datum); - }); - - data = reverse(sortBy(data, 'totalCost')); - - setRows(data); - } catch (e) { - /* eslint no-console: ["error", { allow: ["warn"] }] */ - console.warn( - `Error fetching details for (${controllerKind}, ${controller}):`, - e, - ); - setErrors([ - { - primary: 'Error fetching details', - secondary: `Tried fetching details for: ${namespace}, ${controllerKind}, ${controller}, ${pod}`, - }, - ]); - } - - setLoading(false); - setFetch(false); - } - - if (loading) { - return ( -
-
- -
-
- ); - } - - return ( -
- {!loading && errors.length > 0 && ( -
- -
- )} - - - {cluster && ( - - - - - - - )} - {node && ( - - - - - - - )} - - - - - - - Container - - - Hours - - - CPU - - - $/(CPU*Hr) - - - CPU cost - - - RAM - - - $/(GiB*Hr) - - - RAM cost - - - Total cost - - - - - {rows.map((row, i) => ( - - - {row.container} - - - {row.hours} - - - {row.cpu} - - - {toCurrency(row.cpuCostPerCoreHr, currency, 5)} - - - {toCurrency(row.cpuCost, currency, 3)} - - - {bytesToString(row.ram)} - - - {toCurrency(row.ramCostPerGiBHr, currency, 5)} - - - {toCurrency(row.ramCost, currency, 3)} - - - {toCurrency(row.totalCost, currency, 3)} - - - ))} - -
-
-
- ); -}; - -export default memo(Details); diff --git a/plugins/opencost/src/components/OpenCostPage/OpenCostPage.tsx b/plugins/opencost/src/components/OpenCostPage/OpenCostPage.tsx deleted file mode 100644 index 4062eca155..0000000000 --- a/plugins/opencost/src/components/OpenCostPage/OpenCostPage.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { Grid } from '@material-ui/core'; -import { Header, Page, Content } from '@backstage/core-components'; -import { OpenCostReport } from '../OpenCostReport'; -import logo from '../../images/pig.png'; - -export const OpenCostPage = () => ( - -
- - OpenCost - -
- - - - - - - -
-); diff --git a/plugins/opencost/src/components/OpenCostPage/index.ts b/plugins/opencost/src/components/OpenCostPage/index.ts deleted file mode 100644 index f966c83a30..0000000000 --- a/plugins/opencost/src/components/OpenCostPage/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { OpenCostPage } from './OpenCostPage'; diff --git a/plugins/opencost/src/components/OpenCostReport/OpenCostReport.tsx b/plugins/opencost/src/components/OpenCostReport/OpenCostReport.tsx deleted file mode 100644 index 12f64f3606..0000000000 --- a/plugins/opencost/src/components/OpenCostReport/OpenCostReport.tsx +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// code ported from https://github.com/opencost/opencost/blob/develop/ui/src/Reports.js - -import React, { useEffect, useState } from 'react'; -import CircularProgress from '@material-ui/core/CircularProgress'; -import IconButton from '@material-ui/core/IconButton'; -import Paper from '@material-ui/core/Paper'; -import RefreshIcon from '@material-ui/icons/Refresh'; -import Typography from '@material-ui/core/Typography'; -import { useLocation, useNavigate } from 'react-router-dom'; -import { find, get, sortBy, toArray } from 'lodash'; -import { makeStyles } from '@material-ui/styles'; -import AllocationReport from '../AllocationReport'; -import AllocationService from '../../services/allocation'; -import Controls from '../Controls'; -import Page from '../Page'; -import Subtitle from '../Subtitle'; -import Warnings from '../Warnings'; -import { - checkCustomWindow, - cumulativeToTotals, - rangeToCumulative, - toVerboseTimeRange, -} from '../../util'; -import { currencyCodes } from '../../constants/currencyCodes'; -import { useApi, configApiRef } from '@backstage/core-plugin-api'; - -const windowOptions = [ - { name: 'Today', value: 'today' }, - { name: 'Yesterday', value: 'yesterday' }, - { name: 'Week-to-date', value: 'week' }, - { name: 'Month-to-date', value: 'month' }, - { name: 'Last week', value: 'lastweek' }, - { name: 'Last month', value: 'lastmonth' }, - { name: 'Last 7 days', value: '6d' }, - { name: 'Last 30 days', value: '29d' }, - { name: 'Last 60 days', value: '59d' }, - { name: 'Last 90 days', value: '89d' }, -]; - -const aggregationOptions = [ - { name: 'Cluster', value: 'cluster' }, - { name: 'Node', value: 'node' }, - { name: 'Namespace', value: 'namespace' }, - { name: 'Controller kind', value: 'controllerKind' }, - { name: 'Controller', value: 'controller' }, - { name: 'Service', value: 'service' }, - { name: 'Pod', value: 'pod' }, - { name: 'Container', value: 'container' }, -]; - -const accumulateOptions = [ - { name: 'Entire window', value: true }, - { name: 'Daily', value: false }, -]; - -const useStyles = makeStyles({ - reportHeader: { - display: 'flex', - flexFlow: 'row', - padding: 24, - }, - titles: { - flexGrow: 1, - }, -}); - -// generateTitle generates a string title from a report object -// @ts-ignore: implicitly has an 'any' type -function generateTitle({ window, aggregateBy, accumulate }) { - let windowName = get(find(windowOptions, { value: window }), 'name', ''); - if (windowName === '') { - if (checkCustomWindow(window)) { - windowName = toVerboseTimeRange(window); - } else { - /* eslint no-console: ["error", { allow: ["warn"] }] */ - console.warn(`unknown window: ${window}`); - } - } - - const aggregationName = get( - find(aggregationOptions, { value: aggregateBy }), - 'name', - '', - ).toLocaleLowerCase('en-US'); - if (aggregationName === '') { - /* eslint no-console: ["error", { allow: ["warn"] }] */ - console.warn(`unknown aggregation: ${aggregateBy}`); - } - - let str = `${windowName} by ${aggregationName}`; - - if (!accumulate) { - str = `${str} daily`; - } - - return str; -} - -export const OpenCostReport = () => { - const classes = useStyles(); - // Allocation data state - const [allocationData, setAllocationData] = useState([]); - const [cumulativeData, setCumulativeData] = useState({}); - const [totalData, setTotalData] = useState({}); - - // When allocation data changes, create a cumulative version of it - useEffect(() => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - const cumulative = rangeToCumulative(allocationData, aggregateBy); - setCumulativeData(toArray(cumulative)); - setTotalData(cumulativeToTotals(cumulative)); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [allocationData]); - - // Form state, which controls form elements, but not the report itself. On - // certain actions, the form state may flow into the report state. - const [window, setWindow] = useState(windowOptions[0].value); - const [aggregateBy, setAggregateBy] = useState(aggregationOptions[0].value); - const [accumulate, setAccumulate] = useState(accumulateOptions[0].value); - const [currency, setCurrency] = useState('USD'); - - // Report state, including current report and saved options - const [title, setTitle] = useState('Last 7 days by namespace daily'); - - // When parameters changes, fetch data. This should be the - // only mechanism used to fetch data. Also generate a sensible title from the paramters. - useEffect(() => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - setFetch(true); - setTitle(generateTitle({ window, aggregateBy, accumulate })); - }, [window, aggregateBy, accumulate]); - - // page and settings state - const [init, setInit] = useState(false); - const [fetch, setFetch] = useState(false); - const [loading, setLoading] = useState(true); - const [errors, setErrors] = useState([]); - - // Initialize once, then fetch report each time setFetch(true) is called - useEffect(() => { - if (!init) { - initialize(); - } - if (init && fetch) { - fetchData(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [init, fetch]); - - // parse any context information from the URL - const routerLocation = useLocation(); - const searchParams = new URLSearchParams(routerLocation.search); - const routerNavigate = useNavigate(); - useEffect(() => { - setWindow(searchParams.get('window') || '6d'); - setAggregateBy(searchParams.get('agg') || 'namespace'); - setAccumulate(searchParams.get('acc') === 'true' || false); - setCurrency(searchParams.get('currency') || 'USD'); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [routerLocation]); - - async function initialize() { - setInit(true); - } - - const configApi = useApi(configApiRef); - const baseUrl = configApi.getConfig('opencost').getString('baseUrl'); - /* eslint no-console: 0 */ - console.log(`baseUrl:${baseUrl}`); - - async function fetchData() { - setLoading(true); - setErrors([]); - - try { - const resp = await AllocationService.fetchAllocation( - baseUrl, - window, - aggregateBy, - { accumulate }, - ); - if (resp.data && resp.data.length > 0) { - const allocationRange = resp.data; - for (const i in allocationRange) { - if (Object.hasOwn(allocationRange, i)) { - // update cluster aggregations to use clusterName/clusterId names - allocationRange[i] = sortBy(allocationRange[i], a => a.totalCost); - } - } - setAllocationData(allocationRange); - } else { - setAllocationData([]); - } - } catch (err) { - if (err.message.indexOf('404') === 0) { - setErrors([ - // @ts-ignore: not assignable to type 'never' - { - primary: 'Failed to load report data', - secondary: - 'Please update OpenCost to the latest version, then open an Issue on GitHub if problems persist.', - }, - ]); - } else { - let secondary = - 'Please open an OpenCost issue with a bug report if problems persist.'; - if (err.message.length > 0) { - secondary = err.message; - } - setErrors([ - // @ts-ignore: not assignable to type 'never' - { - primary: 'Failed to load report data', - secondary: secondary, - }, - ]); - } - setAllocationData([]); - } - - setLoading(false); - setFetch(false); - } - return ( - - {!loading && errors.length > 0 && ( -
- -
- )} - {init && ( - -
-
- {title} - -
- - setFetch(true)}> - - - - { - searchParams.set('window', win); - routerNavigate({ - search: `?${searchParams.toString()}`, - }); - }} - aggregationOptions={aggregationOptions} - aggregateBy={aggregateBy} - // @ts-ignore: implicitly has an 'any' type - setAggregateBy={agg => { - searchParams.set('agg', agg); - routerNavigate({ - search: `?${searchParams.toString()}`, - }); - }} - accumulateOptions={accumulateOptions} - accumulate={accumulate} - // @ts-ignore: implicitly has an 'any' type - setAccumulate={acc => { - searchParams.set('acc', acc); - routerNavigate({ - search: `?${searchParams.toString()}`, - }); - }} - title={title} - cumulativeData={cumulativeData} - currency={currency} - currencyOptions={currencyCodes} - // @ts-ignore: implicitly has an 'any' type - setCurrency={curr => { - searchParams.set('currency', curr); - routerNavigate({ - search: `?${searchParams.toString()}`, - }); - }} - /> -
- - {loading && ( -
-
- -
-
- )} - {!loading && ( - - )} -
- )} -
- ); -}; diff --git a/plugins/opencost/src/components/OpenCostReport/index.ts b/plugins/opencost/src/components/OpenCostReport/index.ts deleted file mode 100644 index aee85ea8db..0000000000 --- a/plugins/opencost/src/components/OpenCostReport/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { OpenCostReport } from './OpenCostReport'; diff --git a/plugins/opencost/src/components/Page.jsx b/plugins/opencost/src/components/Page.jsx deleted file mode 100644 index 6346b6287b..0000000000 --- a/plugins/opencost/src/components/Page.jsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { makeStyles } from '@material-ui/styles'; -import React from 'react'; - -const useStyles = makeStyles({ - wrapper: { - display: 'flex', - flexFlow: 'column', - flexGrow: 1, - margin: '20px 30px 0 30px', - minWidth: 800, - }, - flexGrow: { - display: 'flex', - flexFlow: 'column', - flexGrow: 1, - }, -}); - -const Page = props => { - const classes = useStyles(); - - return ( -
-
-
{props.children}
-
-
- ); -}; - -export default Page; diff --git a/plugins/opencost/src/components/SelectWindow.jsx b/plugins/opencost/src/components/SelectWindow.jsx deleted file mode 100644 index 470770f35c..0000000000 --- a/plugins/opencost/src/components/SelectWindow.jsx +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useEffect, useState } from 'react'; -import { makeStyles } from '@material-ui/styles'; -import { - MuiPickersUtilsProvider, - KeyboardDatePicker, -} from '@material-ui/pickers'; -import Button from '@material-ui/core/Button'; -import LuxonUtils from '@date-io/luxon'; -import FormControl from '@material-ui/core/FormControl'; -import Link from '@material-ui/core/Link'; -import Popover from '@material-ui/core/Popover'; -import TextField from '@material-ui/core/TextField'; -import Typography from '@material-ui/core/Typography'; -import { isValid } from 'date-fns'; -import { find, get } from 'lodash'; - -const useStyles = makeStyles({ - dateContainer: { - paddingLeft: 18, - paddingRight: 18, - paddingTop: 6, - paddingBottom: 18, - display: 'flex', - flexFlow: 'row', - }, - dateContainerColumn: { - display: 'flex', - flexFlow: 'column', - }, - formControl: { - margin: 8, - width: 120, - }, -}); - -const SelectWindow = ({ windowOptions, window, setWindow }) => { - const classes = useStyles(); - const [anchorEl, setAnchorEl] = useState(null); - - const [startDate, setStartDate] = useState(null); - const [endDate, setEndDate] = useState(null); - const [intervalString, setIntervalString] = useState(null); - - const handleClick = event => { - setAnchorEl(event.currentTarget); - }; - - const handleClose = () => { - setAnchorEl(null); - }; - - const handleStartDateChange = date => { - if (isValid(date.toJSDate())) { - setStartDate(date.startOf('day').toJSDate()); - } - }; - - const handleEndDateChange = date => { - if (isValid(date.toJSDate())) { - setEndDate(date.endOf('day').toJSDate()); - } - }; - - const handleSubmitPresetDates = dateString => { - setWindow(dateString); - setStartDate(null); - setEndDate(null); - handleClose(); - }; - - const handleSubmitCustomDates = () => { - if (intervalString !== null) { - setWindow(intervalString); - handleClose(); - } - }; - - useEffect(() => { - if (startDate !== null && endDate !== null) { - // Note: getTimezoneOffset() is calculated based on current system locale, NOT date object - const adjustedStartDate = new Date( - startDate - startDate.getTimezoneOffset() * 60000, - ); - const adjustedEndDate = new Date( - endDate - endDate.getTimezoneOffset() * 60000, - ); - setIntervalString( - `${adjustedStartDate.toISOString().split('.')[0]}Z` + - `,${adjustedEndDate.toISOString().split('.')[0]}Z`, - ); - } - }, [startDate, endDate]); - - const open = Boolean(anchorEl); - const id = open ? 'date-range-popover' : undefined; - - return ( - <> - - handleClick(e)} - inputProps={{ - readOnly: true, - style: { cursor: 'pointer' }, - }} - /> - - -
-
- - - - -
- -
-
-
- {windowOptions.map(opt => ( - - handleSubmitPresetDates(opt.value)} - > - {opt.name} - - - ))} -
-
-
- - ); -}; - -export default React.memo(SelectWindow); diff --git a/plugins/opencost/src/components/Subtitle.jsx b/plugins/opencost/src/components/Subtitle.jsx deleted file mode 100644 index 63b3df61ff..0000000000 --- a/plugins/opencost/src/components/Subtitle.jsx +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { makeStyles } from '@material-ui/styles'; -import { upperFirst } from 'lodash'; -import Breadcrumbs from '@material-ui/core/Breadcrumbs'; -import NavigateNextIcon from '@material-ui/icons/NavigateNext'; -import Typography from '@material-ui/core/Typography'; -import { toVerboseTimeRange } from '../util'; - -const useStyles = makeStyles({ - root: { - '& > * + *': { - marginTop: 2, - }, - }, - link: { - cursor: 'pointer', - }, -}); - -const Subtitle = ({ report }) => { - const classes = useStyles(); - - const { aggregateBy, window } = report; - - return ( -
- } - aria-label="breadcrumb" - > - {aggregateBy && aggregateBy.length > 0 ? ( - - {toVerboseTimeRange(window)} by {upperFirst(aggregateBy)} - - ) : ( - {toVerboseTimeRange(window)} - )} - -
- ); -}; - -export default React.memo(Subtitle); diff --git a/plugins/opencost/src/components/Warnings.jsx b/plugins/opencost/src/components/Warnings.jsx deleted file mode 100644 index ae1047ebc2..0000000000 --- a/plugins/opencost/src/components/Warnings.jsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { makeStyles } from '@material-ui/styles'; -import List from '@material-ui/core/List'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import Paper from '@material-ui/core/Paper'; -import WarningIcon from '@material-ui/icons/Warning'; - -const useStyles = makeStyles({ - root: {}, -}); - -const Warnings = ({ warnings }) => { - const classes = useStyles(); - - if (!warnings || warnings.length === 0) { - return null; - } - - return ( - - - {warnings.map((warn, i) => ( - - - - - - - ))} - - - ); -}; - -export default Warnings; diff --git a/plugins/opencost/src/constants/colors.js b/plugins/opencost/src/constants/colors.js deleted file mode 100644 index 8e0289541b..0000000000 --- a/plugins/opencost/src/constants/colors.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import blue from '@material-ui/core/colors/blue'; -import brown from '@material-ui/core/colors/brown'; -import cyan from '@material-ui/core/colors/cyan'; -import deepOrange from '@material-ui/core/colors/deepOrange'; -import deepPurple from '@material-ui/core/colors/deepPurple'; -import green from '@material-ui/core/colors/green'; -import grey from '@material-ui/core/colors/grey'; -import indigo from '@material-ui/core/colors/indigo'; -import orange from '@material-ui/core/colors/orange'; -import red from '@material-ui/core/colors/red'; -import teal from '@material-ui/core/colors/teal'; -import yellow from '@material-ui/core/colors/yellow'; - -export const primary = [ - blue[500], - red[500], - green[500], - yellow[500], - cyan[500], - orange[500], - teal[500], - indigo[500], - deepOrange[500], - deepPurple[500], -]; - -export const greyscale = [ - grey[300], - grey[400], - grey[200], - grey[500], - grey[100], - grey[600], -]; - -export const browns = [brown[500]]; diff --git a/plugins/opencost/src/constants/currencyCodes.js b/plugins/opencost/src/constants/currencyCodes.js deleted file mode 100644 index a325df54d0..0000000000 --- a/plugins/opencost/src/constants/currencyCodes.js +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export const currencyCodes = [ - 'AED', - 'AFN', - 'ALL', - 'AMD', - 'ANG', - 'AOA', - 'ARS', - 'AUD', - 'AWG', - 'AZN', - 'BAM', - 'BBD', - 'BDT', - 'BGN', - 'BHD', - 'BIF', - 'BMD', - 'BND', - 'BOB', - 'BOV', - 'BRL', - 'BSD', - 'BTN', - 'BWP', - 'BYR', - 'BZD', - 'CAD', - 'CDF', - 'CHE', - 'CHF', - 'CHW', - 'CLF', - 'CLP', - 'CNY', - 'COP', - 'COU', - 'CRC', - 'CUC', - 'CUP', - 'CVE', - 'CZK', - 'DJF', - 'DKK', - 'DOP', - 'DZD', - 'EGP', - 'ERN', - 'ETB', - 'EUR', - 'FJD', - 'FKP', - 'GBP', - 'GEL', - 'GHS', - 'GIP', - 'GMD', - 'GNF', - 'GTQ', - 'GYD', - 'HKD', - 'HNL', - 'HRK', - 'HTG', - 'HUF', - 'IDR', - 'ILS', - 'INR', - 'IQD', - 'IRR', - 'ISK', - 'JMD', - 'JOD', - 'JPY', - 'KES', - 'KGS', - 'KHR', - 'KMF', - 'KPW', - 'KRW', - 'KWD', - 'KYD', - 'KZT', - 'LAK', - 'LBP', - 'LKR', - 'LRD', - 'LSL', - 'LTL', - 'LVL', - 'LYD', - 'MAD', - 'MDL', - 'MGA', - 'MKD', - 'MMK', - 'MNT', - 'MOP', - 'MRO', - 'MUR', - 'MVR', - 'MWK', - 'MXN', - 'MXV', - 'MYR', - 'MZN', - 'NAD', - 'NGN', - 'NIO', - 'NOK', - 'NPR', - 'NZD', - 'OMR', - 'PAB', - 'PEN', - 'PGK', - 'PHP', - 'PKR', - 'PLN', - 'PYG', - 'QAR', - 'RON', - 'RSD', - 'RUB', - 'RWF', - 'SAR', - 'SBD', - 'SCR', - 'SDG', - 'SEK', - 'SGD', - 'SHP', - 'SLL', - 'SOS', - 'SRD', - 'SSP', - 'STD', - 'SYP', - 'SZL', - 'THB', - 'TJS', - 'TMT', - 'TND', - 'TOP', - 'TRY', - 'TTD', - 'TWD', - 'TZS', - 'UAH', - 'UGX', - 'USD', - 'USN', - 'USS', - 'UYI', - 'UYU', - 'UZS', - 'VEF', - 'VND', - 'VUV', - 'WST', - 'XAF', - 'XAG', - 'XAU', - 'XBA', - 'XBB', - 'XBC', - 'XBD', - 'XCD', - 'XDR', - 'XFU', - 'XOF', - 'XPD', - 'XPF', - 'XPT', - 'XTS', - 'XXX', - 'YER', - 'ZAR', - 'ZMW', -]; diff --git a/plugins/opencost/src/images/pig.png b/plugins/opencost/src/images/pig.png deleted file mode 100644 index 5de5409e87..0000000000 Binary files a/plugins/opencost/src/images/pig.png and /dev/null differ diff --git a/plugins/opencost/src/index.ts b/plugins/opencost/src/index.ts deleted file mode 100644 index 30153e0c32..0000000000 --- a/plugins/opencost/src/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * A Backstage plugin that integrates with OpenCost - * - * @packageDocumentation - */ - -export { openCostPlugin, OpenCostPage } from './plugin'; diff --git a/plugins/opencost/src/plugin.test.ts b/plugins/opencost/src/plugin.test.ts deleted file mode 100644 index 6d6d20c603..0000000000 --- a/plugins/opencost/src/plugin.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { openCostPlugin } from './plugin'; - -describe('opencost', () => { - it('should export plugin', () => { - expect(openCostPlugin).toBeDefined(); - }); -}); diff --git a/plugins/opencost/src/plugin.ts b/plugins/opencost/src/plugin.ts deleted file mode 100644 index 2725cf3dde..0000000000 --- a/plugins/opencost/src/plugin.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createPlugin, - createRoutableExtension, -} from '@backstage/core-plugin-api'; - -import { rootRouteRef } from './routes'; - -/** @public */ -export const openCostPlugin = createPlugin({ - id: 'opencost', - routes: { - root: rootRouteRef, - }, -}); - -/** @public */ -export const OpenCostPage = openCostPlugin.provide( - createRoutableExtension({ - name: 'OpenCostPage', - component: () => - import('./components/OpenCostPage').then(m => m.OpenCostPage), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/opencost/src/routes.ts b/plugins/opencost/src/routes.ts deleted file mode 100644 index 5f1f9e4527..0000000000 --- a/plugins/opencost/src/routes.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'opencost', -}); diff --git a/plugins/opencost/src/services/allocation.js b/plugins/opencost/src/services/allocation.js deleted file mode 100644 index e7fba8feae..0000000000 --- a/plugins/opencost/src/services/allocation.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import axios from 'axios'; - -class AllocationService { - async fetchAllocation(baseUrl, win, aggregate, options) { - const { accumulate } = options; - const params = { - window: win, - aggregate: aggregate, - step: '1d', - }; - if (typeof accumulate === 'boolean') { - params.accumulate = accumulate; - } - - const result = await axios.get(`${baseUrl}/allocation/compute`, { params }); - - return result.data; - } -} - -export default new AllocationService(); diff --git a/plugins/opencost/src/util.js b/plugins/opencost/src/util.js deleted file mode 100644 index 5854718a55..0000000000 --- a/plugins/opencost/src/util.js +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { forEach, get, round } from 'lodash'; - -// rangeToCumulative takes an AllocationSetRange (type: array[AllocationSet]) -// and accumulates the values into a single AllocationSet (type: object) -export function rangeToCumulative(allocationSetRange, aggregateBy) { - if (allocationSetRange.length === 0) { - return null; - } - - const result = {}; - - forEach(allocationSetRange, allocSet => { - forEach(allocSet, alloc => { - if (result[alloc.name] === undefined) { - const hrs = get(alloc, 'minutes', 0) / 60.0; - - result[alloc.name] = { - name: alloc.name, - [aggregateBy]: alloc.name, - cpuCost: get(alloc, 'cpuCost', 0), - gpuCost: get(alloc, 'gpuCost', 0), - ramCost: get(alloc, 'ramCost', 0), - pvCost: get(alloc, 'pvCost', 0), - networkCost: get(alloc, 'networkCost', 0), - sharedCost: get(alloc, 'sharedCost', 0), - externalCost: get(alloc, 'externalCost', 0), - totalCost: get(alloc, 'totalCost', 0), - cpuUseCoreHrs: get(alloc, 'cpuCoreUsageAverage', 0) * hrs, - cpuReqCoreHrs: get(alloc, 'cpuCoreRequestAverage', 0) * hrs, - ramUseByteHrs: get(alloc, 'ramByteUsageAverage', 0) * hrs, - ramReqByteHrs: get(alloc, 'ramByteRequestAverage', 0) * hrs, - cpuEfficiency: get(alloc, 'cpuEfficiency', 0), - ramEfficiency: get(alloc, 'ramEfficiency', 0), - totalEfficiency: get(alloc, 'totalEfficiency', 0), - }; - } else { - const hrs = get(alloc, 'minutes', 0) / 60.0; - - result[alloc.name].cpuCost += get(alloc, 'cpuCost', 0); - result[alloc.name].gpuCost += get(alloc, 'gpuCost', 0); - result[alloc.name].ramCost += get(alloc, 'ramCost', 0); - result[alloc.name].pvCost += get(alloc, 'pvCost', 0); - result[alloc.name].networkCost += get(alloc, 'networkCost', 0); - result[alloc.name].sharedCost += get(alloc, 'sharedCost', 0); - result[alloc.name].externalCost += get(alloc, 'externalCost', 0); - result[alloc.name].totalCost += get(alloc, 'totalCost', 0); - result[alloc.name].cpuUseCoreHrs += - get(alloc, 'cpuCoreUsageAverage', 0) * hrs; - result[alloc.name].cpuReqCoreHrs += - get(alloc, 'cpuCoreRequestAverage', 0) * hrs; - result[alloc.name].ramUseByteHrs += - get(alloc, 'ramByteUsageAverage', 0) * hrs; - result[alloc.name].ramReqByteHrs += - get(alloc, 'ramByteRequestAverage', 0) * hrs; - } - }); - }); - - // If the range is of length > 1 (i.e. it is not just a single set) then - // compute efficiency for each result after accumulating. - if (allocationSetRange.length > 1) { - forEach(result, (alloc, name) => { - // If we can't compute total efficiency, it defaults to 0.0 - let totalEfficiency = 0.0; - - // CPU efficiency is defined as (usage/request). If request == 0.0 but - // usage > 0, then efficiency gets set to 1.0. - let cpuEfficiency = 0.0; - if (alloc.cpuReqCoreHrs > 0) { - cpuEfficiency = alloc.cpuUseCoreHrs / alloc.cpuReqCoreHrs; - } else if (alloc.cpuUseCoreHrs > 0) { - cpuEfficiency = 1.0; - } - - // RAM efficiency is defined as (usage/request). If request == 0.0 but - // usage > 0, then efficiency gets set to 1.0. - let ramEfficiency = 0.0; - if (alloc.ramReqByteHrs > 0) { - ramEfficiency = alloc.ramUseByteHrs / alloc.ramReqByteHrs; - } else if (alloc.ramUseByteHrs > 0) { - ramEfficiency = 1.0; - } - - // Compute efficiency as the cost-weighted average of CPU and RAM - // efficiency - if (alloc.cpuCost + alloc.ramCost > 0.0) { - totalEfficiency = - (alloc.cpuCost * cpuEfficiency + alloc.ramCost * ramEfficiency) / - (alloc.cpuCost + alloc.ramCost); - } - - result[name].cpuEfficiency = cpuEfficiency; - result[name].ramEfficiency = ramEfficiency; - result[name].totalEfficiency = totalEfficiency; - }); - } - - return result; -} - -// cumulativeToTotals adds each entry in the given AllocationSet (type: object) -// and returns a single Allocation (type: object) representing the totals -export function cumulativeToTotals(allocationSet) { - const totals = { - name: 'Totals', - cpuCost: 0, - gpuCost: 0, - ramCost: 0, - pvCost: 0, - networkCost: 0, - sharedCost: 0, - externalCost: 0, - totalCost: 0, - cpuEfficiency: 0, - ramEfficiency: 0, - totalEfficiency: 0, - }; - - // Use these for computing efficiency. As such, idle will not factor into - // these numbers, including CPU and RAM cost. - let cpuReqCoreHrs = 0; - let cpuUseCoreHrs = 0; - let ramReqByteHrs = 0; - let ramUseByteHrs = 0; - let cpuCost = 0; - let ramCost = 0; - - forEach(allocationSet, (alloc, name) => { - // Accumulate efficiency-related fields - if (name !== '__idle__') { - cpuReqCoreHrs += get(alloc, 'cpuReqCoreHrs', 0.0); - cpuUseCoreHrs += get(alloc, 'cpuUseCoreHrs', 0.0); - ramReqByteHrs += get(alloc, 'ramReqByteHrs', 0.0); - ramUseByteHrs += get(alloc, 'ramUseByteHrs', 0.0); - cpuCost += get(alloc, 'cpuCost', 0.0); - ramCost += get(alloc, 'ramCost', 0.0); - } - - // Sum cumulative fields - totals.cpuCost += get(alloc, 'cpuCost', 0); - totals.gpuCost += get(alloc, 'gpuCost', 0); - totals.ramCost += get(alloc, 'ramCost', 0); - totals.pvCost += get(alloc, 'pvCost', 0); - totals.networkCost += get(alloc, 'networkCost', 0); - totals.sharedCost += get(alloc, 'sharedCost', 0); - totals.externalCost += get(alloc, 'externalCost', 0); - totals.totalCost += get(alloc, 'totalCost', 0); - }); - - // Compute efficiency - if (cpuReqCoreHrs > 0) { - totals.cpuEfficiency = cpuUseCoreHrs / cpuReqCoreHrs; - } else if (cpuUseCoreHrs > 0) { - totals.cpuEfficiency = 1.0; - } - - if (ramReqByteHrs > 0) { - totals.ramEfficiency = ramUseByteHrs / ramReqByteHrs; - } else if (ramUseByteHrs > 0) { - totals.ramEfficiency = 1.0; - } - - if (cpuCost + ramCost > 0) { - totals.totalEfficiency = - (cpuCost * totals.cpuEfficiency + ramCost * totals.ramEfficiency) / - (cpuCost + ramCost); - } - - totals.cpuReqCoreHrs = cpuReqCoreHrs; - totals.cpuUseCoreHrs = cpuUseCoreHrs; - totals.ramReqByteHrs = ramReqByteHrs; - totals.ramUseByteHrs = ramUseByteHrs; - - return totals; -} - -export function toVerboseTimeRange(window) { - const months = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', - ]; - - const start = new Date(); - start.setUTCHours(0, 0, 0, 0); - - const end = new Date(); - end.setUTCHours(0, 0, 0, 0); - - switch (window) { - case 'today': - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()}`; - case 'yesterday': - start.setUTCDate(start.getUTCDate() - 1); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()}`; - case 'week': - start.setUTCDate(start.getUTCDate() - start.getUTCDay()); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} until now`; - case 'month': - start.setUTCDate(1); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} until now`; - case 'lastweek': - start.setUTCDate(start.getUTCDate() - (start.getUTCDay() + 7)); - end.setUTCDate(end.getUTCDate() - (end.getUTCDay() + 1)); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through ${end.getUTCDate()} ${ - months[end.getUTCMonth()] - } ${end.getUTCFullYear()}`; - case 'lastmonth': - end.setUTCDate(1); - end.setUTCDate(end.getUTCDate() - 1); - start.setUTCDate(1); - start.setUTCDate(start.getUTCDate() - 1); - start.setUTCDate(1); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through ${end.getUTCDate()} ${ - months[end.getUTCMonth()] - } ${end.getUTCFullYear()}`; - case '6d': - start.setUTCDate(start.getUTCDate() - 6); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through now`; - case '29d': - start.setUTCDate(start.getUTCDate() - 29); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through now`; - case '59d': - start.setUTCDate(start.getUTCDate() - 59); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through now`; - case '89d': - start.setUTCDate(start.getUTCDate() - 89); - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through now`; - // no default - } - - const splitDates = window.split(','); - if (checkCustomWindow(window) && splitDates.length > 1) { - const s = splitDates[0].split(/\D+/).slice(0, 3); - const e = splitDates[1].split(/\D+/).slice(0, 3); - if (s.length === 3 && e.length === 3) { - start.setUTCFullYear(s[0], s[1] - 1, s[2]); - end.setUTCFullYear(e[0], e[1] - 1, e[2]); - if (start === end) { - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()}`; - } - return `${start.getUTCDate()} ${ - months[start.getUTCMonth()] - } ${start.getUTCFullYear()} through ${end.getUTCDate()} ${ - months[end.getUTCMonth()] - } ${end.getUTCFullYear()}`; - } - } - return ''; -} - -export function bytesToString(bytes) { - const ei = Math.pow(1024, 6); - if (bytes >= ei) { - return `${round(bytes / ei, 1)} EiB`; - } - const pi = Math.pow(1024, 5); - if (bytes >= pi) { - return `${round(bytes / pi, 1)} PiB`; - } - const ti = Math.pow(1024, 4); - if (bytes >= ti) { - return `${round(bytes / ti, 1)} TiB`; - } - const gi = Math.pow(1024, 3); - if (bytes >= gi) { - return `${round(bytes / gi, 1)} GiB`; - } - const mi = Math.pow(1024, 2); - if (bytes >= mi) { - return `${round(bytes / mi, 1)} MiB`; - } - const ki = Math.pow(1024, 1); - if (bytes >= ki) { - return `${round(bytes / ki, 1)} KiB`; - } - - return `${round(bytes, 1)} B`; -} - -const currencyLocale = 'en-US'; - -export function toCurrency(amount, currency, precision) { - if (typeof amount !== 'number') { - Console.warn( - `Tried to convert "${amount}" to currency, but it is not a number`, - ); - return ''; - } - - let ctype = currency; - - if (currency === undefined || currency === '') { - ctype = 'USD'; - } - - const opts = { - style: 'currency', - currency: ctype, - }; - - if (typeof precision === 'number') { - opts.minimumFractionDigits = precision; - opts.maximumFractionDigits = precision; - } - - return amount.toLocaleString(currencyLocale, opts); -} - -export function checkCustomWindow(window) { - // Example ISO interval string: 2020-12-02T00:00:00Z,2020-12-03T23:59:59Z - const customDateRegex = - /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z,\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/; - return customDateRegex.test(window); -} - -export default { - rangeToCumulative, - cumulativeToTotals, - toVerboseTimeRange, - bytesToString, - toCurrency, - checkCustomWindow, -}; diff --git a/plugins/org-react/.eslintrc.js b/plugins/org-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/org-react/.eslintrc.js +++ b/plugins/org-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index f9433defe8..1d25ba359c 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,132 @@ # @backstage/plugin-org-react +## 0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + +## 0.1.23 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- cfb2b78: Added the `no-top-level-material-ui-4-imports` ESLint rule to aid with the migration to Material UI v5 +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + +## 0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## 0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## 0.1.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## 0.1.21 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.2 + - @backstage/core-components@0.14.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + +## 0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + +## 0.1.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + +## 0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + +## 0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + +## 0.1.19 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + ## 0.1.19-next.3 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index fcd5d98ee2..985e05b3c5 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,35 +1,38 @@ { "name": "@backstage/plugin-org-react", - "version": "0.1.19-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "0.1.24-next.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/org-react" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -43,21 +46,18 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx index 57a93ce0fe..4f28faa1eb 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPicker.tsx @@ -21,7 +21,7 @@ import { } from '@backstage/plugin-catalog-react'; import TextField from '@material-ui/core/TextField'; import Autocomplete from '@material-ui/lab/Autocomplete'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import Popover from '@material-ui/core/Popover'; import { useApi } from '@backstage/core-plugin-api'; import { ResponseErrorPanel } from '@backstage/core-components'; diff --git a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx index f4255a18be..b7a31f89f2 100644 --- a/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx +++ b/plugins/org-react/src/components/GroupListPicker/GroupListPickerButton.tsx @@ -15,7 +15,9 @@ */ import React from 'react'; -import { makeStyles, Typography, Button } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown'; import PeopleIcon from '@material-ui/icons/People'; diff --git a/plugins/org/.eslintrc.js b/plugins/org/.eslintrc.js index e2a53a6ad2..a2d8179106 100644 --- a/plugins/org/.eslintrc.js +++ b/plugins/org/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 2b819ea526..17cb3d14a9 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,163 @@ # @backstage/plugin-org +## 0.6.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + +## 0.6.24 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## 0.6.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## 0.6.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## 0.6.23 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 0df5c60: Added ESLint rule `no-top-level-material-ui-4-imports` in the `org` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## 0.6.22 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- 0df5c60: Added ESLint rule `no-top-level-material-ui-4-imports` in the `org` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## 0.6.21 + +### Patch Changes + +- b7b0466: Remove the use of the deprecated `customStyles` for `Avatar` +- 526f00a: Document the new frontend system extensions for the org plugin. +- 2219f8c: Add `relationsType` argument to `MembersListCard`. + This can be used to display an aggregated user list for groups by default. +- a767aaa: Fixed an issue where the `OwnershipCard` component failed to scroll properly when used alongside `react-grid-layout`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-catalog-common@1.0.22 + +## 0.6.21-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## 0.6.21-next.1 + +### Patch Changes + +- a767aaa: Fixed an issue where the `OwnershipCard` component failed to scroll properly when used alongside `react-grid-layout`. +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## 0.6.21-next.0 + +### Patch Changes + +- 526f00a: Document the new frontend system extensions for the org plugin. +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## 0.6.20 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 6e1bf50: Added basic support for the new frontend system, exported from the `/alpha` subpath. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-catalog-common@1.0.21 + ## 0.6.20-next.3 ### Patch Changes diff --git a/plugins/org/README-alpha.md b/plugins/org/README-alpha.md new file mode 100644 index 0000000000..c8f9aee0d6 --- /dev/null +++ b/plugins/org/README-alpha.md @@ -0,0 +1,364 @@ +# Org Plugin + +> [!WARNING] +> This documentation is made for those using the experimental new Frontend system. +> If you are not using the new frontend system, please go [here](./README.md). + +This is a plugin that extends the Catalog entity page with some users and groups overview cards: + +- Group Profile Entity Card +- Member List Entity Card +- Ownership Entity Card +- User Profile Entity Card + +Here is a Catalog group page showing the group profile, members, and ownership cards: + +![Group Page example](./docs/group-page-example.png) + +And below is an example of how a user page looks with the user profile and ownership cards: + +![Group Page example](./docs/user-profile-example.png) + +## Table of Content + +- [Installation](#installation) +- [Packages](#packages) +- [Routes](#routes) +- [Extensions](#extensions) + - [Entity Group Profile Card](#entity-group-profile-card) + - [Entity Group Profile Card](#entity-members-list-card) + - [Entity Group Profile Card](#entity-members-list-card) + - [Entity Group Profile Card](#entity-user-profile-card) + - [My Groups Sidebar Item](#my-groups-sidebar-item) + +## Installation + +1. Install the `org` plugin in your Backstage app: + + ```bash + # From your Backstage root directory + yarn --cwd packages/app add @backstage/plugin-org + ``` + +2. Enable which entity cards and tabs you would like to see on the catalog entity page: + + > [!IMPORTANT] + > The order in which cards are listed in the configuration file will determine the order in which they appear in overview cards and tab lists on entity pages. + + ```yaml + # app-config.yaml + app: + experimental: + # Auto discovering all plugins extensions + packages: all + extensions: + # Enabling the org plugin cards + - entity-card:org/group-profile + - entity-card:org/members-list + - entity-card:org/ownership + - entity-card:org/user-profile + ``` + +3. Then start the app, navigate to an entity's page and see the cards and contents in there. + +## Packages + +The `org` plugin can be automatically discovered, and it is also possible to enable it only in certain [environments](https://backstage.io/docs/conf/writing/#configuration-files). See [this](https://backstage.io/docs/frontend-system/architecture/app/#feature-discovery) packages documentation for more details. + +## Routes + +The `org` plugin exposes an external route ref that can be used to configure route bindings. + +| Key | Type | Description | +| -------------- | -------------- | ---------------------------------- | +| `catalogIndex` | External route | A route ref to Catalog Index page. | + +As an example, here is an association between the external catalog index page and a regular route from another plugin: + +```yaml +# app-config.yaml +app: + routes: + bindings: + # example binding org and catalog index pages + org.catalogIndex: catalog.catalogIndex +``` + +Route binding is also possible through code. For more information, see [this](https://backstage.io/docs/frontend-system/architecture/routes#binding-external-route-references) documentation. + +## Extensions + +### Entity Group Profile Card + +This [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension allows you to view, edit, or update groups metadata, such as team avatar, name, email, parent, and child groups. + +| Kind | Namespace | Name | Id | +| ------------- | --------- | --------------- | ------------------------------- | +| `entity-card` | `org` | `group-profile` | `entity-card:org/group-profile` | + +#### Config + +Currently, this entity card extension has only one configuration: + +| Config key | Default value | Description | +| ---------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `filter` | `kind:group` | An [entity filter](https://github.com/backstage/backstage/pull/21480) that determines when the card should be displayed on the entity page. | + +This is how to configure the `group-profile` extension in the `app-config.yaml` file: + +```yaml +app: + extensions: + - entity-card:org/group-profile: + config: + : '' +``` + +#### Override + +Use extension overrides for completely re-implementing the group-profile entity card extension: + +```tsx +import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; + +export default createExtensionOverrides({ + extensions: [ + createEntityCardExtension({ + // These namespace and name are necessary so the system knows that this extension will override the default 'group-profile' entity card extension provided by the 'org' plugin + namespace: 'org', + name: 'group-profile', + // By default, this card will show up only for groups + filter: 'kind:group' + // Returing a custom card component + loader: () => + import('./components').then(m => ), + }), + ], +}); +``` + +For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). + +### Entity Members List Card + +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that displays the names and emails of group members. By clicking the member's name, you'll be directed to the user's catalog page, and the email opens your default email program. + +| Kind | Namespace | Name | Id | +| ------------- | --------- | -------------- | ------------------------------ | +| `entity-card` | `org` | `members-list` | `entity-card:org/members-list` | + +#### Config + +Currently, this entity card extension has only one configuration: + +| Config key | Default value | Description | +| ---------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `filter` | `kind:group` | An [entity filter](https://github.com/backstage/backstage/pull/21480) that determines when the card should be displayed on the entity page. | + +This is how to configure the `members-list` extension in the `app-config.yaml` file: + +```yaml +app: + extensions: + - entity-card:org/members-list: + config: + : '' +``` + +#### Override + +Use extension overrides for completely re-implementing the members-list entity card extension: + +```tsx +import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; + +export default createExtensionOverrides({ + extensions: [ + createEntityCardExtension({ + // These namespace and name are necessary so the system knows that this extension will override the default 'members-list' entity card extension provided by the 'org' plugin + namespace: 'org', + name: 'members-list', + // By default, this card will show up only for groups + filter: 'kind:group' + // Returing a custom card component + loader: () => + import('./components').then(m => ), + }), + ], +}); +``` + +For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). + +### Entity Ownership Card + +An [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension that displays direct or aggregated group or user ownership relationships. Each entity listed in the card links to its respective entity page in the catalog. + +| Kind | Namespace | Name | Id | +| ------------- | --------- | ----------- | --------------------------- | +| `entity-card` | `org` | `ownership` | `entity-card:org/ownership` | + +#### Config + +Currently, this entity card extension has only one configuration: + +| Config key | Default value | Description | +| ---------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `filter` | `kind:group,user` | An [entity filter](https://github.com/backstage/backstage/pull/21480) that determines when the card should be displayed on the entity page. | + +This is how to configure the `ownership` extension in the `app-config.yaml` file: + +```yaml +app: + extensions: + - entity-card:org/ownership: + config: + : '' +``` + +#### Override + +Use extension overrides for completely re-implementing the ownership entity card extension: + +```tsx +import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; + +export default createExtensionOverrides({ + extensions: [ + createEntityCardExtension({ + // These namespace and name are necessary so the system knows that this extension will override the default 'ownership' entity card extension provided by the 'org' plugin + namespace: 'org', + name: 'ownership', + // By default, this card will show up only for groups or users + filter: 'kind:group,user' + // Returing a custom card component + loader: () => + import('./components').then(m => ), + }), + ], +}); +``` + +For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). + +### Entity User Profile Card + +This [entity card](https://github.com/backstage/backstage/blob/master/plugins/catalog-react/api-report-alpha.md) extension allows you to view user metadata including avatar, name, email, and team. Clicking on the email link will open your default email program while clicking on the team link will direct you to the team page in the catalog plugin. + +| Kind | Namespace | Name | Id | +| ------------- | --------- | -------------- | ------------------------------ | +| `entity-card` | `org` | `user-profile` | `entity-card:org/user-profile` | + +#### Config + +Currently, this entity card extension has only one configuration: + +| Config key | Default value | Description | +| ---------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `filter` | `kind:user` | An [entity filter](https://github.com/backstage/backstage/pull/21480) that determines when the card should be displayed on the entity page. | + +This is how to configure the `user-profile` extension in the `app-config.yaml` file: + +```yaml +app: + extensions: + - entity-card:org/user-profile: + config: + : '' +``` + +#### Override + +Use extension overrides for completely re-implementing the user-profile entity card extension: + +```tsx +import { createExtensionOverrides } from '@backstage/backstage-plugin-api'; +import { createEntityCardExtension } from '@backstage/plugin-catalog-react/alpha'; + +export default createExtensionOverrides({ + extensions: [ + createEntityCardExtension({ + // These namespace and name are necessary so the system knows that this extension will override the default 'user-profile' entity card extension provided by the 'org' plugin + namespace: 'org', + name: 'user-profile', + // By default, this card will show up only for groups or users + filter: 'kind:user' + // Returing a custom card component + loader: () => + import('./components').then(m => ), + }), + ], +}); +``` + +For more information about where to place extension overrides, see the official [documentation](https://backstage.io/docs/frontend-system/architecture/extension-overrides). + +### My Groups Sidebar Item + +As the [NavItem](https://backstage.io/docs/reference/frontend-plugin-api.createnavitemextension) extension type does not support conditional rendering, this plugin does not provide navigation items, so to use the `MyGroupsSidebarItem` component, we recommend overriding the [App/Nav](https://backstage.io/docs/frontend-system/building-apps/built-in-extensions#app-nav) extension and adding the item statically. + +> [!IMPORTANT] +> As you can see in the example below, we are using the same attachment point, inputs and outputs as the default App/Nav extension to avoid side effects on the NavItem and NavLogo extensions. + +```tsx +// ... +import { MyGroupsSidebarItem } from '@backstage/plugin-org'; +import GroupIcon from '@material-ui/icons/People'; + +export default createExtensionOverrides({ + extensions: [ + createExtension({ + // These namespace and name are necessary so the system knows that this extension will override the default app nav extension + namespace: 'app', + name: 'nav', + // Keeping the same attachment point as in the default App/Nav extension + attachTo: { id: 'app/layout', input: 'nav' }, + // Keeping the same inputs as in the default App/Nav extension + inputs: { + items: createExtensionInput({ + target: createNavItemExtension.targetDataRef, + }), + logos: createExtensionInput( + { + elements: createNavLogoExtension.logoElementsDataRef, + }, + { + singleton: true, + optional: true, + }, + ), + }, + // Keeping the same output as in the default App/Nav extension + output: { + element: coreExtensionData.reactElement, + }, + factory({ inputs }) { + return { + element: ( + + {/* Code borrowed from the default extension implementation to render the logos and items inputs */} + + + {inputs.items.map((item, index) => ( + + ))} + {/* Here is where we actually modifies the default implementation by adding a static item to render a group of squad pages */} + }> + {/* The MyGroupsSidebarItem provides quick access to the group(s) the logged in user is a member of directly in the sidebar. */} + + + + ), + }; + }, + }), + ], +}); +``` diff --git a/plugins/org/README.md b/plugins/org/README.md index 0c5452aa62..9cf165f06d 100644 --- a/plugins/org/README.md +++ b/plugins/org/README.md @@ -1,5 +1,8 @@ # Org Plugin for Backstage +> Disclaimer: +> If you are looking for documentation on the experimental new frontend system support, please go [here](./README-alpha.md). + ## Features - Show Group Page diff --git a/plugins/org/api-report.md b/plugins/org/api-report.md index 922b25b610..1960ce839b 100644 --- a/plugins/org/api-report.md +++ b/plugins/org/api-report.md @@ -23,6 +23,7 @@ export const EntityMembersListCard: (props: { memberDisplayTitle?: string | undefined; pageSize?: number | undefined; showAggregateMembersToggle?: boolean | undefined; + relationsType?: EntityRelationAggregation | undefined; }) => JSX_2.Element; // @public (undocumented) @@ -54,6 +55,7 @@ export const MembersListCard: (props: { memberDisplayTitle?: string; pageSize?: number; showAggregateMembersToggle?: boolean; + relationsType?: EntityRelationAggregation; }) => React_2.JSX.Element; // @public diff --git a/plugins/org/package.json b/plugins/org/package.json index f1f6d1af46..c07ef33428 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,14 +1,28 @@ { "name": "@backstage/plugin-org", + "version": "0.6.25-next.0", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.6.20-next.3", - "main": "src/index.ts", - "types": "src/index.ts", + "backstage": { + "role": "frontend-plugin" + }, + "publishConfig": { + "access": "public" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/org" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -19,28 +33,17 @@ ] } }, - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/org" - }, - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -60,11 +63,6 @@ "qs": "^6.10.1", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/catalog-client": "workspace:^", "@backstage/cli": "workspace:^", @@ -75,12 +73,14 @@ "@backstage/plugin-permission-react": "workspace:^", "@backstage/test-utils": "workspace:^", "@backstage/types": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx index 17f285c039..5e6e5b72b4 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -24,7 +24,7 @@ import { import { permissionApiRef } from '@backstage/plugin-permission-react'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import React, { ComponentType, PropsWithChildren } from 'react'; import { GroupProfileCard } from './GroupProfileCard'; diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx index 33c6ee137a..b863bef482 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx @@ -28,16 +28,14 @@ import { InfoCardVariants, Link, } from '@backstage/core-components'; -import { - Box, - Grid, - IconButton, - List, - ListItem, - ListItemIcon, - ListItemText, - Tooltip, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Grid from '@material-ui/core/Grid'; +import IconButton from '@material-ui/core/IconButton'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Tooltip from '@material-ui/core/Tooltip'; import { EntityRefLinks, catalogApiRef, diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx index 0e2b6a39f7..db54be9e02 100644 --- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.stories.tsx @@ -17,7 +17,7 @@ import { Entity, GroupEntity } from '@backstage/catalog-model'; import { catalogApiRef, EntityProvider } from '@backstage/plugin-catalog-react'; import { TestApiProvider } from '@backstage/test-utils'; -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx index cd5801ac71..06ec3b0ebd 100644 --- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx +++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx @@ -311,15 +311,20 @@ describe('MemberTab Test', () => { }, }, ); + + // Should show only direct users on initial load + const displayedMemberNamesBefore = screen.queryAllByTestId('user-link'); + expect(displayedMemberNamesBefore).toHaveLength(2); + // Click the toggle switch await userEvent.click(screen.getByRole('checkbox')); - const displayedMemberNames = screen.queryAllByTestId('user-link'); + const displayedMemberNamesAfter = screen.queryAllByTestId('user-link'); const duplicatedUserText = screen.getByText('Duplicated User'); const groupAUserOneText = screen.getByText('Group A User One'); const groupBUserOneText = screen.getByText('Group B User One'); const groupDUserOneText = screen.getByText('Group D User One'); const groupEUserOneText = screen.getByText('Group E User One'); - expect(displayedMemberNames).toHaveLength(5); + expect(displayedMemberNamesAfter).toHaveLength(5); expect(duplicatedUserText).toBeInTheDocument(); expect(groupAUserOneText).toBeInTheDocument(); expect(groupBUserOneText).toBeInTheDocument(); @@ -339,4 +344,77 @@ describe('MemberTab Test', () => { ); }); }); + + it('Can default to show aggregated members with the aggregate members toggle', async () => { + await renderInTestApp( + + + + + + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + '/catalog': rootRouteRef, + }, + }, + ); + + // Should show aggregated users on initial load + const displayedMemberNamesBefore = screen.queryAllByTestId('user-link'); + expect(displayedMemberNamesBefore).toHaveLength(5); + + // Click the toggle switch + await userEvent.click(screen.getByRole('checkbox')); + + // Should now show only direct users + const displayedMemberNamesAfter = screen.queryAllByTestId('user-link'); + expect(displayedMemberNamesAfter).toHaveLength(2); + }); + + it('Can show aggregated members without the aggregate members toggle', async () => { + await renderInTestApp( + + + + + + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + '/catalog': rootRouteRef, + }, + }, + ); + + // aggregated relations checkbox should not be rendered + expect(screen.queryByRole('checkbox')).toBeNull(); + + // Should show all descendant users on load + const displayedMemberNames = screen.queryAllByTestId('user-link'); + expect(displayedMemberNames).toHaveLength(5); + }); }); diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx index 8967e7cdd7..418a83f5b2 100644 --- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx +++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx @@ -21,18 +21,14 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react'; -import { - Box, - createStyles, - Grid, - makeStyles, - Switch, - Theme, - Typography, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Grid from '@material-ui/core/Grid'; +import Switch from '@material-ui/core/Switch'; +import Typography from '@material-ui/core/Typography'; +import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; import Pagination from '@material-ui/lab/Pagination'; import React, { useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import { Avatar, @@ -48,20 +44,27 @@ import { removeDuplicateEntitiesFrom, } from '../../../../helpers/helpers'; import { EntityRefLink } from '@backstage/plugin-catalog-react'; +import { EntityRelationAggregation } from '../../types'; -const useStyles = makeStyles((theme: Theme) => - createStyles({ - card: { - border: `1px solid ${theme.palette.divider}`, - boxShadow: theme.shadows[2], - borderRadius: '4px', - overflow: 'visible', - position: 'relative', - margin: theme.spacing(4, 1, 1), - flex: '1', - minWidth: '0px', - }, - }), +const useStyles = makeStyles( + (theme: Theme) => + createStyles({ + card: { + border: `1px solid ${theme.palette.divider}`, + boxShadow: theme.shadows[2], + borderRadius: '4px', + overflow: 'visible', + position: 'relative', + margin: theme.spacing(4, 1, 1), + flex: '1', + minWidth: '0px', + }, + avatar: { + position: 'absolute', + top: '-2rem', + }, + }), + { name: 'MembersListCardComponent' }, ); const MemberComponent = (props: { member: UserEntity }) => { @@ -84,10 +87,7 @@ const MemberComponent = (props: { member: UserEntity }) => { { const { memberDisplayTitle = 'Members', pageSize = 50, showAggregateMembersToggle, + relationsType = 'direct', } = props; const classes = useListStyles(); @@ -162,11 +164,13 @@ export const MembersListCard = (props: { setPage(pageIndex); }; - const [showAggregateMembers, setShowAggregateMembers] = useState(false); + const [showAggregateMembers, setShowAggregateMembers] = useState( + relationsType === 'aggregated', + ); const { loading: loadingDescendantMembers, value: descendantMembers } = useAsync(async () => { - if (!showAggregateMembersToggle) { + if (!showAggregateMembers) { return [] as UserEntity[]; } @@ -174,7 +178,7 @@ export const MembersListCard = (props: { groupEntity, catalogApi, ); - }, [catalogApi, groupEntity, showAggregateMembersToggle]); + }, [catalogApi, groupEntity, showAggregateMembers]); const { loading, error, @@ -229,7 +233,7 @@ export const MembersListCard = (props: { memberList = ( {members.slice(pageSize * (page - 1), pageSize * page).map(member => ( - + ))} ); diff --git a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx index dfc654c14b..895bf33205 100644 --- a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx +++ b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx @@ -16,12 +16,10 @@ import { EntityLink } from '@backstage/catalog-model'; import { IconComponent, useApp } from '@backstage/core-plugin-api'; import LanguageIcon from '@material-ui/icons/Language'; -import { - ListItem, - ListItemIcon, - ListItemText, - Divider, -} from '@material-ui/core'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Divider from '@material-ui/core/Divider'; import React from 'react'; import { Link } from '@backstage/core-components'; diff --git a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx index cffed95c7a..ff16a4ab2d 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx @@ -22,18 +22,15 @@ import { ResponseErrorPanel, } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; -import { - Box, - createStyles, - Grid, - makeStyles, - Typography, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Grid from '@material-ui/core/Grid'; +import Typography from '@material-ui/core/Typography'; +import { createStyles, makeStyles } from '@material-ui/core/styles'; import React from 'react'; import pluralize from 'pluralize'; import { catalogIndexRouteRef } from '../../../routes'; import { useGetEntities } from './useGetEntities'; -import { EntityRelationAggregation } from './types'; +import { EntityRelationAggregation } from '../types'; const useStyles = makeStyles(theme => createStyles({ @@ -107,11 +104,13 @@ const EntityCountTile = ({ }; export const ComponentsGrid = ({ + className, entity, relationsType, entityFilterKind, entityLimit = 6, }: { + className?: string; entity: Entity; relationsType: EntityRelationAggregation; entityFilterKind?: string[]; @@ -132,7 +131,7 @@ export const ComponentsGrid = ({ } return ( - + {componentsWithCounters?.map(c => ( - + diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx index 791ce5ca64..a5b0b7bb19 100644 --- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx +++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx @@ -16,20 +16,26 @@ import { InfoCard, InfoCardVariants } from '@backstage/core-components'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { - List, - ListItem, - ListItemSecondaryAction, - ListItemText, - makeStyles, - Switch, - Tooltip, -} from '@material-ui/core'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemText from '@material-ui/core/ListItemText'; +import Switch from '@material-ui/core/Switch'; +import Tooltip from '@material-ui/core/Tooltip'; +import { makeStyles } from '@material-ui/core/styles'; import React, { useEffect, useState } from 'react'; import { ComponentsGrid } from './ComponentsGrid'; -import { EntityRelationAggregation } from './types'; +import { EntityRelationAggregation } from '../types'; const useStyles = makeStyles(theme => ({ + card: { + maxHeight: '100%', + }, + cardContent: { + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + }, list: { [theme.breakpoints.down('xs')]: { padding: `0 0 12px`, @@ -50,6 +56,10 @@ const useStyles = makeStyles(theme => ({ transform: 'unset', }, }, + grid: { + overflowY: 'auto', + marginTop: 0, + }, })); /** @public */ @@ -84,7 +94,12 @@ export const OwnershipCard = (props: { }, [setRelationsType, defaultRelationsType, relationsType]); return ( - + {!relationsToggle && ( @@ -118,6 +133,7 @@ export const OwnershipCard = (props: { )} => { const isGroup = entity.kind === 'Group'; @@ -166,7 +166,7 @@ const getOwnedEntitiesByOwners = ( export function useGetEntities( entity: Entity, - relations: EntityRelationsAggregation, + relations: EntityRelationAggregation, entityFilterKind?: string[], entityLimit = 6, ): { diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx index 6326a043bc..e5d6ab4d19 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.stories.tsx @@ -20,7 +20,7 @@ import { entityRouteRef, } from '@backstage/plugin-catalog-react'; import { wrapInTestApp } from '@backstage/test-utils'; -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import React, { ComponentType, PropsWithChildren } from 'react'; import { UserProfileCard } from './UserProfileCard'; diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx index a45658b3a6..3c60599a39 100644 --- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx +++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx @@ -25,16 +25,14 @@ import { InfoCardVariants, Link, } from '@backstage/core-components'; -import { - Box, - Grid, - IconButton, - List, - ListItem, - ListItemIcon, - ListItemText, - Tooltip, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Grid from '@material-ui/core/Grid'; +import IconButton from '@material-ui/core/IconButton'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Tooltip from '@material-ui/core/Tooltip'; import { EntityRefLinks, getEntityRelations, diff --git a/plugins/org/src/components/Cards/index.ts b/plugins/org/src/components/Cards/index.ts index aec3d8da5e..4c57f5a422 100644 --- a/plugins/org/src/components/Cards/index.ts +++ b/plugins/org/src/components/Cards/index.ts @@ -16,3 +16,4 @@ export * from './Group'; export * from './User'; export * from './OwnershipCard'; +export type { EntityRelationAggregation } from './types'; diff --git a/plugins/org/src/components/Cards/OwnershipCard/types.ts b/plugins/org/src/components/Cards/types.ts similarity index 100% rename from plugins/org/src/components/Cards/OwnershipCard/types.ts rename to plugins/org/src/components/Cards/types.ts diff --git a/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx b/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx index f3e3a6bd9a..7e82d9f928 100644 --- a/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx +++ b/plugins/org/src/components/MyGroupsSidebarItem/MyGroupsSidebarItem.tsx @@ -30,7 +30,7 @@ import { useApi, useRouteRef, } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import { catalogApiRef, CatalogApi, diff --git a/plugins/pagerduty/.eslintrc.js b/plugins/pagerduty/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/pagerduty/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md deleted file mode 100644 index e22fa6b1f5..0000000000 --- a/plugins/pagerduty/CHANGELOG.md +++ /dev/null @@ -1,1734 +0,0 @@ -# @backstage/plugin-pagerduty - -## 0.7.2-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/plugin-home-react@0.1.8-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.7.2-next.2 - -### Patch Changes - -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/plugin-home-react@0.1.8-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.7.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/plugin-home-react@0.1.8-next.1 - - @backstage/errors@1.2.3 - -## 0.7.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/plugin-home-react@0.1.8-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.7.1 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-home-react@0.1.7 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.7.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.7-next.2 - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.7.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/plugin-home-react@0.1.7-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.7.1-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/plugin-home-react@0.1.7-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.7.0 - -### Minor Changes - -- 5fca16f: This package has been deprecated, consider using [@pagerduty/backstage-plugin](https://github.com/pagerduty/backstage-plugin) instead. - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/plugin-home-react@0.1.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.7.0-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.6-next.3 - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.7.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-home-react@0.1.6-next.2 - -## 0.7.0-next.1 - -### Minor Changes - -- 5fca16fdf6: This package has been deprecated, consider using [@pagerduty/backstage-plugin](https://github.com/pagerduty/backstage-plugin) instead. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/plugin-home-react@0.1.6-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.6.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/plugin-home-react@0.1.6-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.6.7 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/plugin-home-react@0.1.5 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.6.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - - @backstage/plugin-home-react@0.1.5-next.2 - -## 0.6.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - - @backstage/plugin-home-react@0.1.5-next.1 - -## 0.6.7-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/plugin-home-react@0.1.5-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.6.6 - -### Patch Changes - -- b9ce306814: Minor fix to avoid usage of deprecated prop -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/plugin-home-react@0.1.4 - - @backstage/theme@0.4.3 - -## 0.6.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - - @backstage/plugin-home-react@0.1.4-next.2 - -## 0.6.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/plugin-home-react@0.1.4-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.6.6-next.0 - -### Patch Changes - -- b9ce306814: Minor fix to avoid usage of deprecated prop -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/plugin-home-react@0.1.4-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.6.5 - -### Patch Changes - -- 3b41afed4d0c: Minor internal tweaks to improve tests -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-home-react@0.1.3 - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.6.5-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/plugin-home-react@0.1.3-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.6.5-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-home-react@0.1.3-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.6.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/plugin-home-react@0.1.3-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.6.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.3-next.0 - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.6.2 - -### Patch Changes - -- 5003fc966741: Add new `disableChangeEvents` prop to `EntityPagerDutyCard` to hide the Change Events tab and disable fetching of change events for the PagerDuty service. -- Updated dependencies - - @backstage/plugin-home-react@0.1.2 - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.6.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - - @backstage/plugin-home-react@0.1.2-next.0 - -## 0.6.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.2-next.0 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.6.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/plugin-home-react@0.1.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.6.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/plugin-home-react@0.1.1-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - -## 0.6.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - - @backstage/plugin-home-react@0.1.1-next.1 - -## 0.6.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - - @backstage/plugin-home-react@0.1.1-next.0 - -## 0.6.0 - -### Minor Changes - -- 64bc274a1ee6: Adds a config schema definition so the plugin will validate with the new Backstage CLI "--strict" flag - -### Patch Changes - -- 9512f13eb3af: Add a homepage widget for the `Pagerduty` component. -- 3d11596a72b5: Update plugin installation docs to be more consistent across documentations -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - - @backstage/plugin-home-react@0.1.0 - -## 0.5.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - - @backstage/plugin-home-react@0.1.0-next.3 - -## 0.5.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/plugin-home-react@0.1.0-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.5.12-next.1 - -### Patch Changes - -- 9512f13eb3af: Add a homepage widget for the `Pagerduty` component. -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/plugin-home-react@0.1.0-next.1 - - @backstage/theme@0.4.0-next.0 - -## 0.5.12-next.0 - -### Patch Changes - -- 3d11596a72b5: Update plugin installation docs to be more consistent across documentations -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.5.11 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.5.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.5.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.5.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19 - -## 0.5.10 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.5.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.5.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.5.10-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.5.10-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - -## 0.5.9 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 9c08ecbaa4b: Update readme link for discord channel -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.5.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.5.9-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 9c08ecbaa4b: Update readme link for discord channel -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.5.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 - -## 0.5.8 - -### Patch Changes - -- 804746dd58: The PagerDutyCard now supports an optional `readOnly` property (``) for suppressing the rendering of the "Create Incident" button from the Backstage UI. -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/errors@1.1.4 - -## 0.5.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.5.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.5.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.5.7 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.5.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.5.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.5.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.5.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.5.5 - -### Patch Changes - -- cb716004ef: Internal refactor to improve tests -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.5.5-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.5.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.5.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.5.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.5.5-next.0 - -### Patch Changes - -- cb716004ef: Internal refactor to improve tests -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.5.4 - -### Patch Changes - -- f905853ad6: Prefer using `Link` from `@backstage/core-components` rather than material-UI. -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/errors@1.1.3 - - @backstage/theme@0.2.16 - -## 0.5.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.5.4-next.0 - -### Patch Changes - -- f905853ad6: Prefer using `Link` from `@backstage/core-components` rather than material-UI. -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.5.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - - @backstage/theme@0.2.16 - -## 0.5.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/theme@0.2.16 - -## 0.5.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.5.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/theme@0.2.16 - -## 0.5.2 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 3f739be9d9: Minor API signatures cleanup -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - - @backstage/errors@1.1.1 - -## 0.5.2-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.5.2-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.5.2-next.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.5.2-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -## 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 - -## 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 - -## 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 - -## 0.5.0-next.3 - -### Patch Changes - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.5.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.5.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.5.0-next.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 - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.4.0 - -### Minor Changes - -- b157c2eb1c: **Breaking**: Use identityApi to provide auth token for pagerduty API calls. - -### Patch Changes - -- 76bf6400fe: Fix alert that was not showing after creating an incident. -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.4.0-next.2 - -### Minor Changes - -- b157c2eb1c: **Breaking**: Use identityApi to provide auth token for pagerduty API calls. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.2 - -## 0.3.33-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.3.33-next.0 - -### Patch Changes - -- 76bf6400fe: Fix alert that was not showing after creating an incident. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.3.32 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.3.32-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.3.32-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.3.32-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.3.31 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.3.31-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.3.31-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.3.30 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - -## 0.3.29 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.3.29-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.3.28 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.3.27 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.3.26 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- edeeac7e9d: Switch `luxon` dependency range to be `^2.0.2` rather than `2.0.2`. -- 7aeb491394: Replace use of deprecated `ENTITY_DEFAULT_NAMESPACE` constant with `DEFAULT_NAMESPACE`. -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - -## 0.3.25 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.3.25-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.3.24 - -### Patch Changes - -- 5a459626bc: Fix change events tab error when change events exist -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.3.24-next.0 - -### Patch Changes - -- 5a459626bc: Fix change events tab error when change events exist -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.3.23 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- 013301e07b: Remove redundant `node-fetch` dependency -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.3.23-next.0 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- 013301e07b: Remove redundant `node-fetch` dependency -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.3.22 - -### Patch Changes - -- 7612e2856b: Clean up emptystate.svg image, removing wrong white artifact from the background -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/catalog-model@0.9.9 - -## 0.3.21 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.3.20 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.3.19 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.3.18 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/catalog-model@0.9.7 - - @backstage/plugin-catalog-react@0.6.4 - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.3.17 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.0 - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.3.16 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - - @backstage/plugin-catalog-react@0.5.2 - - @backstage/catalog-model@0.9.4 - -## 0.3.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - - @backstage/plugin-catalog-react@0.5.1 - -## 0.3.14 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/plugin-catalog-react@0.5.0 - - @backstage/catalog-model@0.9.3 - -## 0.3.13 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/plugin-catalog-react@0.4.6 - - @backstage/core-plugin-api@0.1.8 - -## 0.3.12 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.5 - - @backstage/core-components@0.4.0 - - @backstage/catalog-model@0.9.1 - -## 0.3.11 - -### Patch Changes - -- 8bedb75ae: Update Luxon dependency to 2.x -- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - - @backstage/plugin-catalog-react@0.4.2 - -## 0.3.10 - -### Patch Changes - -- 260c053b9: Fix All Material UI Warnings -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - - @backstage/plugin-catalog-react@0.4.1 - -## 0.3.9 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/plugin-catalog-react@0.4.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.3.8 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.3.0 - -## 0.3.7 - -### Patch Changes - -- d1bd7bb82: Update README -- Updated dependencies - - @backstage/core-components@0.1.5 - - @backstage/catalog-model@0.9.0 - - @backstage/plugin-catalog-react@0.2.6 - -## 0.3.6 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - - @backstage/catalog-model@0.8.4 - - @backstage/plugin-catalog-react@0.2.4 - -## 0.3.5 - -### Patch Changes - -- Updated dependencies [add62a455] -- Updated dependencies [cc592248b] -- Updated dependencies [17c497b81] -- Updated dependencies [704875e26] - - @backstage/catalog-model@0.8.0 - - @backstage/core@0.7.11 - - @backstage/plugin-catalog-react@0.2.0 - -## 0.3.4 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [10c008a3a] -- Updated dependencies [889d89b6e] -- Updated dependencies [16be1d093] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - - @backstage/plugin-catalog-react@0.1.6 - - @backstage/catalog-model@0.7.9 - -## 0.3.3 - -### Patch Changes - -- c614ede9a: Updated README to have up-to-date install instructions. -- Updated dependencies [9afcac5af] -- Updated dependencies [e0c9ed759] -- Updated dependencies [6eaecbd81] - - @backstage/core@0.7.7 - -## 0.3.2 - -### Patch Changes - -- 4c049a1a1: - Adds onClick and other props to IconLinkVertical; - - - Allows TriggerButton component to render when pager duty key is missing; - - Refactors TriggerButton and PagerDutyCard not to have shared state; - - Removes the `action` prop of the IconLinkVertical component while adding `onClick`. - - Instead of having an action including a button with onClick, now the whole component can be clickable making it easier to implement and having a better UX. - - Before: - - ```ts - const myLink: IconLinkVerticalProps = { - label: 'Click me', - action: - } - /> -); diff --git a/plugins/pagerduty/src/components/Errors/ServiceNotFoundError.tsx b/plugins/pagerduty/src/components/Errors/ServiceNotFoundError.tsx deleted file mode 100644 index 236585735e..0000000000 --- a/plugins/pagerduty/src/components/Errors/ServiceNotFoundError.tsx +++ /dev/null @@ -1,35 +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 { Button } from '@material-ui/core'; -import { EmptyState } from '@backstage/core-components'; - -export const ServiceNotFoundError = () => ( - - Read More - - } - /> -); diff --git a/plugins/pagerduty/src/components/Errors/index.ts b/plugins/pagerduty/src/components/Errors/index.ts deleted file mode 100644 index 6c35e0bfd1..0000000000 --- a/plugins/pagerduty/src/components/Errors/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { MissingTokenError } from './MissingTokenError'; -export { ServiceNotFoundError } from './ServiceNotFoundError'; diff --git a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx b/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx deleted file mode 100644 index 5e780f3fa0..0000000000 --- a/plugins/pagerduty/src/components/Escalation/Escalation.test.tsx +++ /dev/null @@ -1,94 +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 { screen, waitFor } from '@testing-library/react'; -import { EscalationPolicy } from './EscalationPolicy'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { PagerDutyUser } from '../types'; -import { pagerDutyApiRef } from '../../api'; -import { ApiProvider } from '@backstage/core-app-api'; - -const mockPagerDutyApi = { - getOnCallByPolicyId: jest.fn(), -}; -const apis = TestApiRegistry.from([pagerDutyApiRef, mockPagerDutyApi]); - -describe('Escalation', () => { - it('Handles an empty response', async () => { - mockPagerDutyApi.getOnCallByPolicyId = jest - .fn() - .mockImplementationOnce(async () => ({ oncalls: [] })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - expect(mockPagerDutyApi.getOnCallByPolicyId).toHaveBeenCalledWith('456'); - }); - - it('Render a list of users', async () => { - mockPagerDutyApi.getOnCallByPolicyId = jest - .fn() - .mockImplementationOnce(async () => ({ - oncalls: [ - { - user: { - name: 'person1', - id: 'p1', - summary: 'person1', - email: 'person1@example.com', - html_url: 'http://a.com/id1', - } as PagerDutyUser, - }, - ], - })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect(screen.getByText('person1')).toBeInTheDocument(); - expect(screen.getByText('person1@example.com')).toBeInTheDocument(); - expect(mockPagerDutyApi.getOnCallByPolicyId).toHaveBeenCalledWith('abc'); - }); - - it('Handles errors', async () => { - mockPagerDutyApi.getOnCallByPolicyId = jest - .fn() - .mockRejectedValueOnce(new Error('Error message')); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect( - screen.getByText( - 'Error encountered while fetching information. Error message', - ), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx b/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx deleted file mode 100644 index 8602733ee3..0000000000 --- a/plugins/pagerduty/src/components/Escalation/EscalationPolicy.tsx +++ /dev/null @@ -1,71 +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 { List, ListSubheader } from '@material-ui/core'; -import { EscalationUsersEmptyState } from './EscalationUsersEmptyState'; -import { EscalationUser } from './EscalationUser'; -import useAsync from 'react-use/lib/useAsync'; -import { pagerDutyApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; - -import { useApi } from '@backstage/core-plugin-api'; -import { Progress } from '@backstage/core-components'; - -type Props = { - policyId: string; -}; - -export const EscalationPolicy = ({ policyId }: Props) => { - const api = useApi(pagerDutyApiRef); - - const { - value: users, - loading, - error, - } = useAsync(async () => { - const { oncalls } = await api.getOnCallByPolicyId(policyId); - const usersItem = oncalls - .sort((a, b) => a.escalation_level - b.escalation_level) - .map(oncall => oncall.user); - - return usersItem; - }); - - if (error) { - return ( - - Error encountered while fetching information. {error.message} - - ); - } - - if (loading) { - return ; - } - - if (!users?.length) { - return ; - } - - return ( - ON CALL}> - {users!.map((user, index) => ( - - ))} - - ); -}; diff --git a/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx b/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx deleted file mode 100644 index d418ad02c0..0000000000 --- a/plugins/pagerduty/src/components/Escalation/EscalationUser.tsx +++ /dev/null @@ -1,78 +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 { - ListItem, - ListItemIcon, - ListItemSecondaryAction, - Tooltip, - ListItemText, - makeStyles, - IconButton, - Typography, -} from '@material-ui/core'; -import Avatar from '@material-ui/core/Avatar'; -import EmailIcon from '@material-ui/icons/Email'; -import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; -import { PagerDutyUser } from '../types'; - -const useStyles = makeStyles({ - listItemPrimary: { - fontWeight: 'bold', - }, -}); - -type Props = { - user: PagerDutyUser; -}; - -export const EscalationUser = ({ user }: Props) => { - const classes = useStyles(); - - return ( - - - - - - {user.name} - - } - secondary={user.email} - /> - - - - - - - - - - - - - - ); -}; diff --git a/plugins/pagerduty/src/components/Escalation/EscalationUsersEmptyState.tsx b/plugins/pagerduty/src/components/Escalation/EscalationUsersEmptyState.tsx deleted file mode 100644 index b4c10ddcf8..0000000000 --- a/plugins/pagerduty/src/components/Escalation/EscalationUsersEmptyState.tsx +++ /dev/null @@ -1,48 +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 { - ListItem, - ListItemIcon, - ListItemText, - makeStyles, -} from '@material-ui/core'; -import { StatusWarning } from '@backstage/core-components'; - -const useStyles = makeStyles({ - denseListIcon: { - marginRight: 0, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - }, -}); - -export const EscalationUsersEmptyState = () => { - const classes = useStyles(); - return ( - - -
- -
-
- -
- ); -}; diff --git a/plugins/pagerduty/src/components/Escalation/index.ts b/plugins/pagerduty/src/components/Escalation/index.ts deleted file mode 100644 index 165ec6690b..0000000000 --- a/plugins/pagerduty/src/components/Escalation/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { EscalationPolicy } from './EscalationPolicy'; diff --git a/plugins/pagerduty/src/components/HomePagePagerDutyCard/Content.tsx b/plugins/pagerduty/src/components/HomePagePagerDutyCard/Content.tsx deleted file mode 100644 index b665a6c294..0000000000 --- a/plugins/pagerduty/src/components/HomePagePagerDutyCard/Content.tsx +++ /dev/null @@ -1,29 +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 { PagerDutyEntity } from '../../types'; -import { PagerDutyCard } from '../PagerDutyCard'; - -/** @public */ -export type HomePagePagerDutyCardProps = PagerDutyEntity & { - readOnly?: boolean; -}; - -/** @public */ -export const Content = (props: HomePagePagerDutyCardProps) => { - return ; -}; diff --git a/plugins/pagerduty/src/components/HomePagePagerDutyCard/index.ts b/plugins/pagerduty/src/components/HomePagePagerDutyCard/index.ts deleted file mode 100644 index e9038852a6..0000000000 --- a/plugins/pagerduty/src/components/HomePagePagerDutyCard/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { Content } from './Content'; -export type { HomePagePagerDutyCardProps } from './Content'; diff --git a/plugins/pagerduty/src/components/Incident/IncidentEmptyState.tsx b/plugins/pagerduty/src/components/Incident/IncidentEmptyState.tsx deleted file mode 100644 index 87108f3d74..0000000000 --- a/plugins/pagerduty/src/components/Incident/IncidentEmptyState.tsx +++ /dev/null @@ -1,41 +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 { Grid, Typography } from '@material-ui/core'; -import EmptyStateImage from '../../assets/emptystate.svg'; - -export const IncidentsEmptyState = () => { - return ( - - - Nice! No incidents found! - - - EmptyState - - - ); -}; diff --git a/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx b/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx deleted file mode 100644 index 3ee92f1470..0000000000 --- a/plugins/pagerduty/src/components/Incident/IncidentListItem.tsx +++ /dev/null @@ -1,120 +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 { - ListItem, - ListItemSecondaryAction, - Tooltip, - ListItemText, - makeStyles, - IconButton, - Typography, - Chip, -} from '@material-ui/core'; -import Done from '@material-ui/icons/Done'; -import Warning from '@material-ui/icons/Warning'; -import { DateTime, Duration } from 'luxon'; -import { PagerDutyIncident } from '../types'; -import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; -import { Link } from '@backstage/core-components'; - -const useStyles = makeStyles(theme => ({ - denseListIcon: { - marginRight: 0, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - }, - listItemPrimary: { - fontWeight: 'bold', - }, - warning: { - borderColor: theme.palette.status.warning, - color: theme.palette.status.warning, - '& *': { - color: theme.palette.status.warning, - }, - }, - error: { - borderColor: theme.palette.status.error, - color: theme.palette.status.error, - '& *': { - color: theme.palette.status.error, - }, - }, -})); - -type Props = { - incident: PagerDutyIncident; -}; - -export const IncidentListItem = ({ incident }: Props) => { - const classes = useStyles(); - const duration = - new Date().getTime() - new Date(incident.created_at).getTime(); - const createdAt = DateTime.local() - .minus(Duration.fromMillis(duration)) - .toRelative({ locale: 'en' }); - const user = incident.assignments[0]?.assignee; - - return ( - - - : } - className={ - incident.status === 'triggered' - ? classes.error - : classes.warning - } - /> - {incident.title} - - } - primaryTypographyProps={{ - variant: 'body1', - className: classes.listItemPrimary, - }} - secondary={ - - Created {createdAt} and assigned to{' '} - {user?.summary ?? 'nobody'} - - } - /> - - - - - - - - - ); -}; diff --git a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx b/plugins/pagerduty/src/components/Incident/Incidents.test.tsx deleted file mode 100644 index f10f48e059..0000000000 --- a/plugins/pagerduty/src/components/Incident/Incidents.test.tsx +++ /dev/null @@ -1,123 +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 { screen, waitFor } from '@testing-library/react'; -import { Incidents } from './Incidents'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { pagerDutyApiRef } from '../../api'; -import { PagerDutyIncident } from '../types'; -import { ApiProvider } from '@backstage/core-app-api'; - -const mockPagerDutyApi = { - getIncidentsByServiceId: jest.fn(), -}; -const apis = TestApiRegistry.from([pagerDutyApiRef, mockPagerDutyApi]); - -describe('Incidents', () => { - it('Renders an empty state when there are no incidents', async () => { - mockPagerDutyApi.getIncidentsByServiceId = jest - .fn() - .mockImplementationOnce(async () => ({ incidents: [] })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(); - }); - - it('Renders all incidents', async () => { - mockPagerDutyApi.getIncidentsByServiceId = jest - .fn() - .mockImplementationOnce(async () => ({ - incidents: [ - { - id: 'id1', - status: 'triggered', - title: 'title1', - created_at: '2020-11-06T00:00:00Z', - assignments: [ - { - assignee: { - id: 'p1', - summary: 'person1', - html_url: 'http://a.com/id1', - }, - }, - ], - html_url: 'http://a.com/id1', - serviceId: 'sId1', - }, - { - id: 'id2', - status: 'acknowledged', - title: 'title2', - created_at: '2020-11-07T00:00:00Z', - assignments: [ - { - assignee: { - id: 'p2', - summary: 'person2', - - html_url: 'http://a.com/id2', - }, - }, - ], - html_url: 'http://a.com/id2', - serviceId: 'sId2', - }, - ] as PagerDutyIncident[], - })); - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('title1')).toBeInTheDocument(); - expect(screen.getByText('title2')).toBeInTheDocument(); - expect(screen.getByText('person1')).toBeInTheDocument(); - expect(screen.getByText('person2')).toBeInTheDocument(); - expect(screen.getByText('triggered')).toBeInTheDocument(); - expect(screen.getByText('acknowledged')).toBeInTheDocument(); - expect(screen.getByTestId('chip-triggered')).toBeInTheDocument(); - expect(screen.getByTestId('chip-acknowledged')).toBeInTheDocument(); - - // assert links, mailto and hrefs, date calculation - expect(screen.getAllByTitle('View in PagerDuty').length).toEqual(2); - }); - - it('Handle errors', async () => { - mockPagerDutyApi.getIncidentsByServiceId = jest - .fn() - .mockRejectedValueOnce(new Error('Error occurred')); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText( - 'Error encountered while fetching information. Error occurred', - ), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/pagerduty/src/components/Incident/Incidents.tsx b/plugins/pagerduty/src/components/Incident/Incidents.tsx deleted file mode 100644 index 2e0e201c79..0000000000 --- a/plugins/pagerduty/src/components/Incident/Incidents.tsx +++ /dev/null @@ -1,72 +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, { useEffect } from 'react'; -import { List, ListSubheader } from '@material-ui/core'; -import { IncidentListItem } from './IncidentListItem'; -import { IncidentsEmptyState } from './IncidentEmptyState'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import { pagerDutyApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; - -import { useApi } from '@backstage/core-plugin-api'; -import { Progress } from '@backstage/core-components'; - -type Props = { - serviceId: string; - refreshIncidents: boolean; -}; - -export const Incidents = ({ serviceId, refreshIncidents }: Props) => { - const api = useApi(pagerDutyApiRef); - - const [{ value: incidents, loading, error }, getIncidents] = useAsyncFn( - async () => { - const { incidents: foundIncidents } = await api.getIncidentsByServiceId( - serviceId, - ); - return foundIncidents; - }, - ); - - useEffect(() => { - getIncidents(); - }, [refreshIncidents, getIncidents]); - - if (error) { - return ( - - Error encountered while fetching information. {error.message} - - ); - } - - if (loading) { - return ; - } - - if (!incidents?.length) { - return ; - } - - return ( - INCIDENTS}> - {incidents!.map((incident, index) => ( - - ))} - - ); -}; diff --git a/plugins/pagerduty/src/components/Incident/index.ts b/plugins/pagerduty/src/components/Incident/index.ts deleted file mode 100644 index 3729de6e01..0000000000 --- a/plugins/pagerduty/src/components/Incident/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { Incidents } from './Incidents'; diff --git a/plugins/pagerduty/src/components/PagerDutyCard/PagerDutyCard.test.tsx b/plugins/pagerduty/src/components/PagerDutyCard/PagerDutyCard.test.tsx deleted file mode 100644 index b1f525bcfa..0000000000 --- a/plugins/pagerduty/src/components/PagerDutyCard/PagerDutyCard.test.tsx +++ /dev/null @@ -1,289 +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 { screen, waitFor, fireEvent, act } from '@testing-library/react'; -import { PagerDutyCard } from './PagerDutyCard'; -import { NotFoundError } from '@backstage/errors'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { pagerDutyApiRef, UnauthorizedError, PagerDutyClient } from '../../api'; -import { PagerDutyService, PagerDutyUser } from '../types'; - -import { alertApiRef } from '@backstage/core-plugin-api'; -import { ApiProvider } from '@backstage/core-app-api'; - -const user: PagerDutyUser = { - name: 'person1', - id: 'p1', - summary: 'person1', - email: 'person1@example.com', - html_url: 'http://a.com/id1', -}; - -const service: PagerDutyService = { - id: 'def456', - name: 'pagerduty-name', - html_url: 'www.example.com', - escalation_policy: { - id: 'def', - user: user, - html_url: 'http://a.com/id1', - }, - integrationKey: 'abc123', -}; - -const mockPagerDutyApi: Partial = { - getServiceByEntity: async () => ({ service }), - getOnCallByPolicyId: async () => ({ oncalls: [] }), - getIncidentsByServiceId: async () => ({ incidents: [] }), -}; - -const apis = TestApiRegistry.from( - [pagerDutyApiRef, mockPagerDutyApi], - [alertApiRef, {}], -); - -describe('PagerDutyCard', () => { - it('Render pagerduty', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockImplementationOnce(async () => ({ service })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Service Directory')).toBeInTheDocument(); - expect(screen.getByText('Create Incident')).toBeInTheDocument(); - expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(); - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - }); - - it('Handles custom error for missing token', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockRejectedValueOnce(new UnauthorizedError()); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText('Missing or invalid PagerDuty Token'), - ).toBeInTheDocument(); - }); - - it('Handles custom NotFoundError', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockRejectedValueOnce(new NotFoundError()); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('PagerDuty Service Not Found')).toBeInTheDocument(); - }); - - it('handles general error', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockRejectedValueOnce(new Error('An error occurred')); - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect( - screen.getByText( - 'Error encountered while fetching information. An error occurred', - ), - ).toBeInTheDocument(); - }); - - it('opens the dialog when trigger button is clicked', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockImplementationOnce(async () => ({ service })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Service Directory')).toBeInTheDocument(); - - const triggerLink = screen.getByText('Create Incident'); - await act(async () => { - fireEvent.click(triggerLink); - }); - expect(screen.getByRole('dialog')).toBeInTheDocument(); - }); - - describe('when entity has the pagerduty.com/service-id annotation', () => { - it('Renders PagerDuty service information', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockImplementationOnce(async () => ({ service })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Service Directory')).toBeInTheDocument(); - expect(screen.getByText('Create Incident')).toBeInTheDocument(); - expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(); - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - }); - - it('Handles custom error for missing token', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockRejectedValueOnce(new UnauthorizedError()); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText('Missing or invalid PagerDuty Token'), - ).toBeInTheDocument(); - }); - - it('Handles custom NotFoundError', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockRejectedValueOnce(new NotFoundError()); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText('PagerDuty Service Not Found'), - ).toBeInTheDocument(); - }); - - it('handles general error', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockRejectedValueOnce(new Error('An error occurred')); - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect( - screen.getByText( - 'Error encountered while fetching information. An error occurred', - ), - ).toBeInTheDocument(); - }); - - it('disables the Create Incident button', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockImplementationOnce(async () => ({ service })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByTitle('Must provide an integration-key to create incidents') - .className, - ).toMatch('disabled'); - }); - }); - - describe('when entity has all annotations', () => { - it('queries by integration key', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockImplementationOnce(async () => ({ service })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Service Directory')).toBeInTheDocument(); - expect(screen.getByText('Create Incident')).toBeInTheDocument(); - expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(); - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - }); - }); - - describe('when entity has all annotations but the plugin has been configured to be "read only"', () => { - it('queries by integration key but does not render the "Create Incident" button', async () => { - mockPagerDutyApi.getServiceByPagerDutyEntity = jest - .fn() - .mockImplementationOnce(async () => ({ service })); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Service Directory')).toBeInTheDocument(); - expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(); - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - expect(() => screen.getByText('Create Incident')).toThrow(); - }); - }); -}); diff --git a/plugins/pagerduty/src/components/PagerDutyCard/PagerDutyCard.tsx b/plugins/pagerduty/src/components/PagerDutyCard/PagerDutyCard.tsx deleted file mode 100644 index 8be87e0f15..0000000000 --- a/plugins/pagerduty/src/components/PagerDutyCard/PagerDutyCard.tsx +++ /dev/null @@ -1,206 +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, { ReactNode, useState, useCallback } from 'react'; -import { - Card, - CardHeader, - Divider, - CardContent, - TabProps, -} from '@material-ui/core'; -import { Incidents } from '../Incident'; -import { EscalationPolicy } from '../Escalation'; -import useAsync from 'react-use/lib/useAsync'; -import { Alert } from '@material-ui/lab'; -import { pagerDutyApiRef, UnauthorizedError } from '../../api'; -import AlarmAddIcon from '@material-ui/icons/AlarmAdd'; -import { MissingTokenError, ServiceNotFoundError } from '../Errors'; -import WebIcon from '@material-ui/icons/Web'; -import DateRangeIcon from '@material-ui/icons/DateRange'; -import { TriggerDialog } from '../TriggerDialog'; -import { ChangeEvents } from '../ChangeEvents'; - -import { useApi } from '@backstage/core-plugin-api'; -import { NotFoundError } from '@backstage/errors'; -import { - Progress, - HeaderIconLinkRow, - IconLinkVerticalProps, - TabbedCard, - CardTab, - InfoCard, -} from '@backstage/core-components'; -import { PagerDutyEntity } from '../../types'; - -const BasicCard = ({ children }: { children: ReactNode }) => ( - {children} -); - -/** @public */ -export type PagerDutyCardProps = PagerDutyEntity & { - readOnly?: boolean; - disableChangeEvents?: boolean; -}; - -/** @public */ -export const PagerDutyCard = (props: PagerDutyCardProps) => { - const { readOnly, disableChangeEvents, integrationKey, name } = props; - const api = useApi(pagerDutyApiRef); - const [refreshIncidents, setRefreshIncidents] = useState(false); - const [refreshChangeEvents, setRefreshChangeEvents] = - useState(false); - const [dialogShown, setDialogShown] = useState(false); - - const showDialog = useCallback(() => { - setDialogShown(true); - }, [setDialogShown]); - const hideDialog = useCallback(() => { - setDialogShown(false); - }, [setDialogShown]); - - const handleRefresh = useCallback(() => { - setRefreshIncidents(x => !x); - setRefreshChangeEvents(x => !x); - }, []); - - const { - value: service, - loading, - error, - } = useAsync(async () => { - const { service: foundService } = await api.getServiceByPagerDutyEntity( - props, - ); - - return { - id: foundService.id, - name: foundService.name, - url: foundService.html_url, - policyId: foundService.escalation_policy.id, - policyLink: foundService.escalation_policy.html_url, - }; - }); - - if (error) { - let errorNode: ReactNode; - - switch (error.constructor) { - case UnauthorizedError: - errorNode = ; - break; - case NotFoundError: - errorNode = ; - break; - default: - errorNode = ( - - Error encountered while fetching information. {error.message} - - ); - } - - return {errorNode}; - } - - if (loading) { - return ( - - - - ); - } - - const serviceLink: IconLinkVerticalProps = { - label: 'Service Directory', - href: service!.url, - icon: , - }; - - /** - * In order to create incidents using the REST API, a valid user email address must be present. - * There is no guarantee the current user entity has a valid email association, so instead just - * only allow triggering incidents when an integration key is present. - */ - const createIncidentDisabled = !integrationKey; - const triggerLink: IconLinkVerticalProps = { - label: 'Create Incident', - onClick: showDialog, - icon: , - color: 'secondary', - disabled: createIncidentDisabled, - title: createIncidentDisabled - ? 'Must provide an integration-key to create incidents' - : '', - }; - - const escalationPolicyLink: IconLinkVerticalProps = { - label: 'Escalation Policy', - href: service!.policyLink, - icon: , - }; - - const tabs: React.ReactElement[] = [ - - - , - ]; - - if (disableChangeEvents !== true) { - tabs.push( - - - , - ); - } - - return ( - <> - - - } - /> - - - {...tabs} - - - - {!createIncidentDisabled && ( - - )} - - ); -}; diff --git a/plugins/pagerduty/src/components/PagerDutyCard/index.ts b/plugins/pagerduty/src/components/PagerDutyCard/index.ts deleted file mode 100644 index 4944a9a13d..0000000000 --- a/plugins/pagerduty/src/components/PagerDutyCard/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { PagerDutyCard, type PagerDutyCardProps } from './PagerDutyCard'; diff --git a/plugins/pagerduty/src/components/TriggerButton/index.test.tsx b/plugins/pagerduty/src/components/TriggerButton/index.test.tsx deleted file mode 100644 index 409f11ec04..0000000000 --- a/plugins/pagerduty/src/components/TriggerButton/index.test.tsx +++ /dev/null @@ -1,126 +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 { act, fireEvent, screen, waitFor } from '@testing-library/react'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { pagerDutyApiRef } from '../../api'; -import { Entity } from '@backstage/catalog-model'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { TriggerButton } from './'; - -import { ApiProvider } from '@backstage/core-app-api'; -import { alertApiRef } from '@backstage/core-plugin-api'; - -describe('TriggerButton', () => { - const mockTriggerAlarmFn = jest.fn(); - const mockPagerDutyApi = { - triggerAlarm: mockTriggerAlarmFn, - }; - - const apis = TestApiRegistry.from( - [alertApiRef, {}], - [pagerDutyApiRef, mockPagerDutyApi], - ); - - it('renders the trigger button, opens and closes dialog', async () => { - const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - annotations: { - 'pagerduty.com/integration-key': 'abc123', - }, - }, - }; - - await renderInTestApp( - - - - - , - ); - - const triggerButton = screen.getByText('Create Incident'); - expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); - - await act(async () => { - fireEvent.click(triggerButton); - }); - await waitFor(() => { - expect(screen.getByRole('dialog')).toBeInTheDocument(); - }); - - const closeButton = screen.getByText('Close'); - await act(async () => { - fireEvent.click(closeButton); - }); - await waitFor(() => { - expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); - }); - }); - - it('renders the trigger button with children', async () => { - const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - annotations: { - 'pagerduty.com/integration-key': 'abc123', - }, - }, - }; - - await renderInTestApp( - - - Send an alert - - , - ); - - expect(screen.getByText('Send an alert')).toBeInTheDocument(); - }); - - it('renders a disabled trigger button if entity does not include key', async () => { - const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - }, - }; - - await renderInTestApp( - - - - - , - ); - - const triggerButton = screen.getByText('Missing integration key'); - - await act(async () => { - fireEvent.click(triggerButton); - }); - await waitFor(() => { - expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/pagerduty/src/components/TriggerButton/index.tsx b/plugins/pagerduty/src/components/TriggerButton/index.tsx deleted file mode 100644 index 60adbd38c0..0000000000 --- a/plugins/pagerduty/src/components/TriggerButton/index.tsx +++ /dev/null @@ -1,68 +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, ReactNode, useState } from 'react'; -import { makeStyles, Button } from '@material-ui/core'; -import { usePagerdutyEntity } from '../../hooks'; -import { TriggerDialog } from '../TriggerDialog'; - -const useStyles = makeStyles(theme => ({ - buttonStyle: { - backgroundColor: theme.palette.error.main, - color: theme.palette.error.contrastText, - '&:hover': { - backgroundColor: theme.palette.error.dark, - }, - }, -})); - -/** @public */ -export function TriggerButton(props: { children?: ReactNode }) { - const { buttonStyle } = useStyles(); - const { integrationKey, name } = usePagerdutyEntity(); - const [dialogShown, setDialogShown] = useState(false); - - const showDialog = useCallback(() => { - setDialogShown(true); - }, [setDialogShown]); - const hideDialog = useCallback(() => { - setDialogShown(false); - }, [setDialogShown]); - - const disabled = !integrationKey; - return ( - <> - - {integrationKey && ( - - )} - - ); -} diff --git a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx deleted file mode 100644 index 74cd5100fa..0000000000 --- a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.test.tsx +++ /dev/null @@ -1,85 +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 { fireEvent, act } from '@testing-library/react'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { pagerDutyApiRef } from '../../api'; -import { TriggerDialog } from './TriggerDialog'; - -import { ApiProvider } from '@backstage/core-app-api'; -import { - alertApiRef, - IdentityApi, - identityApiRef, -} from '@backstage/core-plugin-api'; - -describe('TriggerDialog', () => { - const mockIdentityApi: Partial = { - getBackstageIdentity: async () => ({ - type: 'user', - userEntityRef: 'user:default/guest', - ownershipEntityRefs: [], - }), - }; - - const mockTriggerAlarmFn = jest.fn(); - const mockPagerDutyApi = { - triggerAlarm: mockTriggerAlarmFn, - }; - - const apis = TestApiRegistry.from( - [alertApiRef, {}], - [identityApiRef, mockIdentityApi], - [pagerDutyApiRef, mockPagerDutyApi], - ); - - it('open the dialog and trigger an alarm', async () => { - const { getByText, getByRole, getByTestId } = await renderInTestApp( - - {}} - onIncidentCreated={() => {}} - /> - , - ); - - expect(getByRole('dialog')).toBeInTheDocument(); - expect( - getByText('This action will trigger an incident for ', { - exact: false, - }), - ).toBeInTheDocument(); - const input = getByTestId('trigger-input'); - const description = 'Test Trigger Alarm'; - await act(async () => { - fireEvent.change(input, { target: { value: description } }); - }); - const triggerButton = getByTestId('trigger-button'); - await act(async () => { - fireEvent.click(triggerButton); - }); - expect(mockTriggerAlarmFn).toHaveBeenCalled(); - expect(mockTriggerAlarmFn).toHaveBeenCalledWith({ - integrationKey: 'abc123', - source: window.location.toString(), - description, - userName: 'guest', - }); - }); -}); diff --git a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.tsx b/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.tsx deleted file mode 100644 index 7e273b8d25..0000000000 --- a/plugins/pagerduty/src/components/TriggerDialog/TriggerDialog.tsx +++ /dev/null @@ -1,159 +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, { useState, useEffect } from 'react'; -import { - Dialog, - DialogTitle, - TextField, - DialogActions, - Button, - DialogContent, - Typography, - CircularProgress, -} from '@material-ui/core'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import { pagerDutyApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; -import { - useApi, - alertApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; -import { DEFAULT_NAMESPACE, parseEntityRef } from '@backstage/catalog-model'; - -type Props = { - showDialog: boolean; - handleDialog: () => void; - onIncidentCreated?: () => void; - name: string; - integrationKey: string; -}; - -export const TriggerDialog = ({ - showDialog, - handleDialog, - onIncidentCreated: onIncidentCreated, - name, - integrationKey, -}: Props) => { - const alertApi = useApi(alertApiRef); - const identityApi = useApi(identityApiRef); - const api = useApi(pagerDutyApiRef); - const [description, setDescription] = useState(''); - - const [{ value, loading, error }, handleTriggerAlarm] = useAsyncFn( - async (descriptions: string) => { - const { userEntityRef } = await identityApi.getBackstageIdentity(); - const { name: userName } = parseEntityRef(userEntityRef, { - defaultKind: 'User', - defaultNamespace: DEFAULT_NAMESPACE, - }); - return await api.triggerAlarm({ - integrationKey: integrationKey as string, - source: window.location.toString(), - description: descriptions, - userName, - }); - }, - ); - - const descriptionChanged = ( - event: React.ChangeEvent, - ) => { - setDescription(event.target.value); - }; - - useEffect(() => { - if (value) { - (async () => { - alertApi.post({ - message: `Alarm successfully triggered`, - }); - - handleDialog(); - - // The pager duty API isn't always returning the newly created alarm immediately - await new Promise(resolve => setTimeout(resolve, 1000)); - onIncidentCreated?.(); - })(); - } - }, [value, alertApi, handleDialog, onIncidentCreated]); - - if (error) { - alertApi.post({ - message: `Failed to trigger alarm. ${error.message}`, - severity: 'error', - }); - } - - return ( - - - This action will trigger an incident for "{name}". - - - - - If the issue you are seeing does not need urgent attention, please - get in touch with the responsible team using their preferred - communications channel. You can find information about the owner of - this entity in the "About" card. If the issue is urgent, please - don't hesitate to trigger the alert. - - - - Please describe the problem you want to report. Be as descriptive as - possible. Your signed in user and a reference to the current page will - automatically be amended to the alarm so that the receiver can reach - out to you if necessary. - - - - - - - - - ); -}; diff --git a/plugins/pagerduty/src/components/TriggerDialog/index.ts b/plugins/pagerduty/src/components/TriggerDialog/index.ts deleted file mode 100644 index 5c48cce7ed..0000000000 --- a/plugins/pagerduty/src/components/TriggerDialog/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { TriggerDialog } from './TriggerDialog'; diff --git a/plugins/pagerduty/src/components/constants.ts b/plugins/pagerduty/src/components/constants.ts deleted file mode 100644 index 01308590f1..0000000000 --- a/plugins/pagerduty/src/components/constants.ts +++ /dev/null @@ -1,17 +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. - */ -export const PAGERDUTY_INTEGRATION_KEY = 'pagerduty.com/integration-key'; -export const PAGERDUTY_SERVICE_ID = 'pagerduty.com/service-id'; diff --git a/plugins/pagerduty/src/components/index.ts b/plugins/pagerduty/src/components/index.ts deleted file mode 100644 index 264d7195e9..0000000000 --- a/plugins/pagerduty/src/components/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export type { - PagerDutyChangeEvent, - PagerDutyIncident, - PagerDutyService, - PagerDutyOnCall, - PagerDutyAssignee, - PagerDutyUser, -} from './types'; - -export type { EntityPagerDutyCardProps } from './EntityPagerDutyCard'; -export type { HomePagePagerDutyCardProps } from './HomePagePagerDutyCard'; - -export { - isPluginApplicableToEntity, - isPluginApplicableToEntity as isPagerDutyAvailable, - EntityPagerDutyCard, -} from './EntityPagerDutyCard'; - -export { TriggerButton } from './TriggerButton'; diff --git a/plugins/pagerduty/src/components/pagerDutyEntity.test.ts b/plugins/pagerduty/src/components/pagerDutyEntity.test.ts deleted file mode 100644 index cf551d3d6e..0000000000 --- a/plugins/pagerduty/src/components/pagerDutyEntity.test.ts +++ /dev/null @@ -1,98 +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 { Entity } from '@backstage/catalog-model'; -import { getPagerDutyEntity } from './pagerDutyEntity'; - -const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - annotations: { - 'pagerduty.com/integration-key': 'abc123', - }, - }, -}; - -const entityWithoutAnnotations: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - annotations: {}, - }, -}; - -const entityWithServiceId: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - annotations: { - 'pagerduty.com/service-id': 'def456', - }, - }, -}; - -const entityWithAllAnnotations: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'pagerduty-test', - annotations: { - 'pagerduty.com/integration-key': 'abc123', - 'pagerduty.com/service-id': 'def456', - }, - }, -}; - -describe('getPagerDutyEntity', () => { - describe('when entity has no annotations', () => { - it('returns a PagerDutyEntity', () => { - expect(getPagerDutyEntity(entityWithoutAnnotations)).toEqual({ - name: 'pagerduty-test', - }); - }); - }); - - describe('when entity has integration key annotation', () => { - it('returns a PagerDutyEntity', () => { - expect(getPagerDutyEntity(entity)).toEqual({ - name: 'pagerduty-test', - integrationKey: 'abc123', - }); - }); - }); - - describe('when entity has service id annotation', () => { - it('returns a PagerDutyEntity', () => { - expect(getPagerDutyEntity(entityWithServiceId)).toEqual({ - name: 'pagerduty-test', - serviceId: 'def456', - }); - }); - }); - - describe('when entity has all annotations', () => { - it('returns a PagerDutyEntity', () => { - expect(getPagerDutyEntity(entityWithAllAnnotations)).toEqual({ - name: 'pagerduty-test', - integrationKey: 'abc123', - serviceId: 'def456', - }); - }); - }); -}); diff --git a/plugins/pagerduty/src/components/pagerDutyEntity.ts b/plugins/pagerduty/src/components/pagerDutyEntity.ts deleted file mode 100644 index 950525881e..0000000000 --- a/plugins/pagerduty/src/components/pagerDutyEntity.ts +++ /dev/null @@ -1,29 +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 { Entity } from '@backstage/catalog-model'; -import { PagerDutyEntity } from '../types'; -import { PAGERDUTY_INTEGRATION_KEY, PAGERDUTY_SERVICE_ID } from './constants'; - -export function getPagerDutyEntity(entity: Entity): PagerDutyEntity { - const { - [PAGERDUTY_INTEGRATION_KEY]: integrationKey, - [PAGERDUTY_SERVICE_ID]: serviceId, - } = entity.metadata.annotations || ({} as Record); - const name = entity.metadata.name; - - return { integrationKey, serviceId, name }; -} diff --git a/plugins/pagerduty/src/components/types.ts b/plugins/pagerduty/src/components/types.ts deleted file mode 100644 index 156b5c9b9d..0000000000 --- a/plugins/pagerduty/src/components/types.ts +++ /dev/null @@ -1,93 +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. - */ - -/** @public */ -export type PagerDutyChangeEvent = { - id: string; - integration: [ - { - service: PagerDutyService; - }, - ]; - source: string; - html_url: string; - links: [ - { - href: string; - text: string; - }, - ]; - summary: string; - timestamp: string; -}; - -/** @public */ -export type PagerDutyIncident = { - id: string; - title: string; - status: string; - html_url: string; - assignments: [ - { - assignee: PagerDutyAssignee; - }, - ]; - serviceId: string; - created_at: string; -}; - -/** @public */ -export type PagerDutyService = { - id: string; - name: string; - html_url: string; - integrationKey: string; - escalation_policy: { - id: string; - user: PagerDutyUser; - html_url: string; - }; -}; - -/** @public */ -export type PagerDutyOnCall = { - user: PagerDutyUser; - escalation_level: number; -}; - -/** @public */ -export type PagerDutyAssignee = { - id: string; - summary: string; - html_url: string; -}; - -/** @public */ -export type PagerDutyUser = { - id: string; - summary: string; - email: string; - html_url: string; - name: string; -}; - -/** @public */ -export type SubHeaderLink = { - title: string; - href?: string; - icon: React.ReactNode; - action?: React.ReactNode; -}; diff --git a/plugins/pagerduty/src/deprecated.ts b/plugins/pagerduty/src/deprecated.ts deleted file mode 100644 index e9f60f6894..0000000000 --- a/plugins/pagerduty/src/deprecated.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { EntityPagerDutyCardProps, EntityPagerDutyCard } from './components'; - -/** - * @public - * @deprecated Please use EntityPagerDutyCard - */ -export const PagerDutyCard = EntityPagerDutyCard; - -/** - * @public - * @deprecated Please use EntityPagerDutyCardProps - */ -export type PagerDutyCardProps = EntityPagerDutyCardProps; diff --git a/plugins/pagerduty/src/hooks/index.ts b/plugins/pagerduty/src/hooks/index.ts deleted file mode 100644 index 8950e443e2..0000000000 --- a/plugins/pagerduty/src/hooks/index.ts +++ /dev/null @@ -1,25 +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 { useEntity } from '@backstage/plugin-catalog-react'; -import { PagerDutyEntity } from '../types'; -import { getPagerDutyEntity } from '../components/pagerDutyEntity'; - -export function usePagerdutyEntity(): PagerDutyEntity { - const { entity } = useEntity(); - - return getPagerDutyEntity(entity); -} diff --git a/plugins/pagerduty/src/index.ts b/plugins/pagerduty/src/index.ts deleted file mode 100644 index c6f7aef89a..0000000000 --- a/plugins/pagerduty/src/index.ts +++ /dev/null @@ -1,35 +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. - */ - -/** - * A Backstage plugin that integrates towards PagerDuty - * - * @packageDocumentation - */ - -export { - pagerDutyPlugin, - pagerDutyPlugin as plugin, - EntityPagerDutyCard, - HomePagePagerDutyCard, -} from './plugin'; - -export * from './components'; - -export * from './api'; -export * from './deprecated'; - -export type { PagerDutyEntity } from './types'; diff --git a/plugins/pagerduty/src/plugin.test.ts b/plugins/pagerduty/src/plugin.test.ts deleted file mode 100644 index c9fe003abd..0000000000 --- a/plugins/pagerduty/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { pagerDutyPlugin } from './plugin'; - -describe('pagerduty', () => { - it('should export plugin', () => { - expect(pagerDutyPlugin).toBeDefined(); - }); -}); diff --git a/plugins/pagerduty/src/plugin.ts b/plugins/pagerduty/src/plugin.ts deleted file mode 100644 index 4144eb5878..0000000000 --- a/plugins/pagerduty/src/plugin.ts +++ /dev/null @@ -1,99 +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 { pagerDutyApiRef, PagerDutyClient } from './api'; -import { - createApiFactory, - createPlugin, - createRouteRef, - discoveryApiRef, - fetchApiRef, - configApiRef, - createComponentExtension, -} from '@backstage/core-plugin-api'; -import { createCardExtension } from '@backstage/plugin-home-react'; -import { HomePagePagerDutyCardProps } from './components/HomePagePagerDutyCard/Content'; - -export const rootRouteRef = createRouteRef({ - id: 'pagerduty', -}); - -/** - * @public - * @deprecated This plugin will be removed in a future release. Please use \@pagerduty/backstage-plugin plugin instead (https://www.npmjs.com/package/\@pagerduty/backstage-plugin). - */ -export const pagerDutyPlugin = createPlugin({ - id: 'pagerduty', - apis: [ - createApiFactory({ - api: pagerDutyApiRef, - deps: { - discoveryApi: discoveryApiRef, - configApi: configApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ configApi, discoveryApi, fetchApi }) => - PagerDutyClient.fromConfig(configApi, { discoveryApi, fetchApi }), - }), - ], -}); - -/** - * @public - * @deprecated This plugin and it's cards will be removed in a future release. Please use \@pagerduty/backstage-plugin plugin instead (https://www.npmjs.com/package/\@pagerduty/backstage-plugin). - */ -export const EntityPagerDutyCard = pagerDutyPlugin.provide( - createComponentExtension({ - name: 'EntityPagerDutyCard', - component: { - lazy: () => - import('./components/EntityPagerDutyCard').then( - m => m.EntityPagerDutyCard, - ), - }, - }), -); - -/** - * @public - * @deprecated This plugin and it's cards will be removed in a future release. Please use \@pagerduty/backstage-plugin plugin instead (https://www.npmjs.com/package/\@pagerduty/backstage-plugin). - */ -export const HomePagePagerDutyCard = pagerDutyPlugin.provide( - createCardExtension({ - name: 'HomePagePagerDutyCard', - title: 'PagerDuty Homepage Card', - components: () => import('./components/HomePagePagerDutyCard'), - settings: { - schema: { - title: 'PagerDuty', - type: 'object', - properties: { - integrationKey: { - title: 'PagerDuty integration key', - type: 'string', - }, - serviceId: { - title: 'PagerDuty service id', - type: 'string', - }, - name: { - title: 'PagerDuty service name', - type: 'string', - }, - }, - }, - }, - }), -); diff --git a/plugins/pagerduty/src/setupTests.ts b/plugins/pagerduty/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/pagerduty/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/pagerduty/src/types.ts b/plugins/pagerduty/src/types.ts deleted file mode 100644 index e026a6ffbe..0000000000 --- a/plugins/pagerduty/src/types.ts +++ /dev/null @@ -1,25 +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. - */ - -/** - * @public - * @deprecated This plugin and it's types will be removed in a future release. Please use \@pagerduty/backstage-plugin plugin instead (https://www.npmjs.com/package/\@pagerduty/backstage-plugin). - */ -export type PagerDutyEntity = { - integrationKey?: string; - serviceId?: string; - name: string; -}; diff --git a/plugins/periskop-backend/.eslintrc.js b/plugins/periskop-backend/.eslintrc.js deleted file mode 100644 index 16a033dbc6..0000000000 --- a/plugins/periskop-backend/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint.backend')], -}; diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md deleted file mode 100644 index 83e56a7880..0000000000 --- a/plugins/periskop-backend/CHANGELOG.md +++ /dev/null @@ -1,808 +0,0 @@ -# @backstage/plugin-periskop-backend - -## 0.2.8-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/config@1.1.1 - -## 0.2.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/config@1.1.1 - -## 0.2.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.1 - - @backstage/backend-common@0.21.0-next.1 - - @backstage/config@1.1.1 - -## 0.2.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/backend-plugin-api@0.6.10-next.0 - - @backstage/config@1.1.1 - -## 0.2.7 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/backend-plugin-api@0.6.9 - - @backstage/config@1.1.1 - -## 0.2.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - - @backstage/backend-common@0.20.1-next.2 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/backend-plugin-api@0.6.9-next.1 - -## 0.2.7-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/backend-plugin-api@0.6.9-next.0 - - @backstage/config@1.1.1 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/backend-plugin-api@0.6.8 - - @backstage/config@1.1.1 - -## 0.2.6-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-plugin-api@0.6.8-next.3 - - @backstage/config@1.1.1 - -## 0.2.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/backend-plugin-api@0.6.8-next.2 - - @backstage/config@1.1.1 - -## 0.2.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-plugin-api@0.6.8-next.1 - - @backstage/config@1.1.1 - -## 0.2.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-plugin-api@0.6.8-next.0 - - @backstage/config@1.1.1 - -## 0.2.5 - -### Patch Changes - -- 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export. -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/backend-plugin-api@0.6.7 - - @backstage/config@1.1.1 - -## 0.2.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - - @backstage/backend-common@0.19.9-next.2 - -## 0.2.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-plugin-api@0.6.7-next.1 - - @backstage/config@1.1.1 - -## 0.2.5-next.0 - -### Patch Changes - -- 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export. -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/config@1.1.1 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/backend-plugin-api@0.6.6 - - @backstage/config@1.1.1 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/backend-plugin-api@0.6.6-next.2 - - @backstage/config@1.1.1-next.0 - -## 0.2.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/backend-plugin-api@0.6.5-next.1 - - @backstage/config@1.1.0 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/backend-plugin-api@0.6.5-next.0 - -## 0.2.0 - -### Minor Changes - -- 71114ac50e02: **BREAKING**: The export for the new backend system has been moved to be the `default` export. - - For example, if you are currently importing the plugin using the following pattern: - - ```ts - import { examplePlugin } from '@backstage/plugin-example-backend'; - - backend.add(examplePlugin); - ``` - - It should be migrated to this: - - ```ts - backend.add(import('@backstage/plugin-example-backend')); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/backend-plugin-api@0.6.3 - -## 0.2.0-next.3 - -### Minor Changes - -- 71114ac50e02: **BREAKING**: The export for the new backend system has been moved to be the `default` export. - - For example, if you are currently importing the plugin using the following pattern: - - ```ts - import { examplePlugin } from '@backstage/plugin-example-backend'; - - backend.add(examplePlugin); - ``` - - It should be migrated to this: - - ```ts - backend.add(import('@backstage/plugin-example-backend')); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/backend-plugin-api@0.6.3-next.3 - - @backstage/backend-common@0.19.5-next.3 - -## 0.1.22-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/backend-plugin-api@0.6.3-next.2 - -## 0.1.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/backend-plugin-api@0.6.3-next.1 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/backend-plugin-api@0.6.2-next.0 - - @backstage/config@1.0.8 - -## 0.1.19 - -### Patch Changes - -- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config` -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/backend-plugin-api@0.6.0 - - @backstage/config@1.0.8 - -## 0.1.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.0-next.2 - - @backstage/backend-common@0.19.2-next.2 - -## 0.1.19-next.1 - -### Patch Changes - -- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config` -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/backend-plugin-api@0.6.0-next.1 - - @backstage/config@1.0.8 - -## 0.1.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/backend-plugin-api@0.5.5-next.0 - - @backstage/config@1.0.8 - -## 0.1.18 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1 - - @backstage/backend-plugin-api@0.5.4 - - @backstage/config@1.0.8 - -## 0.1.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1-next.0 - - @backstage/backend-plugin-api@0.5.4-next.0 - - @backstage/config@1.0.8 - -## 0.1.17 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/backend-plugin-api@0.5.3 - - @backstage/config@1.0.8 - -## 0.1.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/backend-plugin-api@0.5.3-next.2 - - @backstage/config@1.0.7 - -## 0.1.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/backend-plugin-api@0.5.3-next.1 - - @backstage/config@1.0.7 - -## 0.1.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-plugin-api@0.5.3-next.0 - -## 0.1.16 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/backend-plugin-api@0.5.2 - - @backstage/config@1.0.7 - -## 0.1.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/backend-plugin-api@0.5.2-next.1 - - @backstage/config@1.0.7 - -## 0.1.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/backend-plugin-api@0.5.2-next.0 - - @backstage/config@1.0.7 - -## 0.1.15 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/backend-plugin-api@0.5.1 - - @backstage/config@1.0.7 - -## 0.1.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/backend-plugin-api@0.5.1-next.2 - - @backstage/config@1.0.7 - -## 0.1.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.1 - - @backstage/backend-plugin-api@0.5.1-next.1 - - @backstage/config@1.0.7 - -## 0.1.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-plugin-api@0.5.1-next.0 - -## 0.1.14 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3 - - @backstage/backend-plugin-api@0.5.0 - - @backstage/config@1.0.7 - -## 0.1.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/backend-plugin-api@0.4.1-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.1.14-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3-next.1 - - @backstage/backend-plugin-api@0.4.1-next.1 - - @backstage/config@1.0.7-next.0 - -## 0.1.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.4.1-next.0 - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - -## 0.1.13 - -### Patch Changes - -- 0ff03319be: Updated usage of `createBackendPlugin`. -- 4a6f38a535: Added a Backend System plugin feature -- Updated dependencies - - @backstage/backend-plugin-api@0.4.0 - - @backstage/backend-common@0.18.2 - - @backstage/config@1.0.6 - -## 0.1.13-next.2 - -### Patch Changes - -- 0ff03319be: Updated usage of `createBackendPlugin`. -- 4a6f38a535: Added a Backend System plugin feature -- Updated dependencies - - @backstage/backend-plugin-api@0.4.0-next.2 - - @backstage/backend-common@0.18.2-next.2 - - @backstage/config@1.0.6 - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/config@1.0.6 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/config@1.0.6 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/config@1.0.6-next.0 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - -## 0.1.10 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/config@1.0.5 - -## 0.1.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.3 - - @backstage/config@1.0.5-next.1 - -## 0.1.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/config@1.0.5-next.1 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/config@1.0.5-next.1 - -## 0.1.10-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/config@1.0.5-next.0 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/config@1.0.4 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/config@1.0.4-next.0 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/config@1.0.4-next.0 - -## 0.1.8 - -### Patch Changes - -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/config@1.0.3 - -## 0.1.8-next.2 - -### Patch Changes - -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/backend-common@0.15.2-next.2 - - @backstage/config@1.0.3-next.2 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/config@1.0.3-next.1 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.0 - - @backstage/config@1.0.3-next.0 - -## 0.1.7 - -### Patch Changes - -- 148568b5c2: Switched to using node-fetch instead of cross-fetch as is standard for our backend packages -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/config@1.0.2 - -## 0.1.7-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/backend-common@0.15.1-next.3 - -## 0.1.7-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.2 - -## 0.1.7-next.1 - -### Patch Changes - -- 148568b5c2: Switched to using node-fetch instead of cross-fetch as is standard for our backend packages -- Updated dependencies - - @backstage/backend-common@0.15.1-next.1 - -## 0.1.7-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.0 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.0-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/backend-common@0.14.1 - -## 0.1.5-next.1 - -### Patch Changes - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.3 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - -## 0.1.4 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/backend-common@0.14.0 - -## 0.1.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - -## 0.1.4-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/backend-common@0.13.6-next.1 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.6-next.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/config@1.0.1 - -## 0.1.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/config@1.0.1-next.0 - -## 0.1.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.2 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.2-next.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/config@1.0.0 - -## 0.1.0 - -### Minor Changes - -- 7ef026339d: Add periskop and periskop-backend plugin, for usage with exception aggregation tool https://periskop.io/ - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0 - -## 0.1.0-next.0 - -### Minor Changes - -- 7ef026339d: Add periskop and periskop-backend plugin, for usage with exception aggregation tool https://periskop.io/ - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 diff --git a/plugins/periskop-backend/README.md b/plugins/periskop-backend/README.md deleted file mode 100644 index 02552fe5b4..0000000000 --- a/plugins/periskop-backend/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# periskop-backend - -Simple plugin that proxies requests to the Periskop server APIs. - -To be used with the [Periskop plugin](../periskop/README.md). diff --git a/plugins/periskop-backend/api-report-alpha.md b/plugins/periskop-backend/api-report-alpha.md deleted file mode 100644 index d6ace05993..0000000000 --- a/plugins/periskop-backend/api-report-alpha.md +++ /dev/null @@ -1,13 +0,0 @@ -## API Report File for "@backstage/plugin-periskop-backend" - -> 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'; - -// @alpha -const _default: () => BackendFeature; -export default _default; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/periskop-backend/api-report.md b/plugins/periskop-backend/api-report.md deleted file mode 100644 index caaed109f9..0000000000 --- a/plugins/periskop-backend/api-report.md +++ /dev/null @@ -1,22 +0,0 @@ -## API Report File for "@backstage/plugin-periskop-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 (undocumented) -export function createRouter(options: RouterOptions): Promise; - -// @public (undocumented) -export interface RouterOptions { - // (undocumented) - config: Config; - // (undocumented) - logger: Logger; -} - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/periskop-backend/catalog-info.yaml b/plugins/periskop-backend/catalog-info.yaml deleted file mode 100644 index 8ad2a7f261..0000000000 --- a/plugins/periskop-backend/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-periskop-backend - title: '@backstage/plugin-periskop-backend' -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: maintainers diff --git a/plugins/periskop-backend/knip-report.md b/plugins/periskop-backend/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/periskop-backend/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json deleted file mode 100644 index 380fe5af9c..0000000000 --- a/plugins/periskop-backend/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@backstage/plugin-periskop-backend", - "version": "0.2.8-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "homepage": "https://periskop.io", - "backstage": { - "role": "backend-plugin" - }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/periskop-backend" - }, - "publishConfig": { - "access": "public" - }, - "exports": { - ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - "alpha": [ - "src/alpha.ts" - ], - "package.json": [ - "package.json" - ] - } - }, - "scripts": { - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/config": "workspace:^", - "@types/express": "*", - "express": "^4.17.1", - "express-promise-router": "^4.1.0", - "node-fetch": "^2.6.7", - "winston": "^3.2.1", - "yn": "^4.0.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/supertest": "^2.0.8", - "supertest": "^6.1.6" - }, - "files": [ - "dist", - "alpha" - ] -} diff --git a/plugins/periskop-backend/src/alpha.ts b/plugins/periskop-backend/src/alpha.ts deleted file mode 100644 index 59271e02fc..0000000000 --- a/plugins/periskop-backend/src/alpha.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { createRouter } from './service/router'; - -/** - * The Periskop backend plugin. - * - * @alpha - */ -export default createBackendPlugin({ - pluginId: 'periskop', - register(env) { - env.registerInit({ - deps: { - config: coreServices.rootConfig, - logger: coreServices.logger, - httpRouter: coreServices.httpRouter, - }, - async init({ config, logger, httpRouter }) { - httpRouter.use( - await createRouter({ config, logger: loggerToWinstonLogger(logger) }), - ); - }, - }); - }, -}); diff --git a/plugins/periskop-backend/src/api/index.ts b/plugins/periskop-backend/src/api/index.ts deleted file mode 100644 index 6245dcacfd..0000000000 --- a/plugins/periskop-backend/src/api/index.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 { AggregatedError, NotFoundInInstance } from '../types'; -import fetch from 'node-fetch'; - -export type Options = { - config: Config; -}; - -type PeriskopInstance = { - name: string; - url: string; -}; - -export class PeriskopApi { - private readonly instances: PeriskopInstance[]; - - constructor(options: Options) { - this.instances = options.config - .getConfigArray('periskop.instances') - .flatMap(locConf => { - const name = locConf.getString('name'); - const url = locConf.getString('url'); - return { name: name, url: url }; - }); - } - - private getApiUrl(instanceName: string): string | undefined { - return this.instances.find(instance => instance.name === instanceName)?.url; - } - - async getErrors( - instanceName: string, - serviceName: string, - ): Promise { - const apiUrl = this.getApiUrl(instanceName); - if (!apiUrl) { - throw new Error( - `failed to fetch data, no periskop instance with name ${instanceName}`, - ); - } - const response = await fetch(`${apiUrl}/services/${serviceName}/errors/`); - - if (!response.ok) { - if (response.status === 404) { - return { - body: await response.text(), - }; - } - - throw new Error( - `failed to fetch data, status ${response.status}: ${response.statusText}`, - ); - } - return response.json(); - } -} diff --git a/plugins/periskop-backend/src/index.ts b/plugins/periskop-backend/src/index.ts deleted file mode 100644 index ca73cb27ba..0000000000 --- a/plugins/periskop-backend/src/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './service/router'; diff --git a/plugins/periskop-backend/src/run.ts b/plugins/periskop-backend/src/run.ts deleted file mode 100644 index 0a3ed2b7f0..0000000000 --- a/plugins/periskop-backend/src/run.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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/periskop-backend/src/service/router.test.ts b/plugins/periskop-backend/src/service/router.test.ts deleted file mode 100644 index 687255c6e0..0000000000 --- a/plugins/periskop-backend/src/service/router.test.ts +++ /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 { getVoidLogger } from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import express from 'express'; -import request from 'supertest'; - -import { createRouter } from './router'; - -describe('createRouter', () => { - let app: express.Express; - - beforeAll(async () => { - const router = await createRouter({ - logger: getVoidLogger(), - config: new ConfigReader({ - periskop: { - instances: [ - { - name: 'db', - url: 'http://periskop-db', - }, - ], - }, - }), - }); - app = express().use(router); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('GET /health', () => { - it('returns ok', async () => { - const response = await request(app).get('/health'); - - expect(response.status).toEqual(200); - expect(response.body).toEqual({ status: 'ok' }); - }); - }); -}); diff --git a/plugins/periskop-backend/src/service/router.ts b/plugins/periskop-backend/src/service/router.ts deleted file mode 100644 index 38a43c5050..0000000000 --- a/plugins/periskop-backend/src/service/router.ts +++ /dev/null @@ -1,57 +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 { errorHandler } from '@backstage/backend-common'; -import express from 'express'; -import Router from 'express-promise-router'; -import { Logger } from 'winston'; -import { PeriskopApi } from '../api/index'; -import { Config } from '@backstage/config'; - -/** - * @public - */ -export interface RouterOptions { - logger: Logger; - config: Config; -} - -/** - * @public - */ -export async function createRouter( - options: RouterOptions, -): Promise { - const { logger, config } = options; - const periskopApi = new PeriskopApi({ config }); - - const router = Router(); - router.use(express.json()); - - router.get('/health', (_, response) => { - logger.info('PONG!'); - response.json({ status: 'ok' }); - }); - - router.get('/:locationName/:serviceName', async (request, response) => { - const { locationName, serviceName } = request.params; - logger.info(`Periskop got queried for ${serviceName} in ${locationName}`); - const errors = await periskopApi.getErrors(locationName, serviceName); - response.status(200).json(errors); - }); - router.use(errorHandler()); - return router; -} diff --git a/plugins/periskop-backend/src/service/standaloneServer.ts b/plugins/periskop-backend/src/service/standaloneServer.ts deleted file mode 100644 index 635b139ccf..0000000000 --- a/plugins/periskop-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 { - createServiceBuilder, - loadBackendConfig, -} from '@backstage/backend-common'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'periskop-backend' }); - const config = await loadBackendConfig({ logger, argv: process.argv }); - - logger.debug('Starting application server...'); - const router = await createRouter({ - logger, - config, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/periskop', 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/periskop-backend/src/setupTests.ts b/plugins/periskop-backend/src/setupTests.ts deleted file mode 100644 index 813cdeaae3..0000000000 --- a/plugins/periskop-backend/src/setupTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 {}; diff --git a/plugins/periskop-backend/src/types.ts b/plugins/periskop-backend/src/types.ts deleted file mode 100644 index 084ba52620..0000000000 --- a/plugins/periskop-backend/src/types.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 AggregatedError { - aggregation_key: string; - total_count: number; - severity: string; - latest_errors: ErrorInstance[]; -} -export interface ErrorInstance { - error: Error; - uuid: string; - timestamp: number; - severity: string; - http_context: HttpContext; -} -export interface Error { - class: string; - message: string; - stacktrace?: string[]; - cause?: Error | null; -} -export interface HttpContext { - request_method: string; - request_url: string; - request_headers: RequestHeaders; - request_body: string; -} -export interface RequestHeaders { - [k: string]: string; -} - -export interface NotFoundInInstance { - body: string; -} diff --git a/plugins/periskop/.eslintrc.js b/plugins/periskop/.eslintrc.js deleted file mode 100644 index 13573efa9c..0000000000 --- a/plugins/periskop/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint')], -}; diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md deleted file mode 100644 index caf57b8c9f..0000000000 --- a/plugins/periskop/CHANGELOG.md +++ /dev/null @@ -1,1142 +0,0 @@ -# @backstage/plugin-periskop - -## 0.1.28-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.1.28-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.1.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/errors@1.2.3 - -## 0.1.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.1.27 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.27-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.1.27-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.27-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.1.26 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.26-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.1.26-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.1.26-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.1.26-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.24 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.24-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.1.24-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - -## 0.1.24-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.23 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - -## 0.1.23-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - -## 0.1.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.22 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.22-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.1.22-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.21-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.1.19 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.1.19-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/catalog-model@1.4.1 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.1-next.0 - -## 0.1.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.18 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.1.18-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - -## 0.1.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.1.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.1.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - -## 0.1.17-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.1.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.1.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.1.16 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.1.16-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.1.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.1.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19 - -## 0.1.15 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.1.15-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.1.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.1.15-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.1.15-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - -## 0.1.14 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.1.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.1.14-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.1.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 - -## 0.1.13 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/errors@1.1.4 - -## 0.1.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.1.10 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.10-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.1.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.1.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.1.10-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.1.9 - -### Patch Changes - -- 7573b65232: Internal refactor of imports to avoid circular dependencies -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/errors@1.1.3 - - @backstage/theme@0.2.16 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.1.9-next.0 - -### Patch Changes - -- 7573b65232: Internal refactor of imports to avoid circular dependencies -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - - @backstage/theme@0.2.16 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/theme@0.2.16 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/theme@0.2.16 - -## 0.1.7 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - - @backstage/errors@1.1.1 - -## 0.1.7-next.2 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.1.7-next.1 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.1.7-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -## 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 - -## 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 - -## 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 - -## 0.1.5-next.3 - -### Patch Changes - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.1.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.1.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.1.4 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.1.4-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.1.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.1.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.1.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.1.2 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.1.2-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.1.1 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - - @backstage/errors@1.0.0 - -## 0.1.0 - -### Minor Changes - -- 7ef026339d: Add periskop and periskop-backend plugin, for usage with exception aggregation tool https://periskop.io/ - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.1.0-next.0 - -### Minor Changes - -- 7ef026339d: Add periskop and periskop-backend plugin, for usage with exception aggregation tool https://periskop.io/ - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 diff --git a/plugins/periskop/README.md b/plugins/periskop/README.md deleted file mode 100644 index 85bced7c1b..0000000000 --- a/plugins/periskop/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# periskop - -[Periskop](https://periskop.io/) is a pull-based, language agnostic exception aggregator for microservice environments. - -![periskop-logo](https://i.imgur.com/z8BLePO.png) - -## Periskop aggregated errors - -The Periskop Backstage Plugin exposes a component named `EntityPeriskopErrorsCard`. -Each of the entries in the table will direct you to the error details in your deployed Periskop instance location. - -![periskop-errors-card](./docs/periskop-plugin-screenshot.png) - -## Setup - -1. Configure the [periskop backend plugin](https://github.com/backstage/backstage/tree/master/plugins/periskop-backend/) - -2. Install the plugin by running: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-periskop -``` - -3. Add to the app `EntityPage` component: - -```tsx -// In packages/app/src/components/catalog/EntityPage.tsx -import { EntityPeriskopErrorsCard } from '@backstage/plugin-periskop'; - -const componentPage = ( - - {/* other tabs... */} - - - - - - - -``` - -4. [Setup the `app-config.yaml`](#instances) `periskop` block - -5. Annotate entities with the periskop service name - -```yaml -annotations: - periskop.io/service-name: '' -``` - -6. Run app with `yarn start` and navigate to `/periskop` or a catalog entity 'Periskop' tab - -### Instances - -The periskop plugin can be configured to fetch aggregated errors from multiple deployment instances. -This is especially useful if you have a multi-zone deployment, or a federated setup and would like to drill deeper into a single instance of the federation. Each of the configured instances will be included in the plugin's UI via a dropdown on the errors table. - -The plugin requires to configure _at least one_ Periskop API location in the [app-config.yaml](https://github.com/backstage/backstage/blob/master/app-config.yaml): - -```yaml -periskop: - instances: - - name: - url: -``` diff --git a/plugins/periskop/api-report.md b/plugins/periskop/api-report.md deleted file mode 100644 index 607cbbb4d0..0000000000 --- a/plugins/periskop/api-report.md +++ /dev/null @@ -1,132 +0,0 @@ -## API Report File for "@backstage/plugin-periskop" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { ConfigApi } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { JSX as JSX_2 } from 'react'; - -// @public (undocumented) -export interface AggregatedError { - // (undocumented) - aggregation_key: string; - // (undocumented) - latest_errors: ErrorInstance[]; - // (undocumented) - severity: string; - // (undocumented) - total_count: number; -} - -// @public (undocumented) -export const EntityPeriskopErrorsCard: () => JSX_2.Element; - -// @public (undocumented) -interface Error_2 { - // (undocumented) - cause?: Error_2 | null; - // (undocumented) - class: string; - // (undocumented) - message: string; - // (undocumented) - stacktrace?: string[]; -} -export { Error_2 as Error }; - -// @public (undocumented) -export interface ErrorInstance { - // (undocumented) - error: Error_2; - // (undocumented) - http_context: HttpContext; - // (undocumented) - severity: string; - // (undocumented) - timestamp: number; - // (undocumented) - uuid: string; -} - -// @public (undocumented) -export interface HttpContext { - // (undocumented) - request_body: string; - // (undocumented) - request_headers: RequestHeaders; - // (undocumented) - request_method: string; - // (undocumented) - request_url: string; -} - -// @public -export const isPeriskopAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export interface NotFoundInInstance { - // (undocumented) - body: string; -} - -// @public -export const PERISKOP_NAME_ANNOTATION = 'periskop.io/service-name'; - -// @public -export interface PeriskopApi { - getErrorInstanceUrl( - instanceName: string, - serviceName: string, - error: AggregatedError, - ): string; - getErrors( - instanceName: string, - serviceName: string, - ): Promise; - getInstanceNames(): string[]; -} - -// @public (undocumented) -export type PeriskopApiOptions = { - discoveryApi: DiscoveryApi; - configApi: ConfigApi; -}; - -// @public (undocumented) -export const periskopApiRef: ApiRef; - -// @public -export class PeriskopClient implements PeriskopApi { - constructor(options: PeriskopApiOptions); - // (undocumented) - getErrorInstanceUrl( - instanceName: string, - serviceName: string, - error: AggregatedError, - ): string; - // (undocumented) - getErrors( - instanceName: string, - serviceName: string, - ): Promise; - // (undocumented) - getInstanceNames(): string[]; -} - -// @public (undocumented) -export const periskopPlugin: BackstagePlugin<{}, {}>; - -// @public (undocumented) -export interface RequestHeaders { - // (undocumented) - [k: string]: string; -} - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/periskop/catalog-info.yaml b/plugins/periskop/catalog-info.yaml deleted file mode 100644 index b4ca9bdd34..0000000000 --- a/plugins/periskop/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-periskop - title: '@backstage/plugin-periskop' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/periskop/config.d.ts b/plugins/periskop/config.d.ts deleted file mode 100644 index dfb914cd4f..0000000000 --- a/plugins/periskop/config.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 { - /** - * Configuration options for the periskop plugin - */ - periskop?: { - /** - * Integration configuration for the periskop servers - * @visibility frontend - */ - instances: Array<{ - /** - * The name of the given Periskop instance - * @visibility frontend - */ - name: string; - /** - * The hostname of the given Periskop instance - * @visibility frontend - */ - url: string; - }>; - }; -} diff --git a/plugins/periskop/dev/index.tsx b/plugins/periskop/dev/index.tsx deleted file mode 100644 index b752f7f8b0..0000000000 --- a/plugins/periskop/dev/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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 { createDevApp } from '@backstage/dev-utils'; -import { periskopPlugin } from '../src/plugin'; - -createDevApp().registerPlugin(periskopPlugin).render(); diff --git a/plugins/periskop/docs/periskop-plugin-screenshot.png b/plugins/periskop/docs/periskop-plugin-screenshot.png deleted file mode 100644 index 9971f41992..0000000000 Binary files a/plugins/periskop/docs/periskop-plugin-screenshot.png and /dev/null differ diff --git a/plugins/periskop/knip-report.md b/plugins/periskop/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/periskop/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json deleted file mode 100644 index 01be969a58..0000000000 --- a/plugins/periskop/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "@backstage/plugin-periskop", - "version": "0.1.28-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "homepage": "https://periskop.io", - "backstage": { - "role": "frontend-plugin" - }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/periskop" - }, - "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "luxon": "^3.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@types/luxon": "^3.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/periskop/src/api/index.ts b/plugins/periskop/src/api/index.ts deleted file mode 100644 index 4171d55ae2..0000000000 --- a/plugins/periskop/src/api/index.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 { ConfigApi, DiscoveryApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { AggregatedError, NotFoundInInstance } from '../types'; - -/** @public */ -export type PeriskopApiOptions = { - discoveryApi: DiscoveryApi; - configApi: ConfigApi; -}; - -type PeriskopInstance = { - name: string; - url: string; -}; - -/** - * API abstraction to interact with Periskop's backends. - * - * @public - */ -export interface PeriskopApi { - /** - * Returns the list of registered Periskop instance names. - */ - getInstanceNames(): string[]; - - /** - * For the given instance and service, returns the URL pointing to the specific error instance occurrence. - * Note: This method might point to an external route. - */ - getErrorInstanceUrl( - instanceName: string, - serviceName: string, - error: AggregatedError, - ): string; - - /** - * Fetches all errors for the given service from the specified Periskop instance, given its name. - */ - getErrors( - instanceName: string, - serviceName: string, - ): Promise; -} - -/** - * API implementation to interact with Periskop's backends. - * - * @public - */ -export class PeriskopClient implements PeriskopApi { - private readonly discoveryApi: DiscoveryApi; - private readonly instances: PeriskopInstance[]; - - constructor(options: PeriskopApiOptions) { - this.discoveryApi = options.discoveryApi; - this.instances = options.configApi - .getConfigArray('periskop.instances') - .flatMap(locConf => { - const name = locConf.getString('name'); - const url = locConf.getString('url'); - return { name: name, url: url }; - }); - } - - private getApiUrl(instanceName: string): string | undefined { - return this.instances.find(instance => instance.name === instanceName)?.url; - } - - getInstanceNames(): string[] { - return this.instances.map(e => e.name); - } - - getErrorInstanceUrl( - instanceName: string, - serviceName: string, - error: AggregatedError, - ): string { - return `${this.getApiUrl( - instanceName, - )}/#/${serviceName}/errors/${encodeURIComponent(error.aggregation_key)}`; - } - - async getErrors( - instanceName: string, - serviceName: string, - ): Promise { - const apiUrl = `${await this.discoveryApi.getBaseUrl( - 'periskop', - )}/${instanceName}/${serviceName}`; - const response = await fetch(apiUrl); - - if (!response.ok) { - if (response.status === 404) { - return { - body: await response.text(), - }; - } - throw await ResponseError.fromResponse(response); - } - return response.json(); - } -} diff --git a/plugins/periskop/src/components/EntityPeriskopErrorsCard/EntityPeriskopErrorsCard.tsx b/plugins/periskop/src/components/EntityPeriskopErrorsCard/EntityPeriskopErrorsCard.tsx deleted file mode 100644 index 73a06693b1..0000000000 --- a/plugins/periskop/src/components/EntityPeriskopErrorsCard/EntityPeriskopErrorsCard.tsx +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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 { Entity } from '@backstage/catalog-model'; -import { useApi } from '@backstage/core-plugin-api'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { - Content, - ContentHeader, - Table, - TableColumn, - Progress, - ResponseErrorPanel, - StatusWarning, - StatusError, - StatusPending, - Select, - EmptyState, - Link, -} from '@backstage/core-components'; -import useAsync from 'react-use/lib/useAsync'; -import { periskopApiRef } from '../../plugin'; -import { AggregatedError, NotFoundInInstance } from '../../types'; - -/** - * Constant storing Periskop project name. - * - * @public - */ -export const PERISKOP_NAME_ANNOTATION = 'periskop.io/service-name'; - -/** - * Returns true if Periskop annotation is present in the given entity. - * - * @public - */ -export const isPeriskopAvailable = (entity: Entity): boolean => - Boolean(entity.metadata.annotations?.[PERISKOP_NAME_ANNOTATION]); - -const renderKey = ( - error: AggregatedError, - linkTarget: string, -): React.ReactNode => { - return {error.aggregation_key}; -}; - -const renderSeverity = (severity: string): React.ReactNode => { - if (severity.toLocaleLowerCase('en-US') === 'warning') { - return {severity}; - } else if (severity.toLocaleLowerCase('en-US') === 'error') { - return {severity}; - } - return {severity}; -}; - -const renderLastOccurrence = (error: AggregatedError): React.ReactNode => { - return DateTime.fromMillis( - error.latest_errors[0].timestamp * 1000, - ).toRelative(); -}; - -function isNotFoundInInstance( - apiResult: AggregatedError[] | NotFoundInInstance | undefined, -): apiResult is NotFoundInInstance { - return (apiResult as NotFoundInInstance)?.body !== undefined; -} - -export const EntityPeriskopErrorsCard = () => { - const { entity } = useEntity(); - const entityPeriskopName: string = - entity.metadata.annotations?.[PERISKOP_NAME_ANNOTATION] ?? - entity.metadata.name; - - const periskopApi = useApi(periskopApiRef); - const instanceNames = periskopApi.getInstanceNames(); - const [instanceOption, setInstanceOption] = React.useState( - instanceNames[0], - ); - const { - value: aggregatedErrors, - loading, - error, - } = useAsync(async (): Promise => { - return periskopApi.getErrors(instanceOption, entityPeriskopName); - }, [instanceOption]); - - if (loading) { - return ; - } else if (error) { - return ; - } - - const columns: TableColumn[] = [ - { - title: 'Key', - field: 'aggregation_key', - highlight: true, - sorting: false, - render: aggregatedError => { - const errorUrl = periskopApi.getErrorInstanceUrl( - instanceOption, - entityPeriskopName, - aggregatedError, - ); - return renderKey(aggregatedError, errorUrl); - }, - }, - { title: 'Occurrences', field: 'total_count', sorting: true }, - { - title: 'Last Occurrence', - render: aggregatedError => renderLastOccurrence(aggregatedError), - defaultSort: 'asc', - customSort: (a, b) => - b.latest_errors[0].timestamp - a.latest_errors[0].timestamp, - type: 'datetime', - }, - { - title: 'Severity', - field: 'severity', - render: aggregatedError => renderSeverity(aggregatedError.severity), - sorting: false, - }, - ]; - - const sortingSelect = ( - - {ownershipRefs?.map(ref => ( - - {humanizeEntityRef(parseEntityRef(ref), { - defaultKind: 'group', - })} - - ))} - - - )} - /> - )} - ( - - - } - /> - } - /> - - - )} - /> - - - -
- - {saving.loading && ( - - )} -
-
- - ); -}; diff --git a/plugins/playlist/src/components/PlaylistEditDialog/index.ts b/plugins/playlist/src/components/PlaylistEditDialog/index.ts deleted file mode 100644 index 3355443b82..0000000000 --- a/plugins/playlist/src/components/PlaylistEditDialog/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './PlaylistEditDialog'; diff --git a/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.test.tsx b/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.test.tsx deleted file mode 100644 index 35feb9cdae..0000000000 --- a/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.test.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { AuthorizeResult } from '@backstage/plugin-permission-common'; -import { - PermissionApi, - permissionApiRef, -} from '@backstage/plugin-permission-react'; -import React from 'react'; - -import { PlaylistApi, playlistApiRef } from '../../api'; -import { playlistRouteRef, rootRouteRef } from '../../routes'; -import { DefaultPlaylistIndexPage } from './DefaultPlaylistIndexPage'; - -const playlistApi: Partial = { - getAllPlaylists: async () => [], -}; - -const permissionApi: Partial = { - authorize: async () => ({ result: AuthorizeResult.ALLOW }), -}; - -describe('DefaultPlaylistIndexPage', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - { - mountedRoutes: { - '/playlists': rootRouteRef, - '/playlists/:playlistId': playlistRouteRef, - }, - }, - ); - expect(rendered.getByText('Playlists')).toBeInTheDocument(); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx b/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx deleted file mode 100644 index a2df92e532..0000000000 --- a/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { - PageWithHeader, - Content, - ContentHeader, - SupportButton, -} from '@backstage/core-components'; -import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; - -import { CreatePlaylistButton } from '../CreatePlaylistButton'; -import { PersonalListPicker } from '../PersonalListPicker'; -import { PlaylistList } from '../PlaylistList'; -import { PlaylistOwnerPicker } from '../PlaylistOwnerPicker'; -import { PlaylistSearchBar } from '../PlaylistSearchBar'; -import { PlaylistSortPicker } from '../PlaylistSortPicker'; -import { PlaylistListProvider } from '../../hooks/PlaylistListProvider'; -import { useTitle } from '../../hooks/useTitle'; - -/** - * @public - */ -export const DefaultPlaylistIndexPage = () => { - const pluralTitle = useTitle({ - pluralize: true, - lowerCase: false, - }); - - return ( - - - - - - - - - - - - - - - - - - - - - - ); -}; diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx deleted file mode 100644 index 5dbe621787..0000000000 --- a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.test.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { renderInTestApp } from '@backstage/test-utils'; -import { useOutlet } from 'react-router-dom'; -import { PlaylistIndexPage } from './PlaylistIndexPage'; - -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useOutlet: jest.fn().mockReturnValue('Route Children'), -})); - -jest.mock('./DefaultPlaylistIndexPage', () => ({ - DefaultPlaylistIndexPage: jest - .fn() - .mockReturnValue('DefaultPlaylistIndexPage'), -})); - -describe('PlaylistIndexPage', () => { - it('renders provided router element', async () => { - const { getByText } = await renderInTestApp(); - - expect(getByText('Route Children')).toBeInTheDocument(); - }); - - it('renders DefaultPlaylistIndexPage when no router children are provided', async () => { - (useOutlet as jest.Mock).mockReturnValueOnce(null); - const { getByText } = await renderInTestApp(); - - expect(getByText('DefaultPlaylistIndexPage')).toBeInTheDocument(); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx b/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx deleted file mode 100644 index 283d33c96d..0000000000 --- a/plugins/playlist/src/components/PlaylistIndexPage/PlaylistIndexPage.tsx +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { useOutlet } from 'react-router-dom'; -import { DefaultPlaylistIndexPage } from './DefaultPlaylistIndexPage'; - -export const PlaylistIndexPage = () => { - const outlet = useOutlet(); - - return outlet || ; -}; diff --git a/plugins/playlist/src/components/PlaylistIndexPage/index.ts b/plugins/playlist/src/components/PlaylistIndexPage/index.ts deleted file mode 100644 index 5c39468d74..0000000000 --- a/plugins/playlist/src/components/PlaylistIndexPage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { DefaultPlaylistIndexPage } from './DefaultPlaylistIndexPage'; -export { PlaylistIndexPage } from './PlaylistIndexPage'; diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx deleted file mode 100644 index 976db99983..0000000000 --- a/plugins/playlist/src/components/PlaylistList/PlaylistList.test.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 { ConfigApi, configApiRef } from '@backstage/core-plugin-api'; -import { Playlist } from '@backstage/plugin-playlist-common'; -import { TestApiProvider } from '@backstage/test-utils'; -import { render } from '@testing-library/react'; -import React from 'react'; - -import { MockPlaylistListProvider } from '../../testUtils'; -import { PlaylistList } from './PlaylistList'; - -const mockConfigApi = { - getOptionalString: () => undefined, -} as Partial; - -jest.mock('../PlaylistCard', () => ({ - PlaylistCard: ({ playlist }: { playlist: Playlist }) => ( -
{playlist.name}
- ), -})); - -describe('', () => { - it('renders error on error', () => { - const rendered = render( - - - - - , - ); - - expect(rendered.getByText('Test Error')).toBeInTheDocument(); - }); - - it('handles no playlists', () => { - const rendered = render( - - - - - , - ); - - expect( - rendered.getByText('No playlists found that match your filter.'), - ).toBeInTheDocument(); - }); - - it('renders playlists', () => { - const rendered = render( - - - - - , - ); - - expect(rendered.getByText('playlist-1')).toBeInTheDocument(); - expect(rendered.getByText('playlist-2')).toBeInTheDocument(); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx b/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx deleted file mode 100644 index 6ec06f3e05..0000000000 --- a/plugins/playlist/src/components/PlaylistList/PlaylistList.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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, - ItemCardGrid, - Progress, - WarningPanel, -} from '@backstage/core-components'; -import { Typography } from '@material-ui/core'; - -import { useTitle, usePlaylistList } from '../../hooks'; -import { PlaylistCard } from '../PlaylistCard'; - -/** - * @public - */ -export const PlaylistList = () => { - const { loading, error, playlists } = usePlaylistList(); - const pluralTitleLowerCase = useTitle({ - pluralize: true, - lowerCase: true, - }); - - return ( - <> - {loading && } - - {error && ( - - {error.message} - - )} - - {!error && !loading && !playlists.length && ( - - No playlists found that match your filter. - - )} - - - - {playlists?.length > 0 && - playlists.map(playlist => ( - - ))} - - - - ); -}; diff --git a/plugins/playlist/src/components/PlaylistList/index.ts b/plugins/playlist/src/components/PlaylistList/index.ts deleted file mode 100644 index 59fa5cf0fb..0000000000 --- a/plugins/playlist/src/components/PlaylistList/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './PlaylistList'; diff --git a/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx b/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx deleted file mode 100644 index c74e6f6853..0000000000 --- a/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.test.tsx +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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 { parseEntityRef } from '@backstage/catalog-model'; -import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; -import { Playlist } from '@backstage/plugin-playlist-common'; -import { fireEvent, render } from '@testing-library/react'; -import React from 'react'; -import { MockPlaylistListProvider } from '../../testUtils'; -import { - PlaylistOwnerFilter, - PlaylistOwnerPicker, -} from './PlaylistOwnerPicker'; - -const samplePlaylists: Playlist[] = [ - { - id: 'id1', - name: 'playlist-1', - owner: 'group:default/some-owner', - public: true, - entities: 1, - followers: 2, - isFollowing: false, - }, - { - id: 'id2', - name: 'playlist-2', - owner: 'group:default/another-owner', - public: true, - entities: 2, - followers: 1, - isFollowing: true, - }, - { - id: 'id3', - name: 'playlist-3', - owner: 'group:default/another-owner', - public: true, - entities: 2, - followers: 1, - isFollowing: true, - }, - { - id: 'id4', - name: 'playlist-4', - owner: 'user:default/owner', - public: true, - entities: 2, - followers: 1, - isFollowing: true, - }, -]; - -describe('', () => { - it('renders all owners', () => { - const rendered = render( - - - , - ); - expect(rendered.getByText('Owner')).toBeInTheDocument(); - - fireEvent.click(rendered.getByTestId('owner-picker-expand')); - samplePlaylists - .map(p => - humanizeEntityRef(parseEntityRef(p.owner), { defaultKind: 'group' }), - ) - .forEach(owner => { - expect(rendered.getByText(owner as string)).toBeInTheDocument(); - }); - }); - - it('renders unique owners in alphabetical order', () => { - const rendered = render( - - - , - ); - expect(rendered.getByText('Owner')).toBeInTheDocument(); - - fireEvent.click(rendered.getByTestId('owner-picker-expand')); - - expect(rendered.getAllByRole('option').map(o => o.textContent)).toEqual([ - 'another-owner', - 'some-owner', - 'user:owner', - ]); - }); - - it('respects the query parameter filter value', () => { - const updateFilters = jest.fn(); - const queryParameters = { owners: ['group:default/another-owner'] }; - render( - - - , - ); - - expect(updateFilters).toHaveBeenLastCalledWith({ - owners: new PlaylistOwnerFilter(['group:default/another-owner']), - }); - }); - - it('adds owners to filters', () => { - const updateFilters = jest.fn(); - const rendered = render( - - - , - ); - expect(updateFilters).toHaveBeenLastCalledWith({ - owners: undefined, - }); - - fireEvent.click(rendered.getByTestId('owner-picker-expand')); - fireEvent.click(rendered.getByText('some-owner')); - expect(updateFilters).toHaveBeenLastCalledWith({ - owners: new PlaylistOwnerFilter(['group:default/some-owner']), - }); - }); - - it('removes owners from filters', () => { - const updateFilters = jest.fn(); - const rendered = render( - - - , - ); - expect(updateFilters).toHaveBeenLastCalledWith({ - owners: new PlaylistOwnerFilter(['group:default/some-owner']), - }); - fireEvent.click(rendered.getByTestId('owner-picker-expand')); - expect(rendered.getByLabelText('some-owner')).toBeChecked(); - - fireEvent.click(rendered.getByLabelText('some-owner')); - expect(updateFilters).toHaveBeenLastCalledWith({ - owner: undefined, - }); - }); - - it('responds to external queryParameters changes', () => { - const updateFilters = jest.fn(); - const rendered = render( - - - , - ); - expect(updateFilters).toHaveBeenLastCalledWith({ - owners: new PlaylistOwnerFilter(['group:default/team-a']), - }); - rendered.rerender( - - - , - ); - expect(updateFilters).toHaveBeenLastCalledWith({ - owners: new PlaylistOwnerFilter(['group:default/team-b']), - }); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx b/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx deleted file mode 100644 index d7fd97ff19..0000000000 --- a/plugins/playlist/src/components/PlaylistOwnerPicker/PlaylistOwnerPicker.tsx +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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 { parseEntityRef } from '@backstage/catalog-model'; -import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; -import { Playlist } from '@backstage/plugin-playlist-common'; -import { - Box, - Checkbox, - Chip, - FormControlLabel, - TextField, - Typography, -} from '@material-ui/core'; -import CheckBoxIcon from '@material-ui/icons/CheckBox'; -import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { Autocomplete } from '@material-ui/lab'; -import React, { useEffect, useMemo, useState } from 'react'; - -import { usePlaylistList } from '../../hooks'; -import { PlaylistFilter } from '../../types'; - -/** - * @public - */ -export class PlaylistOwnerFilter implements PlaylistFilter { - constructor(readonly values: string[]) {} - - filterPlaylist(playlist: Playlist): boolean { - return this.values.some(v => playlist.owner === v); - } - - toQueryValue(): string[] { - return this.values; - } -} - -const icon = ; -const checkedIcon = ; - -/** - * @public - */ -export const PlaylistOwnerPicker = () => { - const { - updateFilters, - backendPlaylists, - filters, - queryParameters: { owners: ownersParameter }, - } = usePlaylistList(); - - const queryParamOwners = useMemo( - () => [ownersParameter].flat().filter(Boolean) as string[], - [ownersParameter], - ); - - const [selectedOwners, setSelectedOwners] = useState( - queryParamOwners.length ? queryParamOwners : filters.owners?.values ?? [], - ); - - // Set selected owners on query parameter updates; this happens at initial page load and from - // external updates to the page location. - useEffect(() => { - if (queryParamOwners.length) { - setSelectedOwners(queryParamOwners); - } - }, [queryParamOwners]); - - useEffect(() => { - updateFilters({ - owners: selectedOwners.length - ? new PlaylistOwnerFilter(selectedOwners) - : undefined, - }); - }, [selectedOwners, updateFilters]); - - const availableOwners = useMemo( - () => [...new Set(backendPlaylists.map(p => p.owner))].sort(), - [backendPlaylists], - ); - - if (!availableOwners.length) return null; - - return ( - - - Owner - setSelectedOwners(value)} - renderTags={(values: string[], getTagProps: Function) => - values.map((val, index) => ( - - )) - } - renderOption={(option, { selected }) => ( - - } - label={humanizeEntityRef(parseEntityRef(option), { - defaultKind: 'group', - })} - /> - )} - size="small" - popupIcon={} - renderInput={params => } - /> - - - ); -}; diff --git a/plugins/playlist/src/components/PlaylistOwnerPicker/index.ts b/plugins/playlist/src/components/PlaylistOwnerPicker/index.ts deleted file mode 100644 index fcde27e956..0000000000 --- a/plugins/playlist/src/components/PlaylistOwnerPicker/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './PlaylistOwnerPicker'; diff --git a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx deleted file mode 100644 index 96ec5677e7..0000000000 --- a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.test.tsx +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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 { - CatalogApi, - catalogApiRef, - entityRouteRef, -} from '@backstage/plugin-catalog-react'; -import { SearchApi, searchApiRef } from '@backstage/plugin-search-react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { fireEvent, getByText, act } from '@testing-library/react'; -import React from 'react'; - -import { AddEntitiesDrawer } from './AddEntitiesDrawer'; - -describe('AddEntitiesDrawer', () => { - const catalogApi: Partial = { - getEntityFacets: jest.fn().mockImplementation(async () => ({ - facets: { - kind: [{ value: 'component' }], - }, - })), - }; - - const mockOnAdd = jest.fn(); - const sampleCurrentEntities = [ - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'system', - metadata: { namespace: 'default', name: 'test-ent' }, - }, - ]; - - const mockSearchResults = [ - { - type: 'software-catalog', - document: { - title: 'Test Ent', - text: 'This is test ent', - location: '/catalog/default/system/test-ent', - kind: 'system', - }, - }, - { - type: 'software-catalog', - document: { - title: 'Test Ent 2', - text: 'This is test ent 2', - location: '/catalog/foo/component/test-ent2', - kind: 'component', - type: 'library', - }, - }, - { - type: 'software-catalog', - document: { - title: 'Test Ent 3', - text: 'This is test ent 3', - location: '/catalog/bar/api/test-ent3', - kind: 'api', - type: 'openapi', - }, - }, - ]; - - const searchApi: Partial = { - query: jest - .fn() - .mockImplementation(async () => ({ results: mockSearchResults })), - }; - - const element = ( - - - - ); - - const render = async () => - renderInTestApp(element, { - mountedRoutes: { '/catalog/:namespace/:kind/:name': entityRouteRef }, - }); - - beforeEach(() => { - mockOnAdd.mockClear(); - }); - - it('should render available entities correctly', async () => { - const rendered = await render(); - expect(searchApi.query).toHaveBeenLastCalledWith({ - filters: {}, - term: '', - types: ['software-catalog'], - }); - - expect(rendered.getByText('Test Ent')).toBeInTheDocument(); - expect(rendered.getByText('This is test ent')).toBeInTheDocument(); - expect(rendered.getByText('Kind: system')).toBeInTheDocument(); - - expect(rendered.getByText('Test Ent 2')).toBeInTheDocument(); - expect(rendered.getByText('This is test ent 2')).toBeInTheDocument(); - expect(rendered.getByText('Kind: component')).toBeInTheDocument(); - expect(rendered.getByText('Type: library')).toBeInTheDocument(); - - expect(rendered.getByText('Test Ent 3')).toBeInTheDocument(); - expect(rendered.getByText('This is test ent 3')).toBeInTheDocument(); - expect(rendered.getByText('Kind: api')).toBeInTheDocument(); - expect(rendered.getByText('Type: openapi')).toBeInTheDocument(); - }); - - it('should disable options that are already added', async () => { - const rendered = await render(); - - const addButtons = rendered.getAllByTestId('entity-drawer-add-button'); - expect(addButtons.length).toEqual(3); - - expect(getByText(addButtons[0], 'Added')).toBeInTheDocument(); - expect(addButtons[0]).toBeDisabled(); - - expect(getByText(addButtons[1], 'Add')).toBeInTheDocument(); - expect(addButtons[1]).not.toBeDisabled(); - - expect(getByText(addButtons[2], 'Add')).toBeInTheDocument(); - expect(addButtons[2]).not.toBeDisabled(); - }); - - it('should add entities correctly', async () => { - const rendered = await render(); - - act(() => { - fireEvent.click(rendered.getAllByTestId('entity-drawer-add-button')[1]); - }); - - expect(mockOnAdd).toHaveBeenCalledWith('component:foo/test-ent2'); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx deleted file mode 100644 index 529327776e..0000000000 --- a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx +++ /dev/null @@ -1,246 +0,0 @@ -/* - * 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 { - CompoundEntityRef, - Entity, - getCompoundEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { useApi, useRouteRef } from '@backstage/core-plugin-api'; -import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; -import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; -import type { SearchDocument } from '@backstage/plugin-search-common'; -import { - SearchBar, - SearchContextProvider, - SearchFilter, - SearchResult, - SearchResultPager, - useSearch, -} from '@backstage/plugin-search-react'; -import { - Box, - Button, - Chip, - createStyles, - Divider, - Drawer, - Grid, - List, - ListItem, - ListItemSecondaryAction, - ListItemText, - makeStyles, - Paper, - Theme, - Typography, -} from '@material-ui/core'; -import React, { useCallback, useEffect, useMemo } from 'react'; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - paper: { - width: '50%', - padding: theme.spacing(2.5), - }, - searchBarContainer: { - borderRadius: 30, - display: 'flex', - height: '100%', - boxShadow: 'none', - }, - gridContainer: { - height: '100%', - }, - searchResults: { - overflow: 'auto', - }, - itemContainer: { - flexWrap: 'wrap', - paddingRight: '75px', - }, - itemText: { - width: '100%', - wordBreak: 'break-word', - marginBottom: '1rem', - }, - }), -); - -const RestrictCatalogIndexResults = () => { - const { setTypes } = useSearch(); - useEffect(() => setTypes(['software-catalog']), [setTypes]); - return null; -}; - -export type AddEntitiesDrawerProps = { - currentEntities: Entity[]; - open: boolean; - onAdd: (entityRef: string) => void; - onClose: () => void; -}; - -export const AddEntitiesDrawer = ({ - currentEntities, - open, - onAdd, - onClose, -}: AddEntitiesDrawerProps) => { - const classes = useStyles(); - const catalogApi = useApi(catalogApiRef); - const entityRoute = useRouteRef(entityRouteRef); - const entityLocationRegex = useMemo(() => { - const forwardSlashRegex = new RegExp('/', 'g'); - // We need to do this in two steps, since entityRoute will ruin some special chars, like question marks - const locationRegex = entityRoute({ - namespace: '__REPLACE_WITH_NAMESPACE__', - kind: '__REPLACE_WITH_KIND__', - name: '__REPLACE_WITH_NAME__', - }) - .replace('__REPLACE_WITH_NAMESPACE__', '(?.+?)') - .replace('__REPLACE_WITH_KIND__', '(?.+?)') - .replace('__REPLACE_WITH_NAME__', '(?.+?)') - .replace(forwardSlashRegex, '\\/'); - return new RegExp(`${locationRegex}$`); - }, [entityRoute]); - - const currentEntityLocations = useMemo( - () => - currentEntities.map(entity => - entityRoute(getCompoundEntityRef(entity)).toLocaleLowerCase('en-US'), - ), - [currentEntities, entityRoute], - ); - - const getEntityKinds = async () => { - return ( - await catalogApi.getEntityFacets({ facets: ['kind'] }) - ).facets.kind.map(f => f.value); - }; - - const addEntity = useCallback( - (entityResult: SearchDocument) => { - // TODO(kuangp): this parsing of the location is not great. Ideally `CatalogEntityDocument` - // contains the `metadata.name` field so we can derive the full ref and we only fall back to - // parsing location if it's missing (ie. for older versions) - const match = entityResult.location.match(entityLocationRegex); - if (match?.groups) { - onAdd(stringifyEntityRef(match?.groups as CompoundEntityRef)); - } else { - // eslint-disable-next-line no-console - console.error( - `Failed to parse entity ref from entity location: ${entityResult.location}`, - ); - } - }, - [entityLocationRegex, onAdd], - ); - - return ( - - - - - - - Let's find something for your playlist - - - - - - - - - - - - - {({ results }) => ( - - {results.map(({ document }) => ( - - -
- - - - - - {(document as CatalogEntityDocument).kind && ( - - )} - {(document as CatalogEntityDocument).type && ( - - )} - -
-
- -
- ))} -
- )} -
- -
-
-
-
- ); -}; diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx deleted file mode 100644 index ba6f94e945..0000000000 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistEntitiesTable.test.tsx +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 { ErrorApi, errorApiRef } from '@backstage/core-plugin-api'; -import { entityRouteRef } from '@backstage/plugin-catalog-react'; -import { AuthorizeResult } from '@backstage/plugin-permission-common'; -import { - PermissionApi, - permissionApiRef, -} from '@backstage/plugin-permission-react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { Button } from '@material-ui/core'; -import { fireEvent, waitFor, act } from '@testing-library/react'; -import React from 'react'; -import { SWRConfig } from 'swr'; -import { PlaylistApi, playlistApiRef } from '../../api'; -import { PlaylistEntitiesTable } from './PlaylistEntitiesTable'; - -jest.mock('./AddEntitiesDrawer', () => ({ - AddEntitiesDrawer: ({ onAdd, open }: { onAdd: Function; open: boolean }) => - open ? ( - -
- - {deleting.loading && ( - - )} -
- - - - ); -}; diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx deleted file mode 100644 index ef9b6d060b..0000000000 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistPage.test.tsx +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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 { ErrorApi, errorApiRef } from '@backstage/core-plugin-api'; -import { AuthorizeResult } from '@backstage/plugin-permission-common'; -import { - PermissionApi, - permissionApiRef, -} from '@backstage/plugin-permission-react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { fireEvent, getByText, waitFor, act } from '@testing-library/react'; -import React from 'react'; -import { SWRConfig } from 'swr'; - -import { PlaylistApi, playlistApiRef } from '../../api'; -import { PlaylistPage } from './PlaylistPage'; - -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useParams: () => ({ playlistId: 'id1' }), -})); - -// Mock out nested components to simplify tests -jest.mock('./PlaylistEntitiesTable', () => ({ - PlaylistEntitiesTable: () => null, -})); - -jest.mock('./PlaylistHeader', () => ({ - PlaylistHeader: () => null, -})); - -describe('PlaylistPage', () => { - const testPlaylist = { - id: 'id1', - name: 'playlist-1', - description: 'test description', - owner: 'group:default/some-owner', - public: true, - entities: 1, - followers: 2, - isFollowing: false, - }; - - const errorApi: Partial = { post: jest.fn() }; - const playlistApi: Partial = { - getPlaylist: jest.fn().mockImplementation(async () => testPlaylist), - followPlaylist: jest.fn().mockImplementation(async () => {}), - unfollowPlaylist: jest.fn().mockImplementation(async () => {}), - }; - const mockAuthorize = jest - .fn() - .mockImplementation(async () => ({ result: AuthorizeResult.ALLOW })); - const permissionApi: Partial = { authorize: mockAuthorize }; - - // SWR used by the usePermission hook needs cache to be reset for each test - const element = ( - new Map() }}> - - - - - ); - - beforeEach(() => { - mockAuthorize.mockClear(); - }); - - it('show render the playlist info', async () => { - const rendered = await renderInTestApp(element); - expect(playlistApi.getPlaylist).toHaveBeenCalledWith('id1'); - expect(rendered.getByText('test description')).toBeInTheDocument(); - expect( - rendered.getByTestId('playlist-page-follow-button'), - ).toBeInTheDocument(); - expect( - getByText(rendered.getByTestId('playlist-page-follow-button'), 'Follow'), - ).toBeInTheDocument(); - }); - - it('should not render the follow button if unauthorized', async () => { - mockAuthorize.mockImplementationOnce(async () => ({ - result: AuthorizeResult.DENY, - })); - const rendered = await renderInTestApp(element); - expect(rendered.queryByTestId('playlist-page-follow-button')).toBeNull(); - }); - - it('should reflect and toggle the following state of the playlist', async () => { - const rendered = await renderInTestApp(element); - - act(() => { - fireEvent.click(rendered.getByTestId('playlist-page-follow-button')); - }); - testPlaylist.isFollowing = true; - - await waitFor(() => { - expect(playlistApi.followPlaylist).toHaveBeenCalledWith('id1'); - expect( - getByText( - rendered.getByTestId('playlist-page-follow-button'), - 'Following', - ), - ).toBeInTheDocument(); - }); - - act(() => { - fireEvent.click(rendered.getByTestId('playlist-page-follow-button')); - }); - testPlaylist.isFollowing = false; - - await waitFor(() => { - expect(playlistApi.unfollowPlaylist).toHaveBeenCalledWith('id1'); - expect( - getByText( - rendered.getByTestId('playlist-page-follow-button'), - 'Follow', - ), - ).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx b/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx deleted file mode 100644 index b17fbd2fb7..0000000000 --- a/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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 { Content, ErrorPage, Page } from '@backstage/core-components'; -import { errorApiRef, useApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { usePermission } from '@backstage/plugin-permission-react'; -import { permissions } from '@backstage/plugin-playlist-common'; -import { - Button, - Card, - CardContent, - CardHeader, - Divider, - LinearProgress, - makeStyles, - Typography, -} from '@material-ui/core'; -import React, { useEffect } from 'react'; -import { useParams } from 'react-router-dom'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; - -import { playlistApiRef } from '../../api'; -import { PlaylistEntitiesTable } from './PlaylistEntitiesTable'; -import { PlaylistHeader } from './PlaylistHeader'; - -const useStyles = makeStyles({ - followButton: { - top: '6px', - right: '8px', - }, -}); - -export const PlaylistPage = () => { - const classes = useStyles(); - const errorApi = useApi(errorApiRef); - const playlistApi = useApi(playlistApiRef); - const { playlistId } = useParams(); - - const [{ value: playlist, loading, error }, loadPlaylist] = useAsyncFn( - () => playlistApi.getPlaylist(playlistId!), - [playlistApi], - ); - - useEffect(() => { - loadPlaylist(); - }, [loadPlaylist]); - - const { allowed: followAllowed } = usePermission({ - permission: permissions.playlistFollowersUpdate, - resourceRef: playlist?.id, - }); - - const [{ loading: loadingFollowRequest }, followPlaylist] = - useAsyncFn(async () => { - try { - if (playlist!.isFollowing) { - await playlistApi.unfollowPlaylist(playlist!.id); - } else { - await playlistApi.followPlaylist(playlist!.id); - } - - loadPlaylist(); - } catch (e) { - errorApi.post(e); - } - }, [errorApi, loadPlaylist, playlist, playlistApi]); - - if (error) { - return ( - - ); - } - - return ( - <> - {loading && } - - {playlist && ( - <> - - - - - {playlist.isFollowing ? 'Following' : 'Follow'} - - ) - } - /> - - - - {playlist.description} - - - -
- -
- - )} -
- - ); -}; diff --git a/plugins/playlist/src/components/PlaylistPage/index.ts b/plugins/playlist/src/components/PlaylistPage/index.ts deleted file mode 100644 index 695b243cd0..0000000000 --- a/plugins/playlist/src/components/PlaylistPage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './PlaylistPage'; diff --git a/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx b/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx deleted file mode 100644 index 84650e4f41..0000000000 --- a/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.test.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 { fireEvent, render, waitFor } from '@testing-library/react'; -import { DefaultPlaylistFilters } from '../../hooks'; -import { MockPlaylistListProvider } from '../../testUtils'; -import { PlaylistSearchBar, PlaylistTextFilter } from './PlaylistSearchBar'; - -describe('PlaylistSearchBar', () => { - it('should display search value and execute set callback', async () => { - const updateFilters = jest.fn(); - - const filters: DefaultPlaylistFilters = { - text: new PlaylistTextFilter('hello'), - }; - - const { getByDisplayValue } = render( - - - , - ); - - const searchInput = getByDisplayValue('hello'); - expect(searchInput).toBeInTheDocument(); - - fireEvent.change(searchInput, { target: { value: 'world' } }); - await waitFor(() => expect(updateFilters.mock.calls.length).toBe(1)); - expect(updateFilters).toHaveBeenCalledWith({ - text: new PlaylistTextFilter('world'), - }); - - fireEvent.change(searchInput, { target: { value: '' } }); - await waitFor(() => expect(updateFilters.mock.calls.length).toBe(2)); - expect(updateFilters).toHaveBeenCalledWith({ - text: undefined, - }); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx b/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx deleted file mode 100644 index 44e0b28c13..0000000000 --- a/plugins/playlist/src/components/PlaylistSearchBar/PlaylistSearchBar.tsx +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 { Playlist } from '@backstage/plugin-playlist-common'; -import { - FormControl, - IconButton, - Input, - InputAdornment, - makeStyles, - Toolbar, -} from '@material-ui/core'; -import Clear from '@material-ui/icons/Clear'; -import Search from '@material-ui/icons/Search'; -import React, { useState } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; - -import { usePlaylistList } from '../../hooks'; -import { PlaylistFilter } from '../../types'; - -/** - * @public - */ -export class PlaylistTextFilter implements PlaylistFilter { - constructor(readonly value: string) {} - - filterPlaylist(playlist: Playlist): boolean { - const upperCaseValue = this.value.toLocaleUpperCase('en-US'); - return ( - playlist.name.toLocaleUpperCase('en-US').includes(upperCaseValue) || - !!playlist.description - ?.toLocaleUpperCase('en-US') - .includes(upperCaseValue) - ); - } -} - -const useStyles = makeStyles(_theme => ({ - searchToolbar: { - paddingLeft: 0, - paddingRight: 0, - }, -})); - -/** - * @public - */ -export const PlaylistSearchBar = () => { - const classes = useStyles(); - - const { filters, updateFilters } = usePlaylistList(); - const [search, setSearch] = useState(filters.text?.value ?? ''); - - useDebounce( - () => { - updateFilters({ - text: search.length ? new PlaylistTextFilter(search) : undefined, - }); - }, - 250, - [search, updateFilters], - ); - - return ( - - - setSearch(event.target.value)} - value={search} - startAdornment={ - - - - } - endAdornment={ - - setSearch('')} - edge="end" - disabled={search.length === 0} - > - - - - } - /> - - - ); -}; diff --git a/plugins/playlist/src/components/PlaylistSearchBar/index.ts b/plugins/playlist/src/components/PlaylistSearchBar/index.ts deleted file mode 100644 index 65b7e181cf..0000000000 --- a/plugins/playlist/src/components/PlaylistSearchBar/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './PlaylistSearchBar'; diff --git a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx deleted file mode 100644 index 6c86b7b34d..0000000000 --- a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.test.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 { - fireEvent, - getByRole, - render, - waitFor, - act, -} from '@testing-library/react'; -import React from 'react'; - -import { MockPlaylistListProvider } from '../../testUtils'; -import { - DefaultPlaylistSortTypes, - DefaultSortCompareFunctions, - PlaylistSortPicker, -} from './PlaylistSortPicker'; - -describe('PlaylistSortPicker', () => { - it('should update sort based on selection', async () => { - const updateSort = jest.fn(); - - const { getByText, getByTestId } = render( - - - , - ); - - act(() => { - fireEvent.mouseDown( - getByRole(getByTestId('sort-picker-select'), 'button'), - ); - }); - const abcSort = getByText('Alphabetical'); - expect(abcSort).toBeInTheDocument(); - - fireEvent.click(abcSort); - await waitFor(() => { - expect(updateSort).toHaveBeenLastCalledWith( - DefaultSortCompareFunctions[DefaultPlaylistSortTypes.alphabetical], - ); - }); - - act(() => { - fireEvent.mouseDown( - getByRole(getByTestId('sort-picker-select'), 'button'), - ); - }); - const entitiesSort = getByText('# Entities'); - expect(entitiesSort).toBeInTheDocument(); - - fireEvent.click(entitiesSort); - await waitFor(() => { - expect(updateSort).toHaveBeenLastCalledWith( - DefaultSortCompareFunctions[DefaultPlaylistSortTypes.numEntities], - ); - }); - }); -}); diff --git a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx b/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx deleted file mode 100644 index 219792e2dc..0000000000 --- a/plugins/playlist/src/components/PlaylistSortPicker/PlaylistSortPicker.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 { Playlist } from '@backstage/plugin-playlist-common'; -import { - ListSubheader, - makeStyles, - MenuItem, - Select, - Typography, -} from '@material-ui/core'; -import SwapVertIcon from '@material-ui/icons/SwapVert'; -import React from 'react'; -import useEffectOnce from 'react-use/lib/useEffectOnce'; - -import { usePlaylistList } from '../../hooks/usePlaylistList'; -import { PlaylistSortCompareFunction } from '../../types'; - -export const enum DefaultPlaylistSortTypes { - popular = 'popular', - alphabetical = 'alphabetical', - numEntities = 'numEntities', -} - -export const DefaultSortCompareFunctions: { - [type in DefaultPlaylistSortTypes]: PlaylistSortCompareFunction; -} = { - [DefaultPlaylistSortTypes.popular]: (a: Playlist, b: Playlist) => { - if (a.followers < b.followers) { - return 1; - } else if (a.followers > b.followers) { - return -1; - } - return 0; - }, - [DefaultPlaylistSortTypes.alphabetical]: (a: Playlist, b: Playlist) => - a.name.localeCompare(b.name), - [DefaultPlaylistSortTypes.numEntities]: (a: Playlist, b: Playlist) => { - if (a.entities < b.entities) { - return 1; - } else if (a.entities > b.entities) { - return -1; - } - return 0; - }, -}; - -const sortTypeLabels = { - [DefaultPlaylistSortTypes.popular]: 'Popular', - [DefaultPlaylistSortTypes.alphabetical]: 'Alphabetical', - [DefaultPlaylistSortTypes.numEntities]: '# Entities', -}; - -const useStyles = makeStyles({ - select: { - width: '10rem', - marginRight: '1rem', - }, - icon: { - verticalAlign: 'bottom', - }, -}); - -/** - * @public - */ -export const PlaylistSortPicker = () => { - const classes = useStyles(); - const { updateSort } = usePlaylistList(); - - useEffectOnce(() => - updateSort(DefaultSortCompareFunctions[DefaultPlaylistSortTypes.popular]), - ); - - return ( - - ); -}; diff --git a/plugins/playlist/src/components/PlaylistSortPicker/index.ts b/plugins/playlist/src/components/PlaylistSortPicker/index.ts deleted file mode 100644 index 04ea5268ef..0000000000 --- a/plugins/playlist/src/components/PlaylistSortPicker/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './PlaylistSortPicker'; diff --git a/plugins/playlist/src/components/index.ts b/plugins/playlist/src/components/index.ts deleted file mode 100644 index 2be300ac51..0000000000 --- a/plugins/playlist/src/components/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 './CreatePlaylistButton'; -export * from './EntityPlaylistDialog'; -export * from './PersonalListPicker'; -export * from './PlaylistCard'; -export * from './PlaylistEditDialog'; -export * from './PlaylistIndexPage'; -export * from './PlaylistList'; -export * from './PlaylistOwnerPicker'; -export * from './PlaylistPage'; -export * from './PlaylistSearchBar'; -export * from './PlaylistSortPicker'; diff --git a/plugins/playlist/src/hooks/PlaylistListProvider.test.tsx b/plugins/playlist/src/hooks/PlaylistListProvider.test.tsx deleted file mode 100644 index ce0d49802b..0000000000 --- a/plugins/playlist/src/hooks/PlaylistListProvider.test.tsx +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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 { - ConfigApi, - configApiRef, - IdentityApi, - identityApiRef, -} from '@backstage/core-plugin-api'; -import { Playlist } from '@backstage/plugin-playlist-common'; -import { TestApiProvider } from '@backstage/test-utils'; -import { act, renderHook, waitFor } from '@testing-library/react'; -import qs from 'qs'; -import React, { PropsWithChildren } from 'react'; -import { MemoryRouter } from 'react-router-dom'; -import { PlaylistApi, playlistApiRef } from '../api'; -import { - DefaultSortCompareFunctions, - DefaultPlaylistSortTypes, - PersonalListFilter, - PersonalListFilterValue, - PersonalListPicker, - PlaylistOwnerPicker, -} from '../components'; -import { PlaylistListProvider } from './PlaylistListProvider'; -import { usePlaylistList } from './usePlaylistList'; - -const playlists: Playlist[] = [ - { - id: 'id1', - name: 'list-1', - owner: 'user:default/guest', - public: true, - entities: 2, - followers: 5, - isFollowing: false, - }, - { - id: 'id2', - name: 'list-2', - owner: 'group:default/foo', - public: true, - entities: 3, - followers: 2, - isFollowing: true, - }, -]; - -const mockConfigApi = { - getOptionalString: () => '', -} as Partial; - -const mockIdentityApi: Partial = { - getBackstageIdentity: async () => ({ - type: 'user', - userEntityRef: 'user:default/guest', - ownershipEntityRefs: [], - }), -}; - -const mockPlaylistApi: Partial = { - getAllPlaylists: jest.fn().mockImplementation(async () => playlists), -}; - -const wrapper = ({ - location, - children, -}: PropsWithChildren<{ - location?: string; -}>) => { - return ( - - - - - - {children} - - - - ); -}; - -describe('', () => { - const origReplaceState = window.history.replaceState; - beforeEach(() => { - window.history.replaceState = jest.fn(); - }); - afterEach(() => { - window.history.replaceState = origReplaceState; - }); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('resolves backend filters', async () => { - const { result } = renderHook(() => usePlaylistList(), { - wrapper, - }); - await waitFor(() => { - expect(result.current.backendPlaylists.length).toBe(2); - expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalled(); - }); - }); - - it('resolves frontend filters', async () => { - const { result } = renderHook(() => usePlaylistList(), { - wrapper, - }); - await waitFor(() => { - expect(result.current.backendPlaylists.length).toBe(2); - }); - - act(() => - result.current.updateFilters({ - personal: new PersonalListFilter( - PersonalListFilterValue.owned, - playlist => playlist.name === 'list-1', - ), - }), - ); - - await waitFor(() => { - expect(result.current.backendPlaylists.length).toBe(2); - expect(result.current.playlists.length).toBe(1); - expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalledTimes(1); - }); - }); - - it('resolves query param filter values', async () => { - const query = qs.stringify({ - filters: { personal: 'all', owners: ['user:default/guest'] }, - }); - const { result } = renderHook(() => usePlaylistList(), { - wrapper: ({ children }) => - wrapper({ location: `/playlist?${query}`, children }), - }); - - await waitFor(() => { - expect(result.current.queryParameters).toEqual({ - personal: 'all', - owners: ['user:default/guest'], - }); - }); - }); - - it('does not fetch when only frontend filters change', async () => { - const { result } = renderHook(() => usePlaylistList(), { - wrapper, - }); - - await waitFor(() => { - expect(result.current.playlists.length).toBe(2); - expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalledTimes(1); - }); - - act(() => - result.current.updateFilters({ - personal: new PersonalListFilter( - PersonalListFilterValue.owned, - playlist => playlist.name === 'list-1', - ), - }), - ); - - await waitFor(() => { - expect(result.current.playlists.length).toBe(1); - expect(mockPlaylistApi.getAllPlaylists).toHaveBeenCalledTimes(1); - }); - }); - - it('applies custom sorting', async () => { - const { result } = renderHook(() => usePlaylistList(), { - wrapper, - }); - - await waitFor(() => { - expect(result.current.playlists.length).toBe(2); - expect(result.current.playlists[0].name).toEqual('list-1'); - expect(result.current.playlists[1].name).toEqual('list-2'); - }); - - act(() => - result.current.updateSort( - DefaultSortCompareFunctions[DefaultPlaylistSortTypes.numEntities], - ), - ); - - await waitFor(() => { - expect(result.current.playlists.length).toBe(2); - expect(result.current.playlists[0].name).toEqual('list-2'); - expect(result.current.playlists[1].name).toEqual('list-1'); - }); - }); - - it('returns an error on playlistApi failure', async () => { - mockPlaylistApi.getAllPlaylists = jest.fn().mockRejectedValue('error'); - const { result } = renderHook(() => usePlaylistList(), { - wrapper, - }); - await waitFor(() => { - expect(result.current.error).toBeDefined(); - }); - }); -}); diff --git a/plugins/playlist/src/hooks/PlaylistListProvider.tsx b/plugins/playlist/src/hooks/PlaylistListProvider.tsx deleted file mode 100644 index 5b8e1ee2b6..0000000000 --- a/plugins/playlist/src/hooks/PlaylistListProvider.tsx +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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 { useApi } from '@backstage/core-plugin-api'; -import { Playlist } from '@backstage/plugin-playlist-common'; -import { compact, isEqual } from 'lodash'; -import qs from 'qs'; -import React, { - PropsWithChildren, - useCallback, - useMemo, - useState, -} from 'react'; -import { useLocation } from 'react-router-dom'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import useDebounce from 'react-use/lib/useDebounce'; -import useMountedState from 'react-use/lib/useMountedState'; - -import { playlistApiRef } from '../api'; -import { - DefaultPlaylistSortTypes, - DefaultSortCompareFunctions, -} from '../components/PlaylistSortPicker'; -import { PlaylistFilter, PlaylistSortCompareFunction } from '../types'; -import { - DefaultPlaylistFilters, - NoopFilter, - PlaylistListContext, -} from './usePlaylistList'; - -const reduceBackendFilters = ( - filters: PlaylistFilter[], -): Record => { - return filters.reduce((compoundFilter, filter) => { - return { - ...compoundFilter, - ...(filter.getBackendFilters ? filter.getBackendFilters() : {}), - }; - }, {} as Record); -}; - -type OutputState = { - appliedFilters: PlaylistFilters; - playlists: Playlist[]; - backendPlaylists: Playlist[]; -}; - -/** - * @public - */ -export const PlaylistListProvider = < - PlaylistFilters extends DefaultPlaylistFilters, ->({ - children, -}: PropsWithChildren<{}>) => { - const isMounted = useMountedState(); - const playlistApi = useApi(playlistApiRef); - const [sortCompareFn, setSortCompareFn] = - useState( - () => DefaultSortCompareFunctions[DefaultPlaylistSortTypes.popular], - ); - const [requestedFilters, setRequestedFilters] = useState( - {} as PlaylistFilters, - ); - - // We use react-router's useLocation hook so updates from external sources trigger an update to - // the queryParameters in outputState. Updates from this hook use replaceState below and won't - // trigger a useLocation change; this would instead come from an external source, such as a manual - // update of the URL or two sidebar links with different filters. - const location = useLocation(); - const queryParameters = useMemo( - () => - (qs.parse(location.search, { - ignoreQueryPrefix: true, - }).filters ?? {}) as Record, - [location], - ); - - const [outputState, setOutputState] = useState>({ - appliedFilters: { - noop: new NoopFilter(), // Init with a noop filter to trigger initial request - } as PlaylistFilters, - playlists: [], - backendPlaylists: [], - }); - - // The main async filter worker. Note that while it has a lot of dependencies - // in terms of its implementation, the triggering only happens (debounced) - // based on the requested filters/sortCompareFn changing. - const [{ loading, error }, refresh] = useAsyncFn( - async () => { - const compacted: PlaylistFilter[] = compact( - Object.values(requestedFilters), - ); - const playlistFilter = (p: Playlist) => - compacted.every( - filter => !filter.filterPlaylist || filter.filterPlaylist(p), - ); - const backendFilter = reduceBackendFilters(compacted); - const previousBackendFilter = reduceBackendFilters( - compact(Object.values(outputState.appliedFilters)), - ); - - const queryParams = Object.keys(requestedFilters).reduce( - (params, key) => { - const filter = requestedFilters[key as keyof PlaylistFilters] as - | PlaylistFilter - | undefined; - if (filter?.toQueryValue) { - params[key] = filter.toQueryValue(); - } - return params; - }, - {} as Record, - ); - - if (!isEqual(previousBackendFilter, backendFilter)) { - const response = await playlistApi.getAllPlaylists({ - filter: backendFilter, - }); - setOutputState({ - appliedFilters: requestedFilters, - backendPlaylists: response, - playlists: response.filter(playlistFilter).sort(sortCompareFn), - }); - } else { - setOutputState({ - appliedFilters: requestedFilters, - backendPlaylists: outputState.backendPlaylists, - playlists: outputState.backendPlaylists - .filter(playlistFilter) - .sort(sortCompareFn), - }); - } - - if (isMounted()) { - const oldParams = qs.parse(location.search, { - ignoreQueryPrefix: true, - }); - const newParams = qs.stringify( - { ...oldParams, filters: queryParams }, - { addQueryPrefix: true, arrayFormat: 'repeat' }, - ); - const newUrl = `${window.location.pathname}${newParams}`; - // We use direct history manipulation since useSearchParams and - // useNavigate in react-router-dom cause unnecessary extra rerenders. - // Also make sure to replace the state rather than pushing, since we - // don't want there to be back/forward slots for every single filter - // change. - window.history?.replaceState(null, document.title, newUrl); - } - }, - [ - playlistApi, - queryParameters, - requestedFilters, - sortCompareFn, - outputState, - ], - { loading: true }, - ); - - // Slight debounce on the refresh, since (especially on page load) several - // filters will be calling this in rapid succession. - useDebounce(refresh, 10, [requestedFilters, sortCompareFn]); - - const updateFilters = useCallback( - ( - update: - | Partial - | ((prevFilters: PlaylistFilters) => Partial), - ) => { - setRequestedFilters(prevFilters => { - const newFilters = - typeof update === 'function' ? update(prevFilters) : update; - return { ...prevFilters, ...newFilters }; - }); - }, - [], - ); - - const updateSort = useCallback( - (compareFn: PlaylistSortCompareFunction) => - setSortCompareFn(() => compareFn), - [], - ); - - const value = useMemo( - () => ({ - filters: outputState.appliedFilters, - playlists: outputState.playlists, - backendPlaylists: outputState.backendPlaylists, - updateFilters, - updateSort, - queryParameters, - loading, - error, - }), - [outputState, updateFilters, updateSort, queryParameters, loading, error], - ); - - return ( - - {children} - - ); -}; diff --git a/plugins/playlist/src/hooks/index.ts b/plugins/playlist/src/hooks/index.ts deleted file mode 100644 index bb164d961c..0000000000 --- a/plugins/playlist/src/hooks/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 './usePlaylistList'; -export * from './useTitle'; diff --git a/plugins/playlist/src/hooks/usePlaylistList.tsx b/plugins/playlist/src/hooks/usePlaylistList.tsx deleted file mode 100644 index cf099b5be2..0000000000 --- a/plugins/playlist/src/hooks/usePlaylistList.tsx +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 { Playlist } from '@backstage/plugin-playlist-common'; -import { createContext, useContext } from 'react'; -import { PersonalListFilter } from '../components/PersonalListPicker'; -import { PlaylistOwnerFilter } from '../components/PlaylistOwnerPicker'; -import { PlaylistTextFilter } from '../components/PlaylistSearchBar'; -import { PlaylistFilter, PlaylistSortCompareFunction } from '../types'; - -/** - * @public - */ -export class NoopFilter implements PlaylistFilter { - getBackendFilters() { - return { '': null }; - } -} - -/** - * @public - */ -export type DefaultPlaylistFilters = { - noop?: NoopFilter; - owners?: PlaylistOwnerFilter; - personal?: PersonalListFilter; - text?: PlaylistTextFilter; -}; - -export type PlaylistListContextProps< - PlaylistFilters extends DefaultPlaylistFilters = DefaultPlaylistFilters, -> = { - /** - * The currently registered filters, adhering to the shape of DefaultPlaylistFilters - */ - filters: PlaylistFilters; - - /** - * The resolved list of playlists, after all filters are applied. - */ - playlists: Playlist[]; - - /** - * The resolved list of playlists, after _only playlist-backend_ filters are applied. - */ - backendPlaylists: Playlist[]; - - /** - * Update one or more of the registered filters. Optional filters can be set to `undefined` to - * reset the filter. - */ - updateFilters: ( - filters: - | Partial - | ((prevFilters: PlaylistFilters) => Partial), - ) => void; - - /** - * Update the compare function used to sort playlists. - */ - updateSort: (compareFn: PlaylistSortCompareFunction) => void; - - /** - * Filter values from query parameters. - */ - queryParameters: Partial>; - - loading: boolean; - error?: Error; -}; - -export const PlaylistListContext = createContext< - PlaylistListContextProps | undefined ->(undefined); - -export function usePlaylistList< - PlaylistFilters extends DefaultPlaylistFilters = DefaultPlaylistFilters, ->(): PlaylistListContextProps { - const context = useContext(PlaylistListContext); - if (!context) - throw new Error('usePlaylistList must be used within PlaylistListProvider'); - return context; -} diff --git a/plugins/playlist/src/hooks/useTitle.ts b/plugins/playlist/src/hooks/useTitle.ts deleted file mode 100644 index 5f46e027d7..0000000000 --- a/plugins/playlist/src/hooks/useTitle.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { configApiRef, useApi } from '@backstage/core-plugin-api'; -import pluralize from 'pluralize'; - -interface UseTitleOptions { - pluralize?: boolean; - lowerCase?: boolean; -} - -export function useTitle(opts: UseTitleOptions) { - const configApi = useApi(configApiRef); - let title = configApi.getOptionalString('playlist.title') ?? 'Playlist'; - - if (opts.pluralize) { - title = pluralize(title); - } - - return opts.lowerCase ? title.toLocaleLowerCase('en-US') : title; -} diff --git a/plugins/playlist/src/index.ts b/plugins/playlist/src/index.ts deleted file mode 100644 index 0281af45f7..0000000000 --- a/plugins/playlist/src/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -/** - * Playlist frontend plugin - * - * @packageDocumentation - */ -export * from './api'; -export { - CreatePlaylistButton, - DefaultPlaylistIndexPage, - PersonalListFilter, - PersonalListFilterValue, - PersonalListPicker, - PlaylistList, - PlaylistOwnerFilter, - PlaylistOwnerPicker, - PlaylistSearchBar, - PlaylistSortPicker, - PlaylistTextFilter, -} from './components'; -export type { EntityPlaylistDialogProps } from './components'; -export { NoopFilter } from './hooks'; -export type { DefaultPlaylistFilters } from './hooks'; -export { PlaylistListProvider } from './hooks/PlaylistListProvider'; -export { - EntityPlaylistDialog, - PlaylistPage, - playlistPlugin, - PlaylistIndexPage, -} from './plugin'; -export type { PlaylistFilter } from './types'; diff --git a/plugins/playlist/src/plugin.test.ts b/plugins/playlist/src/plugin.test.ts deleted file mode 100644 index a2dfc7fcd7..0000000000 --- a/plugins/playlist/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 { playlistPlugin } from './plugin'; - -describe('playlist', () => { - it('should export plugin', () => { - expect(playlistPlugin).toBeDefined(); - }); -}); diff --git a/plugins/playlist/src/plugin.ts b/plugins/playlist/src/plugin.ts deleted file mode 100644 index 7a8a38c673..0000000000 --- a/plugins/playlist/src/plugin.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 { - createApiFactory, - createComponentExtension, - createPlugin, - createRoutableExtension, - discoveryApiRef, - fetchApiRef, -} from '@backstage/core-plugin-api'; - -import { playlistApiRef, PlaylistClient } from './api'; -import { playlistRouteRef, rootRouteRef } from './routes'; - -/** - * @public - */ -export const playlistPlugin = createPlugin({ - id: 'playlist', - routes: { - root: rootRouteRef, - }, - apis: [ - createApiFactory({ - api: playlistApiRef, - deps: { - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ discoveryApi, fetchApi }) => - new PlaylistClient({ discoveryApi, fetchApi }), - }), - ], -}); - -/** - * @public - */ -export const PlaylistIndexPage = playlistPlugin.provide( - createRoutableExtension({ - name: 'PlaylistIndexPage', - component: () => - import('./components/PlaylistIndexPage').then(m => m.PlaylistIndexPage), - mountPoint: rootRouteRef, - }), -); - -/** - * @public - */ -export const PlaylistPage = playlistPlugin.provide( - createRoutableExtension({ - name: 'PlaylistPage', - component: () => - import('./components/PlaylistPage').then(m => m.PlaylistPage), - mountPoint: playlistRouteRef, - }), -); - -/** - * @public - */ -export const EntityPlaylistDialog = playlistPlugin.provide( - createComponentExtension({ - name: 'EntityPlaylistDialog', - component: { - lazy: () => - import('./components/EntityPlaylistDialog').then( - m => m.EntityPlaylistDialog, - ), - }, - }), -); diff --git a/plugins/playlist/src/routes.ts b/plugins/playlist/src/routes.ts deleted file mode 100644 index 2ca833efff..0000000000 --- a/plugins/playlist/src/routes.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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: 'playlist:index-page', -}); - -export const playlistRouteRef = createRouteRef({ - id: 'playlist:playlist-page', - params: ['playlistId'], -}); diff --git a/plugins/playlist/src/setupTests.ts b/plugins/playlist/src/setupTests.ts deleted file mode 100644 index 326d2ed212..0000000000 --- a/plugins/playlist/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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'; diff --git a/plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx b/plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx deleted file mode 100644 index 2acef15e14..0000000000 --- a/plugins/playlist/src/testUtils/MockPlaylistListProvider.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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, { - PropsWithChildren, - useCallback, - useMemo, - useState, -} from 'react'; -import { - DefaultPlaylistSortTypes, - DefaultSortCompareFunctions, -} from '../components'; -import { - DefaultPlaylistFilters, - PlaylistListContext, - PlaylistListContextProps, -} from '../hooks'; -import { PlaylistSortCompareFunction } from '../types'; - -export const MockPlaylistListProvider = ({ - children, - value, -}: PropsWithChildren<{ - value?: Partial; -}>) => { - const [filters, setFilters] = useState( - value?.filters ?? {}, - ); - - const [_, setSortCompareFn] = useState( - () => DefaultSortCompareFunctions[DefaultPlaylistSortTypes.popular], - ); - - const updateFilters = useCallback( - ( - update: - | Partial - | (( - prevFilters: DefaultPlaylistFilters, - ) => Partial), - ) => { - setFilters(prevFilters => { - const newFilters = - typeof update === 'function' ? update(prevFilters) : update; - return { ...prevFilters, ...newFilters }; - }); - }, - [], - ); - - const updateSort = useCallback( - (compareFn: PlaylistSortCompareFunction) => - setSortCompareFn(() => compareFn), - [], - ); - - // Memoize the default values since pickers have useEffect triggers on these; naively defaulting - // below with `?? ` breaks referential equality on subsequent updates. - const defaultValues = useMemo( - () => ({ - playlists: [], - backendPlaylists: [], - queryParameters: {}, - }), - [], - ); - - const resolvedValue: PlaylistListContextProps = useMemo( - () => ({ - playlists: value?.playlists ?? defaultValues.playlists, - backendPlaylists: - value?.backendPlaylists ?? defaultValues.backendPlaylists, - updateFilters: value?.updateFilters ?? updateFilters, - filters, - updateSort: value?.updateSort ?? updateSort, - loading: value?.loading ?? false, - queryParameters: value?.queryParameters ?? defaultValues.queryParameters, - error: value?.error, - }), - [value, defaultValues, filters, updateFilters, updateSort], - ); - - return ( - - {children} - - ); -}; diff --git a/plugins/playlist/src/testUtils/index.ts b/plugins/playlist/src/testUtils/index.ts deleted file mode 100644 index 9b6f333a59..0000000000 --- a/plugins/playlist/src/testUtils/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 './MockPlaylistListProvider'; diff --git a/plugins/playlist/src/types.ts b/plugins/playlist/src/types.ts deleted file mode 100644 index b31b282031..0000000000 --- a/plugins/playlist/src/types.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 { Playlist } from '@backstage/plugin-playlist-common'; - -/** - * @public - */ -export type PlaylistFilter = { - getBackendFilters?: () => Record; - - filterPlaylist?: (playlist: Playlist) => boolean; - - toQueryValue?: () => string | string[]; -}; - -export type PlaylistSortCompareFunction = (a: Playlist, b: Playlist) => number; diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 6b4054df04..0e3d8475b0 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,114 @@ # @backstage/plugin-proxy-backend +## 0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + +## 0.4.15 + +### Patch Changes + +- e5a2ccc: Updated dependency `@types/http-proxy-middleware` to `^1.0.0`. +- 43ca784: Updated dependency `@types/yup` to `^0.32.0`. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/config@1.2.0 + +## 0.4.15-next.1 + +### Patch Changes + +- 43ca784: Updated dependency `@types/yup` to `^0.32.0`. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/config@1.2.0 + +## 0.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + +## 0.4.14 + +### Patch Changes + +- eae097c: Allow unauthenticated requests. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + +## 0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + +## 0.4.12 + +### Patch Changes + +- 1b4fd09: Updated dependency `yup` to `^1.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + +## 0.4.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + +## 0.4.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + +## 0.4.11-next.0 + +### Patch Changes + +- 1b4fd09: Updated dependency `yup` to `^1.0.0`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## 0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + ## 0.4.8-next.3 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 421eea4b30..b955a40211 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-proxy-backend", + "version": "0.4.16-next.0", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.4.8-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/proxy-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,26 +35,18 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/proxy-backend" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,27 +57,22 @@ "express-promise-router": "^4.1.0", "http-proxy-middleware": "^2.0.0", "morgan": "^1.10.0", - "uuid": "^8.0.0", + "uuid": "^9.0.0", "winston": "^3.2.1", "yaml": "^2.0.0", "yn": "^4.0.0", - "yup": "^0.32.9" + "yup": "^1.0.0" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config-loader": "workspace:^", - "@types/http-proxy-middleware": "^0.19.3", + "@types/http-proxy-middleware": "^1.0.0", "@types/supertest": "^2.0.8", - "@types/uuid": "^8.0.0", - "@types/yup": "^0.29.13", + "@types/uuid": "^9.0.0", + "@types/yup": "^0.32.0", "msw": "^1.0.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts", - "alpha" - ], "configSchema": "config.d.ts" } diff --git a/plugins/proxy-backend/src/alpha.ts b/plugins/proxy-backend/src/alpha.ts index 9f6bad4832..c1d55b84b3 100644 --- a/plugins/proxy-backend/src/alpha.ts +++ b/plugins/proxy-backend/src/alpha.ts @@ -44,6 +44,10 @@ export default createBackendPlugin({ logger: loggerToWinstonLogger(logger), }), ); + httpRouter.addAuthPolicy({ + allow: 'unauthenticated', + path: '/', + }); }, }); }, diff --git a/plugins/puppetdb/.eslintrc.js b/plugins/puppetdb/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/puppetdb/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/puppetdb/CHANGELOG.md b/plugins/puppetdb/CHANGELOG.md deleted file mode 100644 index 5471899625..0000000000 --- a/plugins/puppetdb/CHANGELOG.md +++ /dev/null @@ -1,507 +0,0 @@ -# @backstage/plugin-puppetdb - -## 0.1.13-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.1.13-next.2 - -### Patch Changes - -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/errors@1.2.3 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.1.12 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.1.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.12-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.11-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.9 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.9-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - -## 0.1.9-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.8 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.7 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.7-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.1.7-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.6-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.3 - -### Patch Changes - -- e6f50426333b: update some peer dependencies to silence yarn install -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.1.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - -## 0.1.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.1.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - -## 0.1.2-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.1.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.1.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19 - -## 0.1.0 - -### Minor Changes - -- 70a036e940e: Initial version of [PuppetDB plugin](https://github.com/backstage/backstage/blob/master/plugins/puppetdb/README.md). - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 diff --git a/plugins/puppetdb/README.md b/plugins/puppetdb/README.md deleted file mode 100644 index c4fa06b874..0000000000 --- a/plugins/puppetdb/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# PuppetDB Plugin - -A frontend plugin to integrate PuppetDB with Backstage. When combined with the -[catalog-backend-module-puppetdb](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-puppetdb/README.md) plugin, this -frontend plugin allows viewing PuppetDB reports, including their logs and events, of Backstage resource entities. - -## Getting started - -### Prerequisites - -To get started, you need a running instance of PuppetDB. You can find instructions on how to install it -[here](https://www.puppet.com/docs/puppetdb/7/install_via_module.html). -The PuppetDB [should be configured](https://www.puppet.com/docs/puppetdb/7/configure.html#host) to allow being accessed from your Backstage instance. - -In addition, your Backstage instance need to either have -[catalog-backend-module-puppetdb](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-puppetdb/README.md) plugin installed -or you need to ensure your Resource entities have `puppet.com/certname` annotation set to the PuppetDB node name in some other way. - -### Installation - -1. Install the plugin with `yarn` in the root of your Backstage application directory: - -```bash -yarn --cwd packages/app add @backstage/plugin-puppetdb -``` - -1. Import and use the plugin in `packages/app/src/App.tsx`: - -```tsx -import { PuppetDbPage } from '@backstage/plugin-puppetdb'; - -const routes = ( - - {/* ...other routes */} - } /> - -); -``` - -### Configuration - -1. Configure `puppetdb` proxy. As this plugin uses the Backstage proxy to securely communicate with PuppetDB API, - add the following to your `app-config.yaml` to enable this configuration: - -```yaml -proxy: - '/puppetdb': - target: https://your.puppetdb.instance.com -``` - -## Screenshots - -#### Main page with the reports list: - -![Reports list](https://raw.githubusercontent.com/backstage/backstage/42b65232e763d3e39e2e641b105d2ad469db7a59/plugins/puppetdb/assets/Reports.png) - -#### Events for the specific report: - -![Events](https://raw.githubusercontent.com/backstage/backstage/1b39e86db17f139dc995f02daca4896533e53eb0/plugins/puppetdb/assets/Events.png) - -#### Logs of the specific report: - -![Logs](https://raw.githubusercontent.com/backstage/backstage/1b39e86db17f139dc995f02daca4896533e53eb0/plugins/puppetdb/assets/Logs.png) diff --git a/plugins/puppetdb/api-report.md b/plugins/puppetdb/api-report.md deleted file mode 100644 index 890980591f..0000000000 --- a/plugins/puppetdb/api-report.md +++ /dev/null @@ -1,37 +0,0 @@ -## API Report File for "@backstage/plugin-puppetdb" - -> 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 { Entity } from '@backstage/catalog-model'; -import { JSX as JSX_2 } from 'react'; -import { PathParams } from '@backstage/core-plugin-api'; -import { default as React_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; -import { SubRouteRef } from '@backstage/core-plugin-api'; - -// @public -export const isPuppetDbAvailable: (entity: Entity) => boolean; - -// @public -export const PuppetDbPage: () => JSX_2.Element; - -// @public -const puppetdbPlugin: BackstagePlugin<{}, {}>; -export { puppetdbPlugin as plugin }; -export { puppetdbPlugin }; - -// @public (undocumented) -export const puppetDbReportRouteRef: SubRouteRef>; - -// @public (undocumented) -export const puppetDbRouteRef: RouteRef; - -// @public (undocumented) -export const Router: () => React_2.JSX.Element; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/puppetdb/assets/Events.png b/plugins/puppetdb/assets/Events.png deleted file mode 100644 index 163ad67813..0000000000 Binary files a/plugins/puppetdb/assets/Events.png and /dev/null differ diff --git a/plugins/puppetdb/assets/Logs.png b/plugins/puppetdb/assets/Logs.png deleted file mode 100644 index f4e7686764..0000000000 Binary files a/plugins/puppetdb/assets/Logs.png and /dev/null differ diff --git a/plugins/puppetdb/assets/Reports.png b/plugins/puppetdb/assets/Reports.png deleted file mode 100644 index 2bba083fa6..0000000000 Binary files a/plugins/puppetdb/assets/Reports.png and /dev/null differ diff --git a/plugins/puppetdb/catalog-info.yaml b/plugins/puppetdb/catalog-info.yaml deleted file mode 100644 index 98c8d34d81..0000000000 --- a/plugins/puppetdb/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-puppetdb - title: '@backstage/plugin-puppetdb' - description: >- - Backstage plugin to visualize resource information and Puppet facts from - PuppetDB. -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/puppetdb/dev/index.tsx b/plugins/puppetdb/dev/index.tsx deleted file mode 100644 index 8082afcfe2..0000000000 --- a/plugins/puppetdb/dev/index.tsx +++ /dev/null @@ -1,19 +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 { createDevApp } from '@backstage/dev-utils'; -import { puppetdbPlugin } from '../src'; - -createDevApp().registerPlugin(puppetdbPlugin).render(); diff --git a/plugins/puppetdb/knip-report.md b/plugins/puppetdb/knip-report.md deleted file mode 100644 index ccda99cbfb..0000000000 --- a/plugins/puppetdb/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | - diff --git a/plugins/puppetdb/package.json b/plugins/puppetdb/package.json deleted file mode 100644 index b6bf298843..0000000000 --- a/plugins/puppetdb/package.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "@backstage/plugin-puppetdb", - "description": "Backstage plugin to visualize resource information and Puppet facts from PuppetDB.", - "version": "0.1.13-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/puppetdb" - }, - "keywords": [ - "backstage", - "puppetdb", - "puppet" - ], - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "msw": "^1.0.1" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/puppetdb/src/api/PupeptDbClient.test.ts b/plugins/puppetdb/src/api/PupeptDbClient.test.ts deleted file mode 100644 index 8b858e21ca..0000000000 --- a/plugins/puppetdb/src/api/PupeptDbClient.test.ts +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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 { UrlPatternDiscovery } from '@backstage/core-app-api'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { PuppetDbClient } from './PuppetDbClient'; -import { - PuppetDbReport, - PuppetDbReportEvent, - PuppetDbReportLog, -} from './types'; - -const server = setupServer(); - -const reports: PuppetDbReport[] = [ - { - hash: 'hash1', - puppet_version: 'version1', - report_format: 1, - certname: 'node1', - start_time: '2021-01-01T00:00:00Z', - end_time: '2021-01-01T00:00:00Z', - producer_timestamp: '2021-01-01T00:00:00Z', - receive_time: '2021-01-01T00:00:00Z', - producer: 'producer1', - transaction_uuid: 'uuid1', - catalog_uuid: 'uuid1', - code_id: 'id1', - cached_catalog_status: 'status1', - type: 'type1', - corrective_change: false, - configuration_version: 'version1', - environment: 'production', - noop: false, - status: 'changed', - }, - { - hash: 'hash2', - puppet_version: 'version2', - report_format: 2, - certname: 'node1', - start_time: '2021-01-01T00:00:00Z', - end_time: '2021-01-01T00:00:00Z', - producer_timestamp: '2021-01-01T00:00:00Z', - receive_time: '2021-01-01T00:00:00Z', - producer: 'producer2', - transaction_uuid: 'uuid2', - catalog_uuid: 'uuid2', - code_id: 'id2', - cached_catalog_status: 'status2', - type: 'type2', - corrective_change: false, - configuration_version: 'version2', - environment: 'production', - noop: false, - status: 'failed', - }, -]; - -const events: PuppetDbReportEvent[] = [ - { - name: 'event1', - message: 'message1', - file: 'file1', - line: 1, - certname: 'node1', - report: 'hash1', - timestamp: '2021-01-01T00:00:00Z', - report_receive_time: '2021-01-01T00:00:00Z', - run_start_time: '2021-01-01T00:00:00Z', - containing_class: 'class1', - environment: 'production', - configuration_version: 'version1', - containment_path: ['path1'], - corrective_change: false, - run_end_time: '2021-01-01T00:00:00Z', - resource_type: 'type1', - resource_title: 'title1', - property: 'property1', - old_value: 'old1', - new_value: 'new1', - status: 'changed', - }, - { - name: 'event2', - message: 'message2', - file: 'file2', - line: 2, - certname: 'node1', - report: 'hash1', - timestamp: '2021-01-01T00:00:00Z', - report_receive_time: '2021-01-01T00:00:00Z', - run_start_time: '2021-01-01T00:00:00Z', - containing_class: 'class2', - environment: 'production', - configuration_version: 'version2', - containment_path: ['path2'], - corrective_change: false, - run_end_time: '2021-01-01T00:00:00Z', - resource_type: 'type2', - resource_title: 'title2', - property: 'property2', - old_value: 'old2', - new_value: 'new2', - status: 'failed', - }, -]; - -const logs: PuppetDbReportLog[] = [ - { - level: 'level1', - file: 'file1', - line: 1, - time: '2021-01-01T00:00:00Z', - message: 'message1', - source: 'source1', - tags: ['tag1'], - }, - { - level: 'level2', - file: 'file2', - line: 2, - time: '2021-01-01T00:00:00Z', - message: 'message2', - source: 'source2', - tags: ['tag2'], - }, -]; - -describe('PuppetDbClient', () => { - setupRequestMockHandlers(server); - - const puppetDbCertName = 'node1'; - const mockBaseUrl = 'http://backstage:9191/api/proxy'; - const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - let client: PuppetDbClient; - - const setupHandlers = () => { - server.use( - rest.get( - `${mockBaseUrl}/puppetdb/pdb/query/v4/reports`, - (req, res, ctx) => { - if ( - req.url.searchParams.get('query') !== - `["=","certname","${puppetDbCertName}"]` - ) { - return res(ctx.status(400)); - } - - return res(ctx.status(200), ctx.json(reports)); - }, - ), - - rest.get( - `${mockBaseUrl}/puppetdb/pdb/query/v4/reports/hash1/events`, - (_, res, ctx) => { - return res(ctx.status(200), ctx.json(events)); - }, - ), - - rest.get( - `${mockBaseUrl}/puppetdb/pdb/query/v4/reports/hash1/logs`, - (_, res, ctx) => { - return res(ctx.status(200), ctx.json(logs)); - }, - ), - ); - }; - - beforeEach(() => { - setupHandlers(); - client = new PuppetDbClient({ - discoveryApi: discoveryApi, - fetchApi: new MockFetchApi(), - }); - }); - - it('getPuppetDbNodeReports should return reports', async () => { - const got = await client.getPuppetDbNodeReports(puppetDbCertName); - expect(got).toEqual(reports); - }); - - it('getPuppetDbReportEvents should return events', async () => { - const got = await client.getPuppetDbReportEvents('hash1'); - expect(got).toEqual(events); - }); - - it('getPuppetDbReportLogs should return logs', async () => { - const got = await client.getPuppetDbReportLogs('hash1'); - expect(got).toEqual(logs); - }); -}); diff --git a/plugins/puppetdb/src/api/PuppetDbClient.ts b/plugins/puppetdb/src/api/PuppetDbClient.ts deleted file mode 100644 index b8f3c6e404..0000000000 --- a/plugins/puppetdb/src/api/PuppetDbClient.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 { - PuppetDbApi, - PuppetDbReport, - PuppetDbReportEvent, - PuppetDbReportLog, -} from './types'; -import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; - -export class PuppetDbClient implements PuppetDbApi { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - - constructor({ - discoveryApi, - fetchApi, - }: { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - }) { - this.discoveryApi = discoveryApi; - this.fetchApi = fetchApi; - } - - private async callApi( - path: string, - query: { [key in string]: any }, - ): Promise { - const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/puppetdb`; - const response = await this.fetchApi.fetch( - `${apiUrl}${path}?${new URLSearchParams(query).toString()}`, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ); - if (response.ok) { - return (await response.json()) as T; - } - throw await ResponseError.fromResponse(response); - } - - async getPuppetDbReportEvents( - puppetDbReportHash: string, - ): Promise { - if (!puppetDbReportHash) { - throw new Error('PuppetDB report hash is required'); - } - - const events = (await this.callApi( - `/pdb/query/v4/reports/${puppetDbReportHash}/events`, - {}, - )) as PuppetDbReportEvent[]; - - if (!events || events.length === 0) { - return undefined; - } - - return events; - } - - async getPuppetDbReportLogs( - puppetDbReportHash: string, - ): Promise { - if (!puppetDbReportHash) { - throw new Error('PuppetDB report hash is required'); - } - - const events = (await this.callApi( - `/pdb/query/v4/reports/${puppetDbReportHash}/logs`, - {}, - )) as PuppetDbReportLog[]; - - if (!events || events.length === 0) { - return undefined; - } - - return events; - } - - async getPuppetDbNodeReports( - puppetDbCertName: string, - ): Promise { - if (!puppetDbCertName) { - throw new Error('PuppetDB certname is required'); - } - - return this.callApi(`/pdb/query/v4/reports`, { - query: `["=","certname","${puppetDbCertName}"]`, - order_by: `[{"field": "start_time", "order": "desc"},{"field": "end_time", "order": "desc"}]`, - limit: 100, - }); - } -} diff --git a/plugins/puppetdb/src/api/index.ts b/plugins/puppetdb/src/api/index.ts deleted file mode 100644 index a21728431d..0000000000 --- a/plugins/puppetdb/src/api/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 type { - PuppetDbReport, - PuppetDbReportEvent, - PuppetDbReportLog, -} from './types'; -export { puppetDbApiRef } from './types'; -export { PuppetDbClient } from './PuppetDbClient'; diff --git a/plugins/puppetdb/src/api/types.ts b/plugins/puppetdb/src/api/types.ts deleted file mode 100644 index 8005d0e1de..0000000000 --- a/plugins/puppetdb/src/api/types.ts +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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 { createApiRef } from '@backstage/core-plugin-api'; - -/** - * Report from a PuppetDB. - */ -export type PuppetDbReport = { - /** The name of the node that the report was received from. */ - certname: string; - /** The ID of the report. */ - hash: string; - /** The environment assigned to the node that submitted the report. */ - environment: string; - /** The status associated to report's node. */ - status: string; - /** The job id associated with the report. */ - job_id?: string; - /** A flag indicating whether the report was produced by a noop run. */ - noop: boolean; - /** A flag indicating whether the report contains noop events. */ - noop_pending?: boolean; - /** The version of Puppet that generated the report. */ - puppet_version: string; - /** The version number of the report format that Puppet used to generate the original report data. */ - report_format: number; - /** An identifier string that Puppet uses to match a specific catalog for a node to a specific Puppet run. */ - configuration_version: string; - /** The time on the agent at which the Puppet run began. */ - start_time: string; - /** The time on the agent at which the Puppet run ended. */ - end_time: string; - /** The time of catalog submission from the Puppet Server to PuppetDB. */ - producer_timestamp: string; - /** The time at which PuppetDB received the report. */ - receive_time: string; - /** The certname of the Puppet Server that sent the report to PuppetDB. */ - producer: string; - /** A string used to identify a Puppet run. */ - transaction_uuid: string; - /** A string used to tie a catalog to a report to the catalog used from that Puppet run. */ - catalog_uuid: string; - /** A string used to tie a catalog to the Puppet code which generated the catalog. */ - code_id: string; - /** A string used to identify whether the Puppet run used a cached catalogs. */ - cached_catalog_status: string; - /** Either "agent", "plan", or "any" to restrict the results to reports submitted from that source. */ - type: string; - /** A flag indicating whether any of the report's events remediated configuration drift. */ - corrective_change: boolean; - /** Report metrics. */ - metrics?: { - /** Metrics data. */ - data: PuppetDbReportMetric[]; - /** Link to the metrics endpoint. */ - href: string; - }; -}; - -/** - * Resource event generated from Puppet report. - */ -export type PuppetDbReportEvent = { - /** The name of the node on which the event occurred. */ - certname: string; - /** The ID of the report that the event occurred in. */ - report: string; - /** The status of the event. Legal values are success, failure, noop, and skipped. */ - status: string; - /** The timestamp (from the Puppet agent) at which the event occurred. Timestamps are always ISO-8601 compatible date/time strings. */ - timestamp: string; - /** The timestamp (from the Puppet agent) at which the Puppet run began. Timestamps are always ISO-8601 compatible date/time strings. */ - run_start_time: string; - /** The timestamp (from the Puppet agent) at which the Puppet run finished. Timestamps are always ISO-8601 compatible date/time strings. */ - run_end_time: string; - /** The timestamp (from the PuppetDB server) at which the Puppet report was received. Timestamps are always ISO-8601 compatible date/time strings. */ - report_receive_time: string; - /** The type of resource that the event occurred on, such as File, Package, etc. */ - resource_type: string; - /** The title of the resource on which the event occurred. */ - resource_title: string; - /** The property/parameter of the resource on which the event occurred. For example, on a Package resource, this field might have a value of ensure. */ - property?: string; - /** The name of the resource on which the event occurred. */ - name?: string; - /** The new value that Puppet was attempting to set for the specified resource property. Any rich data values will appear as readable strings. */ - new_value?: string; - /** The previous value of the resource property, which Puppet was attempting to change. Any rich data values will appear as readable strings. */ - old_value?: string; - /** A description (supplied by the resource provider) of what happened during the event. */ - message?: string; - /** The manifest file in which the resource definition is located. */ - file?: string; - /** The line (of the containing manifest file) at which the resource definition can be found. */ - line?: number; - /** The Puppet class where this resource is declared. */ - containing_class?: string; - /** Whether the event occurred in the most recent Puppet run (per-node). */ - latest_report?: boolean; - /** The environment associated with the reporting node. */ - environment: string; - /** An identifier string that Puppet uses to match a specific catalog for a node to a specific Puppet run. */ - configuration_version: string; - /** The containment path associated with the event, as an ordered array that ends with the most specific containing element. */ - containment_path: string[]; - /** Whether the event represents a "corrective change", meaning the event rectified configuration drift. */ - corrective_change: boolean; -}; - -/** - * Resource log generated from Puppet report. - */ -export type PuppetDbReportLog = { - /** The manifest file in which the resource definition is located. */ - file?: string; - /** The line (of the containing manifest file) at which the resource definition can be found. */ - line?: number; - /** The timestamp (from the Puppet agent) at which the event occurred. Timestamps are always ISO-8601 compatible date/time strings. */ - time: string; - /** A description (supplied by the resource provider) of what happened during the event. */ - message?: string; - /** The log level. */ - level: string; - /** Log source */ - source: string; - /** Resource tags */ - tags: string[]; -}; - -/** - * A metric from a PuppetDB report. - */ -export type PuppetDbReportMetric = { - /** - * The name of the metric. - */ - name: string; - /** - * The value of the metric. - */ - value: string; - /** - * The category of the metric. - */ - category: string; -}; - -export const puppetDbApiRef = createApiRef({ - id: 'plugin.puppetdb.service', -}); - -/** - * The API provided by the PuppetDB plugin. - */ -export type PuppetDbApi = { - /** - * Get a list of PuppetDB reports for the specified node. - * - * @param puppetDbCertName - The name of the node that the report was received from. - * @returns A list of PuppetDB reports for the specified node. - */ - getPuppetDbNodeReports( - puppetDbCertName: string, - ): Promise; - - /** - * Get a specific PuppetDB report events. - * - * @param puppetDbReportHash - The ID of the report. - * @returns Events from a specific PuppetDB report. - */ - getPuppetDbReportEvents( - puppetDbReportHash: string, - ): Promise; - - /** - * Get a specific PuppetDB report logs. - * - * @param puppetDbReportHash - The ID of the report. - * @returns Logs from a specific PuppetDB report. - */ - getPuppetDbReportLogs( - puppetDbReportHash: string, - ): Promise; -}; diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsEventsTable.test.tsx b/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsEventsTable.test.tsx deleted file mode 100644 index 31775014f2..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsEventsTable.test.tsx +++ /dev/null @@ -1,105 +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 { ReportDetailsEventsTable } from './ReportDetailsEventsTable'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { puppetDbApiRef, PuppetDbReportEvent } from '../../api'; -import { PuppetDbClient } from '../../api'; -import { ApiProvider } from '@backstage/core-app-api'; -import { puppetDbRouteRef } from '../../routes'; - -const events: PuppetDbReportEvent[] = [ - { - name: 'event3', - message: 'message1', - file: 'file1', - line: 1, - certname: 'node1', - report: 'hash1', - timestamp: '2021-01-01T00:00:00Z', - report_receive_time: '2021-01-01T00:00:00Z', - run_start_time: '2021-01-01T00:00:00Z', - containing_class: 'class1', - environment: 'production', - configuration_version: 'version1', - containment_path: ['path1'], - corrective_change: false, - run_end_time: '2021-01-01T00:00:00Z', - resource_type: 'type1', - resource_title: 'title1', - property: 'property1', - old_value: 'old1', - new_value: 'new1', - status: 'changed', - }, - { - name: 'event2', - message: 'message2', - file: 'file2', - line: 2, - certname: 'node1', - report: 'hash1', - timestamp: '2021-01-01T00:00:00Z', - report_receive_time: '2021-01-01T00:00:00Z', - run_start_time: '2021-01-01T00:00:00Z', - containing_class: 'class2', - environment: 'production', - configuration_version: 'version2', - containment_path: ['path2'], - corrective_change: false, - run_end_time: '2021-01-01T00:00:00Z', - resource_type: 'type2', - resource_title: 'title2', - property: 'property2', - old_value: 'old2', - new_value: 'new2', - status: 'failed', - }, -]; - -const mockPuppetDbApi: Partial = { - getPuppetDbReportEvents: async () => events, -}; - -const apis = TestApiRegistry.from([puppetDbApiRef, mockPuppetDbApi]); - -const hash = 'hash'; - -describe('ReportEventsTable', () => { - it('should render', async () => { - const render = await renderInTestApp( - - - , - { - mountedRoutes: { - '/puppetdb/report/:hash': puppetDbRouteRef, - }, - }, - ); - - expect(render.getByText('Latest events')).toBeInTheDocument(); - expect(render.getByText('Containing Class')).toBeInTheDocument(); - expect(render.getByText('Resource')).toBeInTheDocument(); - expect(render.getByText('Property')).toBeInTheDocument(); - expect(render.getByText('Old Value')).toBeInTheDocument(); - expect(render.getByText('New Value')).toBeInTheDocument(); - expect(render.getByText('Status')).toBeInTheDocument(); - expect(render.getByText('property2')).toBeInTheDocument(); - expect(render.getByText('old1')).toBeInTheDocument(); - expect(render.getByText('old2')).toBeInTheDocument(); - }); -}); diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsEventsTable.tsx b/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsEventsTable.tsx deleted file mode 100644 index b7f5b3c436..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsEventsTable.tsx +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 Typography from '@material-ui/core/Typography'; -import React from 'react'; -import { puppetDbApiRef, PuppetDbReportEvent } from '../../api'; -import { - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import useAsync from 'react-use/lib/useAsync'; -import { useApi } from '@backstage/core-plugin-api'; -import { makeStyles } from '@material-ui/core/styles'; -import { StatusField } from '../StatusField'; - -type ReportEventsTableProps = { - hash: string; -}; - -const useStyles = makeStyles(theme => ({ - empty: { - padding: theme.spacing(2), - display: 'flex', - justifyContent: 'center', - }, -})); - -/** - * Component for displaying PuppetDB report events. - * - * @public - */ -export const ReportDetailsEventsTable = (props: ReportEventsTableProps) => { - const { hash } = props; - const puppetDbApi = useApi(puppetDbApiRef); - const classes = useStyles(); - const { value, loading, error } = useAsync(async () => { - return puppetDbApi.getPuppetDbReportEvents(hash); - }, [puppetDbApi, hash]); - - if (error) { - return ; - } - - const columns: TableColumn[] = [ - { - title: 'Run Start Time', - field: 'run_start_time', - align: 'center', - width: '300px', - render: rowData => ( - - {new Date(Date.parse(rowData.run_start_time)).toLocaleString()} - - ), - }, - { - title: 'Run End Time', - field: 'run_end_time', - align: 'center', - width: '300px', - render: rowData => ( - - {new Date(Date.parse(rowData.run_end_time)).toLocaleString()} - - ), - }, - { - title: 'Containing Class', - field: 'containing_class', - render: rowData => ( - - {rowData.containing_class} - - ), - }, - { - title: 'Resource', - field: 'resource_title', - render: rowData => ( - - {rowData.resource_type}[{rowData.resource_title}] - - ), - }, - { - title: 'Property', - field: 'property', - render: rowData => {rowData.property}, - }, - { - title: 'Old Value', - field: 'old_value', - render: rowData => {rowData.old_value}, - }, - { - title: 'New Value', - field: 'new_value', - render: rowData => {rowData.new_value}, - }, - { - title: 'Status', - field: 'status', - render: rowData => , - }, - ]; - - return ( - - No events - - } - title="Latest events" - columns={columns} - data={value || []} - isLoading={loading} - /> - ); -}; diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsLogsTable.test.tsx b/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsLogsTable.test.tsx deleted file mode 100644 index 2d9d973412..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsLogsTable.test.tsx +++ /dev/null @@ -1,74 +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 { ReportDetailsLogsTable } from './ReportDetailsLogsTable'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { puppetDbApiRef, PuppetDbReportLog } from '../../api'; -import { PuppetDbClient } from '../../api'; -import { ApiProvider } from '@backstage/core-app-api'; -import { puppetDbRouteRef } from '../../routes'; - -const logs: PuppetDbReportLog[] = [ - { - level: 'level1', - file: 'file1', - line: 1, - time: '2021-01-01T00:00:00Z', - message: 'message1', - source: 'source1', - tags: ['tag1'], - }, - { - level: 'level2', - file: 'file2', - line: 2, - time: '2021-01-01T00:00:00Z', - message: 'message2', - source: 'source2', - tags: ['tag2'], - }, -]; - -const mockPuppetDbApi: Partial = { - getPuppetDbReportLogs: async () => logs, -}; - -const apis = TestApiRegistry.from([puppetDbApiRef, mockPuppetDbApi]); - -const hash = 'hash'; - -describe('ReportLogsTable', () => { - it('should render', async () => { - const render = await renderInTestApp( - - - , - { - mountedRoutes: { - '/puppetdb/report/:hash': puppetDbRouteRef, - }, - }, - ); - - expect(render.getByText('Latest logs')).toBeInTheDocument(); - expect(render.getByText('Level')).toBeInTheDocument(); - expect(render.getByText('Timestamp')).toBeInTheDocument(); - expect(render.getByText('Source')).toBeInTheDocument(); - expect(render.getByText('Message')).toBeInTheDocument(); - expect(render.getByText('source1')).toBeInTheDocument(); - expect(render.getByText('source2')).toBeInTheDocument(); - }); -}); diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsLogsTable.tsx b/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsLogsTable.tsx deleted file mode 100644 index d12b432314..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsLogsTable.tsx +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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 Typography from '@material-ui/core/Typography'; -import React from 'react'; -import { puppetDbApiRef, PuppetDbReportLog } from '../../api'; -import { - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import useAsync from 'react-use/lib/useAsync'; -import { useApi } from '@backstage/core-plugin-api'; -import { makeStyles } from '@material-ui/core/styles'; - -type ReportLogsTableProps = { - hash: string; -}; - -const useStyles = makeStyles(theme => ({ - empty: { - padding: theme.spacing(2), - display: 'flex', - justifyContent: 'center', - }, - level_error: { - color: theme.palette.error.light, - }, - level_warning: { - color: theme.palette.warning.light, - }, - level_notice: { - color: theme.palette.info.light, - }, -})); - -/** - * Component for displaying PuppetDB report logs. - * - * @public - */ -export const ReportDetailsLogsTable = (props: ReportLogsTableProps) => { - const { hash } = props; - const puppetDbApi = useApi(puppetDbApiRef); - const classes = useStyles(); - const { value, loading, error } = useAsync(async () => { - return puppetDbApi.getPuppetDbReportLogs(hash); - }, [puppetDbApi, hash]); - - if (error) { - return ; - } - - const columns: TableColumn[] = [ - { - title: 'Level', - field: 'level', - align: 'center', - width: '100px', - render: rowData => ( - - {rowData.level.toLocaleUpperCase('en-US')} - - ), - }, - { - title: 'Timestamp', - field: 'time', - align: 'center', - width: '300px', - render: rowData => ( - - {new Date(Date.parse(rowData.time)).toLocaleString()} - - ), - }, - { - title: 'Source', - field: 'source', - render: rowData => {rowData.source}, - }, - { - title: 'Message', - field: 'message', - render: rowData => {rowData.message}, - }, - ]; - - return ( -
- No logs - - } - title="Latest logs" - columns={columns} - data={value || []} - isLoading={loading} - /> - ); -}; diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsPage.test.tsx b/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsPage.test.tsx deleted file mode 100644 index e6ade0e596..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsPage.test.tsx +++ /dev/null @@ -1,45 +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 { ReportDetailsPage } from './ReportDetailsPage'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { puppetDbRouteRef } from '../../routes'; -import { puppetDbApiRef, PuppetDbClient } from '../../api'; -import { ApiProvider } from '@backstage/core-app-api'; - -const mockPuppetDbApi: Partial = { - getPuppetDbReportEvents: async () => [], -}; - -const apis = TestApiRegistry.from([puppetDbApiRef, mockPuppetDbApi]); - -describe('ReportDetailsPage', () => { - it('should render', async () => { - const render = await renderInTestApp( - - - , - { - mountedRoutes: { - '/puppetdb/report': puppetDbRouteRef, - }, - }, - ); - expect(render.getByText('PuppetDB Reports')).toBeInTheDocument(); - expect(render.getByText('Events')).toBeInTheDocument(); - expect(render.getByText('Logs')).toBeInTheDocument(); - }); -}); diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsPage.tsx b/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsPage.tsx deleted file mode 100644 index c7da8df36b..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/ReportDetailsPage.tsx +++ /dev/null @@ -1,106 +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 { Link as RouterLink, useParams } from 'react-router-dom'; -import { Breadcrumbs, Link } from '@backstage/core-components'; -import { makeStyles } from '@material-ui/core/styles'; -import { useRouteRef } from '@backstage/core-plugin-api'; -import { puppetDbRouteRef } from '../../routes'; -import React, { useState } from 'react'; -import { - Card, - CardContent, - Tab, - Box, - Typography, - Tabs, -} from '@material-ui/core'; -import { ReportDetailsEventsTable } from './ReportDetailsEventsTable'; -import { ReportDetailsLogsTable } from './ReportDetailsLogsTable'; - -const useStyles = makeStyles(theme => ({ - cards: { - marginTop: theme.spacing(2), - }, - tabs: { - borderBottom: `1px solid ${theme.palette.textVerySubtle}`, - backgroundColor: theme.palette.background.default, - padding: theme.spacing(0, 4), - }, - default: { - padding: theme.spacing(2), - fontWeight: theme.typography.fontWeightBold, - color: theme.palette.text.secondary, - textTransform: 'uppercase', - }, - selected: { - color: theme.palette.text.primary, - }, -})); - -/** - * Component for displaying the details of a PuppetDB report. - * - * @public - */ -export const ReportDetailsPage = () => { - const { hash = '' } = useParams(); - const classes = useStyles(); - const [tabIndex, setTabIndex] = useState(0); - const reportsRouteLink = useRouteRef(puppetDbRouteRef); - const tabs = [ - { id: 'events', label: 'Events' }, - { id: 'logs', label: 'Logs' }, - ]; - const safeTabIndex = tabIndex > tabs.length - 1 ? 0 : tabIndex; - - return ( -
- - - PuppetDB Reports - - {hash} - - - - setTabIndex(index)} - value={safeTabIndex} - > - {tabs.map((tab, index) => ( - - ))} - - - {safeTabIndex === 0 && } - {safeTabIndex === 1 && } - - - -
- ); -}; diff --git a/plugins/puppetdb/src/components/ReportDetailsPage/index.ts b/plugins/puppetdb/src/components/ReportDetailsPage/index.ts deleted file mode 100644 index 8c0153c853..0000000000 --- a/plugins/puppetdb/src/components/ReportDetailsPage/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ReportDetailsPage } from './ReportDetailsPage'; -export { ReportDetailsEventsTable } from './ReportDetailsEventsTable'; -export { ReportDetailsLogsTable } from './ReportDetailsLogsTable'; diff --git a/plugins/puppetdb/src/components/ReportsPage/ReportsPage.test.tsx b/plugins/puppetdb/src/components/ReportsPage/ReportsPage.test.tsx deleted file mode 100644 index a4c094f69a..0000000000 --- a/plugins/puppetdb/src/components/ReportsPage/ReportsPage.test.tsx +++ /dev/null @@ -1,85 +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 { ReportsPage } from './ReportsPage'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { puppetDbApiRef, PuppetDbClient } from '../../api'; -import { ANNOTATION_PUPPET_CERTNAME } from '../../constants'; -import { Entity } from '@backstage/catalog-model/'; -import { isPuppetDbAvailable } from '../Router'; -import { ApiProvider } from '@backstage/core-app-api'; -import { puppetDbRouteRef } from '../../routes'; - -const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Resource', - metadata: { - name: 'test', - annotations: { - [ANNOTATION_PUPPET_CERTNAME]: 'node1', - }, - }, -}; - -const entityWithoutAnnotations: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Resource', - metadata: { - name: 'test', - annotations: {}, - }, -}; - -const mockPuppetDbApi: Partial = { - getPuppetDbNodeReports: async () => [], -}; - -const apis = TestApiRegistry.from([puppetDbApiRef, mockPuppetDbApi]); - -describe('isPuppetDbAvailable', () => { - describe('when entity has no annotations', () => { - it('returns false', () => { - expect(isPuppetDbAvailable(entityWithoutAnnotations)).toBe(false); - }); - }); - - describe('when entity has the puppet annotation', () => { - it('returns true', () => { - expect(isPuppetDbAvailable(entity)).toBe(true); - }); - }); -}); - -describe('ReportsPage', () => { - it('should render', async () => { - const render = await renderInTestApp( - - - - - , - { - mountedRoutes: { - '/puppetdb': puppetDbRouteRef, - }, - }, - ); - expect( - render.getByText('Latest PuppetDB reports from node node1'), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/puppetdb/src/components/ReportsPage/ReportsPage.tsx b/plugins/puppetdb/src/components/ReportsPage/ReportsPage.tsx deleted file mode 100644 index 8c99e590b5..0000000000 --- a/plugins/puppetdb/src/components/ReportsPage/ReportsPage.tsx +++ /dev/null @@ -1,39 +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 { ReportsTable } from './ReportsTable'; -import { Page, Content } from '@backstage/core-components'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { ANNOTATION_PUPPET_CERTNAME } from '../../constants'; - -/** - * Component to display PuppetDB reports page. - * - * @public - */ -export const ReportsPage = () => { - const { entity } = useEntity(); - const certName = - entity?.metadata?.annotations?.[ANNOTATION_PUPPET_CERTNAME] ?? ''; - - return ( - - - - - - ); -}; diff --git a/plugins/puppetdb/src/components/ReportsPage/ReportsTable.test.tsx b/plugins/puppetdb/src/components/ReportsPage/ReportsTable.test.tsx deleted file mode 100644 index fadfb1a3f9..0000000000 --- a/plugins/puppetdb/src/components/ReportsPage/ReportsTable.test.tsx +++ /dev/null @@ -1,103 +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 { ReportsTable } from './ReportsTable'; -import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; -import { puppetDbApiRef, PuppetDbReport, PuppetDbClient } from '../../api'; -import { ApiProvider } from '@backstage/core-app-api'; -import { puppetDbRouteRef } from '../../routes'; - -const reports: PuppetDbReport[] = [ - { - hash: 'hash1', - puppet_version: 'version1', - report_format: 1, - certname: 'node1', - start_time: '2021-01-01T00:00:00Z', - end_time: '2021-01-01T00:00:00Z', - producer_timestamp: '2021-01-01T00:00:00Z', - receive_time: '2021-01-01T00:00:00Z', - producer: 'producer1', - transaction_uuid: 'uuid1', - catalog_uuid: 'uuid1', - code_id: 'id1', - cached_catalog_status: 'status1', - type: 'type1', - corrective_change: false, - configuration_version: 'version1', - environment: 'production', - noop: true, - status: 'changed', - }, - { - hash: 'hash2', - puppet_version: 'version2', - report_format: 2, - certname: 'node1', - start_time: '2021-01-01T00:00:00Z', - end_time: '2021-01-01T00:00:00Z', - producer_timestamp: '2021-01-01T00:00:00Z', - receive_time: '2021-01-01T00:00:00Z', - producer: 'producer2', - transaction_uuid: 'uuid2', - catalog_uuid: 'uuid2', - code_id: 'id2', - cached_catalog_status: 'status2', - type: 'type2', - corrective_change: false, - configuration_version: 'version2', - environment: 'production', - noop: false, - status: 'failed', - }, -]; - -const mockPuppetDbApi: Partial = { - getPuppetDbNodeReports: async () => reports, -}; - -const apis = TestApiRegistry.from([puppetDbApiRef, mockPuppetDbApi]); - -const certName = 'node1'; - -describe('ReportsTable', () => { - it('should render', async () => { - const render = await renderInTestApp( - - - , - { - mountedRoutes: { - '/puppetdb': puppetDbRouteRef, - }, - }, - ); - - expect( - render.getByText('Latest PuppetDB reports from node node1'), - ).toBeInTheDocument(); - expect(render.getByText('Configuration Version')).toBeInTheDocument(); - expect(render.getByText('Start Time')).toBeInTheDocument(); - expect(render.getByText('End Time')).toBeInTheDocument(); - expect(render.getByText('Run Duration')).toBeInTheDocument(); - expect(render.getByText('Mode')).toBeInTheDocument(); - expect(render.getByText('Status')).toBeInTheDocument(); - expect(render.getByText('NO-NOOP')).toBeInTheDocument(); - expect(render.getByText('NOOP')).toBeInTheDocument(); - expect(render.getByText('FAILED')).toBeInTheDocument(); - expect(render.getByText('CHANGED')).toBeInTheDocument(); - }); -}); diff --git a/plugins/puppetdb/src/components/ReportsPage/ReportsTable.tsx b/plugins/puppetdb/src/components/ReportsPage/ReportsTable.tsx deleted file mode 100644 index 3aeecc70b0..0000000000 --- a/plugins/puppetdb/src/components/ReportsPage/ReportsTable.tsx +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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 { puppetDbApiRef, PuppetDbReport } from '../../api'; -import useAsync from 'react-use/lib/useAsync'; -import React from 'react'; -import { - Link, - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import { useApi, useRouteRef } from '@backstage/core-plugin-api'; -import { makeStyles } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; -import { Link as RouterLink } from 'react-router-dom'; -import { puppetDbReportRouteRef } from '../../routes'; -import { StatusField } from '../StatusField'; - -type ReportsTableProps = { - certName: string; -}; - -const useStyles = makeStyles(theme => ({ - empty: { - padding: theme.spacing(2), - display: 'flex', - justifyContent: 'center', - }, -})); - -/** - * Component for displaying a table of PuppetDB reports for a given node. - * - * @public - */ -export const ReportsTable = (props: ReportsTableProps) => { - const { certName } = props; - const puppetDbApi = useApi(puppetDbApiRef); - const reportsRouteLink = useRouteRef(puppetDbReportRouteRef); - const classes = useStyles(); - - const { value, loading, error } = useAsync(async () => { - return puppetDbApi.getPuppetDbNodeReports(certName); - }, [puppetDbApi, certName]); - - if (error) { - return ; - } - - const columns: TableColumn[] = [ - { - title: 'Configuration Version', - field: 'configuration_version', - render: rowData => ( - - {rowData.configuration_version !== '' ? ( - {rowData.configuration_version} - ) : ( - - (N/A) - - )} - - ), - }, - { - title: 'Start Time', - field: 'start_time', - align: 'center', - width: '300px', - render: rowData => ( - - {new Date(Date.parse(rowData.start_time)).toLocaleString()} - - ), - }, - { - title: 'End Time', - field: 'end_time', - align: 'center', - width: '300px', - render: rowData => ( - - {new Date(Date.parse(rowData.end_time)).toLocaleString()} - - ), - }, - { - title: 'Run Duration', - align: 'center', - width: '400px', - render: rowData => { - const start_date = new Date(Date.parse(rowData.start_time)); - const end_date = new Date(Date.parse(rowData.end_time)); - const duration = new Date(end_date.getTime() - start_date.getTime()); - return ( - - {duration.getUTCHours().toString().padStart(2, '0')}: - {duration.getUTCMinutes().toString().padStart(2, '0')}: - {duration.getUTCSeconds().toString().padStart(2, '0')}. - {duration.getUTCMilliseconds().toString().padStart(4, '0')} - - ); - }, - }, - { - title: 'Environment', - field: 'environment', - }, - { - title: 'Mode', - field: 'noop', - align: 'center', - render: rowData => - rowData.noop ? ( - NOOP - ) : ( - NO-NOOP - ), - }, - { - title: 'Status', - field: 'status', - align: 'center', - render: rowData => , - }, - ]; - - return ( -
- No reports - - } - title={`Latest PuppetDB reports from node ${certName}`} - columns={columns} - data={value || []} - isLoading={loading} - /> - ); -}; diff --git a/plugins/puppetdb/src/components/ReportsPage/index.ts b/plugins/puppetdb/src/components/ReportsPage/index.ts deleted file mode 100644 index 60840e5eb5..0000000000 --- a/plugins/puppetdb/src/components/ReportsPage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ReportsPage } from './ReportsPage'; -export { ReportsTable } from './ReportsTable'; diff --git a/plugins/puppetdb/src/components/Router.tsx b/plugins/puppetdb/src/components/Router.tsx deleted file mode 100644 index 5e6a79bc43..0000000000 --- a/plugins/puppetdb/src/components/Router.tsx +++ /dev/null @@ -1,57 +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 { Routes, Route } from 'react-router-dom'; -import { puppetDbReportRouteRef } from '../routes'; -import { ANNOTATION_PUPPET_CERTNAME } from '../constants'; -import { Entity } from '@backstage/catalog-model'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import { ReportsPage } from './ReportsPage'; -import { ReportDetailsPage } from './ReportDetailsPage'; - -/** - * Checks if the entity has a puppet certname annotation. - * @param entity - The entity to check for the puppet certname annotation. - * - * @public - */ -export const isPuppetDbAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[ANNOTATION_PUPPET_CERTNAME]); - -/** @public */ -export const Router = () => { - const { entity } = useEntity(); - - if (!isPuppetDbAvailable(entity)) { - return ( - - ); - } - - return ( - - } /> - } - /> - - ); -}; diff --git a/plugins/puppetdb/src/components/StatusField/StatusField.test.tsx b/plugins/puppetdb/src/components/StatusField/StatusField.test.tsx deleted file mode 100644 index 1aa8c94ce9..0000000000 --- a/plugins/puppetdb/src/components/StatusField/StatusField.test.tsx +++ /dev/null @@ -1,52 +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 { StatusField } from './StatusField'; -import { renderInTestApp } from '@backstage/test-utils'; - -describe('StatusField', () => { - it('should render failed', async () => { - const render = await renderInTestApp(); - expect(render.getByText('FAILED')).toBeInTheDocument(); - expect( - render.container.querySelector('span[aria-label="Status error"]'), - ).toBeInTheDocument(); - }); - - it('should render changed', async () => { - const render = await renderInTestApp(); - expect(render.getByText('CHANGED')).toBeInTheDocument(); - expect( - render.container.querySelector('span[aria-label="Status running"]'), - ).toBeInTheDocument(); - }); - - it('should render unchanged', async () => { - const render = await renderInTestApp(); - expect(render.getByText('UNCHANGED')).toBeInTheDocument(); - expect( - render.container.querySelector('span[aria-label="Status pending"]'), - ).toBeInTheDocument(); - }); - - it('should render default', async () => { - const render = await renderInTestApp(); - expect(render.getByText('SUCCESSFUL')).toBeInTheDocument(); - expect( - render.container.querySelector('span[aria-label="Status ok"]'), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/puppetdb/src/components/StatusField/StatusField.tsx b/plugins/puppetdb/src/components/StatusField/StatusField.tsx deleted file mode 100644 index 7c1d1b1efc..0000000000 --- a/plugins/puppetdb/src/components/StatusField/StatusField.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { - StatusPending, - StatusRunning, - StatusOK, - StatusError, -} from '@backstage/core-components'; - -type StatusCellProps = { - status: string; -}; - -/** - * Component to display status field for Puppet reports and events. - * - * @public - */ -export const StatusField = (props: StatusCellProps) => { - const { status } = props; - - const statusUC = status.toLocaleUpperCase('en-US'); - switch (status) { - case 'failed': - return ( - <> - - {statusUC} - - ); - case 'changed': - return ( - <> - - {statusUC} - - ); - case 'unchanged': - return ( - <> - - {statusUC} - - ); - default: - return ( - <> - - {statusUC} - - ); - } -}; diff --git a/plugins/puppetdb/src/components/StatusField/index.ts b/plugins/puppetdb/src/components/StatusField/index.ts deleted file mode 100644 index 4f1a8aad1c..0000000000 --- a/plugins/puppetdb/src/components/StatusField/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { StatusField } from './StatusField'; diff --git a/plugins/puppetdb/src/constants.ts b/plugins/puppetdb/src/constants.ts deleted file mode 100644 index 57fb4373f4..0000000000 --- a/plugins/puppetdb/src/constants.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Annotation for specifying the certificate name of a node in PuppetDB. - * - * @public - */ -export const ANNOTATION_PUPPET_CERTNAME = 'puppet.com/certname'; diff --git a/plugins/puppetdb/src/index.ts b/plugins/puppetdb/src/index.ts deleted file mode 100644 index 2361a44bed..0000000000 --- a/plugins/puppetdb/src/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { - puppetdbPlugin, - puppetdbPlugin as plugin, - PuppetDbPage, -} from './plugin'; -export { Router, isPuppetDbAvailable } from './components/Router'; -export * from './routes'; diff --git a/plugins/puppetdb/src/plugin.test.ts b/plugins/puppetdb/src/plugin.test.ts deleted file mode 100644 index 947b88d129..0000000000 --- a/plugins/puppetdb/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { puppetdbPlugin } from './plugin'; - -describe('puppetdb', () => { - it('should export plugin', () => { - expect(puppetdbPlugin).toBeDefined(); - }); -}); diff --git a/plugins/puppetdb/src/plugin.ts b/plugins/puppetdb/src/plugin.ts deleted file mode 100644 index 91a2cbf6c6..0000000000 --- a/plugins/puppetdb/src/plugin.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - createApiFactory, - createPlugin, - createRoutableExtension, - discoveryApiRef, - fetchApiRef, -} from '@backstage/core-plugin-api'; - -import { puppetDbApiRef, PuppetDbClient } from './api'; -import { puppetDbRouteRef } from './routes'; - -/** - * Create the PuppetDB frontend plugin. - * - * @public - * */ -export const puppetdbPlugin = createPlugin({ - id: 'puppetDb', - apis: [ - createApiFactory({ - api: puppetDbApiRef, - deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, - factory: ({ discoveryApi, fetchApi }) => - new PuppetDbClient({ discoveryApi, fetchApi }), - }), - ], -}); - -/** - * Creates a routable extension for the PuppetDB plugin content. - * - * @public - */ -export const PuppetDbPage = puppetdbPlugin.provide( - createRoutableExtension({ - name: 'PuppetDbPage', - component: () => import('./components/Router').then(m => m.Router), - mountPoint: puppetDbRouteRef, - }), -); diff --git a/plugins/puppetdb/src/routes.ts b/plugins/puppetdb/src/routes.ts deleted file mode 100644 index d6812f9f2c..0000000000 --- a/plugins/puppetdb/src/routes.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; - -/** @public */ -export const puppetDbRouteRef = createRouteRef({ - id: 'puppetdb', -}); - -/** @public */ -export const puppetDbReportRouteRef = createSubRouteRef({ - id: 'puppetdb/report', - path: '/:hash', - parent: puppetDbRouteRef, -}); diff --git a/plugins/puppetdb/src/setupTests.ts b/plugins/puppetdb/src/setupTests.ts deleted file mode 100644 index 865308e634..0000000000 --- a/plugins/puppetdb/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import '@testing-library/jest-dom'; diff --git a/plugins/rollbar-backend/.eslintrc.js b/plugins/rollbar-backend/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/rollbar-backend/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md deleted file mode 100644 index e992dbff33..0000000000 --- a/plugins/rollbar-backend/CHANGELOG.md +++ /dev/null @@ -1,992 +0,0 @@ -# @backstage/plugin-rollbar-backend - -## 0.1.55-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/config@1.1.1 - -## 0.1.55-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/config@1.1.1 - -## 0.1.55-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.1 - - @backstage/config@1.1.1 - -## 0.1.55-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/config@1.1.1 - -## 0.1.54 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/config@1.1.1 - -## 0.1.54-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.2 - -## 0.1.54-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - -## 0.1.54-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/config@1.1.1 - -## 0.1.53 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/config@1.1.1 - -## 0.1.53-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/config@1.1.1 - -## 0.1.53-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/config@1.1.1 - -## 0.1.53-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/config@1.1.1 - -## 0.1.53-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/config@1.1.1 - -## 0.1.52 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/config@1.1.1 - -## 0.1.52-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.2 - -## 0.1.52-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/config@1.1.1 - -## 0.1.52-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/config@1.1.1 - -## 0.1.51 - -### Patch Changes - -- 407f4284be: ensure rollbar token is hidden -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/config@1.1.1 - -## 0.1.51-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/config@1.1.1-next.0 - -## 0.1.50-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/config@1.1.0 - -## 0.1.50-next.0 - -### Patch Changes - -- 407f4284be: ensure rollbar token is hidden -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - -## 0.1.48 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - -## 0.1.48-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/backend-common@0.19.5-next.3 - -## 0.1.48-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - -## 0.1.48-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - -## 0.1.47-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/config@1.0.8 - -## 0.1.45 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/config@1.0.8 - -## 0.1.45-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.2 - -## 0.1.45-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/config@1.0.8 - -## 0.1.45-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/config@1.0.8 - -## 0.1.44 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1 - - @backstage/config@1.0.8 - -## 0.1.44-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1-next.0 - - @backstage/config@1.0.8 - -## 0.1.43 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/config@1.0.8 - -## 0.1.43-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/config@1.0.7 - -## 0.1.43-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/config@1.0.7 - -## 0.1.43-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - -## 0.1.42 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/config@1.0.7 - -## 0.1.42-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/config@1.0.7 - -## 0.1.42-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/config@1.0.7 - -## 0.1.41 - -### Patch Changes - -- 66b6cfc5716: Replace `camelcase-keys` dependency with one with better compatibility. -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/config@1.0.7 - -## 0.1.41-next.2 - -### Patch Changes - -- 66b6cfc5716: Replace `camelcase-keys` dependency with one with better compatibility. -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/config@1.0.7 - -## 0.1.41-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - -## 0.1.41-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - -## 0.1.40 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3 - - @backstage/config@1.0.7 - -## 0.1.40-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.1.40-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3-next.1 - - @backstage/config@1.0.7-next.0 - -## 0.1.40-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - -## 0.1.39 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/config@1.0.6 - -## 0.1.39-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/config@1.0.6 - -## 0.1.39-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/config@1.0.6 - -## 0.1.39-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - -## 0.1.37 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/config@1.0.6 - -## 0.1.37-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/config@1.0.6-next.0 - -## 0.1.37-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - -## 0.1.36 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/config@1.0.5 - -## 0.1.36-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.3 - - @backstage/config@1.0.5-next.1 - -## 0.1.36-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/config@1.0.5-next.1 - -## 0.1.36-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/config@1.0.5-next.1 - -## 0.1.36-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/config@1.0.5-next.0 - -## 0.1.35 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/config@1.0.4 - -## 0.1.35-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/config@1.0.4-next.0 - -## 0.1.35-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/config@1.0.4-next.0 - -## 0.1.34 - -### Patch Changes - -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/config@1.0.3 - -## 0.1.34-next.2 - -### Patch Changes - -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/backend-common@0.15.2-next.2 - - @backstage/config@1.0.3-next.2 - -## 0.1.34-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/config@1.0.3-next.1 - -## 0.1.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.0 - - @backstage/config@1.0.3-next.0 - -## 0.1.33 - -### Patch Changes - -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/config@1.0.2 - -## 0.1.33-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/backend-common@0.15.1-next.3 - -## 0.1.33-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.2 - -## 0.1.33-next.1 - -### Patch Changes - -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/backend-common@0.15.1-next.1 - -## 0.1.33-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - -## 0.1.32 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.0 - -## 0.1.32-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.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 - -## 0.1.31-next.1 - -### Patch Changes - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.3 - -## 0.1.31-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - -## 0.1.30 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/backend-common@0.14.0 - -## 0.1.30-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - -## 0.1.30-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/backend-common@0.13.6-next.1 - -## 0.1.30-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.6-next.0 - -## 0.1.29 - -### Patch Changes - -- ab1435dcc9: Updated README to include clearer installation instructions on how to install and configure. -- cfc0f19699: Updated dependency `fs-extra` to `10.1.0`. -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/config@1.0.1 - -## 0.1.29-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/config@1.0.1-next.0 - -## 0.1.29-next.1 - -### Patch Changes - -- ab1435dcc9: Updated README to include clearer installation instructions on how to install and configure. -- Updated dependencies - - @backstage/backend-common@0.13.3-next.1 - -## 0.1.29-next.0 - -### Patch Changes - -- cfc0f19699: Updated dependency `fs-extra` to `10.1.0`. -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - -## 0.1.28 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.2 - -## 0.1.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.2-next.0 - -## 0.1.27 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/config@1.0.0 - -## 0.1.26 - -### Patch Changes - -- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 -- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils` -- Updated dependencies - - @backstage/backend-common@0.13.0 - -## 0.1.26-next.0 - -### Patch Changes - -- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 -- 3c2bc73901: Use `setupRequestMockHandlers` from `@backstage/backend-test-utils` -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 - -## 0.1.25 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.12.0 - -## 0.1.24 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.11.0 - -## 0.1.23 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/backend-common@0.10.9 - - @backstage/config@0.1.15 - -## 0.1.22 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- 1433045c08: Removed unused `helmet` dependency. -- Updated dependencies - - @backstage/backend-common@0.10.8 - - @backstage/config@0.1.14 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7-next.0 - -## 0.1.20 - -### Patch Changes - -- 91faf87aaf: chore(deps): bump `camelcase-keys` from 6.2.2 to 7.0.1 -- Updated dependencies - - @backstage/backend-common@0.10.6 - -## 0.1.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6-next.0 - -## 0.1.20-next.0 - -### Patch Changes - -- 91faf87aaf: chore(deps): bump `camelcase-keys` from 6.2.2 to 7.0.1 - -## 0.1.19 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4 - - @backstage/config@0.1.13 - -## 0.1.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4-next.0 - - @backstage/config@0.1.13-next.0 - -## 0.1.18 - -### Patch Changes - -- 152bd9ba2b: Moved `@backstage/test-utils` to `devDependencies`. -- c5e175cde9: Replace the usage of `axios` with `node-fetch` in the Rollbar API -- Updated dependencies - - @backstage/backend-common@0.10.1 - -## 0.1.17 - -### Patch Changes - -- 58d07a070c: Bump `axios` -- Updated dependencies - - @backstage/backend-common@0.10.0 - -## 0.1.16 - -### Patch Changes - -- bab752e2b3: Change default port of backend from 7000 to 7007. - - This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start. - - You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values: - - ``` - backend: - listen: 0.0.0.0:7123 - baseUrl: http://localhost:7123 - ``` - - More information can be found here: https://backstage.io/docs/conf/writing - -- Updated dependencies - - @backstage/backend-common@0.9.11 - -## 0.1.15 - -### Patch Changes - -- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability -- Updated dependencies - - @backstage/backend-common@0.9.4 - - @backstage/config@0.1.10 - -## 0.1.14 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.9.0 - - @backstage/config@0.1.8 - -## 0.1.13 - -### Patch Changes - -- ae84b20cf: Revert the upgrade to `fs-extra@10.0.0` as that seemed to have broken all installs inexplicably. -- Updated dependencies - - @backstage/backend-common@0.8.6 - -## 0.1.12 - -### Patch Changes - -- 3108ff7bf: Make `yarn dev` respect the `PLUGIN_PORT` environment variable. -- Updated dependencies - - @backstage/backend-common@0.8.3 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies [22fd8ce2a] -- Updated dependencies [f9fb4a205] - - @backstage/backend-common@0.8.0 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies [e0bfd3d44] -- Updated dependencies [38ca05168] -- Updated dependencies [d8b81fd28] - - @backstage/backend-common@0.7.0 - - @backstage/config@0.1.5 - -## 0.1.9 - -### Patch Changes - -- 49574a8a3: Fix some `spleling`. - - The `scaffolder-backend` has a configuration schema change that may be breaking - in rare circumstances. Due to a typo in the schema, the - `scaffolder.github.visibility`, `scaffolder.gitlab.visibility`, and - `scaffolder.bitbucket.visibility` did not get proper validation that the value - is one of the supported strings (`public`, `internal` (not available for - Bitbucket), and `private`). If you had a value that was not one of these three, - you may have to adjust your config. - -- Updated dependencies [d367f63b5] -- Updated dependencies [b42531cfe] - - @backstage/backend-common@0.6.3 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies [8686eb38c] -- Updated dependencies [0434853a5] -- Updated dependencies [8686eb38c] - - @backstage/backend-common@0.6.0 - - @backstage/config@0.1.4 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies [0b135e7e0] -- Updated dependencies [294a70cab] -- Updated dependencies [0ea032763] -- Updated dependencies [5345a1f98] -- Updated dependencies [09a370426] - - @backstage/backend-common@0.5.0 - -## 0.1.6 - -### Patch Changes - -- dde4ab398: Bump `axios` from `^0.20.0` to `^0.21.1`. -- Updated dependencies [5ecd50f8a] -- Updated dependencies [00042e73c] -- Updated dependencies [0829ff126] -- Updated dependencies [036a84373] - - @backstage/backend-common@0.4.2 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies [38e24db00] -- Updated dependencies [e3bd9fc2f] -- Updated dependencies [12bbd748c] -- Updated dependencies [e3bd9fc2f] - - @backstage/backend-common@0.4.0 - - @backstage/config@0.1.2 - -## 0.1.4 - -### Patch Changes - -- 3a201c5d5: Add config schema for the rollbar & rollbar-backend plugins -- Updated dependencies [3aa7efb3f] -- Updated dependencies [b3d4e4e57] - - @backstage/backend-common@0.3.2 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies [1722cb53c] -- Updated dependencies [1722cb53c] -- Updated dependencies [7b37e6834] -- Updated dependencies [8e2effb53] - - @backstage/backend-common@0.3.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies [5249594c5] -- Updated dependencies [56e4eb589] -- Updated dependencies [e37c0a005] -- Updated dependencies [f00ca3cb8] -- Updated dependencies [6579769df] -- Updated dependencies [8c2b76e45] -- Updated dependencies [440a17b39] -- Updated dependencies [8afce088a] -- Updated dependencies [7bbeb049f] - - @backstage/backend-common@0.2.0 diff --git a/plugins/rollbar-backend/README.md b/plugins/rollbar-backend/README.md deleted file mode 100644 index 1f5977f5df..0000000000 --- a/plugins/rollbar-backend/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# Rollbar Backend - -Simple plugin that proxies requests to the [Rollbar](https://rollbar.com) API. - -## Setup - -1. Install the plugin using: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-rollbar-backend -``` - -2. Create a `rollbar.ts` file inside `packages/backend/src/plugins/`: - -```typescript -import { createRouter } from '@backstage/plugin-rollbar-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - return await createRouter({ - logger: env.logger, - config: env.config, - }); -} -``` - -3. Modify your `packages/backend/src/index.ts` to include: - -```diff - ... - - import { Config } from '@backstage/config'; - import app from './plugins/app'; -+import rollbar from './plugins/rollbar'; - import scaffolder from './plugins/scaffolder'; - - ... - - async function main() { - - ... - - const authEnv = useHotMemoize(module, () => createEnv('auth')); -+ const rollbarEnv = useHotMemoize(module, () => createEnv('rollbar')); - const proxyEnv = useHotMemoize(module, () => createEnv('proxy')); - - ... - - const apiRouter = Router(); - apiRouter.use('/catalog', await catalog(catalogEnv)); -+ apiRouter.use('/rollbar', await rollbar(rollbarEnv)); - apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); -``` - -The following values are read from the configuration file. - -```yaml -rollbar: - accountToken: ${ROLLBAR_ACCOUNT_TOKEN} -``` - -_NOTE: The `ROLLBAR_ACCOUNT_TOKEN` environment variable must be set to a read -access account token._ - -## Links - -- [Frontend part of the plugin](https://github.com/backstage/backstage/tree/master/plugins/rollbar) -- [The Backstage homepage](https://backstage.io) diff --git a/plugins/rollbar-backend/api-report.md b/plugins/rollbar-backend/api-report.md deleted file mode 100644 index 72499fbe58..0000000000 --- a/plugins/rollbar-backend/api-report.md +++ /dev/null @@ -1,226 +0,0 @@ -## API Report File for "@backstage/plugin-rollbar-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 (undocumented) -export function createRouter(options: RouterOptions): Promise; - -// @public (undocumented) -export function getRequestHeaders(token: string): { - headers: { - 'X-Rollbar-Access-Token': string; - }; -}; - -// @public (undocumented) -export class RollbarApi { - constructor(accessToken: string, logger: Logger); - // (undocumented) - getActivatedCounts( - projectName: string, - options?: { - environment: string; - item_id?: number; - }, - ): Promise; - // (undocumented) - getAllProjects(): Promise; - // (undocumented) - getOccuranceCounts( - projectName: string, - options?: { - environment: string; - item_id?: number; - }, - ): Promise; - // (undocumented) - getProject(projectName: string): Promise; - // (undocumented) - getProjectItems(projectName: string): Promise; - // (undocumented) - getTopActiveItems( - projectName: string, - options?: { - hours: number; - environment: string; - }, - ): Promise; -} - -// @public (undocumented) -export type RollbarEnvironment = 'production' | string; - -// @public (undocumented) -export enum RollbarFrameworkId { - // (undocumented) - 'browser-js' = 7, - // (undocumented) - 'node-js' = 4, - // (undocumented) - 'rollbar-system' = 8, - // (undocumented) - 'android' = 9, - // (undocumented) - 'celery' = 17, - // (undocumented) - 'django' = 2, - // (undocumented) - 'flask' = 16, - // (undocumented) - 'ios' = 10, - // (undocumented) - 'logentries' = 12, - // (undocumented) - 'mailgun' = 11, - // (undocumented) - 'php' = 6, - // (undocumented) - 'pylons' = 5, - // (undocumented) - 'pyramid' = 3, - // (undocumented) - 'python' = 13, - // (undocumented) - 'rails' = 1, - // (undocumented) - 'rq' = 18, - // (undocumented) - 'ruby' = 14, - // (undocumented) - 'sidekiq' = 15, - // (undocumented) - 'unknown' = 0, -} - -// @public (undocumented) -export type RollbarItem = { - publicItemId: number; - integrationsData: null; - levelLock: number; - controllingId: number; - lastActivatedTimestamp: number; - assignedUserId: number; - groupStatus: number; - hash: string; - id: number; - environment: RollbarEnvironment; - titleLock: number; - title: string; - lastOccurrenceId: number; - lastOccurrenceTimestamp: number; - platform: RollbarPlatformId; - firstOccurrenceTimestamp: number; - project_id: number; - resolvedInVersion: string; - status: 'enabled' | string; - uniqueOccurrences: number; - groupItemId: number; - framework: RollbarFrameworkId; - totalOccurrences: number; - level: RollbarLevel; - counter: number; - lastModifiedBy: number; - firstOccurrenceId: number; - activatingOccurrenceId: number; - lastResolvedTimestamp: number; -}; - -// @public (undocumented) -export type RollbarItemCount = { - timestamp: number; - count: number; -}; - -// @public (undocumented) -export type RollbarItemsResponse = { - items: RollbarItem[]; - page: number; - totalCount: number; -}; - -// @public (undocumented) -export enum RollbarLevel { - // (undocumented) - critical = 50, - // (undocumented) - debug = 10, - // (undocumented) - error = 40, - // (undocumented) - info = 20, - // (undocumented) - warning = 30, -} - -// @public (undocumented) -export enum RollbarPlatformId { - // (undocumented) - 'google-app-engine' = 6, - // (undocumented) - 'android' = 3, - // (undocumented) - 'browser' = 1, - // (undocumented) - 'client' = 7, - // (undocumented) - 'flash' = 2, - // (undocumented) - 'heroku' = 5, - // (undocumented) - 'ios' = 4, - // (undocumented) - 'unknown' = 0, -} - -// @public (undocumented) -export type RollbarProject = { - id: number; - name: string; - accountId: number; - status: 'enabled' | string; -}; - -// @public (undocumented) -export type RollbarProjectAccessToken = { - projectId: number; - name: string; - scopes: RollbarProjectAccessTokenScope[]; - accessToken: string; - status: 'enabled' | string; -}; - -// @public (undocumented) -export type RollbarProjectAccessTokenScope = 'read' | 'write'; - -// @public (undocumented) -export type RollbarTopActiveItem = { - item: { - id: number; - counter: number; - environment: RollbarEnvironment; - framework: RollbarFrameworkId; - lastOccurrenceTimestamp: number; - level: number; - occurrences: number; - projectId: number; - title: string; - uniqueOccurrences: number; - }; - counts: number[]; -}; - -// @public (undocumented) -export interface RouterOptions { - // (undocumented) - config: Config; - // (undocumented) - logger: Logger; - // (undocumented) - rollbarApi?: RollbarApi; -} -``` diff --git a/plugins/rollbar-backend/catalog-info.yaml b/plugins/rollbar-backend/catalog-info.yaml deleted file mode 100644 index 132695d53b..0000000000 --- a/plugins/rollbar-backend/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-rollbar-backend - title: '@backstage/plugin-rollbar-backend' - description: A Backstage backend plugin that integrates towards Rollbar -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: andrewthauer diff --git a/plugins/rollbar-backend/config.d.ts b/plugins/rollbar-backend/config.d.ts deleted file mode 100644 index dd32c16483..0000000000 --- a/plugins/rollbar-backend/config.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the rollbar-backend plugin */ - rollbar?: { - /** - * The authentication token for accessing the Rollbar API - * @see https://explorer.docs.rollbar.com/#section/Authentication - * @visibility secret - */ - accountToken: string; - }; -} diff --git a/plugins/rollbar-backend/knip-report.md b/plugins/rollbar-backend/knip-report.md deleted file mode 100644 index 6ae7c24404..0000000000 --- a/plugins/rollbar-backend/knip-report.md +++ /dev/null @@ -1,11 +0,0 @@ -# Knip report - -## Unused dependencies (4) - -| Name | Location | Severity | -| :---------- | :----------- | :------- | -| compression | package.json | error | -| fs-extra | package.json | error | -| morgan | package.json | error | -| cors | package.json | error | - diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json deleted file mode 100644 index 98106984d6..0000000000 --- a/plugins/rollbar-backend/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@backstage/plugin-rollbar-backend", - "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.55-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/rollbar-backend" - }, - "keywords": [ - "backstage", - "rollbar" - ], - "scripts": { - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/config": "workspace:^", - "@types/express": "^4.17.6", - "compression": "^1.7.4", - "cors": "^2.8.5", - "express": "^4.17.1", - "express-promise-router": "^4.1.0", - "fs-extra": "^11.2.0", - "lodash": "^4.17.21", - "morgan": "^1.10.0", - "node-fetch": "^2.6.7", - "winston": "^3.2.1", - "yn": "^4.0.0" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^", - "@types/supertest": "^2.0.8", - "msw": "^1.0.0", - "supertest": "^6.1.3" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/rollbar-backend/src/api/RollbarApi.test.ts b/plugins/rollbar-backend/src/api/RollbarApi.test.ts deleted file mode 100644 index 25bd931af6..0000000000 --- a/plugins/rollbar-backend/src/api/RollbarApi.test.ts +++ /dev/null @@ -1,75 +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 { getRequestHeaders, RollbarApi } from './RollbarApi'; -import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { getVoidLogger } from '@backstage/backend-common'; - -describe('RollbarApi', () => { - describe('getRequestHeaders', () => { - it('should generate headers based on token passed in constructor', () => { - expect(getRequestHeaders('testtoken')).toEqual({ - headers: { - 'X-Rollbar-Access-Token': `testtoken`, - }, - }); - }); - }); - - describe('getAllProjects', () => { - const server = setupServer(); - setupRequestMockHandlers(server); - - const mockBaseUrl = 'https://api.rollbar.com/api/1'; - - const mockProjects = [ - { id: 123, name: 'abc', account_id: 1, status: 'enabled' }, - { - id: 456, - name: 'xyz', - account_id: 1, - status: 'enabled', - extra_nested: { nested_value: [{ value_here: 'hello_world' }] }, - }, - ]; - - const setupHandlers = () => { - server.use( - rest.get(`${mockBaseUrl}/projects`, (_, res, ctx) => { - return res(ctx.json({ result: mockProjects })); - }), - ); - }; - - it('should return all projects with a name attribute', async () => { - setupHandlers(); - const api = new RollbarApi('my-access-token', getVoidLogger()); - const projects = await api.getAllProjects(); - expect(projects).toEqual([ - { id: 123, name: 'abc', accountId: 1, status: 'enabled' }, - { - id: 456, - name: 'xyz', - accountId: 1, - status: 'enabled', - extraNested: { nestedValue: [{ valueHere: 'hello_world' }] }, - }, - ]); - }); - }); -}); diff --git a/plugins/rollbar-backend/src/api/RollbarApi.ts b/plugins/rollbar-backend/src/api/RollbarApi.ts deleted file mode 100644 index 98dbc19119..0000000000 --- a/plugins/rollbar-backend/src/api/RollbarApi.ts +++ /dev/null @@ -1,201 +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 { Logger } from 'winston'; -import { camelCase } from 'lodash'; -import { buildQuery } from '../util'; -import { - RollbarItemCount, - RollbarItemsResponse, - RollbarProject, - RollbarProjectAccessToken, - RollbarTopActiveItem, -} from './types'; -import fetch from 'node-fetch'; - -const baseUrl = 'https://api.rollbar.com/api/1'; - -const buildUrl = (url: string) => `${baseUrl}${url}`; - -function camelize(val: T): T { - if (Array.isArray(val)) { - return val.map(camelize) as T; - } - if (val && typeof val === 'object') { - return Object.fromEntries( - Object.entries(val).map(([k, v]) => [camelCase(k), camelize(v)]), - ) as T; - } - return val; -} - -/** @public */ -export class RollbarApi { - private projectMap: ProjectMetadataMap | undefined; - - constructor( - private readonly accessToken: string, - private readonly logger: Logger, - ) {} - - async getAllProjects() { - return this.get('/projects').then(projects => - projects.filter(p => p.name), - ); - } - - async getProject(projectName: string) { - return this.getForProject( - `/project/:projectId`, - projectName, - false, - ); - } - - async getProjectItems(projectName: string) { - return this.getForProject( - `/items`, - projectName, - true, - ); - } - - async getTopActiveItems( - projectName: string, - options: { hours: number; environment: string } = { - hours: 24, - environment: 'production', - }, - ) { - return this.getForProject( - `/reports/top_active_items?${buildQuery(options)}`, - projectName, - ); - } - - async getOccuranceCounts( - projectName: string, - options: { environment: string; item_id?: number } = { - environment: 'production', - }, - ) { - return this.getForProject( - `/reports/occurrence_counts?${buildQuery(options as any)}`, - projectName, - ); - } - - async getActivatedCounts( - projectName: string, - options: { environment: string; item_id?: number } = { - environment: 'production', - }, - ) { - return this.getForProject( - `/reports/activated_counts?${buildQuery(options as any)}`, - projectName, - ); - } - - private async getProjectAccessTokens(projectId: number) { - return this.get( - `/project/${projectId}/access_tokens`, - ); - } - - private async get( - url: string, - accessToken?: string, - ): Promise { - const fullUrl = buildUrl(url); - - if (this.logger) { - this.logger.info(`Calling Rollbar REST API, ${fullUrl}`); - } - - const res = await fetch( - fullUrl, - getRequestHeaders(accessToken || this.accessToken || ''), - ); - const data = await res.json(); - return camelize(data?.result) as T; - } - - private async getForProject( - url: string, - projectName: string, - useProjectToken = true, - ) { - const project = await this.getProjectMetadata(projectName); - const resolvedUrl = url.replace(':projectId', project.id.toString()); - return this.get(resolvedUrl, useProjectToken ? project.accessToken : ''); - } - - private async getProjectMetadata(name: string) { - const projectMap = await this.getProjectMap(); - const project = projectMap[name]; - - if (!project) { - throw Error(`Invalid project: '${name}'`); - } - - if (!project.accessToken) { - const tokens = await this.getProjectAccessTokens(project.id); - const token = tokens.find(t => t.scopes.includes('read')); - project.accessToken = token ? token.accessToken : undefined; - } - - if (!project.accessToken) { - throw Error(`Could not find project read access token for '${name}'`); - } - - return project; - } - - private async getProjectMap() { - if (this.projectMap) { - return this.projectMap; - } - - const projects = await this.getAllProjects(); - - this.projectMap = projects.reduce((accum: ProjectMetadataMap, i) => { - accum[i.name] = { id: i.id, name: i.name }; - return accum; - }, {}); - - return this.projectMap; - } -} - -/** @public */ -export function getRequestHeaders(token: string) { - return { - headers: { - 'X-Rollbar-Access-Token': `${token}`, - }, - }; -} - -type ProjectMetadata = { - name: string; - id: number; - accessToken?: string | undefined; -}; - -interface ProjectMetadataMap { - [name: string]: ProjectMetadata; -} diff --git a/plugins/rollbar-backend/src/api/index.ts b/plugins/rollbar-backend/src/api/index.ts deleted file mode 100644 index 08d6c4b061..0000000000 --- a/plugins/rollbar-backend/src/api/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { getRequestHeaders, RollbarApi } from './RollbarApi'; -export * from './types'; diff --git a/plugins/rollbar-backend/src/api/types.ts b/plugins/rollbar-backend/src/api/types.ts deleted file mode 100644 index a1a6202656..0000000000 --- a/plugins/rollbar-backend/src/api/types.ts +++ /dev/null @@ -1,147 +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. - */ - -// TODO: Make this re-usable with backend - -/** @public */ -export type RollbarProjectAccessTokenScope = 'read' | 'write'; - -/** @public */ -export type RollbarEnvironment = 'production' | string; - -/** @public */ -export enum RollbarLevel { - debug = 10, - info = 20, - warning = 30, - error = 40, - critical = 50, -} - -/** @public */ -export enum RollbarFrameworkId { - 'unknown' = 0, - 'rails' = 1, - 'django' = 2, - 'pyramid' = 3, - 'node-js' = 4, - 'pylons' = 5, - 'php' = 6, - 'browser-js' = 7, - 'rollbar-system' = 8, - 'android' = 9, - 'ios' = 10, - 'mailgun' = 11, - 'logentries' = 12, - 'python' = 13, - 'ruby' = 14, - 'sidekiq' = 15, - 'flask' = 16, - 'celery' = 17, - 'rq' = 18, -} - -/** @public */ -export enum RollbarPlatformId { - 'unknown' = 0, - 'browser' = 1, - 'flash' = 2, - 'android' = 3, - 'ios' = 4, - 'heroku' = 5, - 'google-app-engine' = 6, - 'client' = 7, -} - -/** @public */ -export type RollbarProject = { - id: number; - name: string; - accountId: number; - status: 'enabled' | string; -}; - -/** @public */ -export type RollbarProjectAccessToken = { - projectId: number; - name: string; - scopes: RollbarProjectAccessTokenScope[]; - accessToken: string; - status: 'enabled' | string; -}; - -/** @public */ -export type RollbarItem = { - publicItemId: number; - integrationsData: null; - levelLock: number; - controllingId: number; - lastActivatedTimestamp: number; - assignedUserId: number; - groupStatus: number; - hash: string; - id: number; - environment: RollbarEnvironment; - titleLock: number; - title: string; - lastOccurrenceId: number; - lastOccurrenceTimestamp: number; - platform: RollbarPlatformId; - firstOccurrenceTimestamp: number; - project_id: number; - resolvedInVersion: string; - status: 'enabled' | string; - uniqueOccurrences: number; - groupItemId: number; - framework: RollbarFrameworkId; - totalOccurrences: number; - level: RollbarLevel; - counter: number; - lastModifiedBy: number; - firstOccurrenceId: number; - activatingOccurrenceId: number; - lastResolvedTimestamp: number; -}; - -/** @public */ -export type RollbarItemsResponse = { - items: RollbarItem[]; - page: number; - totalCount: number; -}; - -/** @public */ -export type RollbarItemCount = { - timestamp: number; - count: number; -}; - -/** @public */ -export type RollbarTopActiveItem = { - item: { - id: number; - counter: number; - environment: RollbarEnvironment; - framework: RollbarFrameworkId; - lastOccurrenceTimestamp: number; - level: number; - occurrences: number; - projectId: number; - title: string; - uniqueOccurrences: number; - }; - counts: number[]; -}; diff --git a/plugins/rollbar-backend/src/index.ts b/plugins/rollbar-backend/src/index.ts deleted file mode 100644 index 883ae8034d..0000000000 --- a/plugins/rollbar-backend/src/index.ts +++ /dev/null @@ -1,24 +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. - */ - -/** - * A Backstage backend plugin that integrates towards Rollbar - * - * @packageDocumentation - */ - -export * from './api'; -export * from './service/router'; diff --git a/plugins/rollbar-backend/src/run.ts b/plugins/rollbar-backend/src/run.ts deleted file mode 100644 index 0a3ed2b7f0..0000000000 --- a/plugins/rollbar-backend/src/run.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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/rollbar-backend/src/service/router.test.ts b/plugins/rollbar-backend/src/service/router.test.ts deleted file mode 100644 index 2e6c8a663a..0000000000 --- a/plugins/rollbar-backend/src/service/router.test.ts +++ /dev/null @@ -1,124 +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 { getVoidLogger } from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import express from 'express'; -import request from 'supertest'; -import { RollbarApi } from '../api'; -import { createRouter } from './router'; -import { RollbarProject, RollbarTopActiveItem } from '../api/types'; - -describe('createRouter', () => { - let rollbarApi: jest.Mocked; - let app: express.Express; - - beforeAll(async () => { - rollbarApi = { - getAllProjects: jest.fn(), - getProject: jest.fn(), - getProjectItems: jest.fn(), - getTopActiveItems: jest.fn(), - getOccuranceCounts: jest.fn(), - getActivatedCounts: jest.fn(), - } as any; - const router = await createRouter({ - rollbarApi, - logger: getVoidLogger(), - config: new ConfigReader({ rollbar: { accountToken: 'foo' } }), - }); - app = express().use(router); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('GET /projects', () => { - it('lists projects', async () => { - const projects: RollbarProject[] = [ - { id: 123, name: 'abc', accountId: 1, status: 'enabled' }, - { id: 456, name: 'xyz', accountId: 1, status: 'enabled' }, - ]; - - rollbarApi.getAllProjects.mockResolvedValueOnce(projects); - - const response = await request(app).get('/projects'); - - expect(response.status).toEqual(200); - expect(response.body).toEqual(projects); - }); - - it('throws an error', async () => { - rollbarApi.getAllProjects.mockImplementationOnce(() => { - throw Error('error'); - }); - - const response = await request(app).get('/projects'); - - expect(response.status).toEqual(500); - }); - }); - - describe('GET /projects/:id', () => { - it('fetches a single project', async () => { - const project: RollbarProject = { - id: 123, - name: 'abc', - accountId: 1, - status: 'enabled', - }; - - rollbarApi.getProject.mockResolvedValueOnce(project); - - const response = await request(app).get(`/projects/${123}`); - - expect(response.status).toEqual(200); - expect(response.body).toEqual(project); - }); - }); - - describe('GET /projects/:id/top_active_items', () => { - it('fetches a single project', async () => { - const items: RollbarTopActiveItem[] = [ - { - item: { - id: 9898989, - counter: 1234, - environment: 'production', - framework: 2, - lastOccurrenceTimestamp: new Date().getTime() / 1000, - level: 50, - occurrences: 100, - projectId: 12345, - title: 'error occurred', - uniqueOccurrences: 10, - }, - counts: [10, 10, 10, 10, 10, 50], - }, - ]; - - rollbarApi.getTopActiveItems.mockResolvedValueOnce(items); - - const response = await request(app).get( - `/projects/${123}/top_active_items`, - ); - - expect(response.status).toEqual(200); - expect(response.body).toEqual(items); - }); - }); -}); diff --git a/plugins/rollbar-backend/src/service/router.ts b/plugins/rollbar-backend/src/service/router.ts deleted file mode 100644 index 36ae5581a5..0000000000 --- a/plugins/rollbar-backend/src/service/router.ts +++ /dev/null @@ -1,111 +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 express from 'express'; -import Router from 'express-promise-router'; -import { Logger } from 'winston'; -import { errorHandler } from '@backstage/backend-common'; -import { Config } from '@backstage/config'; -import { RollbarApi } from '../api'; - -/** @public */ -export interface RouterOptions { - rollbarApi?: RollbarApi; - logger: Logger; - config: Config; -} - -/** @public */ -export async function createRouter( - options: RouterOptions, -): Promise { - const router = Router(); - - const logger = options.logger.child({ plugin: 'rollbar' }); - const config = options.config.getConfig('rollbar'); - const accessToken = !options.rollbarApi - ? getRollbarAccountToken(config, logger) - : ''; - - if (options.rollbarApi || accessToken) { - const rollbarApi = - options.rollbarApi || new RollbarApi(accessToken, logger); - - router.use(express.json()); - - router.get('/projects', async (_req, res) => { - const projects = await rollbarApi.getAllProjects(); - res.status(200).json(projects); - }); - - router.get('/projects/:id', async (req, res) => { - const { id } = req.params; - const projects = await rollbarApi.getProject(id); - res.status(200).json(projects); - }); - - router.get('/projects/:id/items', async (req, res) => { - const { id } = req.params; - const projects = await rollbarApi.getProjectItems(id); - res.status(200).json(projects); - }); - - router.get('/projects/:id/top_active_items', async (req, res) => { - const { id } = req.params; - const query = req.query; - const items = await rollbarApi.getTopActiveItems(id, query as any); - res.status(200).json(items); - }); - - router.get('/projects/:id/occurance_counts', async (req, res) => { - const { id } = req.params; - const query = req.query; - const items = await rollbarApi.getOccuranceCounts(id, query as any); - res.status(200).json(items); - }); - - router.get('/projects/:id/activated_item_counts', async (req, res) => { - const { id } = req.params; - const query = req.query; - const items = await rollbarApi.getActivatedCounts(id, query as any); - res.status(200).json(items); - }); - } - - router.use(errorHandler()); - - return router; -} - -function getRollbarAccountToken(config: Config, logger: Logger) { - const token = - config.getOptionalString('accountToken') || - process.env.ROLLBAR_ACCOUNT_TOKEN || - ''; - - if (!token) { - if (process.env.NODE_ENV !== 'development') { - throw new Error( - 'The rollbar.accountToken must be provided in config to start the API.', - ); - } - logger.warn( - 'Failed to initialize rollbar backend, set rollbar.accountToken in config to start the API.', - ); - } - - return token; -} diff --git a/plugins/rollbar-backend/src/service/standaloneServer.ts b/plugins/rollbar-backend/src/service/standaloneServer.ts deleted file mode 100644 index 4b6539823f..0000000000 --- a/plugins/rollbar-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,52 +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 { Server } from 'http'; -import { Logger } from 'winston'; -import { - createServiceBuilder, - loadBackendConfig, -} from '@backstage/backend-common'; -import { createRouter } from './router'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'rollbar-backend' }); - const config = await loadBackendConfig({ logger, argv: process.argv }); - - logger.debug('Creating application...'); - - const router = await createRouter({ logger, config }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/catalog', router); - if (options.enableCors) { - service = service.enableCors({ origin: 'http://localhost:3000' }); - } - - return await service.start().catch(err => { - logger.error(err); - process.exit(1); - }); -} diff --git a/plugins/rollbar-backend/src/setupTests.ts b/plugins/rollbar-backend/src/setupTests.ts deleted file mode 100644 index d3232290a7..0000000000 --- a/plugins/rollbar-backend/src/setupTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export {}; diff --git a/plugins/rollbar-backend/src/util/index.ts b/plugins/rollbar-backend/src/util/index.ts deleted file mode 100644 index 317ae8cc60..0000000000 --- a/plugins/rollbar-backend/src/util/index.ts +++ /dev/null @@ -1,25 +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. - */ - -interface PrimitiveMap { - [name: string]: number | string | boolean; -} - -export const buildQuery = (obj: PrimitiveMap) => { - return Object.entries(obj) - .map(pair => pair.map(encodeURIComponent).join('=')) - .join('&'); -}; diff --git a/plugins/rollbar/.eslintrc.js b/plugins/rollbar/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/rollbar/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md deleted file mode 100644 index ab71b89dcc..0000000000 --- a/plugins/rollbar/CHANGELOG.md +++ /dev/null @@ -1,1612 +0,0 @@ -# @backstage/plugin-rollbar - -## 0.4.30-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.4.30-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.4.30-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - -## 0.4.30-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - -## 0.4.29 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - -## 0.4.29-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.4.29-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - -## 0.4.29-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - -## 0.4.28 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - -## 0.4.28-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.4.28-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.4.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.5.0-next.0 - -## 0.4.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.4.26 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - -## 0.4.26-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.4.26-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.4.26-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.4.25 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.4.3 - -## 0.4.25-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/theme@0.4.3-next.0 - -## 0.4.25-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.4.25-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.4.24 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.4.24-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.4.24-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/theme@0.4.1 - -## 0.4.24-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.4.23-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.4.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.4.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.4.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.4.20 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.4.20-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - -## 0.4.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.4.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.4.19 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - -## 0.4.19-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.4.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.4.19-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.4.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.4.18 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.4.18-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.4.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.4.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/theme@0.2.19 - -## 0.4.17 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.4.17-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.4.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.19-next.0 - -## 0.4.17-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - -## 0.4.17-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.4.16 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.4.16-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.4.16-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.4.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - -## 0.4.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - -## 0.4.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.4.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.4.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.4.14 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.4.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - -## 0.4.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.4.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - -## 0.4.13 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.4.12 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.4.12-next.4 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.4.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.4.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.4.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.4.12-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.4.11 - -### Patch Changes - -- f905853ad6: Prefer using `Link` from `@backstage/core-components` rather than material-UI. -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/theme@0.2.16 - -## 0.4.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.4.11-next.0 - -### Patch Changes - -- f905853ad6: Prefer using `Link` from `@backstage/core-components` rather than material-UI. -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.4.10 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - -## 0.4.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - -## 0.4.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.4.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - -## 0.4.9 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - -## 0.4.9-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.4.9-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.4.9-next.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.4.9-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -## 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 - -## 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 - -## 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 - -## 0.4.7-next.3 - -### Patch Changes - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.4.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.4.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.4.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.4.6 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.4.6-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.4.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.4.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.4.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.4.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.4.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.4.4 - -### Patch Changes - -- 7c7919777e: build(deps-dev): bump `@testing-library/react-hooks` from 7.0.2 to 8.0.0 -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.4.4-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.4.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.4.3 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - -## 0.4.2 - -### Patch Changes - -- 9844d4d2bd: Removed usage of removed hook. -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.4.2-next.0 - -### Patch Changes - -- 9844d4d2bd: Removed usage of removed hook. -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.4.1 - -### Patch Changes - -- 899f196af5: Use `getEntityByRef` instead of `getEntityByName` in the catalog client -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.4.0 - -### Minor Changes - -- 2262fe19c9: **BREAKING**: Removed support for passing in an explicit `entity` prop to entity page extensions, which has been deprecated for a long time. This is only a breaking change at the TypeScript level, as this property was already ignored. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.3.27 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - -## 0.3.26 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.3.26-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.3.25 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.3.25-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.3.24 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.3.24-next.0 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.3.23 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/catalog-model@0.9.9 - -## 0.3.22 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.3.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.3.20 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.3.19 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/catalog-model@0.9.7 - - @backstage/plugin-catalog-react@0.6.4 - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.3.18 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.0 - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.3.17 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - - @backstage/plugin-catalog-react@0.5.2 - - @backstage/catalog-model@0.9.4 - -## 0.3.16 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - - @backstage/plugin-catalog-react@0.5.1 - -## 0.3.15 - -### Patch Changes - -- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/plugin-catalog-react@0.5.0 - - @backstage/catalog-model@0.9.3 - -## 0.3.14 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/plugin-catalog-react@0.4.6 - - @backstage/core-plugin-api@0.1.8 - -## 0.3.13 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.5 - - @backstage/core-components@0.4.0 - - @backstage/catalog-model@0.9.1 - -## 0.3.12 - -### Patch Changes - -- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - - @backstage/plugin-catalog-react@0.4.2 - -## 0.3.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - - @backstage/plugin-catalog-react@0.4.1 - -## 0.3.10 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/plugin-catalog-react@0.4.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.3.9 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.3.0 - -## 0.3.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.1.5 - - @backstage/catalog-model@0.9.0 - - @backstage/plugin-catalog-react@0.2.6 - -## 0.3.7 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - - @backstage/catalog-model@0.8.4 - - @backstage/plugin-catalog-react@0.2.4 - -## 0.3.6 - -### Patch Changes - -- Updated dependencies [add62a455] -- Updated dependencies [cc592248b] -- Updated dependencies [17c497b81] -- Updated dependencies [704875e26] - - @backstage/catalog-model@0.8.0 - - @backstage/core@0.7.11 - - @backstage/plugin-catalog-react@0.2.0 - -## 0.3.5 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [10c008a3a] -- Updated dependencies [889d89b6e] -- Updated dependencies [16be1d093] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - - @backstage/plugin-catalog-react@0.1.6 - - @backstage/catalog-model@0.7.9 - -## 0.3.4 - -### Patch Changes - -- c614ede9a: Updated README to have up-to-date install instructions. -- Updated dependencies [9afcac5af] -- Updated dependencies [e0c9ed759] -- Updated dependencies [6eaecbd81] - - @backstage/core@0.7.7 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies [12d8f27a6] -- Updated dependencies [40c0fdbaa] -- Updated dependencies [2a271d89e] -- Updated dependencies [bece09057] -- Updated dependencies [169f48deb] -- Updated dependencies [8a1566719] -- Updated dependencies [9d455f69a] -- Updated dependencies [4c049a1a1] -- Updated dependencies [02816ecd7] - - @backstage/catalog-model@0.7.3 - - @backstage/core@0.7.0 - - @backstage/plugin-catalog-react@0.1.1 - -## 0.3.2 - -### Patch Changes - -- Updated dependencies [3a58084b6] -- Updated dependencies [e799e74d4] -- Updated dependencies [d0760ecdf] -- Updated dependencies [1407b34c6] -- Updated dependencies [88f1f1b60] -- Updated dependencies [bad21a085] -- Updated dependencies [9615e68fb] -- Updated dependencies [49f9b7346] -- Updated dependencies [5c2e2863f] -- Updated dependencies [3a58084b6] -- Updated dependencies [2c1f2a7c2] - - @backstage/core@0.6.3 - - @backstage/plugin-catalog-react@0.1.0 - - @backstage/catalog-model@0.7.2 - -## 0.3.1 - -### Patch Changes - -- Updated dependencies [fd3f2a8c0] -- Updated dependencies [d34d26125] -- Updated dependencies [0af242b6d] -- Updated dependencies [f4c2bcf54] -- Updated dependencies [10a0124e0] -- Updated dependencies [07e226872] -- Updated dependencies [f62e7abe5] -- Updated dependencies [96f378d10] -- Updated dependencies [688b73110] - - @backstage/core@0.6.2 - - @backstage/plugin-catalog-react@0.0.4 - -## 0.3.0 - -### Minor Changes - -- 6ed2b47d6: Include Backstage identity token in requests to backend plugins. - -### Patch Changes - -- Updated dependencies [19d354c78] -- Updated dependencies [b51ee6ece] - - @backstage/plugin-catalog-react@0.0.3 - - @backstage/core@0.6.1 - -## 0.2.9 - -### Patch Changes - -- 9d6ef14bc: Migrated to new composability API, exporting the plugin instance as `rollbarPlugin`, the entity page content as `EntityRollbarContent`, and entity conditional as `isRollbarAvailable`. Updated the `EntityPage` for the `example-app` to include a composite `ErrorsSwitcher` component that works with both `Sentry` & `Rollbar`. Also removed the unused and undocumented `RollbarHome` related components. -- 019fe39a0: Switch dependency from `@backstage/plugin-catalog` to `@backstage/plugin-catalog-react`. -- Updated dependencies [12ece98cd] -- Updated dependencies [d82246867] -- Updated dependencies [7fc89bae2] -- Updated dependencies [c810082ae] -- Updated dependencies [5fa3bdb55] -- Updated dependencies [6e612ce25] -- Updated dependencies [025e122c3] -- Updated dependencies [21e624ba9] -- Updated dependencies [da9f53c60] -- Updated dependencies [32c95605f] -- Updated dependencies [7881f2117] -- Updated dependencies [54c7d02f7] -- Updated dependencies [11cb5ef94] - - @backstage/core@0.6.0 - - @backstage/plugin-catalog-react@0.0.2 - - @backstage/theme@0.2.3 - - @backstage/catalog-model@0.7.1 - -## 0.2.8 - -### Patch Changes - -- Updated dependencies [def2307f3] -- Updated dependencies [efd6ef753] -- Updated dependencies [593632f07] -- Updated dependencies [33846acfc] -- Updated dependencies [a187b8ad0] -- Updated dependencies [f04db53d7] -- Updated dependencies [a93f42213] - - @backstage/catalog-model@0.7.0 - - @backstage/core@0.5.0 - - @backstage/plugin-catalog@0.2.12 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies [c911061b7] -- Updated dependencies [8ef71ed32] -- Updated dependencies [0e6298f7e] -- Updated dependencies [ac3560b42] - - @backstage/catalog-model@0.6.0 - - @backstage/core@0.4.1 - - @backstage/plugin-catalog@0.2.7 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies [2527628e1] -- Updated dependencies [6011b7d3e] -- Updated dependencies [1c69d4716] -- Updated dependencies [83b6e0c1f] -- Updated dependencies [1665ae8bb] -- Updated dependencies [04f26f88d] -- Updated dependencies [ff243ce96] - - @backstage/core@0.4.0 - - @backstage/plugin-catalog@0.2.6 - - @backstage/catalog-model@0.5.0 - - @backstage/theme@0.2.2 - -## 0.2.5 - -### Patch Changes - -- Updated dependencies [08835a61d] -- Updated dependencies [a9fd599f7] -- Updated dependencies [bcc211a08] -- Updated dependencies [ebf37bbae] - - @backstage/catalog-model@0.4.0 - - @backstage/plugin-catalog@0.2.5 - -## 0.2.4 - -### Patch Changes - -- 3a201c5d5: Add config schema for the rollbar & rollbar-backend plugins -- Updated dependencies [6f70ed7a9] -- Updated dependencies [ab94c9542] -- Updated dependencies [2daf18e80] -- Updated dependencies [069cda35f] - - @backstage/plugin-catalog@0.2.4 - - @backstage/catalog-model@0.3.1 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies [475fc0aaa] -- Updated dependencies [1166fcc36] -- Updated dependencies [1185919f3] - - @backstage/core@0.3.2 - - @backstage/catalog-model@0.3.0 - - @backstage/plugin-catalog@0.2.3 - -## 0.2.2 - -### Patch Changes - -- 1722cb53c: Added configuration schema -- Updated dependencies [1722cb53c] -- Updated dependencies [8b7737d0b] - - @backstage/core@0.3.1 - - @backstage/plugin-catalog@0.2.2 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [7b37d65fd] -- Updated dependencies [4aca74e08] -- Updated dependencies [e8f69ba93] -- Updated dependencies [0c0798f08] -- Updated dependencies [0c0798f08] -- Updated dependencies [199237d2f] -- Updated dependencies [6627b626f] -- Updated dependencies [4577e377b] -- Updated dependencies [2d0bd1be7] - - @backstage/core@0.3.0 - - @backstage/theme@0.2.1 - - @backstage/plugin-catalog@0.2.1 - -## 0.2.0 - -### Minor Changes - -- 28edd7d29: Create backend plugin through CLI - -### Patch Changes - -- Updated dependencies [28edd7d29] -- Updated dependencies [819a70229] -- Updated dependencies [3a4236570] -- Updated dependencies [ae5983387] -- Updated dependencies [0d4459c08] -- Updated dependencies [482b6313d] -- Updated dependencies [e0be86b6f] -- Updated dependencies [f70a52868] -- Updated dependencies [12b5fe940] -- Updated dependencies [368fd8243] -- Updated dependencies [1c60f716e] -- Updated dependencies [144c66d50] -- Updated dependencies [a768a07fb] -- Updated dependencies [b79017fd3] -- Updated dependencies [6d97d2d6f] -- Updated dependencies [5adfc005e] -- Updated dependencies [f0aa01bcc] -- Updated dependencies [0aecfded0] -- Updated dependencies [93a3fa3ae] -- Updated dependencies [782f3b354] -- Updated dependencies [8b9c8196f] -- Updated dependencies [2713f28f4] -- Updated dependencies [406015b0d] -- Updated dependencies [82759d3e4] -- Updated dependencies [60d40892c] -- Updated dependencies [ac8d5d5c7] -- Updated dependencies [2ebcfac8d] -- Updated dependencies [fa56f4615] -- Updated dependencies [ebca83d48] -- Updated dependencies [aca79334f] -- Updated dependencies [c0d5242a0] -- Updated dependencies [b3d57961c] -- Updated dependencies [0b956f21b] -- Updated dependencies [97c2cb19b] -- Updated dependencies [3beb5c9fc] -- Updated dependencies [754e31db5] -- Updated dependencies [1611c6dbc] - - @backstage/plugin-catalog@0.2.0 - - @backstage/core@0.2.0 - - @backstage/catalog-model@0.2.0 - - @backstage/theme@0.2.0 diff --git a/plugins/rollbar/README.md b/plugins/rollbar/README.md deleted file mode 100644 index 2b1fb7e40d..0000000000 --- a/plugins/rollbar/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Rollbar Plugin - -Website: [https://rollbar.com/](https://rollbar.com/) - -## Setup - -1. Configure the [rollbar backend plugin](https://github.com/backstage/backstage/tree/master/plugins/rollbar-backend/README.md) - -2. If you have standalone app (you didn't clone this repo), then do - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-rollbar -``` - -3. Add to the app `EntityPage` component: - -```tsx -// In packages/app/src/components/catalog/EntityPage.tsx -import { EntityRollbarContent } from '@backstage/plugin-rollbar'; - -const serviceEntityPage = ( - - {/* other tabs... */} - - - -``` - -4. Setup the `app-config.yaml` and account token environment variable - -```yaml -# app.config.yaml -rollbar: - organization: organization-name - # used by rollbar-backend - accountToken: ${ROLLBAR_ACCOUNT_TOKEN} -``` - -5. Annotate entities with the rollbar project slug - -```yaml -# pump-station-catalog-component.yaml -# ... -metadata: - annotations: - rollbar.com/project-slug: organization-name/project-name - # -- or just --- - rollbar.com/project-slug: project-name -``` - -6. Run app with `yarn start` and navigate to `/rollbar` or a catalog entity - -## Features - -- List rollbar entities that are annotated with `rollbar.com/project-slug` -- View top active items for each rollbar annotated entity - -## Limitations - -- Rollbar has rate limits per token - -## Links - -- [Backend part of the plugin](https://github.com/backstage/backstage/tree/master/plugins/rollbar-backend) -- [The Backstage homepage](https://backstage.io) diff --git a/plugins/rollbar/api-report.md b/plugins/rollbar/api-report.md deleted file mode 100644 index c59475466f..0000000000 --- a/plugins/rollbar/api-report.md +++ /dev/null @@ -1,243 +0,0 @@ -## API Report File for "@backstage/plugin-rollbar" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { JSX as JSX_2 } from 'react'; -import { default as React_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export const EntityPageRollbar: () => React_2.JSX.Element; - -// @public (undocumented) -export const EntityRollbarContent: () => JSX_2.Element; - -// @public (undocumented) -const isPluginApplicableToEntity: (entity: Entity) => boolean; -export { isPluginApplicableToEntity }; -export { isPluginApplicableToEntity as isRollbarAvailable }; - -// @public (undocumented) -export const ROLLBAR_ANNOTATION = 'rollbar.com/project-slug'; - -// @public (undocumented) -export interface RollbarApi { - // (undocumented) - getAllProjects(): Promise; - // (undocumented) - getProject(projectName: string): Promise; - // (undocumented) - getProjectItems(project: string): Promise; - // (undocumented) - getTopActiveItems( - project: string, - hours?: number, - ): Promise; -} - -// @public (undocumented) -export const rollbarApiRef: ApiRef; - -// @public (undocumented) -export class RollbarClient implements RollbarApi { - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }); - // (undocumented) - getAllProjects(): Promise; - // (undocumented) - getProject(projectName: string): Promise; - // (undocumented) - getProjectItems(project: string): Promise; - // (undocumented) - getTopActiveItems( - project: string, - hours?: number, - environment?: string, - ): Promise; -} - -// @public (undocumented) -export type RollbarEnvironment = 'production' | string; - -// @public (undocumented) -export enum RollbarFrameworkId { - // (undocumented) - 'browser-js' = 7, - // (undocumented) - 'node-js' = 4, - // (undocumented) - 'rollbar-system' = 8, - // (undocumented) - 'android' = 9, - // (undocumented) - 'celery' = 17, - // (undocumented) - 'django' = 2, - // (undocumented) - 'flask' = 16, - // (undocumented) - 'ios' = 10, - // (undocumented) - 'logentries' = 12, - // (undocumented) - 'mailgun' = 11, - // (undocumented) - 'php' = 6, - // (undocumented) - 'pylons' = 5, - // (undocumented) - 'pyramid' = 3, - // (undocumented) - 'python' = 13, - // (undocumented) - 'rails' = 1, - // (undocumented) - 'rq' = 18, - // (undocumented) - 'ruby' = 14, - // (undocumented) - 'sidekiq' = 15, - // (undocumented) - 'unknown' = 0, -} - -// @public (undocumented) -export type RollbarItem = { - publicItemId: number; - integrationsData: null; - levelLock: number; - controllingId: number; - lastActivatedTimestamp: number; - assignedUserId: number; - groupStatus: number; - hash: string; - id: number; - environment: RollbarEnvironment; - titleLock: number; - title: string; - lastOccurrenceId: number; - lastOccurrenceTimestamp: number; - platform: RollbarPlatformId; - firstOccurrenceTimestamp: number; - project_id: number; - resolvedInVersion: string; - status: 'enabled' | string; - uniqueOccurrences: number; - groupItemId: number; - framework: RollbarFrameworkId; - totalOccurrences: number; - level: RollbarLevel; - counter: number; - lastModifiedBy: number; - firstOccurrenceId: number; - activatingOccurrenceId: number; - lastResolvedTimestamp: number; -}; - -// @public (undocumented) -export type RollbarItemCount = { - timestamp: number; - count: number; -}; - -// @public (undocumented) -export type RollbarItemsResponse = { - items: RollbarItem[]; - page: number; - totalCount: number; -}; - -// @public (undocumented) -export enum RollbarLevel { - // (undocumented) - critical = 50, - // (undocumented) - debug = 10, - // (undocumented) - error = 40, - // (undocumented) - info = 20, - // (undocumented) - warning = 30, -} - -// @public (undocumented) -export enum RollbarPlatformId { - // (undocumented) - 'google-app-engine' = 6, - // (undocumented) - 'android' = 3, - // (undocumented) - 'browser' = 1, - // (undocumented) - 'client' = 7, - // (undocumented) - 'flash' = 2, - // (undocumented) - 'heroku' = 5, - // (undocumented) - 'ios' = 4, - // (undocumented) - 'unknown' = 0, -} - -// @public (undocumented) -const rollbarPlugin: BackstagePlugin< - { - entityContent: RouteRef; - }, - {} ->; -export { rollbarPlugin as plugin }; -export { rollbarPlugin }; - -// @public (undocumented) -export type RollbarProject = { - id: number; - name: string; - accountId: number; - status: 'enabled' | string; -}; - -// @public (undocumented) -export type RollbarProjectAccessToken = { - projectId: number; - name: string; - scopes: RollbarProjectAccessTokenScope[]; - accessToken: string; - status: 'enabled' | string; -}; - -// @public (undocumented) -export type RollbarProjectAccessTokenScope = 'read' | 'write'; - -// @public (undocumented) -export type RollbarTopActiveItem = { - item: { - id: number; - counter: number; - environment: RollbarEnvironment; - framework: RollbarFrameworkId; - lastOccurrenceTimestamp: number; - level: number; - occurrences: number; - projectId: number; - title: string; - uniqueOccurrences: number; - }; - counts: number[]; -}; - -// @public (undocumented) -export const Router: () => React_2.JSX.Element; -``` diff --git a/plugins/rollbar/catalog-info.yaml b/plugins/rollbar/catalog-info.yaml deleted file mode 100644 index bc3f88019b..0000000000 --- a/plugins/rollbar/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-rollbar - title: '@backstage/plugin-rollbar' - description: A Backstage plugin that integrates towards Rollbar -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: andrewthauer diff --git a/plugins/rollbar/config.d.ts b/plugins/rollbar/config.d.ts deleted file mode 100644 index a4915b18be..0000000000 --- a/plugins/rollbar/config.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the rollbar plugin */ - rollbar?: { - /** - * The Rollbar organization name. This can be omitted by using the `rollbar.com/project-slug` annotation. - * @see https://backstage.io/docs/features/software-catalog/well-known-annotations#rollbarcomproject-slug - * @visibility frontend - */ - organization?: string; - }; -} diff --git a/plugins/rollbar/dev/index.tsx b/plugins/rollbar/dev/index.tsx deleted file mode 100644 index 9342e28682..0000000000 --- a/plugins/rollbar/dev/index.tsx +++ /dev/null @@ -1,20 +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 { createDevApp } from '@backstage/dev-utils'; -import { rollbarPlugin } from '../src/plugin'; - -createDevApp().registerPlugin(rollbarPlugin).render(); diff --git a/plugins/rollbar/knip-report.md b/plugins/rollbar/knip-report.md deleted file mode 100644 index 5e1155a369..0000000000 --- a/plugins/rollbar/knip-report.md +++ /dev/null @@ -1,14 +0,0 @@ -# Knip report - -## Unused dependencies (1) - -| Name | Location | Severity | -| :----- | :----------- | :------- | -| lodash | package.json | error | - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json deleted file mode 100644 index 662b10d3f2..0000000000 --- a/plugins/rollbar/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@backstage/plugin-rollbar", - "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.30-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/rollbar" - }, - "keywords": [ - "backstage", - "rollbar" - ], - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "lodash": "^4.17.21", - "react-sparklines": "^1.7.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/rollbar/src/api/RollbarApi.ts b/plugins/rollbar/src/api/RollbarApi.ts deleted file mode 100644 index d5d6fe6aca..0000000000 --- a/plugins/rollbar/src/api/RollbarApi.ts +++ /dev/null @@ -1,38 +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 { - RollbarItemsResponse, - RollbarProject, - RollbarTopActiveItem, -} from './types'; -import { createApiRef } from '@backstage/core-plugin-api'; - -/** @public */ -export const rollbarApiRef = createApiRef({ - id: 'plugin.rollbar.service', -}); - -/** @public */ -export interface RollbarApi { - getAllProjects(): Promise; - getProject(projectName: string): Promise; - getTopActiveItems( - project: string, - hours?: number, - ): Promise; - getProjectItems(project: string): Promise; -} diff --git a/plugins/rollbar/src/api/RollbarClient.ts b/plugins/rollbar/src/api/RollbarClient.ts deleted file mode 100644 index 71c9f74ff0..0000000000 --- a/plugins/rollbar/src/api/RollbarClient.ts +++ /dev/null @@ -1,75 +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 { RollbarApi } from './RollbarApi'; -import { - RollbarItemsResponse, - RollbarProject, - RollbarTopActiveItem, -} from './types'; -import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; - -/** @public */ -export class RollbarClient implements RollbarApi { - private readonly discoveryApi: DiscoveryApi; - private readonly identityApi: IdentityApi; - - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }) { - this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; - } - - async getAllProjects(): Promise { - return await this.get(`/projects`); - } - - async getProject(projectName: string): Promise { - return await this.get(`/projects/${projectName}`); - } - - async getTopActiveItems( - project: string, - hours = 24, - environment = 'production', - ): Promise { - return await this.get( - `/projects/${project}/top_active_items?environment=${environment}&hours=${hours}`, - ); - } - - async getProjectItems(project: string): Promise { - return await this.get(`/projects/${project}/items`); - } - - private async get(path: string): Promise { - const url = `${await this.discoveryApi.getBaseUrl('rollbar')}${path}`; - const { token: idToken } = await this.identityApi.getCredentials(); - const response = await fetch(url, { - headers: idToken ? { Authorization: `Bearer ${idToken}` } : {}, - }); - - if (!response.ok) { - const payload = await response.text(); - const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`; - throw new Error(message); - } - - return await response.json(); - } -} diff --git a/plugins/rollbar/src/api/index.ts b/plugins/rollbar/src/api/index.ts deleted file mode 100644 index 882024f90f..0000000000 --- a/plugins/rollbar/src/api/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './RollbarApi'; -export * from './RollbarClient'; -export * from './types'; diff --git a/plugins/rollbar/src/api/types.ts b/plugins/rollbar/src/api/types.ts deleted file mode 100644 index 0a8f718a26..0000000000 --- a/plugins/rollbar/src/api/types.ts +++ /dev/null @@ -1,147 +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. - */ - -// TODO: Make this shared/dry with backend - -/** @public */ -export type RollbarProjectAccessTokenScope = 'read' | 'write'; - -/** @public */ -export type RollbarEnvironment = 'production' | string; - -/** @public */ -export enum RollbarLevel { - debug = 10, - info = 20, - warning = 30, - error = 40, - critical = 50, -} - -/** @public */ -export enum RollbarFrameworkId { - 'unknown' = 0, - 'rails' = 1, - 'django' = 2, - 'pyramid' = 3, - 'node-js' = 4, - 'pylons' = 5, - 'php' = 6, - 'browser-js' = 7, - 'rollbar-system' = 8, - 'android' = 9, - 'ios' = 10, - 'mailgun' = 11, - 'logentries' = 12, - 'python' = 13, - 'ruby' = 14, - 'sidekiq' = 15, - 'flask' = 16, - 'celery' = 17, - 'rq' = 18, -} - -/** @public */ -export enum RollbarPlatformId { - 'unknown' = 0, - 'browser' = 1, - 'flash' = 2, - 'android' = 3, - 'ios' = 4, - 'heroku' = 5, - 'google-app-engine' = 6, - 'client' = 7, -} - -/** @public */ -export type RollbarProject = { - id: number; - name: string; - accountId: number; - status: 'enabled' | string; -}; - -/** @public */ -export type RollbarProjectAccessToken = { - projectId: number; - name: string; - scopes: RollbarProjectAccessTokenScope[]; - accessToken: string; - status: 'enabled' | string; -}; - -/** @public */ -export type RollbarItem = { - publicItemId: number; - integrationsData: null; - levelLock: number; - controllingId: number; - lastActivatedTimestamp: number; - assignedUserId: number; - groupStatus: number; - hash: string; - id: number; - environment: RollbarEnvironment; - titleLock: number; - title: string; - lastOccurrenceId: number; - lastOccurrenceTimestamp: number; - platform: RollbarPlatformId; - firstOccurrenceTimestamp: number; - project_id: number; - resolvedInVersion: string; - status: 'enabled' | string; - uniqueOccurrences: number; - groupItemId: number; - framework: RollbarFrameworkId; - totalOccurrences: number; - level: RollbarLevel; - counter: number; - lastModifiedBy: number; - firstOccurrenceId: number; - activatingOccurrenceId: number; - lastResolvedTimestamp: number; -}; - -/** @public */ -export type RollbarItemsResponse = { - items: RollbarItem[]; - page: number; - totalCount: number; -}; - -/** @public */ -export type RollbarItemCount = { - timestamp: number; - count: number; -}; - -/** @public */ -export type RollbarTopActiveItem = { - item: { - id: number; - counter: number; - environment: RollbarEnvironment; - framework: RollbarFrameworkId; - lastOccurrenceTimestamp: number; - level: number; - occurrences: number; - projectId: number; - title: string; - uniqueOccurrences: number; - }; - counts: number[]; -}; diff --git a/plugins/rollbar/src/components/EntityPageRollbar/EntityPageRollbar.tsx b/plugins/rollbar/src/components/EntityPageRollbar/EntityPageRollbar.tsx deleted file mode 100644 index cde396674e..0000000000 --- a/plugins/rollbar/src/components/EntityPageRollbar/EntityPageRollbar.tsx +++ /dev/null @@ -1,26 +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 { useEntity } from '@backstage/plugin-catalog-react'; -import React from 'react'; -import { RollbarProject } from '../RollbarProject/RollbarProject'; - -/** @public */ -export const EntityPageRollbar = () => { - const { entity } = useEntity(); - - return ; -}; diff --git a/plugins/rollbar/src/components/RollbarProject/RollbarProject.tsx b/plugins/rollbar/src/components/RollbarProject/RollbarProject.tsx deleted file mode 100644 index ef7cc155b1..0000000000 --- a/plugins/rollbar/src/components/RollbarProject/RollbarProject.tsx +++ /dev/null @@ -1,39 +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 { Entity } from '@backstage/catalog-model'; -import React from 'react'; -import { useTopActiveItems } from '../../hooks/useTopActiveItems'; -import { RollbarTopItemsTable } from '../RollbarTopItemsTable/RollbarTopItemsTable'; - -type Props = { - entity: Entity; -}; - -export const RollbarProject = ({ entity }: Props) => { - const { items, organization, project, loading, error } = - useTopActiveItems(entity); - - return ( - - ); -}; diff --git a/plugins/rollbar/src/components/RollbarTopItemsTable/RollbarTopItemsTable.test.tsx b/plugins/rollbar/src/components/RollbarTopItemsTable/RollbarTopItemsTable.test.tsx deleted file mode 100644 index 79d4fc5f41..0000000000 --- a/plugins/rollbar/src/components/RollbarTopItemsTable/RollbarTopItemsTable.test.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 { renderInTestApp } from '@backstage/test-utils'; -import { screen } from '@testing-library/react'; -import * as React from 'react'; -import { RollbarTopActiveItem } from '../../api/types'; -import { RollbarTopItemsTable } from './RollbarTopItemsTable'; - -const items: RollbarTopActiveItem[] = [ - { - item: { - id: 89898989, - counter: 1234, - environment: 'production', - framework: 0, - lastOccurrenceTimestamp: new Date().getTime() / 1000, - level: 50, - occurrences: 150, - title: 'Error in foo', - uniqueOccurrences: 40, - projectId: 12345, - }, - counts: [10, 20, 30, 40, 50], - }, -]; - -describe('RollbarTopItemsTable component', () => { - it('should render empty data message when loaded and no data', async () => { - await renderInTestApp( - , - ); - expect(screen.getByText(/No records to display/)).toBeInTheDocument(); - }); - - it('should display item attributes when loading has finished', async () => { - await renderInTestApp( - , - ); - expect(screen.getByText(/1234/)).toBeInTheDocument(); - expect(screen.getByText(/Error in foo/)).toBeInTheDocument(); - expect(screen.getByText(/critical/)).toBeInTheDocument(); - }); -}); diff --git a/plugins/rollbar/src/components/RollbarTopItemsTable/RollbarTopItemsTable.tsx b/plugins/rollbar/src/components/RollbarTopItemsTable/RollbarTopItemsTable.tsx deleted file mode 100644 index 89fa7596b0..0000000000 --- a/plugins/rollbar/src/components/RollbarTopItemsTable/RollbarTopItemsTable.tsx +++ /dev/null @@ -1,133 +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 { Box, Typography } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; -import React from 'react'; -import { - RollbarFrameworkId, - RollbarLevel, - RollbarTopActiveItem, -} from '../../api/types'; -import { buildItemUrl } from '../../utils'; -import { TrendGraph } from '../TrendGraph/TrendGraph'; -import { Table, TableColumn, Link } from '@backstage/core-components'; - -const columns: TableColumn[] = [ - { - title: 'ID', - field: 'item.counter', - type: 'string', - align: 'left', - width: '70px', - render: (data: any) => ( - - {data.item.counter} - - ), - }, - { - title: 'Title', - field: 'item.title', - type: 'string', - align: 'left', - }, - { - title: 'Trend', - sorting: false, - render: (data: any) => , - }, - { - title: 'Occurrences', - field: 'item.occurrences', - type: 'numeric', - align: 'right', - }, - { - title: 'Environment', - field: 'item.environment', - type: 'string', - }, - { - title: 'Level', - field: 'item.level', - type: 'string', - render: data => RollbarLevel[(data as RollbarTopActiveItem).item.level], - }, - { - title: 'Framework', - field: 'item.framework', - type: 'string', - render: data => - RollbarFrameworkId[(data as RollbarTopActiveItem).item.framework], - }, - { - title: 'Last Occurrence', - field: 'item.lastOccurrenceTimestamp', - type: 'datetime', - render: data => - new Date( - (data as RollbarTopActiveItem).item.lastOccurrenceTimestamp * 1000, - ).toLocaleDateString(), - }, -]; - -type Props = { - items: RollbarTopActiveItem[]; - organization: string; - project: string; - loading: boolean; - error?: any; -}; - -export const RollbarTopItemsTable = ({ - items, - organization, - project, - loading, - error, -}: Props) => { - if (error) { - return ( -
- - Error encountered while fetching rollbar top items. {error.toString()} - -
- ); - } - - return ( -
- - Top Active Items / {project} - - } - data={items.map(i => ({ org: organization, project, ...i }))} - /> - ); -}; diff --git a/plugins/rollbar/src/components/Router.tsx b/plugins/rollbar/src/components/Router.tsx deleted file mode 100644 index 0eec406c78..0000000000 --- a/plugins/rollbar/src/components/Router.tsx +++ /dev/null @@ -1,44 +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 { Entity } from '@backstage/catalog-model'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import React from 'react'; -import { Route, Routes } from 'react-router-dom'; -import { ROLLBAR_ANNOTATION } from '../constants'; -import { EntityPageRollbar } from './EntityPageRollbar/EntityPageRollbar'; - -/** @public */ -export const isPluginApplicableToEntity = (entity: Entity) => - Boolean(entity.metadata.annotations?.[ROLLBAR_ANNOTATION]); - -/** @public */ -export const Router = () => { - const { entity } = useEntity(); - - if (!isPluginApplicableToEntity(entity)) { - ; - } - - return ( - - } /> - - ); -}; diff --git a/plugins/rollbar/src/components/TrendGraph/TrendGraph.test.tsx b/plugins/rollbar/src/components/TrendGraph/TrendGraph.test.tsx deleted file mode 100644 index 996ae5bb2c..0000000000 --- a/plugins/rollbar/src/components/TrendGraph/TrendGraph.test.tsx +++ /dev/null @@ -1,29 +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 { renderInTestApp } from '@backstage/test-utils'; -import React from 'react'; -import { TrendGraph } from './TrendGraph'; - -describe('TrendGraph component', () => { - it('should render a trend graph sparkline', async () => { - const mockCounts = [1, 2, 3, 4]; - await renderInTestApp( - , - ); - expect(true).toBeTruthy(); - }); -}); diff --git a/plugins/rollbar/src/components/TrendGraph/TrendGraph.tsx b/plugins/rollbar/src/components/TrendGraph/TrendGraph.tsx deleted file mode 100644 index 7dd2a5eab2..0000000000 --- a/plugins/rollbar/src/components/TrendGraph/TrendGraph.tsx +++ /dev/null @@ -1,30 +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 { Sparklines, SparklinesBars } from 'react-sparklines'; - -type Props = { - counts: number[]; -}; - -export const TrendGraph = ({ counts }: Props) => { - return ( - - - - ); -}; diff --git a/plugins/rollbar/src/constants.ts b/plugins/rollbar/src/constants.ts deleted file mode 100644 index 42031ddcef..0000000000 --- a/plugins/rollbar/src/constants.ts +++ /dev/null @@ -1,18 +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. - */ - -/** @public */ -export const ROLLBAR_ANNOTATION = 'rollbar.com/project-slug'; diff --git a/plugins/rollbar/src/hooks/useCatalogEntity.ts b/plugins/rollbar/src/hooks/useCatalogEntity.ts deleted file mode 100644 index 4845a275be..0000000000 --- a/plugins/rollbar/src/hooks/useCatalogEntity.ts +++ /dev/null @@ -1,35 +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 { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react'; -import useAsync from 'react-use/lib/useAsync'; -import { useApi, useRouteRefParams } from '@backstage/core-plugin-api'; - -export function useCatalogEntity() { - const catalogApi = useApi(catalogApiRef); - const { namespace, name } = useRouteRefParams(entityRouteRef); - - const { - value: entity, - error, - loading, - } = useAsync( - () => catalogApi.getEntityByRef({ kind: 'Component', namespace, name }), - [catalogApi, namespace, name], - ); - - return { entity, error, loading }; -} diff --git a/plugins/rollbar/src/hooks/useProject.ts b/plugins/rollbar/src/hooks/useProject.ts deleted file mode 100644 index 7e1626e6b4..0000000000 --- a/plugins/rollbar/src/hooks/useProject.ts +++ /dev/null @@ -1,37 +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 { Entity } from '@backstage/catalog-model'; -import { ROLLBAR_ANNOTATION } from '../constants'; -import { useApi, configApiRef } from '@backstage/core-plugin-api'; - -export function useProjectSlugFromEntity(entity: Entity) { - const configApi = useApi(configApiRef); - - const [project, organization] = ( - entity?.metadata?.annotations?.[ROLLBAR_ANNOTATION] ?? '' - ) - .split('/') - .reverse(); - - return { - project, - organization: - organization ?? - configApi.getOptionalString('rollbar.organization') ?? - configApi.getString('organization.name'), - }; -} diff --git a/plugins/rollbar/src/hooks/useRollbarEntities.ts b/plugins/rollbar/src/hooks/useRollbarEntities.ts deleted file mode 100644 index 60799e3916..0000000000 --- a/plugins/rollbar/src/hooks/useRollbarEntities.ts +++ /dev/null @@ -1,38 +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 { catalogApiRef } from '@backstage/plugin-catalog-react'; -import useAsync from 'react-use/lib/useAsync'; -import { ROLLBAR_ANNOTATION } from '../constants'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; - -export function useRollbarEntities() { - const configApi = useApi(configApiRef); - const catalogApi = useApi(catalogApiRef); - - const organization = - configApi.getOptionalString('rollbar.organization') ?? - configApi.getString('organization.name'); - - const { value, loading, error } = useAsync(async () => { - const response = await catalogApi.getEntities(); - return response.items.filter(entity => { - return !!entity.metadata.annotations?.[ROLLBAR_ANNOTATION]; - }); - }, [catalogApi]); - - return { entities: value, organization, loading, error }; -} diff --git a/plugins/rollbar/src/hooks/useTopActiveItems.ts b/plugins/rollbar/src/hooks/useTopActiveItems.ts deleted file mode 100644 index 04b65eb8cb..0000000000 --- a/plugins/rollbar/src/hooks/useTopActiveItems.ts +++ /dev/null @@ -1,46 +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 useAsync from 'react-use/lib/useAsync'; -import { Entity } from '@backstage/catalog-model'; -import { rollbarApiRef } from '../api'; -import { RollbarTopActiveItem } from '../api/types'; -import { useProjectSlugFromEntity } from './useProject'; -import { useApi } from '@backstage/core-plugin-api'; - -export function useTopActiveItems(entity: Entity) { - const api = useApi(rollbarApiRef); - const { organization, project } = useProjectSlugFromEntity(entity); - const { value, loading, error } = useAsync(() => { - if (!project) { - return Promise.resolve([]); - } - - return api - .getTopActiveItems(project, 168) - .then(data => - data.sort((a, b) => b.item.occurrences - a.item.occurrences), - ); - }, [api, organization, project, entity]); - - return { - items: value as RollbarTopActiveItem[], - organization, - project, - loading, - error, - }; -} diff --git a/plugins/rollbar/src/index.ts b/plugins/rollbar/src/index.ts deleted file mode 100644 index 3964582bd6..0000000000 --- a/plugins/rollbar/src/index.ts +++ /dev/null @@ -1,35 +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. - */ - -/** - * A Backstage plugin that integrates towards Rollbar - * - * @packageDocumentation - */ - -export * from './api'; -export { EntityPageRollbar } from './components/EntityPageRollbar/EntityPageRollbar'; -export { - isPluginApplicableToEntity, - isPluginApplicableToEntity as isRollbarAvailable, - Router, -} from './components/Router'; -export { ROLLBAR_ANNOTATION } from './constants'; -export { - EntityRollbarContent, - rollbarPlugin as plugin, - rollbarPlugin, -} from './plugin'; diff --git a/plugins/rollbar/src/plugin.test.ts b/plugins/rollbar/src/plugin.test.ts deleted file mode 100644 index 89a8c30016..0000000000 --- a/plugins/rollbar/src/plugin.test.ts +++ /dev/null @@ -1,23 +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 { rollbarPlugin } from './plugin'; - -describe('rollbar', () => { - it('should export plugin', () => { - expect(rollbarPlugin).toBeDefined(); - }); -}); diff --git a/plugins/rollbar/src/plugin.ts b/plugins/rollbar/src/plugin.ts deleted file mode 100644 index de3dd38b1a..0000000000 --- a/plugins/rollbar/src/plugin.ts +++ /dev/null @@ -1,55 +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 { rollbarApiRef } from './api/RollbarApi'; -import { RollbarClient } from './api/RollbarClient'; -import { - createApiFactory, - createPlugin, - createRoutableExtension, - createRouteRef, - discoveryApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'rollbar', -}); - -/** @public */ -export const rollbarPlugin = createPlugin({ - id: 'rollbar', - apis: [ - createApiFactory({ - api: rollbarApiRef, - deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, - factory: ({ discoveryApi, identityApi }) => - new RollbarClient({ discoveryApi, identityApi }), - }), - ], - routes: { - entityContent: rootRouteRef, - }, -}); - -/** @public */ -export const EntityRollbarContent = rollbarPlugin.provide( - createRoutableExtension({ - name: 'EntityRollbarContent', - component: () => import('./components/Router').then(m => m.Router), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/rollbar/src/setupTests.ts b/plugins/rollbar/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/rollbar/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/rollbar/src/utils/index.ts b/plugins/rollbar/src/utils/index.ts deleted file mode 100644 index 16ffec070d..0000000000 --- a/plugins/rollbar/src/utils/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export const buildProjectUrl = (org: string, id: number) => - `https://rollbar.com/${org}/all/items/?projects=${id}`; - -export const buildItemUrl = (org: string, project: string, id: number) => - `https://rollbar.com/${org}/${project}/items/${id}`; diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index 7a59c8cebd..a205da59c8 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,143 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.1.9 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.9-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.6 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.1.6-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.5-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.1.2 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.2-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index 37f8a70c49..46cb67fe74 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", + "version": "0.1.10-next.0", "description": "The azure module for @backstage/plugin-scaffolder-backend", - "version": "0.1.2-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, @@ -13,13 +13,13 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-azure" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -27,17 +27,19 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", @@ -47,9 +49,7 @@ "yaml": "^2.0.0" }, "devDependencies": { - "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" + } } diff --git a/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts index 27989650ce..e00362c457 100644 --- a/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.test.ts @@ -18,11 +18,10 @@ import yaml from 'yaml'; import { ConfigReader } from '@backstage/config'; import { createPublishAzureAction } from './azure'; import { ScmIntegrations } from '@backstage/integration'; -import { getVoidLogger } from '@backstage/backend-common'; import { WebApi } from 'azure-devops-node-api'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { examples } from './azure.examples'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; jest.mock('azure-devops-node-api', () => ({ WebApi: jest.fn(), @@ -55,13 +54,7 @@ describe('publish:azure examples', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishAzureAction({ integrations, config }); - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); const mockGitClient = { createRepository: jest.fn(), diff --git a/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.ts index 48b57c410d..d1459d1820 100644 --- a/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.examples.ts @@ -20,7 +20,7 @@ import yaml from 'yaml'; export const examples: TemplateExample[] = [ { description: - 'Initializes a git repository of the content in the workspace, and publishes it to Azure.', + 'Initializes a git repository with the content in the workspace, and publishes it to Azure DevOps with the default configuration.', example: yaml.stringify({ steps: [ { @@ -36,7 +36,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Add a description.', + description: 'Initializes an Azure DevOps repository with a description.', example: yaml.stringify({ steps: [ { @@ -53,7 +53,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Change the default branch.', + description: + 'Initializes an Azure DevOps repository with a default branch, if not set defaults to master', example: yaml.stringify({ steps: [ { @@ -63,7 +64,6 @@ export const examples: TemplateExample[] = [ input: { repoUrl: 'dev.azure.com?organization=organization&owner=project&repo=repo', - description: 'Initialize a git repository', defaultBranch: 'main', }, }, diff --git a/plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts index 4401e01007..a23eebb93a 100644 --- a/plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.test.ts @@ -34,10 +34,9 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishAzureAction } from './azure'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; import { WebApi } from 'azure-devops-node-api'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:azure', () => { const config = new ConfigReader({ @@ -54,16 +53,10 @@ describe('publish:azure', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishAzureAction({ integrations, config }); - const mockContext = { - input: { - repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org', - }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + + const mockContext = createMockActionContext({ + input: { repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org' }, + }); const mockGitClient = { createRepository: jest.fn(), diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md index cb47516878..67cbfa1af5 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,156 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-cloud +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.1.7 + +### Patch Changes + +- 8dd33a1: Added examples for publish:bitbucketCloud actions +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.1.7-next.0 + +### Patch Changes + +- 8dd33a1: Added examples for publish:bitbucketCloud actions +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.1.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.1.0 + +### Minor Changes + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Cloud. + + - `publish:bitbucketCloud` + - `bitbucket:pipelines:run` + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index d0293d98cf..9d92a7d4e6 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud", + "version": "0.1.8-next.0", "description": "The Bitbucket Cloud module for @backstage/plugin-scaffolder-backend", - "version": "0.1.0-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, @@ -13,13 +13,13 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-bitbucket-cloud" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -27,17 +27,19 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", @@ -50,9 +52,7 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "msw": "^1.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts new file mode 100644 index 0000000000..5e95f41751 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.test.ts @@ -0,0 +1,291 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +import { createPublishBitbucketCloudAction } from './bitbucketCloud'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; +import { sep } from 'path'; +import { examples } from './bitbucketCloud.examples'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; + +describe('publish:bitbucketCloud', () => { + const config = new ConfigReader({ + integrations: { + bitbucketCloud: [ + { + username: 'x-token-auth', + appPassword: 'your-default-auth-token', + }, + ], + }, + scaffolder: { + defaultCommitMessage: 'initial commit', + defaultAuthor: { + name: 'test_user', + email: 'test_user@BackstageBackend.com', + }, + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishBitbucketCloudAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo', + repoVisibility: 'private' as const, + }, + }); + const server = setupServer(); + setupRequestMockHandlers(server); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should call initAndPush with the correct values', async () => { + server.use( + rest.post( + 'https://api.bitbucket.org/2.0/repositories/workspace/repo', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + html: { + href: 'https://bitbucket.org/workspace/repo', + }, + clone: [ + { + name: 'https', + href: 'https://bitbucket.org/workspace/cloneurl', + }, + ], + }, + }), + ), + ), + ); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[0].example).steps[0].input, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.org/workspace/cloneurl', + defaultBranch: 'master', + auth: { username: 'x-token-auth', password: 'your-default-auth-token' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: { + email: 'test_user@BackstageBackend.com', + name: 'test_user', + }, + }); + }); + + it('should call initAndPush with the correct default branch', async () => { + server.use( + rest.post( + 'https://api.bitbucket.org/2.0/repositories/workspace/repo', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + html: { + href: 'https://bitbucket.org/workspace/repo', + }, + clone: [ + { + name: 'https', + href: 'https://bitbucket.org/workspace/cloneurl', + }, + ], + }, + }), + ), + ), + ); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[3].example).steps[0].input, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.org/workspace/cloneurl', + defaultBranch: 'main', + auth: { username: 'x-token-auth', password: 'your-default-auth-token' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: { + email: 'test_user@BackstageBackend.com', + name: 'test_user', + }, + }); + }); + + it('should call initAndPush with the specified source path', async () => { + server.use( + rest.post( + 'https://api.bitbucket.org/2.0/repositories/workspace/repo', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + html: { + href: 'https://bitbucket.org/workspace/repo', + }, + clone: [ + { + name: 'https', + href: 'https://bitbucket.org/workspace/cloneurl', + }, + ], + }, + }), + ), + ), + ); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[4].example).steps[0].input, + }); + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}${sep}repoRoot`, + remoteUrl: 'https://bitbucket.org/workspace/cloneurl', + auth: { username: 'x-token-auth', password: 'your-default-auth-token' }, + logger: mockContext.logger, + defaultBranch: 'master', + commitMessage: 'initial commit', + gitAuthorInfo: { + email: 'test_user@BackstageBackend.com', + name: 'test_user', + }, + }); + }); + + it('should call initAndPush with the authentication token', async () => { + server.use( + rest.post( + 'https://api.bitbucket.org/2.0/repositories/workspace/repo', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + html: { + href: 'https://bitbucket.org/workspace/repo', + }, + clone: [ + { + name: 'https', + href: 'https://bitbucket.org/workspace/cloneurl', + }, + ], + }, + }), + ), + ), + ); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[5].example).steps[0].input, + }); + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.org/workspace/cloneurl', + auth: { username: 'x-token-auth', password: 'your-custom-auth-token' }, + logger: mockContext.logger, + defaultBranch: 'master', + commitMessage: 'initial commit', + gitAuthorInfo: { + email: 'test_user@BackstageBackend.com', + name: 'test_user', + }, + }); + }); + + it('should call initAndPush with all available custom inputs', async () => { + server.use( + rest.post( + 'https://api.bitbucket.org/2.0/repositories/workspace/repo', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + html: { + href: 'https://bitbucket.org/workspace/repo', + }, + clone: [ + { + name: 'https', + href: 'https://bitbucket.org/workspace/cloneurl', + }, + ], + }, + }), + ), + ), + ); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[6].example).steps[0].input, + }); + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.org/workspace/cloneurl', + auth: { username: 'x-token-auth', password: 'your-custom-auth-token' }, + logger: mockContext.logger, + defaultBranch: 'main', + commitMessage: 'initial commit', + gitAuthorInfo: { + email: 'test_user@BackstageBackend.com', + name: 'test_user', + }, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.ts new file mode 100644 index 0000000000..63e4ccb212 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.examples.ts @@ -0,0 +1,148 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: + 'Initializes a git repository with the content in the workspace, and publishes it to Bitbucket Cloud with the default configuration.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + }, + }, + ], + }), + }, + { + description: 'Initializes a Bitbucket Cloud repository with a description.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + description: 'Initialize a git repository', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Bitbucket Cloud repository with public repo visibility, if not set defaults to private', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + repoVisibility: 'public', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Bitbucket Cloud repository with a default Branch, if not set defaults to master', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + defaultBranch: 'main', + }, + }, + ], + }), + }, + { + description: + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + sourcePath: './repoRoot', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Bitbucket Cloud repository with a custom authentication token', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + token: 'your-custom-auth-token', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Bitbucket Cloud repository with all proporties being set', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucketCloud', + name: 'Publish to Bitbucket Cloud', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + description: 'Initialize a git repository', + repoVisibility: 'public', + defaultBranch: 'main', + token: 'your-custom-auth-token', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts index 7045d58e01..6a079a3f9b 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.test.ts @@ -32,9 +32,8 @@ import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:bitbucketCloud', () => { const config = new ConfigReader({ @@ -50,17 +49,12 @@ describe('publish:bitbucketCloud', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishBitbucketCloudAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo', repoVisibility: 'private' as const, }, - workspacePath: 'wsp', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const server = setupServer(); setupRequestMockHandlers(server); diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts index e9d815f5e8..99e8e52a43 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloud.ts @@ -26,6 +26,7 @@ import fetch, { Response, RequestInit } from 'node-fetch'; import { Config } from '@backstage/config'; import { getAuthorizationHeader } from './helpers'; +import { examples } from './bitbucketCloud.examples'; const createRepository = async (opts: { workspace: string; @@ -114,6 +115,7 @@ export function createPublishBitbucketCloudAction(options: { token?: string; }>({ id: 'publish:bitbucketCloud', + examples, description: 'Initializes a git repository of the content in the workspace, and publishes it to Bitbucket Cloud.', schema: { diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts index 90ae2c08b9..472c7a6a03 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.examples.test.ts @@ -14,16 +14,15 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { PassThrough } from 'stream'; import { createBitbucketPipelinesRunAction } from './bitbucketCloudPipelinesRun'; import yaml from 'yaml'; import { examples } from './bitbucketCloudPipelinesRun.examples'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('bitbucket:pipelines:run', () => { const config = new ConfigReader({ @@ -39,14 +38,7 @@ describe('bitbucket:pipelines:run', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createBitbucketPipelinesRunAction({ integrations }); - const mockContext = { - input: {}, - workspacePath: 'wsp', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); const responseJson = { repository: { links: { diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts index dc76a79898..9386246868 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/src/actions/bitbucketCloudPipelinesRun.test.ts @@ -14,14 +14,13 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; -import { PassThrough } from 'stream'; import { createBitbucketPipelinesRunAction } from './bitbucketCloudPipelinesRun'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('bitbucket:pipelines:run', () => { const config = new ConfigReader({ @@ -37,14 +36,7 @@ describe('bitbucket:pipelines:run', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createBitbucketPipelinesRunAction({ integrations }); - const mockContext = { - input: {}, - workspacePath: 'wsp', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); const workspace = 'test-workspace'; const repo_slug = 'test-repo-slug'; const responseJson = { diff --git a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md index a6b7a6e761..29b4d61ddc 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,156 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-server +## 0.1.8-next.0 + +### Patch Changes + +- 24dd655: Add examples for `publish:bitbucketServer:pull-request` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.1.7 + +### Patch Changes + +- 4a15c86: Add examples for `publish:bitbucketServer` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.7-next.1 + +### Patch Changes + +- 4a15c86: Add examples for `publish:bitbucketServer` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 0e48aaf: Added an option to specify a commit author by adding `gitAuthorName` and `gitAuthorEmail` options to the `publish:bitbucketServer:pull-request` action +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.1.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.1.0 + +### Minor Changes + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Server. + + - `publish:bitbucketServer` + - `publish:bitbucketServer:pull-request` + +### Patch Changes + +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.0-next.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-server/api-report.md b/plugins/scaffolder-backend-module-bitbucket-server/api-report.md index 3e2e3dffe4..4d75a3dbda 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/api-report.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/api-report.md @@ -45,6 +45,8 @@ export function createPublishBitbucketServerPullRequestAction(options: { targetBranch?: string | undefined; sourceBranch: string; token?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; }, JsonObject >; diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index 3f5fe30852..5213d00079 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-server", + "version": "0.1.8-next.0", "description": "The Bitbucket Server module for @backstage/plugin-scaffolder-backend", - "version": "0.1.0-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, @@ -13,13 +13,13 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-bitbucket-server" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -27,17 +27,19 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", @@ -50,9 +52,7 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "msw": "^1.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts new file mode 100644 index 0000000000..eae8385822 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.test.ts @@ -0,0 +1,402 @@ +/* + * 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. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +import { createPublishBitbucketServerAction } from './bitbucketServer'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import yaml from 'yaml'; +import { examples } from './bitbucketServer.examples'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; + +describe('publish:bitbucketServer', () => { + const config = new ConfigReader({ + integrations: { + bitbucketServer: [ + { + host: 'hosted.bitbucket.com', + token: 'thing', + apiBaseUrl: 'https://hosted.bitbucket.com/rest/api/1.0', + }, + { + host: 'basic-auth.bitbucket.com', + username: 'test-user', + password: 'test-password', + apiBaseUrl: 'https://basic-auth.bitbucket.com/rest/api/1.0', + }, + { + host: 'no-credentials.bitbucket.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishBitbucketServerAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + repoVisibility: 'private' as const, + }, + }); + const server = setupServer(); + setupRequestMockHandlers(server); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`should ${examples[0].description}`, async () => { + expect.assertions(3); + server.use( + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'master', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + ...yaml.parse(examples[0].example).steps[0].input, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'master', + auth: { token: 'thing' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + it(`should ${examples[1].description}`, async () => { + expect.assertions(3); + server.use( + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[1].example).steps[0].input.token}`, + ); + expect(req.body).toEqual({ + public: false, + name: 'repo', + defaultBranch: 'main', + description: 'This is a test repository', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'private', + defaultBranch: 'main', + sourcePath: 'packages/backend', + enableLFS: false, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }); + + // Ensure that the initRepoAndPush function was called with the correct remoteUrl and input properties + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/${ + yaml.parse(examples[1].example).steps[0].input.sourcePath + }`, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'main', + auth: { token: 'test-token' }, + logger: mockContext.logger, + commitMessage: 'Init check commit', + gitAuthorInfo: { name: 'Test User', email: 'test.user@example.com' }, + }); + }); + + it(`should ${examples[2].description}`, async () => { + expect.assertions(3); + server.use( + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[2].example).steps[0].input.token}`, + ); + expect(req.body).toEqual({ + public: true, + name: 'repo', + defaultBranch: 'main', + description: 'This is a test repository', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'public', + defaultBranch: 'main', + sourcePath: 'packages/backend', + enableLFS: false, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }); + + // Ensure that the initRepoAndPush function was called with the correct remoteUrl and input properties + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/${ + yaml.parse(examples[2].example).steps[0].input.sourcePath + }`, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'main', + auth: { token: 'test-token' }, + logger: mockContext.logger, + commitMessage: 'Init check commit', + gitAuthorInfo: { name: 'Test User', email: 'test.user@example.com' }, + }); + }); + + it(`should ${examples[3].description}`, async () => { + expect.assertions(3); + server.use( + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[3].example).steps[0].input.token}`, + ); + expect(req.body).toEqual({ + public: true, + name: 'repo', + defaultBranch: 'develop', + description: 'This is a test repository', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'public', + defaultBranch: 'develop', + sourcePath: 'packages/backend', + enableLFS: false, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }); + + // Ensure that the initRepoAndPush function was called with the correct remoteUrl and input properties + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/${ + yaml.parse(examples[3].example).steps[0].input.sourcePath + }`, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'develop', + auth: { token: 'test-token' }, + logger: mockContext.logger, + commitMessage: 'Init check commit', + gitAuthorInfo: { name: 'Test User', email: 'test.user@example.com' }, + }); + }); + + it(`should ${examples[4].description}`, async () => { + expect.assertions(3); + server.use( + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[4].example).steps[0].input.token}`, + ); + expect(req.body).toEqual({ + public: true, + name: 'repo', + defaultBranch: 'develop', + description: 'This is a test repository', + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/project/repos/repo', + }, + ], + clone: [ + { + name: 'http', + href: 'https://bitbucket.mycompany.com/scm/project/repo', + }, + ], + }, + }), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'public', + defaultBranch: 'develop', + sourcePath: 'packages/api', + enableLFS: false, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }); + + // Ensure that the initRepoAndPush function was called with the correct remoteUrl and input properties + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/${ + yaml.parse(examples[4].example).steps[0].input.sourcePath + }`, + remoteUrl: 'https://bitbucket.mycompany.com/scm/project/repo', + defaultBranch: 'develop', + auth: { token: 'test-token' }, + logger: mockContext.logger, + commitMessage: 'Init check commit', + gitAuthorInfo: { name: 'Test User', email: 'test.user@example.com' }, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts new file mode 100644 index 0000000000..b3a68eed57 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.examples.ts @@ -0,0 +1,132 @@ +/* + * 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Initialize git repository with required properties', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-minimal', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + }, + }, + ], + }), + }, + { + description: 'Initialize git repository with all properties', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-minimal', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'private', + defaultBranch: 'main', + sourcePath: 'packages/backend', + enableLFS: false, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, + { + description: 'Initialize git repository with public visibility', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-minimal', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'public', + defaultBranch: 'main', + sourcePath: 'packages/backend', + enableLFS: true, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, + { + description: 'Initialize git repository with different default branch', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-minimal', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'public', + defaultBranch: 'develop', + sourcePath: 'packages/backend', + enableLFS: true, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, + { + description: 'Initialize git repository with different source path', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer', + id: 'publish-bitbucket-server-minimal', + name: 'Publish To Bitbucket Server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + description: 'This is a test repository', + repoVisibility: 'public', + defaultBranch: 'develop', + sourcePath: 'packages/api', + enableLFS: true, + token: 'test-token', + gitCommitMessage: 'Init check commit', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts index ab7b52996f..1d42e7368c 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.test.ts @@ -32,9 +32,8 @@ import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:bitbucketServer', () => { const config = new ConfigReader({ @@ -60,17 +59,12 @@ describe('publish:bitbucketServer', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishBitbucketServerAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', repoVisibility: 'private' as const, }, - workspacePath: 'wsp', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const server = setupServer(); setupRequestMockHandlers(server); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts index 31125deab2..413984aff5 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServer.ts @@ -28,6 +28,7 @@ import { import fetch, { Response, RequestInit } from 'node-fetch'; import { Config } from '@backstage/config'; +import { examples } from './bitbucketServer.examples'; const createRepository = async (opts: { project: string; @@ -141,6 +142,7 @@ export function createPublishBitbucketServerAction(options: { id: 'publish:bitbucketServer', description: 'Initializes a git repository of the content in the workspace, and publishes it to Bitbucket Server.', + examples, schema: { input: { type: 'object', diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts new file mode 100644 index 0000000000..1d3556fc88 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.test.ts @@ -0,0 +1,419 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +import { createPublishBitbucketServerPullRequestAction } from './bitbucketServerPullRequest'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import yaml from 'yaml'; +import { examples } from './bitbucketServerPullRequest.examples'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; + +describe('publish:bitbucketServer:pull-request', () => { + const config = new ConfigReader({ + integrations: { + bitbucketServer: [ + { + host: 'hosted.bitbucket.com', + token: 'thing', + apiBaseUrl: 'https://hosted.bitbucket.com/rest/api/1.0', + }, + { + host: 'basic-auth.bitbucket.com', + username: 'test-user', + password: 'test-password', + apiBaseUrl: 'https://basic-auth.bitbucket.com/rest/api/1.0', + }, + { + host: 'no-credentials.bitbucket.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishBitbucketServerPullRequestAction({ + integrations, + config, + }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + title: 'Add Scaffolder actions for Bitbucket Server', + description: + 'I just made a Pull Request that Add Scaffolder actions for Bitbucket Server', + targetBranch: 'master', + sourceBranch: 'develop', + }, + }); + const responseOfBranches = { + size: 3, + limit: 25, + isLastPage: true, + values: [ + { + id: 'refs/heads/master', + displayId: 'master', + type: 'BRANCH', + latestCommit: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + latestChangeset: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + isDefault: true, + }, + { + id: 'refs/heads/my-feature-branch', + displayId: 'my-feature-branch', + type: 'BRANCH', + latestCommit: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + latestChangeset: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + isDefault: true, + }, + { + id: 'refs/heads/develop', + displayId: 'develop', + type: 'BRANCH', + latestCommit: '98e21148205367aeb11c25a52eaca3c2945253fa', + latestChangeset: '98e21148205367aeb11c25a52eaca3c2945253fa', + isDefault: false, + }, + { + id: 'refs/heads/development', + displayId: 'development', + type: 'BRANCH', + latestCommit: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + latestChangeset: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + isDefault: false, + }, + ], + start: 0, + }; + const responseOfPullRequests = { + id: 19, + version: 0, + title: 'Test for bitbucket server pull-requests', + description: 'Test for bitbucket server pull-requests', + state: 'OPEN', + open: true, + closed: false, + createdDate: 1684200289521, + updatedDate: 1684200289521, + fromRef: { + id: 'refs/heads/develop', + displayId: 'develop', + latestCommit: '98e21148205367aeb11c25a52eaca3c2945253fa', + type: 'BRANCH', + repository: { + slug: 'repo', + id: 1812, + name: 'repo', + description: 'This is a test repo', + hierarchyId: '1da8822903a9b11a27b8', + scmId: 'git', + state: 'AVAILABLE', + statusMessage: 'Available', + forkable: true, + project: {}, + public: false, + links: {}, + }, + }, + toRef: { + id: 'refs/heads/master', + displayId: 'master', + latestCommit: 'b1041e3f9b071b3d5cacd6826b7549cd624418f1', + type: 'BRANCH', + repository: { + slug: 'repo', + id: 1812, + name: 'repo', + description: 'This is a test repo', + hierarchyId: '1da8822903a9b11a27b8', + scmId: 'git', + state: 'AVAILABLE', + statusMessage: 'Available', + forkable: true, + project: {}, + public: false, + links: {}, + }, + }, + locked: false, + author: { + user: { + name: 'test-user', + emailAddress: 'test-user@sample.com', + id: 2944, + displayName: 'test-user', + active: true, + slug: 'test-user', + type: 'NORMAL', + links: {}, + }, + role: 'AUTHOR', + approved: false, + status: 'UNAPPROVED', + }, + reviewers: [], + participants: [], + links: { + self: [ + { + href: 'https://hosted.bitbucket.com/projects/project/repos/repo/pull-requests/1', + }, + ], + }, + }; + + const server = setupServer(); + setupRequestMockHandlers(server); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`should ${examples[0].description}`, async () => { + expect.assertions(3); + server.use( + rest.get( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos/repo/branches', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfBranches), + ); + }, + ), + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos/repo/pull-requests', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfPullRequests), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...yaml.parse(examples[0].example).steps[0].input, + }, + }); + }); + + it(`should ${examples[1].description}`, async () => { + expect.assertions(6); + server.use( + rest.get( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos/repo/branches', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfBranches), + ); + }, + ), + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos/repo/pull-requests', + (req, res, ctx) => { + const requestBody = req.body as { + title: string; + fromRef: { displayId: string }; + description: string; + }; + expect(requestBody.title).toBe('My pull request'); + expect(requestBody.fromRef.displayId).toBe('my-feature-branch'); + expect(requestBody.description).toBe( + 'This is a detailed description of my pull request', + ); + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfPullRequests), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...yaml.parse(examples[1].example).steps[0].input, + }, + }); + }); + + it(`should ${examples[2].description}`, async () => { + expect.assertions(6); + server.use( + rest.get( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos/repo/branches', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfBranches), + ); + }, + ), + rest.post( + 'https://hosted.bitbucket.com/rest/api/1.0/projects/project/repos/repo/pull-requests', + (req, res, ctx) => { + const requestBody = req.body as { + title: string; + toRef: { displayId: string }; + description: string; + }; + expect(requestBody.title).toBe('My pull request'); + expect(requestBody.toRef.displayId).toBe('development'); + expect(requestBody.description).toBe( + 'I just made a Pull Request that Add Scaffolder actions for Bitbucket Server', + ); + expect(req.headers.get('Authorization')).toBe('Bearer thing'); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfPullRequests), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...yaml.parse(examples[2].example).steps[0].input, + }, + }); + }); + + it(`should ${examples[3].description}`, async () => { + expect.assertions(3); + server.use( + rest.get( + 'https://no-credentials.bitbucket.com/rest/api/1.0/projects/project/repos/repo/branches', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[3].example).steps[0].input.token}`, + ); + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfBranches), + ); + }, + ), + rest.post( + 'https://no-credentials.bitbucket.com/rest/api/1.0/projects/project/repos/repo/pull-requests', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[3].example).steps[0].input.token}`, + ); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfPullRequests), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...yaml.parse(examples[3].example).steps[0].input, + }, + }); + }); + + it(`should ${examples[4].description}`, async () => { + expect.assertions(7); + server.use( + rest.get( + 'https://no-credentials.bitbucket.com/rest/api/1.0/projects/project/repos/repo/branches', + (req, res, ctx) => { + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[4].example).steps[0].input.token}`, + ); + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfBranches), + ); + }, + ), + rest.post( + 'https://no-credentials.bitbucket.com/rest/api/1.0/projects/project/repos/repo/pull-requests', + (req, res, ctx) => { + const requestBody = req.body as { + title: string; + toRef: { displayId: string }; + fromRef: { displayId: string }; + description: string; + }; + expect(requestBody.title).toBe('My pull request'); + expect(requestBody.fromRef.displayId).toBe('my-feature-branch'); + expect(requestBody.toRef.displayId).toBe('development'); + expect(requestBody.description).toBe( + 'This is a detailed description of my pull request', + ); + expect(req.headers.get('Authorization')).toBe( + `Bearer ${yaml.parse(examples[4].example).steps[0].input.token}`, + ); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json(responseOfPullRequests), + ); + }, + ), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + ...yaml.parse(examples[4].example).steps[0].input, + }, + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.ts new file mode 100644 index 0000000000..77287e64e1 --- /dev/null +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.examples.ts @@ -0,0 +1,118 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: + 'Creating pull request on bitbucket server with required fields', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer:pull-request', + id: 'publish-bitbucket-server-pull-request-minimal', + name: 'Creating pull request on bitbucket server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + title: 'My pull request', + sourceBranch: 'my-feature-branch', + }, + }, + ], + }), + }, + { + description: + 'Creating pull request on bitbucket server with custom descriptions', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer:pull-request', + id: 'publish-bitbucket-server-pull-request-minimal', + name: 'Creating pull request on bitbucket server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + title: 'My pull request', + sourceBranch: 'my-feature-branch', + description: 'This is a detailed description of my pull request', + }, + }, + ], + }), + }, + { + description: + 'Creating pull request on bitbucket server with different target branch', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer:pull-request', + id: 'publish-bitbucket-server-pull-request-target-branch', + name: 'Creating pull request on bitbucket server', + input: { + repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', + title: 'My pull request', + sourceBranch: 'my-feature-branch', + targetBranch: 'development', + }, + }, + ], + }), + }, + { + description: + 'Creating pull request on bitbucket server with authorization token', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer:pull-request', + id: 'publish-bitbucket-server-pull-request-minimal', + name: 'Creating pull request on bitbucket server', + input: { + repoUrl: 'no-credentials.bitbucket.com?project=project&repo=repo', + title: 'My pull request', + sourceBranch: 'my-feature-branch', + token: 'my-auth-token', + }, + }, + ], + }), + }, + { + description: 'Creating pull request on bitbucket server with all fields', + example: yaml.stringify({ + steps: [ + { + action: 'publish:bitbucketServer:pull-request', + id: 'publish-bitbucket-server-pull-request-minimal', + name: 'Creating pull request on bitbucket server', + input: { + repoUrl: 'no-credentials.bitbucket.com?project=project&repo=repo', + title: 'My pull request', + sourceBranch: 'my-feature-branch', + targetBranch: 'development', + description: 'This is a detailed description of my pull request', + token: 'my-auth-token', + gitAuthorName: 'test-user', + gitAuthorEmail: 'test-user@sample.com', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts index 3af47853c3..9d2dd915f8 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.test.ts @@ -32,8 +32,7 @@ import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:bitbucketServer:pull-request', () => { const config = new ConfigReader({ @@ -62,7 +61,7 @@ describe('publish:bitbucketServer:pull-request', () => { integrations, config, }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', title: 'Add Scaffolder actions for Bitbucket Server', @@ -71,12 +70,7 @@ describe('publish:bitbucketServer:pull-request', () => { targetBranch: 'master', sourceBranch: 'develop', }, - workspacePath: 'wsp', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const responseOfBranches = { size: 3, limit: 25, diff --git a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts index fc123f0b80..8fddffaba4 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts +++ b/plugins/scaffolder-backend-module-bitbucket-server/src/actions/bitbucketServerPullRequest.ts @@ -31,6 +31,7 @@ import { import fetch, { RequestInit, Response } from 'node-fetch'; import { Config } from '@backstage/config'; import fs from 'fs-extra'; +import { examples } from './bitbucketServerPullRequest.examples'; const createPullRequest = async (opts: { project: string; @@ -220,8 +221,11 @@ export function createPublishBitbucketServerPullRequestAction(options: { targetBranch?: string; sourceBranch: string; token?: string; + gitAuthorName?: string; + gitAuthorEmail?: string; }>({ id: 'publish:bitbucketServer:pull-request', + examples, schema: { input: { type: 'object', @@ -257,6 +261,16 @@ export function createPublishBitbucketServerPullRequestAction(options: { description: 'The token to use for authorization to BitBucket Server', }, + gitAuthorName: { + title: 'Author Name', + type: 'string', + description: `Sets the author name for the commit. The default value is 'Scaffolder'`, + }, + gitAuthorEmail: { + title: 'Author Email', + type: 'string', + description: `Sets the author email for the commit.`, + }, }, }, output: { @@ -276,6 +290,8 @@ export function createPublishBitbucketServerPullRequestAction(options: { description, targetBranch = 'master', sourceBranch, + gitAuthorName, + gitAuthorEmail, } = ctx.input; const { project, repo, host } = parseRepoUrl(repoUrl, integrations); @@ -354,8 +370,12 @@ export function createPublishBitbucketServerPullRequestAction(options: { }; const gitAuthorInfo = { - name: config.getOptionalString('scaffolder.defaultAuthor.name'), - email: config.getOptionalString('scaffolder.defaultAuthor.email'), + name: + gitAuthorName || + config.getOptionalString('scaffolder.defaultAuthor.name'), + email: + gitAuthorEmail || + config.getOptionalString('scaffolder.defaultAuthor.email'), }; const tempDir = await ctx.createTemporaryDirectory(); diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index 5724a668d6..0203b51ac6 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,184 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.8-next.0 + +## 0.2.7 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.2.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.0 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.6 + +## 0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.5 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.5 + +## 0.2.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.2.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.3-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.3-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.2.0 + +### Minor Changes + +- 5eb6882: Split `@backstage/plugin-scaffolder-backend-module-bitbucket` into + `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` and + `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. + + `@backstage/plugin-scaffolder-backend-module-bitbucket` was **deprecated** in favor of these two replacements. + + Please use any of the two replacements depending on your needs. + + ```diff + - backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket')); + + backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket-cloud')); + + backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket-server')); + ``` + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- fc98bb6: Enhanced the pull request action to allow for adding new content to the PR as described in this issue #21762 +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.2.0-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index 526a915fb7..cd6d38643c 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,11 +1,10 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", + "version": "0.2.8-next.0", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", - "version": "0.2.0-next.3", - "deprecated": true, - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, @@ -14,13 +13,13 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-bitbucket" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -28,17 +27,19 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", @@ -53,9 +54,8 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "deprecated": true } diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts index 73325ab5bf..6633246d70 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.test.ts @@ -32,12 +32,11 @@ import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import yaml from 'yaml'; import { sep } from 'path'; import { examples } from './bitbucket.examples'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:bitbucket', () => { const config = new ConfigReader({ @@ -61,17 +60,12 @@ describe('publish:bitbucket', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishBitbucketAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo', repoVisibility: 'private' as const, }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const server = setupServer(); setupRequestMockHandlers(server); @@ -116,7 +110,7 @@ describe('publish:bitbucket', () => { auth: { username: 'x-token-auth', password: 'tokenlols' }, logger: mockContext.logger, commitMessage: 'initial commit', - gitAuthorInfo: {}, + gitAuthorInfo: { email: undefined, name: undefined }, }); }); @@ -157,7 +151,7 @@ describe('publish:bitbucket', () => { auth: { username: 'x-token-auth', password: 'tokenlols' }, logger: mockContext.logger, commitMessage: 'initial commit', - gitAuthorInfo: {}, + gitAuthorInfo: { email: undefined, name: undefined }, }); }); @@ -195,9 +189,9 @@ describe('publish:bitbucket', () => { remoteUrl: 'https://bitbucket.org/workspace/cloneurl', auth: { username: 'x-token-auth', password: 'tokenlols' }, logger: mockContext.logger, - defaultBranch: 'main', + defaultBranch: 'master', commitMessage: 'initial commit', - gitAuthorInfo: {}, + gitAuthorInfo: { email: undefined, name: undefined }, }); }); @@ -235,9 +229,12 @@ describe('publish:bitbucket', () => { remoteUrl: 'https://bitbucket.org/workspace/cloneurl', auth: { username: 'x-token-auth', password: 'your-auth-token' }, logger: mockContext.logger, - defaultBranch: 'main', + defaultBranch: 'master', commitMessage: 'initial commit', - gitAuthorInfo: {}, + gitAuthorInfo: { + email: undefined, + name: undefined, + }, }); }); @@ -274,9 +271,9 @@ describe('publish:bitbucket', () => { expect(initRepoAndPush).toHaveBeenCalledWith({ dir: mockContext.workspacePath, remoteUrl: 'https://bitbucket.org/workspace/cloneurl', - auth: { username: 'x-token-auth', password: 'your-auth-token' }, + auth: { username: 'x-token-auth', password: 'tokenlols' }, logger: mockContext.logger, - defaultBranch: 'main', + defaultBranch: 'master', commitMessage: 'Initial commit with custom message', gitAuthorInfo: { email: undefined, name: undefined }, }); @@ -315,10 +312,10 @@ describe('publish:bitbucket', () => { expect(initRepoAndPush).toHaveBeenCalledWith({ dir: mockContext.workspacePath, remoteUrl: 'https://bitbucket.org/workspace/cloneurl', - auth: { username: 'x-token-auth', password: 'your-auth-token' }, + auth: { username: 'x-token-auth', password: 'tokenlols' }, logger: mockContext.logger, - defaultBranch: 'main', - commitMessage: 'Initial commit with custom message', + defaultBranch: 'master', + commitMessage: 'initial commit', gitAuthorInfo: { email: 'your.email@example.com', name: 'Your Name' }, }); }); diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.ts index 6667afcc9e..12f9472398 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.examples.ts @@ -20,7 +20,7 @@ import yaml from 'yaml'; export const examples: TemplateExample[] = [ { description: - 'Initializes a git repository of contents in workspace and publish it to Bitbucket with default configuration.', + 'Initializes a git repository with the content in the workspace, and publishes it to Bitbucket with the default configuration.', example: yaml.stringify({ steps: [ { @@ -36,7 +36,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Add a description.', + description: 'Initializes a Bitbucket repository with a description.', example: yaml.stringify({ steps: [ { @@ -53,7 +53,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Change visibility of the repository.', + description: + 'Initializes a Bitbucket repository with public repo visibility, if not set defaults to private', example: yaml.stringify({ steps: [ { @@ -63,7 +64,6 @@ export const examples: TemplateExample[] = [ input: { repoUrl: 'bitbucket.org?repo=repo&workspace=workspace&project=project', - description: 'Initialize a git repository', repoVisibility: 'public', }, }, @@ -71,7 +71,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Set the default branch.', + description: + 'Initializes a Bitbucket repository with a default branch, if not set defaults to master', example: yaml.stringify({ steps: [ { @@ -81,8 +82,6 @@ export const examples: TemplateExample[] = [ input: { repoUrl: 'bitbucket.org?repo=repo&workspace=workspace&project=project', - description: 'Initialize a git repository', - repoVisibility: 'public', defaultBranch: 'main', }, }, @@ -90,7 +89,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Specify a source path within the workspace.', + description: + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository', example: yaml.stringify({ steps: [ { @@ -100,9 +100,6 @@ export const examples: TemplateExample[] = [ input: { repoUrl: 'bitbucket.org?repo=repo&workspace=workspace&project=project', - description: 'Initialize a git repository', - repoVisibility: 'public', - defaultBranch: 'main', sourcePath: './repoRoot', }, }, @@ -110,7 +107,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Enable LFS for the repository.', + description: 'Initializes a Bitbucket repository with LFS enabled', example: yaml.stringify({ steps: [ { @@ -119,10 +116,6 @@ export const examples: TemplateExample[] = [ name: 'Publish to Bitbucket', input: { repoUrl: 'hosted.bitbucket.com?project=project&repo=repo', - description: 'Initialize a git repository', - repoVisibility: 'public', - defaultBranch: 'main', - sourcePath: './repoRoot', enableLFS: true, }, }, @@ -130,7 +123,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Provide an authentication token for Bitbucket.', + description: + 'Initializes a Bitbucket repository with a custom authentication token', example: yaml.stringify({ steps: [ { @@ -140,9 +134,6 @@ export const examples: TemplateExample[] = [ input: { repoUrl: 'bitbucket.org?repo=repo&workspace=workspace&project=project', - description: 'Initialize a git repository', - repoVisibility: 'public', - defaultBranch: 'main', token: 'your-auth-token', }, }, @@ -150,7 +141,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Set a custom commit message.', + description: + 'Initializes a Bitbucket repository with an initial commit message, if not set defaults to `initial commit`', example: yaml.stringify({ steps: [ { @@ -160,10 +152,6 @@ export const examples: TemplateExample[] = [ input: { repoUrl: 'bitbucket.org?repo=repo&workspace=workspace&project=project', - description: 'Initialize a git repository', - repoVisibility: 'public', - defaultBranch: 'main', - token: 'your-auth-token', gitCommitMessage: 'Initial commit with custom message', }, }, @@ -171,7 +159,26 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Set a custom author name and email for the commit.', + description: 'Initializes a Bitbucket repository with a custom author', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:bitbucket', + name: 'Publish to Bitbucket', + input: { + repoUrl: + 'bitbucket.org?repo=repo&workspace=workspace&project=project', + gitAuthorName: 'Your Name', + gitAuthorEmail: 'your.email@example.com', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Bitbucket repository with all proporties being set', example: yaml.stringify({ steps: [ { diff --git a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts index d6e068c039..a63d657904 100644 --- a/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts +++ b/plugins/scaffolder-backend-module-bitbucket/src/actions/bitbucket.test.ts @@ -31,9 +31,8 @@ import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:bitbucket', () => { const config = new ConfigReader({ @@ -57,17 +56,12 @@ describe('publish:bitbucket', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishBitbucketAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo', repoVisibility: 'private' as const, }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const server = setupServer(); setupRequestMockHandlers(server); diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index 77ac0d04d9..b001283394 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md @@ -1,5 +1,150 @@ # @backstage/plugin-scaffolder-backend-module-confluence-to-markdown +## 0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.2.15 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.2.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.14-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.2.11 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.2.11-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json index 01b1ec6575..175f12a605 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,26 +1,26 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", + "version": "0.2.19-next.0", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", - "version": "0.2.11-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "backend-plugin-module" }, + "publishConfig": { + "access": "public" + }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-confluence-to-markdown" }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -28,15 +28,19 @@ ] } }, + "files": [ + "dist", + "config.d.ts" + ], "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", + "help": "backstage-cli help", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "help": "backstage-cli help" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -54,11 +58,8 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts index f3bf1fef35..18ff0ad3ec 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.examples.test.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { PassThrough } from 'stream'; import { createConfluenceToMarkdownAction } from './confluenceToMarkdown'; import { getVoidLogger } from '@backstage/backend-common'; import { UrlReader } from '@backstage/backend-common'; @@ -28,6 +27,7 @@ import { setupServer } from 'msw/node'; import { examples } from './confluenceToMarkdown.examples'; import yaml from 'yaml'; import { ActionContext } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('confluence:transform:markdown examples', () => { const baseUrl = `https://confluence.example.com`; @@ -71,14 +71,11 @@ describe('confluence:transform:markdown examples', () => { }), search: jest.fn(), }; - mockContext = { + mockContext = createMockActionContext({ input: yaml.parse(examples[0].example).steps[0].input, workspacePath, logger, - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); mockDir.setContent({ 'workspace/mkdocs.yml': 'File contents' }); }); diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts index 5ce8bb2697..eccb66f79e 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/src/actions/confluence/confluenceToMarkdown.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { PassThrough } from 'stream'; + import { createConfluenceToMarkdownAction } from './confluenceToMarkdown'; import { getVoidLogger } from '@backstage/backend-common'; import { UrlReader } from '@backstage/backend-common'; @@ -26,6 +26,7 @@ import { import type { ActionContext } from '@backstage/plugin-scaffolder-node'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('confluence:transform:markdown', () => { const baseUrl = `https://nodomain.confluence.com`; @@ -69,7 +70,7 @@ describe('confluence:transform:markdown', () => { }), search: jest.fn(), }; - mockContext = { + mockContext = createMockActionContext({ input: { confluenceUrls: [ 'https://nodomain.confluence.com/display/testing/mkdocs', @@ -79,10 +80,7 @@ describe('confluence:transform:markdown', () => { }, workspacePath, logger, - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); mockDir.setContent({ 'workspace/mkdocs.yml': 'File contents' }); }); @@ -221,7 +219,7 @@ describe('confluence:transform:markdown', () => { const action = createConfluenceToMarkdownAction(options); await expect(async () => { await action.handler(mockContext); - }).rejects.toThrow('Request failed with 401 Error'); + }).rejects.toThrow('Request failed with 401 nope'); }); it('should return nothing in results from the first api call and fail', async () => { @@ -284,6 +282,6 @@ describe('confluence:transform:markdown', () => { const action = createConfluenceToMarkdownAction(options); await expect(async () => { await action.handler(mockContext); - }).rejects.toThrow('Request failed with 404 Error'); + }).rejects.toThrow('Request failed with 404 nope'); }); }); diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 9b56be1579..825a90eae1 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,162 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## 0.2.41 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + +## 0.2.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.2.40 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## 0.2.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## 0.2.38 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## 0.2.38-next.2 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 0.2.37-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + +## 0.2.34 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.34-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index c2c061dd04..0b46079953 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,26 +1,26 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", + "version": "0.2.42-next.0", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.34-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "backend-plugin-module" }, + "publishConfig": { + "access": "public" + }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-cookiecutter" }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -28,14 +28,17 @@ ] } }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,10 +56,8 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^11.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.test.ts b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.test.ts index af63ca0e48..fad544488a 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.test.ts +++ b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.test.ts @@ -14,19 +14,16 @@ * limitations under the License. */ -import { - getVoidLogger, - UrlReader, - ContainerRunner, -} from '@backstage/backend-common'; +import { UrlReader, ContainerRunner } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { ScmIntegrations } from '@backstage/integration'; import { createMockDirectory } from '@backstage/backend-test-utils'; -import { PassThrough } from 'stream'; import { createFetchCookiecutterAction } from './cookiecutter'; import { join } from 'path'; import type { ActionContext } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { Writable } from 'stream'; const executeShellCommand = jest.fn(); const commandExists = jest.fn(); @@ -88,7 +85,7 @@ describe('fetch:cookiecutter', () => { beforeEach(() => { jest.resetAllMocks(); - mockContext = { + mockContext = createMockActionContext({ input: { url: 'https://google.com/cookie/cutter', targetPath: 'something', @@ -101,11 +98,7 @@ describe('fetch:cookiecutter', () => { baseUrl: 'somebase', }, workspacePath: mockTmpDir, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir), - }; + }); mockDir.setContent({ template: {} }); commandExists.mockResolvedValue(null); @@ -174,7 +167,7 @@ describe('fetch:cookiecutter', () => { join(mockTmpDir, 'template'), '--verbose', ], - logStream: mockContext.logStream, + logStream: expect.any(Writable), }), ); }); @@ -195,7 +188,7 @@ describe('fetch:cookiecutter', () => { }, workingDir: '/input', envVars: { HOME: '/tmp' }, - logStream: mockContext.logStream, + logStream: expect.any(Writable), }), ); }); diff --git a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts index 8b084e6377..1a49ab0855 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts +++ b/plugins/scaffolder-backend-module-cookiecutter/src/actions/fetch/cookiecutter.ts @@ -25,7 +25,7 @@ import { ScmIntegrations } from '@backstage/integration'; import commandExists from 'command-exists'; import fs from 'fs-extra'; import path, { resolve as resolvePath } from 'path'; -import { Writable } from 'stream'; +import { PassThrough, Writable } from 'stream'; import { createTemplateAction, fetchContents, @@ -245,10 +245,15 @@ export function createFetchCookiecutterAction(options: { _extensions: ctx.input.extensions, }; + const logStream = new PassThrough(); + logStream.on('data', chunk => { + ctx.logger.info(chunk.toString()); + }); + // Will execute the template in ./template and put the result in ./result await cookiecutter.run({ workspacePath: workDir, - logStream: ctx.logStream, + logStream, values: values, imageName: ctx.input.imageName, templateDir: templateDir, diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index ff1eb001eb..9a2d2fd32a 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,138 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.1.9 + +### Patch Changes + +- 0fb178e: Add examples for `publish:gerrit:review` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.6 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.5-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.1.2 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- 8b269e1: Provide default branch when creating repositories. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.2-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 4d153d7903..78ebe2a2ed 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", + "version": "0.1.10-next.0", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", - "version": "0.1.2-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, @@ -13,13 +13,13 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-gerrit" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -27,14 +27,17 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", @@ -46,12 +49,9 @@ "yaml": "^2.0.0" }, "devDependencies": { - "@backstage/backend-common": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "msw": "^1.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts index 2bd7783cb6..c08544843f 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerrit.test.ts @@ -33,9 +33,8 @@ import { setupServer } from 'msw/node'; import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:gerrit', () => { const config = new ConfigReader({ @@ -53,18 +52,13 @@ describe('publish:gerrit', () => { const description = 'for the lols'; const integrations = ScmIntegrations.fromConfig(config); const action = createPublishGerritAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo', description, }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const server = setupServer(); setupRequestMockHandlers(server); diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts new file mode 100644 index 0000000000..d1bc594d54 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts @@ -0,0 +1,245 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + commitAndPushRepo: jest.fn(), + }; +}); + +import { createPublishGerritReviewAction } from './gerritReview'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import { commitAndPushRepo } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import yaml from 'yaml'; +import { examples } from './gerritReview.examples'; + +describe('publish:gerrit:review', () => { + const config = new ConfigReader({ + integrations: { + gerrit: [ + { + host: 'gerrithost.org', + username: 'gerrituser', + password: 'usertoken', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishGerritReviewAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: + 'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo', + gitCommitMessage: 'Review from backstage', + }, + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`Should ${examples[0].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[0].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[1].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[1].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: undefined, + name: 'Test User', + }, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[2].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[2].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: 'test.user@example.com', + name: 'Test User', + }, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[3].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[3].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'develop', + remoteRef: 'refs/for/develop', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/develop', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[4].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[4].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/src`, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[5].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[5].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/src`, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: 'test.user@example.com', + name: 'Test User', + }, + branch: 'develop', + remoteRef: 'refs/for/develop', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/develop', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); +}); diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts new file mode 100644 index 0000000000..fc01fd1ce3 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts @@ -0,0 +1,126 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Creates a new Gerrit review with minimal options', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with gitAuthorName', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with gitAuthorEmail', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with custom branch', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + branch: 'develop', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with custom sourcePath', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + sourcePath: './src', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with all properties', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + branch: 'develop', + sourcePath: './src', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts index eeae3871ee..91236d4cc0 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.test.ts @@ -24,9 +24,8 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishGerritReviewAction } from './gerritReview'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { commitAndPushRepo } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('publish:gerrit:review', () => { const config = new ConfigReader({ @@ -43,18 +42,13 @@ describe('publish:gerrit:review', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishGerritReviewAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo', gitCommitMessage: 'Review from backstage', }, - workspacePath: 'workspace', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts index bd8d0321ab..b4f844b08f 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts @@ -24,6 +24,7 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; +import { examples } from './gerritReview.examples'; const generateGerritChangeId = (): string => { const changeId = crypto.randomBytes(20).toString('hex'); @@ -50,6 +51,7 @@ export function createPublishGerritReviewAction(options: { }>({ id: 'publish:gerrit:review', description: 'Creates a new Gerrit review.', + examples, schema: { input: { type: 'object', diff --git a/plugins/analytics-module-ga/.eslintrc.js b/plugins/scaffolder-backend-module-gitea/.eslintrc.js similarity index 100% rename from plugins/analytics-module-ga/.eslintrc.js rename to plugins/scaffolder-backend-module-gitea/.eslintrc.js diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md new file mode 100644 index 0000000000..09f5faafcd --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -0,0 +1,141 @@ +# @backstage/plugin-scaffolder-backend-module-gitea + +## 0.1.8-next.0 + +### Patch Changes + +- 554af73: Allow defining `repoVisibility` field for the action `publish:gitea` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.1.7 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.1.4 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 9f19476: Updated README +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.1.4-next.2 + +### Patch Changes + +- 9f19476: Updated README +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.1.0 + +### Minor Changes + +- 458bf21: Created a gitea module for the scaffolder. This module provides a new action "publish:gitea" able to create a gitea repository owned by an organization. See: https://gitea.com/api/swagger#/organization/createOrgRepo + +### Patch Changes + +- ef0f44e: - Fix issue for infinite loop when repository already exists + - Log the root cause of error reported by `checkGiteaOrg` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 diff --git a/plugins/scaffolder-backend-module-gitea/README.md b/plugins/scaffolder-backend-module-gitea/README.md new file mode 100644 index 0000000000..5c6aa59b66 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/README.md @@ -0,0 +1,97 @@ +# scaffolder-backend-module-gitea + +Welcome to the `publish:gitea` action of the `scaffolder-gitea-backend`. + +## Getting started + +To use this action, you will have to add the package using the following command to be executed at the root of your backstage project: + +```bash +yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-gitea +``` + +Alternatively, if you use the new backend system, then register it like this: + +```typescript +// packages/backend/src/index.ts +backend.add(import('@backstage/plugin-scaffolder-backend-module-gitea')); +``` + +Configure the action (if not yet done): +(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): + +Before to create a template, include to your `app-config.yaml` file the +gitea host and credentials under the `integrations:` section + +```yaml +integrations: + gitea: + - host: gitea.com + username: '' + password: '' + - host: localhost:3333 + username: '' + password: '' +``` + +**Important**: As backstage will issue `HTTPS/TLS` requests to the gitea instance, it is needed to configure `gitea` with a valid certificate or at least with a +self-signed certificate `gitea cert --host localhost -ca` trusted by a CA authority. Don't forget to set the env var `NODE_EXTRA_CA_CERTS` to point to the CA file before launching backstage or you can set temporarily `NODE_TLS_REJECT_UNAUTHORIZED=0` but this is not recommended for production! + +When done, you can create a template which: + +- Declare the `RepoUrlPicker` within the `spec/parameters` section to select the gitea host and to provide the name of the repository +- Add an `enum` list allowing the user to define the visibility about the repository to be created: `public` or `private`. If this field is omitted, `public` is then used by the action. +- Include in a step the action: `publish:gitea` + +**Warning**: The list of the `allowedOwners` of the `repoUrlPicker` must match the list of the `organizations` which are available on the gitea host ! + +```yaml +kind: Template +metadata: + name: simple-gitea-project + title: Create a gitea repository + description: Create a gitea repository +spec: + owner: guests + type: service + + parameters: + - title: Choose a location + required: + - repoUrl + properties: + repoUrl: + title: Repository Location + type: string + ui:field: RepoUrlPicker + ui:options: + allowedOwners: + - qteam + - qshift + allowedHosts: + - gitea.localtest.me:3333 + + repoVisibility: + title: Visibility of the repository + type: string + default: 'public' + enum: + - 'public' + - 'private' + enumNames: + - 'public' + - 'private' + + steps: + ... + - id: publish + name: Publishing to a gitea git repository + action: publish:gitea + input: + description: This is ${{ parameters.repoUrl | parseRepoUrl | pick('repo') }} + repoVisibility: ${{ parameters.repoVisibility }} + repoUrl: ${{ parameters.repoUrl }} + defaultBranch: main +``` + +Access the newly gitea repository created using the `repoContentsUrl` ;-) diff --git a/plugins/scaffolder-backend-module-gitea/api-report.md b/plugins/scaffolder-backend-module-gitea/api-report.md new file mode 100644 index 0000000000..b5e20b7b13 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/api-report.md @@ -0,0 +1,33 @@ +## API Report File for "@backstage/plugin-scaffolder-backend-module-gitea" + +> 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 { Config } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; +import { ScmIntegrationRegistry } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; + +// @public +export function createPublishGiteaAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}): TemplateAction< + { + repoUrl: string; + description: string; + defaultBranch?: string | undefined; + repoVisibility?: 'private' | 'public' | undefined; + gitCommitMessage?: string | undefined; + gitAuthorName?: string | undefined; + gitAuthorEmail?: string | undefined; + sourcePath?: string | undefined; + }, + JsonObject +>; + +// @public +const giteaModule: () => BackendFeature; +export default giteaModule; +``` diff --git a/plugins/scaffolder-backend-module-gitea/catalog-info.yaml b/plugins/scaffolder-backend-module-gitea/catalog-info.yaml new file mode 100644 index 0000000000..adfcc754fb --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-backend-module-gitea + title: '@backstage/plugin-scaffolder-backend-module-gitea' +spec: + lifecycle: experimental + type: backstage-backend-plugin-module + owner: maintainers diff --git a/plugins/entity-feedback-backend/knip-report.md b/plugins/scaffolder-backend-module-gitea/knip-report.md similarity index 100% rename from plugins/entity-feedback-backend/knip-report.md rename to plugins/scaffolder-backend-module-gitea/knip-report.md diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json new file mode 100644 index 0000000000..6b8740f791 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -0,0 +1,57 @@ +{ + "name": "@backstage/plugin-scaffolder-backend-module-gitea", + "version": "0.1.8-next.0", + "description": "The gitea module for @backstage/plugin-scaffolder-backend", + "backstage": { + "role": "backend-plugin-module" + }, + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-backend-module-gitea" + }, + "license": "Apache-2.0", + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + }, + "main": "src/index.ts", + "types": "src/index.ts", + "typesVersions": { + "*": { + "package.json": [ + "package.json" + ] + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/backend-plugin-api": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/integration": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", + "node-fetch": "^2.6.7", + "yaml": "^2.0.0" + }, + "devDependencies": { + "@backstage/backend-test-utils": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", + "msw": "^1.0.0" + } +} diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts new file mode 100644 index 0000000000..dd4d038ead --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.examples.ts @@ -0,0 +1,176 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: + 'Initializes a git repository with the content in the workspace, and publishes it to Gitea with the default configuration.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + }, + }, + ], + }), + }, + { + description: 'Initializes a Gitea repository with a description.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description: 'Initialize a gitea repository', + }, + }, + ], + }), + }, + { + description: 'Initializes a private Gitea repository ', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + defaultBranch: 'main', + repoVisibility: 'private', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Gitea repository with a default Branch, if not set defaults to main', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + defaultBranch: 'main', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Gitea repository with an initial commit message, if not set defaults to `initial commit`', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + }, + }, + ], + }), + }, + { + description: + 'Initializes a Gitea repository with a repo Author Name, if not set defaults to Scaffolder', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + gitAuthorName: 'John Doe', + }, + }, + ], + }), + }, + { + description: 'Initializes a Gitea repository with a repo Author Email', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + gitAuthorEmail: 'johndoe@email.com', + }, + }, + ], + }), + }, + { + description: + 'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + sourcePath: 'repository/', + }, + }, + ], + }), + }, + { + description: 'Initializes a Gitea repository with all properties being set', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gitea', + name: 'Publish to Gitea', + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description: 'Initialize a gitea repository', + defaultBranch: 'staging', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'John Doe', + gitAuthorEmail: 'johndoe@email.com', + sourcePath: 'repository/', + repoVisibility: 'public', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts new file mode 100644 index 0000000000..8a72265df0 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.test.ts @@ -0,0 +1,227 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import { createPublishGiteaAction } from './gitea'; +import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { rest } from 'msw'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { setupServer } from 'msw/node'; + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +describe('publish:gitea', () => { + const config = new ConfigReader({ + integrations: { + gitea: [ + { + host: 'gitea.com', + username: 'gitea_user', + password: 'gitea_password', + }, + ], + }, + }); + + const description = 'for the lols'; + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishGiteaAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description, + }, + }); + const mockContextWithPublicRepoVisibility = createMockActionContext({ + input: { + repoUrl: 'gitea.com?repo=repo&owner=owner', + description, + private: false, + }, + }); + + const server = setupServer(); + setupRequestMockHandlers(server); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should throw an error when the repoUrl is not well formed', async () => { + await expect( + action.handler({ + ...mockContext, + input: { repoUrl: 'gitea.com?owner=o', description }, + }), + ).rejects.toThrow(/missing repo/); + }); + + it('should throw if there is no integration config provided for missing.com host', async () => { + await expect( + action.handler({ + ...mockContext, + input: { repoUrl: 'missing.com?repo=repo', description }, + }), + ).rejects.toThrow(/No matching integration configuration/); + }); + + it('should throw if there is no repositoryId returned', async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'gitea_user', password: 'gitea_password' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gitea.com/org1/repo/src/branch/main/', + ); + }); + + it('should create a Gitea repository where visibility is public', async () => { + server.use( + rest.get('https://gitea.com/api/v1/orgs/org1', (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({ + id: 1, + name: 'org1', + visibility: 'public', + repo_admin_change_team_access: false, + username: 'org1', + }), + ); + }), + rest.get( + 'https://gitea.com/org1/repo/src/branch/main', + (_req, res, ctx) => { + return res( + ctx.status(200), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }, + ), + rest.post('https://gitea.com/api/v1/orgs/org1/repos', (req, res, ctx) => { + // Basic auth must match the user and password defined part of the config + expect(req.headers.get('Authorization')).toBe( + 'basic Z2l0ZWFfdXNlcjpnaXRlYV9wYXNzd29yZA==', + ); + expect(req.body).toEqual({ + name: 'repo', + private: false, + description, + }); + return res( + ctx.status(201), + ctx.set('Content-Type', 'application/json'), + ctx.json({}), + ); + }), + ); + + await action.handler({ + ...mockContextWithPublicRepoVisibility, + input: { + ...mockContextWithPublicRepoVisibility.input, + repoUrl: 'gitea.com?repo=repo&owner=org1', + }, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContextWithPublicRepoVisibility.workspacePath, + remoteUrl: 'https://gitea.com/org1/repo.git', + defaultBranch: 'main', + auth: { username: 'gitea_user', password: 'gitea_password' }, + logger: mockContextWithPublicRepoVisibility.logger, + commitMessage: expect.stringContaining('initial commit\n\nChange-Id:'), + gitAuthorInfo: { + email: undefined, + name: undefined, + }, + }); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts new file mode 100644 index 0000000000..6b29ff2a4c --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/gitea.ts @@ -0,0 +1,372 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InputError } from '@backstage/errors'; +import { Config } from '@backstage/config'; +import { + getGiteaRequestOptions, + GiteaIntegrationConfig, + ScmIntegrationRegistry, +} from '@backstage/integration'; +import { + ActionContext, + createTemplateAction, + getRepoSourceDirectory, + initRepoAndPush, + parseRepoUrl, +} from '@backstage/plugin-scaffolder-node'; +import { examples } from './gitea.examples'; +import crypto from 'crypto'; + +const checkGiteaContentUrl = async ( + config: GiteaIntegrationConfig, + options: { + owner?: string; + repo: string; + defaultBranch?: string; + }, +): Promise => { + const { owner, repo, defaultBranch } = options; + let response: Response; + const getOptions: RequestInit = { + method: 'GET', + }; + + try { + response = await fetch( + `${config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}`, + getOptions, + ); + } catch (e) { + throw new Error( + `Unable to get the repository: ${owner}/${repo} metadata , ${e}`, + ); + } + return response; +}; + +const checkGiteaOrg = async ( + config: GiteaIntegrationConfig, + options: { + owner: string; + }, +): Promise => { + const { owner } = options; + let response: Response; + // check first if the org = owner exists + const getOptions: RequestInit = { + method: 'GET', + headers: { + ...getGiteaRequestOptions(config).headers, + 'Content-Type': 'application/json', + }, + }; + try { + response = await fetch( + `${config.baseUrl}/api/v1/orgs/${owner}`, + getOptions, + ); + } catch (e) { + throw new Error( + `Unable to get the Organization: ${owner}; Error cause: ${e.message}, code: ${e.cause.code}`, + ); + } + if (response.status !== 200) { + throw new Error( + `Organization ${owner} do not exist. Please create it first !`, + ); + } +}; + +const createGiteaProject = async ( + config: GiteaIntegrationConfig, + options: { + projectName: string; + owner?: string; + repoVisibility?: string; + description: string; + }, +): Promise => { + const { projectName, description, owner, repoVisibility } = options; + + /* + Several options exist to create a repository using either the user or organisation + User: https://gitea.com/api/swagger#/user/createCurrentUserRepo + Api: URL/api/v1/user/repos + Remark: The user is the username defined part of the backstage integration config for the gitea URL ! + + Org: https://gitea.com/api/swagger#/organization/createOrgRepo + Api: URL/api/v1/orgs/${org_owner}/repos + This is the default scenario that we support currently + */ + let response: Response; + let isPrivate: boolean; + + if (repoVisibility === 'private') { + isPrivate = true; + } else if (repoVisibility === 'public') { + isPrivate = false; + } else { + // Provide a default value if repoVisibility is neither "private" nor "public" + isPrivate = false; + } + + const postOptions: RequestInit = { + method: 'POST', + body: JSON.stringify({ + name: projectName, + description, + private: isPrivate, + }), + headers: { + ...getGiteaRequestOptions(config).headers, + 'Content-Type': 'application/json', + }, + }; + try { + response = await fetch( + `${config.baseUrl}/api/v1/orgs/${owner}/repos`, + postOptions, + ); + } catch (e) { + throw new Error(`Unable to create repository, ${e}`); + } + if (response.status !== 201) { + throw new Error( + `Unable to create repository, ${response.status} ${ + response.statusText + }, ${await response.text()}`, + ); + } +}; + +const generateCommitMessage = ( + config: Config, + commitSubject?: string, +): string => { + const changeId = crypto.randomBytes(20).toString('hex'); + const msg = `${ + config.getOptionalString('scaffolder.defaultCommitMessage') || commitSubject + }\n\nChange-Id: I${changeId}`; + return msg; +}; + +async function checkAvailabilityGiteaRepository( + maxDuration: number, + integrationConfig: GiteaIntegrationConfig, + options: { + owner?: string; + repo: string; + defaultBranch: string; + ctx: ActionContext; + }, +) { + const startTimestamp = Date.now(); + + const { owner, repo, defaultBranch, ctx } = options; + const sleep = (ms: number | undefined) => new Promise(r => setTimeout(r, ms)); + let response: Response; + + while (Date.now() - startTimestamp < maxDuration) { + if (ctx.signal?.aborted) return; + + response = await checkGiteaContentUrl(integrationConfig, { + owner, + repo, + defaultBranch, + }); + + if (response.status !== 200) { + // Repository is not yet available/accessible ... + await sleep(1000); + } else { + // Gitea repository exists ! + break; + } + } +} + +/** + * Creates a new action that initializes a git repository using the content of the workspace. + * and publishes it to a Gitea instance. + * @public + */ +export function createPublishGiteaAction(options: { + integrations: ScmIntegrationRegistry; + config: Config; +}) { + const { integrations, config } = options; + + return createTemplateAction<{ + repoUrl: string; + description: string; + defaultBranch?: string; + repoVisibility?: 'private' | 'public'; + gitCommitMessage?: string; + gitAuthorName?: string; + gitAuthorEmail?: string; + sourcePath?: string; + }>({ + id: 'publish:gitea', + description: + 'Initializes a git repository using the content of the workspace, and publishes it to Gitea.', + examples, + schema: { + input: { + type: 'object', + required: ['repoUrl'], + properties: { + repoUrl: { + title: 'Repository Location', + type: 'string', + }, + description: { + title: 'Repository Description', + type: 'string', + }, + defaultBranch: { + title: 'Default Branch', + type: 'string', + description: `Sets the default branch on the repository. The default value is 'main'`, + }, + repoVisibility: { + title: 'Repository Visibility', + description: `Sets the visibility of the repository. The default value is 'public'.`, + type: 'string', + enum: ['private', 'public'], + }, + gitCommitMessage: { + title: 'Git Commit Message', + type: 'string', + description: `Sets the commit message on the repository. The default value is 'initial commit'`, + }, + gitAuthorName: { + title: 'Default Author Name', + type: 'string', + description: `Sets the default author name for the commit. The default value is 'Scaffolder'`, + }, + gitAuthorEmail: { + title: 'Default Author Email', + type: 'string', + description: `Sets the default author email for the commit.`, + }, + sourcePath: { + title: 'Source Path', + type: 'string', + description: `Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.`, + }, + }, + }, + output: { + type: 'object', + properties: { + remoteUrl: { + title: 'A URL to the repository with the provider', + type: 'string', + }, + repoContentsUrl: { + title: 'A URL to the root of the repository', + type: 'string', + }, + commitHash: { + title: 'The git commit hash of the initial commit', + type: 'string', + }, + }, + }, + }, + async handler(ctx) { + const { + repoUrl, + description, + defaultBranch = 'main', + repoVisibility = 'public', + gitAuthorName, + gitAuthorEmail, + gitCommitMessage = 'initial commit', + sourcePath, + } = ctx.input; + + const { repo, host, owner } = parseRepoUrl(repoUrl, integrations); + + const integrationConfig = integrations.gitea.byHost(host); + if (!integrationConfig) { + throw new InputError( + `No matching integration configuration for host ${host}, please check your integrations config`, + ); + } + const { username, password } = integrationConfig.config; + + if (!username || !password) { + throw new Error('Credentials for the gitea ${host} required.'); + } + + // check if the org exists within the gitea server + if (owner) { + await checkGiteaOrg(integrationConfig.config, { owner }); + } + + await createGiteaProject(integrationConfig.config, { + description, + repoVisibility, + owner: owner, + projectName: repo, + }); + + const auth = { + username: username, + password: password, + }; + const gitAuthorInfo = { + name: gitAuthorName + ? gitAuthorName + : config.getOptionalString('scaffolder.defaultAuthor.name'), + email: gitAuthorEmail + ? gitAuthorEmail + : config.getOptionalString('scaffolder.defaultAuthor.email'), + }; + // The owner to be used should be either the org name or user authenticated with the gitea server + const remoteUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}.git`; + const commitResult = await initRepoAndPush({ + dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath), + remoteUrl, + auth, + defaultBranch, + logger: ctx.logger, + commitMessage: generateCommitMessage(config, gitCommitMessage), + gitAuthorInfo, + }); + + // Check if the gitea repo URL is available before to exit + const maxDuration = 20000; // 20 seconds + await checkAvailabilityGiteaRepository( + maxDuration, + integrationConfig.config, + { + owner, + repo, + defaultBranch, + ctx, + }, + ); + + const repoContentsUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}/src/branch/${defaultBranch}/`; + ctx.output('remoteUrl', remoteUrl); + ctx.output('commitHash', commitResult?.commitHash); + ctx.output('repoContentsUrl', repoContentsUrl); + }, + }); +} diff --git a/plugins/scaffolder-backend-module-gitea/src/actions/index.ts b/plugins/scaffolder-backend-module-gitea/src/actions/index.ts new file mode 100644 index 0000000000..ccf7f23fab --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/actions/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './gitea'; diff --git a/plugins/scaffolder-backend-module-gitea/src/index.ts b/plugins/scaffolder-backend-module-gitea/src/index.ts new file mode 100644 index 0000000000..0b68069178 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A module for the scaffolder backend that lets you interact with gitea + * + * @packageDocumentation + */ + +export * from './actions'; +export { giteaModule as default } from './module'; diff --git a/plugins/scaffolder-backend-module-gitea/src/module.ts b/plugins/scaffolder-backend-module-gitea/src/module.ts new file mode 100644 index 0000000000..658f240471 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitea/src/module.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; +import { createPublishGiteaAction } from './actions'; +import { ScmIntegrations } from '@backstage/integration'; + +/** + * @public + * The Gitea Module for the Scaffolder Backend + */ +export const giteaModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'gitea', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + config: coreServices.rootConfig, + }, + async init({ scaffolder, config }) { + const integrations = ScmIntegrations.fromConfig(config); + scaffolder.addActions( + createPublishGiteaAction({ + integrations, + config, + }), + ); + }, + }); + }, +}); diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index c67fdc3a91..8fa18de2bb 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,162 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.2.8-next.0 + +### Patch Changes + +- 5d99272: Update local development dependencies. +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.2.7 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.2.7-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.2.4 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 35fe005: Export `getOctokitOptions` for easy re-use of Octokit configuration handling +- 1753898: Updated dependency `octokit-plugin-create-pull-request` to `^5.0.0`. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.2.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.4-next.1 + +### Patch Changes + +- 35fe005: Export `getOctokitOptions` for easy re-use of Octokit configuration handling +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.3-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 1753898: Updated dependency `octokit-plugin-create-pull-request` to `^5.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.2.0 + +### Minor Changes + +- fd5eb1c: Allow to force the creation of a pull request from a forked repository +- 3d5c668: support oidc customization + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 8472188: Added or fixed the `repository` field in `package.json`. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.2.0-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-github/api-report.md b/plugins/scaffolder-backend-module-github/api-report.md index de03894a5a..0284c362eb 100644 --- a/plugins/scaffolder-backend-module-github/api-report.md +++ b/plugins/scaffolder-backend-module-github/api-report.md @@ -9,6 +9,7 @@ import { createPullRequest } from 'octokit-plugin-create-pull-request'; import { GithubCredentialsProvider } from '@backstage/integration'; import { JsonObject } from '@backstage/types'; import { Octokit } from 'octokit'; +import { OctokitOptions } from '@octokit/core/dist-types/types'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { ScmIntegrations } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; @@ -392,6 +393,14 @@ export const createPublishGithubPullRequestAction: ( JsonObject >; +// @public +export function getOctokitOptions(options: { + integrations: ScmIntegrationRegistry; + credentialsProvider?: GithubCredentialsProvider; + token?: string; + repoUrl: string; +}): Promise; + // @public const githubModule: () => BackendFeature; export default githubModule; diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index d10a7d5278..925efa8c37 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", + "version": "0.2.8-next.0", "description": "The github module for @backstage/plugin-scaffolder-backend", - "version": "0.2.0-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, @@ -13,13 +13,13 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-github" }, - "backstage": { - "role": "backend-plugin-module" - }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -27,14 +27,17 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -46,19 +49,15 @@ "@octokit/webhooks": "^10.0.0", "libsodium-wrappers": "^0.7.11", "octokit": "^3.0.0", - "octokit-plugin-create-pull-request": "^3.10.0", - "winston": "^3.2.1", + "octokit-plugin-create-pull-request": "^5.0.0", "yaml": "^2.0.0" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@types/libsodium-wrappers": "^0.7.10", "fs-extra": "^11.2.0", - "jest-when": "^3.1.0", "jsonschema": "^1.2.6" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts index 84d8e507b3..ea92201eec 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHelpers.ts @@ -16,13 +16,13 @@ import { assertError } from '@backstage/errors'; import { Octokit } from 'octokit'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; type BranchProtectionOptions = { client: Octokit; owner: string; repoName: string; - logger: Logger; + logger: LoggerService; requireCodeOwnerReviews: boolean; requiredStatusCheckContexts?: string[]; bypassPullRequestAllowances?: { diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts index 7ea5e025ce..6a6c6daf13 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts @@ -36,14 +36,13 @@ import { TemplateAction, initRepoAndPush, } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; import { createPublishGithubAction } from './github'; import { examples } from './github.examples'; import yaml from 'yaml'; @@ -101,19 +100,14 @@ describe('publish:github', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', description: 'description', repoVisibility: 'private' as const, access: 'owner/blam', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { initRepoAndPushMocked.mockResolvedValue({ diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts index 65f2ccdaa3..f8d16c5b5f 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts @@ -20,7 +20,7 @@ import yaml from 'yaml'; export const examples: TemplateExample[] = [ { description: - 'Initializes a git repository of contents in workspace and publish it to GitHub with default configuration.', + 'Initializes a git repository with the content in the workspace, and publishes it to GitHub with the default configuration.', example: yaml.stringify({ steps: [ { @@ -35,7 +35,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Add a description.', + description: 'Initializes a GitHub repository with a description.', example: yaml.stringify({ steps: [ { @@ -51,7 +51,8 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Change visibility of the repository.', + description: + 'Initializes a GitHub repository with public repo visibility, if not set defaults to private', example: yaml.stringify({ steps: [ { @@ -60,7 +61,6 @@ export const examples: TemplateExample[] = [ name: 'Publish to GitHub', input: { repoUrl: 'github.com?repo=repo&owner=owner', - description: 'Initialize a git repository', repoVisibility: 'public', }, }, diff --git a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts index 75d9b74a8b..9eda9a2eb0 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/github.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/github.test.ts @@ -34,15 +34,13 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { }); import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { when } from 'jest-when'; -import { PassThrough } from 'stream'; import { createPublishGithubAction } from './github'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { @@ -103,19 +101,14 @@ describe('publish:github', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', description: 'description', repoVisibility: 'private' as const, access: 'owner/blam', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { initRepoAndPushMocked.mockResolvedValue({ @@ -762,15 +755,13 @@ describe('publish:github', () => { }, }); - when(mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg) - .calledWith({ - org: 'owner', - owner: 'owner', - repo: 'repo', - team_slug: 'robot-1', - permission: 'pull', - }) - .mockRejectedValueOnce(new Error('Something bad happened') as never); + mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg.mockImplementation( + async opts => { + if (opts.team_slug === 'robot-1') { + throw Error('Something bad happened'); + } + }, + ); await action.handler({ ...mockContext, diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.test.ts index fe04142a98..1e59037c04 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.examples.test.ts @@ -20,10 +20,9 @@ import { GithubCredentialsProvider, } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { PassThrough } from 'stream'; import { createGithubActionsDispatchAction } from './githubActionsDispatch'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import yaml from 'yaml'; import { examples } from './githubActionsDispatch.examples'; @@ -56,18 +55,13 @@ describe('github:actions:dispatch', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', workflowId: 'a-workflow-id', branchOrTagName: 'main', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.test.ts index 3d59e43695..7f0d9b0490 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubActionsDispatch.test.ts @@ -20,9 +20,8 @@ import { GithubCredentialsProvider, } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createGithubActionsDispatchAction } from './githubActionsDispatch'; const mockOctokit = { @@ -54,18 +53,13 @@ describe('github:actions:dispatch', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', workflowId: 'a-workflow-id', branchOrTagName: 'main', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts index 612f68dea2..a686ea7f6d 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.examples.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, @@ -22,8 +21,8 @@ import { ScmIntegrations, } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { PassThrough } from 'stream'; import { createGithubAutolinksAction } from './githubAutolinks'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { examples } from './githubAutolinks.examples'; import yaml from 'yaml'; @@ -55,9 +54,12 @@ describe('github:autolinks:create', () => { const integrations = ScmIntegrations.fromConfig(config); let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; + const input = yaml.parse(examples[0].example).steps[0].input; + const mockContext = createMockActionContext({ + input, + }); it('should call the githubApis for creating autolink reference', async () => { - const input = yaml.parse(examples[0].example).steps[0].input; githubCredentialsProvider = DefaultGithubCredentialsProvider.fromIntegrations(integrations); action = createGithubAutolinksAction({ @@ -70,14 +72,7 @@ describe('github:autolinks:create', () => { id: '1', }, }); - await action.handler({ - input, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }); + await action.handler(mockContext); expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({ owner: 'owner', diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts index 95c0226104..56115c156c 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubAutolinks.test.ts @@ -14,15 +14,15 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; +import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { PassThrough } from 'stream'; import { createGithubAutolinksAction } from './githubAutolinks'; const mockOctokit = { @@ -53,13 +53,7 @@ describe('github:autolinks:create', () => { const integrations = ScmIntegrations.fromConfig(config); let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const workspacePath = createMockDirectory().resolve('workspace'); it('should call the githubApis for creating alphanumeric autolink reference', async () => { githubCredentialsProvider = @@ -74,14 +68,16 @@ describe('github:autolinks:create', () => { id: '1', }, }); - await action.handler({ - input: { - repoUrl: 'github.com?repo=repo&owner=owner', - keyPrefix: 'TICKET-', - urlTemplate: 'https://example.com/TICKET?query=', - }, - ...mockContext, - }); + await action.handler( + createMockActionContext({ + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + keyPrefix: 'TICKET-', + urlTemplate: 'https://example.com/TICKET?query=', + }, + workspacePath, + }), + ); expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({ owner: 'owner', @@ -104,15 +100,17 @@ describe('github:autolinks:create', () => { id: '1', }, }); - await action.handler({ - input: { - repoUrl: 'github.com?repo=repo&owner=owner', - keyPrefix: 'TICKET-', - urlTemplate: 'https://example.com/TICKET?query=', - isAlphanumeric: false, - }, - ...mockContext, - }); + await action.handler( + createMockActionContext({ + input: { + repoUrl: 'github.com?repo=repo&owner=owner', + keyPrefix: 'TICKET-', + urlTemplate: 'https://example.com/TICKET?query=', + isAlphanumeric: false, + }, + workspacePath, + }), + ); expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({ owner: 'owner', diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.test.ts index c8e2a5f102..62e79dcd68 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.examples.test.ts @@ -14,11 +14,10 @@ * limitations under the License. */ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createGithubDeployKeyAction } from './githubDeployKey'; import yaml from 'yaml'; import { examples } from './githubDeployKey.examples'; -import { PassThrough } from 'stream'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -55,13 +54,7 @@ describe('Usage examples', () => { const integrations = ScmIntegrations.fromConfig(config); let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.test.ts index 4df9294ff5..798aa7705e 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.test.ts @@ -14,10 +14,9 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; import { createGithubDeployKeyAction } from './githubDeployKey'; -import { getVoidLogger } from '@backstage/backend-common'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -55,19 +54,14 @@ describe('github:deployKey:create', () => { const integrations = ScmIntegrations.fromConfig(config); let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repository&owner=owner', publicKey: 'pubkey', privateKey: 'privkey', deployKeyName: 'Push Tags', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts index 9d5dbfd35c..ecb4e9f092 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { PassThrough } from 'stream'; import { createGithubEnvironmentAction } from './githubEnvironment'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -59,13 +58,7 @@ describe('github:environment:create examples', () => { const integrations = ScmIntegrations.fromConfig(config); let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); beforeEach(() => { mockOctokit.rest.actions.getEnvironmentPublicKey.mockResolvedValue({ diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts index 8ec3d84e36..16872525b4 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts @@ -14,9 +14,8 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; import { createGithubEnvironmentAction } from './githubEnvironment'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -58,17 +57,12 @@ describe('github:environment:create', () => { const integrations = ScmIntegrations.fromConfig(config); let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repository&owner=owner', name: 'envname', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { mockOctokit.rest.actions.getEnvironmentPublicKey.mockResolvedValue({ diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.test.ts index 9d74d53c6d..75ac6025ce 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.examples.test.ts @@ -15,14 +15,13 @@ */ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; import { createGithubIssuesLabelAction } from './githubIssuesLabel'; import yaml from 'yaml'; import { examples } from './githubIssuesLabel.examples'; @@ -64,13 +63,7 @@ describe('github:issues:label examples', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.test.ts index 3da16e677a..13c7df68cb 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubIssuesLabel.test.ts @@ -20,10 +20,9 @@ import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, } from '@backstage/integration'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { PassThrough } from 'stream'; import { getOctokitOptions } from './helpers'; jest.mock('./helpers', () => { @@ -62,18 +61,13 @@ describe('github:issues:label', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', number: '1', labels: ['label1', 'label2'], }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts index 7e5d107026..dd07c88a70 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.examples.test.ts @@ -15,14 +15,13 @@ */ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createPublishGithubPullRequestAction } from './githubPullRequest'; import yaml from 'yaml'; import { examples } from './githubPullRequest.examples'; @@ -57,13 +56,7 @@ describe('publish:github:pull-request examples', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); let fakeClient: { createPullRequest: jest.Mock; rest: { diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts index 3fe4f62e04..c9d1498187 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createRootLogger, getRootLogger } from '@backstage/backend-common'; +import { createRootLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { GithubCredentialsProvider, @@ -25,9 +25,9 @@ import { TemplateAction, } from '@backstage/plugin-scaffolder-node'; import fs from 'fs-extra'; -import { Writable } from 'stream'; import { createPublishGithubPullRequestAction } from './githubPullRequest'; import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; // Make sure root logger is initialized ahead of FS mock createRootLogger(); @@ -131,14 +131,7 @@ describe('createPublishGithubPullRequestAction', () => { [workspacePath]: { 'file.txt': 'Hello there!' }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { @@ -196,14 +189,7 @@ describe('createPublishGithubPullRequestAction', () => { [workspacePath]: { 'file.txt': 'Hello there!' }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { @@ -263,14 +249,7 @@ describe('createPublishGithubPullRequestAction', () => { }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request with only relevant files', async () => { @@ -322,14 +301,7 @@ describe('createPublishGithubPullRequestAction', () => { [workspacePath]: { 'file.txt': 'Hello there!' }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { await instance.handler(ctx); @@ -382,14 +354,7 @@ describe('createPublishGithubPullRequestAction', () => { mockDir.setContent({ [workspacePath]: {} }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request and requests a review from the given reviewers', async () => { @@ -434,14 +399,7 @@ describe('createPublishGithubPullRequestAction', () => { mockDir.setContent({ [workspacePath]: {} }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('does not call the API endpoint for requesting reviewers', async () => { @@ -470,14 +428,7 @@ describe('createPublishGithubPullRequestAction', () => { }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { await instance.handler(ctx); @@ -526,14 +477,7 @@ describe('createPublishGithubPullRequestAction', () => { }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { await instance.handler(ctx); @@ -592,14 +536,7 @@ describe('createPublishGithubPullRequestAction', () => { }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { await instance.handler(ctx); @@ -653,14 +590,7 @@ describe('createPublishGithubPullRequestAction', () => { [workspacePath]: { 'file.txt': 'Hello there!' }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { @@ -705,14 +635,7 @@ describe('createPublishGithubPullRequestAction', () => { [workspacePath]: { 'file.txt': 'Hello there!' }, }); - ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + ctx = createMockActionContext({ input, workspacePath }); }); it('creates a pull request', async () => { diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts index 6a5c939905..b4aa03b602 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubPullRequest.ts @@ -26,12 +26,12 @@ import { serializeDirectoryContents, } from '@backstage/plugin-scaffolder-node'; import { Octokit } from 'octokit'; -import { InputError, CustomErrorBase } from '@backstage/errors'; +import { CustomErrorBase, InputError } from '@backstage/errors'; import { resolveSafeChildPath } from '@backstage/backend-common'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; import { getOctokitOptions } from './helpers'; -import { Logger } from 'winston'; import { examples } from './githubPullRequest.examples'; +import { LoggerService } from '@backstage/backend-plugin-api'; export type Encoding = 'utf-8' | 'base64'; @@ -372,7 +372,7 @@ export const createPublishGithubPullRequestAction = ( reviewers: string[] | undefined, teamReviewers: string[] | undefined, client: Octokit, - logger: Logger, + logger: LoggerService, ) { try { const result = await client.rest.pulls.requestReviewers({ diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts index 2377e9a7eb..843a32f758 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.examples.test.ts @@ -23,14 +23,13 @@ jest.mock('./gitHelpers', () => { }; }); -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createGithubRepoCreateAction } from './githubRepoCreate'; import { entityRefToName } from './gitHelpers'; import yaml from 'yaml'; @@ -82,16 +81,11 @@ describe('github:repo:create examples', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { githubCredentialsProvider = diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts index c72a969e96..1750acdb9a 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoCreate.test.ts @@ -15,6 +15,7 @@ */ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; jest.mock('./gitHelpers', () => { return { @@ -23,15 +24,12 @@ jest.mock('./gitHelpers', () => { }; }); -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { when } from 'jest-when'; -import { PassThrough } from 'stream'; import { createGithubRepoCreateAction } from './githubRepoCreate'; import { entityRefToName } from './gitHelpers'; @@ -82,19 +80,14 @@ describe('github:repo:create', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', description: 'description', repoVisibility: 'private' as const, access: 'owner/blam', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { githubCredentialsProvider = @@ -484,15 +477,13 @@ describe('github:repo:create', () => { }, }); - when(mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg) - .calledWith({ - org: 'owner', - owner: 'owner', - repo: 'repo', - team_slug: 'robot-1', - permission: 'pull', - }) - .mockRejectedValueOnce(new Error('Something bad happened') as never); + mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg.mockImplementation( + async opts => { + if (opts.team_slug === 'robot-1') { + throw Error('Something bad happened'); + } + }, + ); await action.handler({ ...mockContext, diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts index 8f8c9bf8af..691cebd367 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.examples.test.ts @@ -29,14 +29,13 @@ import { TemplateAction, initRepoAndPush, } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; import { createGithubRepoPushAction } from './githubRepoPush'; import { examples } from './githubRepoPush.examples'; import yaml from 'yaml'; @@ -102,13 +101,7 @@ describe('github:repo:push examples', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts index e16da0981d..206d4f067d 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubRepoPush.test.ts @@ -59,14 +59,13 @@ import { TemplateAction, initRepoAndPush, } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; import { enableBranchProtectionOnDefaultRepoBranch } from './gitHelpers'; import { createGithubRepoPushAction } from './githubRepoPush'; @@ -103,19 +102,14 @@ describe('github:repo:push', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repository&owner=owner', description: 'description', repoVisibility: 'private' as const, access: 'owner/blam', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.test.ts index ce1fe76c53..d58d737f93 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.examples.test.ts @@ -14,14 +14,13 @@ * limitations under the License. */ import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; -import { PassThrough } from 'stream'; import { createGithubWebhookAction } from './githubWebhook'; import yaml from 'yaml'; import { examples } from './githubWebhook.examples'; @@ -56,13 +55,7 @@ describe('github:webhook examples', () => { let githubCredentialsProvider: GithubCredentialsProvider; let action: TemplateAction; - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.test.ts index 7901210a6e..cbdcee6af1 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubWebhook.test.ts @@ -20,10 +20,9 @@ import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, } from '@backstage/integration'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { PassThrough } from 'stream'; const mockOctokit = { rest: { @@ -66,17 +65,12 @@ describe('github:repository:webhook:create', () => { }); }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'github.com?repo=repo&owner=owner', webhookUrl: 'https://example.com/payload', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); it('should call the githubApi for creating repository Webhook', async () => { const repoUrl = 'github.com?repo=repo&owner=owner'; diff --git a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts index ec282c74d9..dd2f4a9f76 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/helpers.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/helpers.ts @@ -23,7 +23,6 @@ import { } from '@backstage/integration'; import { OctokitOptions } from '@octokit/core/dist-types/types'; import { Octokit } from 'octokit'; -import { Logger } from 'winston'; import { getRepoSourceDirectory, @@ -36,9 +35,15 @@ import { enableBranchProtectionOnDefaultRepoBranch, entityRefToName, } from './gitHelpers'; +import { LoggerService } from '@backstage/backend-plugin-api'; const DEFAULT_TIMEOUT_MS = 60_000; +/** + * Helper for generating octokit configuration options for given repoUrl. + * If no token is provided, it will attempt to get a token from the credentials provider. + * @public + */ export async function getOctokitOptions(options: { integrations: ScmIntegrationRegistry; credentialsProvider?: GithubCredentialsProvider; @@ -143,7 +148,7 @@ export async function createGithubRepoWithCollaboratorsAndTopics( includeClaimKeys?: string[]; } | undefined, - logger: Logger, + logger: LoggerService, ) { // eslint-disable-next-line testing-library/no-await-sync-queries const user = await client.rest.users.getByUsername({ diff --git a/plugins/scaffolder-backend-module-github/src/actions/index.ts b/plugins/scaffolder-backend-module-github/src/actions/index.ts index 27eaca0e85..40a0da5455 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/index.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/index.ts @@ -28,3 +28,5 @@ export { } from './githubPullRequest'; export { createPublishGithubAction } from './github'; export { createGithubAutolinksAction } from './githubAutolinks'; + +export { getOctokitOptions } from './helpers'; diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 003926a59c..f155b66762 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,162 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.3.4-next.0 + +### Patch Changes + +- ffc73ec: Add examples for `gitlab:repo:push` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + +## 0.3.3 + +### Patch Changes + +- aa514d1: Add examples for `publish:gitlab:merge-request` scaffolder action & improve related tests +- 52f40ea: Add examples for `gitlab:group:ensureExists` scaffolder action & improve related tests +- 33f958a: Improve examples to ensure consistency across all publish actions +- d112225: Add examples for `gitlab:projectDeployToken:create` scaffolder action & improve related tests +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.3.3-next.1 + +### Patch Changes + +- 33f958a: Improve examples to ensure consistency across all publish actions +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + +## 0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + +## 0.3.0 + +### Minor Changes + +- 6bfb7b1: Output the `iid` as `issuesIid` from the `gitlab:issues:create` action + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.3.0-next.2 + +### Minor Changes + +- 6bfb7b1: Output the `iid` as `issuesIid` from the `gitlab:issues:create` action + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.2.16-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + +## 0.2.13 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 1cd2740: Use the Gitbeaker library for `gitlab:projectAccessToken:create` action, enabling the `expiresAt` option +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.2.13-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index f7ec2edac8..4fb965eb13 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -48,6 +48,7 @@ export const createGitlabIssueAction: (options: { { issueUrl: string; issueId: number; + issueIid: number; } >; diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 94d1891bf7..95059f2513 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -1,28 +1,28 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitlab", - "version": "0.2.13-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, + "version": "0.3.4-next.0", "backstage": { "role": "backend-plugin-module" }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-gitlab" }, - "keywords": [ - "backstage" - ], + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -30,14 +30,17 @@ ] } }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -57,9 +60,6 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", - "jest-date-mock": "^1.0.8" - }, - "files": [ - "dist" - ] + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" + } } diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.examples.test.ts new file mode 100644 index 0000000000..2d077c7400 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.examples.test.ts @@ -0,0 +1,198 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createGitlabGroupEnsureExistsAction } from './createGitlabGroupEnsureExistsAction'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ConfigReader } from '@backstage/core-app-api'; +import { ScmIntegrations } from '@backstage/integration'; +import yaml from 'yaml'; +import { examples } from './createGitlabGroupEnsureExistsAction.examples'; + +const mockGitlabClient = { + Groups: { + search: jest.fn(), + create: jest.fn(), + }, +}; +jest.mock('@gitbeaker/node', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:group:ensureExists', () => { + const mockContext = createMockActionContext(); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it(`Should ${examples[0].description}`, async () => { + mockGitlabClient.Groups.search.mockResolvedValue([]); + mockGitlabClient.Groups.create.mockResolvedValue({ + id: 3, + full_path: 'group1', + }); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createGitlabGroupEnsureExistsAction({ integrations }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[0].example).steps[0].input, + }); + + expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith( + 'group1', + 'group1', + {}, + ); + + expect(mockContext.output).toHaveBeenCalledWith('groupId', 3); + }); + + it(`Should ${examples[1].description}`, async () => { + mockGitlabClient.Groups.search.mockResolvedValue([ + { + id: 1, + full_path: 'group1', + }, + ]); + mockGitlabClient.Groups.create.mockResolvedValue({ + id: 3, + full_path: 'group1/group2', + }); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createGitlabGroupEnsureExistsAction({ integrations }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[1].example).steps[0].input, + }); + + expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith( + 'group2', + 'group2', + { + parent_id: 1, + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('groupId', 3); + }); + + it(`Should ${examples[2].description}`, async () => { + mockGitlabClient.Groups.search.mockResolvedValue([ + { + id: 1, + full_path: 'group1', + }, + { + id: 2, + full_path: 'group1/group2', + }, + ]); + mockGitlabClient.Groups.create.mockResolvedValue({ + id: 3, + full_path: 'group1/group2/group3', + }); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createGitlabGroupEnsureExistsAction({ integrations }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[2].example).steps[0].input, + }); + + expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith( + 'group3', + 'group3', + { + parent_id: 2, + }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('groupId', 3); + }); + + it(`Should ${examples[3].description}`, async () => { + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createGitlabGroupEnsureExistsAction({ integrations }); + + await action.handler({ + ...mockContext, + isDryRun: yaml.parse(examples[3].example).steps[0].isDryRun, + input: yaml.parse(examples[3].example).steps[0].input, + }); + + expect(mockGitlabClient.Groups.search).not.toHaveBeenCalled(); + expect(mockGitlabClient.Groups.create).not.toHaveBeenCalled(); + + expect(mockContext.output).toHaveBeenCalledWith('groupId', 42); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.examples.ts new file mode 100644 index 0000000000..41dd822e82 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.examples.ts @@ -0,0 +1,85 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Creating a group at the top level', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabGroup', + name: 'Group', + action: 'gitlab:group:ensureExists', + input: { + repoUrl: 'gitlab.com', + path: ['group1'], + }, + }, + ], + }), + }, + { + description: 'Create a group nested within another group', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabGroup', + name: 'Group', + action: 'gitlab:group:ensureExists', + input: { + repoUrl: 'gitlab.com', + path: ['group1', 'group2'], + }, + }, + ], + }), + }, + { + description: 'Create a group nested within multiple other groups', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabGroup', + name: 'Group', + action: 'gitlab:group:ensureExists', + input: { + repoUrl: 'gitlab.com', + path: ['group1', 'group2', 'group3'], + }, + }, + ], + }), + }, + { + description: 'Create a group in dry run mode', + example: yaml.stringify({ + steps: [ + { + id: 'gitlabGroup', + name: 'Group', + action: 'gitlab:group:ensureExists', + isDryRun: true, + input: { + repoUrl: 'https://gitlab.com/my-repo', + path: ['group1', 'group2', 'group3'], + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts index 72dcddc83d..4dc0305c2e 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts @@ -14,9 +14,8 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; import { createGitlabGroupEnsureExistsAction } from './createGitlabGroupEnsureExistsAction'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; @@ -35,13 +34,7 @@ jest.mock('@gitbeaker/node', () => ({ })); describe('gitlab:group:ensureExists', () => { - const mockContext = { - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); afterEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts index 74d3805254..2cf583a95d 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts @@ -21,6 +21,7 @@ import { GroupSchema } from '@gitbeaker/core/dist/types/resources/Groups'; import commonGitlabConfig from '../commonGitlabConfig'; import { getToken } from '../util'; import { z } from 'zod'; +import { examples } from './createGitlabGroupEnsureExistsAction.examples'; /** * Creates an `gitlab:group:ensureExists` Scaffolder action. @@ -36,6 +37,7 @@ export const createGitlabGroupEnsureExistsAction = (options: { id: 'gitlab:group:ensureExists', description: 'Ensures a Gitlab group exists', supportsDryRun: true, + examples, schema: { input: commonGitlabConfig.merge( z.object({ diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts index fe9e556656..feea436a1e 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.test.ts @@ -14,12 +14,10 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createGitlabIssueAction, IssueType } from './createGitlabIssueAction'; import { ConfigReader } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; -import { advanceTo, clear } from 'jest-date-mock'; const mockGitlabClient = { Issues: { @@ -37,11 +35,13 @@ jest.mock('@gitbeaker/rest', () => ({ describe('gitlab:issues:create', () => { beforeEach(() => { jest.clearAllMocks(); - advanceTo(new Date(1988, 5, 3, 12, 0, 0)); // Set the desired date and time + jest.useFakeTimers({ + now: new Date(1988, 5, 3, 12, 0, 0), + }); }); afterEach(() => { - clear(); // Reset the date mock after each test + jest.useRealTimers(); }); const config = new ConfigReader({ @@ -60,21 +60,18 @@ describe('gitlab:issues:create', () => { const action = createGitlabIssueAction({ integrations }); it('should return a Gitlab issue when called with minimal input params', async () => { - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', projectId: 123, title: 'Computer banks to rule the world', }, workspacePath: 'seen2much', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); mockGitlabClient.Issues.create.mockResolvedValue({ id: 42, + iid: 1, web_url: 'https://gitlab.com/hangar18-/issues/42', }); @@ -102,6 +99,7 @@ describe('gitlab:issues:create', () => { ); expect(mockContext.output).toHaveBeenCalledWith('issueId', 42); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 1); expect(mockContext.output).toHaveBeenCalledWith( 'issueUrl', 'https://gitlab.com/hangar18-/issues/42', @@ -109,7 +107,7 @@ describe('gitlab:issues:create', () => { }); it('should return a Gitlab issue when called with oAuth Token', async () => { - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', projectId: 123, @@ -117,14 +115,11 @@ describe('gitlab:issues:create', () => { token: 'myAwesomeToken', }, workspacePath: 'seen2much', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); mockGitlabClient.Issues.create.mockResolvedValue({ id: 42, + iid: 1, web_url: 'https://gitlab.com/hangar18-/issues/42', }); @@ -152,6 +147,7 @@ describe('gitlab:issues:create', () => { ); expect(mockContext.output).toHaveBeenCalledWith('issueId', 42); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 1); expect(mockContext.output).toHaveBeenCalledWith( 'issueUrl', 'https://gitlab.com/hangar18-/issues/42', @@ -159,7 +155,7 @@ describe('gitlab:issues:create', () => { }); it('should return a Gitlab issue when called with several input params', async () => { - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', projectId: 123, @@ -173,14 +169,11 @@ describe('gitlab:issues:create', () => { labels: 'operation:mindcrime', }, workspacePath: 'seen2much', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); mockGitlabClient.Issues.create.mockResolvedValue({ id: 42, + iid: 1, web_url: 'https://gitlab.com/hangar18-/issues/42', }); @@ -209,6 +202,7 @@ describe('gitlab:issues:create', () => { ); expect(mockContext.output).toHaveBeenCalledWith('issueId', 42); + expect(mockContext.output).toHaveBeenCalledWith('issueIid', 1); expect(mockContext.output).toHaveBeenCalledWith( 'issueUrl', 'https://gitlab.com/hangar18-/issues/42', diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.ts index bc9c796253..894caf635c 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabIssueAction.ts @@ -102,6 +102,7 @@ const issueInputProperties = z.object({ const issueOutputProperties = z.object({ issueUrl: z.string({ description: 'Issue Url' }), issueId: z.number({ description: 'Issue Id' }), + issueIid: z.number({ description: 'Issue Iid' }), }); /** @@ -194,6 +195,7 @@ export const createGitlabIssueAction = (options: { ctx.output('issueId', response.id); ctx.output('issueUrl', response.web_url); + ctx.output('issueIid', response.iid); } catch (error: any) { if (error instanceof z.ZodError) { // Handling Zod validation errors diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.examples.test.ts index ab4fe0e637..5afeaba8ae 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.examples.test.ts @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; -import { PassThrough } from 'stream'; import yaml from 'yaml'; import { createGitlabProjectAccessTokenAction } from './createGitlabProjectAccessTokenAction'; // Adjust the import based on your project structure import { examples } from './createGitlabProjectAccessTokenAction.examples'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { DateTime } from 'luxon'; @@ -59,16 +58,11 @@ describe('gitlab:projectAccessToken:create examples', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createGitlabProjectAccessTokenAction({ integrations }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts new file mode 100644 index 0000000000..dd3b694670 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.test.ts @@ -0,0 +1,179 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createGitlabProjectDeployTokenAction } from './createGitlabProjectDeployTokenAction'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import yaml from 'yaml'; +import { examples } from './createGitlabProjectDeployTokenAction.examples'; + +const mockGitlabClient = { + ProjectDeployTokens: { + add: jest.fn(), + }, +}; +jest.mock('@gitbeaker/node', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:create-deploy-token', () => { + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + { + host: 'hosted.gitlab.com', + apiBaseUrl: 'https://api.hosted.gitlab.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createGitlabProjectDeployTokenAction({ integrations }); + const mockContext = createMockActionContext({ + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '123', + name: 'tokenname', + username: 'tokenuser', + scopes: ['read_repository'], + }, + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`Should ${examples[0].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[0].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + '456', + 'tokenname', + undefined, + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[1].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[1].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + '789', + 'tokenname', + ['read_registry', 'write_repository'], + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[2].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[2].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + '101112', + 'my-custom-token', + undefined, + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[3].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[3].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + 42, + 'tokenname', + undefined, + { username: undefined }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); + + it(`Should ${examples[4].description}`, async () => { + mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({ + token: 'TOKEN', + username: 'User', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[4].example).steps[0].input, + }); + + expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith( + 42, + 'tokenname', + undefined, + { username: 'tokenuser' }, + ); + + expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN'); + expect(mockContext.output).toHaveBeenCalledWith('user', 'User'); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts new file mode 100644 index 0000000000..326747d45a --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.examples.ts @@ -0,0 +1,109 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create a GitLab project deploy token with minimal options.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '456', + name: 'tokenname', + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project deploy token with custom scopes.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '789', + name: 'tokenname', + scopes: ['read_registry', 'write_repository'], + }, + }, + ], + }), + }, + { + description: 'Create a GitLab project deploy token with a specified name.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: '101112', + name: 'my-custom-token', + }, + }, + ], + }), + }, + { + description: + 'Create a GitLab project deploy token with a numeric project ID.', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 42, + name: 'tokenname', + }, + }, + ], + }), + }, + + { + description: 'Create a GitLab project deploy token with a custom username', + example: yaml.stringify({ + steps: [ + { + id: 'createDeployToken', + action: 'gitlab:projectDeployToken:create', + name: 'Create GitLab Project Deploy Token', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + projectId: 42, + name: 'tokenname', + username: 'tokenuser', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.test.ts index 1d3ae804c1..cab72c9a6d 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.test.ts @@ -15,10 +15,9 @@ */ import { createGitlabProjectDeployTokenAction } from './createGitlabProjectDeployTokenAction'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; const mockGitlabClient = { ProjectDeployTokens: { @@ -52,7 +51,7 @@ describe('gitlab:create-deploy-token', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createGitlabProjectDeployTokenAction({ integrations }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', projectId: '123', @@ -60,12 +59,7 @@ describe('gitlab:create-deploy-token', () => { username: 'tokenuser', scopes: ['read_repository'], }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts index 1665d23b39..87d4314b6f 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts @@ -22,6 +22,7 @@ import commonGitlabConfig from '../commonGitlabConfig'; import { getToken } from '../util'; import { InputError } from '@backstage/errors'; import { z } from 'zod'; +import { examples } from './createGitlabProjectDeployTokenAction.examples'; /** * Creates a `gitlab:projectDeployToken:create` Scaffolder action. @@ -35,6 +36,7 @@ export const createGitlabProjectDeployTokenAction = (options: { const { integrations } = options; return createTemplateAction({ id: 'gitlab:projectDeployToken:create', + examples, schema: { input: commonGitlabConfig.merge( z.object({ diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts index e5aa610ebc..4294e5f137 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ import yaml from 'yaml'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; jest.mock('@backstage/plugin-scaffolder-node', () => { return { @@ -31,8 +32,6 @@ import { createPublishGitlabAction } from './gitlab'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { examples } from './gitlab.examples'; const mockGitlabClient = { @@ -76,16 +75,11 @@ describe('publish:gitlab', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishGitlabAction({ integrations, config }); - const mockContext = { + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.ts index b20fcf52e9..ad032e9017 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.examples.ts @@ -20,7 +20,7 @@ import yaml from 'yaml'; export const examples: TemplateExample[] = [ { description: - 'Initializes a git repository of the content in the workspace, and publishes it to GitLab.', + 'Initializes a git repository with the content in the workspace, and publishes it to GitLab with the default configuration.', example: yaml.stringify({ steps: [ { @@ -52,7 +52,7 @@ export const examples: TemplateExample[] = [ }, { description: - 'Sets the commit message on the repository. The default value is `initial commit`.', + 'Initializes a GitLab repository with an initial commit message, if not set defaults to `initial commit`.', example: yaml.stringify({ steps: [ { @@ -69,7 +69,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Initializes a git repository with additional settings.', + description: 'Initializes a GitLab repository with aditional settings.', example: yaml.stringify({ steps: [ { @@ -88,7 +88,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Initializes a git repository with branches settings', + description: 'Initializes a GitLab repository with branch settings.', example: yaml.stringify({ steps: [ { @@ -115,7 +115,7 @@ export const examples: TemplateExample[] = [ }), }, { - description: 'Initializes a git repository with environment variables', + description: 'Initializes a GitLab repository with environment variables.', example: yaml.stringify({ steps: [ { diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts index 5aca0a73e5..bbcae08063 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlab.test.ts @@ -29,9 +29,8 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { createPublishGitlabAction } from './gitlab'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; import { initRepoAndPush } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; const mockGitlabClient = { Namespaces: { @@ -83,7 +82,8 @@ describe('publish:gitlab', () => { const integrations = ScmIntegrations.fromConfig(config); const action = createPublishGitlabAction({ integrations, config }); - const mockContext = { + + const mockContext = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', repoVisibility: 'private' as const, @@ -91,13 +91,8 @@ describe('publish:gitlab', () => { ci_config_path: '.gitlab-ci.yml', }, }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; - const mockContextWithSettings = { + }); + const mockContextWithSettings = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', repoVisibility: 'private' as const, @@ -108,13 +103,8 @@ describe('publish:gitlab', () => { topics: ['topic1', 'topic2'], }, }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; - const mockContextWithBranches = { + }); + const mockContextWithBranches = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', repoVisibility: 'private' as const, @@ -135,13 +125,8 @@ describe('publish:gitlab', () => { }, ], }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; - const mockContextWithVariables = { + }); + const mockContextWithVariables = createMockActionContext({ input: { repoUrl: 'gitlab.com?repo=repo&owner=owner', repoVisibility: 'private' as const, @@ -155,12 +140,7 @@ describe('publish:gitlab', () => { }, ], }, - workspacePath: 'lol', - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.examples.test.ts new file mode 100644 index 0000000000..6f26bc1c68 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.examples.test.ts @@ -0,0 +1,305 @@ +/* + * 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 { createRootLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createPublishGitlabMergeRequestAction } from './gitlabMergeRequest'; +import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { examples } from './gitlabMergeRequest.examples'; +import yaml from 'yaml'; + +// Make sure root logger is initialized ahead of FS mock +createRootLogger(); + +const mockGitlabClient = { + Namespaces: { + show: jest.fn(), + }, + Branches: { + create: jest.fn(), + }, + Commits: { + create: jest.fn(), + }, + MergeRequests: { + create: jest.fn(async (_: any) => { + return { + default_branch: 'main', + }; + }), + }, + Projects: { + create: jest.fn(), + show: jest.fn(async (_: any) => { + return { + default_branch: 'main', + }; + }), + }, + Users: { + current: jest.fn(), + username: jest.fn(async (user: string) => { + const users: string[] = ['John Smith', 'my-assignee']; + if (!users.includes(user)) throw new Error('user does not exist'); + else + return [ + { + id: 123, + }, + ]; + }), + }, +}; + +jest.mock('@gitbeaker/node', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('createGitLabMergeRequest', () => { + let instance: TemplateAction; + + const mockDir = createMockDirectory(); + const workspacePath = mockDir.resolve('workspace'); + + beforeEach(() => { + jest.clearAllMocks(); + + mockDir.clear(); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'token', + apiBaseUrl: 'https://api.gitlab.com', + }, + { + host: 'hosted.gitlab.com', + apiBaseUrl: 'https://api.hosted.gitlab.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + instance = createPublishGitlabMergeRequestAction({ integrations }); + }); + + describe('createGitLabMergeRequestWithAssignee', () => { + it(`Should ${examples[0].description}`, async () => { + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + + const input = yaml.parse(examples[0].example).steps[0].input; + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'main', + 'Create my new MR', + { + description: 'This MR is really good', + removeSourceBranch: false, + assigneeId: 123, + }, + ); + }); + + it('assignee is not set when a valid assignee username is not passed in options', async () => { + const input = { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + branchName: 'new-mr', + description: 'This is an important change', + removeSourceBranch: false, + targetPath: 'Subdirectory', + assingnee: 'John Doe', + }; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'main', + 'Create my new MR', + { + description: 'This is an important change', + removeSourceBranch: false, + assigneeId: undefined, + }, + ); + }); + }); + + describe('createGitLabMergeRequestWithRemoveBranch', () => { + it(`Should ${examples[1].description}`, async () => { + const input = yaml.parse(examples[1].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'main', + 'Create my new MR', + { description: 'This MR is really good', removeSourceBranch: true }, + ); + }); + }); + + describe('createGitLabMergeRequestWithSpecifiedTargetBranch', () => { + it(`Should ${examples[2].description}`, async () => { + const input = yaml.parse(examples[2].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Projects.show).not.toHaveBeenCalled(); + expect(mockGitlabClient.Branches.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'test', + ); + expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'test', + 'Create my new MR', + { description: 'This MR is really good', removeSourceBranch: false }, + ); + expect(ctx.output).toHaveBeenCalledWith('targetBranchName', 'test'); + }); + }); + + describe('createGitLabMergeRequestWithCommitAction', () => { + it(`Should ${examples[3].description}`, async () => { + const input = yaml.parse(examples[3].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'Create my new MR', + [ + { + action: 'create', + filePath: 'source/foo.txt', + content: 'SGVsbG8gdGhlcmUh', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + }); + + it(`Should ${examples[4].description}`, async () => { + const input = yaml.parse(examples[4].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'Create my new MR', + [ + { + action: 'delete', + filePath: 'source/foo.txt', + content: 'SGVsbG8gdGhlcmUh', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + }); + + it(`Should ${examples[5].description}`, async () => { + const input = yaml.parse(examples[5].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + source: { 'foo.txt': 'Hello there!' }, + irrelevant: { 'bar.txt': 'Nothing to see here' }, + }, + }); + + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'new-mr', + 'Create my new MR', + [ + { + action: 'update', + filePath: 'source/foo.txt', + content: 'SGVsbG8gdGhlcmUh', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.examples.ts new file mode 100644 index 0000000000..8bed461d25 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.examples.ts @@ -0,0 +1,142 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Create a merge request with a specific assignee', + example: yaml.stringify({ + steps: [ + { + id: 'createMergeRequest', + action: 'publish:gitlab:merge-request', + name: 'Create a Merge Request', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + description: 'This MR is really good', + sourcePath: './path/to/my/changes', + branchName: 'new-mr', + assignee: 'my-assignee', + }, + }, + ], + }), + }, + { + description: + 'Create a merge request with removal of source branch after merge', + example: yaml.stringify({ + steps: [ + { + id: 'createMergeRequest', + action: 'publish:gitlab:merge-request', + name: 'Create a Merge Request', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + description: 'This MR is really good', + sourcePath: './path/to/my/changes', + branchName: 'new-mr', + removeSourceBranch: true, + }, + }, + ], + }), + }, + { + description: 'Create a merge request with a target branch', + example: yaml.stringify({ + steps: [ + { + id: 'createMergeRequest', + action: 'publish:gitlab:merge-request', + name: 'Create a Merge Request', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + description: 'This MR is really good', + sourcePath: './path/to/my/changes', + branchName: 'new-mr', + targetBranchName: 'test', + targetPath: 'Subdirectory', + }, + }, + ], + }), + }, + { + description: 'Create a merge request with a commit action as create', + example: yaml.stringify({ + steps: [ + { + id: 'createMergeRequest', + action: 'publish:gitlab:merge-request', + name: 'Create a Merge Request', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + branchName: 'new-mr', + description: 'MR description', + commitAction: 'create', + targetPath: 'source', + }, + }, + ], + }), + }, + { + description: 'Create a merge request with a commit action as delete', + example: yaml.stringify({ + steps: [ + { + id: 'createMergeRequest', + action: 'publish:gitlab:merge-request', + name: 'Create a Merge Request', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + branchName: 'new-mr', + description: 'MR description', + commitAction: 'delete', + targetPath: 'source', + }, + }, + ], + }), + }, + { + description: 'Create a merge request with a commit action as update', + example: yaml.stringify({ + steps: [ + { + id: 'createMergeRequest', + action: 'publish:gitlab:merge-request', + name: 'Create a Merge Request', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + title: 'Create my new MR', + branchName: 'new-mr', + description: 'MR description', + commitAction: 'update', + targetPath: 'source', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts index 71a2273aed..befc2c01c9 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createRootLogger, getRootLogger } from '@backstage/backend-common'; +import { createRootLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { Writable } from 'stream'; import { createPublishGitlabMergeRequestAction } from './gitlabMergeRequest'; import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; // Make sure root logger is initialized ahead of FS mock createRootLogger(); @@ -78,6 +78,8 @@ describe('createGitLabMergeRequest', () => { const workspacePath = mockDir.resolve('workspace'); beforeEach(() => { + jest.clearAllMocks(); + mockDir.clear(); const config = new ConfigReader({ @@ -116,14 +118,7 @@ describe('createGitLabMergeRequest', () => { irrelevant: { 'bar.txt': 'Nothing to see here' }, }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Projects.show).not.toHaveBeenCalled(); @@ -158,14 +153,7 @@ describe('createGitLabMergeRequest', () => { irrelevant: { 'bar.txt': 'Nothing to see here' }, }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Projects.show).toHaveBeenCalledWith('owner/repo'); @@ -203,14 +191,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( @@ -238,14 +219,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( @@ -279,14 +253,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( @@ -319,14 +286,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( @@ -359,14 +319,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( @@ -398,14 +351,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith( @@ -433,14 +379,7 @@ describe('createGitLabMergeRequest', () => { irrelevant: { 'bar.txt': 'Nothing to see here' }, }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( @@ -482,14 +421,7 @@ describe('createGitLabMergeRequest', () => { irrelevant: { 'bar.txt': 'Nothing to see here' }, }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( @@ -526,14 +458,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( @@ -568,14 +493,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( @@ -610,14 +528,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( @@ -655,14 +566,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); @@ -700,14 +604,7 @@ describe('createGitLabMergeRequest', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); @@ -737,14 +634,7 @@ describe('createGitLabMergeRequest', () => { commitAction: 'create', }; - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await expect(instance.handler(ctx)).rejects.toThrow( 'Relative path is not allowed to refer to a directory outside its parent', diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts index 86f69ee357..c9b8ce68a9 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.ts @@ -25,6 +25,7 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { InputError } from '@backstage/errors'; import { resolveSafeChildPath } from '@backstage/backend-common'; import { createGitlabApi } from './helpers'; +import { examples } from './gitlabMergeRequest.examples'; /** * Create a new action that creates a gitlab merge request. @@ -52,6 +53,7 @@ export const createPublishGitlabMergeRequestAction = (options: { assignee?: string; }>({ id: 'publish:gitlab:merge-request', + examples, schema: { input: { required: ['repoUrl', 'branchName'], diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.examples.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.examples.test.ts new file mode 100644 index 0000000000..d84181d398 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.examples.test.ts @@ -0,0 +1,186 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRootLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/config'; +import { ScmIntegrations } from '@backstage/integration'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createGitlabRepoPushAction } from './gitlabRepoPush'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { examples } from './gitlabRepoPush.examples'; +import yaml from 'yaml'; + +createRootLogger(); + +const mockGitlabClient = { + Projects: { + create: jest.fn(), + show: jest.fn(async (_: any) => { + return { + default_branch: 'main', + }; + }), + }, + Branches: { + create: jest.fn(), + show: jest.fn(), + }, + Commits: { + create: jest.fn(async (_: any) => ({ + id: 'f8a2c9bd4e2915b0792b43235c779e82ddad54af', + })), + }, +}; + +jest.mock('@gitbeaker/node', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:repo:push', () => { + let instance: TemplateAction; + + const mockDir = createMockDirectory(); + const workspacePath = mockDir.resolve('workspace'); + + beforeEach(() => { + mockDir.clear(); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'token', + apiBaseUrl: 'https://api.gitlab.com', + }, + { + host: 'hosted.gitlab.com', + apiBaseUrl: 'https://api.hosted.gitlab.com', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + instance = createGitlabRepoPushAction({ integrations }); + }); + + describe('Push changes to gitlab repository', () => { + it(`Should ${examples[0].description}`, async () => { + const input = yaml.parse(examples[0].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + 'abcd.txt': 'Test message', + }, + }); + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'feature-branch', + 'Initial Commit', + [ + { + action: 'create', + filePath: 'abcd.txt', + content: 'VGVzdCBtZXNzYWdl', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + expect(ctx.output).toHaveBeenCalledWith( + 'commitHash', + 'f8a2c9bd4e2915b0792b43235c779e82ddad54af', + ); + }); + }); + + describe('Push changes to gitlab repository with a specific source and target path', () => { + it(`Should ${examples[1].description}`, async () => { + const input = yaml.parse(examples[1].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + 'abcd.txt': 'Test message', + source: { + 'abcd.txt': 'Test message', + }, + }, + }); + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'feature-branch', + 'Initial Commit', + [ + { + action: 'create', + filePath: 'abcd.txt', + content: 'VGVzdCBtZXNzYWdl', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + expect(ctx.output).toHaveBeenCalledWith( + 'commitHash', + 'f8a2c9bd4e2915b0792b43235c779e82ddad54af', + ); + }); + }); + + describe('Push changes to gitlab repository with a specific commit action', () => { + it(`Should ${examples[2].description}`, async () => { + const input = yaml.parse(examples[2].example).steps[0].input; + mockDir.setContent({ + [workspacePath]: { + 'abcd.txt': 'Test message', + }, + }); + const ctx = createMockActionContext({ input, workspacePath }); + await instance.handler(ctx); + + expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); + expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith( + 'owner/repo', + 'feature-branch', + 'Initial Commit', + [ + { + action: 'update', + filePath: 'abcd.txt', + content: 'VGVzdCBtZXNzYWdl', + encoding: 'base64', + execute_filemode: false, + }, + ], + ); + expect(ctx.output).toHaveBeenCalledWith( + 'commitHash', + 'f8a2c9bd4e2915b0792b43235c779e82ddad54af', + ); + }); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.examples.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.examples.ts new file mode 100644 index 0000000000..56a59f25bc --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.examples.ts @@ -0,0 +1,76 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Push changes to gitlab repository with minimal changes', + example: yaml.stringify({ + steps: [ + { + id: 'pushChanges', + action: 'gitlab:repo:push', + name: 'Push changes to gitlab repository', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + commitMessage: 'Initial Commit', + branchName: 'feature-branch', + }, + }, + ], + }), + }, + { + description: + 'Push changes to gitlab repository with a specific source and target path', + example: yaml.stringify({ + steps: [ + { + id: 'pushChanges', + action: 'gitlab:repo:push', + name: 'Push changes to gitlab repository', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + commitMessage: 'Initial Commit', + branchName: 'feature-branch', + sourcePath: 'src', + targetPath: 'dest', + }, + }, + ], + }), + }, + { + description: + 'Push changes to gitlab repository with a specific commit action', + example: yaml.stringify({ + steps: [ + { + id: 'pushChanges', + action: 'gitlab:repo:push', + name: 'Push changes to gitlab repository', + input: { + repoUrl: 'gitlab.com?repo=repo&owner=owner', + commitMessage: 'Initial Commit', + branchName: 'feature-branch', + commitAction: 'update', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.test.ts index 840f506540..569d3c0c56 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.test.ts @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createRootLogger, getRootLogger } from '@backstage/backend-common'; +import { createRootLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { Writable } from 'stream'; import { createMockDirectory } from '@backstage/backend-test-utils'; import { createGitlabRepoPushAction } from './gitlabRepoPush'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; // Make sure root logger is initialized ahead of FS mock createRootLogger(); @@ -93,14 +93,7 @@ describe('createGitLabCommit', () => { 'foo.txt': 'Hello there!', }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); @@ -139,14 +132,7 @@ describe('createGitLabCommit', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); @@ -183,14 +169,7 @@ describe('createGitLabCommit', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); @@ -227,14 +206,7 @@ describe('createGitLabCommit', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0); @@ -276,14 +248,7 @@ describe('createGitLabCommit', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); @@ -325,14 +290,7 @@ describe('createGitLabCommit', () => { }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); @@ -366,14 +324,7 @@ describe('createGitLabCommit', () => { commitAction: 'create', }; - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await expect(instance.handler(ctx)).rejects.toThrow( 'Relative path is not allowed to refer to a directory outside its parent', @@ -398,14 +349,7 @@ describe('createGitLabCommit', () => { 'foo.txt': 'Hello there!', }, }); - const ctx = { - createTemporaryDirectory: jest.fn(), - output: jest.fn(), - logger: getRootLogger(), - logStream: new Writable(), - input, - workspacePath, - }; + const ctx = createMockActionContext({ input, workspacePath }); await instance.handler(ctx); expect(mockGitlabClient.Branches.create).toHaveBeenCalledWith( diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.ts index 330d0f6f08..aae3b05c49 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabRepoPush.ts @@ -25,6 +25,7 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { InputError } from '@backstage/errors'; import { resolveSafeChildPath } from '@backstage/backend-common'; import { createGitlabApi } from './helpers'; +import { examples } from './gitlabRepoPush.examples'; /** * Create a new action that commits into a gitlab repository. @@ -46,6 +47,7 @@ export const createGitlabRepoPushAction = (options: { commitAction?: 'create' | 'delete' | 'update'; }>({ id: 'gitlab:repo:push', + examples, schema: { input: { required: ['repoUrl', 'branchName', 'commitMessage'], diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 221ddd8af5..541e175c11 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,163 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## 0.4.34 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.4.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + +## 0.4.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.4.33 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## 0.4.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + +## 0.4.31 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## 0.4.31-next.2 + +### Patch Changes + +- e9663a9: Move away from using `ctx.logStream` +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 0.4.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 0.4.30-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + +## 0.4.27 + +### Patch Changes + +- e9a5228: Make `containerRunner` argument optional +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.4.27-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 9ee2646e7b..26fd91b1b6 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,26 +1,26 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", + "version": "0.4.35-next.0", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.27-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, "backstage": { "role": "backend-plugin-module" }, + "publishConfig": { + "access": "public" + }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-rails" }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "package.json": [ @@ -28,14 +28,17 @@ ] } }, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -51,12 +54,10 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^11.0.0", "@types/node": "^18.17.8", "jest-when": "^3.1.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts index 7548ddd21d..40514dc7c5 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.test.ts @@ -27,18 +27,15 @@ jest.mock('./railsNewRunner', () => { }; }); -import { - ContainerRunner, - getVoidLogger, - UrlReader, -} from '@backstage/backend-common'; +import { ContainerRunner, UrlReader } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { resolve as resolvePath } from 'path'; -import { PassThrough } from 'stream'; import { createFetchRailsAction } from './index'; import { fetchContents } from '@backstage/plugin-scaffolder-node'; import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { Writable } from 'stream'; describe('fetch:rails', () => { const mockDir = createMockDirectory(); @@ -53,8 +50,7 @@ describe('fetch:rails', () => { }), ); - const mockTmpDir = mockDir.path; - const mockContext = { + const mockContext = createMockActionContext({ input: { url: 'https://rubyonrails.org/generator', targetPath: 'something', @@ -66,12 +62,8 @@ describe('fetch:rails', () => { baseUrl: 'somebase', entityRef: 'template:default/myTemplate', }, - workspacePath: mockTmpDir, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir), - }; + workspacePath: mockDir.path, + }); const mockReader: UrlReader = { readUrl: jest.fn(), @@ -102,7 +94,7 @@ describe('fetch:rails', () => { expect(fetchContents).toHaveBeenCalledWith({ reader: mockReader, integrations, - baseUrl: mockContext.templateInfo.baseUrl, + baseUrl: mockContext.templateInfo?.baseUrl, fetchUrl: mockContext.input.url, outputPath: resolvePath(mockContext.workspacePath), }); @@ -112,8 +104,8 @@ describe('fetch:rails', () => { await action.handler(mockContext); expect(mockRailsTemplater.run).toHaveBeenCalledWith({ - workspacePath: mockTmpDir, - logStream: mockContext.logStream, + workspacePath: mockContext.workspacePath, + logStream: expect.any(Writable), values: mockContext.input.values, }); }); @@ -128,8 +120,8 @@ describe('fetch:rails', () => { }); expect(mockRailsTemplater.run).toHaveBeenCalledWith({ - workspacePath: mockTmpDir, - logStream: mockContext.logStream, + workspacePath: mockContext.workspacePath, + logStream: expect.any(Writable), values: { ...mockContext.input.values, imageName: 'foo/rails-custom-image', diff --git a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts index dfc7bea418..394d0fb02c 100644 --- a/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts +++ b/plugins/scaffolder-backend-module-rails/src/actions/fetch/rails/index.ts @@ -26,6 +26,7 @@ import { import { resolve as resolvePath } from 'path'; import { RailsNewRunner } from './railsNewRunner'; +import { PassThrough } from 'stream'; /** * Creates the `fetch:rails` Scaffolder action. @@ -215,10 +216,15 @@ export function createFetchRailsAction(options: { throw new Error(`Image ${imageName} is not allowed`); } + const logStream = new PassThrough(); + logStream.on('data', chunk => { + ctx.logger.info(chunk.toString()); + }); + // Will execute the template in ./template and put the result in ./result await templateRunner.run({ workspacePath: workDir, - logStream: ctx.logStream, + logStream, values: { ...ctx.input.values, imageName }, }); diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 036307d00a..8119d5a446 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,125 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 0.1.22 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + +## 0.1.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/errors@1.2.4-next.0 + +## 0.1.21-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + +## 0.1.18 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + ## 0.1.18-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index f01c7d39ec..9321e7ef1e 100644 --- a/plugins/scaffolder-backend-module-sentry/package.json +++ b/plugins/scaffolder-backend-module-sentry/package.json @@ -1,25 +1,11 @@ { "name": "@backstage/plugin-scaffolder-backend-module-sentry", - "version": "0.1.18-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, + "version": "0.1.26-next.0", "backstage": { "role": "backend-plugin-module" }, - "exports": { - ".": "./src/index.ts", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - "package.json": [ - "package.json" - ] - } + "publishConfig": { + "access": "public" }, "homepage": "https://backstage.io", "repository": { @@ -27,14 +13,31 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-sentry" }, + "license": "Apache-2.0", + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + }, + "main": "src/index.ts", + "types": "src/index.ts", + "typesVersions": { + "*": { + "package.json": [ + "package.json" + ] + } + }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", @@ -46,10 +49,8 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@backstage/types": "workspace:^", "msw": "^2.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts index 972b0f1e8e..158b7db4ae 100644 --- a/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts +++ b/plugins/scaffolder-backend-module-sentry/src/actions/createProject.test.ts @@ -15,6 +15,7 @@ */ import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ConfigReader } from '@backstage/config'; import { InputError } from '@backstage/errors'; import { ActionContext } from '@backstage/plugin-scaffolder-node'; @@ -42,19 +43,17 @@ describe('sentry:project:create action', () => { name: string; slug?: string; authToken?: string; - }> => ({ - workspacePath: './dev/proj', - createTemporaryDirectory: jest.fn(), - logger: jest.createMockFromModule('winston'), - logStream: jest.createMockFromModule('stream'), - input: { - organizationSlug: 'org', - teamSlug: 'team', - name: 'test project', - authToken: randomBytes(5).toString('hex'), - }, - output: jest.fn(), - }); + }> => + createMockActionContext({ + workspacePath: './dev/proj', + logger: jest.createMockFromModule('winston'), + input: { + organizationSlug: 'org', + teamSlug: 'team', + name: 'test project', + authToken: randomBytes(5).toString('hex'), + }, + }); it('should request sentry project create with specified parameters.', async () => { expect.assertions(3); diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 2bff8a0275..4772114265 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,128 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.4-next.0 + +## 0.3.0 + +### Minor Changes + +- fae9638: Add examples for `run:yeoman` scaffolder action. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/plugin-scaffolder-node-test-utils@0.1.3 + - @backstage/types@1.1.1 + +## 0.2.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.3-next.1 + - @backstage/types@1.1.1 + +## 0.2.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.3-next.0 + +## 0.2.37 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/plugin-scaffolder-node-test-utils@0.1.2 + - @backstage/types@1.1.1 + +## 0.2.36 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/types@1.1.1 + +## 0.2.35 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## 0.2.35-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/types@1.1.1 + +## 0.2.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/types@1.1.1 + +## 0.2.34-next.0 + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.0-next.0 + - @backstage/types@1.1.1 + +## 0.2.31 + +### Patch Changes + +- e9a5228: Exporting a default module for the new Backend System +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/types@1.1.1 + ## 0.2.31-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/knip-report.md b/plugins/scaffolder-backend-module-yeoman/knip-report.md index c955ca23f0..7b2c9043ee 100644 --- a/plugins/scaffolder-backend-module-yeoman/knip-report.md +++ b/plugins/scaffolder-backend-module-yeoman/knip-report.md @@ -6,3 +6,9 @@ | :------ | :----------- | :------- | | winston | package.json | error | +## Unused devDependencies (1) + +| Name | Location | Severity | +| :------------------------ | :----------- | :------- | +| @backstage/backend-common | package.json | error | + diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index a37b4da4e9..c091dfbab9 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,25 +1,11 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.2.31-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, + "version": "0.3.1-next.0", "backstage": { "role": "backend-plugin-module" }, - "exports": { - ".": "./src/index.ts", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - "package.json": [ - "package.json" - ] - } + "publishConfig": { + "access": "public" }, "homepage": "https://backstage.io", "repository": { @@ -27,27 +13,43 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/scaffolder-backend-module-yeoman" }, + "license": "Apache-2.0", + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + }, + "main": "src/index.ts", + "types": "src/index.ts", + "typesVersions": { + "*": { + "package.json": [ + "package.json" + ] + } + }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-plugin-api": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@backstage/types": "workspace:^", "winston": "^3.2.1", + "yaml": "^2.0.0", "yeoman-environment": "^3.9.1" }, "devDependencies": { "@backstage/backend-common": "workspace:^", "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts new file mode 100644 index 0000000000..4875089090 --- /dev/null +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.test.ts @@ -0,0 +1,115 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { yeomanRun } from './yeomanRun'; + +jest.mock('./yeomanRun'); + +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import os from 'os'; +import { createRunYeomanAction } from './yeoman'; +import type { ActionContext } from '@backstage/plugin-scaffolder-node'; +import { JsonObject } from '@backstage/types'; +import yaml from 'yaml'; +import { examples } from './yeoman.examples'; + +describe('run:yeoman', () => { + const mockTmpDir = os.tmpdir(); + + let mockContext: ActionContext<{ + namespace: string; + args?: string[]; + options?: JsonObject; + }>; + + const action = createRunYeomanAction(); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`should ${examples[0].description}`, async () => { + const namespace = yaml.parse(examples[0].example).steps[0].input.namespace; + const input = yaml.parse(examples[0].example).steps[0].input; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + undefined, + undefined, + ); + }); + + it(`should ${examples[1].description}`, async () => { + const namespace = yaml.parse(examples[1].example).steps[0].input.namespace; + const input = yaml.parse(examples[1].example).steps[0].input; + const args: string[] = yaml.parse(examples[1].example).steps[0].input.args; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + args, + undefined, + ); + }); + + it(`should ${examples[2].description}`, async () => { + const namespace = yaml.parse(examples[2].example).steps[0].input.namespace; + const input = yaml.parse(examples[2].example).steps[0].input; + const options = yaml.parse(examples[2].example).steps[0].input.options; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + undefined, + options, + ); + }); + + it(`should ${examples[3].description}`, async () => { + const namespace = yaml.parse(examples[3].example).steps[0].input.namespace; + const input = yaml.parse(examples[3].example).steps[0].input; + const options = yaml.parse(examples[3].example).steps[0].input.options; + const args: string[] = yaml.parse(examples[1].example).steps[0].input.args; + mockContext = createMockActionContext({ + input: input, + workspacePath: mockTmpDir, + }); + + await action.handler(mockContext); + expect(yeomanRun).toHaveBeenCalledWith( + mockTmpDir, + namespace, + args, + options, + ); + }); +}); diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts new file mode 100644 index 0000000000..067cd71fab --- /dev/null +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.examples.ts @@ -0,0 +1,87 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: 'Run a Yeoman generator with minimal options', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + }, + }, + ], + }), + }, + { + description: + 'Run a yeoman generator with arguments to pass on to Yeoman for templating', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + args: ['arg1', 'arg2'], + }, + }, + ], + }), + }, + { + description: + 'Run a yeoman generator with options to pass on to Yeoman for templating', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + options: { option1: 'value1', option2: 'value2' }, + }, + }, + ], + }), + }, + { + description: 'Run a yeoman generator with all options', + example: yaml.stringify({ + steps: [ + { + id: 'run:yeoman', + action: 'run:yeoman', + name: 'Running a yeoman generator', + input: { + namespace: 'node:app', + args: ['arg1', 'arg2'], + options: { option1: 'value1', option2: 'value2' }, + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.test.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.test.ts index 146c29f4ac..52bd95a3f9 100644 --- a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.test.ts +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.test.ts @@ -18,9 +18,8 @@ import { yeomanRun } from './yeomanRun'; jest.mock('./yeomanRun'); -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import os from 'os'; -import { PassThrough } from 'stream'; import { createRunYeomanAction } from './yeoman'; import type { ActionContext } from '@backstage/plugin-scaffolder-node'; import { JsonObject } from '@backstage/types'; @@ -46,18 +45,14 @@ describe('run:yeoman', () => { const options = { code: 'owner', }; - mockContext = { + mockContext = createMockActionContext({ input: { namespace, args, options, }, workspacePath: mockTmpDir, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir), - }; + }); await action.handler(mockContext); expect(yeomanRun).toHaveBeenCalledWith( diff --git a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts index 62d62807ae..a8bbbf945d 100644 --- a/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts +++ b/plugins/scaffolder-backend-module-yeoman/src/actions/run/yeoman.ts @@ -17,6 +17,7 @@ import { JsonObject } from '@backstage/types'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { yeomanRun } from './yeomanRun'; +import { examples } from './yeoman.examples'; /** * Creates a `run:yeoman` Scaffolder action. @@ -35,6 +36,7 @@ export function createRunYeomanAction() { }>({ id: 'run:yeoman', description: 'Runs Yeoman on an installed Yeoman generator', + examples, schema: { input: { type: 'object', diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 559c0d7ef9..e9bb1c2b05 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,430 @@ # @backstage/plugin-scaffolder-backend +## 1.22.5-next.0 + +### Patch Changes + +- 025641b: Fix issue with the log format not being respected when logging from actions +- 025641b: Redact `meta` fields too with the logger +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.2.8-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.8-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.4-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.8-next.0 + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.16-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.10-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.8-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.8-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.10-next.0 + +## 1.22.4 + +### Patch Changes + +- f34a9b1: The `catalog:write` action now automatically adds a `backstage.io/template-source` annotation, indicating which Scaffolder template was used to create the entity. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7 + - @backstage/backend-tasks@0.5.22 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.9 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.7 + - @backstage/integration@1.10.0 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.22.4-next.1 + +### Patch Changes + +- f34a9b1: The `catalog:write` action now automatically adds a `backstage.io/template-source` annotation, indicating which Scaffolder template was used to create the entity. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.9-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.7-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.1 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9-next.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.22.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.7-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.15-next.0 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.9-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.7-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.9-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.7-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.7-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.3-next.0 + - @backstage/plugin-scaffolder-common@1.5.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 1.22.3 + +### Patch Changes + +- c74c2de: Fixed an issue causing actions to fail when retrieving auth credentials +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.14 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.2 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-scaffolder-backend-module-github@0.2.6 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.8 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.6 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.8 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.6 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.22.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.10.0 + - @backstage/catalog-client@1.6.2 + - @backstage/backend-common@0.21.5 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.13 + - @backstage/plugin-auth-node@0.4.10 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.1 + - @backstage/backend-tasks@0.5.20 + - @backstage/plugin-permission-node@0.7.26 + - @backstage/plugin-scaffolder-backend-module-github@0.2.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.7 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.5 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.5 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.5 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.7 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.5 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.22.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.9.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.12 + +## 1.22.0 + +### Minor Changes + +- e9663a9: Move away from using `ctx.logStream` +- aa543c9: Migrate plugin to use the new auth services, add an optional service discovery to the router options and change the permissions type to be `PermissionsService`. +- e9663a9: Enable the redaction of secrets using the redacting logger and the secrets from the `TaskSpec` +- c6b132e: Introducing checkpoints for scaffolder task action idempotency + +### Patch Changes + +- 984abfa: Fixing the lost of the initial state after a task recovery. +- 703ebc9: Fix support for unauthenticated requests to create scaffolder tasks +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.6 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4 + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.22.0-next.2 + +### Minor Changes + +- e9663a9: Move away from using `ctx.logStream` +- e9663a9: Enable the redaction of secrets using the redacting logger and the secrets from the `TaskSpec` + +### Patch Changes + +- 703ebc9: Fix support for unauthenticated requests to create scaffolder tasks +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.6-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4-next.2 + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.3.0-next.2 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.4-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.2 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 1.22.0-next.1 + +### Minor Changes + +- aa543c9: Migrate plugin to use the new auth services, add an optional service discovery to the router options and change the permissions type to be `PermissionsService`. + +### Patch Changes + +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.2.4-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.6-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.4-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.6-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.4-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.17-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.11-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 1.22.0-next.0 + +### Minor Changes + +- c6b132e: Introducing checkpoints for scaffolder task action idempotency + +### Patch Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.3-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.3-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.3-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.5-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.3-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.16-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.5-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.3-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.10-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## 1.21.0 + +### Minor Changes + +- 458bf21: Created a gitea module for the scaffolder. This module provides a new action "publish:gitea" able to create a gitea repository owned by an organization. See: https://gitea.com/api/swagger#/organization/createOrgRepo +- 11b9a08: Introduced the first version of recoverable tasks. +- 78c100b: Support providing an overriding token for `fetch:template`, `fetch:plain` and `fetch:file` when interacting with upstream integrations +- e9a5228: The built-in module list has been trimmed down when using the new Backend System. Provider specific modules should now be installed with `backend.add` to provide additional actions to the scaffolder. These modules are as follows: + + - `@backstage/plugin-scaffolder-backend-module-github` + - `@backstage/plugin-scaffolder-backend-module-gitlab` + - `@backstage/plugin-scaffolder-backend-module-bitbucket` + - `@backstage/plugin-scaffolder-backend-module-gitea` + - `@backstage/plugin-scaffolder-backend-module-gerrit` + - `@backstage/plugin-scaffolder-backend-module-confluence-to-markdown` + - `@backstage/plugin-scaffolder-backend-module-cookiecutter` + - `@backstage/plugin-scaffolder-backend-module-rails` + - `@backstage/plugin-scaffolder-backend-module-sentry` + - `@backstage/plugin-scaffolder-backend-module-yeoman` + +### Patch Changes + +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-server`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Server. + + - `publish:bitbucketServer` + - `publish:bitbucketServer:pull-request` + +- 09f8b31: Simple typo fix in the fetch:template action example on the word 'skeleton'. +- c25a500: Fix some deprecations and misplaced `await` usage. +- f6792c6: Move the `NODE_OPTIONS` messaging for `--no-node-snapshot` to the `SecureTemplater` in order to get better messaging at runtime +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 52ae6b9: Updated dependency `esbuild` to `^0.20.0`. +- 5eb6882: New scaffolder module `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud`. + + Extracted from `@backstage/plugin-scaffolder-backend-module-bitbucket` + and replaces its actions related to Bitbucket Cloud. + + - `publish:bitbucketCloud` + - `bitbucket:pipelines:run` + +- 0a395b3: Upgraded `prom-client` to version 15 +- e1c479d: When using node 20+ the `scaffolder-backend` will now throw an error at startup if the `--no-node-snapshot` option was + not provided to node. +- e0e5afe: Add option to configure nunjucks with the `trimBlocks` and `lstripBlocks` options in the fetch:template action +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-scaffolder-backend-module-github@0.2.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.1.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.2.13 + - @backstage/plugin-scaffolder-backend-module-azure@0.1.2 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.1.0 + - @backstage/plugin-scaffolder-node@0.3.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.7 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.0 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + ## 1.21.0-next.3 ### Patch Changes diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 81e5ffb9f9..6af1ac04a6 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -4,12 +4,15 @@ ```ts import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node'; +import { AuthService } from '@backstage/backend-plugin-api'; import * as azure from '@backstage/plugin-scaffolder-backend-module-azure'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; import * as bitbucket from '@backstage/plugin-scaffolder-backend-module-bitbucket'; import * as bitbucketCloud from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud'; import * as bitbucketServer from '@backstage/plugin-scaffolder-backend-module-bitbucket-server'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { Duration } from 'luxon'; import { executeShellCommand as executeShellCommand_2 } from '@backstage/plugin-scaffolder-node'; import { ExecuteShellCommandOptions } from '@backstage/plugin-scaffolder-node'; @@ -18,15 +21,18 @@ import { fetchContents as fetchContents_2 } from '@backstage/plugin-scaffolder-n import * as gerrit from '@backstage/plugin-scaffolder-backend-module-gerrit'; import * as github from '@backstage/plugin-scaffolder-backend-module-github'; import * as gitlab from '@backstage/plugin-scaffolder-backend-module-gitlab'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { HumanDuration } from '@backstage/types'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; import { LifecycleService } from '@backstage/backend-plugin-api'; import { Logger } from 'winston'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; +import { PermissionsService } from '@backstage/backend-plugin-api'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { RESOURCE_TYPE_SCAFFOLDER_ACTION } from '@backstage/plugin-scaffolder-common/alpha'; @@ -81,6 +87,7 @@ export interface CreateBuiltInActionsOptions { additionalTemplateFilters?: Record; // (undocumented) additionalTemplateGlobals?: Record; + auth?: AuthService; catalogClient: CatalogApi; config: Config; integrations: ScmIntegrations; @@ -91,6 +98,7 @@ export interface CreateBuiltInActionsOptions { export function createCatalogRegisterAction(options: { catalogClient: CatalogApi; integrations: ScmIntegrations; + auth?: AuthService; }): TemplateAction_2< | { catalogInfoUrl: string; @@ -125,6 +133,7 @@ export function createDebugLogAction(): TemplateAction_2< // @public export function createFetchCatalogEntityAction(options: { catalogClient: CatalogApi; + auth?: AuthService; }): TemplateAction_2< { entityRef?: string | undefined; @@ -359,6 +368,7 @@ export interface CurrentClaimedTask { createdBy?: string; secrets?: TaskSecrets_2; spec: TaskSpec; + state?: JsonObject; taskId: string; } @@ -397,6 +407,13 @@ export class DatabaseTaskStore implements TaskStore { // (undocumented) getTask(taskId: string): Promise; // (undocumented) + getTaskState({ taskId }: { taskId: string }): Promise< + | { + state: JsonObject; + } + | undefined + >; + // (undocumented) heartbeatTask(taskId: string): Promise; // (undocumented) list(options: { createdBy?: string }): Promise<{ @@ -418,6 +435,8 @@ export class DatabaseTaskStore implements TaskStore { ids: string[]; }>; // (undocumented) + saveTaskState(options: { taskId: string; state?: JsonObject }): Promise; + // (undocumented) shutdownTask(options: TaskStoreShutDownTaskOptions): Promise; } @@ -441,6 +460,8 @@ export interface RouterOptions { // (undocumented) additionalTemplateGlobals?: Record; // (undocumented) + auth?: AuthService; + // (undocumented) catalogClient: CatalogApi; concurrentTasksLimit?: number; // (undocumented) @@ -448,6 +469,10 @@ export interface RouterOptions { // (undocumented) database: PluginDatabaseManager; // (undocumented) + discovery?: DiscoveryService; + // (undocumented) + httpAuth?: HttpAuthService; + // (undocumented) identity?: IdentityApi; // (undocumented) lifecycle?: LifecycleService; @@ -458,7 +483,7 @@ export interface RouterOptions { TemplatePermissionRuleInput | ActionPermissionRuleInput >; // (undocumented) - permissions?: PermissionEvaluator; + permissions?: PermissionsService; // (undocumented) reader: UrlReader; // (undocumented) @@ -511,6 +536,7 @@ export class TaskManager implements TaskContext_2 { storage: TaskStore, abortSignal: AbortSignal, logger: Logger, + auth?: AuthService, ): TaskManager; // (undocumented) get createdBy(): string | undefined; @@ -519,11 +545,34 @@ export class TaskManager implements TaskContext_2 { // (undocumented) emitLog(message: string, logMetadata?: JsonObject): Promise; // (undocumented) + getInitiatorCredentials(): Promise; + // (undocumented) + getTaskState?(): Promise< + | { + state?: JsonObject; + } + | undefined + >; + // (undocumented) getWorkspaceName(): Promise; // (undocumented) get secrets(): TaskSecrets_2 | undefined; // (undocumented) get spec(): TaskSpecV1beta3; + // (undocumented) + updateCheckpoint?( + options: + | { + key: string; + status: 'success'; + value: JsonValue; + } + | { + key: string; + status: 'failed'; + reason: string; + }, + ): Promise; } // @public @deprecated (undocumented) @@ -553,6 +602,13 @@ export interface TaskStore { // (undocumented) getTask(taskId: string): Promise; // (undocumented) + getTaskState?({ taskId }: { taskId: string }): Promise< + | { + state: JsonObject; + } + | undefined + >; + // (undocumented) heartbeatTask(taskId: string): Promise; // (undocumented) list?(options: { createdBy?: string }): Promise<{ @@ -573,6 +629,11 @@ export interface TaskStore { ids: string[]; }>; // (undocumented) + saveTaskState?(options: { + taskId: string; + state?: JsonObject; + }): Promise; + // (undocumented) shutdownTask?(options: TaskStoreShutDownTaskOptions): Promise; } diff --git a/plugins/scaffolder-backend/migrations/20240203232000_state.js b/plugins/scaffolder-backend/migrations/20240203232000_state.js new file mode 100644 index 0000000000..9ffea1716e --- /dev/null +++ b/plugins/scaffolder-backend/migrations/20240203232000_state.js @@ -0,0 +1,35 @@ +/* + * 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. + */ + +// @ts-check + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + await knex.schema.alterTable('tasks', table => { + table.text('state').nullable().comment('A state of the checkpoints'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('tasks', table => { + table.dropColumn('state'); + }); +}; diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 9026761a7c..d107d578cb 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,18 +1,30 @@ { "name": "@backstage/plugin-scaffolder-backend", + "version": "1.22.5-next.0", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.21.0-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +35,21 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/scaffolder-backend" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "migrations", + "config.d.ts", + "assets" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "build:assets": "node scripts/build-nunjucks.js", + "clean": "backstage-cli package clean", "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", - "build:assets": "node scripts/build-nunjucks.js" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -64,6 +70,7 @@ "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "workspace:^", "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^", "@backstage/plugin-scaffolder-backend-module-gerrit": "workspace:^", + "@backstage/plugin-scaffolder-backend-module-gitea": "workspace:^", "@backstage/plugin-scaffolder-backend-module-github": "workspace:^", "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^", "@backstage/plugin-scaffolder-common": "workspace:^", @@ -80,13 +87,15 @@ "jsonschema": "^1.2.6", "knex": "^3.0.0", "lodash": "^4.17.21", + "logform": "^2.3.2", "luxon": "^3.0.0", "nunjucks": "^3.2.3", "p-limit": "^3.1.0", "p-queue": "^6.6.2", "prom-client": "^15.0.0", - "uuid": "^8.2.0", + "uuid": "^9.0.0", "winston": "^3.2.1", + "winston-transport": "^4.7.0", "yaml": "^2.0.0", "zen-observable": "^0.10.0", "zod": "^3.22.4" @@ -94,6 +103,7 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^", "@types/fs-extra": "^11.0.0", "@types/nunjucks": "^3.1.4", "@types/supertest": "^2.0.8", @@ -103,11 +113,5 @@ "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" }, - "files": [ - "dist", - "migrations", - "config.d.ts", - "assets" - ], "configSchema": "config.d.ts" } diff --git a/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile b/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile index 6aa3c0dfa0..ecaefee183 100644 --- a/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile +++ b/plugins/scaffolder-backend/scripts/Cookiecutter.dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.18 +FROM alpine:3.19 RUN apk add --update \ git \ diff --git a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts index 61c5ed12ee..a8213cf585 100644 --- a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts +++ b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts @@ -90,7 +90,10 @@ export const scaffolderPlugin = createBackendPlugin({ reader: coreServices.urlReader, permissions: coreServices.permissions, database: coreServices.database, + auth: coreServices.auth, + discovery: coreServices.discovery, httpRouter: coreServices.httpRouter, + httpAuth: coreServices.httpAuth, catalogClient: catalogServiceRef, }, async init({ @@ -99,7 +102,10 @@ export const scaffolderPlugin = createBackendPlugin({ lifecycle, reader, database, + auth, + discovery, httpRouter, + httpAuth, catalogClient, permissions, }) { @@ -128,8 +134,8 @@ export const scaffolderPlugin = createBackendPlugin({ createDebugLogAction(), createWaitAction(), // todo(blam): maybe these should be a -catalog module? - createCatalogRegisterAction({ catalogClient, integrations }), - createFetchCatalogEntityAction({ catalogClient }), + createCatalogRegisterAction({ catalogClient, integrations, auth }), + createFetchCatalogEntityAction({ catalogClient, auth }), createCatalogWriteAction(), createFilesystemDeleteAction(), createFilesystemRenameAction(), @@ -152,6 +158,9 @@ export const scaffolderPlugin = createBackendPlugin({ taskBroker, additionalTemplateFilters, additionalTemplateGlobals, + auth, + httpAuth, + discovery, permissions, }); httpRouter.use(router); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts index 161ff9d1de..549ed923c2 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.examples.test.ts @@ -14,14 +14,13 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; -import os from 'os'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { CatalogApi } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { createFetchCatalogEntityAction } from './fetch'; import { examples } from './fetch.examples'; import yaml from 'yaml'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; describe('catalog:fetch examples', () => { const getEntityByRef = jest.fn(); @@ -34,16 +33,19 @@ describe('catalog:fetch examples', () => { const action = createFetchCatalogEntityAction({ catalogClient: catalogClient as unknown as CatalogApi, + auth: mockServices.auth(), }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - secrets: { backstageToken: 'secret' }, - }; + const credentials = mockCredentials.user(); + + const token = mockCredentials.service.token({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + + const mockContext = createMockActionContext({ + secrets: { backstageToken: token }, + }); beforeEach(() => { jest.resetAllMocks(); }); @@ -64,7 +66,7 @@ describe('catalog:fetch examples', () => { }); expect(getEntityByRef).toHaveBeenCalledWith('component:default/name', { - token: 'secret', + token, }); expect(mockContext.output).toHaveBeenCalledWith('entity', { metadata: { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts index bed15f2e39..747414f206 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts @@ -14,12 +14,11 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; -import os from 'os'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { CatalogApi } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import { createFetchCatalogEntityAction } from './fetch'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; describe('catalog:fetch', () => { const getEntityByRef = jest.fn(); @@ -32,16 +31,20 @@ describe('catalog:fetch', () => { const action = createFetchCatalogEntityAction({ catalogClient: catalogClient as unknown as CatalogApi, + auth: mockServices.auth(), + }); + + const credentials = mockCredentials.user(); + + const token = mockCredentials.service.token({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + + const mockContext = createMockActionContext({ + secrets: { backstageToken: token }, }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - secrets: { backstageToken: 'secret' }, - }; beforeEach(() => { jest.resetAllMocks(); }); @@ -64,7 +67,7 @@ describe('catalog:fetch', () => { }); expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token: 'secret', + token, }); expect(mockContext.output).toHaveBeenCalledWith('entity', { metadata: { @@ -90,7 +93,7 @@ describe('catalog:fetch', () => { ).rejects.toThrow('Not found'); expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token: 'secret', + token, }); expect(mockContext.output).not.toHaveBeenCalled(); }); @@ -108,7 +111,7 @@ describe('catalog:fetch', () => { ).rejects.toThrow('Entity component:default/test not found'); expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { - token: 'secret', + token, }); expect(mockContext.output).not.toHaveBeenCalled(); }); @@ -133,7 +136,7 @@ describe('catalog:fetch', () => { }); expect(getEntityByRef).toHaveBeenCalledWith('group:ns/test', { - token: 'secret', + token, }); expect(mockContext.output).toHaveBeenCalledWith('entity', entity); }); @@ -163,7 +166,7 @@ describe('catalog:fetch', () => { expect(getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['component:default/test'] }, { - token: 'secret', + token, }, ); expect(mockContext.output).toHaveBeenCalledWith('entities', [ @@ -204,7 +207,7 @@ describe('catalog:fetch', () => { expect(getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['component:default/test', 'component:default/test2'] }, { - token: 'secret', + token, }, ); expect(mockContext.output).not.toHaveBeenCalled(); @@ -235,7 +238,7 @@ describe('catalog:fetch', () => { expect(getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['component:default/test', 'component:default/test2'] }, { - token: 'secret', + token, }, ); expect(mockContext.output).toHaveBeenCalledWith('entities', [ @@ -281,7 +284,7 @@ describe('catalog:fetch', () => { expect(getEntitiesByRefs).toHaveBeenCalledWith( { entityRefs: ['group:ns/test', 'user:default/test'] }, { - token: 'secret', + token, }, ); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts index 75c4bc94ce..824ca4deb3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts @@ -19,6 +19,7 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { z } from 'zod'; import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { examples } from './fetch.examples'; +import { AuthService } from '@backstage/backend-plugin-api'; const id = 'catalog:fetch'; @@ -29,8 +30,9 @@ const id = 'catalog:fetch'; */ export function createFetchCatalogEntityAction(options: { catalogClient: CatalogApi; + auth?: AuthService; }) { - const { catalogClient } = options; + const { catalogClient, auth } = options; return createTemplateAction({ id, @@ -88,13 +90,18 @@ export function createFetchCatalogEntityAction(options: { throw new Error('Missing entity reference or references'); } + const { token } = (await auth?.getPluginRequestToken({ + onBehalfOf: await ctx.getInitiatorCredentials(), + targetPluginId: 'catalog', + })) ?? { token: ctx.secrets?.backstageToken }; + if (entityRef) { const entity = await catalogClient.getEntityByRef( stringifyEntityRef( parseEntityRef(entityRef, { defaultKind, defaultNamespace }), ), { - token: ctx.secrets?.backstageToken, + token, }, ); @@ -114,7 +121,7 @@ export function createFetchCatalogEntityAction(options: { ), }, { - token: ctx.secrets?.backstageToken, + token, }, ); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts index eb5aa88c0f..d279af78dc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.examples.test.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; -import os from 'os'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; @@ -24,6 +22,7 @@ import { createCatalogRegisterAction } from './register'; import { Entity } from '@backstage/catalog-model'; import { examples } from './register.examples'; import yaml from 'yaml'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; describe('catalog:register', () => { const integrations = ScmIntegrations.fromConfig( @@ -42,15 +41,17 @@ describe('catalog:register', () => { const action = createCatalogRegisterAction({ integrations, catalogClient: catalogClient as unknown as CatalogApi, + auth: mockServices.auth(), }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const credentials = mockCredentials.user(); + + const token = mockCredentials.service.token({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + + const mockContext = createMockActionContext(); beforeEach(() => { jest.resetAllMocks(); }); @@ -83,7 +84,7 @@ describe('catalog:register', () => { target: 'http://github.com/backstage/backstage/blob/master/catalog-info.yaml', }, - {}, + { token }, ); expect(addLocation).toHaveBeenNthCalledWith( 2, @@ -93,7 +94,7 @@ describe('catalog:register', () => { target: 'http://github.com/backstage/backstage/blob/master/catalog-info.yaml', }, - {}, + { token }, ); expect(mockContext.output).toHaveBeenCalledWith( diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts index bae9f04575..2db232afa0 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts @@ -14,14 +14,13 @@ * limitations under the License. */ -import { PassThrough } from 'stream'; -import os from 'os'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createCatalogRegisterAction } from './register'; import { Entity } from '@backstage/catalog-model'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; describe('catalog:register', () => { const integrations = ScmIntegrations.fromConfig( @@ -40,15 +39,18 @@ describe('catalog:register', () => { const action = createCatalogRegisterAction({ integrations, catalogClient: catalogClient as unknown as CatalogApi, + auth: mockServices.auth(), }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const credentials = mockCredentials.user(); + + const token = mockCredentials.service.token({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + + const mockContext = createMockActionContext(); + beforeEach(() => { jest.resetAllMocks(); }); @@ -95,7 +97,7 @@ describe('catalog:register', () => { type: 'url', target: 'http://foo/var', }, - {}, + { token }, ); expect(addLocation).toHaveBeenNthCalledWith( 2, @@ -104,7 +106,7 @@ describe('catalog:register', () => { type: 'url', target: 'http://foo/var', }, - {}, + { token }, ); expect(mockContext.output).toHaveBeenCalledWith( @@ -281,7 +283,7 @@ describe('catalog:register', () => { type: 'url', target: 'http://foo/var', }, - {}, + { token }, ); expect(addLocation).toHaveBeenNthCalledWith( 2, @@ -290,7 +292,7 @@ describe('catalog:register', () => { type: 'url', target: 'http://foo/var', }, - {}, + { token }, ); expect(mockContext.output).toHaveBeenCalledWith( @@ -327,7 +329,7 @@ describe('catalog:register', () => { type: 'url', target: 'http://foo/var', }, - {}, + { token }, ); expect(addLocation).toHaveBeenNthCalledWith( 2, @@ -336,7 +338,7 @@ describe('catalog:register', () => { type: 'url', target: 'http://foo/var', }, - {}, + { token }, ); expect(mockContext.output).toHaveBeenCalledWith( diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts index 39372f484f..eab31f14df 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -20,6 +20,7 @@ import { CatalogApi } from '@backstage/catalog-client'; import { stringifyEntityRef, Entity } from '@backstage/catalog-model'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { examples } from './register.examples'; +import { AuthService } from '@backstage/backend-plugin-api'; const id = 'catalog:register'; @@ -30,8 +31,9 @@ const id = 'catalog:register'; export function createCatalogRegisterAction(options: { catalogClient: CatalogApi; integrations: ScmIntegrations; + auth?: AuthService; }) { - const { catalogClient, integrations } = options; + const { catalogClient, integrations, auth } = options; return createTemplateAction< | { catalogInfoUrl: string; optional?: boolean } @@ -125,6 +127,11 @@ export function createCatalogRegisterAction(options: { ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`); + const { token } = (await auth?.getPluginRequestToken({ + onBehalfOf: await ctx.getInitiatorCredentials(), + targetPluginId: 'catalog', + })) ?? { token: ctx.secrets?.backstageToken }; + try { // 1st try to register the location, this will throw an error if the location already exists (see catch) await catalogClient.addLocation( @@ -132,9 +139,7 @@ export function createCatalogRegisterAction(options: { type: 'url', target: catalogInfoUrl, }, - ctx.secrets?.backstageToken - ? { token: ctx.secrets.backstageToken } - : {}, + token ? { token } : {}, ); } catch (e) { if (!input.optional) { @@ -151,9 +156,7 @@ export function createCatalogRegisterAction(options: { type: 'url', target: catalogInfoUrl, }, - ctx.secrets?.backstageToken - ? { token: ctx.secrets.backstageToken } - : {}, + token ? { token } : {}, ); if (result.entities.length) { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts index daa8f4f6b1..e6b4bcde47 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.examples.test.ts @@ -20,24 +20,16 @@ jest.mock('fs-extra'); const fsMock = fs as jest.Mocked; -import { PassThrough } from 'stream'; -import os from 'os'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createCatalogWriteAction } from './write'; import { resolve as resolvePath } from 'path'; import * as yaml from 'yaml'; import { examples } from './write.examples'; +import os from 'os'; describe('catalog:write', () => { const action = createCatalogWriteAction(); - - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext({ workspacePath: os.tmpdir() }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts index dd6f29f99b..658e4365bf 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.test.ts @@ -20,9 +20,8 @@ jest.mock('fs-extra'); const fsMock = fs as jest.Mocked; -import { PassThrough } from 'stream'; import os from 'os'; -import { getVoidLogger } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model'; import { createCatalogWriteAction } from './write'; import { resolve as resolvePath } from 'path'; @@ -31,18 +30,14 @@ import * as yaml from 'yaml'; describe('catalog:write', () => { const action = createCatalogWriteAction(); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; - beforeEach(() => { jest.resetAllMocks(); }); + const mockContext = createMockActionContext({ + workspacePath: os.tmpdir(), + }); + it('should write the catalog-info.yml in the workspace', async () => { const entity = { apiVersion: 'backstage.io/v1alpha1', @@ -99,4 +94,34 @@ describe('catalog:write', () => { yaml.stringify(entity), ); }); + + it('should add backstage.io/source-template if provided', async () => { + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'n', + namespace: 'ns', + annotations: {}, + }, + spec: {}, + }; + + await action.handler({ + ...mockContext, + templateInfo: { entityRef: 'template:default/test-skeleton' }, + input: { entity }, + }); + + const expectedEntity = JSON.parse(JSON.stringify(entity)); + expectedEntity.metadata.annotations = { + 'backstage.io/source-template': 'template:default/test-skeleton', + }; + + expect(fsMock.writeFile).toHaveBeenCalledTimes(1); + expect(fsMock.writeFile).toHaveBeenCalledWith( + resolvePath(mockContext.workspacePath, 'catalog-info.yaml'), + yaml.stringify(expectedEntity), + ); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts index 7663ad15c8..27c39dd098 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/write.ts @@ -49,13 +49,27 @@ export function createCatalogWriteAction() { examples, supportsDryRun: true, async handler(ctx) { - ctx.logStream.write(`Writing catalog-info.yaml`); + ctx.logger.info(`Writing catalog-info.yaml`); const { filePath, entity } = ctx.input; + const entityRef = ctx.templateInfo?.entityRef; const path = filePath ?? 'catalog-info.yaml'; await fs.writeFile( resolveSafeChildPath(ctx.workspacePath, path), - yaml.stringify(entity), + yaml.stringify({ + ...entity, + metadata: { + ...entity.metadata, + ...(entityRef + ? { + annotations: { + ...entity.metadata.annotations, + 'backstage.io/source-template': entityRef, + }, + } + : undefined), + }, + }), ); }, }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index f9c15597a8..a017c2e224 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -81,6 +81,9 @@ import { createPublishGitlabMergeRequestAction, } from '@backstage/plugin-scaffolder-backend-module-gitlab'; +import { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea'; +import { AuthService } from '@backstage/backend-plugin-api'; + /** * The options passed to {@link createBuiltinActions} * @public @@ -98,6 +101,10 @@ export interface CreateBuiltInActionsOptions { * The {@link @backstage/catalog-client#CatalogApi} that will be used in the default actions. */ catalogClient: CatalogApi; + /** + * The {@link @backstage/backend-plugin-api#AuthService} that will be used in the default actions. + */ + auth?: AuthService; /** * The {@link @backstage/config#Config} that will be used in the default actions. */ @@ -127,6 +134,7 @@ export const createBuiltinActions = ( reader, integrations, catalogClient, + auth, config, additionalTemplateFilters, additionalTemplateGlobals, @@ -158,6 +166,10 @@ export const createBuiltinActions = ( integrations, config, }), + createPublishGiteaAction({ + integrations, + config, + }), createPublishGithubAction({ integrations, config, @@ -199,8 +211,8 @@ export const createBuiltinActions = ( }), createDebugLogAction(), createWaitAction(), - createCatalogRegisterAction({ catalogClient, integrations }), - createFetchCatalogEntityAction({ catalogClient }), + createCatalogRegisterAction({ catalogClient, integrations, auth }), + createFetchCatalogEntityAction({ catalogClient, auth }), createCatalogWriteAction(), createFilesystemDeleteAction(), createFilesystemRenameAction(), diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.test.ts index 901f3e5011..0c37db9eb9 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.examples.test.ts @@ -14,31 +14,26 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; -import { Writable } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createDebugLogAction } from './log'; import { join } from 'path'; import yaml from 'yaml'; import { examples } from './log.examples'; import { createMockDirectory } from '@backstage/backend-test-utils'; +import { Logger } from 'winston'; describe('debug:log examples', () => { - const logStream = { - write: jest.fn(), - } as jest.Mocked> as jest.Mocked; + const logger = { + info: jest.fn(), + } as unknown as jest.Mocked; const mockDir = createMockDirectory(); const workspacePath = mockDir.resolve('workspace'); - const mockContext = { - input: {}, - baseUrl: 'somebase', + const mockContext = createMockActionContext({ + logger, workspacePath, - logger: getVoidLogger(), - logStream, - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); const action = createDebugLogAction(); @@ -51,32 +46,26 @@ describe('debug:log examples', () => { }); it('should log message', async () => { - const context = { + await action.handler({ ...mockContext, input: yaml.parse(examples[0].example).steps[0].input, - }; + }); - await action.handler(context); - - expect(logStream.write).toHaveBeenCalledTimes(1); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining('Hello Backstage!'), ); }); it('should log the workspace content, if active', async () => { - const context = { + await action.handler({ ...mockContext, input: yaml.parse(examples[1].example).steps[0].input, - }; + }); - await action.handler(context); - - expect(logStream.write).toHaveBeenCalledTimes(1); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining('README.md'), ); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining(join('a-directory', 'index.md')), ); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts index d6fc5174b3..9c626f1dfe 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.test.ts @@ -14,30 +14,22 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; -import { Writable } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { Logger } from 'winston'; import { createDebugLogAction } from './log'; import { join } from 'path'; import yaml from 'yaml'; import { createMockDirectory } from '@backstage/backend-test-utils'; describe('debug:log', () => { - const logStream = { - write: jest.fn(), - } as jest.Mocked> as jest.Mocked; + const logger = { + info: jest.fn(), + } as unknown as jest.Mocked; const mockDir = createMockDirectory(); const workspacePath = mockDir.resolve('workspace'); - const mockContext = { - input: {}, - baseUrl: 'somebase', - workspacePath, - logger: getVoidLogger(), - logStream, - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext({ workspacePath, logger }); const action = createDebugLogAction(); @@ -49,12 +41,6 @@ describe('debug:log', () => { jest.resetAllMocks(); }); - it('should do nothing', async () => { - await action.handler(mockContext); - - expect(logStream.write).toHaveBeenCalledTimes(0); - }); - it('should log the workspace content, if active', async () => { const context = { ...mockContext, @@ -65,11 +51,10 @@ describe('debug:log', () => { await action.handler(context); - expect(logStream.write).toHaveBeenCalledTimes(1); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining('README.md'), ); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining(join('a-directory', 'index.md')), ); }); @@ -84,8 +69,7 @@ describe('debug:log', () => { await action.handler(context); - expect(logStream.write).toHaveBeenCalledTimes(1); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining('Hello Backstage!'), ); }); @@ -102,11 +86,10 @@ describe('debug:log', () => { await action.handler(context); - expect(logStream.write).toHaveBeenCalledTimes(1); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining('README.md'), ); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining(join('a-directory', 'index.md')), ); }); @@ -123,8 +106,7 @@ describe('debug:log', () => { await action.handler(context); - expect(logStream.write).toHaveBeenCalledTimes(1); - expect(logStream.write).toHaveBeenCalledWith( + expect(logger.info).toHaveBeenCalledWith( expect.stringContaining('Hello Backstage!'), ); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts index 524e12b5c9..98ab02437e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/log.ts @@ -60,12 +60,12 @@ export function createDebugLogAction() { ctx.logger.info(JSON.stringify(ctx.input, null, 2)); if (ctx.input?.message) { - ctx.logStream.write(ctx.input.message); + ctx.logger.info(ctx.input.message); } if (ctx.input?.listWorkspace) { const files = await recursiveReadDir(ctx.workspacePath); - ctx.logStream.write( + ctx.logger.info( `Workspace:\n${files .map(f => ` - ${relative(ctx.workspacePath, f)}`) .join('\n')}`, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.examples.test.ts index 9b755d86dd..8bc29a74c9 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.examples.test.ts @@ -14,12 +14,11 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { createWaitAction } from './wait'; import { Writable } from 'stream'; import { examples } from './wait.examples'; import yaml from 'yaml'; -import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('debug:wait examples', () => { const action = createWaitAction(); @@ -28,18 +27,9 @@ describe('debug:wait examples', () => { write: jest.fn(), } as jest.Mocked> as jest.Mocked; - const mockDir = createMockDirectory(); - const workspacePath = mockDir.resolve('workspace'); - - const mockContext = { - input: {}, - baseUrl: 'somebase', - workspacePath, - logger: getVoidLogger(), + const mockContext = createMockActionContext({ logStream, - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.test.ts index 6f80604a6d..0dcbd10f0f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/debug/wait.test.ts @@ -14,10 +14,9 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; import { createWaitAction } from './wait'; import { Writable } from 'stream'; -import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; describe('debug:wait', () => { const action = createWaitAction(); @@ -26,18 +25,9 @@ describe('debug:wait', () => { write: jest.fn(), } as jest.Mocked> as jest.Mocked; - const mockDir = createMockDirectory(); - const workspacePath = mockDir.resolve('workspace'); - - const mockContext = { - input: {}, - baseUrl: 'somebase', - workspacePath, - logger: getVoidLogger(), + const mockContext = createMockActionContext({ logStream, - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.resetAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.examples.test.ts index 6b308a97eb..82a32fcbac 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.examples.test.ts @@ -16,14 +16,13 @@ import yaml from 'yaml'; -import os from 'os'; import { resolve as resolvePath } from 'path'; -import { getVoidLogger, UrlReader } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createFetchPlainAction } from './plain'; -import { PassThrough } from 'stream'; import { fetchContents } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { examples } from './plain.examples'; jest.mock('@backstage/plugin-scaffolder-node', () => ({ @@ -50,19 +49,15 @@ describe('fetch:plain examples', () => { }); const action = createFetchPlainAction({ integrations, reader }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); it('should fetch plain', async () => { - await action.handler({ - ...mockContext, - input: yaml.parse(examples[0].example).steps[0].input, - }); + await action.handler( + createMockActionContext({ + ...mockContext, + input: yaml.parse(examples[0].example).steps[0].input, + }), + ); expect(fetchContents).toHaveBeenCalledWith( expect.objectContaining({ outputPath: resolvePath(mockContext.workspacePath), diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.test.ts index 917624acf4..bc20fafe19 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plain.test.ts @@ -19,14 +19,13 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { return { ...actual, fetchContents: jest.fn() }; }); -import os from 'os'; import { resolve as resolvePath } from 'path'; -import { getVoidLogger, UrlReader } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { UrlReader } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { fetchContents } from '@backstage/plugin-scaffolder-node'; import { createFetchPlainAction } from './plain'; -import { PassThrough } from 'stream'; describe('fetch:plain', () => { const integrations = ScmIntegrations.fromConfig( @@ -47,13 +46,7 @@ describe('fetch:plain', () => { }); const action = createFetchPlainAction({ integrations, reader }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); it('should disallow a target path outside working directory', async () => { await expect( diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.examples.test.ts index 2ee17c29fe..9978d6d8f5 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.examples.test.ts @@ -14,19 +14,19 @@ * limitations under the License. */ +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; + jest.mock('@backstage/plugin-scaffolder-node', () => { const actual = jest.requireActual('@backstage/plugin-scaffolder-node'); return { ...actual, fetchFile: jest.fn() }; }); import yaml from 'yaml'; -import os from 'os'; import { resolve as resolvePath } from 'path'; -import { getVoidLogger, UrlReader } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { createFetchPlainFileAction } from './plainFile'; -import { PassThrough } from 'stream'; import { fetchFile } from '@backstage/plugin-scaffolder-node'; import { examples } from './plainFile.examples'; @@ -49,13 +49,7 @@ describe('fetch:plain:file examples', () => { }); const action = createFetchPlainFileAction({ integrations, reader }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); it('should fetch plain', async () => { await action.handler({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.test.ts index 7ea74a809b..bf40c7ad0e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/plainFile.test.ts @@ -19,14 +19,13 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { return { ...actual, fetchFile: jest.fn() }; }); -import os from 'os'; import { resolve as resolvePath } from 'path'; -import { getVoidLogger, UrlReader } from '@backstage/backend-common'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import { UrlReader } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { fetchFile } from '@backstage/plugin-scaffolder-node'; import { createFetchPlainFileAction } from './plainFile'; -import { PassThrough } from 'stream'; describe('fetch:plain:file', () => { const integrations = ScmIntegrations.fromConfig( @@ -47,13 +46,7 @@ describe('fetch:plain:file', () => { }); const action = createFetchPlainFileAction({ integrations, reader }); - const mockContext = { - workspacePath: os.tmpdir(), - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + const mockContext = createMockActionContext(); it('should disallow a target path outside working directory', async () => { await expect( diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.examples.test.ts index a1c8381178..36f1f00b50 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.examples.test.ts @@ -16,13 +16,9 @@ import { join as joinPath, sep as pathSep } from 'path'; import fs from 'fs-extra'; -import { - getVoidLogger, - resolvePackagePath, - UrlReader, -} from '@backstage/backend-common'; +import { resolvePackagePath, UrlReader } from '@backstage/backend-common'; import { ScmIntegrations } from '@backstage/integration'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { createFetchTemplateAction } from './template'; import { ActionContext, @@ -61,23 +57,15 @@ describe('fetch:template examples', () => { const mockDir = createMockDirectory(); const workspacePath = mockDir.resolve('workspace'); - const logger = getVoidLogger(); - - const mockContext = (input: any) => ({ - templateInfo: { - baseUrl: 'base-url', - entityRef: 'template:default/test-template', - }, - input: input, - output: jest.fn(), - logStream: new PassThrough(), - logger, - workspacePath, - - async createTemporaryDirectory() { - return fs.mkdtemp(mockDir.resolve('tmp-')); - }, - }); + const mockContext = (input: any) => + createMockActionContext({ + templateInfo: { + baseUrl: 'base-url', + entityRef: 'template:default/test-template', + }, + input, + workspacePath, + }); beforeEach(() => { mockDir.clear(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts index 25b65462e6..fd0ef7d757 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts @@ -21,13 +21,8 @@ jest.mock('@backstage/plugin-scaffolder-node', () => { import { join as joinPath, sep as pathSep } from 'path'; import fs from 'fs-extra'; -import { - getVoidLogger, - resolvePackagePath, - UrlReader, -} from '@backstage/backend-common'; +import { resolvePackagePath, UrlReader } from '@backstage/backend-common'; import { ScmIntegrations } from '@backstage/integration'; -import { PassThrough } from 'stream'; import { createFetchTemplateAction } from './template'; import { fetchContents, @@ -35,6 +30,7 @@ import { TemplateAction, } from '@backstage/plugin-scaffolder-node'; import { createMockDirectory } from '@backstage/backend-test-utils'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; type FetchTemplateInput = ReturnType< typeof createFetchTemplateAction @@ -59,29 +55,22 @@ describe('fetch:template', () => { const mockDir = createMockDirectory(); const workspacePath = mockDir.resolve('workspace'); - const logger = getVoidLogger(); - - const mockContext = (inputPatch: Partial = {}) => ({ - templateInfo: { - baseUrl: 'base-url', - entityRef: 'template:default/test-template', - }, - input: { - url: './skeleton', - targetPath: './target', - values: { - test: 'value', + const mockContext = (inputPatch: Partial = {}) => + createMockActionContext({ + templateInfo: { + baseUrl: 'base-url', + entityRef: 'template:default/test-template', }, - ...inputPatch, - }, - output: jest.fn(), - logStream: new PassThrough(), - logger, - workspacePath, - async createTemporaryDirectory() { - return fs.mkdtemp(mockDir.resolve('tmp-')); - }, - }); + input: { + url: './skeleton', + targetPath: './target', + values: { + test: 'value', + }, + ...inputPatch, + }, + workspacePath, + }); beforeEach(() => { mockDir.setContent({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.examples.test.ts index 023f049ebc..d11b1e4087 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.examples.test.ts @@ -15,8 +15,7 @@ */ import { createFilesystemDeleteAction } from './delete'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import { resolve as resolvePath } from 'path'; import fs from 'fs-extra'; import yaml from 'yaml'; @@ -31,16 +30,12 @@ describe('fs:delete examples', () => { const files: string[] = yaml.parse(examples[0].example).steps[0].input.files; - const mockContext = { + const mockContext = createMockActionContext({ input: { files: files, }, workspacePath, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.restoreAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.test.ts index 2a4f45b862..8226133376 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/delete.test.ts @@ -16,8 +16,7 @@ import { resolve as resolvePath } from 'path'; import { createFilesystemDeleteAction } from './delete'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import fs from 'fs-extra'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -27,16 +26,12 @@ describe('fs:delete', () => { const mockDir = createMockDirectory(); const workspacePath = resolvePath(mockDir.path, 'workspace'); - const mockContext = { + const mockContext = createMockActionContext({ input: { files: ['unit-test-a.js', 'unit-test-b.js'], }, workspacePath, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.restoreAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.examples.test.ts index cbb0fa0d0b..0881bb8260 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.examples.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.examples.test.ts @@ -16,8 +16,7 @@ import { resolve as resolvePath } from 'path'; import { createFilesystemRenameAction } from './rename'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import fs from 'fs-extra'; import yaml from 'yaml'; import { examples } from './rename.examples'; @@ -31,16 +30,12 @@ describe('fs:rename examples', () => { const mockDir = createMockDirectory(); const workspacePath = resolvePath(mockDir.path, 'workspace'); - const mockContext = { + const mockContext = createMockActionContext({ input: { - files: files, + files, }, workspacePath, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.restoreAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.test.ts index d37e967f43..6696fda693 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/filesystem/rename.test.ts @@ -16,8 +16,7 @@ import { resolve as resolvePath } from 'path'; import { createFilesystemRenameAction } from './rename'; -import { getVoidLogger } from '@backstage/backend-common'; -import { PassThrough } from 'stream'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; import fs from 'fs-extra'; import { createMockDirectory } from '@backstage/backend-test-utils'; @@ -41,16 +40,12 @@ describe('fs:rename', () => { to: 'brand-new-folder', }, ]; - const mockContext = { + const mockContext = createMockActionContext({ input: { files: mockInputFiles, }, workspacePath, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn(), - }; + }); beforeEach(() => { jest.restoreAllMocks(); diff --git a/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts b/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts index e202111d79..2eaa505c8c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts @@ -35,11 +35,13 @@ import { DecoratedActionsRegistry } from './DecoratedActionsRegistry'; import fs from 'fs-extra'; import { resolveSafeChildPath } from '@backstage/backend-common'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; interface DryRunInput { spec: TaskSpec; secrets?: TaskSecrets; directoryContents: SerializedFile[]; + credentials: BackstageCredentials; } interface DryRunResult { @@ -116,6 +118,7 @@ export function createDryRunner(options: TemplateTesterCreateOptions) { }, }, secrets: input.secrets, + getInitiatorCredentials: () => Promise.resolve(input.credentials), // No need to update this at the end of the run, so just hard-code it done: false, isDryRun: true, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts index 4c0eb94c82..ab80dcff04 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.test.ts @@ -161,6 +161,44 @@ describe('DatabaseTaskStore', () => { expect(claimedTask.status).toBe('processing'); }); + it('should restore the state of the task after the task recovery', async () => { + const { store } = await createStore(); + const { taskId } = await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'me', + }); + + const task = await store.getTask(taskId); + expect(task.status).toBe('open'); + await store.claimTask(); + + const state = { + state: { + checkpoints: { + 'v1.task.checkpoint.deploy.to.stg': { + status: 'success', + value: true, + }, + 'v1.task.checkpoint.deploy.to.pro': { + status: 'success', + value: true, + }, + }, + }, + }; + + await store.saveTaskState({ + taskId, + state, + }); + + await store.recoverTasks({ timeout: { milliseconds: 0 } }); + await store.claimTask(); + + const claimedTask = await store.getTask(taskId); + expect(claimedTask.state).toEqual({ state: state.state }); + }); + it('should shutdown the running task', async () => { const { store } = await createStore(); const { taskId } = await store.createTask({ @@ -188,4 +226,37 @@ describe('DatabaseTaskStore', () => { await store.shutdownTask({ taskId }); }).rejects.toThrow(ConflictError); }); + + it('should store checkpoints and retrieve task state', async () => { + const { store } = await createStore(); + const { taskId } = await store.createTask({ + spec: {} as TaskSpec, + createdBy: 'me', + }); + + await store.saveTaskState({ + taskId, + state: { + checkpoints: { + 'repo.create': { + status: 'success', + value: { repoUrl: 'https://github.com/backstage/backstage.git' }, + }, + }, + }, + }); + + const state = await store.getTaskState({ taskId }); + + expect(state).toStrictEqual({ + state: { + checkpoints: { + 'repo.create': { + status: 'success', + value: { repoUrl: 'https://github.com/backstage/backstage.git' }, + }, + }, + }, + }); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts index 766db4646e..ac391ea2b6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts @@ -52,6 +52,7 @@ export type RawDbTaskRow = { id: string; spec: string; status: TaskStatus; + state?: string; last_heartbeat_at?: string; created_at: string; created_by: string | null; @@ -211,6 +212,7 @@ export class DatabaseTaskStore implements TaskStore { try { const spec = JSON.parse(result.spec); const secrets = result.secrets ? JSON.parse(result.secrets) : undefined; + const state = result.state ? JSON.parse(result.state).state : undefined; return { id: result.id, spec, @@ -219,6 +221,7 @@ export class DatabaseTaskStore implements TaskStore { createdAt: parseSqlDateToIsoString(result.created_at), createdBy: result.created_by ?? undefined, secrets, + state, }; } catch (error) { throw new Error(`Failed to parse spec of task '${taskId}', ${error}`); @@ -267,6 +270,16 @@ export class DatabaseTaskStore implements TaskStore { return undefined; } + const getState = () => { + try { + return task.state ? JSON.parse(task.state).state : undefined; + } catch (error) { + throw new Error( + `Failed to parse state of the task '${task.id}', ${error}`, + ); + } + }; + const secrets = this.parseTaskSecrets(task); return { id: task.id, @@ -276,6 +289,7 @@ export class DatabaseTaskStore implements TaskStore { createdAt: task.created_at, createdBy: task.created_by ?? undefined, secrets, + state: getState(), }; }); } @@ -394,6 +408,32 @@ export class DatabaseTaskStore implements TaskStore { }); } + async getTaskState({ taskId }: { taskId: string }): Promise< + | { + state: JsonObject; + } + | undefined + > { + const [result] = await this.db('tasks') + .where({ id: taskId }) + .select('state'); + return result.state ? JSON.parse(result.state) : undefined; + } + + async saveTaskState(options: { + taskId: string; + state?: JsonObject; + }): Promise { + if (options.state) { + const serializedState = JSON.stringify({ state: options.state }); + await this.db('tasks') + .where({ id: options.taskId }) + .update({ + state: serializedState, + }); + } + } + async listEvents( options: TaskStoreListEventsOptions, ): Promise<{ events: SerializedTaskEvent[] }> { @@ -505,7 +545,7 @@ export class DatabaseTaskStore implements TaskStore { for (const { id, spec } of result) { const taskSpec = JSON.parse(spec as string) as TaskSpec; - await this.db('task_events').insert({ + await tx('task_events').insert({ task_id: id, event_type: 'recovered', body: JSON.stringify({ diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index cf29d43e19..2e19da669f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -18,6 +18,7 @@ import { getVoidLogger } from '@backstage/backend-common'; import { NunjucksWorkflowRunner } from './NunjucksWorkflowRunner'; import { TemplateActionRegistry } from '../actions'; import { ScmIntegrations } from '@backstage/integration'; +import { JsonObject } from '@backstage/types'; import { ConfigReader } from '@backstage/config'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { @@ -33,7 +34,10 @@ import { PermissionEvaluator, } from '@backstage/plugin-permission-common'; import { RESOURCE_TYPE_SCAFFOLDER_ACTION } from '@backstage/plugin-scaffolder-common/alpha'; -import { createMockDirectory } from '@backstage/backend-test-utils'; +import { + createMockDirectory, + mockCredentials, +} from '@backstage/backend-test-utils'; import stripAnsi from 'strip-ansi'; describe('NunjucksWorkflowRunner', () => { @@ -57,6 +61,13 @@ describe('NunjucksWorkflowRunner', () => { }), ); + const credentials = mockCredentials.user(); + + const token = mockCredentials.service.token({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + const createMockTaskWithSpec = ( spec: TaskSpec, secrets?: TaskSecrets, @@ -70,6 +81,7 @@ describe('NunjucksWorkflowRunner', () => { emitLog: fakeTaskLog, cancelSignal: new AbortController().signal, getWorkspaceName: () => Promise.resolve('test-workspace'), + getInitiatorCredentials: () => Promise.resolve(credentials), }); function expectTaskLog(message: string) { @@ -133,6 +145,26 @@ describe('NunjucksWorkflowRunner', () => { }, }); + actionRegistry.register({ + id: 'checkpoints-action', + description: 'Mock action with checkpoints', + handler: async ctx => { + const key1 = await ctx.checkpoint('key1', async () => { + return 'updated'; + }); + const key2 = await ctx.checkpoint('key2', async () => { + return 'updated'; + }); + const key3 = await ctx.checkpoint('key3', async () => { + return 'updated'; + }); + + ctx.output('key1', key1); + ctx.output('key2', key2); + ctx.output('key3', key3); + }, + }); + mockedPermissionApi.authorizeConditional.mockResolvedValue([ { result: AuthorizeResult.ALLOW }, ]); @@ -275,7 +307,6 @@ describe('NunjucksWorkflowRunner', () => { }); it('should pass token through', async () => { - const fakeToken = 'secret'; const task = createMockTaskWithSpec( { apiVersion: 'scaffolder.backstage.io/v1beta3', @@ -291,14 +322,15 @@ describe('NunjucksWorkflowRunner', () => { ], }, { - backstageToken: fakeToken, + backstageToken: token, + initiatorCredentials: JSON.stringify(credentials), }, ); await runner.execute(task); expect(fakeActionHandler.mock.calls[0][0].secrets).toEqual( - expect.objectContaining({ backstageToken: fakeToken }), + expect.objectContaining({ backstageToken: token }), ); }); }); @@ -538,6 +570,54 @@ describe('NunjucksWorkflowRunner', () => { ); }); + it('should deal with checkpoints', async () => { + const task = { + ...createMockTaskWithSpec({ + apiVersion: 'scaffolder.backstage.io/v1beta3', + parameters: {}, + steps: [ + { + id: 'test', + name: 'name', + action: 'checkpoints-action', + input: { foo: 1 }, + }, + ], + output: { + key1: '${{steps.test.output.key1}}', + key2: '${{steps.test.output.key2}}', + key3: '${{steps.test.output.key3}}', + }, + }), + getTaskState: (): Promise< + | { + state: JsonObject; + } + | undefined + > => { + return Promise.resolve({ + state: { + checkpoints: { + ['v1.task.checkpoint.key1']: { + status: 'success', + value: 'initial', + }, + ['v1.task.checkpoint.key2']: { + status: 'failed', + reason: 'fatal error', + }, + }, + }, + }); + }, + }; + const result = await runner.execute(task); + + expect(result.output.key1).toEqual('initial'); + expect(result.output.key2).toEqual('updated'); + expect(result.output.key3).toEqual('updated'); + }); + it('should template the output from simple actions', async () => { const task = createMockTaskWithSpec({ apiVersion: 'scaffolder.backstage.io/v1beta3', @@ -1103,7 +1183,7 @@ describe('NunjucksWorkflowRunner', () => { ], }, { - backstageToken: 'secret', + backstageToken: token, }, true, ); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index f86cf9019e..5d24ac7cc7 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -21,7 +21,7 @@ import fs from 'fs-extra'; import path from 'path'; import nunjucks from 'nunjucks'; import { JsonArray, JsonObject, JsonValue } from '@backstage/types'; -import { InputError, NotAllowedError } from '@backstage/errors'; +import { InputError, NotAllowedError, stringifyError } from '@backstage/errors'; import { PassThrough } from 'stream'; import { generateExampleOutput, isTruthy } from './helper'; import { validate as validateJsonSchema } from 'jsonschema'; @@ -48,12 +48,14 @@ import { createCounterMetric, createHistogramMetric } from '../../util/metrics'; import { createDefaultFilters } from '../../lib/templating/filters'; import { AuthorizeResult, - PermissionEvaluator, PolicyDecision, } from '@backstage/plugin-permission-common'; import { scaffolderActionRules } from '../../service/rules'; import { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha'; import { TaskRecovery } from '@backstage/plugin-scaffolder-common'; +import { PermissionsService } from '@backstage/backend-plugin-api'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { BackstageLoggerTransport, WinstonLogger } from './logger'; type NunjucksWorkflowRunnerOptions = { workingDirectory: string; @@ -62,7 +64,7 @@ type NunjucksWorkflowRunnerOptions = { logger: winston.Logger; additionalTemplateFilters?: Record; additionalTemplateGlobals?: Record; - permissions?: PermissionEvaluator; + permissions?: PermissionsService; }; type TemplateContext = { @@ -79,6 +81,16 @@ type TemplateContext = { each?: JsonValue; }; +type CheckpointState = + | { + status: 'failed'; + reason: string; + } + | { + status: 'success'; + value: JsonValue; + }; + const isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => { return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3'; }; @@ -86,30 +98,49 @@ const isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => { const createStepLogger = ({ task, step, + rootLogger, }: { task: TaskContext; step: TaskStep; + rootLogger: winston.Logger; }) => { - const metadata = { stepId: step.id }; - const taskLogger = winston.createLogger({ + const stepLogStream = new PassThrough(); + stepLogStream.on('data', async data => { + const message = data.toString().trim(); + if (message?.length > 1) { + await task.emitLog(message, { stepId: step.id }); + } + }); + + const taskLogger = WinstonLogger.create({ level: process.env.LOG_LEVEL || 'info', format: winston.format.combine( winston.format.colorize(), winston.format.simple(), ), - defaultMeta: {}, + transports: [ + new winston.transports.Stream({ stream: stepLogStream }), + new BackstageLoggerTransport(rootLogger), + ], }); + taskLogger.addRedactions(Object.values(task.secrets ?? {})); + + // This stream logger should be deprecated. We're going to replace it with + // just using the logger directly, as all those logs get written to step logs + // using the stepLogStream above. + // Initially this stream used to be the only way to write to the client logs, but that + // has changed over time, there's not really a need for this anymore. + // You can just create a simple wrapper like the below in your action to write to the main logger. + // This way we also get recactions for free. const streamLogger = new PassThrough(); streamLogger.on('data', async data => { const message = data.toString().trim(); if (message?.length > 1) { - await task.emitLog(message, metadata); + taskLogger.info(message); } }); - taskLogger.add(new winston.transports.Stream({ stream: streamLogger })); - return { taskLogger, streamLogger }; }; @@ -233,7 +264,11 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { const action: TemplateAction = this.options.actionRegistry.get(step.action); - const { taskLogger, streamLogger } = createStepLogger({ task, step }); + const { taskLogger, streamLogger } = createStepLogger({ + task, + step, + rootLogger: this.options.logger, + }); if (task.isDryRun) { const redactedSecrets = Object.fromEntries( @@ -330,6 +365,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { } const tmpDirs = new Array(); const stepOutput: { [outputName: string]: JsonValue } = {}; + const prevTaskState = await task.getTaskState?.(); for (const iteration of iterations) { if (iteration.each) { @@ -344,9 +380,47 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { await action.handler({ input: iteration.input, secrets: task.secrets ?? {}, - logger: taskLogger, + // TODO(blam): move to LoggerService and away from Winston + logger: loggerToWinstonLogger(taskLogger), logStream: streamLogger, workspacePath, + async checkpoint( + keySuffix: string, + fn: () => Promise, + ) { + const key = `v1.task.checkpoint.${keySuffix}`; + try { + let prevValue: U | undefined; + if (prevTaskState) { + const prevState = ( + prevTaskState.state?.checkpoints as { + [key: string]: CheckpointState; + } + )?.[key]; + if (prevState && prevState.status === 'success') { + prevValue = prevState.value as U; + } + } + + const value = prevValue ? prevValue : await fn(); + + if (!prevValue) { + task.updateCheckpoint?.({ + key, + status: 'success', + value, + }); + } + return value; + } catch (err) { + task.updateCheckpoint?.({ + key, + status: 'failed', + reason: stringifyError(err), + }); + throw err; + } + }, createTemporaryDirectory: async () => { const tmpDir = await fs.mkdtemp( `${workspacePath}_step-${step.id}-`, @@ -366,6 +440,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { user: task.spec.user, isDryRun: task.isDryRun, signal: task.cancelSignal, + getInitiatorCredentials: () => task.getInitiatorCredentials(), }); } @@ -424,7 +499,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { this.options.permissions && task.spec.steps.length ? await this.options.permissions.authorizeConditional( [{ permission: actionExecutePermission }], - { token: task.secrets?.backstageToken }, + { credentials: await task.getInitiatorCredentials() }, ) : [{ result: AuthorizeResult.ALLOW }]; diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts index 3d2fb28538..f4bae43dbf 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.test.ts @@ -242,4 +242,31 @@ describe('StorageTaskBroker', () => { const promise = broker.list({ createdBy: 'user:default/foo' }); await expect(promise).resolves.toEqual({ tasks: [task] }); }); + + it('should handle checkpoints in task state', async () => { + const broker = new StorageTaskBroker(storage, logger); + + await broker.dispatch({ + spec: { steps: [] } as unknown as TaskSpec, + createdBy: 'user:default/foo', + }); + + const taskA = await broker.claim(); + await taskA.updateCheckpoint?.({ + key: 'repo.create', + status: 'success', + value: 'https://github.com/backstage/backstage.git', + }); + + expect(await taskA.getTaskState?.()).toEqual({ + state: { + checkpoints: { + 'repo.create': { + status: 'success', + value: 'https://github.com/backstage/backstage.git', + }, + }, + }, + }); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts index 1e557512cb..e9a408d9d6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/StorageTaskBroker.ts @@ -16,6 +16,9 @@ import { Config } from '@backstage/config'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; +import { JsonObject, JsonValue, Observable } from '@backstage/types'; +import { Logger } from 'winston'; +import ObservableImpl from 'zen-observable'; import { TaskSecrets, SerializedTask, @@ -25,12 +28,26 @@ import { TaskCompletionState, TaskContext, } from '@backstage/plugin-scaffolder-node'; -import { JsonObject, Observable } from '@backstage/types'; -import { Logger } from 'winston'; -import ObservableImpl from 'zen-observable'; -import { TaskStore } from './types'; +import { InternalTaskSecrets, TaskStore } from './types'; import { readDuration } from './helper'; +import { + AuthService, + BackstageCredentials, +} from '@backstage/backend-plugin-api'; +type TaskState = { + checkpoints: { + [key: string]: + | { + status: 'failed'; + reason: string; + } + | { + status: 'success'; + value: JsonValue; + }; + }; +}; /** * TaskManager * @@ -46,8 +63,9 @@ export class TaskManager implements TaskContext { storage: TaskStore, abortSignal: AbortSignal, logger: Logger, + auth?: AuthService, ) { - const agent = new TaskManager(task, storage, abortSignal, logger); + const agent = new TaskManager(task, storage, abortSignal, logger, auth); agent.startTimeout(); return agent; } @@ -58,6 +76,7 @@ export class TaskManager implements TaskContext { private readonly storage: TaskStore, private readonly signal: AbortSignal, private readonly logger: Logger, + private readonly auth?: AuthService, ) {} get spec() { @@ -91,6 +110,40 @@ export class TaskManager implements TaskContext { }); } + async getTaskState?(): Promise< + | { + state?: JsonObject; + } + | undefined + > { + return this.storage.getTaskState?.({ taskId: this.task.taskId }); + } + + async updateCheckpoint?( + options: + | { + key: string; + status: 'success'; + value: JsonValue; + } + | { + key: string; + status: 'failed'; + reason: string; + }, + ): Promise { + const { key, ...value } = options; + if (this.task.state) { + (this.task.state as TaskState).checkpoints[key] = value; + } else { + this.task.state = { checkpoints: { [key]: value } }; + } + await this.storage.saveTaskState?.({ + taskId: this.task.taskId, + state: this.task.state, + }); + } + async complete( result: TaskCompletionState, metadata?: JsonObject, @@ -124,6 +177,20 @@ export class TaskManager implements TaskContext { } }, 1000); } + + async getInitiatorCredentials(): Promise { + const secrets = this.task.secrets as InternalTaskSecrets; + + if (secrets && secrets.__initiatorCredentials) { + return JSON.parse(secrets.__initiatorCredentials); + } + if (!this.auth) { + throw new Error( + 'Failed to create none credentials in scaffolder task. The TaskManager has not been initialized with an auth service implementation', + ); + } + return this.auth.getNoneCredentials(); + } } /** @@ -144,6 +211,10 @@ export interface CurrentClaimedTask { * The secrets that are stored with the task. */ secrets?: TaskSecrets; + /** + * The state of checkpoints of the task. + */ + state?: JsonObject; /** * The creator of the task. */ @@ -163,6 +234,7 @@ export class StorageTaskBroker implements TaskBroker { private readonly storage: TaskStore, private readonly logger: Logger, private readonly config?: Config, + private readonly auth?: AuthService, ) {} async list(options?: { @@ -244,10 +316,12 @@ export class StorageTaskBroker implements TaskBroker { spec: pendingTask.spec, secrets: pendingTask.secrets, createdBy: pendingTask.createdBy, + state: pendingTask.state, }, this.storage, abortController.signal, this.logger, + this.auth, ); } diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts new file mode 100644 index 0000000000..064eb69349 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/logger.ts @@ -0,0 +1,217 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + LoggerService, + RootLoggerService, +} from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { Format, TransformableInfo } from 'logform'; +import Transport, { TransportStreamOptions } from 'winston-transport'; +import { Logger, format, createLogger, transports } from 'winston'; + +/** + * Escapes a given string to be used inside a RegExp. + * + * Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions + */ +const escapeRegExp = (text: string) => { + return text.replace(/[.*+?^${}(\)|[\]\\]/g, '\\$&'); +}; + +interface WinstonLoggerOptions { + meta?: JsonObject; + level: string; + format: Format; + transports: Transport[]; +} + +// This is a workaround for being able to preserve the log format of the root logger. +// Will revisit all of this implementation once we can break the router to use only `LoggerService`. +export class BackstageLoggerTransport extends Transport { + constructor( + private readonly backstageLogger: LoggerService, + opts?: TransportStreamOptions, + ) { + super(opts); + } + + log(info: unknown, callback: VoidFunction) { + if (typeof info !== 'object' || info === null) { + callback(); + return; + } + const { level, message, ...meta } = info as JsonObject; + switch (level) { + case 'error': + this.backstageLogger.error(String(message), meta); + break; + case 'warn': + this.backstageLogger.warn(String(message), meta); + break; + case 'info': + this.backstageLogger.info(String(message), meta); + break; + case 'debug': + this.backstageLogger.debug(String(message), meta); + break; + default: + this.backstageLogger.info(String(message), meta); + } + callback(); + } +} + +export class WinstonLogger implements RootLoggerService { + #winston: Logger; + #addRedactions?: (redactions: Iterable) => void; + + /** + * Creates a {@link WinstonLogger} instance. + */ + static create(options: WinstonLoggerOptions): WinstonLogger { + const redacter = WinstonLogger.redacter(); + + let logger = createLogger({ + level: options.level, + format: format.combine(redacter.format, options.format), + transports: options.transports ?? new transports.Console(), + }); + if (options.meta) { + logger = logger.child(options.meta); + } + + return new WinstonLogger(logger, redacter.add); + } + + /** + * Creates a winston log formatter for redacting secrets. + */ + static redacter(): { + format: Format; + add: (redactions: Iterable) => void; + } { + const redactionSet = new Set(); + + let redactionPattern: RegExp | undefined = undefined; + + const replace = (obj: TransformableInfo) => { + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + if (typeof obj[key] === 'object') { + obj[key] = replace(obj[key] as TransformableInfo); + } else if (typeof obj[key] === 'string') { + obj[key] = obj[key]?.replace(redactionPattern, '[REDACTED]'); + } + } + } + return obj; + }; + return { + format: format(replace)(), + add(newRedactions) { + let added = 0; + for (const redactionToTrim of newRedactions) { + // Trimming the string ensures that we don't accdentally get extra + // newlines or other whitespace interfering with the redaction; this + // can happen for example when using string literals in yaml + const redaction = redactionToTrim.trim(); + // Exclude secrets that are empty or just one character in length. These + // typically mean that you are running local dev or tests, or using the + // --lax flag which sets things to just 'x'. + if (redaction.length <= 1) { + continue; + } + if (!redactionSet.has(redaction)) { + redactionSet.add(redaction); + added += 1; + } + } + if (added > 0) { + const redactions = Array.from(redactionSet) + .map(r => escapeRegExp(r)) + .join('|'); + redactionPattern = new RegExp(`(${redactions})`, 'g'); + } + }, + }; + } + + /** + * Creates a pretty printed winston log formatter. + */ + static colorFormat(): Format { + const colorizer = format.colorize(); + + return format.combine( + format.timestamp(), + format.colorize({ + colors: { + timestamp: 'dim', + prefix: 'blue', + field: 'cyan', + debug: 'grey', + }, + }), + format.printf((info: TransformableInfo) => { + const { timestamp, level, message, plugin, service, ...fields } = info; + const prefix = plugin || service; + const timestampColor = colorizer.colorize('timestamp', timestamp); + const prefixColor = colorizer.colorize('prefix', prefix); + + const extraFields = Object.entries(fields) + .map( + ([key, value]) => + `${colorizer.colorize('field', `${key}`)}=${value}`, + ) + .join(' '); + + return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`; + }), + ); + } + + private constructor( + winston: Logger, + addRedactions?: (redactions: Iterable) => void, + ) { + this.#winston = winston; + this.#addRedactions = addRedactions; + } + + error(message: string, meta?: JsonObject): void { + this.#winston.error(message, meta); + } + + warn(message: string, meta?: JsonObject): void { + this.#winston.warn(message, meta); + } + + info(message: string, meta?: JsonObject): void { + this.#winston.info(message, meta); + } + + debug(message: string, meta?: JsonObject): void { + this.#winston.debug(message, meta); + } + + child(meta: JsonObject): LoggerService { + return new WinstonLogger(this.#winston.child(meta)); + } + + addRedactions(redactions: Iterable) { + this.#addRedactions?.(redactions); + } +} diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts index c5783ccb49..aa647d8bd6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/types.ts @@ -194,6 +194,18 @@ export interface TaskStore { emitLogEvent(options: TaskStoreEmitOptions): Promise; + getTaskState?({ taskId }: { taskId: string }): Promise< + | { + state: JsonObject; + } + | undefined + >; + + saveTaskState?(options: { + taskId: string; + state?: JsonObject; + }): Promise; + listEvents( options: TaskStoreListEventsOptions, ): Promise<{ events: SerializedTaskEvent[] }>; @@ -216,3 +228,10 @@ export type TaskTrackType = { action: TemplateAction, ) => Promise; }; + +/** + * @internal + */ +export type InternalTaskSecrets = TaskSecrets & { + __initiatorCredentials: string; +}; diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index 8bfbd6b915..2118f46b22 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -41,14 +41,11 @@ import { import { createRouter, DatabaseTaskStore } from '../index'; import { TaskBroker } from '@backstage/plugin-scaffolder-node'; import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker'; -import { - IdentityApiGetIdentityRequest, - BackstageIdentityResponse, -} from '@backstage/plugin-auth-node'; import { AuthorizeResult, PermissionEvaluator, } from '@backstage/plugin-permission-common'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; const mockAccess = jest.fn(); @@ -83,8 +80,6 @@ const mockUrlReader = UrlReaders.default({ config: new ConfigReader({}), }); -const getIdentity = jest.fn(); - const config = new ConfigReader({}); describe('createRouter', () => { @@ -96,6 +91,15 @@ describe('createRouter', () => { authorize: jest.fn(), authorizeConditional: jest.fn(), } as unknown as PermissionEvaluator; + const auth = mockServices.auth(); + const httpAuth = mockServices.httpAuth(); + const discovery = mockServices.discovery(); + + const credentials = mockCredentials.user(); + const token = mockCredentials.service.token({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); const getMockTemplate = (): TemplateEntityV1beta3 => ({ apiVersion: 'scaffolder.backstage.io/v1beta3', @@ -199,6 +203,9 @@ describe('createRouter', () => { reader: mockUrlReader, taskBroker, permissions: permissionApi, + auth, + httpAuth, + discovery, }); app = express().use(router); @@ -287,8 +294,7 @@ describe('createRouter', () => { it('should call the broker with a correct spec', async () => { const broker = taskBroker.dispatch as jest.Mocked['dispatch']; - const mockToken = - 'blob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvZ3Vlc3QiLCJuYW1lIjoiSm9obiBEb2UifQ.blob'; + const mockToken = mockCredentials.user.token(); const mockTemplate = getMockTemplate(); await request(app) @@ -304,11 +310,13 @@ describe('createRouter', () => { requiredParameter2: 'required-value-2', }, }); + expect(broker).toHaveBeenCalledWith( expect.objectContaining({ - createdBy: 'user:default/guest', + createdBy: 'user:default/mock', secrets: { - backstageToken: mockToken, + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), }, spec: { @@ -325,7 +333,7 @@ describe('createRouter', () => { }, user: { entity: mockUser, - ref: 'user:default/guest', + ref: 'user:default/mock', }, templateInfo: { entityRef: stringifyEntityRef({ @@ -343,114 +351,8 @@ describe('createRouter', () => { ); }); - it('should not throw when an invalid authorization header is passed', async () => { - const broker = - taskBroker.dispatch as jest.Mocked['dispatch']; - const mockToken = 'blob.eyJzdWIiOiIiLCJuYW1lIjoiSm9obiBEb2UifQ.blob'; - const mockTemplate = getMockTemplate(); - - await request(app) - .post('/v2/tasks') - .set('Authorization', `Bearer ${mockToken}`) - .send({ - templateRef: stringifyEntityRef({ - kind: 'template', - name: 'create-react-app-template', - }), - values: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - }); - expect(broker).toHaveBeenCalledWith( - expect.objectContaining({ - createdBy: undefined, - secrets: { - backstageToken: undefined, - }, - - spec: { - apiVersion: mockTemplate.apiVersion, - steps: mockTemplate.spec.steps.map((step, index) => ({ - ...step, - id: step.id ?? `step-${index + 1}`, - name: step.name ?? step.action, - })), - output: mockTemplate.spec.output ?? {}, - parameters: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - user: { - entity: undefined, - ref: undefined, - }, - templateInfo: { - entityRef: stringifyEntityRef({ - kind: 'Template', - namespace: 'Default', - name: mockTemplate.metadata?.name, - }), - baseUrl: 'https://dev.azure.com', - entity: { - metadata: mockTemplate.metadata, - }, - }, - }, - }), - ); - }); - - it('should not decorate a user when no backstage auth is passed', async () => { - const broker = - taskBroker.dispatch as jest.Mocked['dispatch']; - - await request(app) - .post('/v2/tasks') - .send({ - templateRef: stringifyEntityRef({ - kind: 'template', - name: 'create-react-app-template', - }), - values: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - }); - - expect(broker).toHaveBeenCalledWith( - expect.objectContaining({ - createdBy: undefined, - spec: expect.objectContaining({ - user: { entity: undefined, ref: undefined }, - }), - }), - ); - }); - - it('should emit auditlog containing without user identifier when no backstage auth is passed', async () => { - await request(app) - .post('/v2/tasks') - .send({ - templateRef: stringifyEntityRef({ - kind: 'template', - name: 'create-react-app-template', - }), - values: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - }); - - expect(loggerSpy).toHaveBeenCalledTimes(1); - expect(loggerSpy).toHaveBeenCalledWith( - 'Scaffolding task for template:default/create-react-app-template', - ); - }); - it('should emit auditlog containing user identifier when backstage auth is passed', async () => { - const mockToken = - 'blob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvZ3Vlc3QiLCJuYW1lIjoiSm9obiBEb2UifQ.blob'; + const mockToken = mockCredentials.user.token(); await request(app) .post('/v2/tasks') @@ -468,7 +370,7 @@ describe('createRouter', () => { expect(loggerSpy).toHaveBeenCalledTimes(1); expect(loggerSpy).toHaveBeenCalledWith( - 'Scaffolding task for template:default/create-react-app-template created by user:default/guest', + 'Scaffolding task for template:default/create-react-app-template created by user:default/mock', ); }); }); @@ -551,7 +453,10 @@ describe('createRouter', () => { spec: {} as any, status: 'completed', createdAt: '', - secrets: { backstageToken: 'secret' }, + secrets: { + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), + }, createdBy: '', }); @@ -797,23 +702,6 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ jest.spyOn(taskBroker, 'event$'); loggerSpy = jest.spyOn(logger, 'info'); - getIdentity.mockImplementation( - async ({ - request: _request, - }: IdentityApiGetIdentityRequest): Promise< - BackstageIdentityResponse | undefined - > => { - return { - identity: { - userEntityRef: 'user:default/guest', - ownershipEntityRefs: [], - type: 'user', - }, - token: 'token', - }; - }, - ); - const router = await createRouter({ logger: logger, config: new ConfigReader({}), @@ -821,8 +709,10 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ catalogClient, reader: mockUrlReader, taskBroker, - identity: { getIdentity }, permissions: permissionApi, + auth, + httpAuth, + discovery, }); app = express().use(router); @@ -1032,9 +922,10 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }); expect(broker).toHaveBeenCalledWith( expect.objectContaining({ - createdBy: 'user:default/guest', + createdBy: 'user:default/mock', secrets: { - backstageToken: 'token', + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), }, spec: { @@ -1047,7 +938,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }, user: { entity: mockUser, - ref: 'user:default/guest', + ref: 'user:default/mock', }, templateInfo: { entityRef: stringifyEntityRef({ @@ -1101,9 +992,10 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }); expect(broker).toHaveBeenCalledWith( expect.objectContaining({ - createdBy: 'user:default/guest', + createdBy: 'user:default/mock', secrets: { - backstageToken: 'token', + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), }, spec: { @@ -1128,7 +1020,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }, user: { entity: mockUser, - ref: 'user:default/guest', + ref: 'user:default/mock', }, templateInfo: { entityRef: stringifyEntityRef({ @@ -1189,9 +1081,10 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }); expect(broker).toHaveBeenCalledWith( expect.objectContaining({ - createdBy: 'user:default/guest', + createdBy: 'user:default/mock', secrets: { - backstageToken: 'token', + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), }, spec: { @@ -1208,7 +1101,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }, user: { entity: mockUser, - ref: 'user:default/guest', + ref: 'user:default/mock', }, templateInfo: { entityRef: stringifyEntityRef({ @@ -1226,96 +1119,6 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ ); }); - describe('when the identity api throws an error', () => { - beforeEach(() => { - getIdentity.mockImplementation( - async ({ - request: _request, - }: IdentityApiGetIdentityRequest): Promise< - BackstageIdentityResponse | undefined - > => { - throw new Error('whoops!'); - }, - ); - }); - it('return an error', async () => { - const response = await request(app) - .post('/v2/tasks') - .send({ - templateRef: stringifyEntityRef({ - kind: 'template', - name: 'create-react-app-template', - }), - values: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - }); - expect(response.status).not.toEqual(201); - }); - }); - - describe('no auth is provided', () => { - beforeEach(() => { - getIdentity.mockImplementation( - async ({ - request: _request, - }: IdentityApiGetIdentityRequest): Promise< - BackstageIdentityResponse | undefined - > => { - return undefined; - }, - ); - }); - - it('should not decorate a user when no backstage auth is passed', async () => { - const broker = - taskBroker.dispatch as jest.Mocked['dispatch']; - - await request(app) - .post('/v2/tasks') - .send({ - templateRef: stringifyEntityRef({ - kind: 'template', - name: 'create-react-app-template', - }), - values: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - }); - - expect(broker).toHaveBeenCalledWith( - expect.objectContaining({ - createdBy: undefined, - spec: expect.objectContaining({ - user: { entity: undefined, ref: undefined }, - }), - }), - ); - }); - - it('should emit auditlog containing without user identifier when no backstage auth is passed', async () => { - await request(app) - .post('/v2/tasks') - .send({ - templateRef: stringifyEntityRef({ - kind: 'template', - name: 'create-react-app-template', - }), - values: { - requiredParameter1: 'required-value-1', - requiredParameter2: 'required-value-2', - }, - }); - - expect(loggerSpy).toHaveBeenCalledTimes(1); - expect(loggerSpy).toHaveBeenCalledWith( - 'Scaffolding task for template:default/create-react-app-template', - ); - }); - }); - it('should emit auditlog containing user identifier when backstage auth is passed', async () => { await request(app) .post('/v2/tasks') @@ -1332,7 +1135,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ expect(loggerSpy).toHaveBeenCalledTimes(1); expect(loggerSpy).toHaveBeenCalledWith( - 'Scaffolding task for template:default/create-react-app-template created by user:default/guest', + 'Scaffolding task for template:default/create-react-app-template created by user:default/mock', ); }); }); @@ -1415,7 +1218,10 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ spec: {} as any, status: 'completed', createdAt: '', - secrets: { backstageToken: 'secret' }, + secrets: { + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), + }, createdBy: '', }); diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index c0322af283..43618ed5a7 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common'; +import { + HostDiscovery, + PluginDatabaseManager, + UrlReader, + createLegacyAuthAdapters, +} from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { CatalogApi } from '@backstage/catalog-client'; import { @@ -62,15 +67,8 @@ import { import { createDryRunner } from '../scaffolder/dryrun'; import { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker'; import { findTemplate, getEntityBaseUrl, getWorkingDirectory } from './helpers'; -import { - IdentityApi, - IdentityApiGetIdentityRequest, -} from '@backstage/plugin-auth-node'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; -import { - PermissionEvaluator, - PermissionRuleParams, -} from '@backstage/plugin-permission-common'; +import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { createConditionAuthorizer, createPermissionIntegrationRouter, @@ -78,7 +76,19 @@ import { } from '@backstage/plugin-permission-node'; import { scaffolderActionRules, scaffolderTemplateRules } from './rules'; import { Duration } from 'luxon'; -import { LifecycleService } from '@backstage/backend-plugin-api'; +import { + AuthService, + BackstageCredentials, + DiscoveryService, + HttpAuthService, + LifecycleService, + PermissionsService, +} from '@backstage/backend-plugin-api'; +import { + IdentityApi, + IdentityApiGetIdentityRequest, +} from '@backstage/plugin-auth-node'; +import { InternalTaskSecrets } from '../scaffolder/tasks/types'; /** * @@ -143,11 +153,14 @@ export interface RouterOptions { taskBroker?: TaskBroker; additionalTemplateFilters?: Record; additionalTemplateGlobals?: Record; - permissions?: PermissionEvaluator; + permissions?: PermissionsService; permissionRules?: Array< TemplatePermissionRuleInput | ActionPermissionRuleInput >; + auth?: AuthService; + httpAuth?: HttpAuthService; identity?: IdentityApi; + discovery?: DiscoveryService; } function isSupportedTemplate(entity: TemplateEntityV1beta3) { @@ -253,22 +266,29 @@ export async function createRouter( additionalTemplateGlobals, permissions, permissionRules, + discovery = HostDiscovery.fromConfig(config), + identity = buildDefaultIdentityClient(options), } = options; + + const { auth, httpAuth } = createLegacyAuthAdapters({ + ...options, + identity, + discovery, + }); + const concurrentTasksLimit = options.concurrentTasksLimit ?? options.config.getOptionalNumber('scaffolder.concurrentTasksLimit'); const logger = parentLogger.child({ plugin: 'scaffolder' }); - const identity: IdentityApi = - options.identity || buildDefaultIdentityClient(options); const workingDirectory = await getWorkingDirectory(config, logger); const integrations = ScmIntegrations.fromConfig(config); let taskBroker: TaskBroker; if (!options.taskBroker) { const databaseTaskStore = await DatabaseTaskStore.create({ database }); - taskBroker = new StorageTaskBroker(databaseTaskStore, logger, config); + taskBroker = new StorageTaskBroker(databaseTaskStore, logger, config, auth); if (scheduler && databaseTaskStore.listStaleTasks) { await scheduler.scheduleTask({ @@ -330,6 +350,7 @@ export async function createRouter( config, additionalTemplateFilters, additionalTemplateGlobals, + auth, }); actionsToRegister.forEach(action => actionRegistry.register(action)); @@ -394,12 +415,18 @@ export async function createRouter( .get( '/v2/templates/:namespace/:kind/:name/parameter-schema', async (req, res) => { - const userIdentity = await identity.getIdentity({ - request: req, - }); - const token = userIdentity?.token; + const credentials = await httpAuth.credentials(req); - const template = await authorizeTemplate(req.params, token); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); + + const template = await authorizeTemplate( + req.params, + token, + credentials, + ); const parameters = [template.spec.parameters ?? []].flat(); @@ -435,11 +462,15 @@ export async function createRouter( defaultKind: 'template', }); - const callerIdentity = await identity.getIdentity({ - request: req, + const credentials = await httpAuth.credentials(req); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', }); - const token = callerIdentity?.token; - const userEntityRef = callerIdentity?.identity.userEntityRef; + + const userEntityRef = auth.isPrincipal(credentials, 'user') + ? credentials.principal.userEntityRef + : undefined; const userEntity = userEntityRef ? await catalogClient.getEntityByRef(userEntityRef, { token }) @@ -456,6 +487,7 @@ export async function createRouter( const template = await authorizeTemplate( { kind, namespace, name }, token, + credentials, ); for (const parameters of [template.spec.parameters ?? []].flat()) { @@ -492,13 +524,16 @@ export async function createRouter( }, }; + const secrets: InternalTaskSecrets = { + ...req.body.secrets, + backstageToken: token, + __initiatorCredentials: JSON.stringify(credentials), + }; + const result = await taskBroker.dispatch({ spec: taskSpec, createdBy: userEntityRef, - secrets: { - ...req.body.secrets, - backstageToken: token, - }, + secrets, }); res.status(201).json({ id: result.taskId }); @@ -636,11 +671,12 @@ export async function createRouter( throw new InputError('Input template is not a template'); } - const token = ( - await identity.getIdentity({ - request: req, - }) - )?.token; + const credentials = await httpAuth.credentials(req); + + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); for (const parameters of [template.spec.parameters ?? []].flat()) { const result = validate(body.values, parameters); @@ -671,6 +707,7 @@ export async function createRouter( ...body.secrets, ...(token && { backstageToken: token }), }, + credentials, }); res.status(200).json({ @@ -691,6 +728,7 @@ export async function createRouter( async function authorizeTemplate( entityRef: CompoundEntityRef, token: string | undefined, + credentials: BackstageCredentials, ) { const template = await findTemplate({ catalogApi: catalogClient, @@ -716,7 +754,7 @@ export async function createRouter( { permission: templateParameterReadPermission }, { permission: templateStepReadPermission }, ], - { token }, + { credentials }, ); // Authorize parameters diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index 1bd8a1f192..4b6da80009 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/plugin-scaffolder-common +## 1.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + +## 1.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + +## 1.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## 1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/types@1.1.1 + +## 1.5.0 + +### Minor Changes + +- 11b9a08: Introduced the first version of recoverable tasks. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + ## 1.5.0-next.1 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index df6f15f2ac..d11e576d52 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,18 +1,34 @@ { "name": "@backstage/plugin-scaffolder-common", + "version": "1.5.2-next.0", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", - "version": "1.5.0-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "scaffolder" + ], + "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-common" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,32 +39,16 @@ ] } }, - "backstage": { - "role": "common-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/scaffolder-common" - }, - "keywords": [ - "scaffolder" - ], "files": [ "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", diff --git a/plugins/analytics-module-ga4/.eslintrc.js b/plugins/scaffolder-node-test-utils/.eslintrc.js similarity index 100% rename from plugins/analytics-module-ga4/.eslintrc.js rename to plugins/scaffolder-node-test-utils/.eslintrc.js diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md new file mode 100644 index 0000000000..3fe4c45621 --- /dev/null +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -0,0 +1,123 @@ +# @backstage/plugin-scaffolder-node-test-utils + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-test-utils@0.3.8-next.0 + - @backstage/plugin-scaffolder-node@0.4.4-next.0 + - @backstage/types@1.1.1 + +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-test-utils@0.3.7 + - @backstage/plugin-scaffolder-node@0.4.3 + - @backstage/types@1.1.1 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-test-utils@0.3.7-next.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.1 + - @backstage/types@1.1.1 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-test-utils@0.3.7-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.3-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-test-utils@0.3.6 + - @backstage/plugin-scaffolder-node@0.4.2 + - @backstage/types@1.1.1 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/backend-test-utils@0.3.5 + - @backstage/plugin-scaffolder-node@0.4.1 + - @backstage/types@1.1.1 + +## 0.1.0 + +### Minor Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- aa543c9: Add an initiator credentials getter to the default mock context. +- 563dfd0: Fix issue with package bundling, should be `dist/index.cjs.js` instead of `dist/index.esm.js`. +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/backend-test-utils@0.3.4 + - @backstage/plugin-scaffolder-node@0.4.0 + - @backstage/backend-common@0.21.4 + - @backstage/types@1.1.1 + +## 0.1.0-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 563dfd0: Fix issue with package bundling, should be `dist/index.cjs.js` instead of `dist/index.esm.js`. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-test-utils@0.3.4-next.2 + - @backstage/types@1.1.1 + +## 0.1.0-next.1 + +### Patch Changes + +- aa543c9: Add an initiator credentials getter to the default mock context. +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.4.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-test-utils@0.3.4-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 0.1.0-next.0 + +### Minor Changes + +- f44589d: Introduced `createMockActionContext` to unify the way of creating scaffolder mock context. + + It will help to maintain tests in a long run during structural changes of action context. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-test-utils@0.3.3-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-scaffolder-node@0.3.3-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 diff --git a/plugins/scaffolder-node-test-utils/README.md b/plugins/scaffolder-node-test-utils/README.md new file mode 100644 index 0000000000..851ddf808d --- /dev/null +++ b/plugins/scaffolder-node-test-utils/README.md @@ -0,0 +1,12 @@ +# @backstage/plugin-scaffolder-node-test-utils + +Contains utilities that can be used when testing scaffolder features. + +## Installation + +Install the package via Yarn into your own packages: + +```sh +cd # if within a monorepo +yarn add --dev @backstage/plugin-scaffolder-node-test-utils +``` diff --git a/plugins/scaffolder-node-test-utils/api-report.md b/plugins/scaffolder-node-test-utils/api-report.md new file mode 100644 index 0000000000..d6cda70b48 --- /dev/null +++ b/plugins/scaffolder-node-test-utils/api-report.md @@ -0,0 +1,18 @@ +## API Report File for "@backstage/plugin-scaffolder-node-test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ActionContext } from '@backstage/plugin-scaffolder-node'; +import { JsonObject } from '@backstage/types'; + +// @public +export const createMockActionContext: < + TActionInput extends JsonObject = JsonObject, + TActionOutput extends JsonObject = JsonObject, +>( + options?: Partial> | undefined, +) => ActionContext; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scaffolder-node-test-utils/catalog-info.yaml b/plugins/scaffolder-node-test-utils/catalog-info.yaml new file mode 100644 index 0000000000..980bd07e34 --- /dev/null +++ b/plugins/scaffolder-node-test-utils/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-scaffolder-node-test-utils + title: '@backstage/plugin-scaffolder-node-test-utils' +spec: + lifecycle: experimental + type: backstage-node-library + owner: maintainers diff --git a/plugins/sonarqube-react/knip-report.md b/plugins/scaffolder-node-test-utils/knip-report.md similarity index 100% rename from plugins/sonarqube-react/knip-report.md rename to plugins/scaffolder-node-test-utils/knip-report.md diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json new file mode 100644 index 0000000000..427bb5664a --- /dev/null +++ b/plugins/scaffolder-node-test-utils/package.json @@ -0,0 +1,43 @@ +{ + "name": "@backstage/plugin-scaffolder-node-test-utils", + "version": "0.1.4-next.0", + "backstage": { + "role": "node-library" + }, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-node-test-utils" + }, + "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-test-utils": "workspace:^", + "@backstage/plugin-scaffolder-node": "workspace:^", + "@backstage/types": "workspace:^" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/react": "*" + } +} diff --git a/plugins/scaffolder-node-test-utils/src/actions/index.ts b/plugins/scaffolder-node-test-utils/src/actions/index.ts new file mode 100644 index 0000000000..161bae8521 --- /dev/null +++ b/plugins/scaffolder-node-test-utils/src/actions/index.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 { createMockActionContext } from './mockActionConext'; diff --git a/plugins/scaffolder-node-test-utils/src/actions/mockActionConext.ts b/plugins/scaffolder-node-test-utils/src/actions/mockActionConext.ts new file mode 100644 index 0000000000..15ad5eb769 --- /dev/null +++ b/plugins/scaffolder-node-test-utils/src/actions/mockActionConext.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PassThrough } from 'stream'; +import { getVoidLogger } from '@backstage/backend-common'; +import { + createMockDirectory, + mockCredentials, +} from '@backstage/backend-test-utils'; +import { JsonObject } from '@backstage/types'; +import { ActionContext } from '@backstage/plugin-scaffolder-node'; + +/** + * A utility method to create a mock action context for scaffolder actions. + * + * @public + * @param options - optional parameters to override default mock context + */ +export const createMockActionContext = < + TActionInput extends JsonObject = JsonObject, + TActionOutput extends JsonObject = JsonObject, +>( + options?: Partial>, +): ActionContext => { + const credentials = mockCredentials.user(); + const defaultContext = { + logger: getVoidLogger(), + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory: jest.fn(), + input: {} as TActionInput, + checkpoint: jest.fn(), + getInitiatorCredentials: () => Promise.resolve(credentials), + }; + + const createDefaultWorkspace = () => ({ + workspacePath: createMockDirectory().resolve('workspace'), + }); + + if (!options) { + return { + ...defaultContext, + ...createDefaultWorkspace(), + }; + } + + const { input, logger, logStream, secrets, templateInfo, workspacePath } = + options; + + return { + ...defaultContext, + ...(workspacePath ? { workspacePath } : createDefaultWorkspace()), + ...(workspacePath && { + createTemporaryDirectory: jest.fn().mockResolvedValue(workspacePath), + }), + ...(logger && { logger }), + ...(logStream && { logStream }), + ...(input && { input }), + ...(secrets && { secrets }), + templateInfo, + }; +}; diff --git a/plugins/scaffolder-node-test-utils/src/index.ts b/plugins/scaffolder-node-test-utils/src/index.ts new file mode 100644 index 0000000000..19eae8d569 --- /dev/null +++ b/plugins/scaffolder-node-test-utils/src/index.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 * from './actions'; diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index 98ab2b4b8d..84cb98bf19 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,178 @@ # @backstage/plugin-scaffolder-node +## 0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/types@1.1.1 + +## 0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 0.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 0.4.0 + +### Minor Changes + +- 02ee466: **DEPRECATION** - Deprecated the `logStream` in the `ActionContext`. Please move to using `ctx.logger.x` instead. +- aa543c9: Update task context type to contain the new auth initiator credentials. + +### Patch Changes + +- 85f4723: Fixed file corruption for non UTF-8 data in fetch contents +- 984abfa: Fixing the lost of the initial state after a task recovery. +- c6b132e: Introducing checkpoints for scaffolder task action idempotency +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 0.4.0-next.2 + +### Minor Changes + +- 02ee466: **DEPRECATION** - Deprecated the `logStream` in the `ActionContext`. Please move to using `ctx.logger.x` instead. + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 0.4.0-next.1 + +### Minor Changes + +- aa543c9: Update task context type to contain the new auth initiator credentials. + +### Patch Changes + +- bbd1fe1: Made "checkpoint" on scaffolder action context non-optional +- Updated dependencies + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 0.3.3-next.0 + +### Patch Changes + +- 85f4723: Fixed file corruption for non UTF-8 data in fetch contents +- c6b132e: Introducing checkpoints for scaffolder task action idempotency +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## 0.3.0 + +### Minor Changes + +- 3a9ba42: Added functions to clone a repo, create a branch, add files and push and commit to the branch. This allows for files to be added to the a PR for use in the bitbucket pull request action for issue #21762 +- 11b9a08: Introduced the first version of recoverable tasks. +- 78c100b: Support providing an overriding token for `fetch:template`, `fetch:plain` and `fetch:file` when interacting with upstream integrations + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 9b0bf20: Add gitea as new type to be used from integrations configuration +- e0e5afe: Add option to configure nunjucks with the `trimBlocks` and `lstripBlocks` options in the fetch:template action +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.3.0-next.3 ### Patch Changes diff --git a/plugins/scaffolder-node/api-report.md b/plugins/scaffolder-node/api-report.md index fec2205462..c757301249 100644 --- a/plugins/scaffolder-node/api-report.md +++ b/plugins/scaffolder-node/api-report.md @@ -5,6 +5,7 @@ ```ts /// +import { BackstageCredentials } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; import { JsonValue } from '@backstage/types'; import { Logger } from 'winston'; @@ -30,11 +31,16 @@ export type ActionContext< secrets?: TaskSecrets; workspacePath: string; input: TActionInput; + checkpoint( + key: string, + fn: () => Promise, + ): Promise; output( name: keyof TActionOutput, value: TActionOutput[keyof TActionOutput], ): void; createTemporaryDirectory(): Promise; + getInitiatorCredentials(): Promise; templateInfo?: TemplateInfo; isDryRun?: boolean; user?: { @@ -280,6 +286,7 @@ export type SerializedTask = { lastHeartbeatAt?: string; createdBy?: string; secrets?: TaskSecrets; + state?: JsonObject; }; // @public @@ -345,6 +352,15 @@ export interface TaskContext { // (undocumented) emitLog(message: string, logMetadata?: JsonObject): Promise; // (undocumented) + getInitiatorCredentials(): Promise; + // (undocumented) + getTaskState?(): Promise< + | { + state?: JsonObject; + } + | undefined + >; + // (undocumented) getWorkspaceName(): Promise; // (undocumented) isDryRun?: boolean; @@ -352,6 +368,20 @@ export interface TaskContext { secrets?: TaskSecrets; // (undocumented) spec: TaskSpec; + // (undocumented) + updateCheckpoint?( + options: + | { + key: string; + status: 'success'; + value: JsonValue; + } + | { + key: string; + status: 'failed'; + reason: string; + }, + ): Promise; } // @public diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 884837a6be..d7d6105689 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-scaffolder-node", + "version": "0.4.4-next.0", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", - "version": "0.3.0-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-node" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,17 @@ ] } }, - "backstage": { - "role": "node-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/scaffolder-node" - }, + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -61,9 +64,5 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^" - }, - "files": [ - "alpha", - "dist" - ] + } } diff --git a/plugins/scaffolder-node/src/actions/fetch.test.ts b/plugins/scaffolder-node/src/actions/fetch.test.ts index 42f75d02b4..ea7f458fde 100644 --- a/plugins/scaffolder-node/src/actions/fetch.test.ts +++ b/plugins/scaffolder-node/src/actions/fetch.test.ts @@ -210,7 +210,26 @@ describe('fetchContents helper', () => { fetchUrl: 'https://github.com/backstage/foo', }); expect(fs.ensureDir).toHaveBeenCalledWith('.'); - expect(fs.outputFile).toHaveBeenCalledWith('foo', 'test'); + expect(fs.outputFile).toHaveBeenCalledWith( + 'foo', + Buffer.from([116, 101, 115, 116]), + ); + }); + + it('should fetch binary content from url', async () => { + readUrl.mockResolvedValue({ + buffer: () => Buffer.from([0, 1, 2, 3, 255, 254, 253, 252]), + }); + await fetchFile({ + ...options, + outputPath: 'foo', + fetchUrl: 'https://github.com/backstage/foo', + }); + expect(fs.ensureDir).toHaveBeenCalledWith('.'); + expect(fs.outputFile).toHaveBeenCalledWith( + 'foo', + Buffer.from([0, 1, 2, 3, 255, 254, 253, 252]), + ); }); it('should fetch content from url into directory', async () => { @@ -223,7 +242,10 @@ describe('fetchContents helper', () => { fetchUrl: 'https://github.com/backstage/foo', }); expect(fs.ensureDir).toHaveBeenCalledWith('mydir'); - expect(fs.outputFile).toHaveBeenCalledWith('mydir/foo', 'test'); + expect(fs.outputFile).toHaveBeenCalledWith( + 'mydir/foo', + Buffer.from([116, 101, 115, 116]), + ); }); it('should pass through the token provided through to the URL reader', async () => { diff --git a/plugins/scaffolder-node/src/actions/fetch.ts b/plugins/scaffolder-node/src/actions/fetch.ts index 2ddc2b1ae6..6b3e08bc7e 100644 --- a/plugins/scaffolder-node/src/actions/fetch.ts +++ b/plugins/scaffolder-node/src/actions/fetch.ts @@ -95,7 +95,7 @@ export async function fetchFile(options: { const res = await reader.readUrl(readUrl, { token }); await fs.ensureDir(path.dirname(outputPath)); const buffer = await res.buffer(); - await fs.outputFile(outputPath, buffer.toString()); + await fs.outputFile(outputPath, buffer); } } diff --git a/plugins/scaffolder-node/src/actions/types.ts b/plugins/scaffolder-node/src/actions/types.ts index 7e8c2b4f5f..f0e4c12869 100644 --- a/plugins/scaffolder-node/src/actions/types.ts +++ b/plugins/scaffolder-node/src/actions/types.ts @@ -16,11 +16,12 @@ import { Logger } from 'winston'; import { Writable } from 'stream'; -import { JsonObject } from '@backstage/types'; +import { JsonObject, JsonValue } from '@backstage/types'; import { TaskSecrets } from '../tasks'; import { TemplateInfo } from '@backstage/plugin-scaffolder-common'; import { UserEntity } from '@backstage/catalog-model'; import { Schema } from 'jsonschema'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; /** * ActionContext is passed into scaffolder actions. @@ -30,11 +31,17 @@ export type ActionContext< TActionInput extends JsonObject, TActionOutput extends JsonObject = JsonObject, > = { + // TODO(blam): move this to LoggerService logger: Logger; + /** @deprecated - use `ctx.logger` instead */ logStream: Writable; secrets?: TaskSecrets; workspacePath: string; input: TActionInput; + checkpoint( + key: string, + fn: () => Promise, + ): Promise; output( name: keyof TActionOutput, value: TActionOutput[keyof TActionOutput], @@ -45,6 +52,11 @@ export type ActionContext< */ createTemporaryDirectory(): Promise; + /** + * Get the credentials for the current request + */ + getInitiatorCredentials(): Promise; + templateInfo?: TemplateInfo; /** diff --git a/plugins/scaffolder-node/src/actions/util.ts b/plugins/scaffolder-node/src/actions/util.ts index 327cfa9c2f..7f7121ef16 100644 --- a/plugins/scaffolder-node/src/actions/util.ts +++ b/plugins/scaffolder-node/src/actions/util.ts @@ -92,6 +92,10 @@ export const parseRepoUrl = ( } break; } + case 'gitea': { + checkRequiredParams(parsed, 'repo'); + break; + } case 'gerrit': { checkRequiredParams(parsed, 'repo'); break; diff --git a/plugins/scaffolder-node/src/tasks/types.ts b/plugins/scaffolder-node/src/tasks/types.ts index 7cdc044bdf..aef2c5f360 100644 --- a/plugins/scaffolder-node/src/tasks/types.ts +++ b/plugins/scaffolder-node/src/tasks/types.ts @@ -14,8 +14,9 @@ * limitations under the License. */ +import { BackstageCredentials } from '@backstage/backend-plugin-api'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; -import { JsonObject, Observable } from '@backstage/types'; +import { JsonObject, JsonValue, Observable } from '@backstage/types'; /** * TaskSecrets @@ -58,6 +59,7 @@ export type SerializedTask = { lastHeartbeatAt?: string; createdBy?: string; secrets?: TaskSecrets; + state?: JsonObject; }; /** @@ -118,7 +120,30 @@ export interface TaskContext { emitLog(message: string, logMetadata?: JsonObject): Promise; + getTaskState?(): Promise< + | { + state?: JsonObject; + } + | undefined + >; + + updateCheckpoint?( + options: + | { + key: string; + status: 'success'; + value: JsonValue; + } + | { + key: string; + status: 'failed'; + reason: string; + }, + ): Promise; + getWorkspaceName(): Promise; + + getInitiatorCredentials(): Promise; } /** diff --git a/plugins/scaffolder-react/.eslintrc.js b/plugins/scaffolder-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/scaffolder-react/.eslintrc.js +++ b/plugins/scaffolder-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 8077a008a4..2236048243 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,223 @@ # @backstage/plugin-scaffolder-react +## 1.8.5-next.0 + +### Patch Changes + +- 0040ec2: Updated dependency `@rjsf/utils` to `5.18.2`. + Updated dependency `@rjsf/core` to `5.18.2`. + Updated dependency `@rjsf/material-ui` to `5.18.2`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.2`. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-scaffolder-common@1.5.2-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.8.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 87d2eb8: Updated dependency `json-schema-library` to `^9.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- 0e692cf: Added ESLint rule `no-top-level-material-ui-4-imports` to migrate the Material UI imports. +- df99f62: The `value` sent on the `create` analytics event (fired when a Scaffolder template is executed) is now set to the number of minutes saved by executing the template. This value is derived from the `backstage.io/time-saved` annotation on the template entity, if available. + + Note: the `create` event is now captured in the `` component. If you are directly making use of the alpha-exported `` component, an analytics `create` event will no longer be captured on your behalf. + +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/version-bridge@1.0.8 + - @backstage/catalog-client@1.6.4 + - @backstage/catalog-model@1.4.5 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.8.4-next.1 + +### Patch Changes + +- 87d2eb8: Updated dependency `json-schema-library` to `^9.0.0`. +- df99f62: The `value` sent on the `create` analytics event (fired when a Scaffolder template is executed) is now set to the number of minutes saved by executing the template. This value is derived from the `backstage.io/time-saved` annotation on the template entity, if available. + + Note: the `create` event is now captured in the `` component. If you are directly making use of the alpha-exported `` component, an analytics `create` event will no longer be captured on your behalf. + +- Updated dependencies + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.8.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.8.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.8.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/catalog-client@1.6.2 + - @backstage/core-components@0.14.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.8.1 + +### Patch Changes + +- 930b5c1: Added 'root' and 'label' class key to TemplateCategoryPicker +- 6d649d2: Updated dependency `flatted` to `3.3.1`. +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1 + +## 1.8.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 1.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1-next.1 + +## 1.8.1-next.0 + +### Patch Changes + +- 930b5c1: Added 'root' and 'label' class key to TemplateCategoryPicker +- 6d649d2: Updated dependency `flatted` to `3.3.1`. +- 0cecb09: Updated dependency `@rjsf/utils` to `5.17.1`. + Updated dependency `@rjsf/core` to `5.17.1`. + Updated dependency `@rjsf/material-ui` to `5.17.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.1`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-scaffolder-common@1.5.1-next.0 + +## 1.8.0 + +### Minor Changes + +- c56f1a2: Remove the old legacy exports from `/alpha` +- 11b9a08: Introduced the first version of recoverable tasks. +- b07ec70: Use more distinguishable icons for link (`Link`) and text output (`Description`). + +### Patch Changes + +- 3f60ad5: fix for: converting circular structure to JSON error +- 0b0c6b6: Allow defining default output text to be shown +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 31f0a0a: Added `ScaffolderPageContextMenu` to `ActionsPage`, `ListTaskPage`, and `TemplateEditorPage` so that you can more easily navigate between these pages +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- e6f0831: Updated dependency `@rjsf/utils` to `5.17.0`. + Updated dependency `@rjsf/core` to `5.17.0`. + Updated dependency `@rjsf/material-ui` to `5.17.0`. + Updated dependency `@rjsf/validator-ajv8` to `5.17.0`. +- 6a74ffd: Updated dependency `@rjsf/utils` to `5.16.1`. + Updated dependency `@rjsf/core` to `5.16.1`. + Updated dependency `@rjsf/material-ui` to `5.16.1`. + Updated dependency `@rjsf/validator-ajv8` to `5.16.1`. +- 3dff4b0: Remove unused deps +- 82affc7: Fix issue where `ui:schema` was replaced with an empty object if `dependencies` is defined +- 2985186: Fix bug that erroneously caused a separator or a 0 to render in the TemplateCard for Templates with empty links +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-scaffolder-common@1.5.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 1.8.0-next.3 ### Patch Changes diff --git a/plugins/scaffolder-react/api-report-alpha.md b/plugins/scaffolder-react/api-report-alpha.md index a521fecc70..683b8cf8be 100644 --- a/plugins/scaffolder-react/api-report-alpha.md +++ b/plugins/scaffolder-react/api-report-alpha.md @@ -16,6 +16,7 @@ import { IconComponent } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { JsonValue } from '@backstage/types'; import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { Overrides } from '@material-ui/core/styles/overrides'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactElement } from 'react'; @@ -25,6 +26,7 @@ import { ScaffolderRJSFFormProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderStep } from '@backstage/plugin-scaffolder-react'; import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; import { SetStateAction } from 'react'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; import { TaskStep } from '@backstage/plugin-scaffolder-common'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react'; @@ -32,6 +34,13 @@ import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common'; import { UiSchema } from '@rjsf/utils'; +// @alpha (undocumented) +export type BackstageOverrides = Overrides & { + [Name in keyof ScaffolderReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + // @alpha (undocumented) export const createAsyncValidators: ( rootSchema: JsonObject, @@ -132,6 +141,14 @@ export type ScaffolderPageContextMenuProps = { onCreateClicked?: () => void; }; +// @alpha (undocumented) +export type ScaffolderReactComponentsNameToClassKey = { + ScaffolderReactTemplateCategoryPicker: ScaffolderReactTemplateCategoryPickerClassKey; +}; + +// @alpha (undocumented) +export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label'; + // @alpha export const Stepper: (stepperProps: StepperProps) => React_2.JSX.Element; diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index 400cf24c53..311f4116b3 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -455,7 +455,9 @@ export interface ScaffolderUseTemplateSecrets { // @public export const SecretsContextProvider: ( - props: PropsWithChildren<{}>, + props: PropsWithChildren<{ + initialSecrets?: Record; + }>, ) => React_2.JSX.Element; // @public diff --git a/plugins/scaffolder-react/knip-report.md b/plugins/scaffolder-react/knip-report.md index 3d42235f5e..3c2e8f3c3c 100644 --- a/plugins/scaffolder-react/knip-report.md +++ b/plugins/scaffolder-react/knip-report.md @@ -1,12 +1,11 @@ # Knip report -## Unused dependencies (4) +## Unused dependencies (3) | Name | Location | Severity | | :------------------------ | :----------- | :------- | | @backstage/catalog-client | package.json | error | | zod-to-json-schema | package.json | error | -| immer | package.json | error | | zod | package.json | error | ## Unused devDependencies (2) diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 0263efd4f4..352478d99d 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-scaffolder-react", + "version": "1.8.5-next.0", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", - "version": "1.8.0-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/scaffolder-react" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,17 @@ ] } }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/scaffolder-react" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-client": "workspace:^", @@ -59,18 +62,17 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^24.0.0", - "@rjsf/core": "5.17.0", - "@rjsf/material-ui": "5.17.0", - "@rjsf/utils": "5.17.0", - "@rjsf/validator-ajv8": "5.17.0", + "@rjsf/core": "5.18.2", + "@rjsf/material-ui": "5.18.2", + "@rjsf/utils": "5.18.2", + "@rjsf/validator-ajv8": "5.18.2", "@types/json-schema": "^7.0.9", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "classnames": "^2.2.6", - "flatted": "3.2.9", + "flatted": "3.3.1", "humanize-duration": "^3.25.1", - "immer": "^9.0.1", "json-schema": "^0.4.0", - "json-schema-library": "^7.3.9", + "json-schema-library": "^9.0.0", "lodash": "^4.17.21", "luxon": "^3.0.0", "qs": "^6.9.4", @@ -80,25 +82,22 @@ "zod": "^3.22.4", "zod-to-json-schema": "^3.20.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/plugin-catalog": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "@types/humanize-duration": "^3.18.1", "@types/luxon": "^3.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx b/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx index 4c86ef0c62..7731cac3f8 100644 --- a/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx +++ b/plugins/scaffolder-react/src/next/components/Form/DescriptionFieldTemplate.tsx @@ -16,7 +16,8 @@ import React from 'react'; import { MarkdownContent } from '@backstage/core-components'; -import { makeStyles, Typography } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import { DescriptionFieldProps, FormContextType, diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index b601f77bf6..e3c7bc303e 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -38,10 +38,11 @@ export const ReviewState = (props: ReviewStateProps) => { .map(([key, value]) => { for (const step of props.schemas) { const parsedSchema = new JSONSchema(step.mergedSchema); - const definitionInSchema = parsedSchema.getSchema( - `#/${key}`, - props.formState, - ); + const definitionInSchema = parsedSchema.getSchema({ + pointer: `#/${key}`, + data: props.formState, + }); + if (definitionInSchema) { const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; diff --git a/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx b/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx index da233eeba0..1bb1656fd0 100644 --- a/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx +++ b/plugins/scaffolder-react/src/next/components/ScaffolderField/ScaffolderField.tsx @@ -16,7 +16,8 @@ import React, { PropsWithChildren, ReactElement } from 'react'; import { MarkdownContent } from '@backstage/core-components'; -import { FormControl, makeStyles } from '@material-ui/core'; +import FormControl from '@material-ui/core/FormControl'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(theme => ({ markdownDescription: { diff --git a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx index 9b6920108b..a5310a5806 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/ErrorListTemplate/errorListTemplate.tsx @@ -15,16 +15,12 @@ */ import React from 'react'; import { ErrorListProps } from '@rjsf/utils'; -import { - List, - ListItem, - ListItemIcon, - ListItemText, - Paper, - Theme, - createStyles, - makeStyles, -} from '@material-ui/core'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Paper from '@material-ui/core/Paper'; +import { Theme, createStyles, makeStyles } from '@material-ui/core/styles'; import ErrorIcon from '@material-ui/icons/Error'; const useStyles = makeStyles((_theme: Theme) => diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 9b475870d2..62effbd14a 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -15,14 +15,12 @@ */ import { useAnalytics, useApiHolder } from '@backstage/core-plugin-api'; import { JsonValue } from '@backstage/types'; -import { - Stepper as MuiStepper, - Step as MuiStep, - StepLabel as MuiStepLabel, - Button, - makeStyles, - LinearProgress, -} from '@material-ui/core'; +import MuiStepper from '@material-ui/core/Stepper'; +import MuiStep from '@material-ui/core/Step'; +import MuiStepLabel from '@material-ui/core/StepLabel'; +import Button from '@material-ui/core/Button'; +import LinearProgress from '@material-ui/core/LinearProgress'; +import { makeStyles } from '@material-ui/core/styles'; import { type IChangeEvent } from '@rjsf/core'; import { ErrorSchema } from '@rjsf/utils'; import React, { @@ -75,6 +73,11 @@ const useStyles = makeStyles(theme => ({ export type StepperProps = { manifest: TemplateParameterSchema; extensions: FieldExtensionOptions[]; + /** + * @deprecated This was only ever used for analytics tracking purposes, which + * is now handled in the `` component. Passing it in will have no + * effect. + */ templateName?: string; formProps?: FormProps; initialState?: Record; @@ -147,10 +150,7 @@ export const Stepper = (stepperProps: StepperProps) => { const handleCreate = useCallback(() => { props.onCreate(formState); - const name = - typeof formState.name === 'string' ? formState.name : undefined; - analytics.captureEvent('create', name ?? props.templateName ?? 'unknown'); - }, [props, formState, analytics]); + }, [props, formState]); const currentStep = useTransformSchemaToProps(steps[activeStep], { layouts }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts index f50f44d8f5..d11d0b9b3b 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts @@ -17,7 +17,11 @@ import { FieldValidation } from '@rjsf/utils'; import type { JsonObject, JsonValue } from '@backstage/types'; import { ApiHolder } from '@backstage/core-plugin-api'; -import { Draft07 as JSONSchema } from 'json-schema-library'; +import { + Draft07 as JSONSchema, + JsonError, + JsonSchema, +} from 'json-schema-library'; import { createFieldValidation, extractSchemaFromStep } from '../../lib'; import { CustomFieldValidator, @@ -30,6 +34,11 @@ export type FormValidation = { [name: string]: FieldValidation | FormValidation; }; +const isJsonError = ( + value: JsonError | JsonSchema, +): value is { type: 'error'; message: string } => + 'type' in value && value.type === 'error'; + /** @alpha */ export const createAsyncValidators = ( rootSchema: JsonObject, @@ -74,9 +83,23 @@ export const createAsyncValidators = ( }; for (const [key, value] of Object.entries(current)) { - const path = `${pathPrefix}/${key}`; - const definitionInSchema = parsedSchema.getSchema(path, formData); - const { schema, uiSchema } = extractSchemaFromStep(definitionInSchema); + const pointer = `${pathPrefix}/${key}`; + const definitionInSchema = parsedSchema.getSchema({ + pointer, + data: formData, + }); + + if (!definitionInSchema) { + continue; + } + + if (isJsonError(definitionInSchema)) { + throw new Error(definitionInSchema.message); + } + + const { schema, uiSchema } = extractSchemaFromStep( + definitionInSchema as JsonObject, + ); const hasItems = definitionInSchema && definitionInSchema.items; @@ -102,7 +125,7 @@ export const createAsyncValidators = ( } }; - if (definitionInSchema && 'ui:field' in definitionInSchema) { + if ('ui:field' in definitionInSchema) { await doValidateItem(definitionInSchema, schema, uiSchema); } else if (hasItems && 'ui:field' in definitionInSchema.items) { await doValidate(definitionInSchema.items); @@ -113,7 +136,7 @@ export const createAsyncValidators = ( await doValidate(propValue); } } else if (isObject(value)) { - formValidation[key] = await validate(formData, path, value); + formValidation[key] = await validate(formData, pointer, value); } } diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx index 58f2eb9050..c397b09a52 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/StepIcon.tsx @@ -15,7 +15,9 @@ */ import React from 'react'; -import { CircularProgress, makeStyles, StepIconProps } from '@material-ui/core'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import { StepIconProps } from '@material-ui/core/StepIcon'; +import { makeStyles } from '@material-ui/core/styles'; import RemoveCircleOutline from '@material-ui/icons/RemoveCircleOutline'; import PanoramaFishEyeIcon from '@material-ui/icons/PanoramaFishEye'; import classNames from 'classnames'; diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx index 3f8fde748c..ab236965c2 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/StepTime.tsx @@ -14,10 +14,10 @@ * limitations under the License. */ import React, { useCallback, useState } from 'react'; -import useInterval from 'react-use/lib/useInterval'; +import useInterval from 'react-use/esm/useInterval'; import { DateTime, Interval } from 'luxon'; import humanizeDuration from 'humanize-duration'; -import { Typography } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; import { useMountEffect } from '@react-hookz/web'; export const StepTime = (props: { diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx index d7a96e3864..a33cdad49e 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskBorder.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { LinearProgress, makeStyles } from '@material-ui/core'; +import LinearProgress from '@material-ui/core/LinearProgress'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(theme => ({ failed: { diff --git a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx index d74d298778..b391e6fce8 100644 --- a/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx +++ b/plugins/scaffolder-react/src/next/components/TaskSteps/TaskSteps.tsx @@ -14,15 +14,13 @@ * limitations under the License. */ import React from 'react'; -import { - Stepper as MuiStepper, - Step as MuiStep, - StepButton as MuiStepButton, - StepLabel as MuiStepLabel, - StepIconProps, - Box, - Paper, -} from '@material-ui/core'; +import MuiStepper from '@material-ui/core/Stepper'; +import MuiStep from '@material-ui/core/Step'; +import MuiStepButton from '@material-ui/core/StepButton'; +import MuiStepLabel from '@material-ui/core/StepLabel'; +import { StepIconProps } from '@material-ui/core/StepIcon'; +import Box from '@material-ui/core/Box'; +import Paper from '@material-ui/core/Paper'; import { TaskStep } from '@backstage/plugin-scaffolder-common'; import { StepIcon } from './StepIcon'; import { StepTime } from './StepTime'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx index 287d813ca7..5aa138340e 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { fireEvent, render } from '@testing-library/react'; import { CardHeader } from './CardHeader'; -import { ThemeProvider } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core/styles'; import { lightTheme } from '@backstage/theme'; import { MockStorageApi, diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx index 1180c8f106..467d26ce76 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardHeader.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { Theme, makeStyles, useTheme } from '@material-ui/core'; +import { Theme, makeStyles, useTheme } from '@material-ui/core/styles'; import { ItemCardHeader } from '@backstage/core-components'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { FavoriteEntity } from '@backstage/plugin-catalog-react'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx index 839d6c7ac1..263a1356b7 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/CardLink.tsx @@ -16,7 +16,7 @@ import { IconComponent } from '@backstage/core-plugin-api'; import { Link } from '@backstage/core-components'; -import { makeStyles } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; interface CardLinkProps { diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx index 2d8ff1e458..4fb2ca0e4a 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx @@ -22,18 +22,15 @@ import { getEntityRelations, } from '@backstage/plugin-catalog-react'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { - Box, - Card, - CardActions, - CardContent, - Chip, - Divider, - Button, - Grid, - makeStyles, - Theme, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import Chip from '@material-ui/core/Chip'; +import Divider from '@material-ui/core/Divider'; +import Button from '@material-ui/core/Button'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import LanguageIcon from '@material-ui/icons/Language'; import React from 'react'; import { CardHeader } from './CardHeader'; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx b/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx index eba6aebf93..24f8a21109 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCategoryPicker/TemplateCategoryPicker.tsx @@ -17,29 +17,40 @@ import React from 'react'; import capitalize from 'lodash/capitalize'; import { Progress } from '@backstage/core-components'; -import { - Box, - Checkbox, - FormControlLabel, - TextField, - Typography, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Checkbox from '@material-ui/core/Checkbox'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import TextField from '@material-ui/core/TextField'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { Autocomplete } from '@material-ui/lab'; +import Autocomplete from '@material-ui/lab/Autocomplete'; import { useEntityTypeFilter } from '@backstage/plugin-catalog-react'; import { alertApiRef, useApi } from '@backstage/core-plugin-api'; const icon = ; const checkedIcon = ; +/** @alpha */ +export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label'; + +const useStyles = makeStyles( + { + root: {}, + label: {}, + }, + { name: 'ScaffolderReactTemplateCategoryPicker' }, +); + /** * The Category Picker that is rendered on the left side for picking * categories and filtering the template list. * @alpha */ export const TemplateCategoryPicker = () => { + const classes = useStyles(); const alertApi = useApi(alertApiRef); const { error, loading, availableTypes, selectedTypes, setSelectedTypes } = useEntityTypeFilter(); @@ -57,8 +68,9 @@ export const TemplateCategoryPicker = () => { if (!availableTypes) return null; return ( - + = { cancelTask: jest.fn(), @@ -36,10 +37,14 @@ const scaffolderApiMock: jest.Mocked = { listActions: jest.fn(), listTasks: jest.fn(), }; +const catalogApiMock: jest.Mocked = { + getEntityByRef: jest.fn(), +} as any; const analyticsMock = new MockAnalyticsApi(); const apis = TestApiRegistry.from( [scaffolderApiRef, scaffolderApiMock], + [catalogApiRef, catalogApiMock], [analyticsApiRef, analyticsMock], ); diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx index c6030930c5..9afc18c438 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { useEffect } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { Content, InfoCard, @@ -22,13 +22,15 @@ import { Progress, } from '@backstage/core-components'; import { stringifyEntityRef } from '@backstage/catalog-model'; -import { makeStyles } from '@material-ui/core'; -import { errorApiRef, useApi } from '@backstage/core-plugin-api'; +import { makeStyles } from '@material-ui/core/styles'; +import { errorApiRef, useAnalytics, useApi } from '@backstage/core-plugin-api'; import { useTemplateParameterSchema } from '../../hooks/useTemplateParameterSchema'; import { Stepper, type StepperProps } from '../Stepper/Stepper'; import { SecretsContextProvider } from '../../../secrets/SecretsContext'; import { useFilteredSchemaProperties } from '../../hooks/useFilteredSchemaProperties'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; +import { useTemplateTimeSavedMinutes } from '../../hooks/useTemplateTimeSaved'; +import { JsonValue } from '@backstage/types'; const useStyles = makeStyles({ markdown: { @@ -68,9 +70,10 @@ export type WorkflowProps = { * @alpha */ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { - const { title, description, namespace, templateName, ...props } = + const { title, description, namespace, templateName, onCreate, ...props } = workflowProps; + const analytics = useAnalytics(); const styles = useStyles(); const templateRef = stringifyEntityRef({ kind: 'Template', @@ -84,6 +87,21 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { const sortedManifest = useFilteredSchemaProperties(manifest); + const minutesSaved = useTemplateTimeSavedMinutes(templateRef); + + const workflowOnCreate = useCallback( + async (formState: Record) => { + onCreate(formState); + + const name = + typeof formState.name === 'string' ? formState.name : undefined; + analytics.captureEvent('create', name ?? templateName ?? 'unknown', { + value: minutesSaved, + }); + }, + [onCreate, analytics, templateName, minutesSaved], + ); + useEffect(() => { if (error) { errorApi.post(new Error(`Failed to load template, ${error}`)); @@ -113,7 +131,7 @@ export const Workflow = (workflowProps: WorkflowProps): JSX.Element | null => { > diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts index 73452f1670..4b4f21ae71 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import { scaffolderApiRef } from '../../api/ref'; import { useApi } from '@backstage/core-plugin-api'; import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateTimeSaved.test.tsx b/plugins/scaffolder-react/src/next/hooks/useTemplateTimeSaved.test.tsx new file mode 100644 index 0000000000..ed54335c7e --- /dev/null +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateTimeSaved.test.tsx @@ -0,0 +1,74 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { useTemplateTimeSavedMinutes } from './useTemplateTimeSaved'; +import { renderHook, waitFor } from '@testing-library/react'; +import { TestApiProvider } from '@backstage/test-utils'; +import React from 'react'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; + +const getTemplateWithTimeSaved = ( + timeSaved: string | undefined, +): TemplateEntityV1beta3 => ({ + apiVersion: 'scaffolder.backstage.io/v1beta3', + kind: 'Template', + metadata: { + name: 'test-fixture', + ...(timeSaved + ? { + annotations: { + 'backstage.io/time-saved': timeSaved, + }, + } + : undefined), + }, + spec: { + type: 'test-fixture', + steps: [], + }, +}); + +describe('useTemplateTimeSavedMinutes', () => { + it.each([ + ['PT2H', 120], + ['P3D', 4320], + ['2 hours', undefined], + [undefined, undefined], + ])( + 'should return the expected duration given "%s"', + async (given, expected) => { + const templateRef = 'template:default/happy-path'; + const template = getTemplateWithTimeSaved(given); + + const { result } = renderHook( + () => useTemplateTimeSavedMinutes(templateRef), + { + wrapper: ({ children }: React.PropsWithChildren<{}>) => ( + template }]]} + > + {children} + + ), + }, + ); + + await waitFor(() => { + expect(result.current).toEqual(expected); + }); + }, + ); +}); diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateTimeSaved.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateTimeSaved.ts new file mode 100644 index 0000000000..df87a8bdfa --- /dev/null +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateTimeSaved.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useApi } from '@backstage/core-plugin-api'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; +import { Duration } from 'luxon'; +import useAsync from 'react-use/lib/useAsync'; + +/** + * Returns the backstage.io/time-saved annotation (as a number of minutes) for + * a given template entity ref. + */ +export const useTemplateTimeSavedMinutes = (templateRef: string) => { + const catalogApi = useApi(catalogApiRef); + + const { value: timeSavedMinutes } = useAsync(async () => { + const entity = await catalogApi.getEntityByRef(templateRef); + const timeSaved = entity?.metadata.annotations?.['backstage.io/time-saved']; + + // This is not a valid template or the template has no time-saved value. + if (!entity || !timeSaved) { + return undefined; + } + + const durationMs = Duration.fromISO(timeSaved).as('minutes'); + + // The time-saved annotation has an invalid value. Ignore. + if (Number.isNaN(durationMs)) { + return undefined; + } + + return durationMs; + }, [catalogApi, templateRef]); + + return timeSavedMinutes; +}; diff --git a/plugins/scaffolder-react/src/next/index.ts b/plugins/scaffolder-react/src/next/index.ts index f13bb76d7a..2c9c1706f0 100644 --- a/plugins/scaffolder-react/src/next/index.ts +++ b/plugins/scaffolder-react/src/next/index.ts @@ -16,3 +16,4 @@ export * from './components'; export * from './lib'; export * from './hooks'; +export * from './overridableComponents'; diff --git a/plugins/scaffolder-react/src/next/overridableComponents.ts b/plugins/scaffolder-react/src/next/overridableComponents.ts new file mode 100644 index 0000000000..56986d4f80 --- /dev/null +++ b/plugins/scaffolder-react/src/next/overridableComponents.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Overrides } from '@material-ui/core/styles/overrides'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; +import { ScaffolderReactTemplateCategoryPickerClassKey } from './components/TemplateCategoryPicker/TemplateCategoryPicker'; + +/** @alpha */ +export type ScaffolderReactComponentsNameToClassKey = { + ScaffolderReactTemplateCategoryPicker: ScaffolderReactTemplateCategoryPickerClassKey; +}; + +/** @alpha */ +export type BackstageOverrides = Overrides & { + [Name in keyof ScaffolderReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + +declare module '@backstage/theme' { + interface OverrideComponentNameToClassKeys + extends ScaffolderReactComponentsNameToClassKey {} +} diff --git a/plugins/scaffolder-react/src/secrets/SecretsContext.test.tsx b/plugins/scaffolder-react/src/secrets/SecretsContext.test.tsx index 4d56b5764c..5252cf77bd 100644 --- a/plugins/scaffolder-react/src/secrets/SecretsContext.test.tsx +++ b/plugins/scaffolder-react/src/secrets/SecretsContext.test.tsx @@ -35,4 +35,20 @@ describe('SecretsContext', () => { expect(result.current.hook?.secrets.foo).toEqual('bar'); }); + + it('should create SecretsContextProvider with initial secrets', async () => { + const { result } = renderHook( + () => ({ + hook: useTemplateSecrets(), + }), + { + wrapper: ({ children }: React.PropsWithChildren<{}>) => ( + + {children} + + ), + }, + ); + expect(result.current.hook?.secrets.foo).toEqual('bar'); + }); }); diff --git a/plugins/scaffolder-react/src/secrets/SecretsContext.tsx b/plugins/scaffolder-react/src/secrets/SecretsContext.tsx index 3cbd23597a..64b25d0e8f 100644 --- a/plugins/scaffolder-react/src/secrets/SecretsContext.tsx +++ b/plugins/scaffolder-react/src/secrets/SecretsContext.tsx @@ -43,8 +43,13 @@ const SecretsContext = createVersionedContext<{ * The Context Provider that holds the state for the secrets. * @public */ -export const SecretsContextProvider = (props: PropsWithChildren<{}>) => { - const [secrets, setSecrets] = useState>({}); +export const SecretsContextProvider = ( + props: PropsWithChildren<{ initialSecrets?: Record }>, +) => { + const { initialSecrets = {} } = props; + const [secrets, setSecrets] = useState>({ + ...initialSecrets, + }); return ( { }, { title: 'Template', + field: 'spec.templateInfo.entity.metadata.title', render: row => ( ', () => { expect(onChange).toHaveBeenCalledWith('group:default/group1'); }); }); + + it('should use the pre-existed formdata value if set with the form', async () => { + const userGroups = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { name: 'group1', title: 'My First Group' }, + spec: { members: ['Bob'] }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { name: 'group2', title: 'My Second Group' }, + spec: { members: ['Bob'] }, + }, + ]; + + catalogApi.getEntities.mockResolvedValue({ items: userGroups }); + + const props = { + onChange, + schema, + required, + formData: 'group:default/group1', + } as unknown as FieldProps; + + const { getByRole } = render( + + + , + ); + + await waitFor(() => + expect(catalogApi.getEntities).toHaveBeenCalledTimes(1), + ); + + const inputField = getByRole('combobox'); + const inputFieldValue = inputField?.querySelector('input')?.value; + + expect(inputFieldValue).toEqual(userGroups[0].metadata.title); + }); }); diff --git a/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.tsx b/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.tsx index fefdd4230c..1e78fa45a1 100644 --- a/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.tsx +++ b/plugins/scaffolder/src/components/fields/MyGroupsPicker/MyGroupsPicker.tsx @@ -20,12 +20,13 @@ import { identityApiRef, useApi, } from '@backstage/core-plugin-api'; -import { TextField, FormControl } from '@material-ui/core'; +import TextField from '@material-ui/core/TextField'; +import FormControl from '@material-ui/core/FormControl'; import { MyGroupsPickerProps, MyGroupsPickerSchema } from './schema'; -import { Autocomplete } from '@material-ui/lab'; +import Autocomplete from '@material-ui/lab/Autocomplete'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { NotFoundError } from '@backstage/errors'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; export { MyGroupsPickerSchema }; @@ -36,6 +37,7 @@ export const MyGroupsPicker = (props: MyGroupsPickerProps) => { required, rawErrors, onChange, + formData, } = props; const identityApi = useApi(identityApiRef); @@ -47,10 +49,6 @@ export const MyGroupsPicker = (props: MyGroupsPickerProps) => { ref: string; }[] >([]); - const [selectedGroup, setSelectedGroup] = useState(null); useAsync(async () => { const { userEntityRef } = await identityApi.getBackstageIdentity(); @@ -81,10 +79,11 @@ export const MyGroupsPicker = (props: MyGroupsPickerProps) => { _: React.ChangeEvent<{}>, value: { label: string; ref: string } | null, ) => { - setSelectedGroup(value); onChange(value?.ref ?? ''); }; + const selectedEntity = groups?.find(e => e.ref === formData) || null; + return ( { group.label} renderInput={params => ( diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index d7999c8c0c..d5351d54e5 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -15,10 +15,10 @@ */ import { RELATION_OWNED_BY } from '@backstage/catalog-model'; import { identityApiRef, useApi } from '@backstage/core-plugin-api'; -import { TextField } from '@material-ui/core'; +import TextField from '@material-ui/core/TextField'; import Autocomplete from '@material-ui/lab/Autocomplete'; import React from 'react'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import { EntityPicker } from '../EntityPicker/EntityPicker'; import { OwnedEntityPickerProps } from './schema'; diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx index fb0b478556..85a50fa7cb 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx @@ -58,9 +58,13 @@ describe('RepoUrlPicker', () => { byHost: () => ({ type: 'github' }), }; - const mockScmAuthApi: Partial = { - getCredentials: jest.fn().mockResolvedValue({ token: 'abc123' }), - }; + let mockScmAuthApi: Partial; + + beforeEach(() => { + mockScmAuthApi = { + getCredentials: jest.fn().mockResolvedValue({ token: 'abc123' }), + }; + }); describe('happy path rendering', () => { it('should render the repo url picker with minimal props', async () => { @@ -350,5 +354,64 @@ describe('RepoUrlPicker', () => { secrets: { testKey: 'abc123' }, }); }); + + it('should not call the scmAuthApi if secret is available in the state', async () => { + const SecretsComponent = () => { + const { secrets } = useTemplateSecrets(); + return ( +
{JSON.stringify({ secrets })}
+ ); + }; + const { getAllByRole, getByTestId } = await renderInTestApp( + + +
, + }} + /> + +
+
, + ); + + const [ownerInput, repoInput] = getAllByRole('textbox'); + + await act(async () => { + fireEvent.change(ownerInput, { target: { value: 'backstage' } }); + fireEvent.change(repoInput, { target: { value: 'repo123' } }); + + // need to wait for the debounce to finish + await new Promise(resolve => setTimeout(resolve, 600)); + }); + + // as we already have a secret in the state, getCredentials should not be called again. + expect(mockScmAuthApi.getCredentials).toHaveBeenCalledTimes(0); + + const currentSecrets = JSON.parse( + getByTestId('current-secrets').textContent!, + ); + + expect(currentSecrets).toEqual({ + secrets: { testKey: 'abc123' }, + }); + }); }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index ba333088ab..abc12093ab 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -30,9 +30,11 @@ import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName'; import { parseRepoPickerUrl, serializeRepoPickerUrl } from './utils'; import { RepoUrlPickerProps } from './schema'; import { RepoUrlPickerState } from './types'; -import useDebounce from 'react-use/lib/useDebounce'; +import useDebounce from 'react-use/esm/useDebounce'; import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react'; -import { Box, Divider, Typography } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Divider from '@material-ui/core/Divider'; +import Typography from '@material-ui/core/Typography'; export { RepoUrlPickerSchema } from './schema'; @@ -49,7 +51,7 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { ); const integrationApi = useApi(scmIntegrationsApiRef); const scmAuthApi = useApi(scmAuthApiRef); - const { setSecrets } = useTemplateSecrets(); + const { secrets, setSecrets } = useTemplateSecrets(); const allowedHosts = useMemo( () => uiSchema?.['ui:options']?.allowedHosts ?? [], [uiSchema], @@ -130,6 +132,11 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { return; } + // don't show login prompt if secret value is already in state + if (secrets[requestUserCredentials.secretsKey]) { + return; + } + // previously, we were encodeURI for state.host, workspace and state.repoName separately. // That created an issue where GitLab workspace can be nested like groupA/subgroupB // when we encodeURi separately and then join, the URL will be malformed and diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.tsx index 51844f02ff..ed06983f90 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerHost.tsx @@ -19,7 +19,7 @@ import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; import { useApi } from '@backstage/core-plugin-api'; import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; export const RepoUrlPickerHost = (props: { host?: string; diff --git a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx index e6eea9fc72..aac0cf809a 100644 --- a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx @@ -17,7 +17,8 @@ import React from 'react'; import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react'; import { ScaffolderRJSFFieldProps } from '@backstage/plugin-scaffolder-react'; import { ScaffolderField } from '@backstage/plugin-scaffolder-react/alpha'; -import { Input, InputLabel } from '@material-ui/core'; +import Input from '@material-ui/core/Input'; +import InputLabel from '@material-ui/core/InputLabel'; export const SecretInput = (props: ScaffolderRJSFFieldProps) => { const { setSecrets, secrets } = useTemplateSecrets(); diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx index 2a4326c432..bddf891ec6 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/CustomFieldExplorer.tsx @@ -15,18 +15,16 @@ */ import { StreamLanguage } from '@codemirror/language'; import { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml'; -import { - Button, - Card, - CardContent, - CardHeader, - FormControl, - IconButton, - InputLabel, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import Card from '@material-ui/core/Card'; +import CardContent from '@material-ui/core/CardContent'; +import CardHeader from '@material-ui/core/CardHeader'; +import FormControl from '@material-ui/core/FormControl'; +import IconButton from '@material-ui/core/IconButton'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; +import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import CodeMirror from '@uiw/react-codemirror'; import React, { useCallback, useMemo, useState } from 'react'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx index 6676c622fa..079294cc50 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/IconLink.tsx @@ -14,7 +14,10 @@ * limitations under the License. */ import React from 'react'; -import { Grid, LinkProps, makeStyles, Typography } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; +import Typography from '@material-ui/core/Typography'; +import Grid from '@material-ui/core/Grid'; +import { LinkProps } from '@material-ui/core/Link'; import LanguageIcon from '@material-ui/icons/Language'; import { IconComponent } from '@backstage/core-plugin-api'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx index 59c1515b79..5f62509551 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskPageLinks.tsx @@ -16,7 +16,7 @@ import { parseEntityRef } from '@backstage/catalog-model'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; -import { Box } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; import LanguageIcon from '@material-ui/icons/Language'; import React from 'react'; import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx index f776d133e0..cde3d6cfb0 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/DryRunResults/TaskStatusStepper.tsx @@ -14,25 +14,21 @@ * limitations under the License. */ import React, { useState } from 'react'; +import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; import { memo } from 'react'; import Step from '@material-ui/core/Step'; import StepLabel from '@material-ui/core/StepLabel'; import Stepper from '@material-ui/core/Stepper'; import { ScaffolderTaskStatus } from '@backstage/plugin-scaffolder-react'; -import { - StepButton, - StepIconProps, - Theme, - createStyles, - makeStyles, - CircularProgress, -} from '@material-ui/core'; +import StepButton from '@material-ui/core/StepButton'; +import { StepIconProps } from '@material-ui/core/StepIcon'; +import CircularProgress from '@material-ui/core/CircularProgress'; import Cancel from '@material-ui/icons/Cancel'; import Check from '@material-ui/icons/Check'; import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'; import Typography from '@material-ui/core/Typography'; import { DateTime, Interval } from 'luxon'; -import useInterval from 'react-use/lib/useInterval'; +import useInterval from 'react-use/esm/useInterval'; import humanizeDuration from 'humanize-duration'; import classNames from 'classnames'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx index a348f5e513..0b6b60661a 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { makeStyles } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; import React, { useState } from 'react'; import type { LayoutOptions } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions } from '@backstage/plugin-scaffolder-react'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx index 996da98d4a..489ec05bbe 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorBrowser.tsx @@ -13,7 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Divider, IconButton, makeStyles, Tooltip } from '@material-ui/core'; +import Divider from '@material-ui/core/Divider'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; +import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import RefreshIcon from '@material-ui/icons/Refresh'; import SaveIcon from '@material-ui/icons/Save'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx index 4b5a00b7ba..e6149f57a1 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx @@ -17,7 +17,7 @@ import { useApiHolder } from '@backstage/core-plugin-api'; import { JsonObject, JsonValue } from '@backstage/types'; import { makeStyles } from '@material-ui/core/styles'; import React, { Component, ReactNode, useMemo, useState } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; +import useDebounce from 'react-use/esm/useDebounce'; import yaml from 'yaml'; import { LayoutOptions, diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx index 588b0cd4ba..ce8db485ea 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorTextArea.tsx @@ -17,7 +17,10 @@ import { StreamLanguage } from '@codemirror/language'; import { yaml as yamlSupport } from '@codemirror/legacy-modes/mode/yaml'; import { showPanel } from '@codemirror/view'; -import { IconButton, makeStyles, Paper, Tooltip } from '@material-ui/core'; +import IconButton from '@material-ui/core/IconButton'; +import Paper from '@material-ui/core/Paper'; +import Tooltip from '@material-ui/core/Tooltip'; +import { makeStyles } from '@material-ui/core/styles'; import RefreshIcon from '@material-ui/icons/Refresh'; import SaveIcon from '@material-ui/icons/Save'; import { useKeyboardEvent } from '@react-hookz/web'; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx index c253bc0a5f..7892adfb3f 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx @@ -19,18 +19,16 @@ import { catalogApiRef, humanizeEntityRef, } from '@backstage/plugin-catalog-react'; -import { - FormControl, - IconButton, - InputLabel, - LinearProgress, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; +import FormControl from '@material-ui/core/FormControl'; +import IconButton from '@material-ui/core/IconButton'; +import InputLabel from '@material-ui/core/InputLabel'; +import LinearProgress from '@material-ui/core/LinearProgress'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; +import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import React, { useCallback, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; import yaml from 'yaml'; import { LayoutOptions, diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx index eab7ce4485..abec7c47e1 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx +++ b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx @@ -22,7 +22,7 @@ import { Link as RouterLink, LinkProps } from 'react-router-dom'; import AddCircleOutline from '@material-ui/icons/AddCircleOutline'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; import { usePermission } from '@backstage/plugin-permission-react'; -import { Theme } from '@material-ui/core'; +import { Theme } from '@material-ui/core/styles'; /** * Properties for {@link RegisterExistingButton} diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx index 26a9dd946c..269ff81271 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx @@ -29,6 +29,9 @@ import { } from '@backstage/plugin-scaffolder-react'; import { TemplateWizardPage } from './TemplateWizardPage'; import { rootRouteRef } from '../../routes'; +import { ANNOTATION_EDIT_URL } from '@backstage/catalog-model'; +import { CatalogApi } from '@backstage/catalog-client'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; jest.mock('react-router-dom', () => { return { @@ -50,12 +53,34 @@ const scaffolderApiMock: jest.Mocked = { listTasks: jest.fn(), }; +const catalogApiMock: jest.Mocked = { + getEntityByRef: jest.fn(), +} as any; + const analyticsMock = new MockAnalyticsApi(); const apis = TestApiRegistry.from( [scaffolderApiRef, scaffolderApiMock], + [catalogApiRef, catalogApiMock], [analyticsApiRef, analyticsMock], + [catalogApiRef, catalogApiMock], ); +const entityRefResponse = { + apiVersion: 'v1', + kind: 'service', + metadata: { + name: 'test', + annotations: { + [ANNOTATION_EDIT_URL]: 'http://localhost:3000', + 'backstage.io/time-saved': 'PT2H', + }, + }, + spec: { + profile: { + displayName: 'BackUser', + }, + }, +}; describe('TemplateWizardPage', () => { it('captures expected analytics events', async () => { scaffolderApiMock.scaffold.mockResolvedValue({ taskId: 'xyz' }); @@ -74,6 +99,7 @@ describe('TemplateWizardPage', () => { ], title: 'React JSON Schema Form Test', }); + catalogApiMock.getEntityByRef.mockResolvedValue(entityRefResponse); const { findByRole, getByRole } = await renderInTestApp( @@ -115,6 +141,67 @@ describe('TemplateWizardPage', () => { action: 'create', subject: 'expected-name', context: { entityRef: 'template:default/test' }, + value: 120, + }); + }); + describe('scaffolder page context menu', () => { + it('should render if editUrl is set to url', async () => { + catalogApiMock.getEntityByRef.mockResolvedValue({ + apiVersion: 'v1', + kind: 'service', + metadata: { + name: 'test', + annotations: { + [ANNOTATION_EDIT_URL]: 'http://localhost:3000', + }, + }, + spec: { + profile: { + displayName: 'BackUser', + }, + }, + }); + const { queryByTestId } = await renderInTestApp( + + + , + + , + { + mountedRoutes: { + '/create': rootRouteRef, + }, + }, + ); + expect(queryByTestId('menu-button')).toBeInTheDocument(); + }); + it('should not render if editUrl is undefined', async () => { + catalogApiMock.getEntityByRef.mockResolvedValue({ + apiVersion: 'v1', + kind: 'service', + metadata: { + name: 'test', + // annotations are not set + }, + spec: { + profile: { + displayName: 'BackUser', + }, + }, + }); + const { queryByTestId } = await renderInTestApp( + + + , + + , + { + mountedRoutes: { + '/create': rootRouteRef, + }, + }, + ); + expect(queryByTestId('menu-button')).not.toBeInTheDocument(); }); }); }); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index 611330e76b..aef6ca6bb1 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -15,7 +15,11 @@ */ import React from 'react'; import { Navigate, useNavigate } from 'react-router-dom'; -import { stringifyEntityRef } from '@backstage/catalog-model'; +import useAsync from 'react-use/esm/useAsync'; +import { + stringifyEntityRef, + ANNOTATION_EDIT_URL, +} from '@backstage/catalog-model'; import { AnalyticsContext, useApi, @@ -30,6 +34,8 @@ import { FieldExtensionOptions, ReviewStepProps, } from '@backstage/plugin-scaffolder-react'; +import { catalogApiRef } from '@backstage/plugin-catalog-react'; + import { Workflow } from '@backstage/plugin-scaffolder-react/alpha'; import { JsonValue } from '@backstage/types'; import { Header, Page } from '@backstage/core-components'; @@ -40,6 +46,8 @@ import { selectedTemplateRouteRef, } from '../../routes'; +import { TemplateWizardPageContextMenu } from './TemplateWizardPageContextMenu'; + /** * @alpha */ @@ -62,6 +70,7 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => { const taskRoute = useRouteRef(scaffolderTaskRouteRef); const { secrets } = useTemplateSecrets(); const scaffolderApi = useApi(scaffolderApiRef); + const catalogApi = useApi(catalogApiRef); const navigate = useNavigate(); const { templateName, namespace } = useRouteRefParams( selectedTemplateRouteRef, @@ -73,6 +82,11 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => { name: templateName, }); + const { value: editUrl } = useAsync(async () => { + const data = await catalogApi.getEntityByRef(templateRef); + return data?.metadata.annotations?.[ANNOTATION_EDIT_URL]; + }, [templateRef, catalogApi]); + const onCreate = async (values: Record) => { const { taskId } = await scaffolderApi.scaffold({ templateRef, @@ -93,7 +107,9 @@ export const TemplateWizardPage = (props: TemplateWizardPageProps) => { title="Create a new component" subtitle="Create new software components using standard templates in your organization" {...props.headerOptions} - /> + > + + ({ + button: { + color: theme.page.fontColor, + }, +})); + +export type TemplateWizardPageContextMenuProps = { + editUrl?: string; +}; + +export function TemplateWizardPageContextMenu( + props: TemplateWizardPageContextMenuProps, +) { + const { editUrl } = props; + const classes = useStyles(); + const [anchorEl, setAnchorEl] = useState(); + + if (!editUrl) { + return null; + } + + const onOpen = (event: React.SyntheticEvent) => { + setAnchorEl(event.currentTarget); + }; + + const onClose = () => { + setAnchorEl(undefined); + }; + + return ( + <> + + + + + + window.open(editUrl, '_blank')}> + + + + + + + + + ); +} diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index d01a18a844..51b9f5674a 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,214 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.23-next.0 + +### Patch Changes + +- d5fff66: Fix wiring of the module exported at the `/alpha` path, which was causing authentication failures. +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.10.0 + - @backstage/catalog-client@1.6.2 + - @backstage/backend-common@0.21.5 + - @backstage/backend-tasks@0.5.20 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.9.0 + +## 0.1.18 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.17-next.0 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## 0.1.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.14-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/api-report.md b/plugins/search-backend-module-catalog/api-report.md index 6f5813ca9e..fc19ede2d4 100644 --- a/plugins/search-backend-module-catalog/api-report.md +++ b/plugins/search-backend-module-catalog/api-report.md @@ -5,6 +5,7 @@ ```ts /// +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; import { Config } from '@backstage/config'; @@ -41,6 +42,7 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { // @public (undocumented) export type DefaultCatalogCollatorFactoryOptions = { + auth?: AuthService; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; locationTemplate?: string; diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index fd11dd6199..1d9a4a37c7 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-catalog", + "version": "0.1.23-next.0", "description": "A module for the search backend that exports catalog modules", - "version": "0.1.14-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-catalog" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-catalog" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -61,9 +65,5 @@ "@backstage/cli": "workspace:^", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-catalog/src/alpha.ts b/plugins/search-backend-module-catalog/src/alpha.ts index 71dabeb011..2ae9cd8af9 100644 --- a/plugins/search-backend-module-catalog/src/alpha.ts +++ b/plugins/search-backend-module-catalog/src/alpha.ts @@ -77,6 +77,7 @@ export default createBackendModule({ env.registerInit({ deps: { + auth: coreServices.auth, config: coreServices.rootConfig, discovery: coreServices.discovery, tokenManager: coreServices.tokenManager, @@ -85,6 +86,7 @@ export default createBackendModule({ catalog: catalogServiceRef, }, async init({ + auth, config, discovery, tokenManager, @@ -97,6 +99,7 @@ export default createBackendModule({ readScheduleConfigOptions(config), ), factory: DefaultCatalogCollatorFactory.fromConfig(config, { + auth, entityTransformer, discovery, tokenManager, diff --git a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts index 586346c385..166985f2d5 100644 --- a/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts +++ b/plugins/search-backend-module-catalog/src/collators/DefaultCatalogCollatorFactory.ts @@ -17,6 +17,7 @@ import { PluginEndpointDiscovery, TokenManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { CatalogApi, @@ -33,9 +34,11 @@ import { Readable } from 'stream'; import { CatalogCollatorEntityTransformer } from './CatalogCollatorEntityTransformer'; import { readCollatorConfigOptions } from './config'; import { defaultCatalogCollatorEntityTransformer } from './defaultCatalogCollatorEntityTransformer'; +import { AuthService } from '@backstage/backend-plugin-api'; /** @public */ export type DefaultCatalogCollatorFactoryOptions = { + auth?: AuthService; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; /** @@ -71,20 +74,26 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { private filter?: GetEntitiesRequest['filter']; private batchSize: number; private readonly catalogClient: CatalogApi; - private tokenManager: TokenManager; private entityTransformer: CatalogCollatorEntityTransformer; + private auth: AuthService; static fromConfig( configRoot: Config, options: DefaultCatalogCollatorFactoryOptions, ) { const configOptions = readCollatorConfigOptions(configRoot); + const { auth: adaptedAuth } = createLegacyAuthAdapters({ + auth: options.auth, + discovery: options.discovery, + tokenManager: options.tokenManager, + }); return new DefaultCatalogCollatorFactory({ locationTemplate: options.locationTemplate ?? configOptions.locationTemplate, filter: options.filter ?? configOptions.filter, batchSize: options.batchSize ?? configOptions.batchSize, entityTransformer: options.entityTransformer, + auth: adaptedAuth, discovery: options.discovery, tokenManager: options.tokenManager, catalogClient: options.catalogClient, @@ -96,17 +105,18 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { filter: GetEntitiesRequest['filter']; batchSize: number; entityTransformer?: CatalogCollatorEntityTransformer; + auth: AuthService; discovery: PluginEndpointDiscovery; tokenManager: TokenManager; catalogClient?: CatalogApi; }) { const { + auth, batchSize, discovery, locationTemplate, filter, catalogClient, - tokenManager, entityTransformer, } = options; @@ -115,9 +125,9 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { this.batchSize = batchSize; this.catalogClient = catalogClient || new CatalogClient({ discoveryApi: discovery }); - this.tokenManager = tokenManager; this.entityTransformer = entityTransformer ?? defaultCatalogCollatorEntityTransformer; + this.auth = auth; } async getCollator(): Promise { @@ -125,7 +135,6 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { } private async *execute(): AsyncGenerator { - const { token } = await this.tokenManager.getToken(); let entitiesRetrieved = 0; let moreEntitiesToGet = true; @@ -133,6 +142,10 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { // limit (and allow some control over) memory used by the search backend // at index-time. while (moreEntitiesToGet) { + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); const entities = ( await this.catalogClient.getEntities( { diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index d2250cc45c..ca4d6ad599 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,149 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## 1.4.0 + +### Minor Changes + +- 4d754e3: When using the New Backend System, the Elasticsearch provider will only be added if the `search.elasticsearch` config section exists. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/integration-aws-node@0.1.12 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.3.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## 1.3.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.3.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/integration-aws-node@0.1.11 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.3.17 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- e1f73d0: Added config.d.ts entry with secrets for the shared auth block +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/integration-aws-node@0.1.10 + +## 1.3.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.3.17-next.1 + +### Patch Changes + +- e1f73d0: Added config.d.ts entry with secrets for the shared auth block +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.3.16-next.0 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + +## 1.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/integration-aws-node@0.1.9 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 1.3.13-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/api-report.md b/plugins/search-backend-module-elasticsearch/api-report.md index 7de3a1857b..053c267f29 100644 --- a/plugins/search-backend-module-elasticsearch/api-report.md +++ b/plugins/search-backend-module-elasticsearch/api-report.md @@ -17,7 +17,7 @@ import { IndexableResultSet } from '@backstage/plugin-search-common'; import { Logger } from 'winston'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Readable } from 'stream'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { SearchQuery } from '@backstage/plugin-search-common'; import { TransportRequestPromise } from '@opensearch-project/opensearch/lib/Transport'; import { TransportRequestPromise as TransportRequestPromise_2 } from '@elastic/elasticsearch/lib/Transport'; diff --git a/plugins/search-backend-module-elasticsearch/config.d.ts b/plugins/search-backend-module-elasticsearch/config.d.ts index b798240cef..401e55f792 100644 --- a/plugins/search-backend-module-elasticsearch/config.d.ts +++ b/plugins/search-backend-module-elasticsearch/config.d.ts @@ -212,6 +212,33 @@ export interface Config { }; } ); + + /** + * Authentication credentials for ElasticSearch. These are fallback + * credentials - in most cases, for known specific ES implementations, the + * respective auth block inside the clientOptions above will be used. + * + * If both ApiKey/Bearer token and username+password is provided, tokens + * take precedence + */ + auth?: + | { + username: string; + + /** + * @visibility secret + */ + password: string; + } + | { + /** + * Base64 Encoded API key to be used to connect to the cluster. + * See: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html + * + * @visibility secret + */ + apiKey: string; + }; }; }; } diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index b78beddc7e..f13616d60b 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", + "version": "1.4.1-next.0", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.3.13-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-elasticsearch" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-elasticsearch" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,7 +57,7 @@ "aws4": "^1.12.0", "elastic-builder": "^2.16.0", "lodash": "^4.17.21", - "uuid": "^8.3.2", + "uuid": "^9.0.0", "winston": "^3.2.1" }, "devDependencies": { @@ -62,9 +66,5 @@ "@elastic/elasticsearch-mock": "^1.0.0", "@short.io/opensearch-mock": "^0.3.1" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-elasticsearch/src/alpha.ts b/plugins/search-backend-module-elasticsearch/src/alpha.ts index f5952fbc86..0af5904df0 100644 --- a/plugins/search-backend-module-elasticsearch/src/alpha.ts +++ b/plugins/search-backend-module-elasticsearch/src/alpha.ts @@ -68,6 +68,15 @@ export default createBackendModule({ config: coreServices.rootConfig, }, async init({ searchEngineRegistry, logger, config }) { + const baseKey = 'search.elasticsearch'; + const baseConfig = config.getOptional(baseKey); + if (!baseConfig) { + logger.warn( + 'No configuration found under "search.elasticsearch" key. Skipping search engine inititalization.', + ); + return; + } + searchEngineRegistry.setSearchEngine( await ElasticSearchSearchEngine.fromConfig({ logger, diff --git a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts index 8ccbe9a4ec..f8c996df51 100644 --- a/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts +++ b/plugins/search-backend-module-elasticsearch/src/engines/ElasticSearchSearchEngine.ts @@ -18,9 +18,9 @@ import { IndexableDocument, IndexableResult, IndexableResultSet, - SearchEngine, SearchQuery, } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { isEmpty, isNumber, isNaN as nan } from 'lodash'; import { AwsSigv4Signer } from '@opensearch-project/opensearch/aws'; diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 9ae6b39868..94519f4751 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,153 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.23-next.0 + +### Patch Changes + +- ca6e2e0: Migrate search collator to use the new auth services. +- 5d99272: Update README.md to point to explore plugin in community-plugins repository. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.21 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/backend-tasks@0.5.20 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.18 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-explore-common@0.0.2 + +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.17-next.0 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-explore-common@0.0.2 + +## 0.1.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-explore-common@0.0.2 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.14-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-explore/README.md b/plugins/search-backend-module-explore/README.md index 5bccf8c737..b2d6ff8758 100644 --- a/plugins/search-backend-module-explore/README.md +++ b/plugins/search-backend-module-explore/README.md @@ -1,6 +1,6 @@ # search-backend-module-explore -This package exports a module that extends the search backend to also indexing the tools exposed by the [`explore` service](https://github.com/backstage/backstage/tree/master/plugins/explore-backend). +This package exports a module that extends the search backend to also indexing the tools exposed by the [`explore` service](https://github.com/backstage/community-plugins/tree/main/workspaces/explore/plugins/explore-backend). ## Installation diff --git a/plugins/search-backend-module-explore/api-report.md b/plugins/search-backend-module-explore/api-report.md index 50cda184a9..c881de9fad 100644 --- a/plugins/search-backend-module-explore/api-report.md +++ b/plugins/search-backend-module-explore/api-report.md @@ -5,11 +5,12 @@ ```ts /// +import { AuthService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { ExploreTool } from '@backstage/plugin-explore-common'; +import { ExploreTool } from '@backstage-community/plugin-explore-common'; import { IndexableDocument } from '@backstage/plugin-search-common'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { Readable } from 'stream'; import { TokenManager } from '@backstage/backend-common'; @@ -35,7 +36,8 @@ export class ToolDocumentCollatorFactory implements DocumentCollatorFactory { // @public export type ToolDocumentCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; - logger: Logger; + logger: LoggerService; tokenManager?: TokenManager; + auth?: AuthService; }; ``` diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 2676a6ca00..612e42df10 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-explore", + "version": "0.1.23-next.0", "description": "A module for the search backend that exports explore modules", - "version": "0.1.14-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-explore" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,43 +32,33 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-explore" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { + "@backstage-community/plugin-explore-common": "^0.0.3", "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-tasks": "workspace:^", "@backstage/config": "workspace:^", - "@backstage/plugin-explore-common": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", - "node-fetch": "^2.6.7", - "winston": "^3.2.1" + "node-fetch": "^2.6.7" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "msw": "^1.2.1" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-explore/src/alpha.ts b/plugins/search-backend-module-explore/src/alpha.ts index 858be9220a..21c5901885 100644 --- a/plugins/search-backend-module-explore/src/alpha.ts +++ b/plugins/search-backend-module-explore/src/alpha.ts @@ -23,7 +23,6 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha'; import { ToolDocumentCollatorFactory } from '@backstage/plugin-search-backend-module-explore'; @@ -45,6 +44,7 @@ export default createBackendModule({ discovery: coreServices.discovery, scheduler: coreServices.scheduler, tokenManager: coreServices.tokenManager, + auth: coreServices.auth, indexRegistry: searchIndexRegistryExtensionPoint, }, async init({ @@ -52,8 +52,9 @@ export default createBackendModule({ logger, discovery, scheduler, - indexRegistry, tokenManager, + auth, + indexRegistry, }) { const defaultSchedule = { frequency: { minutes: 10 }, @@ -71,7 +72,8 @@ export default createBackendModule({ schedule: scheduler.createScheduledTaskRunner(schedule), factory: ToolDocumentCollatorFactory.fromConfig(config, { discovery, - logger: loggerToWinstonLogger(logger), + logger, + auth, tokenManager, }), }); diff --git a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts index bf6f07839b..3a2f73c628 100644 --- a/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts +++ b/plugins/search-backend-module-explore/src/collators/ToolDocumentCollatorFactory.ts @@ -15,18 +15,19 @@ */ import { + createLegacyAuthAdapters, PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; +import { AuthService, LoggerService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; -import { ExploreTool } from '@backstage/plugin-explore-common'; +import { ExploreTool } from '@backstage-community/plugin-explore-common'; import { DocumentCollatorFactory, IndexableDocument, } from '@backstage/plugin-search-common'; import fetch from 'node-fetch'; import { Readable } from 'stream'; -import { Logger } from 'winston'; /** * Extended IndexableDocument with explore tool specific properties @@ -42,8 +43,9 @@ export interface ToolDocument extends IndexableDocument, ExploreTool {} */ export type ToolDocumentCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; - logger: Logger; + logger: LoggerService; tokenManager?: TokenManager; + auth?: AuthService; }; /** @@ -55,13 +57,14 @@ export class ToolDocumentCollatorFactory implements DocumentCollatorFactory { public readonly type: string = 'tools'; private readonly discovery: PluginEndpointDiscovery; - private readonly logger: Logger; - private readonly tokenManager?: TokenManager; + private readonly logger: LoggerService; + private readonly auth: AuthService; private constructor(options: ToolDocumentCollatorFactoryOptions) { this.discovery = options.discovery; this.logger = options.logger; - this.tokenManager = options.tokenManager; + + this.auth = createLegacyAuthAdapters(options).auth; } static fromConfig( @@ -94,16 +97,13 @@ export class ToolDocumentCollatorFactory implements DocumentCollatorFactory { private async fetchTools() { const baseUrl = await this.discovery.getBaseUrl('explore'); - let headers = {}; - - if (this.tokenManager) { - const { token } = await this.tokenManager.getToken(); - headers = { - Authorization: `Bearer ${token}`, - }; - } - - const response = await fetch(`${baseUrl}/tools`, headers); + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'explore', + }); + const response = await fetch(`${baseUrl}/tools`, { + headers: { Authorization: `Bearer ${token}` }, + }); if (!response.ok) { throw new Error( diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index dcebfbb4b3..74e9bc9a1a 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,136 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.5.26 + +### Patch Changes + +- cf163a5: Enable module only on supported databases + + Also pass logger to the service + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.5.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.5.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.5.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.5.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.5.23 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-backend-node@1.2.18 + +## 0.5.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.5.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.5.22-next.0 + +### Patch Changes + +- 744c0cb: Start importing `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` from the `@backstage/plugin-search-backend-node`. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + +## 0.5.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 0.5.19-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-pg/api-report.md b/plugins/search-backend-module-pg/api-report.md index 3c6096090e..21f2d7737d 100644 --- a/plugins/search-backend-module-pg/api-report.md +++ b/plugins/search-backend-module-pg/api-report.md @@ -10,7 +10,7 @@ import { IndexableResultSet } from '@backstage/plugin-search-common'; import { Knex } from 'knex'; import { Logger } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { SearchQuery } from '@backstage/plugin-search-common'; // @public diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 53f74586f4..3666e85273 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-pg", + "version": "0.5.27-next.0", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.5.19-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-pg" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,19 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-pg" - }, + "files": [ + "dist", + "migrations", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -49,17 +54,12 @@ "@backstage/plugin-search-common": "workspace:^", "knex": "^3.0.0", "lodash": "^4.17.21", - "uuid": "^8.3.2", + "uuid": "^9.0.0", "winston": "^3.2.1" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" }, - "files": [ - "dist", - "migrations", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts index 1a27b9f981..b6513a0a97 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts @@ -15,7 +15,7 @@ */ import { PluginDatabaseManager } from '@backstage/backend-common'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { SearchQuery, IndexableResultSet, diff --git a/plugins/search-backend-module-pg/src/alpha.ts b/plugins/search-backend-module-pg/src/alpha.ts index 4628b300f2..902e8c3ad2 100644 --- a/plugins/search-backend-module-pg/src/alpha.ts +++ b/plugins/search-backend-module-pg/src/alpha.ts @@ -19,6 +19,7 @@ import { } from '@backstage/backend-plugin-api'; import { searchEngineRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha'; import { PgSearchEngine } from './PgSearchEngine'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; /** * @alpha @@ -33,13 +34,21 @@ export default createBackendModule({ searchEngineRegistry: searchEngineRegistryExtensionPoint, database: coreServices.database, config: coreServices.rootConfig, + logger: coreServices.logger, }, - async init({ searchEngineRegistry, database, config }) { - searchEngineRegistry.setSearchEngine( - await PgSearchEngine.fromConfig(config, { - database: database, - }), - ); + async init({ searchEngineRegistry, database, config, logger }) { + if (await PgSearchEngine.supported(database)) { + searchEngineRegistry.setSearchEngine( + await PgSearchEngine.fromConfig(config, { + database, + logger: loggerToWinstonLogger(logger), + }), + ); + } else { + logger.warn( + 'Postgres search engine is not supported, skipping registration of search-backend-module-pg', + ); + } }, }); }, diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 3b8a785914..80447b1b78 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,140 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.10 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/backend-tasks@0.5.20 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + +## 0.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/config@1.1.2-next.0 + +## 0.1.3 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8472188: Added or fixed the `repository` field in `package.json`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.3-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-stack-overflow-collator/api-report.md b/plugins/search-backend-module-stack-overflow-collator/api-report.md index 9243e786ac..d70b5f79fd 100644 --- a/plugins/search-backend-module-stack-overflow-collator/api-report.md +++ b/plugins/search-backend-module-stack-overflow-collator/api-report.md @@ -9,7 +9,7 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { IndexableDocument } from '@backstage/plugin-search-common'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { Readable } from 'stream'; // @public @@ -51,7 +51,7 @@ export type StackOverflowQuestionsCollatorFactoryOptions = { apiAccessToken?: string; teamName?: string; requestParams?: StackOverflowQuestionsRequestParams; - logger: Logger; + logger: LoggerService; }; // @public diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index 65a83290c2..ed9ff057aa 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,32 +1,36 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", + "version": "0.1.11-next.0", "description": "A module for the search backend that exports stack overflow modules", - "version": "0.1.3-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "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/search-backend-module-stack-overflow-collator" }, + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -36,17 +40,12 @@ "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "node-fetch": "^2.6.7", - "qs": "^6.9.4", - "winston": "^3.2.1" + "qs": "^6.9.4" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "msw": "^1.2.1" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts index 3c97937365..2a81d7c749 100644 --- a/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts +++ b/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts @@ -15,14 +15,14 @@ */ import { - IndexableDocument, DocumentCollatorFactory, + IndexableDocument, } from '@backstage/plugin-search-common'; import { Config } from '@backstage/config'; import { Readable } from 'stream'; import fetch from 'node-fetch'; import qs from 'qs'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** * Extended IndexableDocument with stack overflow specific properties @@ -55,7 +55,7 @@ export type StackOverflowQuestionsCollatorFactoryOptions = { apiAccessToken?: string; teamName?: string; requestParams?: StackOverflowQuestionsRequestParams; - logger: Logger; + logger: LoggerService; }; /** @@ -72,7 +72,7 @@ export class StackOverflowQuestionsCollatorFactory private readonly apiAccessToken: string | undefined; private readonly teamName: string | undefined; private readonly maxPage: number | undefined; - private readonly logger: Logger; + private readonly logger: LoggerService; public readonly type: string = 'stack-overflow'; private constructor(options: StackOverflowQuestionsCollatorFactoryOptions) { diff --git a/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.ts b/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.ts index a8a0b266ba..bb35b3a766 100644 --- a/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.ts +++ b/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { readTaskScheduleDefinitionFromConfig } from '@backstage/backend-tasks'; import { coreServices, @@ -55,7 +54,7 @@ export const searchStackOverflowCollatorModule = createBackendModule({ indexRegistry.addCollator({ schedule: scheduler.createScheduledTaskRunner(schedule), factory: StackOverflowQuestionsCollatorFactory.fromConfig(config, { - logger: loggerToWinstonLogger(logger), + logger, }), }); }, diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index 5f231e392d..aeb6999a3c 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,214 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-catalog-node@1.11.2-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.22 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-tasks@0.5.22 + - @backstage/catalog-client@1.6.4 + - @backstage/plugin-catalog-node@1.11.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-catalog-node@1.11.1-next.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.11.0 + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.10.0 + - @backstage/catalog-client@1.6.2 + - @backstage/backend-common@0.21.5 + - @backstage/plugin-techdocs-node@1.12.1 + - @backstage/backend-tasks@0.5.20 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.9.0 + +## 0.1.18 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-catalog-node@1.8.0 + - @backstage/catalog-client@1.6.1 + - @backstage/backend-tasks@0.5.19 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## 0.1.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-catalog-node@1.8.0-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-catalog-node@1.8.0-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 0.1.17-next.0 + +### Patch Changes + +- bb368a5: Migrated to support new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/plugin-catalog-node@1.8.0-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## 0.1.14 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/catalog-model@1.4.4 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/plugin-catalog-node@1.7.0 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + ## 0.1.14-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/api-report.md b/plugins/search-backend-module-techdocs/api-report.md index 592cf5065a..fbdecef2a8 100644 --- a/plugins/search-backend-module-techdocs/api-report.md +++ b/plugins/search-backend-module-techdocs/api-report.md @@ -5,11 +5,13 @@ ```ts /// +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { Entity } from '@backstage/catalog-model'; -import { Logger } from 'winston'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { Permission } from '@backstage/plugin-permission-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { Readable } from 'stream'; @@ -42,8 +44,10 @@ export type TechDocsCollatorEntityTransformer = ( // @public export type TechDocsCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; - logger: Logger; + logger: LoggerService; tokenManager: TokenManager; + auth?: AuthService; + httpAuth?: HttpAuthService; locationTemplate?: string; catalogClient?: CatalogApi; parallelismLimit?: number; diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index ebb2d399fa..1dea62aa74 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", + "version": "0.1.23-next.0", "description": "A module for the search backend that exports techdocs modules", - "version": "0.1.14-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin-module" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-module-techdocs" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,18 @@ ] } }, - "backstage": { - "role": "backend-plugin-module" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-module-techdocs" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -56,17 +60,12 @@ "@backstage/plugin-techdocs-node": "workspace:^", "lodash": "^4.17.21", "node-fetch": "^2.6.7", - "p-limit": "^3.1.0", - "winston": "^3.2.1" + "p-limit": "^3.1.0" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "msw": "^1.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend-module-techdocs/src/alpha.ts b/plugins/search-backend-module-techdocs/src/alpha.ts index e8be7cc864..fb4d4004ec 100644 --- a/plugins/search-backend-module-techdocs/src/alpha.ts +++ b/plugins/search-backend-module-techdocs/src/alpha.ts @@ -19,7 +19,6 @@ * A module for the search backend that exports TechDocs modules. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendModule, @@ -27,9 +26,11 @@ import { } from '@backstage/backend-plugin-api'; import { readTaskScheduleDefinitionFromConfig } from '@backstage/backend-tasks'; import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; -import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-search-backend-module-techdocs'; +import { + DefaultTechDocsCollatorFactory, + TechDocsCollatorEntityTransformer, +} from '@backstage/plugin-search-backend-module-techdocs'; import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha'; -import { TechDocsCollatorEntityTransformer } from '@backstage/plugin-search-backend-module-techdocs'; /** @alpha */ export interface TechDocsCollatorEntityTransformerExtensionPoint { @@ -74,6 +75,8 @@ export default createBackendModule({ deps: { config: coreServices.rootConfig, logger: coreServices.logger, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, discovery: coreServices.discovery, tokenManager: coreServices.tokenManager, scheduler: coreServices.scheduler, @@ -83,6 +86,8 @@ export default createBackendModule({ async init({ config, logger, + auth, + httpAuth, discovery, tokenManager, scheduler, @@ -106,7 +111,9 @@ export default createBackendModule({ factory: DefaultTechDocsCollatorFactory.fromConfig(config, { discovery, tokenManager, - logger: loggerToWinstonLogger(logger), + auth, + httpAuth, + logger, catalogClient: catalog, entityTransformer: transformer, }), diff --git a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts index b76fedbdf9..ad820e6ad2 100644 --- a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts +++ b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts @@ -15,13 +15,14 @@ */ import { + createLegacyAuthAdapters, PluginEndpointDiscovery, TokenManager, } from '@backstage/backend-common'; import { + CATALOG_FILTER_EXISTS, CatalogApi, CatalogClient, - CATALOG_FILTER_EXISTS, } from '@backstage/catalog-client'; import { Entity, @@ -38,9 +39,13 @@ import unescape from 'lodash/unescape'; import fetch from 'node-fetch'; import pLimit from 'p-limit'; import { Readable } from 'stream'; -import { Logger } from 'winston'; import { TechDocsCollatorEntityTransformer } from './TechDocsCollatorEntityTransformer'; import { defaultTechDocsCollatorEntityTransformer } from './defaultTechDocsCollatorEntityTransformer'; +import { + AuthService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; interface MkSearchIndexDoc { title: string; @@ -55,8 +60,10 @@ interface MkSearchIndexDoc { */ export type TechDocsCollatorFactoryOptions = { discovery: PluginEndpointDiscovery; - logger: Logger; + logger: LoggerService; tokenManager: TokenManager; + auth?: AuthService; + httpAuth?: HttpAuthService; locationTemplate?: string; catalogClient?: CatalogApi; parallelismLimit?: number; @@ -83,9 +90,9 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { private discovery: PluginEndpointDiscovery; private locationTemplate: string; - private readonly logger: Logger; + private readonly logger: LoggerService; + private readonly auth: AuthService; private readonly catalogClient: CatalogApi; - private readonly tokenManager: TokenManager; private readonly parallelismLimit: number; private readonly legacyPathCasing: boolean; private entityTransformer: TechDocsCollatorEntityTransformer; @@ -100,9 +107,14 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { new CatalogClient({ discoveryApi: options.discovery }); this.parallelismLimit = options.parallelismLimit ?? 10; this.legacyPathCasing = options.legacyPathCasing ?? false; - this.tokenManager = options.tokenManager; this.entityTransformer = options.entityTransformer ?? defaultTechDocsCollatorEntityTransformer; + + this.auth = createLegacyAuthAdapters({ + auth: options.auth, + discovery: options.discovery, + tokenManager: options.tokenManager, + }).auth; } static fromConfig(config: Config, options: TechDocsCollatorFactoryOptions) { @@ -131,7 +143,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { private async *execute(): AsyncGenerator { const limit = pLimit(this.parallelismLimit); const techDocsBaseUrl = await this.discovery.getBaseUrl('techdocs'); - const { token } = await this.tokenManager.getToken(); + let entitiesRetrieved = 0; let moreEntitiesToGet = true; @@ -141,6 +153,11 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { // parallelism limit to simplify configuration. const batchSize = this.parallelismLimit * 50; while (moreEntitiesToGet) { + const { token: catalogToken } = await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'catalog', + }); + const entities = ( await this.catalogClient.getEntities( { @@ -151,7 +168,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { limit: batchSize, offset: entitiesRetrieved, }, - { token }, + { token: catalogToken }, ) ).items; @@ -174,6 +191,12 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { ); try { + const { token: techdocsToken } = + await this.auth.getPluginRequestToken({ + onBehalfOf: await this.auth.getOwnServiceCredentials(), + targetPluginId: 'techdocs', + }); + const searchIndexResponse = await fetch( DefaultTechDocsCollatorFactory.constructDocsIndexUrl( techDocsBaseUrl, @@ -181,7 +204,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { ), { headers: { - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${techdocsToken}`, }, }, ); diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 575fe99c53..9e79ded222 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,156 @@ # @backstage/plugin-search-backend-node +## 1.2.22-next.0 + +### Patch Changes + +- c6cb568: Add lifecycle monitoring for the search index registry +- Updated dependencies + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/backend-tasks@0.5.23-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.2.21 + +### Patch Changes + +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/backend-tasks@0.5.22 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/backend-tasks@0.5.22-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/backend-tasks@0.5.22-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/backend-tasks@0.5.21 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/backend-tasks@0.5.20 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.2.18 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 744c0cb: Exports `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` types. These new types were extracted from the `@backstage/plugin-search-common` package and the `token` property was deprecated in favor of the a new credentials one. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-tasks@0.5.19 + +## 1.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/backend-tasks@0.5.19-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/backend-tasks@0.5.19-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.2.17-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 744c0cb: Exports `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` types. These new types were extracted from the `@backstage/plugin-search-common` package and the `token` property was deprecated in favor of the a new credentials one. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-tasks@0.5.18-next.0 + - @backstage/config@1.1.2-next.0 + +## 1.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-tasks@0.5.15 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + ## 1.2.14-next.3 ### Patch Changes diff --git a/plugins/search-backend-node/api-report-alpha.md b/plugins/search-backend-node/api-report-alpha.md index 74b7a4b4bc..8e35e70f65 100644 --- a/plugins/search-backend-node/api-report-alpha.md +++ b/plugins/search-backend-node/api-report-alpha.md @@ -7,7 +7,7 @@ import { DocumentTypeInfo } from '@backstage/plugin-search-common'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { RegisterCollatorParameters } from '@backstage/plugin-search-backend-node'; import { RegisterDecoratorParameters } from '@backstage/plugin-search-backend-node'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { ServiceRef } from '@backstage/backend-plugin-api'; // @alpha @@ -34,6 +34,7 @@ export const searchIndexRegistryExtensionPoint: ExtensionPoint; start(options: SearchIndexServiceStartOptions): Promise; + stop(): Promise; } // @alpha diff --git a/plugins/search-backend-node/api-report.md b/plugins/search-backend-node/api-report.md index 734bf6e1c0..5e8961a65e 100644 --- a/plugins/search-backend-node/api-report.md +++ b/plugins/search-backend-node/api-report.md @@ -5,18 +5,17 @@ ```ts /// +import { BackstageCredentials } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { DocumentDecoratorFactory } from '@backstage/plugin-search-common'; import { DocumentTypeInfo } from '@backstage/plugin-search-common'; import { IndexableDocument } from '@backstage/plugin-search-common'; import { IndexableResultSet } from '@backstage/plugin-search-common'; -import { Logger } from 'winston'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { default as lunr_2 } from 'lunr'; import { Permission } from '@backstage/plugin-permission-common'; -import { QueryTranslator } from '@backstage/plugin-search-common'; import { Readable } from 'stream'; -import { SearchEngine } from '@backstage/plugin-search-common'; import { SearchQuery } from '@backstage/plugin-search-common'; import { TaskFunction } from '@backstage/backend-tasks'; import { TaskRunner } from '@backstage/backend-tasks'; @@ -69,7 +68,7 @@ export class IndexBuilder { // @public export type IndexBuilderOptions = { searchEngine: SearchEngine; - logger: Logger; + logger: LoggerService; }; // @public @@ -77,7 +76,7 @@ export type LunrQueryTranslator = (query: SearchQuery) => ConcreteLunrQuery; // @public export class LunrSearchEngine implements SearchEngine { - constructor(options: { logger: Logger }); + constructor(options: { logger: LoggerService }); // (undocumented) protected docStore: Record; // (undocumented) @@ -87,7 +86,7 @@ export class LunrSearchEngine implements SearchEngine { // (undocumented) protected highlightPreTag: string; // (undocumented) - protected logger: Logger; + protected logger: LoggerService; // (undocumented) protected lunrIndices: Record; // (undocumented) @@ -140,10 +139,22 @@ export type NewlineDelimitedJsonCollatorFactoryOptions = { type: string; searchPattern: string; reader: UrlReader; - logger: Logger; + logger: LoggerService; visibilityPermission?: Permission; }; +// @public +export type QueryRequestOptions = + | { + token?: string; + } + | { + credentials: BackstageCredentials; + }; + +// @public +export type QueryTranslator = (query: SearchQuery) => unknown; + // @public export interface RegisterCollatorParameters { factory: DocumentCollatorFactory; @@ -157,7 +168,7 @@ export interface RegisterDecoratorParameters { // @public export class Scheduler { - constructor(options: { logger: Logger }); + constructor(options: { logger: LoggerService }); addToSchedule(options: ScheduleTaskParameters): void; start(): void; stop(): void; @@ -170,6 +181,16 @@ export type ScheduleTaskParameters = { scheduledRunner: TaskRunner; }; +// @public +export interface SearchEngine { + getIndexer(type: string): Promise; + query( + query: SearchQuery, + options?: QueryRequestOptions, + ): Promise; + setTranslator(translator: QueryTranslator): void; +} + // @public export class TestPipeline { execute(): Promise; diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index e4b996cb0d..ac59d7eab2 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend-node", + "version": "1.2.22-next.0", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.2.14-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend-node" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,23 +32,17 @@ ] } }, - "backstage": { - "role": "node-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend-node" - }, + "files": [ + "dist" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -53,15 +56,11 @@ "lodash": "^4.17.21", "lunr": "^2.3.9", "ndjson": "^2.0.0", - "uuid": "^8.3.2", - "winston": "^3.2.1" + "uuid": "^9.0.0" }, "devDependencies": { "@backstage/backend-common": "workspace:^", "@backstage/cli": "workspace:^", "@types/ndjson": "^2.0.1" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/search-backend-node/src/IndexBuilder.test.ts b/plugins/search-backend-node/src/IndexBuilder.test.ts index 4a2760dde1..70d00f6974 100644 --- a/plugins/search-backend-node/src/IndexBuilder.test.ts +++ b/plugins/search-backend-node/src/IndexBuilder.test.ts @@ -19,11 +19,10 @@ import { TaskInvocationDefinition, TaskRunner } from '@backstage/backend-tasks'; import { DocumentCollatorFactory, DocumentDecoratorFactory, - SearchEngine, } from '@backstage/plugin-search-common'; import { Readable, Transform } from 'stream'; import { IndexBuilder } from './IndexBuilder'; -import { LunrSearchEngine } from './index'; +import { LunrSearchEngine, SearchEngine } from './index'; class TestDocumentCollatorFactory implements DocumentCollatorFactory { readonly type: string = 'anything'; diff --git a/plugins/search-backend-node/src/IndexBuilder.ts b/plugins/search-backend-node/src/IndexBuilder.ts index 907519f289..6f29e4de57 100644 --- a/plugins/search-backend-node/src/IndexBuilder.ts +++ b/plugins/search-backend-node/src/IndexBuilder.ts @@ -17,16 +17,16 @@ import { DocumentDecoratorFactory, DocumentTypeInfo, - SearchEngine, } from '@backstage/plugin-search-common'; -import { Transform, pipeline } from 'stream'; -import { Logger } from 'winston'; +import { pipeline, Transform } from 'stream'; import { Scheduler } from './Scheduler'; import { IndexBuilderOptions, RegisterCollatorParameters, RegisterDecoratorParameters, + SearchEngine, } from './types'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** * Used for adding collators, decorators and compile them into tasks which are added to a scheduler returned to the caller. @@ -37,7 +37,7 @@ export class IndexBuilder { private decorators: Record; private documentTypes: Record; private searchEngine: SearchEngine; - private logger: Logger; + private logger: LoggerService; constructor(options: IndexBuilderOptions) { this.collators = {}; diff --git a/plugins/search-backend-node/src/Scheduler.ts b/plugins/search-backend-node/src/Scheduler.ts index 39c423263c..7775db086c 100644 --- a/plugins/search-backend-node/src/Scheduler.ts +++ b/plugins/search-backend-node/src/Scheduler.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import { Logger } from 'winston'; import { TaskFunction, TaskRunner } from '@backstage/backend-tasks'; +import { LoggerService } from '@backstage/backend-plugin-api'; type TaskEnvelope = { task: TaskFunction; @@ -37,12 +37,12 @@ export type ScheduleTaskParameters = { * @public */ export class Scheduler { - private logger: Logger; + private logger: LoggerService; private schedule: { [id: string]: TaskEnvelope }; private abortControllers: AbortController[]; private isRunning: boolean; - constructor(options: { logger: Logger }) { + constructor(options: { logger: LoggerService }) { this.logger = options.logger; this.schedule = {}; this.abortControllers = []; diff --git a/plugins/search-backend-node/src/alpha.ts b/plugins/search-backend-node/src/alpha.ts index 943e11b580..331f0ae304 100644 --- a/plugins/search-backend-node/src/alpha.ts +++ b/plugins/search-backend-node/src/alpha.ts @@ -14,27 +14,22 @@ * limitations under the License. */ -import { Logger } from 'winston'; - import { - createServiceRef, - createServiceFactory, coreServices, + createExtensionPoint, + createServiceFactory, + createServiceRef, + LoggerService, } from '@backstage/backend-plugin-api'; -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - DocumentTypeInfo, - SearchEngine, -} from '@backstage/plugin-search-common'; -import { createExtensionPoint } from '@backstage/backend-plugin-api'; - +import { DocumentTypeInfo } from '@backstage/plugin-search-common'; import { + IndexBuilder, RegisterCollatorParameters, RegisterDecoratorParameters, + Scheduler, + SearchEngine, } from '@backstage/plugin-search-backend-node'; -import { IndexBuilder } from './IndexBuilder'; - /** * @alpha * Options for build method on {@link SearchIndexService}. @@ -54,6 +49,11 @@ export interface SearchIndexService { * Starts indexing process */ start(options: SearchIndexServiceStartOptions): Promise; + + /** + * Stops indexing process + */ + stop(): Promise; /** * Returns an index types list. */ @@ -78,7 +78,7 @@ export interface SearchEngineRegistryExtensionPoint { } type DefaultSearchIndexServiceOptions = { - logger: Logger; + logger: LoggerService; }; /** @@ -86,8 +86,9 @@ type DefaultSearchIndexServiceOptions = { * Reponsible for register the indexing task and start the schedule. */ class DefaultSearchIndexService implements SearchIndexService { - private logger: Logger; + private readonly logger: LoggerService; private indexBuilder: IndexBuilder | null = null; + private scheduler: Scheduler | null = null; private constructor(options: DefaultSearchIndexServiceOptions) { this.logger = options.logger; @@ -112,7 +113,15 @@ class DefaultSearchIndexService implements SearchIndexService { ); const { scheduler } = await this.indexBuilder?.build(); - scheduler.start(); + this.scheduler = scheduler; + this.scheduler!.start(); + } + + async stop(): Promise { + if (this.scheduler) { + this.scheduler.stop(); + this.scheduler = null; + } } getDocumentTypes(): Record { @@ -134,7 +143,7 @@ export const searchIndexServiceRef = createServiceRef({ }, factory({ logger }) { return DefaultSearchIndexService.fromConfig({ - logger: loggerToWinstonLogger(logger), + logger, }); }, }), diff --git a/plugins/search-backend-node/src/collators/NewlineDelimitedJsonCollatorFactory.ts b/plugins/search-backend-node/src/collators/NewlineDelimitedJsonCollatorFactory.ts index de77f5ba7a..e7d749dd41 100644 --- a/plugins/search-backend-node/src/collators/NewlineDelimitedJsonCollatorFactory.ts +++ b/plugins/search-backend-node/src/collators/NewlineDelimitedJsonCollatorFactory.ts @@ -16,11 +16,11 @@ import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { Logger } from 'winston'; import { Permission } from '@backstage/plugin-permission-common'; import { Readable } from 'stream'; import { UrlReader } from '@backstage/backend-common'; import { parse as parseNdjson } from 'ndjson'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** * Options for instantiate NewlineDelimitedJsonCollatorFactory @@ -30,7 +30,7 @@ export type NewlineDelimitedJsonCollatorFactoryOptions = { type: string; searchPattern: string; reader: UrlReader; - logger: Logger; + logger: LoggerService; visibilityPermission?: Permission; }; @@ -74,7 +74,7 @@ export class NewlineDelimitedJsonCollatorFactory type: string, private readonly searchPattern: string, private readonly reader: UrlReader, - private readonly logger: Logger, + private readonly logger: LoggerService, visibilityPermission: Permission | undefined, ) { this.type = type; diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts index 55c18cd6fc..e5347b3cb1 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.test.ts @@ -16,10 +16,7 @@ import { getVoidLogger } from '@backstage/backend-common'; import lunr from 'lunr'; -import { - IndexableDocument, - SearchEngine, -} from '@backstage/plugin-search-common'; +import { IndexableDocument } from '@backstage/plugin-search-common'; import { ConcreteLunrQuery, LunrSearchEngine, @@ -28,6 +25,7 @@ import { parseHighlightFields, } from './LunrSearchEngine'; import { LunrSearchEngineIndexer } from './LunrSearchEngineIndexer'; +import { SearchEngine } from '../types'; import { TestPipeline } from '../test-utils'; /** diff --git a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts index 27cfae3fdf..1786d07a9d 100644 --- a/plugins/search-backend-node/src/engines/LunrSearchEngine.ts +++ b/plugins/search-backend-node/src/engines/LunrSearchEngine.ts @@ -18,14 +18,13 @@ import { IndexableDocument, IndexableResultSet, SearchQuery, - QueryTranslator, - SearchEngine, } from '@backstage/plugin-search-common'; +import { QueryTranslator, SearchEngine } from '../types'; import { MissingIndexError } from '../errors'; import lunr from 'lunr'; import { v4 as uuid } from 'uuid'; -import { Logger } from 'winston'; import { LunrSearchEngineIndexer } from './LunrSearchEngineIndexer'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** * Type of translated query for the Lunr Search Engine. @@ -55,11 +54,11 @@ export type LunrQueryTranslator = (query: SearchQuery) => ConcreteLunrQuery; export class LunrSearchEngine implements SearchEngine { protected lunrIndices: Record = {}; protected docStore: Record; - protected logger: Logger; + protected logger: LoggerService; protected highlightPreTag: string; protected highlightPostTag: string; - constructor(options: { logger: Logger }) { + constructor(options: { logger: LoggerService }) { this.logger = options.logger; this.docStore = {}; const uuidTag = uuid(); diff --git a/plugins/search-backend-node/src/index.ts b/plugins/search-backend-node/src/index.ts index a188509c1c..78e4880305 100644 --- a/plugins/search-backend-node/src/index.ts +++ b/plugins/search-backend-node/src/index.ts @@ -33,6 +33,9 @@ export type { IndexBuilderOptions, RegisterCollatorParameters, RegisterDecoratorParameters, + SearchEngine, + QueryRequestOptions, + QueryTranslator, } from './types'; export * from './errors'; export * from './indexing'; diff --git a/plugins/search-backend-node/src/types.ts b/plugins/search-backend-node/src/types.ts index dfcf4d12ce..18853d1069 100644 --- a/plugins/search-backend-node/src/types.ts +++ b/plugins/search-backend-node/src/types.ts @@ -14,13 +14,18 @@ * limitations under the License. */ +import { + BackstageCredentials, + LoggerService, +} from '@backstage/backend-plugin-api'; import { TaskRunner } from '@backstage/backend-tasks'; import { DocumentCollatorFactory, DocumentDecoratorFactory, - SearchEngine, + IndexableResultSet, + SearchQuery, } from '@backstage/plugin-search-common'; -import { Logger } from 'winston'; +import { Writable } from 'stream'; /** * Options required to instantiate the index builder. @@ -28,7 +33,7 @@ import { Logger } from 'winston'; */ export type IndexBuilderOptions = { searchEngine: SearchEngine; - logger: Logger; + logger: LoggerService; }; /** @@ -57,3 +62,55 @@ export interface RegisterDecoratorParameters { */ factory: DocumentDecoratorFactory; } + +/** + * A type of function responsible for translating an abstract search query into + * a concrete query relevant to a particular search engine. + * @public + */ +export type QueryTranslator = (query: SearchQuery) => unknown; + +/** + * Options when querying a search engine. + * @public + */ +export type QueryRequestOptions = + | { + /** @deprecated use the `credentials` option instead. */ + token?: string; + } + | { + credentials: BackstageCredentials; + }; + +/** + * Interface that must be implemented by specific search engines, responsible + * for performing indexing and querying and translating abstract queries into + * concrete, search engine-specific queries. + * @public + */ +export interface SearchEngine { + /** + * Override the default translator provided by the SearchEngine. + */ + setTranslator(translator: QueryTranslator): void; + + /** + * Factory method for getting a search engine indexer for a given document + * type. + * + * @param type - The type or name of the document set for which an indexer + * should be retrieved. This corresponds to the `type` property on the + * document collator/decorator factories and will most often be used to + * identify an index or group to which documents should be written. + */ + getIndexer(type: string): Promise; + + /** + * Perform a search query against the SearchEngine. + */ + query( + query: SearchQuery, + options?: QueryRequestOptions, + ): Promise; +} diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index c5f0745734..f064499e07 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,201 @@ # @backstage/plugin-search-backend +## 1.5.8-next.0 + +### Patch Changes + +- c6cb568: Add lifecycle monitoring for the search index registry +- Updated dependencies + - @backstage/plugin-search-backend-node@1.2.22-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/repo-tools@0.8.1-next.0 + - @backstage/backend-openapi-utils@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.29-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.5.7 + +### Patch Changes + +- 2bd291e: Allow reserved characters in requests. +- d5a1fe1: Replaced winston logger with `LoggerService` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/repo-tools@0.8.0 + - @backstage/plugin-permission-node@0.7.28 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-node@1.2.21 + - @backstage/backend-openapi-utils@0.1.10 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.5.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/repo-tools@0.8.0-next.1 + - @backstage/plugin-permission-node@0.7.28-next.1 + - @backstage/plugin-search-backend-node@1.2.21-next.1 + - @backstage/backend-openapi-utils@0.1.10-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/repo-tools@0.8.0-next.0 + - @backstage/backend-openapi-utils@0.1.10-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-permission-node@0.7.28-next.0 + - @backstage/plugin-search-backend-node@1.2.21-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-permission-node@0.7.27 + - @backstage/plugin-search-backend-node@1.2.20 + - @backstage/backend-openapi-utils@0.1.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-permission-node@0.7.26 + - @backstage/plugin-search-backend-node@1.2.19 + - @backstage/backend-openapi-utils@0.1.8 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + +## 1.5.4 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- 744c0cb: Update the router to use the new `auth` services, it now accepts an optional discovery service option to get credentials for the permission service. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-common@1.2.11 + - @backstage/backend-openapi-utils@0.1.7 + - @backstage/plugin-search-backend-node@1.2.18 + - @backstage/plugin-permission-node@0.7.25 + - @backstage/types@1.1.1 + +## 1.5.4-next.2 + +### Patch Changes + +- 2bd1410: Removed unused dependencies +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-openapi-utils@0.1.7-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.2 + - @backstage/plugin-search-backend-node@1.2.18-next.2 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-permission-node@0.7.25-next.1 + - @backstage/plugin-search-backend-node@1.2.18-next.1 + - @backstage/backend-openapi-utils@0.1.7-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.5.3-next.0 + +### Patch Changes + +- 744c0cb: Update the router to use the new `auth` services, it now accepts an optional discovery service option to get credentials for the permission service. +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/backend-openapi-utils@0.1.6-next.0 + - @backstage/plugin-search-backend-node@1.2.17-next.0 + - @backstage/plugin-permission-node@0.7.24-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## 1.5.0 + +### Minor Changes + +- 126c2f9: Updates the OpenAPI spec to use plugin as `info.title` instead of package name. +- 04907c3: Updates the OpenAPI specification title to plugin ID instead of package name. + +### Patch Changes + +- 3ed0eac: Authorized search engine now obeys query page limit +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/backend-openapi-utils@0.1.3 + - @backstage/plugin-permission-node@0.7.21 + - @backstage/plugin-search-backend-node@1.2.14 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.12 + - @backstage/plugin-search-common@1.2.10 + ## 1.5.0-next.3 ### Patch Changes diff --git a/plugins/search-backend/api-report.md b/plugins/search-backend/api-report.md index d6274d9a94..717a9dbe8b 100644 --- a/plugins/search-backend/api-report.md +++ b/plugins/search-backend/api-report.md @@ -3,13 +3,16 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { DocumentTypeInfo } from '@backstage/plugin-search-common'; import express from 'express'; -import { Logger } from 'winston'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; @@ -18,8 +21,11 @@ export function createRouter(options: RouterOptions): Promise; export type RouterOptions = { engine: SearchEngine; types: Record; + discovery?: DiscoveryService; permissions: PermissionEvaluator | PermissionAuthorizer; config: Config; - logger: Logger; + logger: LoggerService; + auth?: AuthService; + httpAuth?: HttpAuthService; }; ``` diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index e02e1e600e..34ea122db9 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,18 +1,27 @@ { "name": "@backstage/plugin-search-backend", + "version": "1.5.8-next.0", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.5.0-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,24 +32,20 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-backend" - }, + "files": [ + "dist", + "config.d.ts" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "fuzz": "backstage-repo-tools package schema openapi fuzz", + "generate": "backstage-repo-tools package schema openapi generate --server", "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", - "generate": "backstage-repo-tools package schema openapi generate --server" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -48,11 +53,11 @@ "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", - "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-search-common": "workspace:^", + "@backstage/repo-tools": "workspace:^", "@backstage/types": "workspace:^", "@types/express": "^4.17.6", "dataloader": "^2.0.0", @@ -69,9 +74,5 @@ "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/search-backend/src/alpha.ts b/plugins/search-backend/src/alpha.ts index 8a9d4498bc..a17b542903 100644 --- a/plugins/search-backend/src/alpha.ts +++ b/plugins/search-backend/src/alpha.ts @@ -18,22 +18,21 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { + LunrSearchEngine, RegisterCollatorParameters, RegisterDecoratorParameters, - LunrSearchEngine, + SearchEngine, } from '@backstage/plugin-search-backend-node'; import { - searchIndexServiceRef, - searchIndexRegistryExtensionPoint, - SearchIndexRegistryExtensionPoint, SearchEngineRegistryExtensionPoint, searchEngineRegistryExtensionPoint, + searchIndexRegistryExtensionPoint, + SearchIndexRegistryExtensionPoint, + searchIndexServiceRef, } from '@backstage/plugin-search-backend-node/alpha'; import { createRouter } from './service/router'; -import { SearchEngine } from '@backstage/plugin-search-common'; class SearchIndexRegistry implements SearchIndexRegistryExtensionPoint { private collators: RegisterCollatorParameters[] = []; @@ -94,31 +93,54 @@ export default createBackendPlugin({ deps: { logger: coreServices.logger, config: coreServices.rootConfig, + discovery: coreServices.discovery, permissions: coreServices.permissions, + auth: coreServices.auth, http: coreServices.httpRouter, + httpAuth: coreServices.httpAuth, + lifecycle: coreServices.rootLifecycle, searchIndexService: searchIndexServiceRef, }, - async init({ config, logger, permissions, http, searchIndexService }) { + async init({ + config, + logger, + discovery, + permissions, + auth, + http, + httpAuth, + lifecycle, + searchIndexService, + }) { let searchEngine = searchEngineRegistry.getSearchEngine(); if (!searchEngine) { searchEngine = new LunrSearchEngine({ - logger: loggerToWinstonLogger(logger), + logger, }); } const collators = searchIndexRegistry.getCollators(); const decorators = searchIndexRegistry.getDecorators(); - await searchIndexService.start({ - searchEngine, - collators, - decorators, + lifecycle.addStartupHook(async () => { + await searchIndexService.start({ + searchEngine: searchEngine!, + collators, + decorators, + }); + }); + + lifecycle.addShutdownHook(async () => { + await searchIndexService.stop(); }); const router = await createRouter({ config, + discovery, permissions, - logger: loggerToWinstonLogger(logger), + auth, + httpAuth, + logger, engine: searchEngine, types: searchIndexService.getDocumentTypes(), }); diff --git a/plugins/search-backend/src/schema/openapi.generated.ts b/plugins/search-backend/src/schema/openapi.generated.ts index 06b576ba70..8ad27546d6 100644 --- a/plugins/search-backend/src/schema/openapi.generated.ts +++ b/plugins/search-backend/src/schema/openapi.generated.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -197,6 +197,7 @@ export const spec = { name: 'term', in: 'query', required: false, + allowReserved: true, schema: { type: 'string', default: '', @@ -208,6 +209,7 @@ export const spec = { required: false, style: 'deepObject', explode: true, + allowReserved: true, schema: { $ref: '#/components/schemas/JsonObject', }, @@ -216,6 +218,7 @@ export const spec = { name: 'types', in: 'query', required: false, + allowReserved: true, schema: { type: 'array', items: { @@ -227,6 +230,7 @@ export const spec = { name: 'pageCursor', in: 'query', required: false, + allowReserved: true, schema: { type: 'string', }, @@ -235,6 +239,7 @@ export const spec = { name: 'pageLimit', in: 'query', required: false, + allowReserved: true, schema: { type: 'integer', }, diff --git a/plugins/search-backend/src/schema/openapi.yaml b/plugins/search-backend/src/schema/openapi.yaml index 47f7e0a1e5..358f94fcf6 100644 --- a/plugins/search-backend/src/schema/openapi.yaml +++ b/plugins/search-backend/src/schema/openapi.yaml @@ -132,6 +132,7 @@ paths: - name: term in: query required: false + allowReserved: true schema: type: string default: '' @@ -140,6 +141,7 @@ paths: required: false style: deepObject explode: true + allowReserved: true schema: # JsonObject is used here instead of the full ZOD schema definition as # resolution of recursive schemas isn't possible with the library we're using @@ -148,6 +150,7 @@ paths: - name: types in: query required: false + allowReserved: true schema: type: array items: @@ -155,10 +158,12 @@ paths: - name: pageCursor in: query required: false + allowReserved: true schema: type: string - name: pageLimit in: query required: false + allowReserved: true schema: type: integer diff --git a/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts b/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts index b2355a7239..420af5744b 100644 --- a/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts +++ b/plugins/search-backend/src/service/AuthorizedSearchEngine.test.ts @@ -25,8 +25,8 @@ import { import { DocumentTypeInfo, IndexableDocument, - SearchEngine, } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { encodePageCursor, decodePageCursor, diff --git a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts index 52c87d76c7..defb535f42 100644 --- a/plugins/search-backend/src/service/AuthorizedSearchEngine.ts +++ b/plugins/search-backend/src/service/AuthorizedSearchEngine.ts @@ -18,26 +18,28 @@ import { compact, zipObject } from 'lodash'; import qs from 'qs'; import DataLoader from 'dataloader'; import { - EvaluatePermissionResponse, - EvaluatePermissionRequest, - AuthorizeResult, - isResourcePermission, - PermissionEvaluator, AuthorizePermissionRequest, + AuthorizeResult, + EvaluatePermissionRequest, + EvaluatePermissionResponse, + isResourcePermission, QueryPermissionRequest, } from '@backstage/plugin-permission-common'; import { DocumentTypeInfo, IndexableResult, IndexableResultSet, + SearchQuery, +} from '@backstage/plugin-search-common'; +import { QueryRequestOptions, QueryTranslator, SearchEngine, - SearchQuery, -} from '@backstage/plugin-search-common'; +} from '@backstage/plugin-search-backend-node'; import { Config } from '@backstage/config'; import { InputError } from '@backstage/errors'; import { Writable } from 'stream'; +import { PermissionsService } from '@backstage/backend-plugin-api'; export function decodePageCursor(pageCursor?: string): { page: number } { if (!pageCursor) { @@ -63,13 +65,12 @@ export function encodePageCursor({ page }: { page: number }): string { } export class AuthorizedSearchEngine implements SearchEngine { - private readonly pageSize = 25; private readonly queryLatencyBudgetMs: number; constructor( private readonly searchEngine: SearchEngine, private readonly types: Record, - private readonly permissions: PermissionEvaluator, + private readonly permissions: PermissionsService, config: Config, ) { this.queryLatencyBudgetMs = @@ -162,8 +163,9 @@ export class AuthorizedSearchEngine implements SearchEngine { ); } + const pageSize = query.pageLimit || 25; const { page } = decodePageCursor(query.pageCursor); - const targetResults = (page + 1) * this.pageSize; + const targetResults = (page + 1) * pageSize; let filteredResults: IndexableResult[] = []; let nextPageCursor: string | undefined; @@ -190,12 +192,12 @@ export class AuthorizedSearchEngine implements SearchEngine { return { results: filteredResults - .slice(page * this.pageSize, (page + 1) * this.pageSize) + .slice(page * pageSize, (page + 1) * pageSize) .map((result, index) => { // Overwrite any/all rank entries to avoid leaking knowledge of filtered results. return { ...result, - rank: page * this.pageSize + index + 1, + rank: page * pageSize + index + 1, }; }), previousPageCursor: diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index 401488dcbf..59f2f95afe 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -14,16 +14,22 @@ * limitations under the License. */ -import { getVoidLogger } from '@backstage/backend-common'; +import { + PluginEndpointDiscovery, + getVoidLogger, +} from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; -import { IndexBuilder } from '@backstage/plugin-search-backend-node'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { + IndexBuilder, + SearchEngine, +} from '@backstage/plugin-search-backend-node'; import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; import { wrapInOpenApiTestServer } from '@backstage/backend-openapi-utils'; import { Server } from 'http'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; const mockPermissionEvaluator: PermissionEvaluator = { authorize: () => { @@ -38,6 +44,16 @@ describe('createRouter', () => { let app: express.Express | Server; let mockSearchEngine: jest.Mocked; + const mockBaseUrl = 'http://backstage:9191/api/proxy'; + const discovery: PluginEndpointDiscovery = { + async getBaseUrl() { + return mockBaseUrl; + }, + async getExternalBaseUrl() { + return mockBaseUrl; + }, + }; + beforeAll(async () => { const logger = getVoidLogger(); mockSearchEngine = { @@ -65,7 +81,10 @@ describe('createRouter', () => { search: { maxPageLimit: 200, maxTermLength: 20 }, }), permissions: mockPermissionEvaluator, + discovery, logger, + auth: mockServices.auth(), + httpAuth: mockServices.httpAuth(), }); app = wrapInOpenApiTestServer(express().use(router)); }); @@ -80,7 +99,6 @@ describe('createRouter', () => { mockSearchEngine.query.mockRejectedValueOnce(error); const response = await request(app).get('/query'); - console.log((response as any).text); expect(response.status).toEqual(500); expect(response.body).toMatchObject( @@ -108,6 +126,8 @@ describe('createRouter', () => { 'types[0]=first-type&types[1]=second-type', 'filters[prop]=value', 'pageCursor=foo', + // https://github.com/backstage/backstage/issues/23973 + 'term=foo+bar', ])('accepts valid query string "%s"', async queryString => { const response = await request(app).get(`/query?${queryString}`); @@ -227,7 +247,11 @@ describe('createRouter', () => { unknownKey2: 'unknownValue1', }; const secondArg = { - token: undefined, + credentials: mockCredentials.user(), + token: mockCredentials.service.token({ + onBehalfOf: mockCredentials.user(), + targetPluginId: 'search', + }), }; expect(response.status).toEqual(200); expect(mockSearchEngine.query).toHaveBeenCalledWith(firstArg, secondArg); @@ -251,6 +275,7 @@ describe('createRouter', () => { types: indexBuilder.getDocumentTypes(), config: new ConfigReader({ permissions: { enabled: false } }), permissions: mockPermissionEvaluator, + discovery, logger, }); app = express().use(router); diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 876cb5d103..250be2853c 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -15,13 +15,15 @@ */ import express from 'express'; -import { Logger } from 'winston'; import { z } from 'zod'; -import { errorHandler } from '@backstage/backend-common'; +import { + createLegacyAuthAdapters, + errorHandler, + HostDiscovery, +} from '@backstage/backend-common'; import { InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; import { JsonObject, JsonValue } from '@backstage/types'; -import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { PermissionAuthorizer, PermissionEvaluator, @@ -32,9 +34,15 @@ import { IndexableResultSet, SearchResultSet, } from '@backstage/plugin-search-common'; -import { SearchEngine } from '@backstage/plugin-search-common'; +import { SearchEngine } from '@backstage/plugin-search-backend-node'; import { AuthorizedSearchEngine } from './AuthorizedSearchEngine'; import { createOpenApiRouter } from '../schema/openapi.generated'; +import { + AuthService, + DiscoveryService, + HttpAuthService, + LoggerService, +} from '@backstage/backend-plugin-api'; const jsonObjectSchema: z.ZodSchema = z.lazy(() => { const jsonValueSchema: z.ZodSchema = z.lazy(() => @@ -57,9 +65,12 @@ const jsonObjectSchema: z.ZodSchema = z.lazy(() => { export type RouterOptions = { engine: SearchEngine; types: Record; + discovery?: DiscoveryService; permissions: PermissionEvaluator | PermissionAuthorizer; config: Config; - logger: Logger; + logger: LoggerService; + auth?: AuthService; + httpAuth?: HttpAuthService; }; const defaultMaxPageLimit = 100; @@ -73,7 +84,19 @@ export async function createRouter( options: RouterOptions, ): Promise { const router = await createOpenApiRouter(); - const { engine: inputEngine, types, permissions, config, logger } = options; + const { + engine: inputEngine, + types, + permissions, + config, + logger, + discovery = HostDiscovery.fromConfig(config), + } = options; + + const { auth, httpAuth } = createLegacyAuthAdapters({ + ...options, + discovery, + }); const maxPageLimit = config.getOptionalNumber('search.maxPageLimit') ?? defaultMaxPageLimit; @@ -169,12 +192,16 @@ export async function createRouter( }`, ); - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); - try { - const resultSet = await engine?.query(query, { token }); + const credentials = await httpAuth.credentials(req); + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'search', + }); + const resultSet = await engine?.query(query, { + token, + credentials, + }); res.json(filterResultSet(toSearchResults(resultSet))); } catch (error) { diff --git a/plugins/search-backend/src/service/standaloneServer.ts b/plugins/search-backend/src/service/standaloneServer.ts index 9e4294d39f..09fa4f87ee 100644 --- a/plugins/search-backend/src/service/standaloneServer.ts +++ b/plugins/search-backend/src/service/standaloneServer.ts @@ -57,6 +57,7 @@ export async function startStandaloneServer( const router = await createRouter({ engine: indexBuilder.getSearchEngine(), types: indexBuilder.getDocumentTypes(), + discovery, permissions, config, logger, diff --git a/plugins/search-common/CHANGELOG.md b/plugins/search-common/CHANGELOG.md index d14a8e37b3..ae1b24dea6 100644 --- a/plugins/search-common/CHANGELOG.md +++ b/plugins/search-common/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-search-common +## 1.2.11 + +### Patch Changes + +- 744c0cb: Deprecate `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` in favor of the types exported from `@backstage/plugin-search-backend-node`. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13 + - @backstage/types@1.1.1 + +## 1.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/types@1.1.1 + +## 1.2.11-next.0 + +### Patch Changes + +- 744c0cb: Deprecate `QueryTranslator`, `QueryRequestOptions` and `SearchEngine` in favor of the types exported from `@backstage/plugin-search-backend-node`. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/types@1.1.1 + ## 1.2.10 ### Patch Changes diff --git a/plugins/search-common/api-report.md b/plugins/search-common/api-report.md index 2006689ab9..497defc46d 100644 --- a/plugins/search-common/api-report.md +++ b/plugins/search-common/api-report.md @@ -42,12 +42,12 @@ export type IndexableResult = Result; // @public (undocumented) export type IndexableResultSet = ResultSet; -// @public +// @public @deprecated export type QueryRequestOptions = { token?: string; }; -// @public +// @public @deprecated export type QueryTranslator = (query: SearchQuery) => unknown; // @public (undocumented) @@ -87,7 +87,7 @@ export interface SearchDocument { title: string; } -// @public +// @public @deprecated export interface SearchEngine { getIndexer(type: string): Promise; query( diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index e753ea764c..9a3c7bce03 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,42 +1,47 @@ { "name": "@backstage/plugin-search-common", + "version": "1.2.11", "description": "Common functionalities for Search, to be shared between various search-enabled plugins", - "version": "1.2.10", - "main": "src/index.ts", - "types": "src/index.ts", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" - }, + "keywords": [ + "backstage", + "search" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/search-common" }, - "keywords": [ - "backstage", - "search" - ], "license": "Apache-2.0", + "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" + "test": "backstage-cli package test" }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "jest": { + "roots": [ + ".." + ] }, "dependencies": { "@backstage/plugin-permission-common": "workspace:^", @@ -44,10 +49,5 @@ }, "devDependencies": { "@backstage/cli": "workspace:^" - }, - "jest": { - "roots": [ - ".." - ] } } diff --git a/plugins/search-common/src/deprecated.ts b/plugins/search-common/src/deprecated.ts new file mode 100644 index 0000000000..8d76d3a22d --- /dev/null +++ b/plugins/search-common/src/deprecated.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Writable } from 'stream'; +import { SearchQuery, IndexableResultSet } from './types'; + +/** + * A type of function responsible for translating an abstract search query into + * a concrete query relevant to a particular search engine. + * @public + * @deprecated Import from `@backstage/plugin-search-backend-node` instead + */ +export type QueryTranslator = (query: SearchQuery) => unknown; + +/** + * Options when querying a search engine. + * @public + * @deprecated Import from `@backstage/plugin-search-backend-node` instead + */ +export type QueryRequestOptions = { + token?: string; +}; + +/** + * Interface that must be implemented by specific search engines, responsible + * for performing indexing and querying and translating abstract queries into + * concrete, search engine-specific queries. + * @public + * @deprecated Import from `@backstage/plugin-search-backend-node` instead + */ +export interface SearchEngine { + /** + * Override the default translator provided by the SearchEngine. + */ + setTranslator(translator: QueryTranslator): void; + + /** + * Factory method for getting a search engine indexer for a given document + * type. + * + * @param type - The type or name of the document set for which an indexer + * should be retrieved. This corresponds to the `type` property on the + * document collator/decorator factories and will most often be used to + * identify an index or group to which documents should be written. + */ + getIndexer(type: string): Promise; + + /** + * Perform a search query against the SearchEngine. + */ + query( + query: SearchQuery, + options?: QueryRequestOptions, + ): Promise; +} diff --git a/plugins/search-common/src/index.ts b/plugins/search-common/src/index.ts index e71f8cd660..5d8ae2d42f 100644 --- a/plugins/search-common/src/index.ts +++ b/plugins/search-common/src/index.ts @@ -21,3 +21,4 @@ */ export * from './types'; +export * from './deprecated'; diff --git a/plugins/search-common/src/types.ts b/plugins/search-common/src/types.ts index 2ea4a490ca..9d1f9aa887 100644 --- a/plugins/search-common/src/types.ts +++ b/plugins/search-common/src/types.ts @@ -16,7 +16,7 @@ import { Permission } from '@backstage/plugin-permission-common'; import { JsonObject } from '@backstage/types'; -import { Readable, Transform, Writable } from 'stream'; +import { Readable, Transform } from 'stream'; /** * @public @@ -206,50 +206,3 @@ export interface DocumentDecoratorFactory { */ getDecorator(): Promise; } - -/** - * A type of function responsible for translating an abstract search query into - * a concrete query relevant to a particular search engine. - * @public - */ -export type QueryTranslator = (query: SearchQuery) => unknown; - -/** - * Options when querying a search engine. - * @public - */ -export type QueryRequestOptions = { - token?: string; -}; - -/** - * Interface that must be implemented by specific search engines, responsible - * for performing indexing and querying and translating abstract queries into - * concrete, search engine-specific queries. - * @public - */ -export interface SearchEngine { - /** - * Override the default translator provided by the SearchEngine. - */ - setTranslator(translator: QueryTranslator): void; - - /** - * Factory method for getting a search engine indexer for a given document - * type. - * - * @param type - The type or name of the document set for which an indexer - * should be retrieved. This corresponds to the `type` property on the - * document collator/decorator factories and will most often be used to - * identify an index or group to which documents should be written. - */ - getIndexer(type: string): Promise; - - /** - * Perform a search query against the SearchEngine. - */ - query( - query: SearchQuery, - options?: QueryRequestOptions, - ): Promise; -} diff --git a/plugins/search-react/.eslintrc.js b/plugins/search-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/search-react/.eslintrc.js +++ b/plugins/search-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index 77ddd1d132..b7ef7b85fc 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,154 @@ # @backstage/plugin-search-react +## 1.7.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.11 + +## 1.7.10 + +### Patch Changes + +- 8d50bd3: add mui imports eslint rule +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/version-bridge@1.0.8 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.11 + +## 1.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## 1.7.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## 1.7.9 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## 1.7.8 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## 1.7.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.7.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.7.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.7.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.7.6 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-components@0.14.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + ## 1.7.6-next.3 ### Patch Changes diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index b0edd42646..36f5f049c5 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -7,7 +7,7 @@ import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; -import { ListItemProps } from '@material-ui/core'; +import { ListItemProps } from '@material-ui/core/ListItem'; import { PortableSchema } from '@backstage/frontend-plugin-api'; import { SearchDocument } from '@backstage/plugin-search-common'; import { SearchResult } from '@backstage/plugin-search-common'; diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md index 97c8300c14..b5b06a2904 100644 --- a/plugins/search-react/api-report.md +++ b/plugins/search-react/api-report.md @@ -6,16 +6,16 @@ /// import { ApiRef } from '@backstage/core-plugin-api'; -import { AsyncState } from 'react-use/lib/useAsync'; -import { AutocompleteProps } from '@material-ui/lab'; +import { AsyncState } from 'react-use/esm/useAsync'; +import { AutocompleteProps } from '@material-ui/lab/Autocomplete'; import { Extension } from '@backstage/core-plugin-api'; import { ForwardRefExoticComponent } from 'react'; import { JsonObject } from '@backstage/types'; import { JsonValue } from '@backstage/types'; import { LinkProps } from '@backstage/core-components'; -import { ListItemProps } from '@material-ui/core'; -import { ListItemTextProps } from '@material-ui/core'; -import { ListProps } from '@material-ui/core'; +import { ListItemProps } from '@material-ui/core/ListItem'; +import { ListItemTextProps } from '@material-ui/core/ListItemText'; +import { ListProps } from '@material-ui/core/List'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactElement } from 'react'; @@ -26,7 +26,7 @@ import { SearchQuery } from '@backstage/plugin-search-common'; import { SearchResult as SearchResult_2 } from '@backstage/plugin-search-common'; import { SearchResultSet } from '@backstage/plugin-search-common'; import { TextFieldProps } from '@material-ui/core/TextField'; -import { TypographyProps } from '@material-ui/core'; +import { TypographyProps } from '@material-ui/core/Typography'; // @public (undocumented) export const AutocompleteFilter: ( diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 8dd669840c..00cc8032f2 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,17 +1,30 @@ { "name": "@backstage/plugin-search-react", - "version": "1.7.6-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "1.7.11-next.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-react" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -22,27 +35,17 @@ ] } }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search-react" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -60,23 +63,20 @@ "qs": "^6.9.4", "react-use": "^17.3.2" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/frontend-app-api": "workspace:^", "@backstage/frontend-test-utils": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/search-react/src/alpha.tsx b/plugins/search-react/src/alpha.tsx index e075d9bfb8..db198fa99d 100644 --- a/plugins/search-react/src/alpha.tsx +++ b/plugins/search-react/src/alpha.tsx @@ -16,7 +16,7 @@ import React, { lazy } from 'react'; -import { ListItemProps } from '@material-ui/core'; +import { ListItemProps } from '@material-ui/core/ListItem'; import { ExtensionBoundary, diff --git a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx index 7049b7f4ef..89c98f6e72 100644 --- a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx +++ b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx @@ -16,7 +16,7 @@ import { LinkButton } from '@backstage/core-components'; import { lightTheme } from '@backstage/theme'; -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import CssBaseline from '@material-ui/core/CssBaseline'; import { ThemeProvider } from '@material-ui/core/styles'; import FindInPageIcon from '@material-ui/icons/FindInPage'; diff --git a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx index 0d2c59e173..812e951439 100644 --- a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx +++ b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.tsx @@ -21,7 +21,9 @@ import { SearchDocument, } from '@backstage/plugin-search-common'; import { HighlightedSearchResultText } from '../HighlightedSearchResultText'; -import { ListItemIcon, ListItemText, Box } from '@material-ui/core'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import Box from '@material-ui/core/Box'; import Typography from '@material-ui/core/Typography'; import { Link } from '@backstage/core-components'; diff --git a/plugins/search-react/src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx b/plugins/search-react/src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx index 511635a4d0..d6474f5d56 100644 --- a/plugins/search-react/src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx +++ b/plugins/search-react/src/components/HighlightedSearchResultText/HighlightedSearchResultText.tsx @@ -15,7 +15,7 @@ */ import React, { useMemo } from 'react'; -import { makeStyles } from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles( () => ({ diff --git a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx index 0eaece87bb..eb113cb5fd 100644 --- a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx +++ b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.stories.tsx @@ -16,7 +16,7 @@ import React, { ComponentType, PropsWithChildren } from 'react'; -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import LabelIcon from '@material-ui/icons/Label'; import { TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.tsx b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.tsx index 2a3cb6bee4..bc9e3bff13 100644 --- a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.tsx +++ b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocomplete.tsx @@ -16,14 +16,16 @@ import React, { ChangeEvent, useCallback, useMemo } from 'react'; -import { CircularProgress, makeStyles } from '@material-ui/core'; -import { - Autocomplete, +import CircularProgress from '@material-ui/core/CircularProgress'; +import { makeStyles } from '@material-ui/core/styles'; +import Autocomplete, { AutocompleteProps, + AutocompleteRenderInputParams, +} from '@material-ui/lab/Autocomplete'; +import { AutocompleteChangeDetails, AutocompleteChangeReason, - AutocompleteRenderInputParams, -} from '@material-ui/lab'; +} from '@material-ui/lab/useAutocomplete'; import { SearchContextProvider, useSearch } from '../../context'; import { SearchBar, SearchBarProps } from '../SearchBar'; diff --git a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.stories.tsx b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.stories.tsx index f671546efa..3c4cfd8809 100644 --- a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.stories.tsx +++ b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.stories.tsx @@ -16,7 +16,8 @@ import React, { ComponentType, PropsWithChildren } from 'react'; -import { Grid, ListItem } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import ListItem from '@material-ui/core/ListItem'; import LabelIcon from '@material-ui/icons/Label'; import { TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx index db0dc81456..d2227ef0d3 100644 --- a/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx +++ b/plugins/search-react/src/components/SearchAutocomplete/SearchAutocompleteDefaultOption.tsx @@ -15,11 +15,10 @@ */ import React, { ReactNode } from 'react'; -import { - ListItemIcon, - ListItemText, +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText, { ListItemTextProps, -} from '@material-ui/core'; +} from '@material-ui/core/ListItemText'; /** * Props for {@link SearchAutocompleteDefaultOption}. diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx index f342eed211..852a3a1881 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.stories.tsx @@ -15,7 +15,8 @@ */ import React, { ComponentType, PropsWithChildren } from 'react'; -import { Grid, makeStyles } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; import { TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/search-react/src/components/SearchBar/SearchBar.tsx b/plugins/search-react/src/components/SearchBar/SearchBar.tsx index 534fefbd8c..254f39e48e 100644 --- a/plugins/search-react/src/components/SearchBar/SearchBar.tsx +++ b/plugins/search-react/src/components/SearchBar/SearchBar.tsx @@ -19,7 +19,9 @@ import { configApiRef, useApi, } from '@backstage/core-plugin-api'; -import { IconButton, InputAdornment, TextField } from '@material-ui/core'; +import IconButton from '@material-ui/core/IconButton'; +import InputAdornment from '@material-ui/core/InputAdornment'; +import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button'; import { TextFieldProps } from '@material-ui/core/TextField'; import SearchIcon from '@material-ui/icons/Search'; @@ -34,7 +36,7 @@ import React, { useRef, useState, } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; +import useDebounce from 'react-use/esm/useDebounce'; import { SearchContextProvider, useSearch } from '../../context'; diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx index 35d1f376e5..09f571a4c9 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.Autocomplete.tsx @@ -15,12 +15,12 @@ */ import React, { ChangeEvent, useState } from 'react'; -import { Chip, TextField } from '@material-ui/core'; -import { - Autocomplete, +import Chip from '@material-ui/core/Chip'; +import TextField from '@material-ui/core/TextField'; +import Autocomplete, { AutocompleteGetTagProps, AutocompleteRenderInputParams, -} from '@material-ui/lab'; +} from '@material-ui/lab/Autocomplete'; import { useSearch } from '../../context'; import { useAsyncFilterValues, useDefaultFilterValue } from './hooks'; diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.stories.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.stories.tsx index 505c1e13c3..028fadc276 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.stories.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.stories.tsx @@ -15,7 +15,8 @@ */ import React, { ComponentType, PropsWithChildren } from 'react'; -import { Grid, Paper } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import Paper from '@material-ui/core/Paper'; import { TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx b/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx index 8579f01caa..acfa6aec3b 100644 --- a/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx +++ b/plugins/search-react/src/components/SearchFilter/SearchFilter.tsx @@ -15,17 +15,15 @@ */ import React, { ReactElement, ChangeEvent } from 'react'; -import { - makeStyles, - FormControl, - FormControlLabel, - InputLabel, - Checkbox, - Select, - MenuItem, - FormLabel, - Typography, -} from '@material-ui/core'; +import FormControl from '@material-ui/core/FormControl'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import InputLabel from '@material-ui/core/InputLabel'; +import Checkbox from '@material-ui/core/Checkbox'; +import Select from '@material-ui/core/Select'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormLabel from '@material-ui/core/FormLabel'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; import { useSearch } from '../../context'; import { diff --git a/plugins/search-react/src/components/SearchFilter/hooks.ts b/plugins/search-react/src/components/SearchFilter/hooks.ts index 5771cc5288..987c85bb7c 100644 --- a/plugins/search-react/src/components/SearchFilter/hooks.ts +++ b/plugins/search-react/src/components/SearchFilter/hooks.ts @@ -15,8 +15,8 @@ */ import { useEffect, useRef } from 'react'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import useDebounce from 'react-use/lib/useDebounce'; +import useAsyncFn from 'react-use/esm/useAsyncFn'; +import useDebounce from 'react-use/esm/useDebounce'; import { useSearch } from '../../context'; diff --git a/plugins/search-react/src/components/SearchPagination/SearchPagination.stories.tsx b/plugins/search-react/src/components/SearchPagination/SearchPagination.stories.tsx index dfb4e7ea91..84d47b94cd 100644 --- a/plugins/search-react/src/components/SearchPagination/SearchPagination.stories.tsx +++ b/plugins/search-react/src/components/SearchPagination/SearchPagination.stories.tsx @@ -15,7 +15,7 @@ */ import React, { ComponentType, PropsWithChildren } from 'react'; -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import { TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx b/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx index 743d3ccb52..18b4c5f525 100644 --- a/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx +++ b/plugins/search-react/src/components/SearchPagination/SearchPagination.tsx @@ -21,7 +21,7 @@ import React, { useCallback, useMemo, } from 'react'; -import { TablePagination } from '@material-ui/core'; +import TablePagination from '@material-ui/core/TablePagination'; import { useSearch } from '../../context'; const encodePageCursor = (pageCursor: number): string => { diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx index a64d053dae..bc08270c28 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.stories.tsx @@ -16,7 +16,8 @@ import React, { ComponentType, PropsWithChildren } from 'react'; -import { List, ListItem } from '@material-ui/core'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; import DefaultIcon from '@material-ui/icons/InsertDriveFile'; import CustomIcon from '@material-ui/icons/NoteAdd'; diff --git a/plugins/search-react/src/components/SearchResult/SearchResult.tsx b/plugins/search-react/src/components/SearchResult/SearchResult.tsx index f362ff27d3..5a733ad8bf 100644 --- a/plugins/search-react/src/components/SearchResult/SearchResult.tsx +++ b/plugins/search-react/src/components/SearchResult/SearchResult.tsx @@ -15,7 +15,7 @@ */ import React, { ReactNode } from 'react'; -import useAsync, { AsyncState } from 'react-use/lib/useAsync'; +import useAsync, { AsyncState } from 'react-use/esm/useAsync'; import { isFunction } from 'lodash'; import { diff --git a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx index 2f497d4568..a016a7c5ed 100644 --- a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx +++ b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.stories.tsx @@ -21,13 +21,11 @@ import React, { PropsWithChildren, } from 'react'; -import { - Grid, - ListItem, - ListItemIcon, - ListItemText, - MenuItem, -} from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import MenuItem from '@material-ui/core/MenuItem'; import DocsIcon from '@material-ui/icons/InsertDriveFile'; import { JsonValue } from '@backstage/types'; diff --git a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx index 1d572b371b..66513783d4 100644 --- a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx +++ b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.test.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { MenuItem } from '@material-ui/core'; +import MenuItem from '@material-ui/core/MenuItem'; import DocsIcon from '@material-ui/icons/InsertDriveFile'; import { diff --git a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx index ea1817193c..428e34981b 100644 --- a/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx +++ b/plugins/search-react/src/components/SearchResultGroup/SearchResultGroup.tsx @@ -23,20 +23,15 @@ import React, { } from 'react'; import qs from 'qs'; -import { - makeStyles, - Theme, - List, - ListProps, - ListSubheader, - Menu, - MenuItem, - InputBase, - Select, - Chip, - Typography, - TypographyProps, -} from '@material-ui/core'; +import List, { ListProps } from '@material-ui/core/List'; +import ListSubheader from '@material-ui/core/ListSubheader'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; +import InputBase from '@material-ui/core/InputBase'; +import Select from '@material-ui/core/Select'; +import Chip from '@material-ui/core/Chip'; +import Typography, { TypographyProps } from '@material-ui/core/Typography'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import AddIcon from '@material-ui/icons/Add'; import ArrowRightIcon from '@material-ui/icons/ArrowForwardIos'; diff --git a/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx b/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx index d822d0f52d..5b3bd48d41 100644 --- a/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx +++ b/plugins/search-react/src/components/SearchResultList/SearchResultList.stories.tsx @@ -16,7 +16,10 @@ import React, { ComponentType, useState, PropsWithChildren } from 'react'; -import { Grid, ListItem, ListItemIcon, ListItemText } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; import { CatalogIcon, Link } from '@backstage/core-components'; import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; diff --git a/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx b/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx index 1a539b74a6..5abea8d961 100644 --- a/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx +++ b/plugins/search-react/src/components/SearchResultList/SearchResultList.tsx @@ -16,7 +16,7 @@ import React, { ReactNode } from 'react'; -import { List, ListProps } from '@material-ui/core'; +import List, { ListProps } from '@material-ui/core/List'; import { Progress, diff --git a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx index b4c834a678..14a0dcf395 100644 --- a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx +++ b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx @@ -16,7 +16,8 @@ import React from 'react'; -import { Button, makeStyles } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos'; import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos'; diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx index f8140e2f19..f09ebac42a 100644 --- a/plugins/search-react/src/context/SearchContext.tsx +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -22,8 +22,8 @@ import React, { useEffect, useState, } from 'react'; -import useAsync, { AsyncState } from 'react-use/lib/useAsync'; -import usePrevious from 'react-use/lib/usePrevious'; +import useAsync, { AsyncState } from 'react-use/esm/useAsync'; +import usePrevious from 'react-use/esm/usePrevious'; import { createVersionedContext, diff --git a/plugins/search-react/src/extensions.test.tsx b/plugins/search-react/src/extensions.test.tsx index febe82dbe1..170dca2b6d 100644 --- a/plugins/search-react/src/extensions.test.tsx +++ b/plugins/search-react/src/extensions.test.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { ListItemText } from '@material-ui/core'; +import ListItemText from '@material-ui/core/ListItemText'; import { renderInTestApp, diff --git a/plugins/search-react/src/extensions.tsx b/plugins/search-react/src/extensions.tsx index 132fad25b5..75b6eaaa1f 100644 --- a/plugins/search-react/src/extensions.tsx +++ b/plugins/search-react/src/extensions.tsx @@ -33,7 +33,8 @@ import { } from '@backstage/core-plugin-api'; import { SearchDocument, SearchResult } from '@backstage/plugin-search-common'; -import { ListItem, List, ListProps, ListItemProps } from '@material-ui/core'; +import List, { ListProps } from '@material-ui/core/List'; +import ListItem, { ListItemProps } from '@material-ui/core/ListItem'; import { DefaultResultListItem } from './components/DefaultResultListItem'; diff --git a/plugins/search/.eslintrc.js b/plugins/search/.eslintrc.js index e2a53a6ad2..a2d8179106 100644 --- a/plugins/search/.eslintrc.js +++ b/plugins/search/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 89e549cb84..bd07286578 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,192 @@ # @backstage/plugin-search +## 1.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## 1.4.10 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/version-bridge@1.0.8 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-search-common@1.2.11 + +## 1.4.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + +## 1.4.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + +## 1.4.9 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## 1.4.8 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/plugin-search-react@1.7.8 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11 + +## 1.4.7 + +### Patch Changes + +- 70ee3b7: Remove the hardcoded 'black' color give to the search type accordion icon as it doesn't work with dark themes +- f0464b0: Removes ADR from the default set of search filters +- cd872b9: Added ESLint rule `no-top-level-material-ui-4-imports` in the `search` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-react@1.7.7 + +## 1.4.7-next.2 + +### Patch Changes + +- 70ee3b7: Remove the hardcoded 'black' color give to the search type accordion icon as it doesn't work with dark themes +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.4.7-next.0 + +### Patch Changes + +- f0464b0: Removes ADR from the default set of search filters +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + +## 1.4.6 + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.7 + - @backstage/plugin-search-common@1.2.10 + ## 1.4.6-next.3 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index e055914f76..5aeeecbfd3 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-search", + "version": "1.4.11-next.0", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.4.6-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/search" - }, - "keywords": [ - "backstage" + "files": [ + "dist", + "config.d.ts" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-compat-api": "workspace:^", @@ -62,25 +66,21 @@ "qs": "^6.9.4", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "history": "^5.0.0" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/search/src/alpha.tsx b/plugins/search/src/alpha.tsx index 4f654548f5..9fffa41bfb 100644 --- a/plugins/search/src/alpha.tsx +++ b/plugins/search/src/alpha.tsx @@ -16,7 +16,9 @@ import React from 'react'; -import { makeStyles, Theme, Grid, Paper } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import Paper from '@material-ui/core/Paper'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import SearchIcon from '@material-ui/icons/Search'; import { @@ -153,11 +155,6 @@ export const searchPage = createPageExtension({ name: 'Documentation', icon: , }, - { - value: 'adr', - name: 'Architecture Decision Records', - icon: , - }, ]} /> diff --git a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx index c1b1f0df87..c3a54f442b 100644 --- a/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx +++ b/plugins/search/src/components/HomePageComponent/HomePageSearchBar.stories.tsx @@ -17,7 +17,8 @@ import { rootRouteRef, HomePageSearchBar } from '../../plugin'; import { searchApiRef } from '@backstage/plugin-search-react'; import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { Grid, makeStyles } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; import React, { ComponentType, PropsWithChildren } from 'react'; export default { diff --git a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx index 525eadc9df..7f789d2e53 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx @@ -23,16 +23,14 @@ import { SearchResultPager, } from '@backstage/plugin-search-react'; import { TestApiProvider, wrapInTestApp } from '@backstage/test-utils'; -import { - Box, - Button, - DialogActions, - DialogContent, - DialogTitle, - Grid, - IconButton, - List, -} from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Button from '@material-ui/core/Button'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Grid from '@material-ui/core/Grid'; +import IconButton from '@material-ui/core/IconButton'; +import List from '@material-ui/core/List'; import { makeStyles } from '@material-ui/core/styles'; import CloseIcon from '@material-ui/icons/Close'; import React, { ComponentType, PropsWithChildren } from 'react'; diff --git a/plugins/search/src/components/SearchModal/SearchModal.tsx b/plugins/search/src/components/SearchModal/SearchModal.tsx index dec0f9f482..814779fb45 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.tsx @@ -21,15 +21,13 @@ import { SearchResult, SearchResultPager, } from '@backstage/plugin-search-react'; -import { - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Divider, - Grid, - useTheme, -} from '@material-ui/core'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Divider from '@material-ui/core/Divider'; +import Grid from '@material-ui/core/Grid'; +import { useTheme } from '@material-ui/core/styles'; import Box from '@material-ui/core/Box'; import Button from '@material-ui/core/Button'; import IconButton from '@material-ui/core/IconButton'; diff --git a/plugins/search/src/components/SearchModal/useSearchModal.tsx b/plugins/search/src/components/SearchModal/useSearchModal.tsx index 279484bd47..b8c59e780a 100644 --- a/plugins/search/src/components/SearchModal/useSearchModal.tsx +++ b/plugins/search/src/components/SearchModal/useSearchModal.tsx @@ -20,7 +20,7 @@ import { createVersionedContext, createVersionedValueMap, } from '@backstage/version-bridge'; -import useUpdateEffect from 'react-use/lib/useUpdateEffect'; +import useUpdateEffect from 'react-use/esm/useUpdateEffect'; /** * The state of the search modal, as well as functions for changing the modal's diff --git a/plugins/search/src/components/SearchPage/SearchPage.tsx b/plugins/search/src/components/SearchPage/SearchPage.tsx index 3ee444bd32..7ea4160216 100644 --- a/plugins/search/src/components/SearchPage/SearchPage.tsx +++ b/plugins/search/src/components/SearchPage/SearchPage.tsx @@ -15,7 +15,7 @@ */ import React, { useEffect } from 'react'; -import usePrevious from 'react-use/lib/usePrevious'; +import usePrevious from 'react-use/esm/usePrevious'; import qs from 'qs'; import { useLocation, useOutlet } from 'react-router-dom'; import { diff --git a/plugins/search/src/components/SearchPage/UrlUpdater.tsx b/plugins/search/src/components/SearchPage/UrlUpdater.tsx index d44195b6e2..d4bfe057a3 100644 --- a/plugins/search/src/components/SearchPage/UrlUpdater.tsx +++ b/plugins/search/src/components/SearchPage/UrlUpdater.tsx @@ -15,7 +15,7 @@ */ import { useEffect } from 'react'; -import usePrevious from 'react-use/lib/usePrevious'; +import usePrevious from 'react-use/esm/usePrevious'; import qs from 'qs'; import { useLocation } from 'react-router-dom'; import { useSearch } from '@backstage/plugin-search-react'; diff --git a/plugins/search/src/components/SearchType/SearchType.Accordion.tsx b/plugins/search/src/components/SearchType/SearchType.Accordion.tsx index 67785b89cb..f9a07b6dcd 100644 --- a/plugins/search/src/components/SearchType/SearchType.Accordion.tsx +++ b/plugins/search/src/components/SearchType/SearchType.Accordion.tsx @@ -17,23 +17,21 @@ import React, { cloneElement, Fragment, useEffect, useState } from 'react'; import { useApi } from '@backstage/core-plugin-api'; import { searchApiRef, useSearch } from '@backstage/plugin-search-react'; -import { - Accordion, - AccordionSummary, - AccordionDetails, - Card, - CardContent, - CardHeader, - Divider, - List, - ListItem, - ListItemIcon, - ListItemText, - makeStyles, -} from '@material-ui/core'; +import Accordion from '@material-ui/core/Accordion'; +import AccordionSummary from '@material-ui/core/AccordionSummary'; +import AccordionDetails from '@material-ui/core/AccordionDetails'; +import Card from '@material-ui/core/Card'; +import CardContent from '@material-ui/core/CardContent'; +import CardHeader from '@material-ui/core/CardHeader'; +import Divider from '@material-ui/core/Divider'; +import List from '@material-ui/core/List'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import { makeStyles } from '@material-ui/core/styles'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import AllIcon from '@material-ui/icons/FontDownload'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; const useStyles = makeStyles(theme => ({ card: { @@ -43,7 +41,7 @@ const useStyles = makeStyles(theme => ({ paddingTop: theme.spacing(1), }, icon: { - color: theme.palette.common.black, + color: theme.palette.text.primary, }, list: { width: '100%', diff --git a/plugins/search/src/components/SearchType/SearchType.Tabs.tsx b/plugins/search/src/components/SearchType/SearchType.Tabs.tsx index 5b3990f7bb..d48420bdac 100644 --- a/plugins/search/src/components/SearchType/SearchType.Tabs.tsx +++ b/plugins/search/src/components/SearchType/SearchType.Tabs.tsx @@ -16,7 +16,9 @@ import React, { useEffect } from 'react'; import { useSearch } from '@backstage/plugin-search-react'; -import { makeStyles, Tab, Tabs } from '@material-ui/core'; +import Tab from '@material-ui/core/Tab'; +import Tabs from '@material-ui/core/Tabs'; +import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles(theme => ({ tabs: { diff --git a/plugins/search/src/components/SearchType/SearchType.stories.tsx b/plugins/search/src/components/SearchType/SearchType.stories.tsx index 250eab051d..8cce7eb5e3 100644 --- a/plugins/search/src/components/SearchType/SearchType.stories.tsx +++ b/plugins/search/src/components/SearchType/SearchType.stories.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Grid, Paper } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import Paper from '@material-ui/core/Paper'; import CatalogIcon from '@material-ui/icons/MenuBook'; import DocsIcon from '@material-ui/icons/Description'; import UsersGroupsIcon from '@material-ui/icons/Person'; diff --git a/plugins/search/src/components/SearchType/SearchType.tsx b/plugins/search/src/components/SearchType/SearchType.tsx index b20e8b5fba..6e470ea7a8 100644 --- a/plugins/search/src/components/SearchType/SearchType.tsx +++ b/plugins/search/src/components/SearchType/SearchType.tsx @@ -13,18 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - Checkbox, - Chip, - FormControl, - InputLabel, - ListItemText, - makeStyles, - MenuItem, - Select, -} from '@material-ui/core'; +import Checkbox from '@material-ui/core/Checkbox'; +import Chip from '@material-ui/core/Chip'; +import FormControl from '@material-ui/core/FormControl'; +import InputLabel from '@material-ui/core/InputLabel'; +import ListItemText from '@material-ui/core/ListItemText'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; +import { makeStyles } from '@material-ui/core/styles'; import React, { ChangeEvent } from 'react'; -import useEffectOnce from 'react-use/lib/useEffectOnce'; +import useEffectOnce from 'react-use/esm/useEffectOnce'; import { SearchTypeAccordion, SearchTypeAccordionProps, diff --git a/plugins/sentry/.eslintrc.js b/plugins/sentry/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/sentry/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md deleted file mode 100644 index de6be812c8..0000000000 --- a/plugins/sentry/CHANGELOG.md +++ /dev/null @@ -1,1768 +0,0 @@ -# @backstage/plugin-sentry - -## 0.5.15-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.5.15-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.5.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - -## 0.5.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - -## 0.5.14 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - -## 0.5.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.5.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - -## 0.5.14-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - -## 0.5.13 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - -## 0.5.13-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.5.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.5.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.5.0-next.0 - -## 0.5.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.5.11 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - -## 0.5.11-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.5.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.5.11-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.5.10 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.4.3 - -## 0.5.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/theme@0.4.3-next.0 - -## 0.5.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.5.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.5.9 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.5.9-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.5.9-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/theme@0.4.1 - -## 0.5.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.5.8-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.5.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.5.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.5.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.5.5 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.5.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - -## 0.5.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.5.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.5.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - -## 0.5.4-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.5.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.5.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.5.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.5.3 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.5.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.5.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.5.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/theme@0.2.19 - -## 0.5.2 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.5.2-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.5.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.19-next.0 - -## 0.5.2-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - -## 0.5.2-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.5.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.5.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.5.1-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.5.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - -## 0.5.0 - -### Minor Changes - -- 6a8d6b9a0c: Add option to filter issues based on the time it was triggered - -### Patch Changes - -- 85b04f659a: Internal refactor to not use deprecated `substr` -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - -## 0.5.0-next.2 - -### Minor Changes - -- 6a8d6b9a0c: Add option to filter issues based on the time it was triggered - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.4.8-next.1 - -### Patch Changes - -- 85b04f659a: Internal refactor to not use deprecated `substr` -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.4.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.4.7 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.4.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - -## 0.4.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.4.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - -## 0.4.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.4.5 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.4.5-next.4 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.4.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.4.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.4.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.4.5-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.4.4 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/theme@0.2.16 - -## 0.4.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.4.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.4.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - -## 0.4.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - -## 0.4.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.4.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - -## 0.4.2 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 3f739be9d9: Minor API signatures cleanup -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - -## 0.4.2-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.4.2-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.4.2-next.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.4.2-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- 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`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.3.45-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.3.45-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.3.45-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.3.44 - -### Patch Changes - -- c55f6cb22d: Exported `isSentryAvailable` which can be used to determine if sentry is available. -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.3.44-next.1 - -### Patch Changes - -- c55f6cb22d: Exported `isSentryAvailable` which can be used to determine if sentry is available. -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.3.44-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.3.43 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.3.43-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.3.43-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.3.43-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.3.42 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 68bb66102d: Exposed options for the material table -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.3.42-next.2 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.3.42-next.1 - -### Patch Changes - -- 68bb66102d: Exposed options for the material table -- Updated dependencies - - @backstage/core-components@0.9.3-next.1 - - @backstage/plugin-catalog-react@1.0.1-next.2 - - @backstage/catalog-model@1.0.1-next.1 - -## 0.3.42-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.3.41 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - -## 0.3.40 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.3.40-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.3.39 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.3.38 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.3.37 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - -## 0.3.36 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.3.36-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.3.35 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.3.35-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.3.34 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.3.34-next.0 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.3.33 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/catalog-model@0.9.9 - -## 0.3.32 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.3.31 - -### Patch Changes - -- 7a4bd2ceac: Prefer using `Link` from `@backstage/core-components` rather than material-UI. -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.3.30 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.3.29 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/catalog-model@0.9.7 - - @backstage/plugin-catalog-react@0.6.4 - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.3.28 - -### Patch Changes - -- 33d7bd0baa: fix: sentry-plugin can forward identity token to backend (for case when it requires authorization) -- Updated dependencies - - @backstage/core-components@0.7.3 - - @backstage/theme@0.2.13 - - @backstage/core-plugin-api@0.1.13 - - @backstage/plugin-catalog-react@0.6.3 - -## 0.3.27 - -### Patch Changes - -- 97231f5581: feature: sentry-plugin allows passing search query for listing issues -- 61fe752dad: fix: sentry-plugin correction for allowed period values -- Updated dependencies - - @backstage/theme@0.2.12 - - @backstage/core-components@0.7.2 - - @backstage/plugin-catalog-react@0.6.2 - - @backstage/catalog-model@0.9.6 - - @backstage/core-plugin-api@0.1.12 - -## 0.3.26 - -### Patch Changes - -- f93e4349e5: fix: parameter name on call to sentry api -- Updated dependencies - - @backstage/core-components@0.7.1 - - @backstage/core-plugin-api@0.1.11 - - @backstage/plugin-catalog-react@0.6.1 - - @backstage/catalog-model@0.9.5 - -## 0.3.25 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.0 - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.3.24 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - - @backstage/plugin-catalog-react@0.5.2 - - @backstage/catalog-model@0.9.4 - -## 0.3.23 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - - @backstage/plugin-catalog-react@0.5.1 - -## 0.3.22 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/plugin-catalog-react@0.5.0 - - @backstage/catalog-model@0.9.3 - -## 0.3.21 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/plugin-catalog-react@0.4.6 - - @backstage/core-plugin-api@0.1.8 - -## 0.3.20 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.5 - - @backstage/core-components@0.4.0 - - @backstage/catalog-model@0.9.1 - -## 0.3.19 - -### Patch Changes - -- 0e7595d19: Do not show [No Type] when issue metadata includes title instead of type -- d8e4afc62: Render the statsFor property in sentry issues table -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.3 - - @backstage/core-components@0.3.2 - - @backstage/theme@0.2.10 - -## 0.3.18 - -### Patch Changes - -- 8bedb75ae: Update Luxon dependency to 2.x -- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - - @backstage/plugin-catalog-react@0.4.2 - -## 0.3.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - - @backstage/plugin-catalog-react@0.4.1 - -## 0.3.16 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/plugin-catalog-react@0.4.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.3.15 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.3.0 - -## 0.3.14 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.1.5 - - @backstage/catalog-model@0.9.0 - - @backstage/plugin-catalog-react@0.2.6 - -## 0.3.13 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - - @backstage/catalog-model@0.8.4 - - @backstage/plugin-catalog-react@0.2.4 - -## 0.3.12 - -### Patch Changes - -- 6c12f0ec6: Migrated the package from `timeago.js` to `luxon`. See #4278 -- Updated dependencies - - @backstage/plugin-catalog-react@0.2.3 - - @backstage/catalog-model@0.8.3 - - @backstage/core@0.7.13 - -## 0.3.11 - -### Patch Changes - -- Updated dependencies [add62a455] -- Updated dependencies [cc592248b] -- Updated dependencies [17c497b81] -- Updated dependencies [704875e26] - - @backstage/catalog-model@0.8.0 - - @backstage/core@0.7.11 - - @backstage/plugin-catalog-react@0.2.0 - -## 0.3.10 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [10c008a3a] -- Updated dependencies [889d89b6e] -- Updated dependencies [16be1d093] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - - @backstage/plugin-catalog-react@0.1.6 - - @backstage/catalog-model@0.7.9 - -## 0.3.9 - -### Patch Changes - -- c614ede9a: Updated README to have up-to-date install instructions. -- Updated dependencies [9afcac5af] -- Updated dependencies [e0c9ed759] -- Updated dependencies [6eaecbd81] - - @backstage/core@0.7.7 - -## 0.3.8 - -### Patch Changes - -- Updated dependencies [12d8f27a6] -- Updated dependencies [40c0fdbaa] -- Updated dependencies [2a271d89e] -- Updated dependencies [bece09057] -- Updated dependencies [169f48deb] -- Updated dependencies [8a1566719] -- Updated dependencies [9d455f69a] -- Updated dependencies [4c049a1a1] -- Updated dependencies [02816ecd7] - - @backstage/catalog-model@0.7.3 - - @backstage/core@0.7.0 - - @backstage/plugin-catalog-react@0.1.1 - -## 0.3.7 - -### Patch Changes - -- Updated dependencies [3a58084b6] -- Updated dependencies [e799e74d4] -- Updated dependencies [d0760ecdf] -- Updated dependencies [1407b34c6] -- Updated dependencies [88f1f1b60] -- Updated dependencies [bad21a085] -- Updated dependencies [9615e68fb] -- Updated dependencies [49f9b7346] -- Updated dependencies [5c2e2863f] -- Updated dependencies [3a58084b6] -- Updated dependencies [2c1f2a7c2] - - @backstage/core@0.6.3 - - @backstage/plugin-catalog-react@0.1.0 - - @backstage/catalog-model@0.7.2 - -## 0.3.6 - -### Patch Changes - -- f4c2bcf54: Use a more strict type for `variant` of cards. -- Updated dependencies [fd3f2a8c0] -- Updated dependencies [d34d26125] -- Updated dependencies [0af242b6d] -- Updated dependencies [f4c2bcf54] -- Updated dependencies [10a0124e0] -- Updated dependencies [07e226872] -- Updated dependencies [f62e7abe5] -- Updated dependencies [96f378d10] -- Updated dependencies [688b73110] - - @backstage/core@0.6.2 - - @backstage/plugin-catalog-react@0.0.4 - -## 0.3.5 - -### Patch Changes - -- 53d3e2d62: Export the plugin instance as `sentryPlugin`. The plugin instance is still exported as `plugin` as well, but it will be removed in the future. -- Updated dependencies [19d354c78] -- Updated dependencies [b51ee6ece] - - @backstage/plugin-catalog-react@0.0.3 - - @backstage/core@0.6.1 - -## 0.3.4 - -### Patch Changes - -- 019fe39a0: Switch dependency from `@backstage/plugin-catalog` to `@backstage/plugin-catalog-react`. -- Updated dependencies [12ece98cd] -- Updated dependencies [d82246867] -- Updated dependencies [7fc89bae2] -- Updated dependencies [c810082ae] -- Updated dependencies [5fa3bdb55] -- Updated dependencies [6e612ce25] -- Updated dependencies [025e122c3] -- Updated dependencies [21e624ba9] -- Updated dependencies [da9f53c60] -- Updated dependencies [32c95605f] -- Updated dependencies [7881f2117] -- Updated dependencies [54c7d02f7] -- Updated dependencies [11cb5ef94] - - @backstage/core@0.6.0 - - @backstage/plugin-catalog-react@0.0.2 - - @backstage/theme@0.2.3 - - @backstage/catalog-model@0.7.1 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies [def2307f3] -- Updated dependencies [efd6ef753] -- Updated dependencies [593632f07] -- Updated dependencies [33846acfc] -- Updated dependencies [a187b8ad0] -- Updated dependencies [f04db53d7] -- Updated dependencies [a93f42213] - - @backstage/catalog-model@0.7.0 - - @backstage/core@0.5.0 - - @backstage/plugin-catalog@0.2.12 - -## 0.3.2 - -### Patch Changes - -- 88da267cc: Port to new composability API by exporting new `EntitySentryContent` and `EntitySentryCard` component extensions. -- Updated dependencies [9c09a364f] - - @backstage/plugin-catalog@0.2.10 - -## 0.3.1 - -### Patch Changes - -- 962d1ad66: Added configuration schema for the commonly used properties -- Updated dependencies [c911061b7] -- Updated dependencies [8ef71ed32] -- Updated dependencies [0e6298f7e] -- Updated dependencies [ac3560b42] - - @backstage/catalog-model@0.6.0 - - @backstage/core@0.4.1 - -## 0.3.0 - -### Minor Changes - -- 075d3dc5a: The plugin uses the `proxy-backend` instead of a custom `sentry-backend`. - It requires a proxy configuration: - - `app-config.yaml`: - - ```yaml - proxy: - '/sentry/api': - target: https://sentry.io/api/ - allowedMethods: ['GET'] - headers: - Authorization: - $env: SENTRY_TOKEN # export SENTRY_TOKEN="Bearer " - ``` - - The `MockApiBackend` is no longer configured by the `NODE_ENV` variable. - Instead, the mock backend can be used with an api-override: - - `packages/app/src/apis.ts`: - - ```ts - import { createApiFactory } from '@backstage/core'; - import { MockSentryApi, sentryApiRef } from '@backstage/plugin-sentry'; - - export const apis = [ - // ... - - createApiFactory(sentryApiRef, new MockSentryApi()), - ]; - ``` - - If you already use the Sentry backend, you must remove it from the backend: - - Delete `packages/backend/src/plugins/sentry.ts`. - - ```diff - # packages/backend/package.json - - ... - "@backstage/plugin-scaffolder-backend": "^0.3.2", - - "@backstage/plugin-sentry-backend": "^0.1.3", - "@backstage/plugin-techdocs-backend": "^0.3.0", - ... - ``` - - ```diff - // packages/backend/src/index.html - - const apiRouter = Router(); - apiRouter.use('/catalog', await catalog(catalogEnv)); - apiRouter.use('/rollbar', await rollbar(rollbarEnv)); - apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); - - apiRouter.use('/sentry', await sentry(sentryEnv)); - apiRouter.use('/auth', await auth(authEnv)); - apiRouter.use('/techdocs', await techdocs(techdocsEnv)); - apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv)); - apiRouter.use('/proxy', await proxy(proxyEnv)); - apiRouter.use('/graphql', await graphql(graphqlEnv)); - apiRouter.use(notFoundHandler()); - ``` - -### Patch Changes - -- Updated dependencies [2527628e1] -- Updated dependencies [1c69d4716] -- Updated dependencies [83b6e0c1f] -- Updated dependencies [1665ae8bb] -- Updated dependencies [04f26f88d] -- Updated dependencies [ff243ce96] - - @backstage/core@0.4.0 - - @backstage/catalog-model@0.5.0 - - @backstage/theme@0.2.2 - -## 0.2.4 - -### Patch Changes - -- 303c5ea17: Refactor route registration to remove deprecating code -- Updated dependencies [08835a61d] -- Updated dependencies [a9fd599f7] -- Updated dependencies [bcc211a08] - - @backstage/catalog-model@0.4.0 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies [475fc0aaa] -- Updated dependencies [1166fcc36] -- Updated dependencies [1185919f3] - - @backstage/core@0.3.2 - - @backstage/catalog-model@0.3.0 - -## 0.2.2 - -### Patch Changes - -- 1722cb53c: Added configuration schema -- Updated dependencies [1722cb53c] - - @backstage/core@0.3.1 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies [7b37d65fd] -- Updated dependencies [4aca74e08] -- Updated dependencies [e8f69ba93] -- Updated dependencies [0c0798f08] -- Updated dependencies [0c0798f08] -- Updated dependencies [199237d2f] -- Updated dependencies [6627b626f] -- Updated dependencies [4577e377b] - - @backstage/core@0.3.0 - - @backstage/theme@0.2.1 - -## 0.2.0 - -### Minor Changes - -- 28edd7d29: Create backend plugin through CLI - -### Patch Changes - -- Updated dependencies [819a70229] -- Updated dependencies [3a4236570] -- Updated dependencies [ae5983387] -- Updated dependencies [0d4459c08] -- Updated dependencies [482b6313d] -- Updated dependencies [e0be86b6f] -- Updated dependencies [f70a52868] -- Updated dependencies [12b5fe940] -- Updated dependencies [1c60f716e] -- Updated dependencies [144c66d50] -- Updated dependencies [a768a07fb] -- Updated dependencies [b79017fd3] -- Updated dependencies [6d97d2d6f] -- Updated dependencies [5adfc005e] -- Updated dependencies [93a3fa3ae] -- Updated dependencies [782f3b354] -- Updated dependencies [2713f28f4] -- Updated dependencies [406015b0d] -- Updated dependencies [82759d3e4] -- Updated dependencies [ac8d5d5c7] -- Updated dependencies [fa56f4615] -- Updated dependencies [ebca83d48] -- Updated dependencies [aca79334f] -- Updated dependencies [c0d5242a0] -- Updated dependencies [b3d57961c] -- Updated dependencies [3beb5c9fc] -- Updated dependencies [754e31db5] -- Updated dependencies [1611c6dbc] - - @backstage/core@0.2.0 - - @backstage/catalog-model@0.2.0 - - @backstage/theme@0.2.0 diff --git a/plugins/sentry/README.md b/plugins/sentry/README.md deleted file mode 100644 index 78f31952b2..0000000000 --- a/plugins/sentry/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# Sentry Plugin - -The Sentry Plugin displays issues from [Sentry](https://sentry.io). - -![Sentry Card](./docs/sentry-card.png) - -## Getting Started - -1. Install the Sentry Plugin: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-sentry -``` - -2. Add the `EntitySentryCard` to the EntityPage: - -```jsx -// packages/app/src/components/catalog/EntityPage.tsx - -import { EntitySentryCard } from '@backstage/plugin-sentry'; - -const overviewContent = ( - - // ... - - - - // ... - -); -``` - -> You can also import the full-page `EntitySentryContent` extension if you want to have a dedicated sentry page: -> -> ```tsx -> // packages/app/src/components/catalog/EntityPage.tsx -> -> import { EntitySentryContent } from '@backstage/plugin-sentry'; -> -> const serviceEntityPage = ( -> -> // ... -> -> -> -> // ... -> -> ); -> ``` - -3. Add the proxy config: - -```yaml -# app-config.yaml - -proxy: - '/sentry/api': - target: https://sentry.io/api/ - allowedMethods: ['GET'] - headers: - Authorization: Bearer ${SENTRY_TOKEN} - -sentry: - organization: -``` - -4. Create a new internal integration with the permissions `Issues & Events: Read` (https://docs.sentry.io/product/integrations/integration-platform/) and provide it as `SENTRY_TOKEN` as env variable. - -5. Add the `sentry.io/project-slug` annotation to your catalog-info.yaml file: - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage - description: | - Backstage is an open-source developer portal that puts the developer experience first. - annotations: - sentry.io/project-slug: YOUR_PROJECT_SLUG -spec: - type: library - owner: CNCF - lifecycle: experimental -``` - -### Demo Mode - -The plugin provides a MockAPI that always returns dummy data instead of talking to the sentry backend. -You can add it by overriding the `sentryApiRef`: - -```ts -// packages/app/src/apis.ts - -import { createApiFactory } from '@backstage/core-plugin-api'; -import { MockSentryApi, sentryApiRef } from '@backstage/plugin-sentry'; - -export const apis = [ - // ... - - createApiFactory(sentryApiRef, new MockSentryApi()), -]; -``` diff --git a/plugins/sentry/api-report.md b/plugins/sentry/api-report.md deleted file mode 100644 index dc5fb69556..0000000000 --- a/plugins/sentry/api-report.md +++ /dev/null @@ -1,153 +0,0 @@ -## API Report File for "@backstage/plugin-sentry" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { InfoCardVariants } from '@backstage/core-components'; -import { Options } from '@material-table/core'; -import { default as React_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export const EntitySentryCard: (props: SentryPageProps) => React_2.JSX.Element; - -// @public (undocumented) -export const EntitySentryContent: ( - props: SentryPageProps, -) => React_2.JSX.Element; - -// @public (undocumented) -export type EventPoint = number[]; - -// @public -export const isSentryAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export class MockSentryApi implements SentryApi { - // (undocumented) - fetchIssues(): Promise; -} - -// @public (undocumented) -export class ProductionSentryApi implements SentryApi { - constructor( - discoveryApi: DiscoveryApi, - organization: string, - identityApi?: IdentityApi | undefined, - ); - // (undocumented) - fetchIssues( - entity: Entity, - options: { - statsFor: string; - query?: string; - }, - ): Promise; -} - -// @public (undocumented) -export const Router: (props: { entity: Entity }) => React_2.JSX.Element; - -// @public (undocumented) -export interface SentryApi { - // (undocumented) - fetchIssues( - entity: Entity, - options: { - statsFor: string; - query?: string; - }, - ): Promise; -} - -// @public (undocumented) -export type SentryApiError = { - detail: string; -}; - -// @public (undocumented) -export const sentryApiRef: ApiRef; - -// @public (undocumented) -export type SentryIssue = { - platform: SentryPlatform; - lastSeen: string; - numComments: number; - userCount: number; - stats: { - '24h'?: EventPoint[]; - '14d'?: EventPoint[]; - }; - culprit: string; - title: string; - id: string; - assignedTo: any; - logger: any; - type: string; - annotations: any[]; - metadata: SentryIssueMetadata; - status: string; - subscriptionDetails: any; - isPublic: boolean; - hasSeen: boolean; - shortId: string; - shareId: string | null; - firstSeen: string; - count: string; - permalink: string; - level: string; - isSubscribed: boolean; - isBookmarked: boolean; - project: SentryProject; - statusDetails: any; -}; - -// @public (undocumented) -export type SentryIssueMetadata = { - function?: string; - type?: string; - value?: string; - filename?: string; -}; - -// @public (undocumented) -export const SentryIssuesWidget: (props: { - entity: Entity; - statsFor: '24h' | '14d' | ''; - tableOptions: Options; - variant?: InfoCardVariants; - query?: string; -}) => React_2.JSX.Element; - -// @public (undocumented) -export type SentryPageProps = { - statsFor?: '24h' | '14d' | ''; - tableOptions?: Options; -}; - -// @public (undocumented) -export type SentryPlatform = 'javascript' | 'javascript-react' | string; - -// @public (undocumented) -const sentryPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -export { sentryPlugin as plugin }; -export { sentryPlugin }; - -// @public (undocumented) -export type SentryProject = { - platform: SentryPlatform; - slug: string; - id: string; - name: string; -}; -``` diff --git a/plugins/sentry/catalog-info.yaml b/plugins/sentry/catalog-info.yaml deleted file mode 100644 index 863361fe4d..0000000000 --- a/plugins/sentry/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-sentry - title: '@backstage/plugin-sentry' - description: A Backstage plugin that integrates towards Sentry -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/sentry/config.d.ts b/plugins/sentry/config.d.ts deleted file mode 100644 index 83172965f6..0000000000 --- a/plugins/sentry/config.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the sentry plugin */ - sentry: { - /** - * The 'organization' attribute - * @visibility frontend - */ - organization: string; - }; -} diff --git a/plugins/sentry/dev/index.tsx b/plugins/sentry/dev/index.tsx deleted file mode 100644 index 667f965354..0000000000 --- a/plugins/sentry/dev/index.tsx +++ /dev/null @@ -1,110 +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 { Entity } from '@backstage/catalog-model'; -import { createDevApp, EntityGridItem } from '@backstage/dev-utils'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { Grid } from '@material-ui/core'; -import React from 'react'; -import { - EntitySentryCard, - EntitySentryContent, - MockSentryApi, - SentryApi, - sentryApiRef, -} from '../src'; -import { - SENTRY_PROJECT_SLUG_ANNOTATION, - getProjectSlug, -} from '../src/api/annotations'; -import { Content, Header, Page } from '@backstage/core-components'; - -const entity = (name?: string) => - ({ - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - annotations: { - [SENTRY_PROJECT_SLUG_ANNOTATION]: name, - }, - name: name, - }, - } as Entity); - -createDevApp() - .registerApi({ - api: sentryApiRef, - deps: {}, - factory: () => - ({ - fetchIssues: async (e: Entity) => { - switch (getProjectSlug(e)) { - case 'error': - throw new Error('Error!'); - - case 'never': - return new Promise(() => {}); - - case 'with-values': - return new MockSentryApi().fetchIssues(); - - default: - return []; - } - }, - } as SentryApi), - }) - .addPage({ - title: 'Entity Content', - element: ( - -
- - - - - - - ), - }) - .addPage({ - title: 'Cards', - element: ( - -
- - - - - - - - - - - - - - - - - - - - - ), - }) - .render(); diff --git a/plugins/sentry/docs/sentry-card.png b/plugins/sentry/docs/sentry-card.png deleted file mode 100644 index 29fefe32e2..0000000000 Binary files a/plugins/sentry/docs/sentry-card.png and /dev/null differ diff --git a/plugins/sentry/knip-report.md b/plugins/sentry/knip-report.md deleted file mode 100644 index ed7c1e61f0..0000000000 --- a/plugins/sentry/knip-report.md +++ /dev/null @@ -1,15 +0,0 @@ -# Knip report - -## Unused dependencies (1) - -| Name | Location | Severity | -| :------------ | :----------- | :------- | -| @date-io/core | package.json | error | - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json deleted file mode 100644 index f81b1d11a0..0000000000 --- a/plugins/sentry/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "@backstage/plugin-sentry", - "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.5.15-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/sentry" - }, - "keywords": [ - "backstage", - "sentry" - ], - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@date-io/core": "^1.3.13", - "@material-table/core": "^3.1.0", - "@material-ui/core": "^4.12.2", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "luxon": "^3.0.0", - "react-sparklines": "^1.7.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@types/luxon": "^3.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/sentry/src/api/annotations.test.ts b/plugins/sentry/src/api/annotations.test.ts deleted file mode 100644 index 633966dc10..0000000000 --- a/plugins/sentry/src/api/annotations.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 { Entity } from '@backstage/catalog-model'; -import { - getOrganization, - getProjectSlug, - SENTRY_PROJECT_SLUG_ANNOTATION, -} from './annotations'; - -const entity = (name?: string) => - ({ - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - annotations: { - [SENTRY_PROJECT_SLUG_ANNOTATION]: name, - }, - name: 'something', - }, - } as Entity); - -describe('sentry annotations', () => { - it('getOrganization should works', () => { - const data = [ - [entity('orgs/some'), 'orgs'], - [entity('spotify/some'), 'spotify'], - [entity('slug'), ''], - ]; - - data.map(([input, expected]) => - expect(getOrganization(input as Entity)).toBe(expected), - ); - }); - it('getProjectSlug should works', () => { - const data = [ - [entity('orgs/some'), 'some'], - [entity('spotify/some'), 'some'], - [entity('slug'), 'slug'], - [entity(''), ''], - ]; - - data.map(([input, expected]) => - expect(getProjectSlug(input as Entity)).toBe(expected), - ); - }); -}); diff --git a/plugins/sentry/src/api/annotations.ts b/plugins/sentry/src/api/annotations.ts deleted file mode 100644 index 169dc59ca0..0000000000 --- a/plugins/sentry/src/api/annotations.ts +++ /dev/null @@ -1,36 +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 { Entity } from '@backstage/catalog-model'; - -export const SENTRY_PROJECT_SLUG_ANNOTATION = 'sentry.io/project-slug'; - -// The value can be the format of `[organization]/[project-slug]` or just `[project-slug] -const parseAnnotation = (entity: Entity) => { - return (entity?.metadata.annotations?.[SENTRY_PROJECT_SLUG_ANNOTATION] ?? '') - .split('/') - .reverse(); -}; - -export const getProjectSlug = (entity: Entity) => { - const [projectSlug, _] = parseAnnotation(entity); - return projectSlug ?? ''; -}; - -export const getOrganization = (entity: Entity) => { - const [_, organization] = parseAnnotation(entity); - return organization ?? ''; -}; diff --git a/plugins/sentry/src/api/index.ts b/plugins/sentry/src/api/index.ts deleted file mode 100644 index 9ae6d4eea2..0000000000 --- a/plugins/sentry/src/api/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './mock'; -export type { SentryApi } from './sentry-api'; -export { sentryApiRef } from './sentry-api'; -export type { - EventPoint, - SentryApiError, - SentryIssue, - SentryIssueMetadata, - SentryPlatform, - SentryProject, -} from './sentry-issue'; -export { ProductionSentryApi } from './production-api'; diff --git a/plugins/sentry/src/api/mock/index.ts b/plugins/sentry/src/api/mock/index.ts deleted file mode 100644 index 743f660baf..0000000000 --- a/plugins/sentry/src/api/mock/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { MockSentryApi } from './mock-api'; diff --git a/plugins/sentry/src/api/mock/mock-api.ts b/plugins/sentry/src/api/mock/mock-api.ts deleted file mode 100644 index 4f9f4254fc..0000000000 --- a/plugins/sentry/src/api/mock/mock-api.ts +++ /dev/null @@ -1,45 +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 { SentryIssue } from '../sentry-issue'; -import { SentryApi } from '../sentry-api'; -import mockData from './sentry-issue-mock.json'; - -function getMockIssue(): SentryIssue { - const randomizedStats = { - '24h': new Array(24) - .fill(0) - .map(() => [0, Math.floor(Math.random() * 100)]), - }; - return { - ...mockData, - userCount: Math.floor(Math.random() * 1000), - stats: randomizedStats, - }; -} - -function getMockIssues(number: number): SentryIssue[] { - return new Array(number).fill(0).map(getMockIssue); -} - -/** @public */ -export class MockSentryApi implements SentryApi { - fetchIssues(): Promise { - return new Promise(resolve => { - setTimeout(() => resolve(getMockIssues(14)), 800); - }); - } -} diff --git a/plugins/sentry/src/api/mock/sentry-issue-mock.json b/plugins/sentry/src/api/mock/sentry-issue-mock.json deleted file mode 100644 index 34201d56ee..0000000000 --- a/plugins/sentry/src/api/mock/sentry-issue-mock.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "platform": "javascript", - "lastSeen": "2020-05-15T09:17:17.384804Z", - "numComments": 0, - "userCount": 0, - "stats": { - "24h": [ - [1589450400, 7], - [1589454000, 2], - [1589457600, 6], - [1589461200, 8], - [1589464800, 9], - [1589468400, 11], - [1589472000, 4], - [1589475600, 19], - [1589479200, 3], - [1589482800, 24], - [1589486400, 8], - [1589490000, 5], - [1589493600, 5], - [1589497200, 10], - [1589500800, 16], - [1589504400, 24], - [1589508000, 24], - [1589511600, 54], - [1589515200, 4], - [1589518800, 7], - [1589522400, 4], - [1589526000, 4], - [1589529600, 13], - [1589533200, 1] - ] - }, - "culprit": "https://www.example.com/de/account//", - "title": "TypeError: Failed to fetch", - "id": "991214716", - "assignedTo": null, - "logger": null, - "type": "error", - "annotations": [], - "metadata": { "type": "TypeError", "value": "Failed to fetch" }, - "status": "unresolved", - "subscriptionDetails": null, - "isPublic": false, - "hasSeen": true, - "shortId": "example-slug-21", - "shareId": null, - "firstSeen": "2019-04-18T23:36:40.988000Z", - "count": "169815", - "permalink": "https://sentry.io/organizations/example/issues/99176416/", - "level": "error", - "isSubscribed": false, - "isBookmarked": false, - "project": { - "platform": "javascript-react", - "slug": "example-slug", - "id": "1282343", - "name": "example-slug" - }, - "statusDetails": {} -} diff --git a/plugins/sentry/src/api/production-api.ts b/plugins/sentry/src/api/production-api.ts deleted file mode 100644 index 7fe4afdf98..0000000000 --- a/plugins/sentry/src/api/production-api.ts +++ /dev/null @@ -1,75 +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 { SentryIssue } from './sentry-issue'; -import { SentryApi } from './sentry-api'; -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, - private readonly organization: string, - private readonly identityApi?: IdentityApi, - ) {} - - async fetchIssues( - entity: Entity, - options: { - statsFor: string; - query?: string; - }, - ): Promise { - const { query, statsFor } = options; - - const project = getProjectSlug(entity); - const organization = getOrganization(entity) || this.organization; - - if (!project) { - return []; - } - - const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/sentry/api`; - const authOpts = await this.authOptions(); - - const queryPart = query ? `&query=${query}` : ''; - - const response = await fetch( - `${apiUrl}/0/projects/${organization}/${project}/issues/?statsPeriod=${statsFor}${queryPart}`, - authOpts, - ); - - if (response.status >= 400 && response.status < 600) { - throw new Error('Failed fetching Sentry issues'); - } - - return (await response.json()) as SentryIssue[]; - } - - private async authOptions() { - if (!this.identityApi) { - return {}; - } - const { token } = await this.identityApi.getCredentials(); - return { - headers: { - authorization: `Bearer ${token}`, - }, - }; - } -} diff --git a/plugins/sentry/src/api/sentry-api.ts b/plugins/sentry/src/api/sentry-api.ts deleted file mode 100644 index 73f1301cad..0000000000 --- a/plugins/sentry/src/api/sentry-api.ts +++ /dev/null @@ -1,35 +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 { 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, - options: { - statsFor: string; - query?: string; - }, - ): Promise; -} diff --git a/plugins/sentry/src/api/sentry-issue.ts b/plugins/sentry/src/api/sentry-issue.ts deleted file mode 100644 index e25cf88829..0000000000 --- a/plugins/sentry/src/api/sentry-issue.ts +++ /dev/null @@ -1,76 +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. - */ - -/** @public */ -export type SentryPlatform = 'javascript' | 'javascript-react' | string; - -/** @public */ -export type EventPoint = number[]; - -/** @public */ -export type SentryProject = { - platform: SentryPlatform; - slug: string; - id: string; - name: string; -}; - -/** @public */ -export type SentryIssueMetadata = { - function?: string; - type?: string; - value?: string; - filename?: string; -}; - -/** @public */ -export type SentryIssue = { - platform: SentryPlatform; - lastSeen: string; - numComments: number; - userCount: number; - stats: { - '24h'?: EventPoint[]; - '14d'?: EventPoint[]; - }; - culprit: string; - title: string; - id: string; - assignedTo: any; - logger: any; - type: string; - annotations: any[]; - metadata: SentryIssueMetadata; - status: string; - subscriptionDetails: any; - isPublic: boolean; - hasSeen: boolean; - shortId: string; - shareId: string | null; - firstSeen: string; - count: string; - permalink: string; - level: string; - isSubscribed: boolean; - isBookmarked: boolean; - project: SentryProject; - statusDetails: any; -}; - -/** @public */ -export type SentryApiError = { - detail: string; -}; diff --git a/plugins/sentry/src/components/ErrorCell/ErrorCell.test.tsx b/plugins/sentry/src/components/ErrorCell/ErrorCell.test.tsx deleted file mode 100644 index 22cb5cf0a0..0000000000 --- a/plugins/sentry/src/components/ErrorCell/ErrorCell.test.tsx +++ /dev/null @@ -1,57 +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 { ErrorCell } from './ErrorCell'; -import React from 'react'; -import mockIssue from '../../api/mock/sentry-issue-mock.json'; -import { renderInTestApp } from '@backstage/test-utils'; - -describe('Sentry error cell component', () => { - it('should render a link that lead to Sentry', async () => { - const testIssue = { - ...mockIssue, - metadata: { - type: 'Exception', - value: 'exception was thrown', - }, - count: '1', - userCount: 2, - permalink: 'http://example.com', - }; - const cell = await renderInTestApp(); - const errorType = await cell.findByText('Exception'); - expect(errorType.closest('a')).toHaveAttribute( - 'href', - 'http://example.com', - ); - }); - it('should render the title if type is not present', async () => { - const testIssue = { - ...mockIssue, - title: 'Exception: Could not load credentials from any providers', - count: '1', - metadata: {}, - userCount: 2, - permalink: 'http://example.com', - }; - const cell = await renderInTestApp(); - const errorType = await cell.findByText('Exception: Could not load cr...'); - expect(errorType.closest('a')).toHaveAttribute( - 'href', - 'http://example.com', - ); - }); -}); diff --git a/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx b/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx deleted file mode 100644 index 2a0e0fbb69..0000000000 --- a/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx +++ /dev/null @@ -1,73 +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 { SentryIssue } from '../../api'; -import { Typography } from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; -import { Link } from '@backstage/core-components'; - -function stripText(text: string, maxLength: number) { - return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; -} - -const useStyles = makeStyles(theme => ({ - root: { - minWidth: 260, - position: 'relative', - '&::before': { - left: -16, - position: 'absolute', - width: '4px', - height: '100%', - content: '""', - backgroundColor: theme.palette.status.error, - borderRadius: 2, - }, - }, - text: { - marginBottom: 0, - }, -})); - -export const ErrorCell = ({ sentryIssue }: { sentryIssue: SentryIssue }) => { - const classes = useStyles(); - let issueType = '[No Type]'; - if (sentryIssue.metadata.type) { - issueType = sentryIssue.metadata.type; - } else if (sentryIssue.title) { - issueType = sentryIssue.title; - } - - return ( -
- - - {stripText(issueType, 28)} - - - - {sentryIssue.metadata.value && - stripText(sentryIssue.metadata.value, 48)} - -
- ); -}; diff --git a/plugins/sentry/src/components/ErrorGraph/ErrorGraph.tsx b/plugins/sentry/src/components/ErrorGraph/ErrorGraph.tsx deleted file mode 100644 index 0448b7cfea..0000000000 --- a/plugins/sentry/src/components/ErrorGraph/ErrorGraph.tsx +++ /dev/null @@ -1,32 +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 { SentryIssue } from '../../api'; -import { Sparklines, SparklinesBars } from 'react-sparklines'; - -export const ErrorGraph = ({ sentryIssue }: { sentryIssue: SentryIssue }) => { - const data = - '14d' in sentryIssue.stats - ? sentryIssue.stats['14d'] - : sentryIssue.stats['24h']; - - return ( - val)} svgHeight={48} margin={4}> - - - ); -}; diff --git a/plugins/sentry/src/components/Router.tsx b/plugins/sentry/src/components/Router.tsx deleted file mode 100644 index 766a3eaa14..0000000000 --- a/plugins/sentry/src/components/Router.tsx +++ /dev/null @@ -1,44 +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 { Entity } from '@backstage/catalog-model'; -import { Route, Routes } from 'react-router-dom'; -import { SentryIssuesWidget } from './SentryIssuesWidget'; - -/** @public */ -export const Router = (props: { entity: Entity }) => { - return ( - - - } - /> - ) - - ); -}; diff --git a/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.test.tsx b/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.test.tsx deleted file mode 100644 index 6e04e65ef0..0000000000 --- a/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.test.tsx +++ /dev/null @@ -1,112 +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 SentryIssuesTable from './SentryIssuesTable'; -import { SentryIssue } from '../../api'; -import mockIssue from '../../api/mock/sentry-issue-mock.json'; -import { renderInTestApp } from '@backstage/test-utils'; -import { DateTime } from 'luxon'; - -describe('SentryIssuesTable', () => { - it('should render headers in a table', async () => { - const issues: SentryIssue[] = [ - { - ...mockIssue, - metadata: { - type: 'Exception', - value: 'exception was thrown', - }, - count: '1', - userCount: 2, - }, - ]; - const table = await renderInTestApp( - , - ); - expect(await table.findByText('Error')).toBeInTheDocument(); - expect(await table.findByText('Graph')).toBeInTheDocument(); - expect(await table.findByText('First seen')).toBeInTheDocument(); - expect(await table.findByText('Last seen')).toBeInTheDocument(); - expect(await table.findByText('Events')).toBeInTheDocument(); - expect(await table.findByText('Users')).toBeInTheDocument(); - }); - it('should render values in a table', async () => { - const issues: SentryIssue[] = [ - { - ...mockIssue, - metadata: { - type: 'Exception', - value: 'exception was thrown', - }, - count: '101', - userCount: 202, - lastSeen: DateTime.now().toISO()!, - }, - ]; - const table = await renderInTestApp( - , - ); - expect(await table.findByText('Exception')).toBeInTheDocument(); - expect(await table.findByText('exception was thrown')).toBeInTheDocument(); - expect(await table.findByText('101')).toBeInTheDocument(); - expect(await table.findByText('202')).toBeInTheDocument(); - }); - it('should render statsFor in table subtitle', async () => { - const issues: SentryIssue[] = [ - { - ...mockIssue, - metadata: { - type: 'Exception', - value: 'exception was thrown', - }, - count: '101', - userCount: 202, - }, - ]; - const table = await renderInTestApp( - , - ); - expect(await table.findByText('Stats for 24h')).toBeInTheDocument(); - }); -}); diff --git a/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx b/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx deleted file mode 100644 index 8f336c629b..0000000000 --- a/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx +++ /dev/null @@ -1,130 +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, { useCallback, useState } from 'react'; -import { SentryIssue } from '../../api'; -import { DateTime, Duration } from 'luxon'; -import { ErrorCell } from '../ErrorCell/ErrorCell'; -import { ErrorGraph } from '../ErrorGraph/ErrorGraph'; -import { Table, TableColumn } from '@backstage/core-components'; -import Select from '@material-ui/core/Select'; -import { Options } from '@material-table/core'; -import { FormControl, Grid, MenuItem } from '@material-ui/core'; - -const ONE_DAY_IN_MILLIS = 86400000; -const SEVEN_DAYS_IN_MILLIS = ONE_DAY_IN_MILLIS * 7; -const FOURTEEN_DAYS_IN_MILLIS = ONE_DAY_IN_MILLIS * 14; - -const columns: TableColumn[] = [ - { - title: 'Error', - render: data => , - }, - { - title: 'Graph', - render: data => , - }, - { - title: 'First seen', - field: 'firstSeen', - render: data => { - const { firstSeen } = data as SentryIssue; - - return DateTime.fromISO(firstSeen).toRelative({ locale: 'en' }); - }, - }, - { - title: 'Last seen', - field: 'lastSeen', - render: data => { - const { lastSeen } = data as SentryIssue; - return DateTime.fromISO(lastSeen).toRelative({ locale: 'en' }); - }, - }, - { - title: 'Events', - field: 'count', - }, - { - title: 'Users', - field: 'userCount', - }, -]; - -type SentryIssuesTableProps = { - sentryIssues: SentryIssue[]; - statsFor: '24h' | '14d' | ''; - tableOptions: Options; -}; - -const SentryIssuesTable = (props: SentryIssuesTableProps) => { - const { sentryIssues, statsFor, tableOptions } = props; - const [selected, setSelected] = useState(ONE_DAY_IN_MILLIS); - - const filterByDate = useCallback( - (issue: SentryIssue, selectedFilter: number) => { - return ( - DateTime.fromISO(issue.lastSeen) > - DateTime.now().minus(Duration.fromMillis(selectedFilter)) - ); - }, - [], - ); - const [filteredIssues, setFilteredIssues] = useState( - sentryIssues.filter(i => filterByDate(i, selected)), - ); - - const handleFilterChange = ( - event: React.ChangeEvent<{ name?: string; value: unknown }>, - ) => { - const item = event.target.value; - if (typeof item === 'number') { - setSelected(item); - if (item === Number.NEGATIVE_INFINITY) { - setFilteredIssues(sentryIssues); - return; - } - setFilteredIssues(sentryIssues.filter(i => filterByDate(i, item))); - } - }; - return ( - <> -
- Sentry Issues - - - - - - - } - subtitle={statsFor ? `Stats for ${statsFor}` : undefined} - data={filteredIssues} - /> - - ); -}; - -export default SentryIssuesTable; diff --git a/plugins/sentry/src/components/SentryIssuesWidget/SentryIssuesWidget.tsx b/plugins/sentry/src/components/SentryIssuesWidget/SentryIssuesWidget.tsx deleted file mode 100644 index 4db2721efb..0000000000 --- a/plugins/sentry/src/components/SentryIssuesWidget/SentryIssuesWidget.tsx +++ /dev/null @@ -1,95 +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 { Entity } from '@backstage/catalog-model'; -import React, { useEffect } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { sentryApiRef } from '../../api'; -import SentryIssuesTable from '../SentryIssuesTable/SentryIssuesTable'; -import { SENTRY_PROJECT_SLUG_ANNOTATION, useProjectSlug } from '../hooks'; -import { MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react'; - -import { - EmptyState, - InfoCard, - InfoCardVariants, - Progress, -} from '@backstage/core-components'; - -import { ErrorApi, errorApiRef, useApi } from '@backstage/core-plugin-api'; -import { Options } from '@material-table/core'; - -/** @public */ -export const SentryIssuesWidget = (props: { - entity: Entity; - statsFor: '24h' | '14d' | ''; - tableOptions: Options; - variant?: InfoCardVariants; - query?: string; -}) => { - const { - entity, - statsFor, - tableOptions, - variant = 'gridItem', - query = '', - } = props; - const errorApi = useApi(errorApiRef); - const sentryApi = useApi(sentryApiRef); - - const projectId = useProjectSlug(entity); - - const { loading, value, error } = useAsync( - () => sentryApi.fetchIssues(entity, { statsFor, query }), - [sentryApi, statsFor, projectId, query], - ); - - useEffect(() => { - if (error) { - errorApi.post(error); - } - }, [error, errorApi]); - - if (loading || !projectId || error) { - return ( - - {loading && } - - {!loading && !projectId && ( - - )} - - {!loading && error && ( - - )} - - ); - } - - return ( - - ); -}; diff --git a/plugins/sentry/src/components/SentryIssuesWidget/index.ts b/plugins/sentry/src/components/SentryIssuesWidget/index.ts deleted file mode 100644 index 7be76f5983..0000000000 --- a/plugins/sentry/src/components/SentryIssuesWidget/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { SentryIssuesWidget } from './SentryIssuesWidget'; diff --git a/plugins/sentry/src/components/hooks.ts b/plugins/sentry/src/components/hooks.ts deleted file mode 100644 index 0f1cb08526..0000000000 --- a/plugins/sentry/src/components/hooks.ts +++ /dev/null @@ -1,25 +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 { - getProjectSlug, - getOrganization, - SENTRY_PROJECT_SLUG_ANNOTATION, -} from '../api/annotations'; - -export const useProjectSlug = getProjectSlug; -export const useOrganization = getOrganization; -export { SENTRY_PROJECT_SLUG_ANNOTATION }; diff --git a/plugins/sentry/src/components/index.ts b/plugins/sentry/src/components/index.ts deleted file mode 100644 index 9af8a05853..0000000000 --- a/plugins/sentry/src/components/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './SentryIssuesWidget'; -export { isSentryAvailable } from './isSentryAvailable'; diff --git a/plugins/sentry/src/components/isSentryAvailable.ts b/plugins/sentry/src/components/isSentryAvailable.ts deleted file mode 100644 index a0803f6b45..0000000000 --- a/plugins/sentry/src/components/isSentryAvailable.ts +++ /dev/null @@ -1,25 +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 { Entity } from '@backstage/catalog-model'; -import { SENTRY_PROJECT_SLUG_ANNOTATION } from './hooks'; - -/** - * @public - * Checks to see if sentry is available - */ -export const isSentryAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[SENTRY_PROJECT_SLUG_ANNOTATION]); diff --git a/plugins/sentry/src/extensions.tsx b/plugins/sentry/src/extensions.tsx deleted file mode 100644 index 2dc2f7fb9d..0000000000 --- a/plugins/sentry/src/extensions.tsx +++ /dev/null @@ -1,92 +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 { useEntity } from '@backstage/plugin-catalog-react'; -import React from 'react'; -import { sentryPlugin, rootRouteRef } from './plugin'; -import { - createComponentExtension, - createRoutableExtension, -} from '@backstage/core-plugin-api'; -import { Options } from '@material-table/core'; - -/** @public */ -export type SentryPageProps = { - statsFor?: '24h' | '14d' | ''; - tableOptions?: Options; -}; - -/** @public */ -export const EntitySentryContent = sentryPlugin.provide( - createRoutableExtension({ - name: 'EntitySentryContent', - mountPoint: rootRouteRef, - component: () => - import('./components/SentryIssuesWidget').then( - ({ SentryIssuesWidget }) => { - const SentryPage = (props: SentryPageProps) => { - const { entity } = useEntity(); - const defaultOptions: Options = { - padding: 'dense', - paging: true, - search: false, - pageSize: 5, - }; - return ( - - ); - }; - return SentryPage; - }, - ), - }), -); - -/** @public */ -export const EntitySentryCard = sentryPlugin.provide( - createComponentExtension({ - name: 'EntitySentryCard', - component: { - lazy: () => - import('./components/SentryIssuesWidget').then( - ({ SentryIssuesWidget }) => { - const SentryCard = (props: SentryPageProps) => { - const { entity } = useEntity(); - return ( - - ); - }; - return SentryCard; - }, - ), - }, - }), -); diff --git a/plugins/sentry/src/index.ts b/plugins/sentry/src/index.ts deleted file mode 100644 index a3d4db7f5d..0000000000 --- a/plugins/sentry/src/index.ts +++ /dev/null @@ -1,28 +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. - */ - -/** - * A Backstage plugin that integrates towards Sentry - * - * @packageDocumentation - */ - -export * from './api'; -export * from './components'; -export { sentryPlugin, sentryPlugin as plugin } from './plugin'; -export type { SentryPageProps } from './extensions'; -export { EntitySentryCard, EntitySentryContent } from './extensions'; -export { Router } from './components/Router'; diff --git a/plugins/sentry/src/plugin.test.ts b/plugins/sentry/src/plugin.test.ts deleted file mode 100644 index 9b7d95abfb..0000000000 --- a/plugins/sentry/src/plugin.test.ts +++ /dev/null @@ -1,23 +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 { sentryPlugin } from './plugin'; - -describe('sentry', () => { - it('should export plugin', () => { - expect(sentryPlugin).toBeDefined(); - }); -}); diff --git a/plugins/sentry/src/plugin.ts b/plugins/sentry/src/plugin.ts deleted file mode 100644 index 51957b87a3..0000000000 --- a/plugins/sentry/src/plugin.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ProductionSentryApi, sentryApiRef } from './api'; -import { - configApiRef, - createApiFactory, - createPlugin, - createRouteRef, - discoveryApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; - -/** @public */ -export const rootRouteRef = createRouteRef({ - id: 'sentry', -}); - -/** @public */ -export const sentryPlugin = createPlugin({ - id: 'sentry', - apis: [ - createApiFactory({ - api: sentryApiRef, - deps: { - configApi: configApiRef, - discoveryApi: discoveryApiRef, - identityApi: identityApiRef, - }, - factory: ({ configApi, discoveryApi, identityApi }) => - new ProductionSentryApi( - discoveryApi, - configApi.getString('sentry.organization'), - identityApi, - ), - }), - ], - routes: { - root: rootRouteRef, - }, -}); diff --git a/plugins/sentry/src/setupTests.ts b/plugins/sentry/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/sentry/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/shortcuts/.eslintrc.js b/plugins/shortcuts/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/shortcuts/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md deleted file mode 100644 index b6aca6ee2e..0000000000 --- a/plugins/shortcuts/CHANGELOG.md +++ /dev/null @@ -1,1216 +0,0 @@ -# @backstage/plugin-shortcuts - -## 0.3.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.1-next.1 - - @backstage/core-components@0.14.0-next.2 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/types@1.1.1 - -## 0.3.19-next.1 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/theme@0.5.1-next.0 - - @backstage/types@1.1.1 - -## 0.3.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/theme@0.5.0 - - @backstage/types@1.1.1 - -## 0.3.18 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/theme@0.5.0 - - @backstage/types@1.1.1 - -## 0.3.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/theme@0.5.0 - - @backstage/types@1.1.1 - -## 0.3.18-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/core-plugin-api@1.8.1 - - @backstage/theme@0.5.0 - - @backstage/types@1.1.1 - -## 0.3.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/types@1.1.1 - -## 0.3.17-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/types@1.1.1 - -## 0.3.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/types@1.1.1 - -## 0.3.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.0 - - @backstage/types@1.1.1 - -## 0.3.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/types@1.1.1 - -## 0.3.16 - -### Patch Changes - -- 55725922a5: Ensure that shortcuts aren't duplicate-checked against themselves -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/types@1.1.1 - -## 0.3.16-next.2 - -### Patch Changes - -- [#20990](https://github.com/backstage/backstage/pull/20990) [`55725922a5`](https://github.com/backstage/backstage/commit/55725922a5d149ed6a5bb0d5976ec3130b14dd96) Thanks [@freben](https://github.com/freben)! - Ensure that shortcuts aren't duplicate-checked against themselves - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - -## 0.3.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/types@1.1.1 - -## 0.3.16-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/types@1.1.1 - -## 0.3.15 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/theme@0.4.3 - - @backstage/types@1.1.1 - -## 0.3.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/theme@0.4.3-next.0 - - @backstage/types@1.1.1 - -## 0.3.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/theme@0.4.2 - - @backstage/types@1.1.1 - -## 0.3.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/theme@0.4.2 - - @backstage/types@1.1.1 - -## 0.3.14 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - - @backstage/types@1.1.1 - -## 0.3.14-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/theme@0.4.2-next.0 - - @backstage/types@1.1.1-next.0 - -## 0.3.14-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - -## 0.3.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - -## 0.3.14-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - -## 0.3.13 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- ee52a48b63d5: Limit the use of the duplicate shortcut name when adding a shortcut -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - -## 0.3.13-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - -## 0.3.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - -## 0.3.12 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/types@1.1.0 - -## 0.3.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/types@1.1.0 - -## 0.3.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - -## 0.3.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/types@1.1.0 - -## 0.3.11 - -### Patch Changes - -- 2e036369d83b: Updated `alertApi` usages with severity of `info` or `success` to use `display: transient` -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/types@1.1.0 - - @backstage/theme@0.4.0 - -## 0.3.11-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/types@1.0.2 - -## 0.3.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.3.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/types@1.0.2 - -## 0.3.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/types@1.0.2 - -## 0.3.10 - -### Patch Changes - -- 8a7174e297c: Marked `LocalStoredShortcuts` as deprecated, replacing it with `DefaultShortcutsApi` whose naming more clearly suggests that the shortcuts aren't necessarily stored locally (it depends on the storage implementation). -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/core-components@0.13.1 - - @backstage/core-plugin-api@1.5.1 - - @backstage/types@1.0.2 - -## 0.3.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.10-next.0 - -### Patch Changes - -- 8a7174e297c: Marked `LocalStoredShortcuts` as deprecated, replacing it with `DefaultShortcutsApi` whose naming more clearly suggests that the shortcuts aren't necessarily stored locally (it depends on the storage implementation). -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/theme@0.2.19 - - @backstage/types@1.0.2 - -## 0.3.9 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- 328ec5f96c6: Added the Analytics event in the save handler of AddShortcut and EditShortcut -- 99df676e324: Allow external links to be added as shortcuts -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/types@1.0.2 - -## 0.3.9-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/types@1.0.2 - -## 0.3.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/types@1.0.2 - -## 0.3.9-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/theme@0.2.19-next.0 - - @backstage/types@1.0.2 - -## 0.3.9-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- 99df676e324: Allow external links to be added as shortcuts -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - - @backstage/types@1.0.2 - -## 0.3.8 - -### Patch Changes - -- cb8ec97cdeb: Change black & white colors to be theme aware -- 7c38e565d1f: Fixed bug in LocalStoredShortcuts client where adding new Shortcut results in replacing entire shortcut list. - - Refactored LocalStoredShortcuts client to listen to `storageApi` updates to ensure that local state is always up to date. - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - - @backstage/types@1.0.2 - -## 0.3.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.3.8-next.1 - -### Patch Changes - -- cb8ec97cdeb: Change black & white colors to be theme aware -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/types@1.0.2 - -## 0.3.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - - @backstage/types@1.0.2 - -## 0.3.7 - -### Patch Changes - -- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/types@1.0.2 - -## 0.3.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - -## 0.3.4 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. -- c3fa90e184: Updated dependency `zen-observable` to `^0.10.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/types@1.0.2 - - @backstage/theme@0.2.16 - -## 0.3.4-next.4 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2-next.1 - -## 0.3.4-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2-next.1 - -## 0.3.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2-next.1 - -## 0.3.4-next.1 - -### Patch Changes - -- c3fa90e184: Updated dependency `zen-observable` to `^0.10.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/theme@0.2.16 - -## 0.3.4-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 19356df560: Updated dependency `zen-observable` to `^0.9.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/theme@0.2.16 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/types@1.0.1 - - @backstage/theme@0.2.16 - -## 0.3.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.1-next.0 - -## 0.3.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/theme@0.2.16 - -## 0.3.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - -## 0.3.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - -## 0.3.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - -## 0.3.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - -## 0.3.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- 8a57ffc0fa: Ensure that a stable observable is used in the shortcuts API -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - -## 0.3.1-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.3.1-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.3.1-next.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - -## 0.3.1-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - -## 0.2.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/theme@0.2.16-next.1 - -## 0.2.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/theme@0.2.16-next.0 - -## 0.2.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.0 - -## 0.2.7 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - -## 0.2.7-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - -## 0.2.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.0 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - -## 0.2.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - -## 0.2.5 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.2.5-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - -## 0.2.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.3-next.0 - -## 0.2.4 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/types@1.0.0 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.1 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.1-next.0 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/core-plugin-api@0.7.0 - -## 0.2.0 - -### Minor Changes - -- dc9fd0acf9: Use Avatar instead of custom icon for ShortcutIcon - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/theme@0.2.15 - - @backstage/types@0.1.2 - -## 0.1.22 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - -## 0.1.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - -## 0.1.20 - -### Patch Changes - -- 7ba416be78: **@backstage/plugin-user-settings:** Hide Header on mobile screens to improve the UI & give more space to the content. Furthermore, the "Pin Sidebar" setting is removed on mobile screens, as the mobile sidebar is always pinned to the bottom. - - **Other plugins:** Smaller style adjustments across plugins to improve the UI on mobile devices. - -- c52ae0a73b: Allow shortcut side bar item icon to be configurable -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - -## 0.1.20-next.0 - -### Patch Changes - -- 7ba416be78: **@backstage/plugin-user-settings:** Hide Header on mobile screens to improve the UI & give more space to the content. Furthermore, the "Pin Sidebar" setting is removed on mobile screens, as the mobile sidebar is always pinned to the bottom. - - **Other plugins:** Smaller style adjustments across plugins to improve the UI on mobile devices. - -- c52ae0a73b: Allow shortcut side bar item icon to be configurable -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - -## 0.1.19 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - -## 0.1.18 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/core-components@0.8.3 - -## 0.1.17 - -### Patch Changes - -- b50cbd047b: Properly read saved shortcuts from StorageApi - -## 0.1.16 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/core-components@0.8.2 - -## 0.1.15 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - -## 0.1.14 - -### Patch Changes - -- f93e56ae3a: Add tooltip to display shortcut title on hover. This should improve the readability of shortcuts with long names, which are cutoff by ellipsis. -- Updated dependencies - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.1.13 - -### Patch Changes - -- 10615525f3: Switch to use the json and observable types from `@backstage/types` -- Updated dependencies - - @backstage/theme@0.2.12 - - @backstage/core-components@0.7.2 - - @backstage/core-plugin-api@0.1.12 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.1.11 - -### Patch Changes - -- ca0559444c: Avoid usage of `.to*Case()`, preferring `.toLocale*Case('en-US')` instead. -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - -## 0.1.8 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/core-plugin-api@0.1.8 - -## 0.1.7 - -### Patch Changes - -- e0a6aea82: Bumped `react-hook-form` to `^7.12.2` -- b8e8a3424: Fix material-ui warning about deprecated `onExit` prop -- Updated dependencies - - @backstage/core-components@0.4.0 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - -## 0.1.5 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.1.4 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - -## 0.1.3 - -### Patch Changes - -- 15ffc1ac9: Fix horizontal scroll bar appearance issue - -## 0.1.2 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- Updated dependencies [062bbf90f] -- Updated dependencies [889d89b6e] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 diff --git a/plugins/shortcuts/README.md b/plugins/shortcuts/README.md deleted file mode 100644 index 18deb7ae37..0000000000 --- a/plugins/shortcuts/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# shortcuts - -The shortcuts plugin allows a user to have easy access to pages within a Backstage app by storing them as "shortcuts" in the Sidebar. - -## Usage - -### Install the package: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-shortcuts -``` - -### Register plugin: - -This plugin requires explicit registration, so you will need to add it to your App's `plugins.ts` file: - -```ts -// ... -export { shortcutsPlugin } from '@backstage/plugin-shortcuts'; -``` - -If you don't have a `plugins.ts` file see: [troubleshooting](#troubleshooting) - -### Add the `` component within your ``: - -Edit file `packages/app/src/components/Root/Root.tsx` - -```tsx -import { - Sidebar, - SidebarDivider, - SidebarSpace, -} from '@backstage/core-components'; -import { Shortcuts } from '@backstage/plugin-shortcuts'; - -export const SidebarComponent = () => ( - - {/* ... */} - - - - -); -``` - -To allow external links to be added as shortcut, you can add `allowExternalLinks` property to the `` component. - -The plugin exports a `shortcutApiRef` but the plugin includes a default implementation of the `ShortcutApi` that uses `localStorage` to store each user's shortcuts. - -To overwrite the default implementation add it to the App's `apis.ts`: - -```ts -import { shortcutsApiRef } from '@backstage/plugin-shortcuts'; -import { CustomShortcutsImpl } from '...'; - -export const apis = [ - // ... - createApiFactory({ - api: shortcutsApiRef, - deps: {}, - factory: () => new CustomShortcutsImpl(), - }), -]; -``` - -# Troubleshooting - -If you don't have a `plugins.ts` file, you can create it with the path `packages/app/src/plugins.ts` and then import it into your `App.tsx`: - -```diff -+ import * as plugins from './plugins'; - -const app = createApp({ - apis, -+ plugins: Object.values(plugins), - bindRoutes({ bind }) { - /* ... */ - }, -}); -``` - -Or simply edit `App.tsx` with: - -```diff -+ import { shortcutsPlugin } from '@backstage/plugin-shortcuts - -const app = createApp({ - apis, -+ plugins: [shortcutsPlugin], - bindRoutes({ bind }) { - /* ... */ - }, -}); -``` diff --git a/plugins/shortcuts/api-report.md b/plugins/shortcuts/api-report.md deleted file mode 100644 index 64d9d15156..0000000000 --- a/plugins/shortcuts/api-report.md +++ /dev/null @@ -1,70 +0,0 @@ -## API Report File for "@backstage/plugin-shortcuts" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { IconComponent } from '@backstage/core-plugin-api'; -import { JSX as JSX_2 } from 'react'; -import { Observable } from '@backstage/types'; -import { Shortcut as Shortcut_2 } from '@backstage/plugin-shortcuts'; -import { ShortcutApi as ShortcutApi_2 } from '@backstage/plugin-shortcuts'; -import type { StorageApi } from '@backstage/core-plugin-api'; - -// @public -export class DefaultShortcutsApi implements ShortcutApi_2 { - constructor(storageApi: StorageApi); - // (undocumented) - add(shortcut: Omit): Promise; - // (undocumented) - get(): Shortcut_2[]; - // (undocumented) - getColor(url: string): string; - // (undocumented) - remove(id: string): Promise; - // (undocumented) - shortcut$(): Observable; - // (undocumented) - update(shortcut: Shortcut_2): Promise; -} - -// @public @deprecated (undocumented) -export const LocalStoredShortcuts: typeof DefaultShortcutsApi; - -// @public (undocumented) -export type Shortcut = { - id: string; - url: string; - title: string; -}; - -// @public (undocumented) -export interface ShortcutApi { - add(shortcut: Omit): Promise; - get(): Shortcut[]; - getColor(url: string): string; - remove(id: string): Promise; - shortcut$(): Observable; - update(shortcut: Shortcut): Promise; -} - -// @public (undocumented) -export const Shortcuts: (props: ShortcutsProps) => JSX_2.Element; - -// @public (undocumented) -export const shortcutsApiRef: ApiRef; - -// @public (undocumented) -export const shortcutsPlugin: BackstagePlugin<{}, {}>; - -// @public -export interface ShortcutsProps { - // (undocumented) - allowExternalLinks?: boolean; - // (undocumented) - icon?: IconComponent; -} -``` diff --git a/plugins/shortcuts/catalog-info.yaml b/plugins/shortcuts/catalog-info.yaml deleted file mode 100644 index cd17d626e6..0000000000 --- a/plugins/shortcuts/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-shortcuts - title: '@backstage/plugin-shortcuts' - description: A Backstage plugin that provides a shortcuts feature to the sidebar -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/shortcuts/dev/index.tsx b/plugins/shortcuts/dev/index.tsx deleted file mode 100644 index aab4395514..0000000000 --- a/plugins/shortcuts/dev/index.tsx +++ /dev/null @@ -1,26 +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 { createDevApp } from '@backstage/dev-utils'; -import { shortcutsPlugin, Shortcuts } from '../src/plugin'; - -createDevApp() - .registerPlugin(shortcutsPlugin) - .addPage({ - element: , - title: 'Root Page', - }) - .render(); diff --git a/plugins/shortcuts/knip-report.md b/plugins/shortcuts/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/shortcuts/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json deleted file mode 100644 index 20f914dbdf..0000000000 --- a/plugins/shortcuts/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@backstage/plugin-shortcuts", - "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.19-next.2", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/shortcuts" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/theme": "workspace:^", - "@backstage/types": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-hook-form": "^7.12.2", - "react-use": "^17.2.4", - "uuid": "^8.3.2", - "zen-observable": "^0.10.0" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@types/zen-observable": "^0.8.2" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/shortcuts/src/AddShortcut.test.tsx b/plugins/shortcuts/src/AddShortcut.test.tsx deleted file mode 100644 index b9c09ab124..0000000000 --- a/plugins/shortcuts/src/AddShortcut.test.tsx +++ /dev/null @@ -1,185 +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, fireEvent, waitFor } from '@testing-library/react'; -import { AddShortcut } from './AddShortcut'; -import { DefaultShortcutsApi, shortcutsApiRef } from './api'; -import { - MockAnalyticsApi, - MockStorageApi, - TestApiProvider, - renderInTestApp, -} from '@backstage/test-utils'; -import { AlertDisplay } from '@backstage/core-components'; -import { analyticsApiRef } from '@backstage/core-plugin-api'; - -describe('AddShortcut', () => { - const api = new DefaultShortcutsApi(MockStorageApi.create()); - - const props = { - onClose: jest.fn(), - anchorEl: document.createElement('div'), - api, - }; - - beforeEach(() => { - jest.clearAllMocks(); - document.title = 'some document title'; - }); - - it('displays the title', async () => { - await renderInTestApp( - - - , - ); - - expect(screen.getByText('Add Shortcut')).toBeInTheDocument(); - }); - - it('closes the popup', async () => { - await renderInTestApp( - - - , - ); - - fireEvent.click(screen.getByText('Cancel')); - expect(props.onClose).toHaveBeenCalledTimes(1); - }); - - it('saves the input', async () => { - const spy = jest.spyOn(api, 'add'); - - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { target: { value: '/some-url' } }); - fireEvent.change(titleInput, { target: { value: 'some title' } }); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(spy).toHaveBeenCalledWith({ - title: 'some title', - url: '/some-url', - }); - }); - }); - - it('should capture analytics event', async () => { - const analyticsSpy = new MockAnalyticsApi(); - const spy = jest.spyOn(api, 'add'); - - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { target: { value: '/some-url' } }); - fireEvent.change(titleInput, { target: { value: 'some title' } }); - - fireEvent.click(screen.getByText('Save')); - - await waitFor(() => { - expect(spy).toHaveBeenCalledWith({ - title: 'some title', - url: '/some-url', - }); - }); - - expect(analyticsSpy.getEvents()[0]).toMatchObject({ - action: 'click', - subject: `Clicked 'Save' in AddShortcut`, - }); - }); - - it('pastes the values', async () => { - const spy = jest.spyOn(api, 'add'); - - await renderInTestApp( - - , - , - { - routeEntries: ['/some-initial-url'], - }, - ); - - fireEvent.click(screen.getByText('Use current page')); - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(spy).toHaveBeenCalledWith({ - title: 'some document title', - url: '/some-initial-url', - }); - }); - }); - - it('displays errors', async () => { - jest.spyOn(api, 'add').mockRejectedValueOnce(new Error('some add error')); - - await renderInTestApp( - <> - - - - - , - ); - - fireEvent.click(screen.getByText('Use current page')); - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect( - screen.getByText('Could not add shortcut: some add error'), - ).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/shortcuts/src/AddShortcut.tsx b/plugins/shortcuts/src/AddShortcut.tsx deleted file mode 100644 index 15850ab389..0000000000 --- a/plugins/shortcuts/src/AddShortcut.tsx +++ /dev/null @@ -1,132 +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, { useState } from 'react'; -import { useLocation } from 'react-router-dom'; -import { SubmitHandler } from 'react-hook-form'; -import { - Button, - Card, - CardHeader, - makeStyles, - Popover, -} from '@material-ui/core'; -import { ShortcutForm } from './ShortcutForm'; -import { FormValues, Shortcut } from './types'; -import { ShortcutApi } from './api'; -import { alertApiRef, useApi, useAnalytics } from '@backstage/core-plugin-api'; - -const useStyles = makeStyles(theme => ({ - card: { - maxWidth: 400, - }, - header: { - marginBottom: theme.spacing(1), - }, - button: { - marginTop: theme.spacing(1), - }, -})); - -type Props = { - onClose: () => void; - anchorEl?: Element; - api: ShortcutApi; - - allowExternalLinks?: boolean; -}; - -export const AddShortcut = ({ - onClose, - anchorEl, - api, - allowExternalLinks, -}: Props) => { - const classes = useStyles(); - const alertApi = useApi(alertApiRef); - const { pathname } = useLocation(); - const [formValues, setFormValues] = useState(); - const open = Boolean(anchorEl); - const analytics = useAnalytics(); - - const handleSave: SubmitHandler = async ({ url, title }) => { - analytics.captureEvent('click', `Clicked 'Save' in AddShortcut`); - const shortcut: Omit = { url, title }; - - try { - await api.add(shortcut); - alertApi.post({ - message: `Added shortcut '${title}' to your sidebar`, - severity: 'success', - display: 'transient', - }); - } catch (error) { - alertApi.post({ - message: `Could not add shortcut: ${error.message}`, - severity: 'error', - }); - } - - onClose(); - }; - - const handlePaste = () => { - setFormValues({ url: pathname, title: document.title }); - }; - - const handleClose = () => { - setFormValues(undefined); - onClose(); - }; - - return ( - - - - Use current page - - } - /> - - - - ); -}; diff --git a/plugins/shortcuts/src/EditShortcut.test.tsx b/plugins/shortcuts/src/EditShortcut.test.tsx deleted file mode 100644 index 3077168193..0000000000 --- a/plugins/shortcuts/src/EditShortcut.test.tsx +++ /dev/null @@ -1,198 +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, fireEvent, waitFor } from '@testing-library/react'; -import { EditShortcut } from './EditShortcut'; -import { Shortcut } from './types'; -import { DefaultShortcutsApi, shortcutsApiRef } from './api'; -import { - MockAnalyticsApi, - MockStorageApi, - TestApiProvider, - renderInTestApp, -} from '@backstage/test-utils'; -import { AlertDisplay } from '@backstage/core-components'; -import { analyticsApiRef } from '@backstage/core-plugin-api'; - -describe('EditShortcut', () => { - const shortcut: Shortcut = { - id: 'id', - url: '/some-url', - title: 'some title', - }; - const api = new DefaultShortcutsApi(MockStorageApi.create()); - - const props = { - onClose: jest.fn(), - anchorEl: document.createElement('div'), - shortcut, - api, - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('displays the title', async () => { - await renderInTestApp( - - - , - ); - - expect(screen.getByText('Edit Shortcut')).toBeInTheDocument(); - }); - - it('closes the popup', async () => { - await renderInTestApp( - - - , - ); - - fireEvent.click(screen.getByText('Cancel')); - expect(props.onClose).toHaveBeenCalledTimes(1); - }); - - it('updates the shortcut', async () => { - const spy = jest.spyOn(api, 'update'); - - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { target: { value: '/some-new-url' } }); - fireEvent.change(titleInput, { target: { value: 'some new title' } }); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(spy).toHaveBeenCalledWith({ - id: 'id', - title: 'some new title', - url: '/some-new-url', - }); - expect(props.onClose).toHaveBeenCalledTimes(1); - }); - }); - - it('should capture analytics event', async () => { - const analyticsSpy = new MockAnalyticsApi(); - const spy = jest.spyOn(api, 'update'); - - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { target: { value: '/some-new-url' } }); - fireEvent.change(titleInput, { target: { value: 'some new title' } }); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(spy).toHaveBeenCalledWith({ - id: 'id', - title: 'some new title', - url: '/some-new-url', - }); - expect(props.onClose).toHaveBeenCalledTimes(1); - }); - - expect(analyticsSpy.getEvents()[0]).toMatchObject({ - action: 'click', - subject: `Clicked 'Save' in Edit Shortcut`, - }); - }); - - it('removes the shortcut', async () => { - const spy = jest.spyOn(api, 'remove'); - - await renderInTestApp( - - - , - ); - - fireEvent.click(screen.getByText('Remove')); - expect(spy).toHaveBeenCalledWith('id'); - }); - - it('displays errors', async () => { - jest - .spyOn(api, 'update') - .mockRejectedValueOnce(new Error('some update error')); - - jest - .spyOn(api, 'remove') - .mockRejectedValueOnce(new Error('some remove error')); - - await renderInTestApp( - <> - - - - - , - ); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect( - screen.getByText('Could not update shortcut: some update error'), - ).toBeInTheDocument(); - }); - fireEvent.click(screen.getByTestId('error-button-close')); - - fireEvent.click(screen.getByText('Remove')); - await waitFor(() => { - expect( - screen.getByText('Could not delete shortcut: some remove error'), - ).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/shortcuts/src/EditShortcut.tsx b/plugins/shortcuts/src/EditShortcut.tsx deleted file mode 100644 index 9f2ffe10be..0000000000 --- a/plugins/shortcuts/src/EditShortcut.tsx +++ /dev/null @@ -1,146 +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 { SubmitHandler } from 'react-hook-form'; -import { - Button, - Card, - CardHeader, - makeStyles, - Popover, -} from '@material-ui/core'; -import { ShortcutForm } from './ShortcutForm'; -import { FormValues, Shortcut } from './types'; -import DeleteIcon from '@material-ui/icons/Delete'; -import { ShortcutApi } from './api'; -import { alertApiRef, useApi, useAnalytics } from '@backstage/core-plugin-api'; - -const useStyles = makeStyles(theme => ({ - card: { - width: 400, - }, - header: { - marginBottom: theme.spacing(1), - }, - button: { - marginTop: theme.spacing(1), - }, -})); - -type Props = { - shortcut: Shortcut; - onClose: () => void; - anchorEl?: Element; - api: ShortcutApi; - allowExternalLinks?: boolean; -}; - -export const EditShortcut = ({ - shortcut, - onClose, - anchorEl, - api, - allowExternalLinks, -}: Props) => { - const classes = useStyles(); - const alertApi = useApi(alertApiRef); - const open = Boolean(anchorEl); - const analytics = useAnalytics(); - - const handleSave: SubmitHandler = async ({ url, title }) => { - analytics.captureEvent('click', `Clicked 'Save' in Edit Shortcut`); - const newShortcut: Shortcut = { - ...shortcut, - url, - title, - }; - - try { - await api.update(newShortcut); - alertApi.post({ - message: `Updated shortcut '${title}'`, - severity: 'success', - display: 'transient', - }); - } catch (error) { - alertApi.post({ - message: `Could not update shortcut: ${error.message}`, - severity: 'error', - }); - } - - onClose(); - }; - - const handleRemove = async () => { - try { - await api.remove(shortcut.id); - alertApi.post({ - message: `Removed shortcut '${shortcut.title}' from your sidebar`, - severity: 'success', - display: 'transient', - }); - } catch (error) { - alertApi.post({ - message: `Could not delete shortcut: ${error.message}`, - severity: 'error', - }); - } - }; - - const handleClose = () => { - onClose(); - }; - - return ( - - - } - onClick={handleRemove} - > - Remove - - } - /> - - - - ); -}; diff --git a/plugins/shortcuts/src/ShortcutForm.test.tsx b/plugins/shortcuts/src/ShortcutForm.test.tsx deleted file mode 100644 index 388c072725..0000000000 --- a/plugins/shortcuts/src/ShortcutForm.test.tsx +++ /dev/null @@ -1,190 +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, fireEvent, waitFor } from '@testing-library/react'; -import { ShortcutForm } from './ShortcutForm'; -import { DefaultShortcutsApi, shortcutsApiRef } from './api'; -import { - renderInTestApp, - TestApiProvider, - MockStorageApi, -} from '@backstage/test-utils'; - -describe('ShortcutForm', () => { - const props = { - onSave: jest.fn(), - onClose: jest.fn(), - }; - - it('displays validation messages', async () => { - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { target: { value: 'url' } }); - fireEvent.change(titleInput, { target: { value: 't' } }); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect( - screen.getByText('Must be a relative URL (starts with a /)'), - ).toBeInTheDocument(); - expect( - screen.getByText('Must be at least 2 characters'), - ).toBeInTheDocument(); - }); - }); - - it('displays duplicate validation messages for title and URL', async () => { - const mockShortcutApi = new DefaultShortcutsApi(MockStorageApi.create()); - mockShortcutApi.add({ title: 'Existing Title', url: '/existing-url' }); - - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - - fireEvent.change(urlInput, { target: { value: '/existing-url' } }); - fireEvent.change(titleInput, { target: { value: 'Existing Title' } }); - - fireEvent.click(screen.getByText('Save')); - - await waitFor(() => { - expect( - screen.getByText('A shortcut with this title already exists'), - ).toBeInTheDocument(); - expect( - screen.getByText('A shortcut with this url already exists'), - ).toBeInTheDocument(); - }); - - expect(props.onSave).not.toHaveBeenCalled(); - expect(props.onClose).not.toHaveBeenCalled(); - }); - - it('allows external links', async () => { - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { - target: { value: 'https://www.backstage.io' }, - }); - fireEvent.change(titleInput, { target: { value: 'Backstage' } }); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(props.onSave).toHaveBeenCalledWith( - expect.objectContaining({ - title: 'Backstage', - url: 'https://www.backstage.io', - }), - expect.anything(), - ); - }); - }); - - it('allows relative links when external links are enabled', async () => { - await renderInTestApp( - - - , - ); - - const urlInput = screen.getByPlaceholderText('Enter a URL'); - const titleInput = screen.getByPlaceholderText('Enter a display name'); - fireEvent.change(urlInput, { - target: { value: '/catalog' }, - }); - fireEvent.change(titleInput, { target: { value: 'Catalog' } }); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(props.onSave).toHaveBeenCalledWith( - expect.objectContaining({ - title: 'Catalog', - url: '/catalog', - }), - expect.anything(), - ); - }); - }); - - it('calls the save handler', async () => { - await renderInTestApp( - - - , - , - ); - - fireEvent.click(screen.getByText('Save')); - await waitFor(() => { - expect(props.onSave).toHaveBeenCalledWith( - expect.objectContaining({ title: 'some title', url: '/some-url' }), - expect.anything(), - ); - }); - }); - - it('calls the close handler', async () => { - await renderInTestApp( - - - , - ); - - fireEvent.click(screen.getByText('Cancel')); - await waitFor(() => { - expect(props.onClose).toHaveBeenCalled(); - }); - }); -}); diff --git a/plugins/shortcuts/src/ShortcutForm.tsx b/plugins/shortcuts/src/ShortcutForm.tsx deleted file mode 100644 index 4d6fdcbc27..0000000000 --- a/plugins/shortcuts/src/ShortcutForm.tsx +++ /dev/null @@ -1,183 +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, { useEffect, useRef } from 'react'; -import useObservable from 'react-use/lib/useObservable'; -import { useForm, SubmitHandler, Controller } from 'react-hook-form'; -import { - Button, - CardActions, - CardContent, - makeStyles, - TextField, -} from '@material-ui/core'; -import { FormValues } from './types'; -import { shortcutsApiRef } from './api'; -import { useApi } from '@backstage/core-plugin-api'; - -const useStyles = makeStyles(theme => ({ - field: { - marginBottom: theme.spacing(2), - }, - actionRoot: { - paddingLeft: theme.spacing(2), - paddingBottom: theme.spacing(3), - justifyContent: 'flex-start', - }, -})); - -type Props = { - formValues?: FormValues; - onSave: SubmitHandler; - onClose: () => void; - allowExternalLinks?: boolean; -}; - -export const ShortcutForm = ({ - formValues, - onSave, - onClose, - allowExternalLinks, -}: Props) => { - const classes = useStyles(); - const shortcutApi = useApi(shortcutsApiRef); - const shortcutData = useObservable( - shortcutApi.shortcut$(), - shortcutApi.get(), - ); - const { current: originalValues } = useRef({ - url: formValues?.url ?? '', - title: formValues?.title ?? '', - }); - const { - handleSubmit, - reset, - control, - formState: { errors }, - } = useForm({ - mode: 'onChange', - defaultValues: originalValues, - }); - - const titleIsUnique = (title: string) => { - if ( - title !== originalValues.title && - shortcutData.some(shortcutTitle => shortcutTitle.title === title) - ) - return 'A shortcut with this title already exists'; - return true; - }; - - const urlIsUnique = (url: string) => { - if ( - url !== originalValues.url && - shortcutData.some(shortcutUrl => shortcutUrl.url === url) - ) - return 'A shortcut with this url already exists'; - return true; - }; - - useEffect(() => { - reset(formValues); - }, [reset, formValues]); - - return ( - <> - - ( - - )} - /> - ( - - )} - /> - - - - - - - ); -}; diff --git a/plugins/shortcuts/src/ShortcutIcon.tsx b/plugins/shortcuts/src/ShortcutIcon.tsx deleted file mode 100644 index be78928452..0000000000 --- a/plugins/shortcuts/src/ShortcutIcon.tsx +++ /dev/null @@ -1,42 +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 { makeStyles } from '@material-ui/core/styles'; -import Avatar from '@material-ui/core/Avatar'; - -type Props = { - text: string; - color: string; -}; - -const useStyles = makeStyles(theme => ({ - avatar: (props: Props) => ({ - color: theme.palette.getContrastText(props.color), - backgroundColor: props.color, - width: 28, - height: 28, - fontWeight: 'bold', - fontSize: 13, - filter: 'contrast(150%) brightness(1.4)', - }), -})); - -export const ShortcutIcon = (props: Props) => { - const classes = useStyles(props); - - return {props.text}; -}; diff --git a/plugins/shortcuts/src/ShortcutItem.test.tsx b/plugins/shortcuts/src/ShortcutItem.test.tsx deleted file mode 100644 index b78b72e9cb..0000000000 --- a/plugins/shortcuts/src/ShortcutItem.test.tsx +++ /dev/null @@ -1,75 +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, waitFor } from '@testing-library/react'; -import { ShortcutItem } from './ShortcutItem'; -import { Shortcut } from './types'; -import { DefaultShortcutsApi } from './api'; -import { MockStorageApi, renderInTestApp } from '@backstage/test-utils'; -import { SidebarOpenStateProvider } from '@backstage/core-components'; - -describe('ShortcutItem', () => { - const shortcut: Shortcut = { - id: 'id', - url: '/some-url', - title: 'some title', - }; - const api = new DefaultShortcutsApi(MockStorageApi.create()); - - it('displays the shortcut', async () => { - await renderInTestApp( - {} }}> - - , - ); - expect(screen.getByText('ST')).toBeInTheDocument(); - expect(screen.getByText('some title')).toBeInTheDocument(); - }); - - it('calculates the shortcut text correctly', async () => { - const shortcut1: Shortcut = { - id: 'id1', - url: '/some-url', - title: 'onetitle', - }; - const shortcut2: Shortcut = { - id: 'id2', - url: '/some-url', - title: 'two title', - }; - const shortcut3: Shortcut = { - id: 'id3', - url: '/some-url', - title: 'more | title words', - }; - - const { rerender } = await renderInTestApp( - , - ); - expect(screen.getByText('On')).toBeInTheDocument(); - - rerender(); - await waitFor(() => { - expect(screen.getByText('TT')).toBeInTheDocument(); - }); - - rerender(); - await waitFor(() => { - expect(screen.getByText('MT')).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/shortcuts/src/ShortcutItem.tsx b/plugins/shortcuts/src/ShortcutItem.tsx deleted file mode 100644 index d193b5941a..0000000000 --- a/plugins/shortcuts/src/ShortcutItem.tsx +++ /dev/null @@ -1,108 +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 { makeStyles } from '@material-ui/core/styles'; -import IconButton from '@material-ui/core/IconButton'; -import Tooltip from '@material-ui/core/Tooltip'; -import EditIcon from '@material-ui/icons/Edit'; -import { ShortcutIcon } from './ShortcutIcon'; -import { EditShortcut } from './EditShortcut'; -import { ShortcutApi } from './api'; -import { Shortcut } from './types'; -import { SidebarItem } from '@backstage/core-components'; - -const useStyles = makeStyles(theme => ({ - root: { - '&:hover #edit': { - visibility: 'visible', - }, - }, - button: { - visibility: 'hidden', - }, - icon: { - color: theme.palette.common.white, - fontSize: 16, - }, -})); - -const getIconText = (title: string) => - title.split(' ').length === 1 - ? // If there's only one word, keep the first two characters - // eslint-disable-next-line no-restricted-syntax - title[0].toUpperCase() + title[1].toLowerCase() - : // If there's more than one word, take the first character of the first two words - // eslint-disable-next-line no-restricted-syntax - title - .replace(/\B\W/g, '') - .split(' ') - .map(s => s[0]) - .join('') - .slice(0, 2) - .toUpperCase(); - -type Props = { - shortcut: Shortcut; - api: ShortcutApi; - allowExternalLinks?: boolean; -}; - -export const ShortcutItem = ({ shortcut, api, allowExternalLinks }: Props) => { - const classes = useStyles(); - const [anchorEl, setAnchorEl] = React.useState(); - - const handleClick = (event: React.MouseEvent) => { - event.preventDefault(); - setAnchorEl(event.currentTarget); - }; - - const handleClose = () => { - setAnchorEl(undefined); - }; - - const text = getIconText(shortcut.title); - const color = api.getColor(shortcut.url); - - return ( - <> - - } - > - - - - - - - - ); -}; diff --git a/plugins/shortcuts/src/Shortcuts.test.tsx b/plugins/shortcuts/src/Shortcuts.test.tsx deleted file mode 100644 index a1339083b6..0000000000 --- a/plugins/shortcuts/src/Shortcuts.test.tsx +++ /dev/null @@ -1,45 +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 { - MockStorageApi, - renderInTestApp, - TestApiProvider, -} from '@backstage/test-utils'; -import { screen, waitFor } from '@testing-library/react'; -import { Shortcuts } from './Shortcuts'; -import { DefaultShortcutsApi, shortcutsApiRef } from './api'; - -import { SidebarOpenStateProvider } from '@backstage/core-components'; - -describe('Shortcuts', () => { - it('displays an add button', async () => { - await renderInTestApp( - {} }}> - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Add Shortcuts')).toBeInTheDocument(); - }); -}); diff --git a/plugins/shortcuts/src/Shortcuts.tsx b/plugins/shortcuts/src/Shortcuts.tsx deleted file mode 100644 index 6b9ea4d79b..0000000000 --- a/plugins/shortcuts/src/Shortcuts.tsx +++ /dev/null @@ -1,82 +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 useObservable from 'react-use/lib/useObservable'; -import PlayListAddIcon from '@material-ui/icons/PlaylistAdd'; -import { ShortcutItem } from './ShortcutItem'; -import { AddShortcut } from './AddShortcut'; -import { shortcutsApiRef } from './api'; - -import { - Progress, - SidebarItem, - SidebarScrollWrapper, -} from '@backstage/core-components'; -import { IconComponent, useApi } from '@backstage/core-plugin-api'; - -/** - * ShortcutsProps - * Props for the {@link Shortcuts} component. - * @public - */ -export interface ShortcutsProps { - icon?: IconComponent; - allowExternalLinks?: boolean; -} - -export const Shortcuts = (props: ShortcutsProps) => { - const shortcutApi = useApi(shortcutsApiRef); - const shortcuts = useObservable(shortcutApi.shortcut$(), shortcutApi.get()); - const [anchorEl, setAnchorEl] = React.useState(); - const loading = Boolean(!shortcuts); - - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - - const handleClose = () => { - setAnchorEl(undefined); - }; - - return ( - - - - {loading ? ( - - ) : ( - shortcuts?.map(shortcut => ( - - )) - )} - - ); -}; diff --git a/plugins/shortcuts/src/api/DefaultShortcutsApi.test.ts b/plugins/shortcuts/src/api/DefaultShortcutsApi.test.ts deleted file mode 100644 index 44bc99fb98..0000000000 --- a/plugins/shortcuts/src/api/DefaultShortcutsApi.test.ts +++ /dev/null @@ -1,91 +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 { MockStorageApi } from '@backstage/test-utils'; -import { pageTheme } from '@backstage/theme'; -import { Shortcut } from '../types'; -import { DefaultShortcutsApi } from './DefaultShortcutsApi'; -import { ShortcutApi } from './ShortcutApi'; - -describe('DefaultShortcutsApi', () => { - it('should observe shortcuts', async () => { - const shortcutApi: ShortcutApi = new DefaultShortcutsApi( - MockStorageApi.create(), - ); - const shortcut: Shortcut = { id: 'id', title: 'title', url: '/url' }; - - const observerNextHandler = jest.fn(); - - await new Promise(resolve => { - shortcutApi.shortcut$().subscribe({ - next: data => { - observerNextHandler(data); - resolve(); - }, - }); - }); - observerNextHandler.mockClear(); // handler is called with current state to start - await shortcutApi.add(shortcut); - - expect(observerNextHandler).toHaveBeenCalledTimes(1); - expect(observerNextHandler).toHaveBeenCalledWith( - expect.arrayContaining([{ ...shortcut, id: expect.anything() }]), - ); - }); - - it('should add shortcuts with ids', async () => { - const storageApi = MockStorageApi.create(); - const shortcutApi: ShortcutApi = new DefaultShortcutsApi(storageApi); - const shortcut: Omit = { title: 'title', url: '/url' }; - const spy = jest.spyOn(storageApi, 'set'); - - await shortcutApi.add(shortcut); - expect(spy).toHaveBeenCalledWith( - 'items', - expect.objectContaining([{ ...shortcut, id: expect.anything() }]), - ); - }); - - it('should update shortcuts', async () => { - const storageApi = MockStorageApi.create(); - const shortcutApi: ShortcutApi = new DefaultShortcutsApi(storageApi); - const shortcut: Shortcut = { id: 'someid', title: 'title', url: '/url' }; - const spy = jest.spyOn(storageApi, 'set'); - - await shortcutApi.update(shortcut); - expect(spy).toHaveBeenCalledWith( - 'items', - expect.objectContaining([shortcut]), - ); - }); - - it('should remove shortcuts', async () => { - const storageApi = MockStorageApi.create(); - const shortcutApi: ShortcutApi = new DefaultShortcutsApi(storageApi); - const shortcut: Shortcut = { id: 'someid', title: 'title', url: '/url' }; - const spy = jest.spyOn(storageApi, 'set'); - - await shortcutApi.remove(shortcut.id); - expect(spy).toHaveBeenCalledWith('items', []); - }); - - it('should get a color', () => { - const storageApi = MockStorageApi.create(); - const shortcutApi: ShortcutApi = new DefaultShortcutsApi(storageApi); - - expect(shortcutApi.getColor('/catalog')).toEqual(pageTheme.home.colors[0]); - }); -}); diff --git a/plugins/shortcuts/src/api/DefaultShortcutsApi.ts b/plugins/shortcuts/src/api/DefaultShortcutsApi.ts deleted file mode 100644 index 8e5fd99540..0000000000 --- a/plugins/shortcuts/src/api/DefaultShortcutsApi.ts +++ /dev/null @@ -1,112 +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 { pageTheme } from '@backstage/theme'; -import { v4 as uuid } from 'uuid'; -import { ShortcutApi, type Shortcut } from '@backstage/plugin-shortcuts'; -import type { StorageApi } from '@backstage/core-plugin-api'; -import type { Observable } from '@backstage/types'; -import ObservableImpl from 'zen-observable'; - -/** - * Default implementation of the {@link ShortcutApi} that uses the - * {@link @backstage/core-plugin-api#StorageApi} to store shortcuts. - * - * @remarks - * - * Note that the storage API given is used directly, as in, this implementation - * does not itself dive into a sub-bucket. So you may want to provide a bucket - * that is scoped to the plugin (default: 'shortcuts'). - * - * @public - */ -export class DefaultShortcutsApi implements ShortcutApi { - private shortcuts: Shortcut[]; - private readonly subscribers = new Set< - ZenObservable.SubscriptionObserver - >(); - - private readonly observable = new ObservableImpl(subscriber => { - // forward the the latest value - subscriber.next(this.shortcuts); - - this.subscribers.add(subscriber); - return () => { - this.subscribers.delete(subscriber); - }; - }); - - constructor(private readonly storageApi: StorageApi) { - this.shortcuts = this.storageApi.snapshot('items').value ?? []; - this.storageApi.observe$('items').subscribe({ - next: next => { - this.shortcuts = next.value ?? []; - this.notifyChanges(); - }, - }); - } - - shortcut$(): Observable { - return this.observable; - } - - get() { - return this.shortcuts; - } - - async add(shortcut: Omit) { - const shortcuts = this.sort([...this.get(), { ...shortcut, id: uuid() }]); - - await this.storageApi.set('items', shortcuts); - } - - async remove(id: string) { - const shortcuts = this.get().filter(s => s.id !== id); - - await this.storageApi.set('items', shortcuts); - } - - async update(shortcut: Shortcut) { - const shortcuts = this.get().filter(s => s.id !== shortcut.id); - shortcuts.push(shortcut); - - await this.storageApi.set('items', shortcuts); - } - - getColor(url: string) { - const type = url.split('/')[1]; - const theme = - this.THEME_MAP[type] ?? - (Object.keys(pageTheme).includes(type) ? type : 'tool'); - - return pageTheme[theme].colors[0]; - } - - private readonly THEME_MAP: Record = { - catalog: 'home', - docs: 'documentation', - }; - - private sort(shortcuts: Shortcut[]): Shortcut[] { - return shortcuts.slice().sort((a, b) => (a.title >= b.title ? 1 : -1)); - } - - private notifyChanges() { - for (const subscription of this.subscribers) { - subscription.next(this.shortcuts); - } - } -} diff --git a/plugins/shortcuts/src/api/ShortcutApi.ts b/plugins/shortcuts/src/api/ShortcutApi.ts deleted file mode 100644 index 96c5de1697..0000000000 --- a/plugins/shortcuts/src/api/ShortcutApi.ts +++ /dev/null @@ -1,61 +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 { Shortcut } from '../types'; -import { createApiRef } from '@backstage/core-plugin-api'; -import { Observable } from '@backstage/types'; - -/** @public */ -export const shortcutsApiRef = createApiRef({ - id: 'plugin.shortcuts.api', -}); - -/** @public */ -export interface ShortcutApi { - /** - * Returns an Observable that will subscribe to changes. - */ - shortcut$(): Observable; - - /** - * Returns an immediate snapshot of shortcuts, sorted by title - */ - get(): Shortcut[]; - - /** - * Generates a unique id for the shortcut and then saves it. - */ - add(shortcut: Omit): Promise; - - /** - * Removes the shortcut. - */ - remove(id: string): Promise; - - /** - * Finds an existing shortcut that matches the ID of the - * supplied shortcut and updates its values. - */ - update(shortcut: Shortcut): Promise; - - /** - * Each shortcut should get a color for its icon based on the url. - * - * Preferably using some abstraction between the url and the actual - * color value. - */ - getColor(url: string): string; -} diff --git a/plugins/shortcuts/src/api/index.ts b/plugins/shortcuts/src/api/index.ts deleted file mode 100644 index ae975208a0..0000000000 --- a/plugins/shortcuts/src/api/index.ts +++ /dev/null @@ -1,19 +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. - */ - -export { DefaultShortcutsApi } from './DefaultShortcutsApi'; -export { shortcutsApiRef } from './ShortcutApi'; -export type { ShortcutApi } from './ShortcutApi'; diff --git a/plugins/shortcuts/src/deprecated.ts b/plugins/shortcuts/src/deprecated.ts deleted file mode 100644 index 8d5a2463fd..0000000000 --- a/plugins/shortcuts/src/deprecated.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { DefaultShortcutsApi } from './api'; - -/** - * @public - * @deprecated Use {@link DefaultShortcutsApi} instead. - */ -export const LocalStoredShortcuts = DefaultShortcutsApi; diff --git a/plugins/shortcuts/src/index.ts b/plugins/shortcuts/src/index.ts deleted file mode 100644 index 1d35cc2721..0000000000 --- a/plugins/shortcuts/src/index.ts +++ /dev/null @@ -1,27 +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. - */ - -/** - * A Backstage plugin that provides a shortcuts feature to the sidebar - * - * @packageDocumentation - */ - -export { shortcutsPlugin, Shortcuts } from './plugin'; -export * from './api'; -export * from './deprecated'; -export type { Shortcut } from './types'; -export type { ShortcutsProps } from './Shortcuts'; diff --git a/plugins/shortcuts/src/plugin.test.ts b/plugins/shortcuts/src/plugin.test.ts deleted file mode 100644 index 8ecc279d2c..0000000000 --- a/plugins/shortcuts/src/plugin.test.ts +++ /dev/null @@ -1,22 +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 { shortcutsPlugin } from './plugin'; - -describe('shortcuts', () => { - it('should export plugin', () => { - expect(shortcutsPlugin).toBeDefined(); - }); -}); diff --git a/plugins/shortcuts/src/plugin.ts b/plugins/shortcuts/src/plugin.ts deleted file mode 100644 index 8288c4fb87..0000000000 --- a/plugins/shortcuts/src/plugin.ts +++ /dev/null @@ -1,44 +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 { DefaultShortcutsApi, shortcutsApiRef } from './api'; -import { - createApiFactory, - createComponentExtension, - createPlugin, - storageApiRef, -} from '@backstage/core-plugin-api'; - -/** @public */ -export const shortcutsPlugin = createPlugin({ - id: 'shortcuts', - apis: [ - createApiFactory({ - api: shortcutsApiRef, - deps: { storageApi: storageApiRef }, - factory: ({ storageApi }) => - new DefaultShortcutsApi(storageApi.forBucket('shortcuts')), - }), - ], -}); - -/** @public */ -export const Shortcuts = shortcutsPlugin.provide( - createComponentExtension({ - name: 'Shortcuts', - component: { lazy: () => import('./Shortcuts').then(m => m.Shortcuts) }, - }), -); diff --git a/plugins/shortcuts/src/setupTests.ts b/plugins/shortcuts/src/setupTests.ts deleted file mode 100644 index 992b60d3a4..0000000000 --- a/plugins/shortcuts/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/shortcuts/src/types.ts b/plugins/shortcuts/src/types.ts deleted file mode 100644 index 75ef561f74..0000000000 --- a/plugins/shortcuts/src/types.ts +++ /dev/null @@ -1,27 +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. - */ - -/** @public */ -export type Shortcut = { - id: string; - url: string; - title: string; -}; - -export type FormValues = { - url: string; - title: string; -}; diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index a3eb2bd3e7..a787465282 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,176 @@ # @backstage/plugin-signals-backend +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.4-next.0 + - @backstage/plugin-signals-node@0.1.4-next.0 + +## 0.1.3 + +### Patch Changes + +- 5f9877b: Fix unauthorized signals connection by allowing unauthenticated requests +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-events-node@0.3.3 + - @backstage/plugin-signals-node@0.1.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/plugin-signals-node@0.1.3-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.3-next.0 + +### Patch Changes + +- 5f9877b: Fix unauthorized signals connection by allowing unauthenticated requests +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + - @backstage/plugin-signals-node@0.1.3-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-signals-node@0.1.2 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-auth-node@0.4.10 + - @backstage/plugin-events-node@0.3.1 + - @backstage/plugin-signals-node@0.1.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.0 + +### Minor Changes + +- 6c1547a: **BREAKING** Type definition added to signal recipients + + Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}` + instead string entity references + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- 4467036: Allow unauthenticated access to health check endpoint. +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 6d84ee6: Changed to use the refactored signal service naming +- df45710: Improved error logging and fixed authentication +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/plugin-signals-node@0.1.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## 0.1.0-next.2 + +### Patch Changes + +- 6d84ee6: Changed to use the refactored signal service naming +- Updated dependencies + - @backstage/plugin-signals-node@0.1.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## 0.1.0-next.1 + +### Minor Changes + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- df45710: Improved error logging and fixed authentication +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/plugin-signals-node@0.1.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## 0.0.4-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-signals-node@0.0.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## 0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/plugin-signals-node@0.0.1 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.19 + ## 0.0.1-next.3 ### Patch Changes diff --git a/plugins/signals-backend/README.md b/plugins/signals-backend/README.md index ff1fcb6562..d76038a38e 100644 --- a/plugins/signals-backend/README.md +++ b/plugins/signals-backend/README.md @@ -6,7 +6,7 @@ Signals plugin allows backend plugins to publish messages to frontend plugins. ## Getting started -First install the `@backstage/plugin-signals-node` plugin to get the `SignalService` set up. +First install the `@backstage/plugin-signals-node` plugin to get the `SignalsService` set up. Next, add Signals router to your backend in `packages/backend/src/plugins/signals.ts`: diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md index 8bdaa581f3..cad43bfaae 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/api-report.md @@ -3,26 +3,32 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; -import { EventBroker } from '@backstage/plugin-events-node'; +import { EventsService } from '@backstage/plugin-events-node'; import express from 'express'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { UserInfoService } from '@backstage/backend-plugin-api'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; // @public (undocumented) export interface RouterOptions { + // (undocumented) + auth?: AuthService; // (undocumented) discovery: PluginEndpointDiscovery; // (undocumented) - eventBroker?: EventBroker; + events: EventsService; // (undocumented) identity: IdentityApi; // (undocumented) logger: LoggerService; + // (undocumented) + userInfo?: UserInfoService; } // @public diff --git a/plugins/signals-backend/dev/index.ts b/plugins/signals-backend/dev/index.ts new file mode 100644 index 0000000000..39021a9fcd --- /dev/null +++ b/plugins/signals-backend/dev/index.ts @@ -0,0 +1,61 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createBackend } from '@backstage/backend-defaults'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { signalService } from '@backstage/plugin-signals-node'; + +const signalDebug = createBackendPlugin({ + pluginId: 'signals-debug', + register(env) { + env.registerInit({ + deps: { + signals: signalService, + lifecycle: coreServices.lifecycle, + }, + async init({ signals, lifecycle }) { + let interval: NodeJS.Timeout | undefined; + lifecycle.addStartupHook(async () => { + interval = setInterval(async () => { + await signals.publish<{ date: string }>({ + channel: 'debug', + message: { date: new Date().toISOString() }, + recipients: { type: 'broadcast' }, + }); + }, 1000); + }); + + lifecycle.addShutdownHook(async () => { + if (interval) { + clearInterval(interval); + } + }); + }, + }); + }, +}); + +const backend = createBackend(); +backend.add(import('@backstage/plugin-events-backend/alpha')); +backend.add(import('@backstage/plugin-auth-backend')); +backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); +backend.add(import('../src')); +backend.add(signalDebug); + +backend.start(); diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 33887a153d..ac1e74332b 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.0.1-next.3", + "version": "0.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -39,13 +39,17 @@ "express-promise-router": "^4.1.0", "http-proxy-middleware": "^2.0.0", "node-fetch": "^2.6.7", - "uuid": "^8.0.0", + "uuid": "^9.0.0", "winston": "^3.2.1", "ws": "^8.14.2", "yn": "^4.0.0" }, "devDependencies": { + "@backstage/backend-defaults": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/plugin-auth-backend": "workspace:^", + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^", + "@backstage/plugin-events-backend": "workspace:^", "@types/supertest": "^2.0.8", "msw": "^1.0.0", "supertest": "^6.2.4" diff --git a/plugins/signals-backend/src/plugin.ts b/plugins/signals-backend/src/plugin.ts index 11b63163d5..3e00c00a34 100644 --- a/plugins/signals-backend/src/plugin.ts +++ b/plugins/signals-backend/src/plugin.ts @@ -18,6 +18,7 @@ import { createBackendPlugin, } from '@backstage/backend-plugin-api'; import { createRouter } from './service/router'; +import { eventsServiceRef } from '@backstage/plugin-events-node'; /** * Signals backend plugin @@ -33,17 +34,33 @@ export const signalsPlugin = createBackendPlugin({ logger: coreServices.logger, identity: coreServices.identity, discovery: coreServices.discovery, - // TODO: EventBroker. It is optional for now but it's actually required so waiting for the new backend system - // for the events-backend for this to work. + userInfo: coreServices.userInfo, + auth: coreServices.auth, + events: eventsServiceRef, }, - async init({ httpRouter, logger, identity, discovery }) { + async init({ + httpRouter, + logger, + identity, + discovery, + userInfo, + auth, + events, + }) { httpRouter.use( await createRouter({ logger, identity, discovery, + userInfo, + auth, + events, }), ); + httpRouter.addAuthPolicy({ + path: '/', + allow: 'unauthenticated', + }); }, }); }, diff --git a/plugins/signals-backend/src/run.ts b/plugins/signals-backend/src/run.ts deleted file mode 100644 index d299ed23e9..0000000000 --- a/plugins/signals-backend/src/run.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { getRootLogger } from '@backstage/backend-common'; -import yn from 'yn'; -import { startStandaloneServer } from './service/standaloneServer'; - -const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; -const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); -const logger = getRootLogger(); - -startStandaloneServer({ port, enableCors, logger }).catch(err => { - logger.error(err); - process.exit(1); -}); - -process.on('SIGINT', () => { - logger.info('CTRL+C pressed; exiting.'); - process.exit(0); -}); diff --git a/plugins/signals-backend/src/service/SignalManager.test.ts b/plugins/signals-backend/src/service/SignalManager.test.ts index 5720d1ff52..3ee99bb34b 100644 --- a/plugins/signals-backend/src/service/SignalManager.test.ts +++ b/plugins/signals-backend/src/service/SignalManager.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { WebSocket } from 'ws'; -import { EventSubscriber } from '@backstage/plugin-events-node'; +import { EventsServiceSubscribeOptions } from '@backstage/plugin-events-node'; import { SignalManager } from './SignalManager'; import { getVoidLogger } from '@backstage/backend-common'; @@ -56,15 +56,15 @@ class MockWebSocket { describe('SignalManager', () => { let onEvent: Function; - const mockEventBroker = { + const mockEvents = { publish: async () => {}, - subscribe: (subscriber: EventSubscriber) => { + subscribe: async (subscriber: EventsServiceSubscribeOptions) => { onEvent = subscriber.onEvent; }, }; const manager = SignalManager.create({ - eventBroker: mockEventBroker, + events: mockEvents, logger: getVoidLogger(), }); @@ -89,7 +89,7 @@ describe('SignalManager', () => { await onEvent({ topic: 'signals', eventPayload: { - recipients: null, + recipients: { type: 'broadcast' }, channel: 'test', message: { msg: 'test' }, }, @@ -109,7 +109,7 @@ describe('SignalManager', () => { await onEvent({ topic: 'signals', eventPayload: { - recipients: null, + recipients: { type: 'broadcast' }, channel: 'test', message: { msg: 'test' }, }, @@ -126,25 +126,15 @@ describe('SignalManager', () => { // Connection with identity and subscription const ws2 = new MockWebSocket(); manager.addConnection(ws2 as unknown as WebSocket, { - identity: { - type: 'user', - ownershipEntityRefs: ['user:default/john.doe'], - userEntityRef: 'user:default/john.doe', - }, - expiresInSeconds: 3600, - token: '1234', + ownershipEntityRefs: ['user:default/john.doe'], + userEntityRef: 'user:default/john.doe', }); // Connection without subscription const ws3 = new MockWebSocket(); manager.addConnection(ws3 as unknown as WebSocket, { - identity: { - type: 'user', - ownershipEntityRefs: ['user:default/john.doe'], - userEntityRef: 'user:default/john.doe', - }, - expiresInSeconds: 3600, - token: '1234', + ownershipEntityRefs: ['user:default/john.doe'], + userEntityRef: 'user:default/john.doe', }); ws1.trigger( @@ -162,7 +152,7 @@ describe('SignalManager', () => { await onEvent({ topic: 'signals', eventPayload: { - recipients: 'user:default/john.doe', + recipients: { type: 'user', entityRef: 'user:default/john.doe' }, channel: 'test', message: { msg: 'test' }, }, diff --git a/plugins/signals-backend/src/service/SignalManager.ts b/plugins/signals-backend/src/service/SignalManager.ts index db374418e1..3211c51c9c 100644 --- a/plugins/signals-backend/src/service/SignalManager.ts +++ b/plugins/signals-backend/src/service/SignalManager.ts @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EventBroker, EventParams } from '@backstage/plugin-events-node'; +import { EventParams, EventsService } from '@backstage/plugin-events-node'; import { SignalPayload } from '@backstage/plugin-signals-node'; import { RawData, WebSocket } from 'ws'; import { v4 as uuid } from 'uuid'; import { JsonObject } from '@backstage/types'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + BackstageUserInfo, + LoggerService, +} from '@backstage/backend-plugin-api'; /** * @internal @@ -36,8 +38,7 @@ export type SignalConnection = { * @internal */ export type SignalManagerOptions = { - // TODO: Remove optional when events-backend can offer this service - eventBroker?: EventBroker; + events: EventsService; logger: LoggerService; }; @@ -47,7 +48,7 @@ export class SignalManager { string, SignalConnection >(); - private eventBroker?: EventBroker; + private events: EventsService; private logger: LoggerService; static create(options: SignalManagerOptions) { @@ -55,23 +56,24 @@ export class SignalManager { } private constructor(options: SignalManagerOptions) { - ({ eventBroker: this.eventBroker, logger: this.logger } = options); + ({ events: this.events, logger: this.logger } = options); - this.eventBroker?.subscribe({ - supportsEventTopics: () => ['signals'], - onEvent: (params: EventParams) => - this.onEventBrokerEvent(params), + this.events.subscribe({ + id: 'signals', + topics: ['signals'], + onEvent: (params: EventParams) => + this.onEventBrokerEvent(params.eventPayload as SignalPayload), }); } - addConnection(ws: WebSocket, identity?: BackstageIdentityResponse) { + addConnection(ws: WebSocket, identity?: BackstageUserInfo) { const id = uuid(); const conn = { id, - user: identity?.identity.userEntityRef ?? 'user:default/guest', + user: identity?.userEntityRef ?? 'user:default/guest', ws, - ownershipEntityRefs: identity?.identity.ownershipEntityRefs ?? [ + ownershipEntityRefs: identity?.ownershipEntityRefs ?? [ 'user:default/guest', ], subscriptions: new Set(), @@ -80,7 +82,7 @@ export class SignalManager { this.connections.set(id, conn); ws.on('error', (err: Error) => { - this.logger.info( + this.logger.error( `Error occurred with connection ${id}: ${err}, closing connection`, ); ws.close(); @@ -124,10 +126,7 @@ export class SignalManager { } } - private async onEventBrokerEvent( - params: EventParams, - ): Promise { - const { eventPayload } = params; + private async onEventBrokerEvent(eventPayload: SignalPayload): Promise { if (!eventPayload.channel || !eventPayload.message) { return; } @@ -135,8 +134,10 @@ export class SignalManager { const { channel, recipients, message } = eventPayload; const jsonMessage = JSON.stringify({ channel, message }); let users: string[] = []; - if (recipients !== null) { - users = Array.isArray(recipients) ? recipients : [recipients]; + if (recipients.type === 'user') { + users = Array.isArray(recipients.entityRef) + ? recipients.entityRef + : [recipients.entityRef]; } // Actual websocket message sending @@ -144,9 +145,10 @@ export class SignalManager { if (!conn.subscriptions.has(channel)) { return; } - // Sending to all users can be done with null + + // Sending to all users can be done with broadcast if ( - recipients !== null && + recipients.type !== 'broadcast' && !conn.ownershipEntityRefs.some((ref: string) => users.includes(ref)) ) { return; diff --git a/plugins/signals-backend/src/service/router.test.ts b/plugins/signals-backend/src/service/router.test.ts index 807b45d53e..bbcf506d19 100644 --- a/plugins/signals-backend/src/service/router.test.ts +++ b/plugins/signals-backend/src/service/router.test.ts @@ -21,10 +21,11 @@ import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; -import { EventBroker } from '@backstage/plugin-events-node'; +import { EventsService } from '@backstage/plugin-events-node'; import { IdentityApi } from '@backstage/plugin-auth-node'; +import { UserInfoService } from '@backstage/backend-plugin-api'; -const eventBrokerMock: jest.Mocked = { +const eventsServiceMock: jest.Mocked = { subscribe: jest.fn(), publish: jest.fn(), }; @@ -38,6 +39,10 @@ const discovery: jest.Mocked = { getExternalBaseUrl: jest.fn(), }; +const userInfo: jest.Mocked = { + getUserInfo: jest.fn(), +}; + describe('createRouter', () => { let app: express.Express; @@ -45,8 +50,9 @@ describe('createRouter', () => { const router = await createRouter({ logger: getVoidLogger(), identity: identityApiMock, - eventBroker: eventBrokerMock, + events: eventsServiceMock, discovery, + userInfo, }); app = express().use(router); }); diff --git a/plugins/signals-backend/src/service/router.ts b/plugins/signals-backend/src/service/router.ts index cc8fe9b851..fab706e878 100644 --- a/plugins/signals-backend/src/service/router.ts +++ b/plugins/signals-backend/src/service/router.ts @@ -14,44 +14,111 @@ * limitations under the License. */ import { + createLegacyAuthAdapters, errorHandler, PluginEndpointDiscovery, } from '@backstage/backend-common'; import express, { NextFunction, Request, Response } from 'express'; import Router from 'express-promise-router'; -import { LoggerService } from '@backstage/backend-plugin-api'; +import { + AuthService, + BackstageUserInfo, + LoggerService, + UserInfoService, +} from '@backstage/backend-plugin-api'; import * as https from 'https'; import http, { IncomingMessage } from 'http'; import { SignalManager } from './SignalManager'; -import { - BackstageIdentityResponse, - IdentityApi, - IdentityApiGetIdentityRequest, -} from '@backstage/plugin-auth-node'; -import { EventBroker } from '@backstage/plugin-events-node'; +import { IdentityApi } from '@backstage/plugin-auth-node'; +import { EventsService } from '@backstage/plugin-events-node'; import { WebSocket, WebSocketServer } from 'ws'; +import { Duplex } from 'stream'; /** @public */ export interface RouterOptions { logger: LoggerService; - eventBroker?: EventBroker; + events: EventsService; identity: IdentityApi; discovery: PluginEndpointDiscovery; + auth?: AuthService; + userInfo?: UserInfoService; } /** @public */ export async function createRouter( options: RouterOptions, ): Promise { - const { logger, identity, discovery } = options; + const { logger, discovery } = options; + const { auth, userInfo } = createLegacyAuthAdapters(options); + const manager = SignalManager.create(options); let subscribedToUpgradeRequests = false; + let apiUrl: string | undefined = undefined; const webSocketServer = new WebSocketServer({ noServer: true, clientTracking: false, }); + webSocketServer.on('error', (error: Error) => { + logger.error('WebSocket server error', error); + }); + + webSocketServer.on('close', () => { + logger.info('WebSocket server closed'); + }); + + const handleUpgrade = async ( + request: Request, + socket: Duplex, + head: Buffer, + ) => { + if (!apiUrl) { + apiUrl = await discovery.getBaseUrl('signals'); + } + + if (!request.url || !apiUrl || !apiUrl.endsWith(request.url)) { + return; + } + + let userIdentity: BackstageUserInfo | undefined = undefined; + + // Authentication token is passed in Sec-WebSocket-Protocol header as there + // is no other way to pass the token with plain websockets + try { + const token = request.headers['sec-websocket-protocol']; + if (token) { + const credentials = await auth.authenticate(token); + if (auth.isPrincipal(credentials, 'user')) { + userIdentity = await userInfo.getUserInfo(credentials); + } + } + } catch (e) { + logger.error('Failed to authenticate WebSocket connection', e); + socket.write( + 'HTTP/1.1 401 Web Socket Protocol Handshake\r\n' + + 'Upgrade: WebSocket\r\n' + + 'Connection: Upgrade\r\n' + + '\r\n', + ); + socket.destroy(); + return; + } + + try { + webSocketServer.handleUpgrade( + request, + socket, + head, + (ws: WebSocket, __: IncomingMessage) => { + manager.addConnection(ws, userIdentity); + }, + ); + } catch (e) { + logger.error('Failed to handle WebSocket upgrade', e); + } + }; + const upgradeMiddleware = async ( req: Request, _: Response, @@ -70,34 +137,7 @@ export async function createRouter( } subscribedToUpgradeRequests = true; - const apiUrl = await discovery.getBaseUrl('signals'); - server.on('upgrade', async (request, socket, head) => { - if (!request.url || !apiUrl.endsWith(request.url)) { - return; - } - - let userIdentity: BackstageIdentityResponse | undefined = undefined; - - // Authentication token is passed in Sec-WebSocket-Protocol header as there - // is no other way to pass the token with plain websockets - const token = req.headers['sec-websocket-protocol']; - if (token) { - userIdentity = await identity.getIdentity({ - request: { - headers: { authorization: token }, - }, - } as IdentityApiGetIdentityRequest); - } - - webSocketServer.handleUpgrade( - request, - socket, - head, - (ws: WebSocket, __: IncomingMessage) => { - manager.addConnection(ws, userIdentity); - }, - ); - }); + server.on('upgrade', handleUpgrade); }; const router = Router(); diff --git a/plugins/signals-backend/src/service/standaloneServer.ts b/plugins/signals-backend/src/service/standaloneServer.ts deleted file mode 100644 index 00ef7b5c77..0000000000 --- a/plugins/signals-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - createServiceBuilder, - HostDiscovery, - loadBackendConfig, -} from '@backstage/backend-common'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; -import { DefaultSignalService } from '@backstage/plugin-signals-node'; -import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; -import { - EventBroker, - EventParams, - EventSubscriber, -} from '@backstage/plugin-events-node'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'signals-backend' }); - logger.debug('Starting application server...'); - const config = await loadBackendConfig({ logger, argv: process.argv }); - const discovery = HostDiscovery.fromConfig(config); - - const identity = DefaultIdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }); - - const mockSubscribers: EventSubscriber[] = []; - const eventBroker: EventBroker = { - async publish(params: EventParams): Promise { - mockSubscribers.forEach(sub => sub.onEvent(params)); - }, - subscribe(...subscribers: EventSubscriber[]) { - subscribers.flat().forEach(subscriber => { - mockSubscribers.push(subscriber); - }); - }, - }; - - const signals = DefaultSignalService.create({ - eventBroker, - }); - - const router = await createRouter({ - logger, - identity, - eventBroker, - discovery, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/signals', router); - if (options.enableCors) { - service = service.enableCors({ origin: 'http://localhost:3000' }); - } - - let server: Promise; - try { - server = service.start(); - - setInterval(() => { - signals.publish({ - recipients: null, - channel: 'test', - message: { hello: 'world' }, - }); - }, 5000); - } catch (err) { - logger.error(err); - process.exit(1); - } - return server; -} - -module.hot?.accept(); diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index fec196efb5..3599e86aaa 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,162 @@ # @backstage/plugin-signals-node +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.4-next.0 + +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/plugin-events-node@0.3.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/plugin-events-node@0.3.3-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + - @backstage/plugin-events-node@0.3.3-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/plugin-events-node@0.3.2 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-auth-node@0.4.10 + - @backstage/plugin-events-node@0.3.1 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.0 + +### Minor Changes + +- 6c1547a: **BREAKING** Type definition added to signal recipients + + Update to use `{type: 'broadcast'}` instead `null` and `{type: 'user', entityRef: ''}` + instead string entity references + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- 6d84ee6: Renamed `SignalService` to `SignalsService` and `signalService` to `signalServiceRef` + to follow the naming scheme of services and their references +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0 + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## 0.1.0-next.2 + +### Patch Changes + +- 6d84ee6: Renamed `SignalService` to `SignalsService` and `signalService` to `signalServiceRef` + to follow the naming scheme of services and their references +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.2 + +## 0.1.0-next.1 + +### Minor Changes + +- daf85dc: BREAKING CHANGE: Migrates signals to use the `EventsService` and makes it mandatory + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.3.0-next.1 + +## 0.0.4-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/plugin-events-node@0.3.0-next.0 + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## 0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- 1ab22c4: Allow defining signal type to publish and receive +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.2.19 + ## 0.0.1-next.3 ### Patch Changes diff --git a/plugins/signals-node/README.md b/plugins/signals-node/README.md index 5e738a849d..9315e65680 100644 --- a/plugins/signals-node/README.md +++ b/plugins/signals-node/README.md @@ -6,28 +6,70 @@ Signals plugin allows backend plugins to publish messages to frontend plugins. ## Getting started +### New backend system + +In `packages/backend/index.ts`, add the signals backend: + +```ts +backend.add(import('@backstage/plugin-signals-backend')); +``` + +To use signals in your plugin, add it as a dependency to `my-plugin/plugin.ts`: + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { signalsServiceRef } from '@backstage/plugin-signals-node'; + +export const myPlugin = createBackendPlugin({ + pluginId: 'my-plugin', + register(env) { + env.registerInit({ + deps: { + httpRouter: coreServices.httpRouter, + signals: signalsServiceRef, + }, + async init({ httpRouter, signals }) { + httpRouter.use( + await createRouter({ + signals, + }), + ); + }, + }); + }, +}); +``` + +### Old backend system + Add SignalService to your plugin environment in `packages/backend/src/types.ts`: ```ts -import { SignalService } from '@backstage/plugin-signals-node'; +import { SignalsService } from '@backstage/plugin-signals-node'; export type PluginEnvironment = { // ... - signalService: SignalService; + signals: SignalsService; }; ``` Add it also to your `makeCreateEnv` to allow access from the other plugins: ```ts -import { SignalService } from '@backstage/plugin-signals-node'; +import { + SignalsService, + DefaultSignalsService, +} from '@backstage/plugin-signals-node'; import { DefaultEventBroker } from '@backstage/plugin-events-backend'; function makeCreateEnv(config: Config) { // ... const eventBroker = new DefaultEventBroker(root.child({ type: 'plugin' })); - const signalService = DefaultSignalService.create({ + const signalsService = DefaultSignalsService.create({ eventBroker, }); @@ -36,7 +78,7 @@ function makeCreateEnv(config: Config) { return { logger, eventBroker, - signalService, + signals: signalsService, // ... }; }; @@ -49,13 +91,13 @@ To allow connections from the frontend, you should also install the `@backstage/ Once you have both of the backend plugins installed, you can utilize the signal service by calling the `publish` method. This will publish the message to all subscribers in the frontend. To send message to -all subscribers, you can use `null` as `recipients` parameter. +all subscribers, you can use `broadcast` type: ```ts // Periodic sending example setInterval(async () => { - await signalService.publish({ - recipients: null, + await signals.publish({ + recipients: { type: 'broadcast' }, channel: 'my_plugin', message: { message: 'hello world', @@ -76,7 +118,7 @@ to work: eventBroker.publish({ topic: 'signals', eventPayload: { - recipients: ['user:default/user1'], + recipients: { type: 'user', entityRef: 'user:default/user1' }, message: { message: 'hello world', }, diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index 9d67e24732..cf4ab84aff 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -3,14 +3,17 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { EventBroker } from '@backstage/plugin-events-node'; +import { EventsService } from '@backstage/plugin-events-node'; import { JsonObject } from '@backstage/types'; import { ServiceRef } from '@backstage/backend-plugin-api'; +// @public @deprecated (undocumented) +export const DefaultSignalService: typeof DefaultSignalsService; + // @public (undocumented) -export class DefaultSignalService implements SignalService { +export class DefaultSignalsService implements SignalsService { // (undocumented) - static create(options: SignalServiceOptions): DefaultSignalService; + static create(options: SignalsServiceOptions): DefaultSignalsService; publish( signal: SignalPayload, ): Promise; @@ -18,25 +21,38 @@ export class DefaultSignalService implements SignalService { // @public (undocumented) export type SignalPayload = { - recipients: string[] | string | null; + recipients: + | { + type: 'user'; + entityRef: string | string[]; + } + | { + type: 'broadcast'; + }; channel: string; message: TMessage; }; +// @public @deprecated (undocumented) +export interface SignalService extends SignalsService {} + +// @public @deprecated (undocumented) +export const signalService: ServiceRef; + // @public (undocumented) -export interface SignalService { +export interface SignalsService { publish( signal: SignalPayload, ): Promise; } // @public (undocumented) -export const signalService: ServiceRef; +export type SignalsServiceOptions = { + events: EventsService; +}; // @public (undocumented) -export type SignalServiceOptions = { - eventBroker?: EventBroker; -}; +export const signalsServiceRef: ServiceRef; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 4c42255a32..ba454635ac 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-signals-node", "description": "Node.js library for the signals plugin", - "version": "0.0.1-next.3", + "version": "0.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -41,7 +41,7 @@ "@backstage/plugin-events-node": "workspace:^", "@backstage/types": "workspace:^", "express": "^4.17.1", - "uuid": "^8.0.0", + "uuid": "^9.0.0", "ws": "^8.14.2" } } diff --git a/plugins/signals-node/src/DefaultSignalService.test.ts b/plugins/signals-node/src/DefaultSignalService.test.ts deleted file mode 100644 index 9938c84c86..0000000000 --- a/plugins/signals-node/src/DefaultSignalService.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { DefaultSignalService } from './DefaultSignalService'; - -describe('DefaultSignalService', () => { - const mockEventBroker = { - publish: jest.fn(), - subscribe: jest.fn(), - }; - - const service = DefaultSignalService.create({ eventBroker: mockEventBroker }); - - it('should publish signal', () => { - const signal = { - channel: 'test-channel', - recipients: null, - message: { msg: 'hello world' }, - }; - service.publish(signal); - expect(mockEventBroker.publish).toHaveBeenCalledWith({ - topic: 'signals', - eventPayload: signal, - }); - }); -}); diff --git a/plugins/signals-node/src/DefaultSignalService.ts b/plugins/signals-node/src/DefaultSignalService.ts deleted file mode 100644 index d1bc14e166..0000000000 --- a/plugins/signals-node/src/DefaultSignalService.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { EventBroker } from '@backstage/plugin-events-node'; -import { SignalPayload, SignalServiceOptions } from './types'; -import { SignalService } from './SignalService'; -import { JsonObject } from '@backstage/types'; - -/** @public */ -export class DefaultSignalService implements SignalService { - // TODO: Remove this to be optional when events-backend has eventBroker as service - private eventBroker?: EventBroker; - - static create(options: SignalServiceOptions) { - return new DefaultSignalService(options); - } - - private constructor(options: SignalServiceOptions) { - ({ eventBroker: this.eventBroker } = options); - } - - /** - * Publishes a signal to user refs to specific topic - * @param signal - Signal to publish - */ - async publish( - signal: SignalPayload, - ) { - await this.eventBroker?.publish({ - topic: 'signals', - eventPayload: signal, - }); - } -} diff --git a/plugins/signals-node/src/DefaultSignalsService.test.ts b/plugins/signals-node/src/DefaultSignalsService.test.ts new file mode 100644 index 0000000000..982ca20d53 --- /dev/null +++ b/plugins/signals-node/src/DefaultSignalsService.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { DefaultSignalsService } from './DefaultSignalsService'; +import { SignalPayload } from './types'; + +describe('DefaultSignalsService', () => { + const mockEvents = { + publish: jest.fn(), + subscribe: jest.fn(), + }; + + const service = DefaultSignalsService.create({ events: mockEvents }); + + it('should publish signal', () => { + const signal: SignalPayload = { + channel: 'test-channel', + recipients: { type: 'broadcast' }, + message: { msg: 'hello world' }, + }; + service.publish(signal); + expect(mockEvents.publish).toHaveBeenCalledWith({ + topic: 'signals', + eventPayload: signal, + }); + }); +}); diff --git a/plugins/signals-node/src/DefaultSignalsService.ts b/plugins/signals-node/src/DefaultSignalsService.ts new file mode 100644 index 0000000000..ca1412c6fa --- /dev/null +++ b/plugins/signals-node/src/DefaultSignalsService.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { EventsService } from '@backstage/plugin-events-node'; +import { SignalPayload, SignalsServiceOptions } from './types'; +import { SignalsService } from './SignalsService'; +import { JsonObject } from '@backstage/types'; + +/** @public */ +export class DefaultSignalsService implements SignalsService { + private events: EventsService; + + static create(options: SignalsServiceOptions) { + return new DefaultSignalsService(options); + } + + private constructor(options: SignalsServiceOptions) { + ({ events: this.events } = options); + } + + /** + * Publishes a signal to user refs to specific topic + * @param signal - Signal to publish + */ + async publish( + signal: SignalPayload, + ) { + await this.events.publish({ + topic: 'signals', + eventPayload: signal, + }); + } +} + +/** + * @public + * @deprecated Use `DefaultSignalsService` instead + */ +export const DefaultSignalService = DefaultSignalsService; diff --git a/plugins/signals-node/src/SignalService.ts b/plugins/signals-node/src/SignalService.ts deleted file mode 100644 index 7011c6c525..0000000000 --- a/plugins/signals-node/src/SignalService.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { SignalPayload } from './types'; -import { JsonObject } from '@backstage/types'; - -/** @public */ -export interface SignalService { - /** - * Publishes a signal to user refs to specific topic - * @param signal - Signal to publish - */ - publish( - signal: SignalPayload, - ): Promise; -} diff --git a/plugins/signals-node/src/SignalsService.ts b/plugins/signals-node/src/SignalsService.ts new file mode 100644 index 0000000000..f338ceaaad --- /dev/null +++ b/plugins/signals-node/src/SignalsService.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { SignalPayload } from './types'; +import { JsonObject } from '@backstage/types'; + +/** @public */ +export interface SignalsService { + /** + * Publishes a signal to user refs to specific topic + * @param signal - Signal to publish + */ + publish( + signal: SignalPayload, + ): Promise; +} + +/** + * @public + * @deprecated Use `SignalsService` instead + */ +export interface SignalService extends SignalsService {} diff --git a/plugins/signals-node/src/index.ts b/plugins/signals-node/src/index.ts index f9c220b1e9..822670040f 100644 --- a/plugins/signals-node/src/index.ts +++ b/plugins/signals-node/src/index.ts @@ -15,6 +15,6 @@ */ export * from './lib'; -export * from './DefaultSignalService'; -export * from './SignalService'; +export * from './DefaultSignalsService'; +export * from './SignalsService'; export * from './types'; diff --git a/plugins/signals-node/src/lib.ts b/plugins/signals-node/src/lib.ts index 095a2f085d..1eed90e273 100644 --- a/plugins/signals-node/src/lib.ts +++ b/plugins/signals-node/src/lib.ts @@ -17,22 +17,28 @@ import { createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; -import { DefaultSignalService } from './DefaultSignalService'; -import { SignalService } from './SignalService'; +import { DefaultSignalsService } from './DefaultSignalsService'; +import { SignalsService } from './SignalsService'; +import { eventsServiceRef } from '@backstage/plugin-events-node'; /** @public */ -export const signalService = createServiceRef({ +export const signalsServiceRef = createServiceRef({ id: 'signals.service', scope: 'plugin', defaultFactory: async service => createServiceFactory({ service, deps: { - // TODO: EventBroker. It is optional for now but it's actually required so waiting for the new backend system - // for the events-backend for this to work. + events: eventsServiceRef, }, - factory({}) { - return DefaultSignalService.create({}); + factory({ events }) { + return DefaultSignalsService.create({ events }); }, }), }); + +/** + * @public + * @deprecated Use `signalsServiceRef` instead + */ +export const signalService = signalsServiceRef; diff --git a/plugins/signals-node/src/types.ts b/plugins/signals-node/src/types.ts index ec6e815b29..4decef6272 100644 --- a/plugins/signals-node/src/types.ts +++ b/plugins/signals-node/src/types.ts @@ -13,19 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EventBroker } from '@backstage/plugin-events-node'; +import { EventsService } from '@backstage/plugin-events-node'; import { JsonObject } from '@backstage/types'; /** * @public */ -export type SignalServiceOptions = { - eventBroker?: EventBroker; +export type SignalsServiceOptions = { + events: EventsService; }; /** @public */ export type SignalPayload = { - recipients: string[] | string | null; + recipients: + | { type: 'user'; entityRef: string | string[] } + | { type: 'broadcast' }; channel: string; message: TMessage; }; diff --git a/plugins/signals-react/.eslintrc.js b/plugins/signals-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/signals-react/.eslintrc.js +++ b/plugins/signals-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/signals-react/CHANGELOG.md b/plugins/signals-react/CHANGELOG.md index b0732d8e3d..72f0bc4084 100644 --- a/plugins/signals-react/CHANGELOG.md +++ b/plugins/signals-react/CHANGELOG.md @@ -1,5 +1,60 @@ # @backstage/plugin-signals-react +## 0.0.3 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + +## 0.0.3-next.0 + +### Patch Changes + +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## 0.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + +## 0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/types@1.1.1 + +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + +## 0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- 1ab22c4: Allow defining signal type to publish and receive +- Updated dependencies + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + ## 0.0.1-next.3 ### Patch Changes diff --git a/plugins/signals-react/README.md b/plugins/signals-react/README.md index 4da9338866..df8321db24 100644 --- a/plugins/signals-react/README.md +++ b/plugins/signals-react/README.md @@ -38,9 +38,9 @@ You can also use the signal API directly. This allows more fine-grained control subscriptions. ```ts -import { signalsApiRef } from '@backstage/plugin-signals-react'; +import { signalApiRef } from '@backstage/plugin-signals-react'; -const signals = useApi(signalsApiRef); +const signals = useApi(signalApiRef); const { unsubscribe } = signals.subscribe( 'myplugin:channel', (message: JsonObject) => { diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index a3f8cc397e..4b36dddd5c 100644 --- a/plugins/signals-react/package.json +++ b/plugins/signals-react/package.json @@ -1,10 +1,10 @@ { "name": "@backstage/plugin-signals-react", + "version": "0.0.3", "description": "Web library for the signals plugin", - "version": "0.0.1-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -15,34 +15,34 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/signals-react" }, - "backstage": { - "role": "web-library" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-plugin-api": "workspace:^", "@backstage/types": "workspace:^", "@material-ui/core": "^4.12.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" + "@testing-library/react": "^15.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + } } diff --git a/plugins/signals/.eslintrc.js b/plugins/signals/.eslintrc.js index e2a53a6ad2..a2d8179106 100644 --- a/plugins/signals/.eslintrc.js +++ b/plugins/signals/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index 50c9ddf132..3f0e646944 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,139 @@ # @backstage/plugin-signals +## 0.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.3 + +## 0.0.5 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- 9a41a7b: Migrate signals and notifications to the new backend in local development +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/theme@0.5.3 + - @backstage/plugin-signals-react@0.0.3 + - @backstage/types@1.1.1 + +## 0.0.5-next.1 + +### Patch Changes + +- f06458c: fixed typo in docs +- Updated dependencies + - @backstage/plugin-signals-react@0.0.3-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## 0.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## 0.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## 0.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## 0.0.2 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- 72df7c6: Added ESLint rule `no-top-level-material-ui-4-imports` in the `signals` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/theme@0.5.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2 + +## 0.0.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## 0.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.1 + +## 0.0.2-next.0 + +### Patch Changes + +- 0fb419b: Updated dependency `uuid` to `^9.0.0`. + Updated dependency `@types/uuid` to `^9.0.0`. +- Updated dependencies + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.2-next.0 + +## 0.0.1 + +### Patch Changes + +- 447d210: Fix disconnect loop on server start +- 8472188: Added or fixed the `repository` field in `package.json`. +- 047bead: Add support to subscribe and publish messages through signals plugins +- 1ab22c4: Allow defining signal type to publish and receive +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-signals-react@0.0.1 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/types@1.1.1 + ## 0.0.1-next.3 ### Patch Changes diff --git a/plugins/signals/README.md b/plugins/signals/README.md index 7b96da32f1..38dc18808b 100644 --- a/plugins/signals/README.md +++ b/plugins/signals/README.md @@ -30,9 +30,9 @@ const app = createApp({ Now you can utilize the API from other plugins using the `@backstage/plugin-signals-react` package or simply by: ```ts -import { signalsApiRef } from '@backstage/plugin-signals-react'; +import { signalApiRef } from '@backstage/plugin-signals-react'; -const signals = useApi(signalsApiRef); +const signals = useApi(signalApiRef); const { unsubscribe } = signals.subscribe( 'myplugin:topic', (message: JsonObject) => { diff --git a/plugins/signals/dev/index.tsx b/plugins/signals/dev/index.tsx index e8c7928f57..629c820a8e 100644 --- a/plugins/signals/dev/index.tsx +++ b/plugins/signals/dev/index.tsx @@ -16,20 +16,33 @@ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; import { signalsPlugin } from '../src/plugin'; -import { Content, Header, Page } from '@backstage/core-components'; -import { Typography } from '@material-ui/core'; +import { CodeSnippet, Content, Header, Page } from '@backstage/core-components'; +import Typography from '@material-ui/core/Typography'; +import { useSignal } from '@backstage/plugin-signals-react'; + +const SignalsDebugPage = () => { + const { lastSignal } = useSignal('debug'); + return ( + +
+ + Last signal: + + {lastSignal ? ( + + ) : ( + 'Not received' + )} + + + + ); +}; createDevApp() .registerPlugin(signalsPlugin) .addPage({ title: 'Debug', - element: ( - -
- - TODO - - - ), + element: , }) .render(); diff --git a/plugins/signals/package.json b/plugins/signals/package.json index 6201397b8e..9f248def27 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,9 +1,9 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.1-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "0.0.6-next.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,18 +14,21 @@ "url": "https://github.com/backstage/backstage", "directory": "plugins/signals" }, - "backstage": { - "role": "frontend-plugin" - }, + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -37,10 +40,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", "react-use": "^17.2.4", - "uuid": "^8.0.0" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" + "uuid": "^9.0.0" }, "devDependencies": { "@backstage/cli": "workspace:^", @@ -48,12 +48,12 @@ "@backstage/dev-utils": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "jest-websocket-mock": "^2.5.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + } } diff --git a/plugins/sonarqube-backend/.eslintrc.js b/plugins/sonarqube-backend/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/sonarqube-backend/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md deleted file mode 100644 index 7b3b23fb0b..0000000000 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ /dev/null @@ -1,699 +0,0 @@ -# @backstage/plugin-sonarqube-backend - -## 0.2.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.12-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.1 - - @backstage/backend-common@0.21.0-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/backend-plugin-api@0.6.10-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.11 - -### Patch Changes - -- 53445cd: Updated README -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/backend-plugin-api@0.6.9 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.11-next.2 - -### Patch Changes - -- 53445cd: Updated README -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - - @backstage/backend-common@0.20.1-next.2 - -## 0.2.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/backend-plugin-api@0.6.9-next.1 - - @backstage/errors@1.2.3 - -## 0.2.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/backend-plugin-api@0.6.9-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.10 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/backend-plugin-api@0.6.8 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-plugin-api@0.6.8-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/backend-plugin-api@0.6.8-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-plugin-api@0.6.8-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-plugin-api@0.6.8-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.9 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/backend-plugin-api@0.6.7 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - - @backstage/backend-common@0.19.9-next.2 - -## 0.2.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-plugin-api@0.6.7-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.2.8 - -### Patch Changes - -- a5d592d0ad: Added support for the [new backend system](https://backstage.io/docs/backend-system/) -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/errors@1.2.3 - - @backstage/backend-plugin-api@0.6.6 - - @backstage/config@1.1.1 - -## 0.2.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/backend-plugin-api@0.6.6-next.2 - - @backstage/config@1.1.1-next.0 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/backend-plugin-api@0.6.5-next.1 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.2.7-next.0 - -### Patch Changes - -- a5d592d0ad: Added support for the [new backend system](https://backstage.io/docs/backend-system/) -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/backend-plugin-api@0.6.5-next.0 - - @backstage/errors@1.2.2 - -## 0.2.5 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.2.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/backend-common@0.19.5-next.3 - -## 0.2.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/errors@1.2.1 - -## 0.2.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/errors@1.2.1 - -## 0.2.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.2.2 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- a24d9df8757c: Added optional `externalBaseUrl` config for setting a different frontend URL -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.2.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.2 - -## 0.2.2-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.2.1 - -### Patch Changes - -- fcaf4cfc70ee: Made default config optional -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/config@1.0.8 - -## 0.2.1-next.1 - -### Patch Changes - -- fcaf4cfc70ee: Made default config optional -- Updated dependencies - - @backstage/config@1.0.8 - -## 0.2.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/config@1.0.8 - -## 0.2.0 - -### Minor Changes - -- ce9bc94c15e1: fix sonarqube case in config schema definition - -### Patch Changes - -- 0bb0b19b0da2: Provide full schema definition for sonarqube plugin, especially to protect api keys. -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/errors@1.2.0 - - @backstage/config@1.0.8 - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.2.0-next.0 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/errors@1.2.0-next.0 - - @backstage/config@1.0.7 - -## 0.1.11-next.0 - -### Patch Changes - -- 0bb0b19b0da2: Provide full schema definition for sonarqube plugin, especially to protect api keys. -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/config@1.0.7 - -## 0.1.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.9 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.9-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.8 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3 - - @backstage/errors@1.1.5 - - @backstage/config@1.0.7 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.1.8-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/backend-common@0.18.3-next.1 - - @backstage/config@1.0.7-next.0 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - -## 0.1.4 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 3dee2f5ad0: Added links to the frontend and backend plugins in the readme. -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/errors@1.1.4 - - @backstage/config@1.0.5 - -## 0.1.4-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.1.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.1.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.1.4-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/config@1.0.4 - - @backstage/errors@1.1.3 - -## 0.1.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.1.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.1.2 - -### Patch Changes - -- 9c595302cb: Normalize on winston version ^3.2.1 -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/config@1.0.3 - - @backstage/errors@1.1.2 - -## 0.1.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/errors@1.1.2-next.2 - -## 0.1.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/errors@1.1.2-next.1 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/errors@1.1.2-next.0 - -## 0.1.1 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- ef9ab322de: Minor API signatures cleanup -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/backend-common@0.15.1-next.3 - -## 0.1.1-next.1 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.2 - -## 0.1.1-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- ef9ab322de: Minor API signatures cleanup -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - -## 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 deleted file mode 100644 index 6206cd8257..0000000000 --- a/plugins/sonarqube-backend/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# sonarqube-backend - -Welcome to the sonarqube-backend backend plugin! - -## New Backend System - -The Sonarqube backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: - -In your `packages/backend/src/index.ts` make the following changes: - -```diff - import { createBackend } from '@backstage/backend-defaults'; - const backend = createBackend(); - // ... other feature additions -+ backend.add(import('@backstage/plugin-sonarqube-backend')); - backend.start(); -``` - -## Integrating into a backstage instance - -This plugin needs to be added to an existing backstage instance. - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @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 -``` - -#### Example - Different frontend and backend URLs - -In some instances, you might want to use one URL for the backend and another for the frontend. -This can be achieved by using the optional `externalBaseUrl` property in the config. - -##### Single instance config - -```yaml -sonarqube: - baseUrl: https://sonarqube-internal.example.com - externalBaseUrl: https://sonarqube.example.com - apiKey: 123456789abcdef0123456789abcedf012 -``` - -##### Multiple instance config - -```yaml -sonarqube: - instances: - - name: default - baseUrl: https://default-sonarqube-internal.example.com - externalBaseUrl: https://default-sonarqube.example.com - apiKey: 123456789abcdef0123456789abcedf012 - - name: specialProject - baseUrl: https://special-project-sonarqube.example.com - apiKey: abcdef0123456789abcedf0123456789ab -``` - -## Links - -- [Sonarqube Frontend](../sonarqube/README.md) diff --git a/plugins/sonarqube-backend/api-report.md b/plugins/sonarqube-backend/api-report.md deleted file mode 100644 index c3c684f9d4..0000000000 --- a/plugins/sonarqube-backend/api-report.md +++ /dev/null @@ -1,81 +0,0 @@ -## 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 { BackendFeature } from '@backstage/backend-plugin-api'; -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; - externalBaseUrl?: 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; - externalBaseUrl?: string; - }; - getFindings(options: { - componentKey: string; - instanceName?: string; - }): Promise; -} - -// @public -export interface SonarqubeInstanceConfig { - apiKey: string; - baseUrl: string; - externalBaseUrl?: string; - name: string; -} - -// @public -export interface SonarqubeMeasure { - metric: string; - value: string; -} - -// @public -const sonarqubePlugin: () => BackendFeature; -export default sonarqubePlugin; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/sonarqube-backend/catalog-info.yaml b/plugins/sonarqube-backend/catalog-info.yaml deleted file mode 100644 index 5609e72120..0000000000 --- a/plugins/sonarqube-backend/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-sonarqube-backend - title: '@backstage/plugin-sonarqube-backend' -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: maintainers diff --git a/plugins/sonarqube-backend/config.d.ts b/plugins/sonarqube-backend/config.d.ts deleted file mode 100644 index 6e03a53f0c..0000000000 --- a/plugins/sonarqube-backend/config.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Optional configurations for the SonarQube plugin */ - sonarqube?: { - /** - * The base url of the sonarqube installation. Defaults to https://sonarcloud.io. - * @visibility frontend - */ - baseUrl?: string; - - /** - * The external url of the sonarqube installation. - * Use this if you want to use a different url for the frontend than the backend. - * @visibility frontend - */ - externalBaseUrl?: string; - - /** - * The api key to access the sonarqube instance under baseUrl. - * @visibility secret - */ - apiKey?: string; - - /** - * The optional sonarqube instances. - * @visibility frontend - */ - instances?: Array<{ - /** - * The name of the sonarqube instance. - * @visibility frontend - */ - name: string; - - /** - * The base url of the sonarqube instance. - * @visibility frontend - */ - baseUrl: string; - - /** - * The external url of the sonarqube instance. - * Use this if you want to use a different url for the frontend than the backend. - * @visibility frontend - */ - externalBaseUrl?: string; - - /** - * The api key to access the sonarqube instance. - * @visibility secret - */ - apiKey: string; - }>; - }; -} diff --git a/plugins/sonarqube-backend/knip-report.md b/plugins/sonarqube-backend/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/sonarqube-backend/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json deleted file mode 100644 index c27a553470..0000000000 --- a/plugins/sonarqube-backend/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@backstage/plugin-sonarqube-backend", - "version": "0.2.12-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/sonarqube-backend" - }, - "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": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@types/express": "*", - "express": "^4.18.1", - "express-promise-router": "^4.1.0", - "node-fetch": "^2.6.7", - "winston": "^3.2.1", - "yn": "^5.0.0" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^", - "@types/supertest": "^2.0.12", - "msw": "^1.0.0", - "supertest": "^6.2.4" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/sonarqube-backend/src/index.ts b/plugins/sonarqube-backend/src/index.ts deleted file mode 100644 index 4bb82df34e..0000000000 --- a/plugins/sonarqube-backend/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './service/router'; -export * from './service/sonarqubeInfoProvider'; -export { sonarqubePlugin as default } from './plugin'; diff --git a/plugins/sonarqube-backend/src/plugin.test.tsx b/plugins/sonarqube-backend/src/plugin.test.tsx deleted file mode 100644 index 9b26a88862..0000000000 --- a/plugins/sonarqube-backend/src/plugin.test.tsx +++ /dev/null @@ -1,22 +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 { sonarqubePlugin } from './plugin'; - -describe('sonarqube', () => { - it('should export the sonarqube plugin', () => { - expect(sonarqubePlugin).toBeDefined(); - }); -}); diff --git a/plugins/sonarqube-backend/src/plugin.ts b/plugins/sonarqube-backend/src/plugin.ts deleted file mode 100644 index fd4fb77fb4..0000000000 --- a/plugins/sonarqube-backend/src/plugin.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - createBackendPlugin, - coreServices, -} from '@backstage/backend-plugin-api'; -import { DefaultSonarqubeInfoProvider } from './service/sonarqubeInfoProvider'; -import { createRouter } from './service/router'; - -/** - * Sonarqube backend plugin - * - * @public - */ -export const sonarqubePlugin = createBackendPlugin({ - pluginId: 'sonarqube', - register(env) { - env.registerInit({ - deps: { - logger: coreServices.logger, - config: coreServices.rootConfig, - httpRouter: coreServices.httpRouter, - }, - async init({ logger, config, httpRouter }) { - const winstonLogger = loggerToWinstonLogger(logger); - httpRouter.use( - await createRouter({ - /** - * Logger for logging purposes - */ - logger: winstonLogger, - /** - * Info provider to be able to get all necessary information for the APIs - */ - sonarqubeInfoProvider: - DefaultSonarqubeInfoProvider.fromConfig(config), - }), - ); - }, - }); - }, -}); diff --git a/plugins/sonarqube-backend/src/run.ts b/plugins/sonarqube-backend/src/run.ts deleted file mode 100644 index 0a3ed2b7f0..0000000000 --- a/plugins/sonarqube-backend/src/run.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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 deleted file mode 100644 index b40e2d1528..0000000000 --- a/plugins/sonarqube-backend/src/service/router.test.ts +++ /dev/null @@ -1,162 +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 { 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; externalBaseUrl?: 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).toHaveBeenCalledTimes(1); - expect(getFindingsMock).toHaveBeenCalledWith({ - 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).toHaveBeenCalledTimes(1); - expect(getFindingsMock).toHaveBeenCalledWith({ - 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-internal.example.com'; - const DUMMY_INSTANCE_EXTERNAL_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).toHaveBeenCalledTimes(1); - expect(getBaseUrlMock).toHaveBeenCalledWith({ - 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).toHaveBeenCalledTimes(1); - expect(getBaseUrlMock).toHaveBeenCalledWith({ - instanceName: undefined, - }); - expect(response.status).toEqual(200); - expect(response.body).toEqual({ instanceUrl: DUMMY_INSTANCE_URL }); - }); - - it('returns the external base url when provided', async () => { - getBaseUrlMock.mockReturnValue({ - baseUrl: DUMMY_INSTANCE_URL, - externalBaseUrl: DUMMY_INSTANCE_EXTERNAL_URL, - }); - const response = await request(app).get('/instanceUrl').send(); - expect(response.status).toEqual(200); - expect(response.body).toEqual({ - instanceUrl: DUMMY_INSTANCE_EXTERNAL_URL, - }); - }); - }); -}); diff --git a/plugins/sonarqube-backend/src/service/router.ts b/plugins/sonarqube-backend/src/service/router.ts deleted file mode 100644 index 5a993b5d59..0000000000 --- a/plugins/sonarqube-backend/src/service/router.ts +++ /dev/null @@ -1,94 +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 { 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, externalBaseUrl } = sonarqubeInfoProvider.getBaseUrl({ - instanceName: instanceKey, - }); - response.json({ - instanceUrl: externalBaseUrl || 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 deleted file mode 100644 index 468020c1b3..0000000000 --- a/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.test.ts +++ /dev/null @@ -1,584 +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 { ConfigReader } from '@backstage/config'; -import { - DefaultSonarqubeInfoProvider, - SonarqubeConfig, -} from './sonarqubeInfoProvider'; -import { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/backend-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, - }, - ], - }, - }), - ), - ).toThrow(Error); - }); - - it('Throw an error if default config is partially provided', async () => { - expect(() => - SonarqubeConfig.fromConfig( - new ConfigReader({ - sonarqube: { - baseUrl: DUMMY_SONAR_URL, - }, - }), - ), - ).toThrow(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' }), - ).toThrow(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' }), - ).toThrow(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', - }); - }); - - it('Provide external base url for simple config', async () => { - const provider = configureProvider({ - sonarqube: { - baseUrl: 'https://sonarqube-internal.example.com', - externalBaseUrl: 'https://sonarqube.example.com', - apiKey: '123456789abcdef0123456789abcedf012', - }, - }); - - expect(provider.getBaseUrl()).toEqual({ - baseUrl: 'https://sonarqube-internal.example.com', - externalBaseUrl: 'https://sonarqube.example.com', - }); - }); - - it('Provide external 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-internal.example.com', - externalBaseUrl: 'https://sonarqube-other.example.com', - apiKey: '123456789abcdef0123456789abcedf012', - }, - ], - }, - }); - - expect(provider.getBaseUrl({ instanceName: 'other' })).toEqual({ - baseUrl: 'https://sonarqube-other-internal.example.com', - externalBaseUrl: '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 deleted file mode 100644 index a5c0bf985a..0000000000 --- a/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.ts +++ /dev/null @@ -1,397 +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 { 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; - externalBaseUrl?: 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; - /** - * External url to access the instance from the frontend - */ - externalBaseUrl?: 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'), - externalBaseUrl: c.getOptionalString('externalBaseUrl'), - 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 externalBaseUrl = - sonarqubeConfig.getOptionalString('externalBaseUrl'); - const apiKey = sonarqubeConfig.getOptionalString('apiKey'); - - if (hasNamedDefault && (baseUrl || externalBaseUrl || 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, externalBaseUrl, apiKey }, - ] as { - name: string; - baseUrl: string; - externalBaseUrl?: 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; - externalBaseUrl?: string; - } { - const instanceConfig = this.config.getInstanceConfig({ - sonarqubeName: options.instanceName, - }); - return { - baseUrl: instanceConfig.baseUrl, - externalBaseUrl: instanceConfig.externalBaseUrl, - }; - } - - /** - * {@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 deleted file mode 100644 index 06a8d4ffb2..0000000000 --- a/plugins/sonarqube-backend/src/service/standaloneServer.ts +++ /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 { - 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 deleted file mode 100644 index d3232290a7..0000000000 --- a/plugins/sonarqube-backend/src/setupTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export {}; diff --git a/plugins/sonarqube-react/.eslintrc.js b/plugins/sonarqube-react/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/sonarqube-react/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/sonarqube-react/CHANGELOG.md b/plugins/sonarqube-react/CHANGELOG.md deleted file mode 100644 index 1fbf8229f9..0000000000 --- a/plugins/sonarqube-react/CHANGELOG.md +++ /dev/null @@ -1,348 +0,0 @@ -# @backstage/plugin-sonarqube-react - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2 - - @backstage/catalog-model@1.4.3 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/catalog-model@1.4.3 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/catalog-model@1.4.3 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.1.10 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-plugin-api@1.8.0 - - @backstage/catalog-model@1.4.3 - -## 0.1.10-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/catalog-model@1.4.3 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - -## 0.1.8 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - -## 0.1.8-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-plugin-api@1.6.0-next.3 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/catalog-model@1.4.2-next.1 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/catalog-model@1.4.1 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.1.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/catalog-model@1.4.1-next.0 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.3-next.0 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/catalog-model@1.4.0 - -## 0.1.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.5 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.1.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-plugin-api@1.5.1-next.1 - -## 0.1.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - -## 0.1.5-next.0 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/catalog-model@1.2.1 - -## 0.1.4 - -### Patch Changes - -- 928a12a9b3e: Internal refactor of `/alpha` exports. -- 8ae65a0bc1d: Moved imports from `/alpha` to main public exports. -- Updated dependencies - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - -## 0.1.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.1.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.1.4-next.0 - -### Patch Changes - -- 928a12a9b3: Internal refactor of `/alpha` exports. -- 8ae65a0bc1: Moved imports from `/alpha` to main public exports. -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0 - - @backstage/core-plugin-api@1.4.0 - -## 0.1.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-plugin-api@1.3.0 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.6-next.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/core-plugin-api@1.3.0 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/catalog-model@1.1.5-next.1 - -## 0.1.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/core-plugin-api@1.2.0 - -## 0.1.0 - -### Minor Changes - -- 6b59903bfa: Parts of plugin-sonarqube have been moved into a new plugin-sonarqube-react package. Additionally some types that were - previously internal to plugin-sonarqube have been made public and will allow access for third-parties. As the sonarqube - plugin has not yet reached 1.0 breaking changes are expected in the future. As such exports of plugin-sonarqube-react - require importing via the `/alpha` entrypoint: - - ```ts - import { sonarQubeApiRef } from '@backstage/plugin-sonarqube-react/alpha'; - - const sonarQubeApi = useApi(sonarQubeApiRef); - ``` - - Moved from plugin-sonarqube to plugin-sonarqube-react: - - - isSonarQubeAvailable - - SONARQUBE_PROJECT_KEY_ANNOTATION - - Exports that been introduced to plugin-sonarqube-react are documented in the [API report](https://github.com/backstage/backstage/blob/master/plugins/sonarqube-react/api-report.md). - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/catalog-model@1.1.4 diff --git a/plugins/sonarqube-react/api-report.md b/plugins/sonarqube-react/api-report.md deleted file mode 100644 index 6ffa98915b..0000000000 --- a/plugins/sonarqube-react/api-report.md +++ /dev/null @@ -1,71 +0,0 @@ -## API Report File for "@backstage/plugin-sonarqube-react" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ApiRef } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; - -// @public (undocumented) -export interface FindingSummary { - // (undocumented) - getComponentMeasuresUrl: SonarUrlProcessorFunc; - // (undocumented) - getIssuesUrl: SonarUrlProcessorFunc; - // (undocumented) - getSecurityHotspotsUrl: () => string; - // (undocumented) - lastAnalysis: string; - // (undocumented) - metrics: Metrics; - // (undocumented) - projectUrl: string; -} - -// @public (undocumented) -export const isSonarQubeAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export type MetricKey = - | 'alert_status' - | 'bugs' - | 'reliability_rating' - | 'vulnerabilities' - | 'security_rating' - | 'code_smells' - | 'sqale_rating' - | 'security_hotspots_reviewed' - | 'security_review_rating' - | 'coverage' - | 'duplicated_lines_density'; - -// @public -export type Metrics = { - [key in MetricKey]: string | undefined; -}; - -// @public (undocumented) -export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; - -// @public (undocumented) -export type SonarQubeApi = { - getFindingSummary(options: { - componentKey?: string; - projectInstance?: string; - }): Promise; -}; - -// @public (undocumented) -export const sonarQubeApiRef: ApiRef; - -// @public (undocumented) -export type SonarUrlProcessorFunc = (identifier: string) => string; - -// @public -export const useProjectInfo: (entity: Entity) => { - projectInstance: string | undefined; - projectKey: string | undefined; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/sonarqube-react/catalog-info.yaml b/plugins/sonarqube-react/catalog-info.yaml deleted file mode 100644 index abcae8a465..0000000000 --- a/plugins/sonarqube-react/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-sonarqube-react - title: '@backstage/plugin-sonarqube-react' -spec: - lifecycle: experimental - type: backstage-web-library - owner: maintainers diff --git a/plugins/sonarqube-react/package.json b/plugins/sonarqube-react/package.json deleted file mode 100644 index 8245d529da..0000000000 --- a/plugins/sonarqube-react/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@backstage/plugin-sonarqube-react", - "version": "0.1.13-next.1", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "exports": { - ".": "./src/index.ts", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - "package.json": [ - "package.json" - ] - } - }, - "backstage": { - "role": "web-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/sonarqube-react" - }, - "keywords": [ - "backstage" - ], - "sideEffects": false, - "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/catalog-model": "workspace:^", - "@backstage/core-plugin-api": "workspace:^" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/react": "^16.13.1 || ^17.0.0" - }, - "files": [ - "dist", - "alpha" - ] -} diff --git a/plugins/sonarqube-react/src/api/SonarQubeApi.ts b/plugins/sonarqube-react/src/api/SonarQubeApi.ts deleted file mode 100644 index 13517d97fe..0000000000 --- a/plugins/sonarqube-react/src/api/SonarQubeApi.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 { createApiRef } from '@backstage/core-plugin-api'; - -/** @public */ -export type MetricKey = - // alert status - | 'alert_status' - - // bugs and rating (-> reliability) - | 'bugs' - | 'reliability_rating' - - // vulnerabilities and rating (-> security) - | 'vulnerabilities' - | 'security_rating' - - // code smells and rating (-> maintainability) - | 'code_smells' - | 'sqale_rating' - - // security hotspots - | 'security_hotspots_reviewed' - | 'security_review_rating' - - // coverage - | 'coverage' - - // duplicated lines - | 'duplicated_lines_density'; - -/** @public */ -export type SonarUrlProcessorFunc = (identifier: string) => string; - -/** - * @public - * - * Define a type to make sure that all metrics are used - */ -export type Metrics = { - [key in MetricKey]: string | undefined; -}; - -/** @public */ -export interface FindingSummary { - lastAnalysis: string; - metrics: Metrics; - projectUrl: string; - getIssuesUrl: SonarUrlProcessorFunc; - getComponentMeasuresUrl: SonarUrlProcessorFunc; - getSecurityHotspotsUrl: () => string; -} - -/** @public */ -export const sonarQubeApiRef = createApiRef({ - id: 'plugin.sonarqube.service', -}); - -/** @public */ -export type SonarQubeApi = { - getFindingSummary(options: { - componentKey?: string; - projectInstance?: string; - }): Promise; -}; diff --git a/plugins/sonarqube-react/src/api/index.ts b/plugins/sonarqube-react/src/api/index.ts deleted file mode 100644 index 35ebdacabe..0000000000 --- a/plugins/sonarqube-react/src/api/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 { sonarQubeApiRef } from './SonarQubeApi'; -export type { - Metrics, - MetricKey, - SonarQubeApi, - FindingSummary, - SonarUrlProcessorFunc, -} from './SonarQubeApi'; diff --git a/plugins/sonarqube-react/src/components/index.ts b/plugins/sonarqube-react/src/components/index.ts deleted file mode 100644 index 44c63fe052..0000000000 --- a/plugins/sonarqube-react/src/components/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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 { - isSonarQubeAvailable, - SONARQUBE_PROJECT_KEY_ANNOTATION, -} from './isSonarQubeAvailable'; diff --git a/plugins/sonarqube-react/src/components/isSonarQubeAvailable.test.ts b/plugins/sonarqube-react/src/components/isSonarQubeAvailable.test.ts deleted file mode 100644 index 9053b1a347..0000000000 --- a/plugins/sonarqube-react/src/components/isSonarQubeAvailable.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 { Entity } from '@backstage/catalog-model'; -import { - isSonarQubeAvailable, - SONARQUBE_PROJECT_KEY_ANNOTATION, -} from './isSonarQubeAvailable'; - -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); - }); -}); diff --git a/plugins/sonarqube-react/src/components/isSonarQubeAvailable.ts b/plugins/sonarqube-react/src/components/isSonarQubeAvailable.ts deleted file mode 100644 index d538b700f3..0000000000 --- a/plugins/sonarqube-react/src/components/isSonarQubeAvailable.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 { Entity } from '@backstage/catalog-model'; - -/** @public */ -export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; - -/** @public */ -export const isSonarQubeAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[SONARQUBE_PROJECT_KEY_ANNOTATION]); diff --git a/plugins/sonarqube-react/src/hooks/index.ts b/plugins/sonarqube-react/src/hooks/index.ts deleted file mode 100644 index 16892a5e3d..0000000000 --- a/plugins/sonarqube-react/src/hooks/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { useProjectInfo } from './useProjectInfo'; diff --git a/plugins/sonarqube-react/src/hooks/useProjectInfo.test.ts b/plugins/sonarqube-react/src/hooks/useProjectInfo.test.ts deleted file mode 100644 index db5e1f9689..0000000000 --- a/plugins/sonarqube-react/src/hooks/useProjectInfo.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 { Entity } from '@backstage/catalog-model'; -import { SONARQUBE_PROJECT_KEY_ANNOTATION } from '../components'; -import { useProjectInfo } from './useProjectInfo'; -import { SONARQUBE_PROJECT_INSTANCE_SEPARATOR } from './useProjectInfo'; - -const createDummyEntity = (sonarqubeAnnotationValue: string): Entity => { - return { - apiVersion: '', - kind: '', - metadata: { - name: 'dummy', - annotations: { - [SONARQUBE_PROJECT_KEY_ANNOTATION]: sonarqubeAnnotationValue, - }, - }, - }; -}; - -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, - }); - }); - - it('parse annotation with instance, tenant/project-key', () => { - const DUMMY_KEY_WITH_TENANT = 'dummy-tenant/dummyKey'; - const entity = createDummyEntity( - DUMMY_INSTANCE + - SONARQUBE_PROJECT_INSTANCE_SEPARATOR + - DUMMY_KEY_WITH_TENANT, - ); - expect(useProjectInfo(entity)).toEqual({ - projectInstance: DUMMY_INSTANCE, - projectKey: DUMMY_KEY_WITH_TENANT, - }); - }); - - it('parse annotation with instance, tenant:project-key', () => { - const DUMMY_KEY_WITH_TENANT = 'dummy-tenant:dummyKey'; - const entity = createDummyEntity( - DUMMY_INSTANCE + - SONARQUBE_PROJECT_INSTANCE_SEPARATOR + - DUMMY_KEY_WITH_TENANT, - ); - expect(useProjectInfo(entity)).toEqual({ - projectInstance: DUMMY_INSTANCE, - projectKey: DUMMY_KEY_WITH_TENANT, - }); - }); - - // 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-react/src/hooks/useProjectInfo.ts b/plugins/sonarqube-react/src/hooks/useProjectInfo.ts deleted file mode 100644 index 3336bd1805..0000000000 --- a/plugins/sonarqube-react/src/hooks/useProjectInfo.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 { Entity } from '@backstage/catalog-model'; -import { SONARQUBE_PROJECT_KEY_ANNOTATION } from '../components'; - -export const SONARQUBE_PROJECT_INSTANCE_SEPARATOR = '/'; - -/** - * - * Try to parse sonarqube information from an entity. - * - * If part or all info are not found, they will default to undefined - * - * @public - * @param entity - entity to find the sonarqube information from. - * @returns 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) { - const instanceSeparatorIndex = annotation.indexOf( - SONARQUBE_PROJECT_INSTANCE_SEPARATOR, - ); - if (instanceSeparatorIndex > -1) { - // Examples: - // instanceA/projectA -> projectInstance = "instanceA" & projectKey = "projectA" - // instanceA/tenantA:projectA -> projectInstance = "instanceA" & projectKey = "tenantA:projectA" - // instanceA/tenantA/projectA -> projectInstance = "instanceA" & projectKey = "tenantA/projectA" - projectInstance = annotation.substring(0, instanceSeparatorIndex); - projectKey = annotation.substring(instanceSeparatorIndex + 1); - } else { - projectKey = annotation; - } - } - return { projectInstance, projectKey }; -}; diff --git a/plugins/sonarqube-react/src/index.ts b/plugins/sonarqube-react/src/index.ts deleted file mode 100644 index fe04a0459f..0000000000 --- a/plugins/sonarqube-react/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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 './api'; -export * from './components'; -export * from './hooks'; diff --git a/plugins/sonarqube/.eslintrc.js b/plugins/sonarqube/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/sonarqube/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md deleted file mode 100644 index 287c805923..0000000000 --- a/plugins/sonarqube/CHANGELOG.md +++ /dev/null @@ -1,1766 +0,0 @@ -# @backstage/plugin-sonarqube - -## 0.7.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-sonarqube-react@0.1.13-next.1 - -## 0.7.12-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/plugin-sonarqube-react@0.1.13-next.1 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.7.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/plugin-sonarqube-react@0.1.13-next.0 - -## 0.7.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-sonarqube-react@0.1.12 - -## 0.7.11 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/plugin-sonarqube-react@0.1.12 - -## 0.7.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.7.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/plugin-sonarqube-react@0.1.12-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.7.11-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-sonarqube-react@0.1.11 - -## 0.7.10 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/plugin-sonarqube-react@0.1.11 - - @backstage/catalog-model@1.4.3 - -## 0.7.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - - @backstage/plugin-sonarqube-react@0.1.11-next.1 - -## 0.7.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-sonarqube-react@0.1.11-next.1 - -## 0.7.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/plugin-sonarqube-react@0.1.11-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.5.0-next.0 - -## 0.7.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/plugin-sonarqube-react@0.1.11-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.7.8 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- 62b5922916: Internal theme type updates -- 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/plugin-sonarqube-react@0.1.10 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - -## 0.7.8-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.7.8-next.1 - -### Patch Changes - -- 62b5922916: Internal theme type updates -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/plugin-sonarqube-react@0.1.10-next.0 - -## 0.7.8-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/plugin-sonarqube-react@0.1.10-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.7.6 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.4.3 - - @backstage/plugin-sonarqube-react@0.1.9 - -## 0.7.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/theme@0.4.3-next.0 - - @backstage/plugin-sonarqube-react@0.1.9-next.1 - -## 0.7.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - - @backstage/plugin-sonarqube-react@0.1.9-next.0 - -## 0.7.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - - @backstage/plugin-sonarqube-react@0.1.9-next.0 - -## 0.7.5 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- db92d1244897: Updated dependency `rc-progress` to `3.5.1`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/plugin-sonarqube-react@0.1.8 - - @backstage/theme@0.4.2 - -## 0.7.5-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/plugin-sonarqube-react@0.1.8-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.7.5-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- db92d1244897: Updated dependency `rc-progress` to `3.5.1`. -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/plugin-sonarqube-react@0.1.8-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/theme@0.4.1 - -## 0.7.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/plugin-sonarqube-react@0.1.8-next.1 - - @backstage/theme@0.4.1 - -## 0.7.4-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - - @backstage/plugin-sonarqube-react@0.1.8-next.0 - -## 0.7.2 - -### Patch Changes - -- b2ccddefbdc6: Remove sonarQube card disable class -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-sonarqube-react@0.1.7 - -## 0.7.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.7.2-next.1 - -### Patch Changes - -- b2ccddefbdc6: Remove sonarQube card disable class -- Updated dependencies - - @backstage/catalog-model@1.4.1 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/plugin-sonarqube-react@0.1.7 - -## 0.7.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-sonarqube-react@0.1.7 - -## 0.7.1 - -### Patch Changes - -- fcaf4cfc70ee: Made default config optional -- 015439b5b6ca: Updated dependency `rc-progress` to `3.4.2`. -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/plugin-sonarqube-react@0.1.7 - -## 0.7.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/plugin-sonarqube-react@0.1.7-next.2 - -## 0.7.1-next.1 - -### Patch Changes - -- fcaf4cfc70ee: Made default config optional -- 015439b5b6ca: Updated dependency `rc-progress` to `3.4.2`. -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - - @backstage/plugin-sonarqube-react@0.1.7-next.1 - -## 0.7.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - - @backstage/plugin-sonarqube-react@0.1.7-next.0 - -## 0.7.0 - -### Minor Changes - -- ce9bc94c15e1: fix sonarqube case in config schema definition - -### Patch Changes - -- 1108f1c65d31: fixed issued related #18259 now using luxon as adr102 asked -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/plugin-sonarqube-react@0.1.6 - -## 0.6.8-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - - @backstage/plugin-sonarqube-react@0.1.6-next.1 - -## 0.6.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.6.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/plugin-sonarqube-react@0.1.6-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.6.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/plugin-sonarqube-react@0.1.5 - -## 0.6.7 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-sonarqube-react@0.1.5 - -## 0.6.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.6.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.6.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/theme@0.2.19 - - @backstage/plugin-sonarqube-react@0.1.5 - -## 0.6.6 - -### Patch Changes - -- 5a368d12bc9: amend getSecurityHotspotsUrl to conditionally remove project path if sonarqube is self hosted -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/plugin-sonarqube-react@0.1.5 - -## 0.6.6-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/plugin-sonarqube-react@0.1.5-next.2 - -## 0.6.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/plugin-sonarqube-react@0.1.5-next.1 - -## 0.6.6-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-sonarqube-react@0.1.5-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - -## 0.6.6-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - - @backstage/plugin-sonarqube-react@0.1.4 - -## 0.6.5 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- 928a12a9b3e: Internal refactor of `/alpha` exports. -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 8ae65a0bc1d: Moved imports from `/alpha` to main public exports. -- d3d624e8e8d: Show a more appropriate icon if there are no code smells and/or vulnerabilities. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/plugin-sonarqube-react@0.1.4 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.6.5-next.2 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - - @backstage/plugin-sonarqube-react@0.1.4-next.2 - -## 0.6.5-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - - @backstage/plugin-sonarqube-react@0.1.4-next.1 - -## 0.6.5-next.0 - -### Patch Changes - -- 928a12a9b3: Internal refactor of `/alpha` exports. -- 8ae65a0bc1: Moved imports from `/alpha` to main public exports. -- d3d624e8e8: Show a more appropriate icon if there are no code smells and/or vulnerabilities. -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/plugin-sonarqube-react@0.1.4-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - -## 0.6.3 - -### Patch Changes - -- 6310eacc11: Additional export added in order to bind SonarQubeClient to its apiref -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/plugin-sonarqube-react@0.1.2 - -## 0.6.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - - @backstage/plugin-sonarqube-react@0.1.2-next.1 - -## 0.6.3-next.1 - -### Patch Changes - -- 6310eacc11: Additional export added in order to bind SonarQubeClient to its apiref -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-sonarqube-react@0.1.2-next.0 - -## 0.6.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/plugin-sonarqube-react@0.1.2-next.0 - -## 0.6.2 - -### Patch Changes - -- 80ce4e8c29: Small updates to some components to ensure theme typography properties are inherited correctly. -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-sonarqube-react@0.1.1 - -## 0.6.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-sonarqube-react@0.1.1-next.2 - -## 0.6.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - - @backstage/plugin-sonarqube-react@0.1.1-next.1 - -## 0.6.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-sonarqube-react@0.1.1-next.0 - -## 0.6.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.6.0 - -### Minor Changes - -- 6b59903bfa: Parts of plugin-sonarqube have been moved into a new plugin-sonarqube-react package. Additionally some types that were - previously internal to plugin-sonarqube have been made public and will allow access for third-parties. As the sonarqube - plugin has not yet reached 1.0 breaking changes are expected in the future. As such exports of plugin-sonarqube-react - require importing via the `/alpha` entrypoint: - - ```ts - import { sonarQubeApiRef } from '@backstage/plugin-sonarqube-react/alpha'; - - const sonarQubeApi = useApi(sonarQubeApiRef); - ``` - - Moved from plugin-sonarqube to plugin-sonarqube-react: - - - isSonarQubeAvailable - - SONARQUBE_PROJECT_KEY_ANNOTATION - - Exports that been introduced to plugin-sonarqube-react are documented in the [API report](https://github.com/backstage/backstage/blob/master/plugins/sonarqube-react/api-report.md). - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. -- 3dee2f5ad0: Added links to the frontend and backend plugins in the readme. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/plugin-sonarqube-react@0.1.0 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.5.1-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.5.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.5.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.5.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.5.1-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 17a8e32f39: Updated dependency `rc-progress` to `3.4.1`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.5.0 - -### Minor Changes - -- 786117e98a: Fix sonarqube annotation parsing. Add content page for Sonarqube. - Removed the deprecated `plugin` export; please use `sonarQubePlugin` instead. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/theme@0.2.16 - -## 0.4.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.4.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.4.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - -## 0.4.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - -## 0.4.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.4.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - -## 0.4.1 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- 7d47def9c4: Removed dependency on `@types/jest`. -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - -## 0.4.1-next.2 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.4.1-next.1 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.4.1-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.3.7-next.2 - -### Patch Changes - -- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.3.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.3.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.3.6 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.3.6-next.2 - -### Patch Changes - -- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.2 - -## 0.3.6-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.3.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.3.5 - -### Patch Changes - -- e462112be5: Updated dependency `rc-progress` to `3.3.2`. -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.3.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.3.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.3.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.3.4 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.3.4-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.3.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.3.3 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - -## 0.3.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.3.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.3.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.3.0 - -### Minor Changes - -- 2262fe19c9: **BREAKING**: Removed support for passing in an explicit `entity` prop to entity page extensions, which has been deprecated for a long time. This is only a breaking change at the TypeScript level, as this property was already ignored. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.2.17 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - -## 0.2.16 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.2.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.2.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.2.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.2.14 - -### Patch Changes - -- 7346b5fb96: chore(deps): bump `rc-progress` from 3.1.4 to 3.2.4 -- Updated dependencies - - @backstage/core-components@0.8.6 - -## 0.2.13 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.2.13-next.0 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.2.12 - -### Patch Changes - -- 3423b3b24d: Enhance token description by highlighting that the trailing colon is required. -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/catalog-model@0.9.9 - -## 0.2.11 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.2.10 - -### Patch Changes - -- 27af6d996b: Locking `rc-progress` to the working version of 3.1.4 -- 7a4bd2ceac: Prefer using `Link` from `@backstage/core-components` rather than material-UI. -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.2.9 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.2.8 - -### Patch Changes - -- b055a6addc: Align on usage of `cross-fetch` vs `node-fetch` in frontend vs backend packages, and remove some unnecessary imports of either one of them -- 59677fadb1: Improvements to API Reference documentation -- Updated dependencies - - @backstage/core-components@0.7.6 - - @backstage/theme@0.2.14 - - @backstage/core-plugin-api@0.2.2 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.9.7 - - @backstage/plugin-catalog-react@0.6.4 - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.0 - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.2.5 - -### Patch Changes - -- ca0559444c: Avoid usage of `.to*Case()`, preferring `.toLocale*Case('en-US')` instead. -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - - @backstage/plugin-catalog-react@0.5.2 - - @backstage/catalog-model@0.9.4 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - - @backstage/plugin-catalog-react@0.5.1 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/plugin-catalog-react@0.5.0 - - @backstage/catalog-model@0.9.3 - -## 0.2.2 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/plugin-catalog-react@0.4.6 - - @backstage/core-plugin-api@0.1.8 - -## 0.2.1 - -### Patch Changes - -- 38fd73fb5: Update README to show a simpler proxy configuration. -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.5 - - @backstage/core-components@0.4.0 - - @backstage/catalog-model@0.9.1 - -## 0.2.0 - -### Minor Changes - -- 8db48b968: Use IdentityApi to provide Auth Token for SonarQubeClient Api calls - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - - @backstage/plugin-catalog-react@0.4.2 - -## 0.1.24 - -### Patch Changes - -- 260c053b9: Fix All Material UI Warnings -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - - @backstage/plugin-catalog-react@0.4.1 - -## 0.1.23 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/plugin-catalog-react@0.4.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.1.22 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.3.0 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.1.5 - - @backstage/catalog-model@0.9.0 - - @backstage/plugin-catalog-react@0.2.6 - -## 0.1.20 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - - @backstage/catalog-model@0.8.4 - - @backstage/plugin-catalog-react@0.2.4 - -## 0.1.19 - -### Patch Changes - -- Updated dependencies [add62a455] -- Updated dependencies [cc592248b] -- Updated dependencies [17c497b81] -- Updated dependencies [704875e26] - - @backstage/catalog-model@0.8.0 - - @backstage/core@0.7.11 - - @backstage/plugin-catalog-react@0.2.0 - -## 0.1.18 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [10c008a3a] -- Updated dependencies [889d89b6e] -- Updated dependencies [16be1d093] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - - @backstage/plugin-catalog-react@0.1.6 - - @backstage/catalog-model@0.7.9 - -## 0.1.17 - -### Patch Changes - -- c614ede9a: Updated README to have up-to-date install instructions. -- Updated dependencies [9afcac5af] -- Updated dependencies [e0c9ed759] -- Updated dependencies [6eaecbd81] - - @backstage/core@0.7.7 - -## 0.1.16 - -### Patch Changes - -- db802fafb: Export isSonarQubeAvailable. -- Updated dependencies [bb5055aee] -- Updated dependencies [d0d1c2f7b] -- Updated dependencies [5d0740563] -- Updated dependencies [5cafcf452] -- Updated dependencies [86a95ba67] -- Updated dependencies [e27cb6c45] - - @backstage/catalog-model@0.7.7 - - @backstage/core@0.7.5 - -## 0.1.15 - -### Patch Changes - -- 322e01a95: Support SonarQube project keys containing special characters like colons. -- Updated dependencies [01ccef4c7] -- Updated dependencies [fcc3ada24] -- Updated dependencies [4618774ff] -- Updated dependencies [df59930b3] - - @backstage/plugin-catalog-react@0.1.3 - - @backstage/core@0.7.3 - - @backstage/theme@0.2.5 - -## 0.1.14 - -### Patch Changes - -- 410550388: Collect all available metric types if the number exceeds the default page size of 100. -- a4c575802: Display '-' instead of 'undefined' if no code coverage is reported. -- Updated dependencies [12d8f27a6] -- Updated dependencies [40c0fdbaa] -- Updated dependencies [2a271d89e] -- Updated dependencies [bece09057] -- Updated dependencies [169f48deb] -- Updated dependencies [8a1566719] -- Updated dependencies [9d455f69a] -- Updated dependencies [4c049a1a1] -- Updated dependencies [02816ecd7] - - @backstage/catalog-model@0.7.3 - - @backstage/core@0.7.0 - - @backstage/plugin-catalog-react@0.1.1 - -## 0.1.13 - -### Patch Changes - -- Updated dependencies [3a58084b6] -- Updated dependencies [e799e74d4] -- Updated dependencies [d0760ecdf] -- Updated dependencies [1407b34c6] -- Updated dependencies [88f1f1b60] -- Updated dependencies [bad21a085] -- Updated dependencies [9615e68fb] -- Updated dependencies [49f9b7346] -- Updated dependencies [5c2e2863f] -- Updated dependencies [3a58084b6] -- Updated dependencies [2c1f2a7c2] - - @backstage/core@0.6.3 - - @backstage/plugin-catalog-react@0.1.0 - - @backstage/catalog-model@0.7.2 - -## 0.1.12 - -### Patch Changes - -- 3a82293da: Fix bug retrieving current theme -- f4c2bcf54: Use a more strict type for `variant` of cards. -- Updated dependencies [fd3f2a8c0] -- Updated dependencies [d34d26125] -- Updated dependencies [0af242b6d] -- Updated dependencies [f4c2bcf54] -- Updated dependencies [10a0124e0] -- Updated dependencies [07e226872] -- Updated dependencies [f62e7abe5] -- Updated dependencies [96f378d10] -- Updated dependencies [688b73110] - - @backstage/core@0.6.2 - - @backstage/plugin-catalog-react@0.0.4 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies [19d354c78] -- Updated dependencies [b51ee6ece] - - @backstage/plugin-catalog-react@0.0.3 - - @backstage/core@0.6.1 - -## 0.1.10 - -### Patch Changes - -- 8dfdec613: Migrate to new composability API, exporting the plugin as `sonarQubePlugin` and card as `EntitySonarQubeCard`. -- Updated dependencies [12ece98cd] -- Updated dependencies [d82246867] -- Updated dependencies [7fc89bae2] -- Updated dependencies [c810082ae] -- Updated dependencies [5fa3bdb55] -- Updated dependencies [6e612ce25] -- Updated dependencies [025e122c3] -- Updated dependencies [21e624ba9] -- Updated dependencies [da9f53c60] -- Updated dependencies [32c95605f] -- Updated dependencies [7881f2117] -- Updated dependencies [54c7d02f7] -- Updated dependencies [11cb5ef94] - - @backstage/core@0.6.0 - - @backstage/plugin-catalog-react@0.0.2 - - @backstage/theme@0.2.3 - - @backstage/catalog-model@0.7.1 - -## 0.1.9 - -### Patch Changes - -- 49a67732f: Ask the SonarQube server for all support metrics prior to querying them for a project. - -## 0.1.8 - -### Patch Changes - -- 57f9d92cb: Add support for the security hotspots that are provided by SonarQube and SonarCloud. -- Updated dependencies [def2307f3] -- Updated dependencies [efd6ef753] -- Updated dependencies [a187b8ad0] -- Updated dependencies [a93f42213] - - @backstage/catalog-model@0.7.0 - - @backstage/core@0.5.0 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies [c911061b7] -- Updated dependencies [8ef71ed32] -- Updated dependencies [0e6298f7e] -- Updated dependencies [ac3560b42] - - @backstage/catalog-model@0.6.0 - - @backstage/core@0.4.1 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies [2527628e1] -- Updated dependencies [1c69d4716] -- Updated dependencies [83b6e0c1f] -- Updated dependencies [1665ae8bb] -- Updated dependencies [04f26f88d] -- Updated dependencies [ff243ce96] - - @backstage/core@0.4.0 - - @backstage/catalog-model@0.5.0 - - @backstage/theme@0.2.2 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies [08835a61d] -- Updated dependencies [a9fd599f7] -- Updated dependencies [bcc211a08] - - @backstage/catalog-model@0.4.0 - -## 0.1.4 - -### Patch Changes - -- 26484d413: Add configuration schema -- Updated dependencies [475fc0aaa] -- Updated dependencies [1166fcc36] -- Updated dependencies [1185919f3] - - @backstage/core@0.3.2 - - @backstage/catalog-model@0.3.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies [7b37d65fd] -- Updated dependencies [4aca74e08] -- Updated dependencies [e8f69ba93] -- Updated dependencies [0c0798f08] -- Updated dependencies [0c0798f08] -- Updated dependencies [199237d2f] -- Updated dependencies [6627b626f] -- Updated dependencies [4577e377b] - - @backstage/core@0.3.0 - - @backstage/theme@0.2.1 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies [819a70229] -- Updated dependencies [3a4236570] -- Updated dependencies [ae5983387] -- Updated dependencies [0d4459c08] -- Updated dependencies [482b6313d] -- Updated dependencies [e0be86b6f] -- Updated dependencies [f70a52868] -- Updated dependencies [12b5fe940] -- Updated dependencies [1c60f716e] -- Updated dependencies [144c66d50] -- Updated dependencies [a768a07fb] -- Updated dependencies [b79017fd3] -- Updated dependencies [6d97d2d6f] -- Updated dependencies [5adfc005e] -- Updated dependencies [93a3fa3ae] -- Updated dependencies [782f3b354] -- Updated dependencies [2713f28f4] -- Updated dependencies [406015b0d] -- Updated dependencies [82759d3e4] -- Updated dependencies [ac8d5d5c7] -- Updated dependencies [fa56f4615] -- Updated dependencies [ebca83d48] -- Updated dependencies [aca79334f] -- Updated dependencies [c0d5242a0] -- Updated dependencies [b3d57961c] -- Updated dependencies [3beb5c9fc] -- Updated dependencies [754e31db5] -- Updated dependencies [1611c6dbc] - - @backstage/core@0.2.0 - - @backstage/catalog-model@0.2.0 - - @backstage/theme@0.2.0 diff --git a/plugins/sonarqube/README.md b/plugins/sonarqube/README.md deleted file mode 100644 index 9d3bc701f9..0000000000 --- a/plugins/sonarqube/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# SonarQube Plugin - -The SonarQube Plugin displays code statistics from [SonarCloud](https://sonarcloud.io) or [SonarQube](https://sonarqube.com). - -![Sonar Card](./docs/sonar-card.png) - -## Getting Started - -1. Install the SonarQube Plugin: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-sonarqube -``` - -2. Add the `EntitySonarQubeCard` to the EntityPage: - -```diff - // packages/app/src/components/catalog/EntityPage.tsx -+ import { EntitySonarQubeCard } from '@backstage/plugin-sonarqube'; - - ... - - const overviewContent = ( - - - - -+ -+ -+ - - ); -``` - -3. Run the following commands in the root folder of the project to install and compile the changes. - -```yaml -yarn install -yarn tsc -``` - -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 -kind: Component -metadata: - name: backstage - description: | - Backstage is an open-source developer portal that puts the developer experience first. - annotations: - 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. - -## Links - -- [Sonarqube Backend](../sonarqube-backend/README.md) diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md deleted file mode 100644 index 32894b6eeb..0000000000 --- a/plugins/sonarqube/api-report.md +++ /dev/null @@ -1,75 +0,0 @@ -## API Report File for "@backstage/plugin-sonarqube" - -> 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 { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { FindingSummary } from '@backstage/plugin-sonarqube-react'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { InfoCardVariants } from '@backstage/core-components'; -import { JSX as JSX_2 } from 'react'; -import { default as React_2 } from 'react'; -import { SonarQubeApi } from '@backstage/plugin-sonarqube-react'; - -// @public (undocumented) -export type DuplicationRating = { - greaterThan: number; - rating: '1.0' | '2.0' | '3.0' | '4.0' | '5.0'; -}; - -// @public (undocumented) -export const EntitySonarQubeCard: (props: { - variant?: InfoCardVariants | undefined; - duplicationRatings?: DuplicationRating[] | undefined; -}) => JSX_2.Element; - -// @public (undocumented) -export const EntitySonarQubeContentPage: ( - props: SonarQubeContentPageProps, -) => JSX_2.Element; - -// @public @deprecated (undocumented) -export const isSonarQubeAvailable: (entity: Entity) => boolean; - -// @public @deprecated (undocumented) -export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; - -// @public (undocumented) -export const SonarQubeCard: (props: { - variant?: InfoCardVariants; - duplicationRatings?: DuplicationRating[]; -}) => React_2.JSX.Element; - -// @public (undocumented) -export class SonarQubeClient implements SonarQubeApi { - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }); - // (undocumented) - discoveryApi: DiscoveryApi; - // (undocumented) - getFindingSummary({ - componentKey, - projectInstance, - }?: { - componentKey?: string; - projectInstance?: string; - }): Promise; - // (undocumented) - identityApi: IdentityApi; -} - -// @public (undocumented) -export type SonarQubeContentPageProps = { - title?: string; - supportTitle?: string; -}; - -// @public (undocumented) -export const sonarQubePlugin: BackstagePlugin<{}, {}>; -``` diff --git a/plugins/sonarqube/catalog-info.yaml b/plugins/sonarqube/catalog-info.yaml deleted file mode 100644 index 19cc481e93..0000000000 --- a/plugins/sonarqube/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-sonarqube - title: '@backstage/plugin-sonarqube' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: sda-se-reviewers diff --git a/plugins/sonarqube/config.d.ts b/plugins/sonarqube/config.d.ts deleted file mode 100644 index 8ba989b02c..0000000000 --- a/plugins/sonarqube/config.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Optional configurations for the SonarQube plugin */ - sonarqube?: { - /** - * The base url of the sonarqube installation. Defaults to https://sonarcloud.io. - * @visibility frontend - */ - baseUrl?: string; - }; -} diff --git a/plugins/sonarqube/dev/index.tsx b/plugins/sonarqube/dev/index.tsx deleted file mode 100644 index 33a36bcaef..0000000000 --- a/plugins/sonarqube/dev/index.tsx +++ /dev/null @@ -1,158 +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 { Entity } from '@backstage/catalog-model'; -import { createDevApp, EntityGridItem } from '@backstage/dev-utils'; -import { Grid } from '@material-ui/core'; -import React from 'react'; -import { EntitySonarQubeCard, sonarQubePlugin } from '../src'; -import { Content, Header, Page } from '@backstage/core-components'; -import { - FindingSummary, - SonarQubeApi, - sonarQubeApiRef, -} from '@backstage/plugin-sonarqube-react'; -import { SONARQUBE_PROJECT_KEY_ANNOTATION } from '@backstage/plugin-sonarqube-react'; - -const entity = (name?: string) => - ({ - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - annotations: { - [SONARQUBE_PROJECT_KEY_ANNOTATION]: name, - }, - name: name, - }, - } as Entity); - -createDevApp() - .registerPlugin(sonarQubePlugin) - .addPage({ - title: 'Cards', - element: ( - -
- - - - - - - - - - - - - - - - - - - - - - - - ), - }) - .registerApi({ - api: sonarQubeApiRef, - deps: {}, - factory: () => - ({ - getFindingSummary: async ({ componentKey }) => { - switch (componentKey) { - case 'error': - throw new Error('Error!'); - - case 'never': - return new Promise(() => {}); - - case 'not-computed': - return { - lastAnalysis: new Date().toISOString(), - metrics: { - bugs: '0', - reliability_rating: '1.0', - vulnerabilities: '0', - security_rating: '1.0', - code_smells: '0', - sqale_rating: '1.0', - coverage: '0.0', - duplicated_lines_density: '0.0', - }, - projectUrl: `/#${componentKey}`, - getIssuesUrl: i => `/#${componentKey}/issues/${i}`, - getComponentMeasuresUrl: i => `/#${componentKey}/measures/${i}`, - getSecurityHotspotsUrl: () => - `#${componentKey}/security_hotspots`, - } as FindingSummary; - - case 'failed': - return { - lastAnalysis: new Date().toISOString(), - metrics: { - alert_status: 'FAILED', - bugs: '4', - reliability_rating: '2.0', - vulnerabilities: '18', - security_rating: '3.0', - security_review_rating: '3.0', - code_smells: '22', - sqale_rating: '5.0', - coverage: '15.7', - duplicated_lines_density: '15.6', - }, - projectUrl: `/#${componentKey}`, - getIssuesUrl: i => `/#${componentKey}/issues/${i}`, - getComponentMeasuresUrl: i => `/#${componentKey}/measures/${i}`, - getSecurityHotspotsUrl: () => - `#${componentKey}/security_hotspots`, - } as FindingSummary; - - case 'passed': - return { - lastAnalysis: new Date().toISOString(), - metrics: { - alert_status: 'OK', - bugs: '0', - reliability_rating: '1.0', - vulnerabilities: '0', - security_rating: '1.0', - security_hotspots_reviewed: '100.0', - security_review_rating: '1.0', - code_smells: '0', - sqale_rating: '1.0', - coverage: '100.0', - duplicated_lines_density: '0.0', - }, - projectUrl: `/#${componentKey}`, - getIssuesUrl: i => `/#${componentKey}/issues/${i}`, - getComponentMeasuresUrl: i => `/#${componentKey}/measures/${i}`, - getSecurityHotspotsUrl: () => - `#${componentKey}/security_hotspots`, - } as FindingSummary; - - default: - return undefined; - } - }, - } as SonarQubeApi), - }) - .render(); diff --git a/plugins/sonarqube/docs/sonar-card.png b/plugins/sonarqube/docs/sonar-card.png deleted file mode 100644 index 0104b96781..0000000000 Binary files a/plugins/sonarqube/docs/sonar-card.png and /dev/null differ diff --git a/plugins/sonarqube/knip-report.md b/plugins/sonarqube/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/sonarqube/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json deleted file mode 100644 index f5b4377342..0000000000 --- a/plugins/sonarqube/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "@backstage/plugin-sonarqube", - "description": "", - "version": "0.7.12-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/sonarqube" - }, - "keywords": [ - "backstage", - "sonarqube", - "sonarcloud" - ], - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@backstage/plugin-sonarqube-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@material-ui/styles": "^4.10.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "cross-fetch": "^4.0.0", - "luxon": "^3.0.0", - "rc-progress": "3.5.1", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "msw": "^1.0.0" - }, - "files": [ - "dist", - "alpha", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/sonarqube/src/api/SonarQubeClient.test.ts b/plugins/sonarqube/src/api/SonarQubeClient.test.ts deleted file mode 100644 index 592f08457f..0000000000 --- a/plugins/sonarqube/src/api/SonarQubeClient.test.ts +++ /dev/null @@ -1,284 +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 { setupRequestMockHandlers } from '@backstage/test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { SonarQubeClient } from './index'; -import { InstanceUrlWrapper, FindingsWrapper } from './types'; -import { UrlPatternDiscovery } from '@backstage/core-app-api'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { FindingSummary } from '@backstage/plugin-sonarqube-react'; - -const server = setupServer(); - -const identityApiAuthenticated: IdentityApi = { - signOut: jest.fn(), - getProfileInfo: jest.fn(), - getBackstageIdentity: jest.fn(), - getCredentials: jest.fn().mockResolvedValue({ token: 'fake-id-token' }), -}; -const identityApiGuest: IdentityApi = { - signOut: jest.fn(), - getProfileInfo: jest.fn(), - getBackstageIdentity: jest.fn(), - getCredentials: jest.fn().mockResolvedValue({ token: undefined }), -}; - -describe('SonarQubeClient', () => { - setupRequestMockHandlers(server); - - const mockBaseUrl = 'http://backstage:9191/api/sonarqube'; - const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - - const setupHandlers = () => { - server.use( - rest.get(`${mockBaseUrl}/findings`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe( - 'componentKey=our%3Aservice&instanceKey=', - ); - - return res( - ctx.json({ - analysisDate: '2020-01-01T00:00:00Z', - measures: [ - { - metric: 'alert_status', - value: 'OK', - }, - { - metric: 'bugs', - value: '2', - }, - { - metric: 'reliability_rating', - value: '3.0', - }, - { - metric: 'vulnerabilities', - value: '4', - }, - { - metric: 'security_rating', - value: '1.0', - }, - { - metric: 'security_hotspots_reviewed', - value: '100', - }, - { - metric: 'security_review_rating', - value: '1.0', - }, - { - metric: 'code_smells', - value: '100', - }, - { - metric: 'sqale_rating', - value: '2.0', - }, - { - metric: 'coverage', - value: '55.5', - }, - { - metric: 'duplicated_lines_density', - value: '1.0', - }, - ], - } 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), - ); - }), - ); - }; - - it('should report finding summary', async () => { - setupHandlers(); - - const client = new SonarQubeClient({ - discoveryApi, - identityApi: identityApiAuthenticated, - }); - - const summary = await client.getFindingSummary({ - componentKey: '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: 'https://sonarcloud.io/dashboard?id=our%3Aservice', - }), - ); - expect(summary?.getIssuesUrl('CODE_SMELL')).toEqual( - 'https://sonarcloud.io/project/issues?id=our%3Aservice&types=CODE_SMELL&resolved=false', - ); - expect(summary?.getComponentMeasuresUrl('COVERAGE')).toEqual( - 'https://sonarcloud.io/component_measures?id=our%3Aservice&metric=coverage&resolved=false&view=list', - ); - }); - - 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, - identityApi: identityApiAuthenticated, - }); - - const summary = await client.getFindingSummary({ - componentKey: 'our:service', - projectInstance: 'custom', - }); - - expect(summary).toEqual( - expect.objectContaining({ - lastAnalysis: '2020-01-03T00:00:00Z', - metrics: { - alert_status: 'ERROR', - bugs: '45', - reliability_rating: '5.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 add identity token for logged in users', async () => { - setupHandlers(); - server.use( - 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({ - analysisDate: '2020-01-01T00:00:00Z', - measures: [], - } as FindingsWrapper), - ); - }), - ); - - const client = new SonarQubeClient({ - discoveryApi, - identityApi: identityApiAuthenticated, - }); - const summary = await client.getFindingSummary({ - componentKey: 'our:service', - }); - - expect(summary?.lastAnalysis).toBe('2020-01-01T00:00:00Z'); - }); - - it('should omit identity token for guest users', async () => { - setupHandlers(); - server.use( - 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({ - analysisDate: '2020-01-01T00:00:00Z', - measures: [], - } as FindingsWrapper), - ); - }), - ); - - const client = new SonarQubeClient({ - discoveryApi, - identityApi: identityApiGuest, - }); - 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 deleted file mode 100644 index 09cfce06cb..0000000000 --- a/plugins/sonarqube/src/api/SonarQubeClient.ts +++ /dev/null @@ -1,135 +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 fetch from 'cross-fetch'; -import { - FindingSummary, - Metrics, - SonarQubeApi, -} from '@backstage/plugin-sonarqube-react'; -import { InstanceUrlWrapper, FindingsWrapper } from './types'; -import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; - -/** @public */ -export class SonarQubeClient implements SonarQubeApi { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }) { - this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; - } - - private async callApi( - path: string, - query: { [key in string]: any }, - ): Promise { - const { token: idToken } = await this.identityApi.getCredentials(); - - const apiUrl = `${await this.discoveryApi.getBaseUrl('sonarqube')}`; - const response = await fetch( - `${apiUrl}/${path}?${new URLSearchParams(query).toString()}`, - { - headers: { - 'Content-Type': 'application/json', - ...(idToken && { Authorization: `Bearer ${idToken}` }), - }, - }, - ); - if (response.status === 200) { - return (await response.json()) as T; - } - return undefined; - } - - async getFindingSummary({ - componentKey, - projectInstance, - }: { - componentKey?: string; - projectInstance?: string; - } = {}): Promise { - if (!componentKey) { - return undefined; - } - - const instanceKey = projectInstance || ''; - - const metrics: Metrics = { - alert_status: undefined, - bugs: undefined, - reliability_rating: undefined, - vulnerabilities: undefined, - security_rating: undefined, - security_hotspots_reviewed: undefined, - security_review_rating: undefined, - code_smells: undefined, - sqale_rating: undefined, - coverage: undefined, - duplicated_lines_density: undefined, - }; - - 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 findings = await this.callApi('findings', { - componentKey, - instanceKey, - }); - if (!findings) { - return undefined; - } - - findings.measures.forEach(m => { - metrics[m.metric] = m.value; - }); - - return { - lastAnalysis: findings.analysisDate, - metrics, - projectUrl: `${baseUrl}dashboard?id=${encodeURIComponent(componentKey)}`, - getIssuesUrl: identifier => - `${baseUrl}project/issues?id=${encodeURIComponent( - componentKey, - )}&types=${identifier.toLocaleUpperCase('en-US')}&resolved=false`, - getComponentMeasuresUrl: identifier => - `${baseUrl}component_measures?id=${encodeURIComponent( - componentKey, - )}&metric=${identifier.toLocaleLowerCase( - 'en-US', - )}&resolved=false&view=list`, - getSecurityHotspotsUrl: () => - `${baseUrl}${ - baseUrl === 'https://sonarcloud.io/' ? 'project/' : '' - }security_hotspots?id=${encodeURIComponent(componentKey)}`, - }; - } -} diff --git a/plugins/sonarqube/src/api/index.ts b/plugins/sonarqube/src/api/index.ts deleted file mode 100644 index ddf355af33..0000000000 --- a/plugins/sonarqube/src/api/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { SonarQubeClient } from './SonarQubeClient'; diff --git a/plugins/sonarqube/src/api/types.ts b/plugins/sonarqube/src/api/types.ts deleted file mode 100644 index 29b7e7ca54..0000000000 --- a/plugins/sonarqube/src/api/types.ts +++ /dev/null @@ -1,44 +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 { - MetricKey as NonDeprecatedMetricKey, - SonarUrlProcessorFunc as NonDeprecatedSonarUrlProcessorFunc, -} from '@backstage/plugin-sonarqube-react'; - -export interface InstanceUrlWrapper { - instanceUrl: string; -} - -export interface FindingsWrapper { - analysisDate: string; - measures: Measure[]; -} - -/** - * @deprecated use the same type from `@backstage/plugin-sonarqube-react` instead - */ -export type MetricKey = NonDeprecatedMetricKey; - -export interface Measure { - metric: MetricKey; - value: string; -} - -/** - * @deprecated use the same type from `@backstage/plugin-sonarqube-react` instead - */ -export type SonarUrlProcessorFunc = NonDeprecatedSonarUrlProcessorFunc; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/Percentage.tsx b/plugins/sonarqube/src/components/SonarQubeCard/Percentage.tsx deleted file mode 100644 index efc19d4bf5..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeCard/Percentage.tsx +++ /dev/null @@ -1,44 +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 { makeStyles } from '@material-ui/core/styles'; -import { useTheme } from '@material-ui/core'; -import { Circle } from 'rc-progress'; -import React from 'react'; - -const useStyles = makeStyles(theme => ({ - root: { - height: theme.spacing(3), - width: theme.spacing(3), - }, -})); - -export const Percentage = ({ value }: { value?: string }) => { - const classes = useStyles(); - const theme = useTheme(); - - return ( - - ); -}; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/Rating.tsx b/plugins/sonarqube/src/components/SonarQubeCard/Rating.tsx deleted file mode 100644 index fb722fd857..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeCard/Rating.tsx +++ /dev/null @@ -1,111 +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 { Avatar } from '@material-ui/core'; -import { lighten, makeStyles } from '@material-ui/core/styles'; -import { CSSProperties } from '@material-ui/styles'; -import React, { useMemo } from 'react'; - -const useStyles = makeStyles(theme => { - const commonCardRating: CSSProperties = { - height: theme.spacing(3), - width: theme.spacing(3), - color: theme.palette.common.white, - }; - - return { - ratingDefault: { - ...commonCardRating, - background: theme.palette.status.aborted, - }, - ratingA: { - ...commonCardRating, - background: theme.palette.status.ok, - }, - ratingB: { - ...commonCardRating, - background: lighten(theme.palette.status.ok, 0.5), - }, - ratingC: { - ...commonCardRating, - background: theme.palette.status.pending, - }, - ratingD: { - ...commonCardRating, - background: theme.palette.status.warning, - }, - ratingE: { - ...commonCardRating, - background: theme.palette.error.main, - }, - }; -}); - -export const Rating = ({ - rating, - hideValue, -}: { - rating?: string; - hideValue?: boolean; -}) => { - const classes = useStyles(); - - const ratingProp = useMemo(() => { - switch (rating) { - case '1.0': - return { - name: 'A', - className: classes.ratingA, - }; - - case '2.0': - return { - name: 'B', - className: classes.ratingB, - }; - - case '3.0': - return { - name: 'C', - className: classes.ratingC, - }; - - case '4.0': - return { - name: 'D', - className: classes.ratingD, - }; - - case '5.0': - return { - name: 'E', - className: classes.ratingE, - }; - - default: - return { - name: '', - className: classes.ratingDefault, - }; - } - }, [classes, rating]); - - return ( - - {!hideValue && ratingProp.name} - - ); -}; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/RatingCard.tsx b/plugins/sonarqube/src/components/SonarQubeCard/RatingCard.tsx deleted file mode 100644 index 547c3008c0..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeCard/RatingCard.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Link } from '@backstage/core-components'; -import { Grid, Typography } from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; -import React, { ReactNode } from 'react'; - -const useStyles = makeStyles(theme => { - return { - root: { - margin: theme.spacing(1, 0), - minWidth: '140px', - }, - upper: { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - }, - cardTitle: { - textAlign: 'center', - }, - wrapIcon: { - display: 'inline-flex', - verticalAlign: 'baseline', - }, - left: { - display: 'flex', - }, - right: { - display: 'flex', - marginLeft: theme.spacing(0.5), - }, - }; -}); - -export const RatingCard = ({ - leftSlot, - rightSlot, - title, - titleIcon, - link, -}: { - leftSlot: ReactNode; - rightSlot: ReactNode; - title: string; - titleIcon?: ReactNode; - link: string; -}) => { - const classes = useStyles(); - - return ( - - - - - {leftSlot} - - - {rightSlot} - - - - - {titleIcon} {title} - - - - - ); -}; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx b/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx deleted file mode 100644 index 9a6e9fb8ed..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx +++ /dev/null @@ -1,281 +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 { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import { - sonarQubeApiRef, - useProjectInfo, -} from '@backstage/plugin-sonarqube-react'; -import { SONARQUBE_PROJECT_KEY_ANNOTATION } from '@backstage/plugin-sonarqube-react'; -import { Chip, Grid } from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; -import BugReport from '@material-ui/icons/BugReport'; -import Lock from '@material-ui/icons/Lock'; -import LockOpen from '@material-ui/icons/LockOpen'; -import Security from '@material-ui/icons/Security'; -import SentimentVeryDissatisfied from '@material-ui/icons/SentimentVeryDissatisfied'; -import SentimentVerySatisfied from '@material-ui/icons/SentimentVerySatisfied'; -import React, { useMemo } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { Percentage } from './Percentage'; -import { Rating } from './Rating'; -import { RatingCard } from './RatingCard'; -import { Value } from './Value'; -import { - EmptyState, - InfoCard, - InfoCardVariants, - Progress, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { DateTime } from 'luxon'; - -const useStyles = makeStyles(theme => ({ - badgeLabel: { - color: theme.palette.common.white, - }, - badgeError: { - margin: 0, - backgroundColor: theme.palette.error.main, - }, - badgeSuccess: { - margin: 0, - backgroundColor: theme.palette.success.main, - }, - badgeUnknown: { - backgroundColor: theme.palette.grey[500], - }, - header: { - padding: theme.spacing(2, 2, 2, 2.5), - }, - action: { - margin: 0, - }, - lastAnalyzed: { - color: theme.palette.text.secondary, - }, -})); - -/** @public */ -export type DuplicationRating = { - greaterThan: number; - rating: '1.0' | '2.0' | '3.0' | '4.0' | '5.0'; -}; - -const defaultDuplicationRatings: DuplicationRating[] = [ - { greaterThan: 0, rating: '1.0' }, - { greaterThan: 3, rating: '2.0' }, - { greaterThan: 5, rating: '3.0' }, - { greaterThan: 10, rating: '4.0' }, - { greaterThan: 20, rating: '5.0' }, -]; - -/** @public */ -export const SonarQubeCard = (props: { - variant?: InfoCardVariants; - duplicationRatings?: DuplicationRating[]; -}) => { - const { - variant = 'gridItem', - duplicationRatings = defaultDuplicationRatings, - } = props; - const { entity } = useEntity(); - const sonarQubeApi = useApi(sonarQubeApiRef); - - const { projectKey: projectTitle, projectInstance } = useProjectInfo(entity); - - const { value, loading } = useAsync( - async () => - sonarQubeApi.getFindingSummary({ - componentKey: projectTitle, - projectInstance: projectInstance, - }), - [sonarQubeApi, projectTitle], - ); - - const deepLink = - !loading && value - ? { - title: 'View more', - link: value.projectUrl, - } - : undefined; - - const classes = useStyles(); - let gateLabel = 'Not computed'; - let gateColor = classes.badgeUnknown; - - if (value?.metrics.alert_status) { - const gatePassed = value.metrics.alert_status === 'OK'; - gateLabel = gatePassed ? 'Gate passed' : 'Gate failed'; - gateColor = gatePassed ? classes.badgeSuccess : classes.badgeError; - } - - const qualityBadge = !loading && value && ( - - ); - - const duplicationRating = useMemo(() => { - if (loading || !value || !value.metrics.duplicated_lines_density) { - return ''; - } - - let rating = ''; - - for (const r of duplicationRatings) { - if (+value.metrics.duplicated_lines_density >= r.greaterThan) { - rating = r.rating; - } - } - - return rating; - }, [loading, value, duplicationRatings]); - - return ( - - {loading && } - - {!loading && !projectTitle && ( - - )} - - {!loading && projectTitle && !value && ( - - )} - - {!loading && value && ( - <> - - - } - title="Bugs" - link={value.getIssuesUrl('BUG')} - leftSlot={} - rightSlot={} - /> - - ) : ( - - ) - } - title="Vulnerabilities" - link={value.getIssuesUrl('VULNERABILITY')} - leftSlot={} - rightSlot={} - /> - - ) : ( - - ) - } - title="Code Smells" - link={value.getIssuesUrl('CODE_SMELL')} - leftSlot={} - rightSlot={} - /> - {value.metrics.security_review_rating && ( - } - title="Hotspots Reviewed" - link={value.getSecurityHotspotsUrl()} - leftSlot={ - - } - rightSlot={ - - } - /> - )} -
- } - rightSlot={ - - } - /> - } - rightSlot={ - - } - /> - - - Last analyzed on{' '} - {DateTime.fromISO(value.lastAnalysis).toLocaleString( - DateTime.DATETIME_MED, - )} - - - - )} - - ); -}; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx b/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx deleted file mode 100644 index af1b5059ba..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx +++ /dev/null @@ -1,37 +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 { makeStyles } from '@material-ui/core/styles'; -import Typography from '@material-ui/core/Typography'; -import React from 'react'; - -const useStyles = makeStyles(theme => { - return { - value: { - fontSize: '1.5rem', - fontWeight: theme.typography.fontWeightMedium, - }, - }; -}); - -export const Value = (props: { value?: string }) => { - const classes = useStyles(); - return ( - - {props.value} - - ); -}; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/index.ts b/plugins/sonarqube/src/components/SonarQubeCard/index.ts deleted file mode 100644 index 307a9abc41..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeCard/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export type { DuplicationRating } from './SonarQubeCard'; -export { SonarQubeCard } from './SonarQubeCard'; diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx deleted file mode 100644 index 0bf5f04640..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx +++ /dev/null @@ -1,90 +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 { EntityProvider } from '@backstage/plugin-catalog-react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import React from 'react'; -import { - SonarQubeApi, - sonarQubeApiRef, - isSonarQubeAvailable, - SONARQUBE_PROJECT_KEY_ANNOTATION, -} from '@backstage/plugin-sonarqube-react'; - -const Providers = ({ - annotation, - children, -}: { annotation: string } & React.PropsWithChildren): JSX.Element => ( - - - {children} - - -); - -describe('', () => { - beforeAll(() => { - jest.mock('@backstage/plugin-sonarqube', () => ({ - __esModule: true, - isSonarQubeAvailable, - EntitySonarQubeCard: () => { - return
; - }, - })); - }); - - it('renders EntitySonarQubeCard', async () => { - const { SonarQubeContentPage } = require('./SonarQubeContentPage'); - - const rendered = await renderInTestApp( - - - , - ); - expect(rendered.getByText('SonarQube Dashboard')).toBeInTheDocument(); - expect(rendered.getByText('No information to display')).toBeInTheDocument(); - expect( - rendered.getByText("There is no SonarQube project with key 'bar'."), - ).toBeInTheDocument(); - }, 15000); - - it('renders MissingAnnotationEmptyState if sonar annotation is missing', async () => { - const { SonarQubeContentPage } = require('./SonarQubeContentPage'); - - const rendered = await renderInTestApp( - - - , - ); - expect(rendered.getByText('Missing Annotation')).toBeInTheDocument(); - expect( - rendered.getAllByText(SONARQUBE_PROJECT_KEY_ANNOTATION, { exact: false }) - .length, - ).toBe(2); - }, 15000); -}); diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx deleted file mode 100644 index 877a52843c..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.tsx +++ /dev/null @@ -1,55 +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 { - Content, - ContentHeader, - SupportButton, -} from '@backstage/core-components'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import React from 'react'; -import { SonarQubeCard } from '../SonarQubeCard'; -import { - isSonarQubeAvailable, - SONARQUBE_PROJECT_KEY_ANNOTATION, -} from '@backstage/plugin-sonarqube-react'; - -/** @public */ -export type SonarQubeContentPageProps = { - title?: string; - supportTitle?: string; -}; - -export const SonarQubeContentPage = (props: SonarQubeContentPageProps) => { - const { entity } = useEntity(); - const { title, supportTitle } = props; - - return isSonarQubeAvailable(entity) ? ( - - - {supportTitle && {supportTitle}} - - - - ) : ( - - ); -}; diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts b/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts deleted file mode 100644 index 59327e9a88..0000000000 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { SonarQubeContentPage } from './SonarQubeContentPage'; -export type { SonarQubeContentPageProps } from './SonarQubeContentPage'; diff --git a/plugins/sonarqube/src/components/index.ts b/plugins/sonarqube/src/components/index.ts deleted file mode 100644 index 252c12c5db..0000000000 --- a/plugins/sonarqube/src/components/index.ts +++ /dev/null @@ -1,39 +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 { - isSonarQubeAvailable as NonDeprecatedIsSonarQubeAvailable, - SONARQUBE_PROJECT_KEY_ANNOTATION as NON_DEPRECATED_SONARQUBE_PROJECT_KEY_ANNOTATION, -} from '@backstage/plugin-sonarqube-react'; - -export { SonarQubeCard } from './SonarQubeCard'; -export type { DuplicationRating } from './SonarQubeCard'; -export type { SonarQubeContentPageProps } from './SonarQubeContentPage'; - -/** - * @public - * - * @deprecated use the same type from `@backstage/plugin-sonarqube-react` instead - */ -export const isSonarQubeAvailable = NonDeprecatedIsSonarQubeAvailable; - -/** - * @public - * - * @deprecated use the same type from `@backstage/plugin-sonarqube-react` instead - */ -export const SONARQUBE_PROJECT_KEY_ANNOTATION = - NON_DEPRECATED_SONARQUBE_PROJECT_KEY_ANNOTATION; diff --git a/plugins/sonarqube/src/index.ts b/plugins/sonarqube/src/index.ts deleted file mode 100644 index 93648caeb5..0000000000 --- a/plugins/sonarqube/src/index.ts +++ /dev/null @@ -1,26 +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. - */ - -/** - * A Backstage plugin to display {@link https://www.sonarqube.org | SonarQube} - * code quality and security results. - * - * @packageDocumentation - */ - -export * from './api'; -export * from './components'; -export * from './plugin'; diff --git a/plugins/sonarqube/src/plugin.test.ts b/plugins/sonarqube/src/plugin.test.ts deleted file mode 100644 index 18844d1c45..0000000000 --- a/plugins/sonarqube/src/plugin.test.ts +++ /dev/null @@ -1,23 +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 { sonarQubePlugin } from './plugin'; - -describe('sonarqube', () => { - it('should export plugin', () => { - expect(sonarQubePlugin).toBeDefined(); - }); -}); diff --git a/plugins/sonarqube/src/plugin.ts b/plugins/sonarqube/src/plugin.ts deleted file mode 100644 index c66d8c4e96..0000000000 --- a/plugins/sonarqube/src/plugin.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { SonarQubeClient } from './api'; -import { - createApiFactory, - createComponentExtension, - createPlugin, - discoveryApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; -import { sonarQubeApiRef } from '@backstage/plugin-sonarqube-react'; - -/** @public */ -export const sonarQubePlugin = createPlugin({ - id: 'sonarqube', - apis: [ - createApiFactory({ - api: sonarQubeApiRef, - deps: { - discoveryApi: discoveryApiRef, - identityApi: identityApiRef, - }, - factory: ({ discoveryApi, identityApi }) => - new SonarQubeClient({ - discoveryApi, - identityApi, - }), - }), - ], -}); - -/** @public */ -export const EntitySonarQubeCard = sonarQubePlugin.provide( - createComponentExtension({ - name: 'EntitySonarQubeCard', - component: { - lazy: () => - import('./components/SonarQubeCard').then(m => m.SonarQubeCard), - }, - }), -); - -/** @public */ -export const EntitySonarQubeContentPage = sonarQubePlugin.provide( - createComponentExtension({ - name: 'EntitySonarQubeContentPage', - component: { - lazy: () => - import('./components/SonarQubeContentPage').then( - m => m.SonarQubeContentPage, - ), - }, - }), -); diff --git a/plugins/sonarqube/src/setupTests.ts b/plugins/sonarqube/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/sonarqube/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/splunk-on-call/.eslintrc.js b/plugins/splunk-on-call/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/splunk-on-call/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md deleted file mode 100644 index afbb2df038..0000000000 --- a/plugins/splunk-on-call/CHANGELOG.md +++ /dev/null @@ -1,1493 +0,0 @@ -# @backstage/plugin-splunk-on-call - -## 0.4.19-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - -## 0.4.19-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - -## 0.4.19-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - -## 0.4.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - -## 0.4.18 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - -## 0.4.18-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.4.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - -## 0.4.18-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - -## 0.4.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - -## 0.4.17-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.4.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.4.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.5.0-next.0 - -## 0.4.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.4.15 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - -## 0.4.15-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.4.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.4.15-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - -## 0.4.14 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/theme@0.4.3 - -## 0.4.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/theme@0.4.3-next.0 - -## 0.4.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.4.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/theme@0.4.2 - -## 0.4.13 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.4.13-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.4.13-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/theme@0.4.1 - -## 0.4.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.4.12-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.4.10 - -### Patch Changes - -- 3d86be999fdf: Prefer simple `theme.spacing` without string interpolation -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.4.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.4.10-next.0 - -### Patch Changes - -- 3d86be999fdf: Prefer simple `theme.spacing` without string interpolation -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/theme@0.4.1 - -## 0.4.9 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.4.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - -## 0.4.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.4.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.4.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - -## 0.4.8-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.4.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.4.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.4.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.4.7 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.4.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.4.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.4.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/theme@0.2.19 - -## 0.4.6 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - -## 0.4.6-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.4.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.19-next.0 - -## 0.4.6-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - -## 0.4.6-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.4.5 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.4.5-next.2 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.4.5-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.4.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - -## 0.4.4 - -### Patch Changes - -- 3598136ac7: Refactor plugin Card component to not rerender contents unnecessarily. -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - -## 0.4.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.4.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.4.4-next.0 - -### Patch Changes - -- 3598136ac7: Refactor plugin Card component to not rerender contents unnecessarily. -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.4.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.4.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - -## 0.4.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.4.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - -## 0.4.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.4.1 - -### Patch Changes - -- cb716004ef: Internal refactor to improve tests -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.4.1-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.4.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.4.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.4.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.4.1-next.0 - -### Patch Changes - -- cb716004ef: Internal refactor to improve tests -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.4.0 - -### Minor Changes - -- 34b772ef31: Use the routing key if it's available instead of team name when triggering incidents. - - BREAKING CHANGE: - Before, the team name was used even if the routing key (with or without team) was used. - Now, the routing key defined for the component will be used instead of the team name. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/theme@0.2.16 - -## 0.4.0-next.1 - -### Minor Changes - -- 34b772ef31: Use the routing key if it's available instead of team name when triggering incidents. - - BREAKING CHANGE: - Before, the team name was used even if the routing key (with or without team) was used. - Now, the routing key defined for the component will be used instead of the team name. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.3.35-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.3.34 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - -## 0.3.34-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - -## 0.3.34-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.3.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - -## 0.3.33 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - -## 0.3.33-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.3.33-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.3.33-next.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.3.33-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.3.31-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.3.31-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.3.31-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.3.30 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.3.30-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.3.30-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.3.29 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.3.29-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.3.29-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.3.29-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.3.28 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.3.28-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.3.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.3.27 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - -## 0.3.26 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.3.26-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.3.25 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.3.24 - -### Patch Changes - -- 02faa6781b: The Splunk On-Call plugin now supports an optional `readOnly` property (``) for suppressing the rendering of incident trigger-acknowledge-resolve controls from the Backstage UI. -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.3.23 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - -## 0.3.22 - -### Patch Changes - -- c17be55ffb: Add Splunk On-Call plugin support for a `splunk.com/on-call-routing-key` annotation. If the `splunk.com/on-call-routing-key` is provided, the plugin displays a Splunk On-Call card for each of the teams associated with the routing key. -- 6c6d1c6439: Correct spelling of 'Acknowledge' in tooltip. -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.3.22-next.0 - -### Patch Changes - -- 6c6d1c6439: Correct spelling of 'Acknowledge' in tooltip. -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.3.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.3.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.3.20 - -### Patch Changes - -- 013301e07b: Remove redundant `node-fetch` dependency -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.3.20-next.0 - -### Patch Changes - -- 013301e07b: Remove redundant `node-fetch` dependency -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.3.19 - -### Patch Changes - -- 7612e2856b: Clean up emptystate.svg image, removing wrong white artifact from the background -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/catalog-model@0.9.9 - -## 0.3.18 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.3.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.3.16 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.3.15 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/catalog-model@0.9.7 - - @backstage/plugin-catalog-react@0.6.4 - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.3.14 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.0 - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.3.13 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - - @backstage/plugin-catalog-react@0.5.2 - - @backstage/catalog-model@0.9.4 - -## 0.3.12 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - - @backstage/plugin-catalog-react@0.5.1 - -## 0.3.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/plugin-catalog-react@0.5.0 - - @backstage/catalog-model@0.9.3 - -## 0.3.10 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/plugin-catalog-react@0.4.6 - - @backstage/core-plugin-api@0.1.8 - -## 0.3.9 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.5 - - @backstage/core-components@0.4.0 - - @backstage/catalog-model@0.9.1 - -## 0.3.8 - -### Patch Changes - -- 8bedb75ae: Update Luxon dependency to 2.x -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - - @backstage/plugin-catalog-react@0.4.2 - -## 0.3.7 - -### Patch Changes - -- 260c053b9: Fix All Material UI Warnings -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - - @backstage/plugin-catalog-react@0.4.1 - -## 0.3.6 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/plugin-catalog-react@0.4.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.3.5 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.3.0 - -## 0.3.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.1.5 - - @backstage/catalog-model@0.9.0 - - @backstage/plugin-catalog-react@0.2.6 - -## 0.3.3 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - - @backstage/catalog-model@0.8.4 - - @backstage/plugin-catalog-react@0.2.4 - -## 0.3.2 - -### Patch Changes - -- ae903f8e7: Added config schema to expose `splunkOnCall.eventsRestEndpoint` config option to the frontend -- Updated dependencies - - @backstage/plugin-catalog-react@0.2.3 - - @backstage/catalog-model@0.8.3 - - @backstage/core@0.7.13 - -## 0.3.1 - -### Patch Changes - -- dc3558e84: Update Splunk On Call plugin to render warning message about incorrectly configured team annotation -- Updated dependencies [add62a455] -- Updated dependencies [cc592248b] -- Updated dependencies [17c497b81] -- Updated dependencies [704875e26] - - @backstage/catalog-model@0.8.0 - - @backstage/core@0.7.11 - - @backstage/plugin-catalog-react@0.2.0 - -## 0.3.0 - -### Minor Changes - -- 8aa0b6025: Updates the Splunk On-Call plugin for the [composability system - migration](https://backstage.io/docs/plugins/composability#porting-existing-plugins). - - To upgrade, modify your `EntityPage` to use the updated export names. The - `EntitySplunkOnCallCard` should be wrapped in an `` condition as - shown in the plugin README, which you may already have in place. - - ```diff - import { - - isPluginApplicableToEntity as isSplunkOnCallAvailable, - + isSplunkOnCallAvailable, - - SplunkOnCallCard - + EntitySplunkOnCallCard, - } from '@backstage/plugin-splunk-on-call'; - - ... - - - + - ``` - -### Patch Changes - -- Updated dependencies [f7f7783a3] -- Updated dependencies [65e6c4541] -- Updated dependencies [68fdbf014] -- Updated dependencies [5da6a561d] - - @backstage/catalog-model@0.7.10 - - @backstage/core@0.7.10 - -## 0.2.1 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [10c008a3a] -- Updated dependencies [889d89b6e] -- Updated dependencies [16be1d093] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - - @backstage/plugin-catalog-react@0.1.6 - - @backstage/catalog-model@0.7.9 - -## 0.2.0 - -### Minor Changes - -- a310f33d8: Updated splunk-on-call plugin to use the REST endpoint (incident creation-acknowledgement-resolution). - It implies switching from `splunkOnCall.username` configuration to `splunkOnCall.eventsRestEndpoint` configuration, this is a breaking change. - -### Patch Changes - -- Updated dependencies [0b42fff22] -- Updated dependencies [ff4d666ab] -- Updated dependencies [2089de76b] -- Updated dependencies [dc1fc92c8] - - @backstage/catalog-model@0.7.4 - - @backstage/core@0.7.1 - - @backstage/theme@0.2.4 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies [12d8f27a6] -- Updated dependencies [40c0fdbaa] -- Updated dependencies [2a271d89e] -- Updated dependencies [bece09057] -- Updated dependencies [169f48deb] -- Updated dependencies [8a1566719] -- Updated dependencies [9d455f69a] -- Updated dependencies [4c049a1a1] -- Updated dependencies [02816ecd7] - - @backstage/catalog-model@0.7.3 - - @backstage/core@0.7.0 - - @backstage/plugin-catalog-react@0.1.1 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies [3a58084b6] -- Updated dependencies [e799e74d4] -- Updated dependencies [d0760ecdf] -- Updated dependencies [1407b34c6] -- Updated dependencies [88f1f1b60] -- Updated dependencies [bad21a085] -- Updated dependencies [9615e68fb] -- Updated dependencies [49f9b7346] -- Updated dependencies [5c2e2863f] -- Updated dependencies [3a58084b6] -- Updated dependencies [2c1f2a7c2] - - @backstage/core@0.6.3 - - @backstage/plugin-catalog-react@0.1.0 - - @backstage/catalog-model@0.7.2 - -## 0.1.2 - -### Patch Changes - -- 70e2ba9cf: Added splunk-on-call plugin. -- Updated dependencies [fd3f2a8c0] -- Updated dependencies [d34d26125] -- Updated dependencies [0af242b6d] -- Updated dependencies [f4c2bcf54] -- Updated dependencies [10a0124e0] -- Updated dependencies [07e226872] -- Updated dependencies [f62e7abe5] -- Updated dependencies [96f378d10] -- Updated dependencies [688b73110] - - @backstage/core@0.6.2 - - @backstage/plugin-catalog-react@0.0.4 diff --git a/plugins/splunk-on-call/README.md b/plugins/splunk-on-call/README.md deleted file mode 100644 index ceeec2fa4c..0000000000 --- a/plugins/splunk-on-call/README.md +++ /dev/null @@ -1,155 +0,0 @@ -# Splunk On-Call - -## Overview - -This plugin displays Splunk On-Call (formerly VictorOps) information associated with an entity. - -It also provides the ability to trigger new incidents to specific users and/or specific teams from within Backstage. - -This plugin requires that entities feature either a `splunk.com/on-call-team` or a `splunk.com/on-call-routing-key` annotation. See below for further details. - -This plugin provides: - -- A list of incidents -- A way to trigger a new incident to specific users and/or teams -- A way to acknowledge/resolve an incident -- Information details about the persons on-call - -## Setup instructions - -Install the plugin: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-splunk-on-call -``` - -Add it to your `EntityPage`: - -```ts -// packages/app/src/components/catalog/EntityPage.tsx -import { - isSplunkOnCallAvailable, - EntitySplunkOnCallCard, -} from '@backstage/plugin-splunk-on-call'; -// ... -const overviewContent = ( - - - - - - - - -``` - -### `readOnly` mode - -To suppress the rendering of the actionable create-acknowledge-resolve incident buttons and UI controls, the `EntitySplunkOnCallCard` can also be instantiated in `readOnly` mode: - -```ts - -``` - -## Client configuration - -In order to be able to perform certain actions (create-acknowledge-resolve an action), you need to provide a REST Endpoint. - -To enable the REST Endpoint integration you can go on https://portal.victorops.com/ inside Integrations > 3rd Party Integrations > REST – Generic. -You can now copy the URL to notify: `/$routing_key` - -In `app-config.yaml`: - -```yaml -splunkOnCall: - eventsRestEndpoint: -``` - -In order to make the API calls, you need to provide a new proxy config which will redirect to the Splunk On-Call API endpoint and add authentication information in the headers: - -```yaml -# app-config.yaml -proxy: - # ... - '/splunk-on-call': - target: https://api.victorops.com/api-public - headers: - X-VO-Api-Id: ${SPLUNK_ON_CALL_API_ID} - X-VO-Api-Key: ${SPLUNK_ON_CALL_API_KEY} -``` - -In addition, to make certain API calls (trigger-resolve-acknowledge an incident) you need to add the `PATCH` method to the backend `cors` methods list: `[GET, POST, PUT, DELETE, PATCH]`. - -**WARNING**: In current implementation, the Splunk OnCall plugin requires the `/splunk-on-call` proxy endpoint be exposed by the Backstage backend as an unprotected endpoint, in effect enabling Splunk OnCall API access using the configured `SPLUNK_ON_CALL_API_KEY` for any user or process with access to the `/splunk-on-call` Backstage backend endpoint. See below for further configuration options enabling protection of this endpoint. If you regard this as problematic, consider using the plugin in `readOnly` mode (``) using the following proxy configuration: - -```yaml -proxy: - '/splunk-on-call': - target: https://api.victorops.com/api-public - headers: - X-VO-Api-Id: ${SPLUNK_ON_CALL_API_ID} - X-VO-Api-Key: ${SPLUNK_ON_CALL_API_KEY} - # prohibit the `/splunk-on-call` proxy endpoint from servicing non-GET requests - allowedMethods: ['GET'] -``` - -### Adding your team name to the entity annotation - -The information displayed for each entity is based on either an associated team name or an associated routing key. - -To use this plugin for an entity, the entity must be labeled with either a `splunk.com/on-call-team` or a `splunk.com/on-call-routing-key` annotation. - -For example, by specifying a `splunk.com/on-call-team`, the plugin displays Splunk On-Call data associated with the specified team: - -```yaml -annotations: - splunk.com/on-call-team: -``` - -Alternatively, by specifying a `splunk.com/on-call-routing-key`, the plugin displays Splunk On-Call data associated with _each_ of the teams associated with the specified routing key: - -```yaml -annotations: - splunk.com/on-call-routing-key: -``` - -### Create the Routing Key - -To be able to use the REST Endpoint seen above, you must have created a routing key with the **same name** as the provided team. - -You can create a new routing key on https://portal.victorops.com/ by going to Settings > Routing Keys. - -You can read [Create & Manage Alert Routing Keys](https://help.victorops.com/knowledge-base/routing-keys/#routing-key-tips-tricks) for further information. - -## Providing the API key and API id - -In order for the client to make requests to the [Splunk On-Call API](https://portal.victorops.com/public/api-docs.html#/) it needs an [API ID and an API Key](https://help.victorops.com/knowledge-base/api/). - -Then start the backend passing the values as an environment variable: - -```bash -$ SPLUNK_ON_CALL_API_KEY='' SPLUNK_ON_CALL_API_ID='' yarn start -``` - -This will proxy the request by adding `X-VO-Api-Id` and `X-VO-Api-Key` headers with the provided values. - -You can also add the values in your helm template: - -```yaml -# backend-secret.yaml -stringData: - # ... - SPLUNK_ON_CALL_API_ID: { { .Values.auth.splunkOnCallApiId } } - SPLUNK_ON_CALL_API_KEY: { { .Values.auth.splunkOnCallApiKey } } -``` - -To enable it you need to provide them in the chart's values: - -```yaml -# values.yaml -auth: - # ... - splunkOnCallApiId: h - splunkOnCallApiKey: h -``` diff --git a/plugins/splunk-on-call/api-report.md b/plugins/splunk-on-call/api-report.md deleted file mode 100644 index d80ee6f874..0000000000 --- a/plugins/splunk-on-call/api-report.md +++ /dev/null @@ -1,286 +0,0 @@ -## API Report File for "@backstage/plugin-splunk-on-call" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { ConfigApi } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export type ClientApiConfig = { - eventsRestEndpoint: string | null; - discoveryApi: DiscoveryApi; -}; - -// @public (undocumented) -export const EntitySplunkOnCallCard: ( - props: EntitySplunkOnCallCardProps, -) => JSX_2.Element; - -// @public (undocumented) -export type EntitySplunkOnCallCardProps = { - readOnly?: boolean; -}; - -// @public (undocumented) -export type EscalationPolicyInfo = { - policy: EscalationPolicySummary; - team?: EscalationPolicyTeam; -}; - -// @public (undocumented) -export type EscalationPolicyResponse = { - policies: EscalationPolicyInfo[]; -}; - -// @public (undocumented) -export type EscalationPolicySummary = { - name: string; - slug: string; - _selfUrl: string; -}; - -// @public (undocumented) -export type EscalationPolicyTeam = { - name: string; - slug: string; -}; - -// @public (undocumented) -export type Incident = { - incidentNumber?: string; - startTime?: string; - currentPhase: IncidentPhase; - entityState?: string; - entityType?: string; - routingKey?: string; - alertCount?: number; - lastAlertTime?: string; - lastAlertId?: string; - entityId: string; - host?: string; - service?: string; - pagedUsers?: string[]; - pagedTeams?: string[]; - entityDisplayName?: string; - pagedPolicies?: EscalationPolicyInfo[]; - transitions?: IncidentTransition[]; - firstAlertUuid?: string; - monitorName?: string; - monitorType?: string; - incidentLink?: string; -}; - -// @public (undocumented) -export type IncidentPhase = 'UNACKED' | 'ACKED' | 'RESOLVED'; - -// @public (undocumented) -export type IncidentsResponse = { - incidents: Incident[]; -}; - -// @public (undocumented) -export type IncidentTransition = { - name?: string; - at?: string; - by?: string; - message?: string; - manually?: boolean; - alertId?: string; - alertUrl?: string; -}; - -// @public (undocumented) -export const isSplunkOnCallAvailable: (entity: Entity) => boolean; - -// @public (undocumented) -export type ListRoutingKeyResponse = { - routingKeys: RoutingKey[]; - _selfUrl?: string; -}; - -// @public (undocumented) -export type ListUserResponse = { - users: User[]; - _selfUrl?: string; -}; - -// @public (undocumented) -export type MessageType = - | 'CRITICAL' - | 'WARNING' - | 'ACKNOWLEDGEMENT' - | 'INFO' - | 'RECOVERY'; - -// @public (undocumented) -export type OnCall = { - team?: OnCallTeamResource; - oncallNow?: OnCallNowResource[]; -}; - -// @public (undocumented) -export type OnCallEscalationPolicyResource = { - name?: string; - slug?: string; -}; - -// @public (undocumented) -export type OnCallNowResource = { - escalationPolicy?: OnCallEscalationPolicyResource; - users?: OnCallUsersResource[]; -}; - -// @public (undocumented) -export type OnCallsResponse = { - teamsOnCall: OnCall[]; -}; - -// @public (undocumented) -export type OnCallTeamResource = { - name?: string; - slug?: string; -}; - -// @public (undocumented) -export type OnCallUser = { - username?: string; -}; - -// @public (undocumented) -export type OnCallUsersResource = { - onCalluser?: OnCallUser; -}; - -// @public (undocumented) -export type RequestOptions = { - method: string; - headers: HeadersInit; - body?: BodyInit; -}; - -// @public (undocumented) -export type RoutingKey = { - routingKey: string; - targets: RoutingKeyTarget[]; - isDefault: boolean; -}; - -// @public (undocumented) -export type RoutingKeyTarget = { - policyName: string; - policySlug: string; - _teamUrl: string; -}; - -// @public (undocumented) -export interface SplunkOnCallApi { - getEscalationPolicies(): Promise; - getIncidents(): Promise; - getOnCallUsers(): Promise; - getRoutingKeys(): Promise; - getTeams(): Promise; - getUsers(): Promise; - incidentAction(request: TriggerAlarmRequest): Promise; -} - -// @public (undocumented) -export const splunkOnCallApiRef: ApiRef; - -// @public (undocumented) -export class SplunkOnCallClient implements SplunkOnCallApi { - constructor(config: ClientApiConfig); - // (undocumented) - static fromConfig( - configApi: ConfigApi, - discoveryApi: DiscoveryApi, - ): SplunkOnCallClient; - // (undocumented) - getEscalationPolicies(): Promise; - // (undocumented) - getIncidents(): Promise; - // (undocumented) - getOnCallUsers(): Promise; - // (undocumented) - getRoutingKeys(): Promise; - // (undocumented) - getTeams(): Promise; - // (undocumented) - getUsers(): Promise; - // (undocumented) - incidentAction(options: TriggerAlarmRequest): Promise; -} - -// @public (undocumented) -export const SplunkOnCallPage: { - (props: SplunkOnCallPageProps): JSX.Element; - defaultProps: { - title: string; - subtitle: string; - pageTitle: string; - }; -}; - -// @public (undocumented) -export type SplunkOnCallPageProps = { - title?: string; - subtitle?: string; - pageTitle?: string; -}; - -// @public (undocumented) -const splunkOnCallPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -export { splunkOnCallPlugin as plugin }; -export { splunkOnCallPlugin }; - -// @public (undocumented) -export type Team = { - name?: string; - slug?: string; - memberCount?: number; - version?: number; - isDefaultTeam?: boolean; - _selfUrl?: string; - _policiesUrl?: string; - _membersUrl?: string; - _adminsUrl?: string; -}; - -// @public (undocumented) -export type TriggerAlarmRequest = { - routingKey?: string; - incidentType: MessageType; - incidentId?: string; - incidentDisplayName?: string; - incidentMessage?: string; - incidentStartTime?: number; -}; - -// @public (undocumented) -export class UnauthorizedError extends Error {} - -// @public (undocumented) -export type User = { - firstName?: string; - lastName?: string; - displayName?: string; - username?: string; - email?: string; - createdAt?: string; - passwordLastUpdated?: string; - verified?: boolean; - _selfUrl?: string; -}; -``` diff --git a/plugins/splunk-on-call/catalog-info.yaml b/plugins/splunk-on-call/catalog-info.yaml deleted file mode 100644 index 8c41ec7165..0000000000 --- a/plugins/splunk-on-call/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-splunk-on-call - title: '@backstage/plugin-splunk-on-call' - description: A Backstage plugin that integrates towards Splunk On-Call -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/splunk-on-call/config.d.ts b/plugins/splunk-on-call/config.d.ts deleted file mode 100644 index bd089cc0cc..0000000000 --- a/plugins/splunk-on-call/config.d.ts +++ /dev/null @@ -1,26 +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. - */ -export interface Config { - /** - * Splunk On Call Plugin specific configs - */ - splunkOnCall?: { - /** - * @visibility frontend - */ - eventsRestEndpoint?: string; - }; -} diff --git a/plugins/splunk-on-call/dev/index.tsx b/plugins/splunk-on-call/dev/index.tsx deleted file mode 100644 index b89687acdf..0000000000 --- a/plugins/splunk-on-call/dev/index.tsx +++ /dev/null @@ -1,26 +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 { createDevApp } from '@backstage/dev-utils'; -import { splunkOnCallPlugin, SplunkOnCallPage } from '../src/plugin'; - -createDevApp() - .registerPlugin(splunkOnCallPlugin) - .addPage({ - title: 'Splunk On-Call', - element: , - }) - .render(); diff --git a/plugins/splunk-on-call/knip-report.md b/plugins/splunk-on-call/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/splunk-on-call/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json deleted file mode 100644 index 533a06b40c..0000000000 --- a/plugins/splunk-on-call/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "@backstage/plugin-splunk-on-call", - "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.4.19-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/splunk-on-call" - }, - "keywords": [ - "backstage", - "splunk-on-call" - ], - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "luxon": "^3.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@types/luxon": "^3.0.0" - }, - "configSchema": "config.d.ts", - "files": [ - "dist", - "config.d.ts" - ] -} diff --git a/plugins/splunk-on-call/src/api/client.ts b/plugins/splunk-on-call/src/api/client.ts deleted file mode 100644 index dc4cd95168..0000000000 --- a/plugins/splunk-on-call/src/api/client.ts +++ /dev/null @@ -1,179 +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 { - Incident, - OnCall, - User, - EscalationPolicyInfo, - RoutingKey, - Team, -} from '../components/types'; -import { - SplunkOnCallApi, - TriggerAlarmRequest, - IncidentsResponse, - OnCallsResponse, - ClientApiConfig, - RequestOptions, - ListUserResponse, - EscalationPolicyResponse, - ListRoutingKeyResponse, -} from './types'; -import { - createApiRef, - DiscoveryApi, - ConfigApi, -} from '@backstage/core-plugin-api'; - -/** @public */ -export class UnauthorizedError extends Error {} - -/** @public */ -export const splunkOnCallApiRef = createApiRef({ - id: 'plugin.splunk-on-call.api', -}); - -/** @public */ -export class SplunkOnCallClient implements SplunkOnCallApi { - static fromConfig(configApi: ConfigApi, discoveryApi: DiscoveryApi) { - const eventsRestEndpoint: string | null = - configApi.getOptionalString('splunkOnCall.eventsRestEndpoint') || null; - return new SplunkOnCallClient({ - eventsRestEndpoint, - discoveryApi, - }); - } - constructor(private readonly config: ClientApiConfig) {} - - async getIncidents(): Promise { - const url = `${await this.config.discoveryApi.getBaseUrl( - 'proxy', - )}/splunk-on-call/v1/incidents`; - - const { incidents } = await this.findByUrl(url); - - return incidents; - } - - async getOnCallUsers(): Promise { - const url = `${await this.config.discoveryApi.getBaseUrl( - 'proxy', - )}/splunk-on-call/v1/oncall/current`; - const { teamsOnCall } = await this.findByUrl(url); - - return teamsOnCall; - } - - async getTeams(): Promise { - const url = `${await this.config.discoveryApi.getBaseUrl( - 'proxy', - )}/splunk-on-call/v1/team`; - const teams = await this.findByUrl(url); - - return teams; - } - - async getRoutingKeys(): Promise { - const url = `${await this.config.discoveryApi.getBaseUrl( - 'proxy', - )}/splunk-on-call/v1/org/routing-keys`; - const { routingKeys } = await this.findByUrl(url); - - return routingKeys; - } - - async getUsers(): Promise { - const url = `${await this.config.discoveryApi.getBaseUrl( - 'proxy', - )}/splunk-on-call/v2/user`; - const { users } = await this.findByUrl(url); - - return users; - } - - async getEscalationPolicies(): Promise { - const url = `${await this.config.discoveryApi.getBaseUrl( - 'proxy', - )}/splunk-on-call/v1/policies`; - const { policies } = await this.findByUrl(url); - - return policies; - } - - async incidentAction(options: TriggerAlarmRequest): Promise { - const { - routingKey, - incidentType, - incidentId, - incidentDisplayName, - incidentMessage, - incidentStartTime, - } = options; - - const body = JSON.stringify({ - message_type: incidentType, - ...(incidentId ? { entity_id: incidentId } : {}), - ...(incidentDisplayName - ? { entity_display_name: incidentDisplayName } - : {}), - ...(incidentMessage ? { state_message: incidentMessage } : {}), - ...(incidentStartTime ? { state_start_time: incidentStartTime } : {}), - }); - - const request = { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body, - }; - - const url = `${this.config.eventsRestEndpoint}/${routingKey}`; - - return this.request(url, request); - } - - private async findByUrl(url: string): Promise { - const options = { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }; - const response = await this.request(url, options); - - return response.json(); - } - - private async request( - url: string, - options: RequestOptions, - ): Promise { - const response = await fetch(url, options); - if (response.status === 403) { - throw new UnauthorizedError(); - } - if (!response.ok) { - const payload = await response.json(); - const errors = payload.errors.map((error: string) => error).join(' '); - const message = `Request failed with ${response.status}, ${errors}`; - throw new Error(message); - } - return response; - } -} diff --git a/plugins/splunk-on-call/src/api/index.ts b/plugins/splunk-on-call/src/api/index.ts deleted file mode 100644 index ecfb7acca7..0000000000 --- a/plugins/splunk-on-call/src/api/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { - SplunkOnCallClient, - splunkOnCallApiRef, - UnauthorizedError, -} from './client'; -export * from './types'; diff --git a/plugins/splunk-on-call/src/api/mocks.ts b/plugins/splunk-on-call/src/api/mocks.ts deleted file mode 100644 index 8db06fb9d3..0000000000 --- a/plugins/splunk-on-call/src/api/mocks.ts +++ /dev/null @@ -1,119 +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 { - EscalationPolicyInfo, - Incident, - RoutingKey, - Team, - User, -} from '../components/types'; - -export const MOCKED_USER: User = { - createdAt: '2021-02-01T23:38:38Z', - displayName: 'Test User', - email: 'test@example.com', - firstName: 'FirstNameTest', - lastName: 'LastNameTest', - passwordLastUpdated: '2021-02-01T23:38:38Z', - username: 'test_user', - verified: true, - _selfUrl: '/api-public/v1/user/test_user', -}; - -export const MOCKED_ON_CALL = [ - { - team: { name: 'team_example', slug: 'team-zEalMCgwYSA0Lt40' }, - oncallNow: [ - { - escalationPolicy: { name: 'Example', slug: 'team-zEalMCgwYSA0Lt40' }, - users: [{ onCalluser: { username: 'test_user' } }], - }, - ], - }, -]; - -export const MOCK_INCIDENT: Incident = { - alertCount: 1, - currentPhase: 'ACKED', - entityDisplayName: 'test-incident', - entityId: 'entityId', - entityState: 'CRITICAL', - entityType: 'SERVICE', - incidentNumber: '1', - lastAlertId: 'lastAlertId', - lastAlertTime: '2021-02-03T00:13:11Z', - routingKey: 'routingdefault', - service: 'test', - startTime: '2021-02-03T00:13:11Z', - pagedTeams: ['team-O9SqT13fsnCstjMi'], - pagedUsers: [], - pagedPolicies: [ - { - policy: { - name: 'Generated Direct User Policy for test_user', - slug: 'directUserPolicySlug-test', - _selfUrl: '/test', - }, - }, - ], - transitions: [{ name: 'ACKED', at: '2021-02-03T01:20:00Z', by: 'test' }], - monitorName: 'vouser-user', - monitorType: 'Manual', - firstAlertUuid: 'firstAlertUuid', - incidentLink: 'https://portal.victorops.com/example', -}; - -export const MOCK_TEAM: Team = { - _selfUrl: '/api-public/v1/team/team-O9SqT13fsnCstjMi', - _membersUrl: '/api-public/v1/team/team-O9SqT13fsnCstjMi/members', - _policiesUrl: '/api-public/v1/team/team-O9SqT13fsnCstjMi/policies', - _adminsUrl: '/api-public/v1/team/team-O9SqT13fsnCstjMi/admins', - name: 'test', - slug: 'team-O9SqT13fsnCstjMi', - memberCount: 1, - version: 1, - isDefaultTeam: false, -}; - -export const MOCK_ROUTING_KEY: RoutingKey = { - routingKey: 'test-routing-key', - targets: [ - { - policyName: 'some policy', - policySlug: MOCK_TEAM.slug || '', - _teamUrl: `/api-public/v1/team/${MOCK_TEAM.slug}`, - }, - ], - isDefault: false, -}; - -export const MOCK_TEAM_NO_INCIDENTS: Team = { - ...MOCK_TEAM, - name: 'test-noincidents', - slug: 'team-O9SqT13fsnCstjMj', -}; - -export const ESCALATION_POLICIES: EscalationPolicyInfo[] = [ - { - policy: { - name: 'Example', - slug: 'team-zEalMCgwYSA0Lt40', - _selfUrl: '/api-public/v1/policies/team-zEalMCgwYSA0Lt40', - }, - team: { name: 'Example', slug: 'team-zEalMCgwYSA0Lt40' }, - }, -]; diff --git a/plugins/splunk-on-call/src/api/types.ts b/plugins/splunk-on-call/src/api/types.ts deleted file mode 100644 index 427eb8bbca..0000000000 --- a/plugins/splunk-on-call/src/api/types.ts +++ /dev/null @@ -1,121 +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 { - EscalationPolicyInfo, - Incident, - OnCall, - RoutingKey, - Team, - User, -} from '../components/types'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; - -/** @public */ -export type MessageType = - | 'CRITICAL' - | 'WARNING' - | 'ACKNOWLEDGEMENT' - | 'INFO' - | 'RECOVERY'; - -/** @public */ -export type TriggerAlarmRequest = { - routingKey?: string; - incidentType: MessageType; - incidentId?: string; - incidentDisplayName?: string; - incidentMessage?: string; - incidentStartTime?: number; -}; - -/** @public */ -export interface SplunkOnCallApi { - /** - * Fetches a list of incidents - */ - getIncidents(): Promise; - - /** - * Fetches the list of users in an escalation policy. - */ - getOnCallUsers(): Promise; - - /** - * Triggers-Resolves-Acknowledge an incident. - */ - incidentAction(request: TriggerAlarmRequest): Promise; - - /** - * Get a list of users for your organization. - */ - getUsers(): Promise; - - /** - * Get a list of teams for your organization. - */ - getTeams(): Promise; - - /** - * Get a list of routing keys for your organization. - */ - getRoutingKeys(): Promise; - - /** - * Get a list of escalation policies for your organization. - */ - getEscalationPolicies(): Promise; -} - -/** @public */ -export type EscalationPolicyResponse = { - policies: EscalationPolicyInfo[]; -}; - -/** @public */ -export type ListUserResponse = { - users: User[]; - _selfUrl?: string; -}; - -/** @public */ -export type ListRoutingKeyResponse = { - routingKeys: RoutingKey[]; - _selfUrl?: string; -}; - -/** @public */ -export type IncidentsResponse = { - incidents: Incident[]; -}; - -/** @public */ -export type OnCallsResponse = { - teamsOnCall: OnCall[]; -}; - -/** @public */ -export type ClientApiConfig = { - eventsRestEndpoint: string | null; - discoveryApi: DiscoveryApi; -}; - -/** @public */ -export type RequestOptions = { - method: string; - headers: HeadersInit; - body?: BodyInit; -}; diff --git a/plugins/splunk-on-call/src/assets/emptystate.svg b/plugins/splunk-on-call/src/assets/emptystate.svg deleted file mode 100644 index 8a0490727f..0000000000 --- a/plugins/splunk-on-call/src/assets/emptystate.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx deleted file mode 100644 index 5d1d41d01c..0000000000 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.test.tsx +++ /dev/null @@ -1,328 +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 { Entity } from '@backstage/catalog-model'; -import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; -import { - alertApiRef, - ConfigApi, - configApiRef, -} from '@backstage/core-plugin-api'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { act, fireEvent, screen, waitFor } from '@testing-library/react'; -import React from 'react'; -import { - splunkOnCallApiRef, - SplunkOnCallClient, - UnauthorizedError, -} from '../api'; -import { - ESCALATION_POLICIES, - MOCKED_ON_CALL, - MOCKED_USER, - MOCK_INCIDENT, - MOCK_ROUTING_KEY, - MOCK_TEAM, - MOCK_TEAM_NO_INCIDENTS, -} from '../api/mocks'; -import { EntitySplunkOnCallCard } from './EntitySplunkOnCallCard'; -import { expectTriggeredIncident } from './TriggerDialog/testUtils'; - -const mockSplunkOnCallApi: Partial = { - getUsers: async () => [], - getIncidents: async () => [MOCK_INCIDENT], - getOnCallUsers: async () => MOCKED_ON_CALL, - getTeams: async () => [MOCK_TEAM], - getRoutingKeys: async () => [MOCK_ROUTING_KEY], - getEscalationPolicies: async () => ESCALATION_POLICIES, -}; - -const configApi: ConfigApi = new ConfigReader({ - splunkOnCall: { - eventsRestEndpoint: 'EXAMPLE_REST_ENDPOINT', - }, -}); - -const apis = TestApiRegistry.from( - [splunkOnCallApiRef, mockSplunkOnCallApi], - [configApiRef, configApi], - [alertApiRef, {}], -); - -const mockEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'splunkoncall-test', - annotations: { - 'splunk.com/on-call-team': 'test', - }, - }, -} as Entity; - -const mockEntityWithRoutingKeyAnnotation = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'splunkoncall-test', - annotations: { - 'splunk.com/on-call-routing-key': MOCK_ROUTING_KEY.routingKey, - }, - }, -} as Entity; - -const mockEntityNoAnnotation = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'splunkoncall-test', - annotations: {}, - }, -} as Entity; - -const mockEntityNoIncidents = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'splunkoncall-test', - annotations: { - 'splunk.com/on-call-team': 'test-noincidents', - }, - }, -} as Entity; - -describe('SplunkOnCallCard', () => { - it('Render splunkoncall', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockImplementationOnce(async () => [MOCKED_USER]); - mockSplunkOnCallApi.getTeams = jest - .fn() - .mockImplementation(async () => [MOCK_TEAM_NO_INCIDENTS]); - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Create Incident')).toBeInTheDocument(); - await waitFor( - () => - expect( - screen.getByText('Nice! No incidents found!'), - ).toBeInTheDocument(), - { timeout: 2000 }, - ); - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - }); - - it('does not render a "Create incident" link in read only mode', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockImplementationOnce(async () => [MOCKED_USER]); - mockSplunkOnCallApi.getTeams = jest - .fn() - .mockImplementation(async () => [MOCK_TEAM_NO_INCIDENTS]); - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(() => screen.getByText('Create Incident')).toThrow(); - await waitFor( - () => - expect( - screen.getByText('Nice! No incidents found!'), - ).toBeInTheDocument(), - { timeout: 2000 }, - ); - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - }); - - it('handles a "splunk.com/on-call-routing-key" annotation', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockImplementationOnce(async () => [MOCKED_USER]); - mockSplunkOnCallApi.getRoutingKeys = jest - .fn() - .mockImplementationOnce(async () => [MOCK_ROUTING_KEY]); - mockSplunkOnCallApi.getTeams = jest - .fn() - .mockImplementation(async () => [MOCK_TEAM]); - const mockTriggerAlarmFn = jest.fn(); - mockSplunkOnCallApi.incidentAction = mockTriggerAlarmFn; - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText(`Team: ${MOCK_TEAM.name}`)).toBeInTheDocument(); - expect(screen.getByText('Create Incident')).toBeInTheDocument(); - await waitFor( - () => expect(screen.getByText('test-incident')).toBeInTheDocument(), - { timeout: 2000 }, - ); - - const createIncidentButton = screen.getByText('Create Incident'); - await act(async () => { - fireEvent.click(createIncidentButton); - }); - expect(screen.getByRole('dialog')).toBeInTheDocument(); - - await expectTriggeredIncident( - 'test-routing-key', - screen.getByTestId, - mockTriggerAlarmFn, - ); - }); - - it('Handles custom error for missing token', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockRejectedValueOnce(new UnauthorizedError()); - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText( - 'Missing or invalid Splunk On-Call API key and/or API id', - ), - ).toBeInTheDocument(); - }); - - it('handles general error', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockRejectedValueOnce(new Error('An error occurred')); - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect( - screen.getByText( - 'Error encountered while fetching information. An error occurred', - ), - ).toBeInTheDocument(); - }); - - it('handles warning for missing required annotations', async () => { - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getAllByText('Missing Annotation').length).toEqual(1); - }); - - it('handles warning for incorrect team annotation', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockImplementationOnce(async () => [MOCKED_USER]); - mockSplunkOnCallApi.getTeams = jest - .fn() - .mockImplementationOnce(async () => []); - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText( - 'Splunk On-Call API returned no record of teams associated with the "test" team name', - ), - ).toBeInTheDocument(); - }); - - it('handles warning for incorrect routing key annotation', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockImplementationOnce(async () => [MOCKED_USER]); - mockSplunkOnCallApi.getRoutingKeys = jest - .fn() - .mockImplementationOnce(async () => [MOCK_ROUTING_KEY]); - mockSplunkOnCallApi.getTeams = jest - .fn() - .mockImplementationOnce(async () => []); - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect( - screen.getByText( - `Splunk On-Call API returned no record of teams associated with the "${MOCK_ROUTING_KEY.routingKey}" routing key`, - ), - ).toBeInTheDocument(); - }); - - it('opens the dialog when trigger button is clicked', async () => { - mockSplunkOnCallApi.getUsers = jest - .fn() - .mockImplementationOnce(async () => [MOCKED_USER]); - mockSplunkOnCallApi.getTeams = jest - .fn() - .mockImplementationOnce(async () => [MOCK_TEAM]); - - await renderInTestApp( - - - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - expect(screen.getByText('Create Incident')).toBeInTheDocument(); - const triggerButton = screen.getByText('Create Incident'); - await act(async () => { - fireEvent.click(triggerButton); - }); - expect(screen.getByRole('dialog')).toBeInTheDocument(); - }); -}); diff --git a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx b/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx deleted file mode 100644 index 5800ea98b6..0000000000 --- a/plugins/splunk-on-call/src/components/EntitySplunkOnCallCard.tsx +++ /dev/null @@ -1,282 +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, { useCallback, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { Entity } from '@backstage/catalog-model'; -import { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import { - Card, - CardContent, - CardHeader, - Divider, - makeStyles, - Typography, -} from '@material-ui/core'; -import AlarmAddIcon from '@material-ui/icons/AlarmAdd'; -import WebIcon from '@material-ui/icons/Web'; -import { Alert } from '@material-ui/lab'; -import { splunkOnCallApiRef, UnauthorizedError } from '../api'; -import { MissingApiKeyOrApiIdError } from './Errors'; -import { EscalationPolicy } from './Escalation'; -import { Incidents } from './Incident'; -import { TriggerDialog } from './TriggerDialog'; -import { RoutingKey, User } from './types'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; - -import { - EmptyState, - HeaderIconLinkRow, - IconLinkVerticalProps, - Progress, -} from '@backstage/core-components'; - -export const SPLUNK_ON_CALL_TEAM = 'splunk.com/on-call-team'; -export const SPLUNK_ON_CALL_ROUTING_KEY = 'splunk.com/on-call-routing-key'; - -export const MissingAnnotation = () => ( -
- - The Splunk On Call plugin requires setting either the{' '} - {SPLUNK_ON_CALL_TEAM} or the{' '} - {SPLUNK_ON_CALL_ROUTING_KEY} annotation. - - -
-); - -export const InvalidAnnotation = ({ - teamName, - routingKey, -}: { - teamName: string | undefined; - routingKey: string | undefined; -}) => { - let titleSuffix = 'provided annotation'; - - if (routingKey) { - titleSuffix = `"${routingKey}" routing key`; - } - - if (teamName) { - titleSuffix = `"${teamName}" team name`; - } - - return ( - - - - - - - ); -}; - -export const MissingEventsRestEndpoint = () => ( - - - -); - -/** @public */ -export const isSplunkOnCallAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[SPLUNK_ON_CALL_TEAM]) || - Boolean(entity.metadata.annotations?.[SPLUNK_ON_CALL_ROUTING_KEY]); - -const useStyles = makeStyles({ - onCallCard: { - marginBottom: '1em', - }, -}); - -/** @public */ -export type EntitySplunkOnCallCardProps = { - readOnly?: boolean; -}; - -/** @public */ -export const EntitySplunkOnCallCard = (props: EntitySplunkOnCallCardProps) => { - const { readOnly } = props; - const classes = useStyles(); - const config = useApi(configApiRef); - const api = useApi(splunkOnCallApiRef); - const { entity } = useEntity(); - const [showDialog, setShowDialog] = useState(false); - const [refreshIncidents, setRefreshIncidents] = useState(false); - const teamAnnotation = entity - ? entity.metadata.annotations![SPLUNK_ON_CALL_TEAM] - : undefined; - const routingKeyAnnotation = entity - ? entity.metadata.annotations![SPLUNK_ON_CALL_ROUTING_KEY] - : undefined; - - const eventsRestEndpoint = - config.getOptionalString('splunkOnCall.eventsRestEndpoint') || null; - - const handleRefresh = useCallback(() => { - setRefreshIncidents(x => !x); - }, []); - - const handleDialog = useCallback(() => { - setShowDialog(x => !x); - }, []); - - const { - value: entityData, - loading, - error, - } = useAsync(async () => { - const allUsers = await api.getUsers(); - const usersHashMap = allUsers.reduce( - (map: Record, obj: User) => { - if (obj.username) { - map[obj.username] = obj; - } - return map; - }, - {}, - ); - const teams = await api.getTeams(); - let foundTeams = [ - teams.find(teamValue => teamValue.name === teamAnnotation), - ].filter(team => team !== undefined); - - let foundRoutingKey: RoutingKey | undefined; - if (routingKeyAnnotation) { - const routingKeys = await api.getRoutingKeys(); - foundRoutingKey = routingKeys.find( - key => key.routingKey === routingKeyAnnotation, - ); - } - - if (!foundTeams.length) { - foundTeams = foundRoutingKey - ? foundRoutingKey.targets - .map(target => { - const teamUrlParts = target._teamUrl.split('/'); - const teamSlug = teamUrlParts[teamUrlParts.length - 1]; - - return teams.find(teamValue => teamValue.slug === teamSlug); - }) - .filter(team => team !== undefined) - : []; - } - - return { usersHashMap, foundTeams, foundRoutingKey }; - }); - - if (!teamAnnotation && !routingKeyAnnotation) { - return ; - } - - if (!eventsRestEndpoint) { - return ; - } - - if (error instanceof UnauthorizedError) { - return ; - } - - if (error) { - return ( - - Error encountered while fetching information. {error.message} - - ); - } - - if (loading) { - return ; - } - - if (!entityData?.foundTeams || !entityData?.foundTeams.length) { - return ( - - ); - } - - const triggerLink: IconLinkVerticalProps = { - label: 'Create Incident', - onClick: handleDialog, - color: 'secondary', - icon: , - }; - - const serviceLink = { - label: 'Portal', - href: 'https://portal.victorops.com/', - icon: , - }; - - const teams = entityData?.foundTeams || []; - - return ( - <> - {teams.map((team, i) => { - const teamName = team?.name ?? ''; - return ( - - - Team: {team && team.name ? team.name : ''} - , - , - ]} - /> - - - - {entityData?.usersHashMap && team && ( - - )} - - - - ); - })} - - ); -}; diff --git a/plugins/splunk-on-call/src/components/Errors/MissingApiKeyOrApiIdError.tsx b/plugins/splunk-on-call/src/components/Errors/MissingApiKeyOrApiIdError.tsx deleted file mode 100644 index bc8aa05813..0000000000 --- a/plugins/splunk-on-call/src/components/Errors/MissingApiKeyOrApiIdError.tsx +++ /dev/null @@ -1,35 +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 { Button } from '@material-ui/core'; -import { EmptyState } from '@backstage/core-components'; - -export const MissingApiKeyOrApiIdError = () => ( - - Read More - - } - /> -); diff --git a/plugins/splunk-on-call/src/components/Errors/index.ts b/plugins/splunk-on-call/src/components/Errors/index.ts deleted file mode 100644 index 09b256d0e9..0000000000 --- a/plugins/splunk-on-call/src/components/Errors/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { MissingApiKeyOrApiIdError } from './MissingApiKeyOrApiIdError'; diff --git a/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx b/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx deleted file mode 100644 index 70242dd388..0000000000 --- a/plugins/splunk-on-call/src/components/Escalation/Escalation.test.tsx +++ /dev/null @@ -1,97 +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 { screen, waitFor } from '@testing-library/react'; -import { EscalationPolicy } from './EscalationPolicy'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { splunkOnCallApiRef } from '../../api'; -import { MOCKED_ON_CALL, MOCKED_USER } from '../../api/mocks'; -import { ApiProvider } from '@backstage/core-app-api'; - -const mockSplunkOnCallApi = { - getOnCallUsers: jest.fn(), -}; -const apis = TestApiRegistry.from([splunkOnCallApiRef, mockSplunkOnCallApi]); - -describe('Escalation', () => { - it('Handles an empty response', async () => { - mockSplunkOnCallApi.getOnCallUsers = jest - .fn() - .mockImplementationOnce(async () => []); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect(screen.getByText('Empty escalation policy')).toBeInTheDocument(); - expect(mockSplunkOnCallApi.getOnCallUsers).toHaveBeenCalled(); - }); - - it('Render a list of users', async () => { - mockSplunkOnCallApi.getOnCallUsers = jest - .fn() - .mockImplementationOnce(async () => MOCKED_ON_CALL); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect(screen.getByText('FirstNameTest LastNameTest')).toBeInTheDocument(); - expect(screen.getByText('test@example.com')).toBeInTheDocument(); - expect(mockSplunkOnCallApi.getOnCallUsers).toHaveBeenCalled(); - }); - - it('Handles errors', async () => { - mockSplunkOnCallApi.getOnCallUsers = jest - .fn() - .mockRejectedValueOnce(new Error('Error message')); - - await renderInTestApp( - - - , - ); - await waitFor(() => !screen.queryByTestId('progress')); - - expect( - screen.getByText( - 'Error encountered while fetching information. Error message', - ), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/splunk-on-call/src/components/Escalation/EscalationPolicy.tsx b/plugins/splunk-on-call/src/components/Escalation/EscalationPolicy.tsx deleted file mode 100644 index 7902453490..0000000000 --- a/plugins/splunk-on-call/src/components/Escalation/EscalationPolicy.tsx +++ /dev/null @@ -1,111 +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 { - createStyles, - List, - ListSubheader, - makeStyles, - Theme, -} from '@material-ui/core'; -import { EscalationUsersEmptyState } from './EscalationUsersEmptyState'; -import { EscalationUser } from './EscalationUser'; -import useAsync from 'react-use/lib/useAsync'; -import { splunkOnCallApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; -import { User } from '../types'; - -import { useApi } from '@backstage/core-plugin-api'; -import { Progress } from '@backstage/core-components'; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - maxHeight: '400px', - overflow: 'auto', - }, - subheader: { - backgroundColor: theme.palette.background.paper, - }, - progress: { - margin: theme.spacing(0, 2), - }, - }), -); - -type Props = { - users: { [key: string]: User }; - team: string; -}; - -export const EscalationPolicy = ({ users, team }: Props) => { - const classes = useStyles(); - const api = useApi(splunkOnCallApiRef); - - const { - value: userNames, - loading, - error, - } = useAsync(async () => { - const oncalls = await api.getOnCallUsers(); - const teamUsernames = oncalls - .filter(oncall => oncall.team?.name === team) - .flatMap(oncall => { - return oncall.oncallNow?.flatMap(oncallNow => { - return oncallNow.users?.flatMap(user => { - return user?.onCalluser?.username; - }); - }); - }); - return teamUsernames; - }); - - if (error) { - return ( - - Error encountered while fetching information. {error.message} - - ); - } - - if (!loading && !userNames?.length) { - return ; - } - - return ( - ON CALL - } - > - {loading ? ( - - ) : ( - userNames && - userNames.map( - (userName, index) => - userName && - userName in users && ( - - ), - ) - )} - - ); -}; diff --git a/plugins/splunk-on-call/src/components/Escalation/EscalationUser.tsx b/plugins/splunk-on-call/src/components/Escalation/EscalationUser.tsx deleted file mode 100644 index ba7abbddab..0000000000 --- a/plugins/splunk-on-call/src/components/Escalation/EscalationUser.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 { - ListItem, - ListItemIcon, - ListItemSecondaryAction, - Tooltip, - ListItemText, - makeStyles, - IconButton, - Typography, -} from '@material-ui/core'; -import Avatar from '@material-ui/core/Avatar'; -import EmailIcon from '@material-ui/icons/Email'; -import { User } from '../types'; - -const useStyles = makeStyles({ - listItemPrimary: { - fontWeight: 'bold', - }, -}); - -type Props = { - user: User; -}; - -export const EscalationUser = ({ user }: Props) => { - const classes = useStyles(); - - return ( - - - - - - {user.firstName} {user.lastName} - - } - secondary={user.email} - /> - - - - - - - - - ); -}; diff --git a/plugins/splunk-on-call/src/components/Escalation/EscalationUsersEmptyState.tsx b/plugins/splunk-on-call/src/components/Escalation/EscalationUsersEmptyState.tsx deleted file mode 100644 index b4c10ddcf8..0000000000 --- a/plugins/splunk-on-call/src/components/Escalation/EscalationUsersEmptyState.tsx +++ /dev/null @@ -1,48 +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 { - ListItem, - ListItemIcon, - ListItemText, - makeStyles, -} from '@material-ui/core'; -import { StatusWarning } from '@backstage/core-components'; - -const useStyles = makeStyles({ - denseListIcon: { - marginRight: 0, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - }, -}); - -export const EscalationUsersEmptyState = () => { - const classes = useStyles(); - return ( - - -
- -
-
- -
- ); -}; diff --git a/plugins/splunk-on-call/src/components/Escalation/index.ts b/plugins/splunk-on-call/src/components/Escalation/index.ts deleted file mode 100644 index 165ec6690b..0000000000 --- a/plugins/splunk-on-call/src/components/Escalation/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { EscalationPolicy } from './EscalationPolicy'; diff --git a/plugins/splunk-on-call/src/components/Incident/IncidentEmptyState.tsx b/plugins/splunk-on-call/src/components/Incident/IncidentEmptyState.tsx deleted file mode 100644 index 87108f3d74..0000000000 --- a/plugins/splunk-on-call/src/components/Incident/IncidentEmptyState.tsx +++ /dev/null @@ -1,41 +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 { Grid, Typography } from '@material-ui/core'; -import EmptyStateImage from '../../assets/emptystate.svg'; - -export const IncidentsEmptyState = () => { - return ( - - - Nice! No incidents found! - - - EmptyState - - - ); -}; diff --git a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx b/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx deleted file mode 100644 index d8b6a56efc..0000000000 --- a/plugins/splunk-on-call/src/components/Incident/IncidentListItem.tsx +++ /dev/null @@ -1,268 +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, { useEffect } from 'react'; -import { - ListItem, - ListItemIcon, - ListItemSecondaryAction, - Tooltip, - ListItemText, - makeStyles, - IconButton, - Typography, -} from '@material-ui/core'; -import DoneIcon from '@material-ui/icons/Done'; -import DoneAllIcon from '@material-ui/icons/DoneAll'; -import { DateTime, Duration } from 'luxon'; -import { Incident, IncidentPhase } from '../types'; -import OpenInBrowserIcon from '@material-ui/icons/OpenInBrowser'; -import { splunkOnCallApiRef } from '../../api/client'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import { TriggerAlarmRequest } from '../../api/types'; - -import { - StatusError, - StatusWarning, - StatusOK, -} from '@backstage/core-components'; -import { useApi, alertApiRef } from '@backstage/core-plugin-api'; - -const useStyles = makeStyles({ - denseListIcon: { - marginRight: 0, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', - }, - listItemPrimary: { - fontWeight: 'bold', - }, - listItemIcon: { - minWidth: '1em', - }, - secondaryAction: { - paddingRight: 48, - }, -}); - -type Props = { - team: string; - incident: Incident; - onIncidentAction: () => void; - readOnly: boolean; -}; - -const IncidentPhaseStatus = ({ - currentPhase, -}: { - currentPhase: IncidentPhase; -}) => { - switch (currentPhase) { - case 'UNACKED': - return ; - case 'ACKED': - return ; - default: - return ; - } -}; - -const incidentPhaseTooltip = (currentPhase: IncidentPhase) => { - switch (currentPhase) { - case 'UNACKED': - return 'Triggered'; - case 'ACKED': - return 'Acknowledged'; - default: - return 'Resolved'; - } -}; - -const IncidentAction = ({ - currentPhase, - incidentId, - resolveAction, - acknowledgeAction, -}: { - currentPhase: string; - incidentId: string; - resolveAction: (args: TriggerAlarmRequest) => void; - acknowledgeAction: (args: TriggerAlarmRequest) => void; -}) => { - switch (currentPhase) { - case 'UNACKED': - return ( - - - acknowledgeAction({ incidentId, incidentType: 'ACKNOWLEDGEMENT' }) - } - > - - - - ); - case 'ACKED': - return ( - - - resolveAction({ incidentId, incidentType: 'RECOVERY' }) - } - > - - - - ); - default: - return <>; - } -}; - -export const IncidentListItem = ({ - incident, - readOnly, - onIncidentAction, - team, -}: Props) => { - const classes = useStyles(); - const duration = - new Date().getTime() - new Date(incident.startTime!).getTime(); - const createdAt = DateTime.local() - .minus(Duration.fromMillis(duration)) - .toRelative({ locale: 'en' }); - const alertApi = useApi(alertApiRef); - const api = useApi(splunkOnCallApiRef); - - const hasBeenManuallyTriggered = incident.monitorName?.includes('vouser-'); - - const source = () => { - if (hasBeenManuallyTriggered) { - return incident.monitorName?.replace('vouser-', ''); - } - if (incident.monitorType === 'API') { - return '{ REST }'; - } - - return incident.monitorName; - }; - - const [{ value: resolveValue, error: resolveError }, handleResolveIncident] = - useAsyncFn( - async ({ incidentId, incidentType }: TriggerAlarmRequest) => - await api.incidentAction({ - routingKey: team, - incidentType, - incidentId, - }), - ); - - const [ - { value: acknowledgeValue, error: acknowledgeError }, - handleAcknowledgeIncident, - ] = useAsyncFn( - async ({ incidentId, incidentType }: TriggerAlarmRequest) => - await api.incidentAction({ - routingKey: team, - incidentType, - incidentId, - }), - ); - - useEffect(() => { - if (acknowledgeValue) { - alertApi.post({ - message: `Incident successfully acknowledged`, - }); - } - - if (resolveValue) { - alertApi.post({ - message: `Incident successfully resolved`, - }); - } - if (resolveValue || acknowledgeValue) { - onIncidentAction(); - } - }, [acknowledgeValue, resolveValue, alertApi, onIncidentAction]); - - if (acknowledgeError) { - alertApi.post({ - message: `Failed to acknowledge incident. ${acknowledgeError.message}`, - severity: 'error', - }); - } - - if (resolveError) { - alertApi.post({ - message: `Failed to resolve incident. ${resolveError.message}`, - severity: 'error', - }); - } - - return ( - - - -
- -
-
-
- - #{incident.incidentNumber} - Created {createdAt}{' '} - {source() && `by ${source()}`} - - } - /> - - {incident.incidentLink && incident.incidentNumber && ( - - {!readOnly && ( - - )} - - - - - - - )} -
- ); -}; diff --git a/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx b/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx deleted file mode 100644 index 9b8d5feb97..0000000000 --- a/plugins/splunk-on-call/src/components/Incident/Incidents.test.tsx +++ /dev/null @@ -1,139 +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 { screen, waitFor } from '@testing-library/react'; -import { Incidents } from './Incidents'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { splunkOnCallApiRef } from '../../api'; -import { MOCK_TEAM, MOCK_INCIDENT } from '../../api/mocks'; - -import { alertApiRef } from '@backstage/core-plugin-api'; -import { ApiProvider } from '@backstage/core-app-api'; - -const mockSplunkOnCallApi = { - getIncidents: jest.fn(), - getTeams: jest.fn(), -}; -const apis = TestApiRegistry.from( - [alertApiRef, {}], - [splunkOnCallApiRef, mockSplunkOnCallApi], -); - -describe('Incidents', () => { - beforeEach(() => { - jest.useFakeTimers(); - }); - afterEach(() => { - jest.resetAllMocks(); - jest.useRealTimers(); - }); - - it('Renders an empty state when there are no incidents', async () => { - mockSplunkOnCallApi.getIncidents.mockResolvedValue([]); - mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]); - - await renderInTestApp( - - - , - ); - jest.advanceTimersByTime(2000); - await waitFor(() => expect(screen.queryByTestId('progress')).toBe(null)); - await waitFor(() => - expect(screen.getByText('Nice! No incidents found!')).toBeInTheDocument(), - ); - }); - - it('Renders all incidents', async () => { - mockSplunkOnCallApi.getIncidents.mockResolvedValue([MOCK_INCIDENT]); - mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]); - - await renderInTestApp( - - - , - ); - jest.advanceTimersByTime(2000); - await waitFor(() => expect(screen.queryByTestId('progress')).toBe(null)); - await waitFor(() => - expect( - screen.getByText('user', { - exact: false, - }), - ).toBeInTheDocument(), - ); - expect(screen.getByText('test-incident')).toBeInTheDocument(); - expect(screen.getByTitle('Acknowledged')).toBeInTheDocument(); - expect(screen.getByLabelText('Status warning')).toBeInTheDocument(); - - // assert links, mailto and hrefs, date calculation - expect(screen.getAllByTitle('View in Splunk On-Call').length).toEqual(1); - }); - - it('does not render incident action buttons in read only mode', async () => { - mockSplunkOnCallApi.getIncidents.mockResolvedValue([MOCK_INCIDENT]); - mockSplunkOnCallApi.getTeams.mockResolvedValue([MOCK_TEAM]); - - await renderInTestApp( - - - , - ); - jest.advanceTimersByTime(2000); - await waitFor(() => expect(screen.queryByTestId('progress')).toBe(null)); - await waitFor(() => - expect( - screen.getByText('user', { - exact: false, - }), - ).toBeInTheDocument(), - ); - expect(screen.getByText('test-incident')).toBeInTheDocument(); - expect(screen.getByLabelText('Status warning')).toBeInTheDocument(); - expect(() => screen.getAllByTitle('Acknowledge')).toThrow( - 'Unable to find an element with the title: Acknowledge.', - ); - expect(() => screen.getAllByTitle('Resolve')).toThrow( - 'Unable to find an element with the title: Resolve.', - ); - - // assert links, mailto and hrefs, date calculation - expect(screen.getAllByTitle('View in Splunk On-Call').length).toEqual(1); - }); - - it('Handle errors', async () => { - mockSplunkOnCallApi.getIncidents.mockRejectedValueOnce( - new Error('Error occurred'), - ); - mockSplunkOnCallApi.getTeams.mockResolvedValue([]); - - await renderInTestApp( - - - , - ); - jest.advanceTimersByTime(2000); - await waitFor(() => expect(screen.queryByTestId('progress')).toBe(null)); - await waitFor(() => - expect( - screen.getByText( - 'Error encountered while fetching information. Error occurred', - ), - ).toBeInTheDocument(), - ); - }); -}); diff --git a/plugins/splunk-on-call/src/components/Incident/Incidents.tsx b/plugins/splunk-on-call/src/components/Incident/Incidents.tsx deleted file mode 100644 index 6dcb4f9989..0000000000 --- a/plugins/splunk-on-call/src/components/Incident/Incidents.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useEffect } from 'react'; -import { - createStyles, - List, - ListSubheader, - makeStyles, - Theme, -} from '@material-ui/core'; -import { IncidentListItem } from './IncidentListItem'; -import { IncidentsEmptyState } from './IncidentEmptyState'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import { splunkOnCallApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; - -import { useApi } from '@backstage/core-plugin-api'; -import { Progress } from '@backstage/core-components'; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - maxHeight: '400px', - overflow: 'auto', - }, - subheader: { - backgroundColor: theme.palette.background.paper, - }, - progress: { - margin: theme.spacing(0, 2), - }, - }), -); - -type Props = { - refreshIncidents: boolean; - team: string; - readOnly: boolean; -}; - -export const Incidents = ({ readOnly, refreshIncidents, team }: Props) => { - const classes = useStyles(); - const api = useApi(splunkOnCallApiRef); - - const [{ value: incidents, loading, error }, getIncidents] = useAsyncFn( - async () => { - // For some reason the changes applied to incidents (trigger-resolve-acknowledge) - // may take some time to actually be applied after receiving the response from the server. - // The timeout compensates for this latency. - await new Promise(resolve => setTimeout(resolve, 2000)); - const allIncidents = await api.getIncidents(); - const teams = await api.getTeams(); - const teamSlug = teams.find(teamValue => teamValue.name === team)?.slug; - const filteredIncidents = teamSlug - ? allIncidents.filter(incident => - incident.pagedTeams?.includes(teamSlug), - ) - : []; - return filteredIncidents; - }, - ); - - useEffect(() => { - getIncidents(); - }, [refreshIncidents, getIncidents]); - - if (error) { - return ( - - Error encountered while fetching information. {error.message} - - ); - } - - if (!loading && !incidents?.length) { - return ; - } - - return ( - - CRITICAL INCIDENTS - - } - > - {loading ? ( - - ) : ( - incidents!.map((incident, index) => ( - getIncidents()} - key={index} - team={team} - incident={incident} - readOnly={readOnly} - /> - )) - )} - - ); -}; diff --git a/plugins/splunk-on-call/src/components/Incident/index.ts b/plugins/splunk-on-call/src/components/Incident/index.ts deleted file mode 100644 index 3729de6e01..0000000000 --- a/plugins/splunk-on-call/src/components/Incident/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { Incidents } from './Incidents'; diff --git a/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx b/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx deleted file mode 100644 index 4cbefa244d..0000000000 --- a/plugins/splunk-on-call/src/components/SplunkOnCallPage.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { Grid, makeStyles } from '@material-ui/core'; -import { EntitySplunkOnCallCard } from './EntitySplunkOnCallCard'; -import { - Content, - ContentHeader, - Page, - Header, - SupportButton, -} from '@backstage/core-components'; - -const useStyles = makeStyles(() => ({ - overflowXScroll: { - overflowX: 'scroll', - }, -})); - -/** @public */ -export type SplunkOnCallPageProps = { - title?: string; - subtitle?: string; - pageTitle?: string; -}; - -export const SplunkOnCallPage = (props: SplunkOnCallPageProps): JSX.Element => { - const { title, subtitle, pageTitle } = props; - const classes = useStyles(); - - return ( - -
- - - - This is used to help you automate incident management. - - - - - - - - - - ); -}; - -SplunkOnCallPage.defaultProps = { - title: 'Splunk On-Call', - subtitle: 'Automate incident management', - pageTitle: 'Dashboard', -}; diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx deleted file mode 100644 index f66d4a0333..0000000000 --- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.test.tsx +++ /dev/null @@ -1,61 +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 { ApiProvider } from '@backstage/core-app-api'; -import { alertApiRef } from '@backstage/core-plugin-api'; -import { TestApiRegistry, renderInTestApp } from '@backstage/test-utils'; -import { screen } from '@testing-library/react'; -import React from 'react'; -import { splunkOnCallApiRef } from '../../api'; -import { TriggerDialog } from './TriggerDialog'; -import { expectTriggeredIncident } from './testUtils'; - -describe('TriggerDialog', () => { - const mockTriggerAlarmFn = jest.fn(); - const mockSplunkOnCallApi = { - incidentAction: mockTriggerAlarmFn, - }; - - const apis = TestApiRegistry.from( - [alertApiRef, {}], - [splunkOnCallApiRef, mockSplunkOnCallApi], - ); - - it('open the dialog and trigger an alarm', async () => { - await renderInTestApp( - - {}} - onIncidentCreated={() => {}} - /> - , - ); - - expect(screen.getByRole('dialog')).toBeInTheDocument(); - expect( - screen.getByText('This action will trigger an incident', { - exact: false, - }), - ).toBeInTheDocument(); - await expectTriggeredIncident( - 'Example', - screen.getByTestId, - mockTriggerAlarmFn, - ); - }); -}); diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx b/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx deleted file mode 100644 index dd8f0b1909..0000000000 --- a/plugins/splunk-on-call/src/components/TriggerDialog/TriggerDialog.tsx +++ /dev/null @@ -1,263 +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, { useState, useEffect } from 'react'; -import { - Dialog, - DialogTitle, - TextField, - DialogActions, - Button, - DialogContent, - Typography, - CircularProgress, - Select, - MenuItem, - createStyles, - makeStyles, - Theme, - FormControl, - InputLabel, -} from '@material-ui/core'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import { splunkOnCallApiRef } from '../../api'; -import { Alert } from '@material-ui/lab'; -import { TriggerAlarmRequest } from '../../api'; -import { useApi, alertApiRef } from '@backstage/core-plugin-api'; - -type Props = { - routingKey: string; - showDialog: boolean; - handleDialog: () => void; - onIncidentCreated: () => void; -}; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - chips: { - display: 'flex', - flexWrap: 'wrap', - }, - chip: { - margin: 2, - }, - formControl: { - margin: theme.spacing(1), - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - minWidth: `calc(100% - ${theme.spacing(2)}px)`, - }, - formHeader: { - width: '50%', - }, - incidentType: { - width: '90%', - }, - targets: { - display: 'flex', - flexDirection: 'column', - width: '100%', - }, - }), -); - -export const TriggerDialog = ({ - routingKey, - showDialog, - handleDialog, - onIncidentCreated: onIncidentCreated, -}: Props) => { - const alertApi = useApi(alertApiRef); - const api = useApi(splunkOnCallApiRef); - const classes = useStyles(); - - const [incidentType, setIncidentType] = useState(''); - const [incidentId, setIncidentId] = useState(); - const [incidentDisplayName, setIncidentDisplayName] = useState(''); - const [incidentMessage, setIncidentMessage] = useState(''); - const [incidentStartTime, setIncidentStartTime] = useState(); - - const [ - { value, loading: triggerLoading, error: triggerError }, - handleTriggerAlarm, - ] = useAsyncFn( - async (params: TriggerAlarmRequest) => await api.incidentAction(params), - ); - - const handleIncidentType = (event: React.ChangeEvent<{ value: unknown }>) => { - setIncidentType(event.target.value as string); - }; - - const handleIncidentId = (event: React.ChangeEvent) => { - setIncidentId(event.target.value as string); - }; - - const handleIncidentDisplayName = ( - event: React.ChangeEvent, - ) => { - setIncidentDisplayName(event.target.value); - }; - - const handleIncidentMessage = ( - event: React.ChangeEvent, - ) => { - setIncidentMessage(event.target.value); - }; - - const handleIncidentStartTime = ( - event: React.ChangeEvent, - ) => { - const dateTime = new Date(event.target.value).getTime(); - const dateTimeInSeconds = Math.floor(dateTime / 1000); - setIncidentStartTime(dateTimeInSeconds); - }; - - useEffect(() => { - if (value) { - alertApi.post({ - message: `Alarm successfully triggered`, - }); - onIncidentCreated(); - handleDialog(); - } - }, [value, alertApi, handleDialog, onIncidentCreated]); - - if (triggerError) { - alertApi.post({ - message: `Failed to trigger alarm. ${triggerError.message}`, - severity: 'error', - }); - } - - return ( - - This action will trigger an incident - - - Created by: {`{ REST } Endpoint`} - - - - If the issue you are seeing does not need urgent attention, please - get in touch with the responsible team using their preferred - communications channel. You can find information about the owner of - this entity in the "About" card. If the issue is urgent, please - don't hesitate to trigger the alert. - - - - Please describe the problem you want to report. Be as descriptive as - possible.
- Note that only the Incident type, Incident display name{' '} - and the Incident message fields are required. -
- -
- Incident type - -
- -
- - - -
- - - - -
- ); -}; diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/index.ts b/plugins/splunk-on-call/src/components/TriggerDialog/index.ts deleted file mode 100644 index 5c48cce7ed..0000000000 --- a/plugins/splunk-on-call/src/components/TriggerDialog/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { TriggerDialog } from './TriggerDialog'; diff --git a/plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts b/plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts deleted file mode 100644 index 9beb4e150e..0000000000 --- a/plugins/splunk-on-call/src/components/TriggerDialog/testUtils.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ -// eslint-disable-next-line @backstage/no-undeclared-imports -import { - act, - fireEvent, - Matcher, - MatcherOptions, -} from '@testing-library/react'; - -export async function expectTriggeredIncident( - routingKey: string, - getByTestId: ( - id: Matcher, - options?: MatcherOptions | undefined, - ) => HTMLElement, - mockTriggerAlarmFn: any, -): Promise { - const incidentType = getByTestId('trigger-incident-type'); - const incidentId = getByTestId('trigger-incident-id'); - const incidentDisplayName = getByTestId('trigger-incident-displayName'); - const incidentMessage = getByTestId('trigger-incident-message'); - - await act(async () => { - fireEvent.change(incidentType, { target: { value: 'CRITICAL' } }); - fireEvent.change(incidentId, { target: { value: 'incident-id' } }); - fireEvent.change(incidentDisplayName, { - target: { value: 'incident-display-name' }, - }); - fireEvent.change(incidentMessage, { - target: { value: 'incident-message' }, - }); - }); - - // Trigger incident creation button - const triggerButton = getByTestId('trigger-button'); - await act(async () => { - fireEvent.click(triggerButton); - }); - - expect(mockTriggerAlarmFn).toHaveBeenCalled(); - expect(mockTriggerAlarmFn).toHaveBeenCalledWith({ - incidentType: 'CRITICAL', - incidentId: 'incident-id', - routingKey: routingKey, - incidentDisplayName: 'incident-display-name', - incidentMessage: 'incident-message', - }); -} diff --git a/plugins/splunk-on-call/src/components/index.ts b/plugins/splunk-on-call/src/components/index.ts deleted file mode 100644 index 47fd7fbf27..0000000000 --- a/plugins/splunk-on-call/src/components/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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 type { SplunkOnCallPageProps } from './SplunkOnCallPage'; -export type { EntitySplunkOnCallCardProps } from './EntitySplunkOnCallCard'; -export { isSplunkOnCallAvailable } from './EntitySplunkOnCallCard'; -export * from './types'; diff --git a/plugins/splunk-on-call/src/components/types.ts b/plugins/splunk-on-call/src/components/types.ts deleted file mode 100644 index 7e83de84a7..0000000000 --- a/plugins/splunk-on-call/src/components/types.ts +++ /dev/null @@ -1,147 +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. - */ - -/** @public */ -export type Team = { - name?: string; - slug?: string; - memberCount?: number; - version?: number; - isDefaultTeam?: boolean; - _selfUrl?: string; - _policiesUrl?: string; - _membersUrl?: string; - _adminsUrl?: string; -}; - -/** @public */ -export type OnCall = { - team?: OnCallTeamResource; - oncallNow?: OnCallNowResource[]; -}; - -/** @public */ -export type OnCallTeamResource = { - name?: string; - slug?: string; -}; - -/** @public */ -export type OnCallNowResource = { - escalationPolicy?: OnCallEscalationPolicyResource; - users?: OnCallUsersResource[]; -}; - -/** @public */ -export type OnCallEscalationPolicyResource = { - name?: string; - slug?: string; -}; - -/** @public */ -export type OnCallUsersResource = { - onCalluser?: OnCallUser; -}; - -/** @public */ -export type OnCallUser = { - username?: string; -}; - -/** @public */ -export type User = { - firstName?: string; - lastName?: string; - displayName?: string; - username?: string; - email?: string; - createdAt?: string; - passwordLastUpdated?: string; - verified?: boolean; - _selfUrl?: string; -}; - -/** @public */ -export type IncidentPhase = 'UNACKED' | 'ACKED' | 'RESOLVED'; - -/** @public */ -export type Incident = { - incidentNumber?: string; - startTime?: string; - currentPhase: IncidentPhase; - entityState?: string; - entityType?: string; - routingKey?: string; - alertCount?: number; - lastAlertTime?: string; - lastAlertId?: string; - entityId: string; - host?: string; - service?: string; - pagedUsers?: string[]; - pagedTeams?: string[]; - entityDisplayName?: string; - pagedPolicies?: EscalationPolicyInfo[]; - transitions?: IncidentTransition[]; - firstAlertUuid?: string; - monitorName?: string; - monitorType?: string; - incidentLink?: string; -}; - -/** @public */ -export type EscalationPolicyInfo = { - policy: EscalationPolicySummary; - team?: EscalationPolicyTeam; -}; - -/** @public */ -export type IncidentTransition = { - name?: string; - at?: string; - by?: string; - message?: string; - manually?: boolean; - alertId?: string; - alertUrl?: string; -}; - -/** @public */ -export type EscalationPolicySummary = { - name: string; - slug: string; - _selfUrl: string; -}; - -/** @public */ -export type EscalationPolicyTeam = { - name: string; - slug: string; -}; - -/** @public */ -export type RoutingKey = { - routingKey: string; - targets: RoutingKeyTarget[]; - isDefault: boolean; -}; - -/** @public */ -export type RoutingKeyTarget = { - policyName: string; - policySlug: string; - _teamUrl: string; -}; diff --git a/plugins/splunk-on-call/src/index.ts b/plugins/splunk-on-call/src/index.ts deleted file mode 100644 index 285e6c8f89..0000000000 --- a/plugins/splunk-on-call/src/index.ts +++ /dev/null @@ -1,30 +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. - */ - -/** - * A Backstage plugin that integrates towards Splunk On-Call - * - * @packageDocumentation - */ - -export { - EntitySplunkOnCallCard, - splunkOnCallPlugin, - splunkOnCallPlugin as plugin, - SplunkOnCallPage, -} from './plugin'; -export * from './components'; -export * from './api'; diff --git a/plugins/splunk-on-call/src/plugin.test.ts b/plugins/splunk-on-call/src/plugin.test.ts deleted file mode 100644 index c30eb7bfa2..0000000000 --- a/plugins/splunk-on-call/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { splunkOnCallPlugin } from './plugin'; - -describe('splunk-on-call', () => { - it('should export plugin', () => { - expect(splunkOnCallPlugin).toBeDefined(); - }); -}); diff --git a/plugins/splunk-on-call/src/plugin.ts b/plugins/splunk-on-call/src/plugin.ts deleted file mode 100644 index f1fa08bfcc..0000000000 --- a/plugins/splunk-on-call/src/plugin.ts +++ /dev/null @@ -1,66 +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 { splunkOnCallApiRef, SplunkOnCallClient } from './api'; -import { - createApiFactory, - createPlugin, - createRouteRef, - discoveryApiRef, - configApiRef, - createRoutableExtension, - createComponentExtension, -} from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ id: 'splunk-on-call' }); - -/** @public */ -export const splunkOnCallPlugin = createPlugin({ - id: 'splunk-on-call', - apis: [ - createApiFactory({ - api: splunkOnCallApiRef, - deps: { discoveryApi: discoveryApiRef, configApi: configApiRef }, - factory: ({ configApi, discoveryApi }) => - SplunkOnCallClient.fromConfig(configApi, discoveryApi), - }), - ], - routes: { - root: rootRouteRef, - }, -}); - -/** @public */ -export const SplunkOnCallPage = splunkOnCallPlugin.provide( - createRoutableExtension({ - name: 'SplunkOnCallPage', - component: () => - import('./components/SplunkOnCallPage').then(m => m.SplunkOnCallPage), - mountPoint: rootRouteRef, - }), -); - -/** @public */ -export const EntitySplunkOnCallCard = splunkOnCallPlugin.provide( - createComponentExtension({ - name: 'EntitySplunkOnCallCard', - component: { - lazy: () => - import('./components/EntitySplunkOnCallCard').then( - m => m.EntitySplunkOnCallCard, - ), - }, - }), -); diff --git a/plugins/splunk-on-call/src/setupTests.ts b/plugins/splunk-on-call/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/splunk-on-call/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/stack-overflow-backend/.eslintrc.js b/plugins/stack-overflow-backend/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/stack-overflow-backend/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md deleted file mode 100644 index c4e9676dfa..0000000000 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ /dev/null @@ -1,750 +0,0 @@ -# @backstage/plugin-stack-overflow-backend - -## 0.2.14-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.3-next.3 - -## 0.2.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.3-next.2 - -## 0.2.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.3-next.1 - -## 0.2.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.3-next.0 - -## 0.2.13 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2 - -## 0.2.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2-next.2 - -## 0.2.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2-next.1 - -## 0.2.13-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.2-next.0 - -## 0.2.12 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.9 - -## 0.2.12-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/config@1.1.1 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.3 - - @backstage/plugin-search-common@1.2.8 - -## 0.2.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.2 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.8 - -## 0.2.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/config@1.1.1 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.1 - - @backstage/plugin-search-common@1.2.8 - -## 0.2.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.1-next.0 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.8 - -## 0.2.11 - -### Patch Changes - -- b168d7e7ea: Deprecate package in favor of the new `@backstage/plugin-search-backend-module-stack-overflow-collator` module. - - The search collator `requestParams` option is optional now, so its default value is `{ order: 'desc', sort: 'activity', site: 'stackoverflow' }` as defined in the `Try It` section on the [official Stack Overflow API documentation](https://api.stackexchange.com/docs/questions). - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.0 - - @backstage/backend-common@0.19.9 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.8 - -## 0.2.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.2 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.0-next.2 - -## 0.2.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.0-next.1 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.7 - -## 0.2.11-next.0 - -### Patch Changes - -- b168d7e7ea: Deprecate package in favor of the new `@backstage/plugin-search-backend-module-stack-overflow-collator` module. - - The search collator `requestParams` option is optional now, so its default value is `{ order: 'desc', sort: 'activity', site: 'stackoverflow' }` as defined in the `Try It` section on the [official Stack Overflow API documentation](https://api.stackexchange.com/docs/questions). - -- Updated dependencies - - @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.0-next.0 - - @backstage/backend-common@0.19.9-next.0 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.7 - -## 0.2.10 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.7 - -## 0.2.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/config@1.1.1-next.0 - - @backstage/plugin-search-common@1.2.7-next.0 - -## 0.2.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/config@1.1.0 - - @backstage/plugin-search-common@1.2.6 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/plugin-search-common@1.2.6 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/plugin-search-common@1.2.6 - -## 0.2.7-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/plugin-search-common@1.2.6-next.2 - - @backstage/backend-common@0.19.5-next.3 - -## 0.2.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/plugin-search-common@1.2.6-next.1 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/plugin-search-common@1.2.6-next.0 - -## 0.2.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5 - -## 0.2.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.2 - -## 0.2.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5 - -## 0.2.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1-next.0 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5-next.0 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.4 - -## 0.2.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.4-next.0 - -## 0.2.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.4-next.0 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3 - -## 0.2.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/config@1.0.7 - -## 0.2.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3 - -## 0.2.0 - -### Minor Changes - -- 51ff6f9edff: Adding support for v2.3 API and PAT authentication - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3 - -## 0.1.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3-next.0 - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3-next.0 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.2 - -## 0.1.12 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.2 - -## 0.1.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.1.12-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-common@0.18.3-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/plugin-search-common@1.2.2-next.0 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/config@1.0.6 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/config@1.0.6 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/config@1.0.6 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - -## 0.1.9 - -### Patch Changes - -- 06f6a4f0f1: Enable configuration override for StackOverflow backend plugin when instantiating the search indexer. This makes it possible to set different configuration for frontend and backend of the plugin. -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/config@1.0.6 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/plugin-search-common@1.2.1-next.0 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/plugin-search-common@1.2.1-next.0 - -## 0.1.9-next.0 - -### Patch Changes - -- 06f6a4f0f1: Enable configuration override for StackOverflow backend plugin when instantiating the search indexer. This makes it possible to set different configuration for frontend and backend of the plugin. -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/config@1.0.5 - - @backstage/plugin-search-common@1.2.0 - -## 0.1.8 - -### Patch Changes - -- fd0ca6f447: Added option to supply API Access Token. This is required in addition to an API key when trying to access the data for a private Stack Overflow Team. -- Updated dependencies - - @backstage/cli@0.22.0 - - @backstage/plugin-search-common@1.2.0 - - @backstage/config@1.0.5 - -## 0.1.8-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.22.0-next.4 - - @backstage/config@1.0.5-next.1 - - @backstage/plugin-search-common@1.2.0-next.3 - -## 0.1.8-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.21.2-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/plugin-search-common@1.2.0-next.2 - -## 0.1.8-next.2 - -### Patch Changes - -- fd0ca6f447: Added option to supply API Access Token. This is required in addition to an API key when trying to access the data for a private Stack Overflow Team. -- Updated dependencies - - @backstage/cli@0.21.2-next.2 - - @backstage/plugin-search-common@1.2.0-next.2 - - @backstage/config@1.0.5-next.1 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.21.2-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/plugin-search-common@1.1.2-next.1 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.21.2-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/plugin-search-common@1.1.2-next.0 - -## 0.1.7 - -### Patch Changes - -- cbe11d1e23: Tweak README -- a6d779d58a: Remove explicit default visibility at `config.d.ts` files. - - ```ts - /** - * @visibility backend - */ - ``` - -- Updated dependencies - - @backstage/cli@0.21.0 - - @backstage/config@1.0.4 - - @backstage/plugin-search-common@1.1.1 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.21.0-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/plugin-search-common@1.1.1-next.0 - -## 0.1.7-next.0 - -### Patch Changes - -- cbe11d1e23: Tweak README -- a6d779d58a: Remove explicit default visibility at `config.d.ts` files. - - ```ts - /** - * @visibility backend - */ - ``` - -- Updated dependencies - - @backstage/cli@0.21.0-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/plugin-search-common@1.1.1-next.0 - -## 0.1.6 - -### Patch Changes - -- 8006f8a602: In order to improve the debuggability of the search indexing process, messages logged during indexing are now tagged with a `documentType` whose value corresponds to the `type` being indexed. -- Updated dependencies - - @backstage/cli@0.20.0 - - @backstage/plugin-search-common@1.1.0 - - @backstage/config@1.0.3 - -## 0.1.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.20.0-next.2 - - @backstage/plugin-search-common@1.1.0-next.2 - - @backstage/config@1.0.3-next.2 - -## 0.1.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.20.0-next.1 - - @backstage/plugin-search-common@1.1.0-next.1 - - @backstage/config@1.0.3-next.1 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/cli@0.20.0-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/plugin-search-common@1.0.2-next.0 - -## 0.1.5 - -### Patch Changes - -- 79040f73f7: Now requests all questions available using pagination. Default max page is set to 100, with a configurable `maxPage` option on the collator. -- 148568b5c2: Switched to using node-fetch instead of cross-fetch as is standard for our backend packages -- Updated dependencies - - @backstage/cli@0.19.0 - - @backstage/config@1.0.2 - - @backstage/plugin-search-common@1.0.1 - -## 0.1.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/cli@0.19.0-next.3 - -## 0.1.5-next.1 - -### Patch Changes - -- 79040f73f7: Now requests all questions available using pagination. Default max page is set to 100, with a configurable `maxPage` option on the collator. -- 148568b5c2: Switched to using node-fetch instead of cross-fetch as is standard for our backend packages - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@1.0.1-next.0 - -## 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 - -- 52b4f796e3: app-config is now picked up properly. -- Updated dependencies - - @backstage/plugin-search-common@0.3.6-next.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@0.3.5 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@0.3.5-next.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.1 - - @backstage/plugin-search-common@0.3.4 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.1-next.0 - - @backstage/plugin-search-common@0.3.4-next.0 - -## 0.1.0 - -### Minor Changes - -- ac323de4ad: Add stack overflow backend plugin - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@0.3.3 - -## 0.1.0-next.0 - -### Minor Changes - -- ac323de4ad: Add stack overflow backend plugin - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@0.3.3-next.1 diff --git a/plugins/stack-overflow-backend/README.md b/plugins/stack-overflow-backend/README.md deleted file mode 100644 index 8129d36e38..0000000000 --- a/plugins/stack-overflow-backend/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Stack Overflow Backend - -Deprecated, consider using `@backstage/plugin-search-backend-module-stack-overflow-collator` instead. diff --git a/plugins/stack-overflow-backend/api-report.md b/plugins/stack-overflow-backend/api-report.md deleted file mode 100644 index 14dcdf2007..0000000000 --- a/plugins/stack-overflow-backend/api-report.md +++ /dev/null @@ -1,23 +0,0 @@ -## API Report File for "@backstage/plugin-stack-overflow-backend" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { StackOverflowDocument as StackOverflowDocument_2 } from '@backstage/plugin-search-backend-module-stack-overflow-collator'; -import { StackOverflowQuestionsCollatorFactory as StackOverflowQuestionsCollatorFactory_2 } from '@backstage/plugin-search-backend-module-stack-overflow-collator'; -import { StackOverflowQuestionsRequestParams as StackOverflowQuestionsRequestParams_2 } from '@backstage/plugin-search-backend-module-stack-overflow-collator'; - -// @public @deprecated (undocumented) -export type StackOverflowDocument = StackOverflowDocument_2; - -// @public @deprecated (undocumented) -export const StackOverflowQuestionsCollatorFactory: typeof StackOverflowQuestionsCollatorFactory_2; - -// @public @deprecated (undocumented) -export type StackOverflowQuestionsCollatorFactoryOptions = - StackOverflowQuestionsCollatorFactory_2; - -// @public @deprecated (undocumented) -export type StackOverflowQuestionsRequestParams = - StackOverflowQuestionsRequestParams_2; -``` diff --git a/plugins/stack-overflow-backend/catalog-info.yaml b/plugins/stack-overflow-backend/catalog-info.yaml deleted file mode 100644 index 797f2c857f..0000000000 --- a/plugins/stack-overflow-backend/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-stack-overflow-backend - title: '@backstage/plugin-stack-overflow-backend' -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: discoverability-maintainers diff --git a/plugins/stack-overflow-backend/config.d.ts b/plugins/stack-overflow-backend/config.d.ts deleted file mode 100644 index 613a7aa887..0000000000 --- a/plugins/stack-overflow-backend/config.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 { - /** - * Configuration options for the stack overflow plugin - */ - stackoverflow?: { - /** - * The base url of the Stack Overflow API used for the plugin - */ - baseUrl?: string; - - /** - * The API key to authenticate to Stack Overflow API - * @visibility secret - */ - apiKey?: string; - - /** - * The name of the team for a Stack Overflow for Teams account - */ - teamName?: string; - - /** - * The API Access Token to authenticate to Stack Overflow API - * @visibility secret - */ - apiAccessToken?: string; - - /** - * Type representing the request parameters. - */ - requestParams?: { - [key: string]: string | string[] | number; - }; - }; -} diff --git a/plugins/stack-overflow-backend/knip-report.md b/plugins/stack-overflow-backend/knip-report.md deleted file mode 100644 index 01a8246832..0000000000 --- a/plugins/stack-overflow-backend/knip-report.md +++ /dev/null @@ -1,16 +0,0 @@ -# Knip report - -## Unused dependencies (3) - -| Name | Location | Severity | -| :--------- | :----------- | :------- | -| node-fetch | package.json | error | -| winston | package.json | error | -| qs | package.json | error | - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :---------------------------- | :----------- | :------- | -| @backstage/backend-test-utils | package.json | error | - diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json deleted file mode 100644 index 974636e55a..0000000000 --- a/plugins/stack-overflow-backend/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@backstage/plugin-stack-overflow-backend", - "description": "Deprecated, consider using @backstage/plugin-search-backend-module-stack-overflow-collator instead", - "version": "0.2.14-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/stack-overflow-backend" - }, - "keywords": [ - "backstage", - "stack-overflow" - ], - "scripts": { - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/plugin-search-backend-module-stack-overflow-collator": "workspace:^", - "node-fetch": "^2.6.7", - "qs": "^6.9.4", - "winston": "^3.2.1" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/stack-overflow-backend/src/index.ts b/plugins/stack-overflow-backend/src/index.ts deleted file mode 100644 index 5ca1c8d283..0000000000 --- a/plugins/stack-overflow-backend/src/index.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ - -/** - * @packageDocumentation - * Stack Overflow backend plugin - * @deprecated - * Deprecated, consider using `@backstage/plugin-search-backend-module-stack-overflow-collator` instead. - */ - -import { - StackOverflowDocument as _StackOverflowDocument, - StackOverflowQuestionsRequestParams as _StackOverflowQuestionsRequestParams, - StackOverflowQuestionsCollatorFactory as _StackOverflowQuestionsCollatorFactory, - StackOverflowQuestionsCollatorFactoryOptions as _StackOverflowQuestionsCollatorFactoryOptions, -} from '@backstage/plugin-search-backend-module-stack-overflow-collator'; - -/** - * @public - * @deprecated - * Import from `@backstage/plugin-search-backend-module-stack-overflow-collator` instead. - */ -export type StackOverflowDocument = _StackOverflowDocument; - -/** - * @public - * @deprecated - * Import from `@backstage/plugin-search-backend-module-stack-overflow-collator` instead. - */ -export type StackOverflowQuestionsRequestParams = - _StackOverflowQuestionsRequestParams; - -/** - * @public - * @deprecated - * Import from `@backstage/plugin-search-backend-module-stack-overflow-collator` instead. - */ -export type StackOverflowQuestionsCollatorFactoryOptions = - _StackOverflowQuestionsCollatorFactory; - -/** - * @public - * @deprecated - * Import from `@backstage/plugin-search-backend-module-stack-overflow-collator` instead. - */ -export const StackOverflowQuestionsCollatorFactory = - _StackOverflowQuestionsCollatorFactory; diff --git a/plugins/stack-overflow/.eslintrc.js b/plugins/stack-overflow/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/stack-overflow/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md deleted file mode 100644 index 9c07133aab..0000000000 --- a/plugins/stack-overflow/CHANGELOG.md +++ /dev/null @@ -1,1210 +0,0 @@ -# @backstage/plugin-stack-overflow - -## 0.1.25-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-home-react@0.1.8-next.3 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/frontend-plugin-api@0.6.0-next.3 - - @backstage/plugin-search-common@1.2.10 - - @backstage/plugin-search-react@1.7.6-next.3 - -## 0.1.25-next.2 - -### Patch Changes - -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/frontend-plugin-api@0.6.0-next.2 - - @backstage/plugin-search-react@1.7.6-next.2 - - @backstage/plugin-home-react@0.1.8-next.2 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.10 - -## 0.1.25-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.6.0-next.1 - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-search-react@1.7.6-next.1 - - @backstage/plugin-home-react@0.1.8-next.1 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.10 - -## 0.1.25-next.0 - -### Patch Changes - -- c1bc331: Fixes a bug that made the API return questions not related to the tags provided -- Updated dependencies - - @backstage/frontend-plugin-api@0.5.1-next.0 - - @backstage/plugin-home-react@0.1.8-next.0 - - @backstage/core-components@0.13.10 - - @backstage/plugin-search-react@1.7.6-next.0 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-search-common@1.2.10 - -## 0.1.24 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/frontend-plugin-api@0.5.0 - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-home-react@0.1.7 - - @backstage/plugin-search-react@1.7.5 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.10 - -## 0.1.24-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.4.1-next.2 - - @backstage/plugin-home-react@0.1.7-next.2 - - @backstage/plugin-search-react@1.7.5-next.2 - -## 0.1.24-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/frontend-plugin-api@0.4.1-next.1 - - @backstage/plugin-home-react@0.1.7-next.1 - - @backstage/plugin-search-react@1.7.5-next.1 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.9 - -## 0.1.24-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/frontend-plugin-api@0.4.1-next.0 - - @backstage/plugin-home-react@0.1.7-next.0 - - @backstage/plugin-search-react@1.7.5-next.0 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-search-common@1.2.9 - -## 0.1.23 - -### Patch Changes - -- 5814122: Updated `/alpha` exports to fit new naming patterns. -- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/frontend-plugin-api@0.4.0 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/plugin-search-react@1.7.4 - - @backstage/plugin-home-react@0.1.6 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.9 - -## 0.1.23-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.6-next.3 - - @backstage/core-components@0.13.9-next.3 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/frontend-plugin-api@0.4.0-next.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-search-common@1.2.8 - - @backstage/plugin-search-react@1.7.4-next.3 - -## 0.1.23-next.2 - -### Patch Changes - -- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. -- Updated dependencies - - @backstage/frontend-plugin-api@0.4.0-next.2 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-search-react@1.7.4-next.2 - - @backstage/config@1.1.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-home-react@0.1.6-next.2 - - @backstage/plugin-search-common@1.2.8 - -## 0.1.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.4.0-next.1 - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-search-react@1.7.4-next.1 - - @backstage/plugin-home-react@0.1.6-next.1 - - @backstage/config@1.1.1 - - @backstage/theme@0.5.0-next.0 - - @backstage/plugin-search-common@1.2.8 - -## 0.1.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/plugin-search-react@1.7.4-next.0 - - @backstage/plugin-home-react@0.1.6-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/frontend-plugin-api@0.3.1-next.0 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.8 - -## 0.1.22 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- b168d7e7ea: Migrate package to the new Frontend system, the new module is distributed with a `/alpha` subpath. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/frontend-plugin-api@0.3.0 - - @backstage/core-plugin-api@1.8.0 - - @backstage/plugin-search-react@1.7.2 - - @backstage/plugin-home-react@0.1.5 - - @backstage/theme@0.4.4 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.8 - -## 0.1.22-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/frontend-plugin-api@0.3.0-next.2 - - @backstage/plugin-home-react@0.1.5-next.2 - - @backstage/plugin-search-react@1.7.2-next.2 - -## 0.1.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.3.0-next.1 - - @backstage/plugin-search-react@1.7.2-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/config@1.1.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/plugin-home-react@0.1.5-next.1 - - @backstage/plugin-search-common@1.2.7 - -## 0.1.22-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- b168d7e7ea: Migrate package to the new Frontend system, the new module is distributed with a `/alpha` subpath. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/frontend-plugin-api@0.3.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/plugin-search-react@1.7.2-next.0 - - @backstage/plugin-home-react@0.1.5-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.7 - -## 0.1.21 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/plugin-search-react@1.7.1 - - @backstage/plugin-home-react@0.1.4 - - @backstage/theme@0.4.3 - - @backstage/config@1.1.1 - - @backstage/plugin-search-common@1.2.7 - -## 0.1.21-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/plugin-search-react@1.7.1-next.2 - - @backstage/theme@0.4.3-next.0 - - @backstage/config@1.1.1-next.0 - - @backstage/plugin-home-react@0.1.4-next.2 - - @backstage/plugin-search-common@1.2.7-next.0 - -## 0.1.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-search-react@1.7.1-next.1 - - @backstage/plugin-home-react@0.1.4-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/config@1.1.0 - - @backstage/theme@0.4.2 - - @backstage/plugin-search-common@1.2.6 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/config@1.1.0 - - @backstage/plugin-home-react@0.1.4-next.0 - - @backstage/plugin-search-react@1.7.1-next.0 - - @backstage/theme@0.4.2 - - @backstage/plugin-search-common@1.2.6 - -## 0.1.20 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-home-react@0.1.3 - - @backstage/core-components@0.13.5 - - @backstage/config@1.1.0 - - @backstage/core-plugin-api@1.6.0 - - @backstage/plugin-search-common@1.2.6 - - @backstage/plugin-search-react@1.7.0 - - @backstage/theme@0.4.2 - -## 0.1.20-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/plugin-home-react@0.1.3-next.3 - - @backstage/plugin-search-common@1.2.6-next.2 - - @backstage/plugin-search-react@1.7.0-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.1.20-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-home-react@0.1.3-next.2 - - @backstage/config@1.1.0-next.1 - - @backstage/plugin-search-react@1.7.0-next.2 - - @backstage/theme@0.4.1 - - @backstage/plugin-search-common@1.2.6-next.1 - -## 0.1.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/config@1.1.0-next.0 - - @backstage/plugin-search-react@1.7.0-next.1 - - @backstage/plugin-home-react@0.1.3-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-search-common@1.2.6-next.0 - -## 0.1.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.3-next.0 - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/config@1.0.8 - - @backstage/theme@0.4.1 - - @backstage/plugin-search-common@1.2.5 - - @backstage/plugin-search-react@1.6.5-next.0 - -## 0.1.19 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/plugin-home-react@0.1.2 - - @backstage/core-components@0.13.4 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-search-react@1.6.4 - - @backstage/config@1.0.8 - - @backstage/theme@0.4.1 - - @backstage/plugin-search-common@1.2.5 - -## 0.1.19-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/config@1.0.8 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - - @backstage/plugin-home-react@0.1.2-next.0 - - @backstage/plugin-search-common@1.2.5 - - @backstage/plugin-search-react@1.6.4-next.0 - -## 0.1.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.2-next.0 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-search-react@1.6.4-next.0 - - @backstage/config@1.0.8 - - @backstage/theme@0.4.1 - - @backstage/plugin-search-common@1.2.5 - -## 0.1.18 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/core-components@0.13.3 - - @backstage/plugin-home-react@0.1.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5 - - @backstage/plugin-search-react@1.6.3 - -## 0.1.18-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home-react@0.1.1-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.5-next.0 - - @backstage/plugin-search-react@1.6.3-next.2 - -## 0.1.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-search-react@1.6.3-next.1 - - @backstage/plugin-home-react@0.1.1-next.1 - - @backstage/config@1.0.8 - -## 0.1.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/config@1.0.8 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-home-react@0.1.1-next.0 - - @backstage/plugin-search-common@1.2.5-next.0 - - @backstage/plugin-search-react@1.6.3-next.0 - -## 0.1.17 - -### Patch Changes - -- 41e8037a8a6d: Extract new plugin-home-react package and deprecate createCardExtension in plugin-home -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/plugin-search-react@1.6.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-home-react@0.1.0 - - @backstage/config@1.0.8 - - @backstage/plugin-search-common@1.2.4 - -## 0.1.17-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-react@1.6.2-next.3 - - @backstage/core-components@0.13.2-next.3 - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-home-react@0.1.0-next.3 - - @backstage/plugin-search-common@1.2.4-next.0 - -## 0.1.16-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/core-components@0.13.2-next.2 - - @backstage/plugin-home-react@0.1.0-next.2 - - @backstage/plugin-search-react@1.6.1-next.2 - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-react@1.6.1-next.1 - - @backstage/core-components@0.13.2-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/plugin-home-react@0.1.0-next.1 - - @backstage/config@1.0.7 - - @backstage/theme@0.4.0-next.0 - - @backstage/plugin-search-common@1.2.4-next.0 - -## 0.1.16-next.0 - -### Patch Changes - -- 41e8037a8a6d: Extract new plugin-home-react package and deprecate createCardExtension in plugin-home -- Updated dependencies - - @backstage/plugin-home-react@0.1.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/config@1.0.7 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-search-react@1.6.1-next.0 - - @backstage/plugin-search-common@1.2.3 - -## 0.1.15 - -### Patch Changes - -- c1ff65f315a: StackOverflowSearchResultListItem can now accept an empty result prop so that it can be rendered in the suggested SearchResultListItem pattern. -- Updated dependencies - - @backstage/plugin-home@0.5.2 - - @backstage/theme@0.3.0 - - @backstage/plugin-search-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-search-common@1.2.3 - -## 0.1.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home@0.5.2-next.2 - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-search-react@1.6.0-next.2 - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.1 - -## 0.1.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home@0.5.2-next.1 - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-search-react@1.6.0-next.1 - - @backstage/config@1.0.7 - -## 0.1.14-next.0 - -### Patch Changes - -- c1ff65f315a: StackOverflowSearchResultListItem can now accept an empty result prop so that it can be rendered in the suggested SearchResultListItem pattern. -- Updated dependencies - - @backstage/plugin-search-react@1.6.0-next.0 - - @backstage/plugin-home@0.5.1-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/config@1.0.7 - - @backstage/theme@0.2.19 - - @backstage/plugin-search-common@1.2.3 - -## 0.1.13 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-search-react@1.5.2 - - @backstage/plugin-home@0.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3 - -## 0.1.13-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0-next.3 - - @backstage/config@1.0.7 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/plugin-home@0.4.33-next.3 - - @backstage/plugin-search-common@1.2.3-next.0 - - @backstage/plugin-search-react@1.5.2-next.3 - -## 0.1.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/config@1.0.7 - - @backstage/theme@0.2.19-next.0 - - @backstage/plugin-home@0.4.33-next.2 - - @backstage/plugin-search-common@1.2.3-next.0 - - @backstage/plugin-search-react@1.5.2-next.2 - -## 0.1.13-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-search-react@1.5.2-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/plugin-home@0.4.33-next.1 - - @backstage/config@1.0.7 - - @backstage/plugin-search-common@1.2.3-next.0 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-search-react@1.5.2-next.0 - - @backstage/plugin-home@0.4.33-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/config@1.0.7 - - @backstage/theme@0.2.18 - - @backstage/plugin-search-common@1.2.2 - -## 0.1.12 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- 3ef5fb09ca5: Export api ref and StackOverflowApi type -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-search-react@1.5.1 - - @backstage/core-plugin-api@1.5.0 - - @backstage/plugin-home@0.4.32 - - @backstage/config@1.0.7 - - @backstage/theme@0.2.18 - - @backstage/plugin-search-common@1.2.2 - -## 0.1.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-search-react@1.5.1-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - - @backstage/plugin-home@0.4.32-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.1.12-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/plugin-home@0.4.32-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-search-common@1.2.2-next.0 - - @backstage/plugin-search-react@1.5.1-next.1 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/config@1.0.6 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - - @backstage/plugin-home@0.4.32-next.0 - - @backstage/plugin-search-common@1.2.1 - - @backstage/plugin-search-react@1.5.1-next.0 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/plugin-home@0.4.31 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-search-react@1.5.0 - - @backstage/config@1.0.6 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-react@1.5.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/config@1.0.6 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.31-next.2 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home@0.4.31-next.1 - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-search-react@1.5.0-next.0 - - @backstage/config@1.0.6 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home@0.4.31-next.0 - -## 0.1.10 - -### Patch Changes - -- 27a5e90e97: Small updates to some paragraph components to ensure theme typography properties are inherited correctly. -- Updated dependencies - - @backstage/core-components@0.12.3 - - @backstage/plugin-home@0.4.30 - - @backstage/plugin-search-react@1.4.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/config@1.0.6 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.2.1 - -## 0.1.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.30-next.2 - - @backstage/plugin-search-common@1.2.1-next.0 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.6-next.0 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.30-next.1 - - @backstage/plugin-search-common@1.2.1-next.0 - - @backstage/plugin-search-react@1.3.2-next.1 - -## 0.1.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.0 - - @backstage/config@1.0.5 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.30-next.0 - - @backstage/plugin-search-common@1.2.0 - - @backstage/plugin-search-react@1.3.2-next.0 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-home@0.4.29 - - @backstage/plugin-search-react@1.3.1 - -## 0.1.8 - -### Patch Changes - -- a19cffbeed: Update search links to only have header as linkable text -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- c981e83612: The `` component is now able to highlight the result title and/or text when provided. To take advantage of this, pass in the `highlight` prop, similar to how it is done on other result list item components. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/plugin-search-react@1.3.0 - - @backstage/core-components@0.12.1 - - @backstage/plugin-home@0.4.28 - - @backstage/plugin-search-common@1.2.0 - - @backstage/config@1.0.5 - - @backstage/theme@0.2.16 - -## 0.1.8-next.4 - -### Patch Changes - -- c981e83612: The `` component is now able to highlight the result title and/or text when provided. To take advantage of this, pass in the `highlight` prop, similar to how it is done on other result list item components. -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-home@0.4.28-next.4 - - @backstage/plugin-search-react@1.3.0-next.4 - - @backstage/config@1.0.5-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.2.0-next.3 - -## 0.1.8-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.28-next.3 - - @backstage/plugin-search-common@1.2.0-next.2 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-search-common@1.2.0-next.2 - - @backstage/plugin-home@0.4.28-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/theme@0.2.16 - -## 0.1.8-next.1 - -### Patch Changes - -- a19cffbeed: Update search links to only have header as linkable text -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-home@0.4.28-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.1.2-next.1 - -## 0.1.8-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-home@0.4.28-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.1.2-next.0 - -## 0.1.7 - -### Patch Changes - -- e32d5643e3: `StackOverflowSearchResultListItem` now accept optional rank property to be able to capture rank analytics data. -- Updated dependencies - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/plugin-home@0.4.27 - - @backstage/config@1.0.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.1.1 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.27-next.1 - - @backstage/plugin-search-common@1.1.1-next.0 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/plugin-home@0.4.27-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.1.1-next.0 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2 - - @backstage/plugin-search-common@1.1.0 - - @backstage/plugin-home@0.4.26 - - @backstage/core-plugin-api@1.0.7 - - @backstage/config@1.0.3 - - @backstage/theme@0.2.16 - -## 0.1.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@1.1.0-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - - @backstage/plugin-home@0.4.26-next.2 - -## 0.1.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-search-common@1.1.0-next.1 - - @backstage/plugin-home@0.4.26-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/theme@0.2.16 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-home@0.4.26-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-search-common@1.0.2-next.0 - -## 0.1.5 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- b8190af939: Create a front end API. -- a720c44070: Support showing HTML entity references from the API response before rendering the question title to the list component. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-home@0.4.25 - - @backstage/config@1.0.2 - - @backstage/plugin-search-common@1.0.1 - -## 0.1.5-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/plugin-home@0.4.25-next.3 - -## 0.1.5-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- b8190af939: Create a front end API. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - - @backstage/plugin-home@0.4.25-next.2 - -## 0.1.5-next.1 - -### Patch Changes - -- a720c44070: Support showing HTML entity references from the API response before rendering the question title to the list component. -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-home@0.4.25-next.1 - -## 0.1.5-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-home@0.4.25-next.0 - - @backstage/plugin-search-common@1.0.1-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/plugin-home@0.4.23-next.3 - -## 0.1.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-home@0.4.23-next.2 - -## 0.1.3-next.1 - -### Patch Changes - -- 52b4f796e3: app-config is now picked up properly. -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/plugin-home@0.4.23-next.1 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-search-common@0.3.6-next.0 - -## 0.1.3-next.0 - -### Patch Changes - -- 12ae3eed2f: - Publicly exports `StackOverflowIcon`. - - `HomePageStackOverflowQuestions` accepts optional icon property. -- Updated dependencies - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-home@0.4.23-next.0 - -## 0.1.2 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-search-common@0.3.5 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/plugin-home@0.4.22 - -## 0.1.2-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/plugin-home@0.4.22-next.1 - - @backstage/plugin-search-common@0.3.5-next.0 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.0 - - @backstage/plugin-home@0.4.22-next.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-home@0.4.21 - - @backstage/config@1.0.1 - - @backstage/plugin-search-common@0.3.4 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/config@1.0.1-next.0 - - @backstage/plugin-search-common@0.3.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - - @backstage/plugin-home@0.4.21-next.2 - -## 0.1.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-home@0.4.21-next.1 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home@0.4.21-next.0 - -## 0.1.0 - -### Minor Changes - -- ac323de4ad: Add stack overflow plugin - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-home@0.4.20 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - - @backstage/plugin-search-common@0.3.3 - -## 0.1.0-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-home@0.4.20-next.3 - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - -## 0.1.0-next.0 - -### Minor Changes - -- ac323de4ad: Add stack overflow plugin - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-home@0.4.20-next.1 - - @backstage/plugin-search-common@0.3.3-next.1 diff --git a/plugins/stack-overflow/README.md b/plugins/stack-overflow/README.md deleted file mode 100644 index 96a8f524e3..0000000000 --- a/plugins/stack-overflow/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Stack Overflow - -A plugin that provides stack overflow specific functionality that can be used in different ways (e.g. for homepage and search) to compose your Backstage App. - -## Getting started - -Before we begin, make sure: - -- You have created your own standalone Backstage app using @backstage/create-app and not using a fork of the backstage repository. If you haven't setup Backstage already, start [here](https://backstage.io/docs/getting-started/). - -To use any of the functionality this plugin provides, you need to start by configuring your App with the following config: - -```yaml -stackoverflow: - baseUrl: https://api.stackexchange.com/2.2 # alternative: your internal stack overflow instance -``` - -## Areas of Responsibility - -This stack overflow frontend plugin is primarily responsible for the following: - -- Exposing various stack-overflow related components like `` which can be used for composing the search page, and `` which can be used for composing the homepage. - -#### Use specific search result list item for Stack Overflow Question - -> Note: For Stack Overflow specific search results to be returned, it needs to be indexed. Use the [stack-overflow-backend plugin](https://github.com/backstage/backstage/blob/master/plugins/stack-overflow-backend/README.md) to index Stack Overflow Questions to search. - -When you have your `packages/app/src/components/search/SearchPage.tsx` file ready to make modifications, add the following code snippet to add the `StackOverflowSearchResultListItem` when the type of the search results are `stack-overflow`. - -```tsx - case 'stack-overflow': - return ( - - ); -``` - -#### Use Stack Overflow Questions on your homepage - -Before you are able to add the stack overflow question component to your homepage, you need to go through the [homepage getting started guide](https://backstage.io/docs/getting-started/homepage). When its ready, add the following code snippet to your `packages/app/src/components/home/HomePage.tsx` file. - -```tsx - - - -``` diff --git a/plugins/stack-overflow/api-report-alpha.md b/plugins/stack-overflow/api-report-alpha.md deleted file mode 100644 index 167f8e1736..0000000000 --- a/plugins/stack-overflow/api-report-alpha.md +++ /dev/null @@ -1,13 +0,0 @@ -## API Report File for "@backstage/plugin-stack-overflow" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; - -// @alpha (undocumented) -const _default: BackstagePlugin<{}, {}>; -export default _default; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/stack-overflow/api-report.md b/plugins/stack-overflow/api-report.md deleted file mode 100644 index 293c2ac226..0000000000 --- a/plugins/stack-overflow/api-report.md +++ /dev/null @@ -1,69 +0,0 @@ -## API Report File for "@backstage/plugin-stack-overflow" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { CardExtensionProps } from '@backstage/plugin-home-react'; -import { JSX as JSX_2 } from 'react'; -import { default as React_2 } from 'react'; -import { ResultHighlight } from '@backstage/plugin-search-common'; -import { SearchResultListItemExtensionProps } from '@backstage/plugin-search-react'; - -// @public -export const HomePageStackOverflowQuestions: ( - props: CardExtensionProps, -) => JSX_2.Element; - -// @public (undocumented) -export type StackOverflowApi = { - listQuestions(options?: { - requestParams: StackOverflowQuestionsRequestParams; - }): Promise; -}; - -// @public (undocumented) -export const stackOverflowApiRef: ApiRef; - -// @public -export const StackOverflowIcon: () => React_2.JSX.Element; - -// @public -export const stackOverflowPlugin: BackstagePlugin<{}, {}>; - -// @public -export type StackOverflowQuestion = { - title: string; - link: string; - owner: Record; - tags: string[]; - answer_count: number; -}; - -// @public -export type StackOverflowQuestionsContentProps = { - requestParams: StackOverflowQuestionsRequestParams; - icon?: React.ReactNode; -}; - -// @public -export type StackOverflowQuestionsRequestParams = { - [key: string]: string | string[] | number; -}; - -// @public -export const StackOverflowSearchResultListItem: ( - props: SearchResultListItemExtensionProps, -) => JSX.Element | null; - -// @public -export type StackOverflowSearchResultListItemProps = { - result?: any; - icon?: React_2.ReactNode; - rank?: number; - highlight?: ResultHighlight; -}; -``` diff --git a/plugins/stack-overflow/catalog-info.yaml b/plugins/stack-overflow/catalog-info.yaml deleted file mode 100644 index a949dbda3b..0000000000 --- a/plugins/stack-overflow/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-stack-overflow - title: '@backstage/plugin-stack-overflow' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: discoverability-maintainers diff --git a/plugins/stack-overflow/config.d.ts b/plugins/stack-overflow/config.d.ts deleted file mode 100644 index c0638e3c19..0000000000 --- a/plugins/stack-overflow/config.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 { - /** - * Configuration options for the stack overflow plugin - */ - stackoverflow?: { - /** - * The base url of the Stack Overflow API used for the plugin - * @visibility frontend - */ - baseUrl?: string; - }; -} diff --git a/plugins/stack-overflow/knip-report.md b/plugins/stack-overflow/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/stack-overflow/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json deleted file mode 100644 index 0149427e1c..0000000000 --- a/plugins/stack-overflow/package.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "name": "@backstage/plugin-stack-overflow", - "version": "0.1.25-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "exports": { - ".": "./src/index.ts", - "./alpha": "./src/alpha.tsx", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - "alpha": [ - "src/alpha.tsx" - ], - "package.json": [ - "package.json" - ] - } - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/stack-overflow" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/config": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/frontend-plugin-api": "workspace:^", - "@backstage/plugin-home-react": "workspace:^", - "@backstage/plugin-search-common": "workspace:^", - "@backstage/plugin-search-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@testing-library/jest-dom": "^6.0.0", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "cross-fetch": "^4.0.0", - "lodash": "^4.17.21", - "qs": "^6.9.4", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/react": "^14.0.0", - "@testing-library/user-event": "^14.0.0", - "msw": "^1.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/stack-overflow/src/alpha.tsx b/plugins/stack-overflow/src/alpha.tsx deleted file mode 100644 index 689522b114..0000000000 --- a/plugins/stack-overflow/src/alpha.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { configApiRef, createApiFactory } from '@backstage/core-plugin-api'; -import { - createApiExtension, - createPlugin, -} from '@backstage/frontend-plugin-api'; -import { createSearchResultListItemExtension } from '@backstage/plugin-search-react/alpha'; -import { StackOverflowClient, stackOverflowApiRef } from './api'; - -/** @alpha */ -const stackOverflowApi = createApiExtension({ - factory: createApiFactory({ - api: stackOverflowApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => StackOverflowClient.fromConfig(configApi), - }), -}); - -/** @alpha */ -const stackOverflowSearchResultListItem = createSearchResultListItemExtension({ - predicate: result => result.type === 'stack-overflow', - component: () => - import('./search/StackOverflowSearchResultListItem').then( - m => m.StackOverflowSearchResultListItem, - ), -}); - -/** @alpha */ -export default createPlugin({ - id: 'stack-overflow', - // TODO: Migrate homepage cards when the declarative homepage plugin supports them - extensions: [stackOverflowApi, stackOverflowSearchResultListItem], -}); diff --git a/plugins/stack-overflow/src/api/StackOverflowApi.ts b/plugins/stack-overflow/src/api/StackOverflowApi.ts deleted file mode 100644 index d470e879e7..0000000000 --- a/plugins/stack-overflow/src/api/StackOverflowApi.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 { createApiRef } from '@backstage/core-plugin-api'; -import { - StackOverflowQuestion, - StackOverflowQuestionsRequestParams, -} from '../types'; - -/** - * @public - */ -export const stackOverflowApiRef = createApiRef({ - id: 'plugin.stackoverflow.service', -}); - -/** - * @public - */ -export type StackOverflowApi = { - listQuestions(options?: { - requestParams: StackOverflowQuestionsRequestParams; - }): Promise; -}; diff --git a/plugins/stack-overflow/src/api/StackOverflowClient.test.ts b/plugins/stack-overflow/src/api/StackOverflowClient.test.ts deleted file mode 100644 index e5967b6d45..0000000000 --- a/plugins/stack-overflow/src/api/StackOverflowClient.test.ts +++ /dev/null @@ -1,97 +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 { setupRequestMockHandlers } from '@backstage/test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { StackOverflowClient } from './index'; -import { StackOverflowQuestion } from '../types'; -import { ConfigReader } from '@backstage/config'; - -const server = setupServer(); - -const backstageQuestions: StackOverflowQuestion[] = [ - { - title: 'What is it?', - link: 'https://example.com:9191/questions/1', - tags: ['backstage'], - owner: { who: 'me' }, - answer_count: 3, - }, - { - title: 'Is it?', - link: 'https://example.com:9191/questions/2', - tags: ['backstage'], - owner: { who: 'me' }, - answer_count: 4, - }, -]; - -const vimQuestions: StackOverflowQuestion[] = [ - { - title: 'How do I exit vim?', - link: 'https://example.com:9191/questions/3', - tags: ['vim'], - owner: { who: 'me' }, - answer_count: 5, - }, -]; - -const questionMap: Record = { - backstage: backstageQuestions, - vim: vimQuestions, -}; - -describe('StackOverflowClient', () => { - setupRequestMockHandlers(server); - - const mockBaseUrl = 'https://example.com:9191'; - - const setupHandlers = () => { - server.use( - rest.get(`${mockBaseUrl}/questions`, (req, res, ctx) => { - const taggedParam = req.url.searchParams.get('tagged'); - const questions = taggedParam ? questionMap[taggedParam] || [] : []; - - return res(ctx.json({ items: questions })); - }), - ); - }; - - it('list questions should return all questions with the provided tag', async () => { - setupHandlers(); - const client = StackOverflowClient.fromConfig( - new ConfigReader({ - stackoverflow: { - baseUrl: 'https://example.com:9191', - }, - }), - ); - - const bsQuestions = await client.listQuestions({ - requestParams: { tagged: 'backstage' }, - }); - - const vQuestions = await client.listQuestions({ - requestParams: { tagged: 'vim' }, - }); - - expect(bsQuestions.length).toEqual(2); - expect(bsQuestions).toEqual(backstageQuestions); - expect(vQuestions.length).toEqual(1); - expect(vQuestions).toEqual(vimQuestions); - }); -}); diff --git a/plugins/stack-overflow/src/api/StackOverflowClient.ts b/plugins/stack-overflow/src/api/StackOverflowClient.ts deleted file mode 100644 index d2f95c5236..0000000000 --- a/plugins/stack-overflow/src/api/StackOverflowClient.ts +++ /dev/null @@ -1,55 +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 fetch from 'cross-fetch'; -import qs from 'qs'; -import { StackOverflowApi } from './StackOverflowApi'; -import { - StackOverflowQuestion, - StackOverflowQuestionsRequestParams, -} from '../types'; -import { Config } from '@backstage/config'; - -export class StackOverflowClient implements StackOverflowApi { - private baseUrl: string; - - private constructor({ baseUrl }: { baseUrl: string }) { - this.baseUrl = baseUrl; - } - - static fromConfig(config: Config) { - return new StackOverflowClient({ - baseUrl: - config.getOptionalString('stackoverflow.baseUrl') || - 'https://api.stackexchange.com/2.2', - }); - } - - /** - * List questions in the StackOverflow instance - */ - async listQuestions(options: { - requestParams: StackOverflowQuestionsRequestParams; - }): Promise { - const params = qs.stringify(options.requestParams, { - addQueryPrefix: true, - arrayFormat: 'repeat', - }); - const response = await fetch(`${this.baseUrl}/questions${params}`); - const data = await response.json(); - return data.items; - } -} diff --git a/plugins/stack-overflow/src/api/index.ts b/plugins/stack-overflow/src/api/index.ts deleted file mode 100644 index 2d2db5f5cc..0000000000 --- a/plugins/stack-overflow/src/api/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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. - */ - -/** - * An API definition and client for integrating with the StackOverflow Backend - * API - * - * @packageDocumentation - */ - -export * from './StackOverflowApi'; -export * from './StackOverflowClient'; diff --git a/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx b/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx deleted file mode 100644 index 8d8aeccb3b..0000000000 --- a/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 { useApi } from '@backstage/core-plugin-api'; -import { Link } from '@backstage/core-components'; -import { - IconButton, - List, - ListItem, - ListItemText, - ListItemSecondaryAction, - ListItemIcon, -} from '@material-ui/core'; -import Typography from '@material-ui/core/Typography'; -import OpenInNewIcon from '@material-ui/icons/OpenInNew'; -import useAsync from 'react-use/lib/useAsync'; -import _unescape from 'lodash/unescape'; -import React from 'react'; -import { - StackOverflowQuestion, - StackOverflowQuestionsContentProps, -} from '../../types'; -import { stackOverflowApiRef } from '../../api'; - -/** - * A component to display a list of stack overflow questions on the homepage. - * - * @public - */ - -export const Content = (props: StackOverflowQuestionsContentProps) => { - const { requestParams } = props; - const stackOverflowApi = useApi(stackOverflowApiRef); - - const { value, loading, error } = useAsync(async (): Promise< - StackOverflowQuestion[] - > => { - return await stackOverflowApi.listQuestions({ requestParams }); - }, []); - - if (loading) { - return loading...; - } - - if (error || !value || !value.length) { - return could not load questions; - } - - const getSecondaryText = (answer_count: number) => - answer_count > 1 ? `${answer_count} answers` : `${answer_count} answer`; - - return ( - - {value.map(question => ( - - - {props.icon && {props.icon}} - - - - - - - - - ))} - - ); -}; diff --git a/plugins/stack-overflow/src/home/StackOverflowQuestions/StackOverflowQuestions.stories.tsx b/plugins/stack-overflow/src/home/StackOverflowQuestions/StackOverflowQuestions.stories.tsx deleted file mode 100644 index 9f0fd75341..0000000000 --- a/plugins/stack-overflow/src/home/StackOverflowQuestions/StackOverflowQuestions.stories.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 { HomePageStackOverflowQuestions } from '../../plugin'; -import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { configApiRef } from '@backstage/core-plugin-api'; -import { ConfigReader } from '@backstage/config'; -import { Grid } from '@material-ui/core'; -import React, { ComponentType, PropsWithChildren } from 'react'; -import { StackOverflowIcon } from '../../icons'; -import { stackOverflowApiRef } from '../../api'; - -const mockStackOverflowApi = { - listQuestions: async () => [ - { - title: 'Customizing Spotify backstage UI', - link: 'stackoverflow.question/1', - answer_count: 0, - tags: ['backstage'], - owner: { 'some owner': 'name' }, - }, - { - title: 'Customizing Spotify backstage UI', - link: 'stackoverflow.question/1', - answer_count: 0, - tags: ['backstage'], - owner: { 'some owner': 'name' }, - }, - ], -}; - -export default { - title: 'Plugins/Home/Components/StackOverflow', - component: HomePageStackOverflowQuestions, - decorators: [ - (Story: ComponentType>) => - wrapInTestApp( - <> - - - - , - ), - ], -}; - -export const Default = () => { - return ( - - - - ); -}; - -export const WithIcon = () => { - return ( - - } - /> - - ); -}; diff --git a/plugins/stack-overflow/src/home/StackOverflowQuestions/index.ts b/plugins/stack-overflow/src/home/StackOverflowQuestions/index.ts deleted file mode 100644 index 1faa9a2426..0000000000 --- a/plugins/stack-overflow/src/home/StackOverflowQuestions/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 { Content } from './Content'; diff --git a/plugins/stack-overflow/src/icons/StackOverflowIcon.tsx b/plugins/stack-overflow/src/icons/StackOverflowIcon.tsx deleted file mode 100644 index 8befe53177..0000000000 --- a/plugins/stack-overflow/src/icons/StackOverflowIcon.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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'; - -/** - * Stack Overflow Icon - * @public - */ -export const StackOverflowIcon = () => { - return ( - - - - - ); -}; diff --git a/plugins/stack-overflow/src/icons/index.ts b/plugins/stack-overflow/src/icons/index.ts deleted file mode 100644 index 141d87d7b1..0000000000 --- a/plugins/stack-overflow/src/icons/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 './StackOverflowIcon'; diff --git a/plugins/stack-overflow/src/index.ts b/plugins/stack-overflow/src/index.ts deleted file mode 100644 index 11af38f7ab..0000000000 --- a/plugins/stack-overflow/src/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - */ -/** - * Stack Overflow frontend plugin - * - * @packageDocumentation - */ - -export { - stackOverflowPlugin, - StackOverflowSearchResultListItem, - HomePageStackOverflowQuestions, -} from './plugin'; -export { StackOverflowIcon } from './icons'; -export type { - StackOverflowQuestion, - StackOverflowQuestionsContentProps, - StackOverflowQuestionsRequestParams, -} from './types'; -export type { StackOverflowSearchResultListItemProps } from './search/StackOverflowSearchResultListItem'; -export { stackOverflowApiRef } from './api'; -export type { StackOverflowApi } from './api'; diff --git a/plugins/stack-overflow/src/plugin.test.ts b/plugins/stack-overflow/src/plugin.test.ts deleted file mode 100644 index b25cfe01ee..0000000000 --- a/plugins/stack-overflow/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 { stackOverflowPlugin } from './plugin'; - -describe('stack-overflow', () => { - it('should export plugin', () => { - expect(stackOverflowPlugin).toBeDefined(); - }); -}); diff --git a/plugins/stack-overflow/src/plugin.ts b/plugins/stack-overflow/src/plugin.ts deleted file mode 100644 index 017900bc02..0000000000 --- a/plugins/stack-overflow/src/plugin.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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, - createComponentExtension, - createApiFactory, - configApiRef, -} from '@backstage/core-plugin-api'; -import { createCardExtension } from '@backstage/plugin-home-react'; -import { StackOverflowQuestionsContentProps } from './types'; -import { stackOverflowApiRef, StackOverflowClient } from './api'; -import { SearchResultListItemExtensionProps } from '@backstage/plugin-search-react'; -import { StackOverflowSearchResultListItemProps } from './search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem'; - -/** - * The Backstage plugin that holds stack overflow specific components - * - * @public - */ -export const stackOverflowPlugin = createPlugin({ - id: 'stack-overflow', - apis: [ - createApiFactory({ - api: stackOverflowApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => StackOverflowClient.fromConfig(configApi), - }), - ], -}); - -/** - * A component to display a stack overflow search result - * - * @public - */ -export const StackOverflowSearchResultListItem: ( - props: SearchResultListItemExtensionProps, -) => JSX.Element | null = stackOverflowPlugin.provide( - createComponentExtension({ - name: 'StackOverflowResultListItem', - component: { - lazy: () => - import('./search/StackOverflowSearchResultListItem').then( - m => m.StackOverflowSearchResultListItem, - ), - }, - }), -); - -/** - * A component to display a list of stack overflow questions on the homepage. - * - * @public - */ -export const HomePageStackOverflowQuestions = stackOverflowPlugin.provide( - createCardExtension({ - name: 'HomePageStackOverflowQuestions', - title: 'Stack Overflow Questions', - components: () => import('./home/StackOverflowQuestions'), - }), -); diff --git a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.stories.tsx b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.stories.tsx deleted file mode 100644 index 067243d619..0000000000 --- a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.stories.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 { StackOverflowSearchResultListItem } from '../../plugin'; -import { wrapInTestApp } from '@backstage/test-utils'; -import React, { ComponentType, PropsWithChildren } from 'react'; -import { StackOverflowIcon } from '../../icons'; - -export default { - title: 'Plugins/Search/StackOverflowResultListItem', - component: StackOverflowSearchResultListItem, - decorators: [ - (Story: ComponentType>) => wrapInTestApp(), - ], -}; - -export const Default = () => { - return ( - - ); -}; - -export const WithIcon = () => { - return ( - } - /> - ); -}; - -export const WithHighlight = () => { - return ( - } - highlight={{ - fields: { title: 'Customizing Spotify backstage ui' }, - preTag: '', - postTag: '', - }} - /> - ); -}; diff --git a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx deleted file mode 100644 index bd3640a5ec..0000000000 --- a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.test.tsx +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 { - MockAnalyticsApi, - renderInTestApp, - TestApiProvider, -} from '@backstage/test-utils'; -import userEvent from '@testing-library/user-event'; -import { screen } from '@testing-library/react'; -import { StackOverflowSearchResultListItem } from './StackOverflowSearchResultListItem'; -import { analyticsApiRef } from '@backstage/core-plugin-api'; - -describe('', () => { - it('should render without exploding', async () => { - await renderInTestApp( - , - ); - expect( - screen.getByText(/Customizing Spotify backstage UI/i), - ).toBeInTheDocument(); - expect(screen.getByText(/Tag: backstage/i)).toBeInTheDocument(); - expect( - screen.getByText(/Customizing Spotify backstage UI/i).closest('a'), - ).toHaveAttribute('href', 'https://stackoverflow.com/questions/7'); - }); - - it('should capture analytics for rank', async () => { - const analyticsSpy = new MockAnalyticsApi(); - - await renderInTestApp( - - - , - , - ); - - await userEvent.click( - screen.getByText(/Customizing Spotify backstage UI/i), - ); - - expect(analyticsSpy.getEvents()[0]).toMatchObject({ - action: 'discover', - attributes: { to: 'https://stackoverflow.com/questions/7' }, - context: { extension: 'App', pluginId: 'root', routeRef: 'unknown' }, - subject: 'Customizing Spotify backstage UI', - value: 1, - }); - }); - - it('should render highlight', async () => { - await renderInTestApp( - ', - postTag: '', - }} - />, - ); - expect(screen.getByText(/Highlighted Title/i)).toBeInTheDocument(); - expect(screen.getByText(/Highlighted Author/i)).toBeInTheDocument(); - }); -}); diff --git a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx deleted file mode 100644 index 245666deeb..0000000000 --- a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 _unescape from 'lodash/unescape'; -import { Link } from '@backstage/core-components'; -import { - Divider, - ListItem, - ListItemText, - ListItemIcon, - Box, - Chip, -} from '@material-ui/core'; -import { useAnalytics } from '@backstage/core-plugin-api'; -import { ResultHighlight } from '@backstage/plugin-search-common'; -import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; - -/** - * Props for {@link StackOverflowSearchResultListItem} - * - * @public - */ -export type StackOverflowSearchResultListItemProps = { - result?: any; // TODO(emmaindal): type to StackOverflowDocument. - icon?: React.ReactNode; - rank?: number; - highlight?: ResultHighlight; -}; - -export const StackOverflowSearchResultListItem = ( - props: StackOverflowSearchResultListItemProps, -) => { - const { result, highlight } = props; - const analytics = useAnalytics(); - - const handleClick = () => { - analytics.captureEvent('discover', result.title, { - attributes: { to: result.location }, - value: props.rank, - }); - }; - - if (!result) { - return null; - } - - return ( - <> - - {props.icon && {props.icon}} - - - {highlight?.fields?.title ? ( - - ) : ( - _unescape(result.title) - )} - - } - secondary={ - highlight?.fields?.text ? ( - <> - Author:{' '} - - - ) : ( - `Author: ${result.text}` - ) - } - /> - - {result.tags && - result.tags.map((tag: string) => ( - - ))} - - - - - ); -}; diff --git a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/index.ts b/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/index.ts deleted file mode 100644 index 7aeec9e55a..0000000000 --- a/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 { StackOverflowSearchResultListItem } from './StackOverflowSearchResultListItem'; -export type { StackOverflowSearchResultListItemProps } from './StackOverflowSearchResultListItem'; diff --git a/plugins/stack-overflow/src/setupTests.ts b/plugins/stack-overflow/src/setupTests.ts deleted file mode 100644 index 326d2ed212..0000000000 --- a/plugins/stack-overflow/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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'; diff --git a/plugins/stack-overflow/src/types.ts b/plugins/stack-overflow/src/types.ts deleted file mode 100644 index 8f2d8847ec..0000000000 --- a/plugins/stack-overflow/src/types.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ - -/** - * Type representing a stack overflow question - * - * @public - */ -export type StackOverflowQuestion = { - title: string; - link: string; - owner: Record; - tags: string[]; - answer_count: number; -}; - -/** - * Props for HomePageStackOverflowQuestions - * - * @public - */ -export type StackOverflowQuestionsContentProps = { - requestParams: StackOverflowQuestionsRequestParams; - icon?: React.ReactNode; -}; - -/** - * Type representing the request parameters accepted by the HomePageStackOverflowQuestions component - * - * @public - */ -export type StackOverflowQuestionsRequestParams = { - [key: string]: string | string[] | number; -}; diff --git a/plugins/stackstorm/.eslintrc.js b/plugins/stackstorm/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/stackstorm/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/stackstorm/CHANGELOG.md b/plugins/stackstorm/CHANGELOG.md deleted file mode 100644 index e86ddd87bb..0000000000 --- a/plugins/stackstorm/CHANGELOG.md +++ /dev/null @@ -1,482 +0,0 @@ -# @backstage/plugin-stackstorm - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.1.11-next.1 - -### Patch Changes - -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/errors@1.2.3 - -## 0.1.10 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.1.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/errors@1.2.3 - -## 0.1.10-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/errors@1.2.3 - -## 0.1.9-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - -## 0.1.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/errors@1.2.3 - -## 0.1.8 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/errors@1.2.3 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - -## 0.1.8-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.1.7 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - -## 0.1.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - -## 0.1.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.6 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.6-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/theme@0.4.2-next.0 - -## 0.1.6-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.4 - -### Patch Changes - -- 1745959daf98: Add props to StackstormHome for Header Customization -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - -## 0.1.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/errors@1.2.1-next.0 - -## 0.1.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - -## 0.1.4-next.0 - -### Patch Changes - -- 1745959daf98: Add props to StackstormHome for Header Customization -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/errors@1.2.0 - -## 0.1.3-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - -## 0.1.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.1.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/core-components@0.13.1 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.1.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.1.1 - -### Patch Changes - -- 29ba8267d69: Updated dependency `@material-ui/lab` to `4.0.0-alpha.61`. -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.1.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.1.1-next.1 - -### Patch Changes - -- 29ba8267d69: Updated dependency `@material-ui/lab` to `4.0.0-alpha.61`. -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/theme@0.2.19-next.0 - - @backstage/errors@1.1.5 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - -## 0.1.0 - -### Minor Changes - -- f3a15259e91: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - -## 0.1.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.1.0-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - -## 0.1.0-next.0 - -### Minor Changes - -- f3a15259e9: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 diff --git a/plugins/stackstorm/README.md b/plugins/stackstorm/README.md deleted file mode 100644 index 0d5caeaca2..0000000000 --- a/plugins/stackstorm/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# StackStorm Plugin - -Welcome to the StackStorm plugin! - -A Backstage integration for the [StackStorm](https://docs.stackstorm.com/overview.html). -This plugin allows you to display a list of executions, view execution details, -browse installed packs, actions and more. - -## Getting started - -To get started, first you need a running instance of StackStorm. -One of the quickest ways is [running StackStorm with Docker](https://docs.stackstorm.com/install/docker.html). - -### Installation - -1. Install the plugin with `yarn` in the root of your Backstage directory - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-stackstorm -``` - -2. Import and use the plugin in `packages/app/src/App.tsx` - -```tsx -import { StackstormPage } from '@backstage/plugin-stackstorm'; - -const routes = ( - - {/* ...other routes */} - } /> - -``` - -### Configuration - -1. Configure `webUrl` for links to the StackStorm Web UI in `app-config.yaml`. - -```yaml -stackstorm: - webUrl: 'https://your.stackstorm.webui.com' -``` - -2. Configure `stackstorm` proxy - This plugin uses the Backstage proxy to securely communicate with StackStorm API. - Add the following to your `app-config.yaml` to enable this configuration: - -```yaml -proxy: - '/stackstorm': - target: https://your.stackstorm.instance.com/api - headers: - St2-Api-Key: ${ST2_API_KEY} -``` - -In your production deployment of Backstage, you would also need to ensure that -you've set the `ST2_API_KEY` environment variable before starting -the backend. - -Read more about how to find or generate this key in the -[StackStorm Authentication Documentation](https://docs.stackstorm.com/authentication.html#api-keys). diff --git a/plugins/stackstorm/api-report.md b/plugins/stackstorm/api-report.md deleted file mode 100644 index 14f09c3202..0000000000 --- a/plugins/stackstorm/api-report.md +++ /dev/null @@ -1,30 +0,0 @@ -## API Report File for "@backstage/plugin-stackstorm" - -> 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 { JSX as JSX_2 } from 'react'; -import { default as React_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export type StackstormHomeProps = { - title?: string; - subtitle?: string; - headerButtons?: React_2.ReactNode[]; -}; - -// @public -export const StackstormPage: (props: StackstormHomeProps) => JSX_2.Element; - -// @public -export const stackstormPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -``` diff --git a/plugins/stackstorm/catalog-info.yaml b/plugins/stackstorm/catalog-info.yaml deleted file mode 100644 index 1377f8d013..0000000000 --- a/plugins/stackstorm/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-stackstorm - title: '@backstage/plugin-stackstorm' - description: A Backstage plugin that integrates towards StackStorm -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/stackstorm/config.d.ts b/plugins/stackstorm/config.d.ts deleted file mode 100644 index bf7b56823a..0000000000 --- a/plugins/stackstorm/config.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export interface Config { - stackstorm?: { - /** - * StackStorm Web UI url - * Used in links to StackStorm web UI - * @visibility frontend - */ - webUrl: string; - }; -} diff --git a/plugins/stackstorm/dev/index.tsx b/plugins/stackstorm/dev/index.tsx deleted file mode 100644 index 33bd89adda..0000000000 --- a/plugins/stackstorm/dev/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { createDevApp } from '@backstage/dev-utils'; -import { stackstormPlugin, StackstormPage } from '../src/plugin'; - -createDevApp() - .registerPlugin(stackstormPlugin) - .addPage({ - element: , - title: 'Root Page', - path: '/stackstorm', - }) - .render(); diff --git a/plugins/stackstorm/knip-report.md b/plugins/stackstorm/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/stackstorm/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json deleted file mode 100644 index d98b444a15..0000000000 --- a/plugins/stackstorm/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@backstage/plugin-stackstorm", - "description": "A Backstage plugin that integrates towards StackStorm", - "version": "0.1.11-next.2", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/stackstorm" - }, - "keywords": [ - "backstage", - "stackstorm", - "st2" - ], - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "msw": "^1.0.0" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/stackstorm/src/api/StackstormClient.test.ts b/plugins/stackstorm/src/api/StackstormClient.test.ts deleted file mode 100644 index 9757bde2af..0000000000 --- a/plugins/stackstorm/src/api/StackstormClient.test.ts +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; -import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { StackstormClient } from './StackstormClient'; -import { Action, Execution, Pack } from './types'; - -const server = setupServer(); - -const executions: Execution[] = [ - { - id: '63dcac3e18ba00e09e7bb3b6', - action: { - name: 'post_message', - ref: 'chatops.post_message', - description: 'Post a message to stream for chatops', - pack: 'chatops', - runner_type: 'announcement', - id: '62fe101b11935b6aaff4ff92', - }, - status: 'succeeded', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: {}, - parameters: {}, - elapsed_seconds: 2.2, - log: [], - }, - { - id: '63dcac3e18ba00e09e7bb3b6', - action: { - name: 'post_result', - ref: 'chatops.post_result', - description: 'Post an execution result to stream for chatops', - pack: 'chatops', - runner_type: 'orquesta', - id: '62fe101b11935b6aaff4ff93', - }, - status: 'succeeded', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: {}, - parameters: {}, - elapsed_seconds: 18.5, - log: [], - }, - { - id: '63dcac3c9e0b4fe98f46becc', - action: { - name: 'run', - ref: 'shell.run', - description: 'Run shell script', - pack: 'shell', - runner_type: 'shell', - id: '63736caac3d8557c4d61883a', - }, - status: 'failed', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: {}, - parameters: {}, - elapsed_seconds: 5.0, - log: [], - }, -]; - -const executionWithDetails: Execution = { - id: '63dcac3e18ba00e09e7bb3b6', - action: { - name: 'post_message', - ref: 'chatops.post_message', - description: 'Post a message to stream for chatops', - pack: 'chatops', - runner_type: 'announcement', - id: '62fe101b11935b6aaff4ff92', - }, - status: 'succeeded', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: { - output: { - result: 'hello', - }, - }, - parameters: { - var: 'val', - }, - elapsed_seconds: 2.2, - log: [ - { status: 'requested', timestamp: new Date().toISOString() }, - { status: 'succeeded', timestamp: new Date().toISOString() }, - ], -}; - -const packs: Pack[] = [ - { - ref: 'chatops', - description: 'ChatOps integration pack', - version: '3.7.0', - }, - { - ref: 'core', - description: 'Basic core actions.', - version: '3.7.0', - }, -]; - -const actions: Action[] = [ - { - id: '62fe101b11935b6aaff4ff96', - name: 'announcement', - ref: 'core.announcement', - pack: 'core', - description: - 'Action that broadcasts the announcement to all stream consumers.', - runner_type: 'announcement', - }, - { - id: '62fe101b11935b6aaff4ff97', - name: 'echo', - ref: 'core.echo', - pack: 'core', - description: - 'Action that executes the Linux echo command on the localhost.', - runner_type: 'local-shell-cmd', - }, -]; - -describe('StackstormClient', () => { - setupRequestMockHandlers(server); - - const mockBaseUrl = 'http://backstage:9191/api/proxy'; - const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - let client: StackstormClient; - - const setupHandlers = () => { - server.use( - rest.get(`${mockBaseUrl}/stackstorm/executions`, (req, res, ctx) => { - const limit = req.url.searchParams.get('limit') - ? Number(req.url.searchParams.get('limit')) - : executions.length; - const offset = req.url.searchParams.get('offset') - ? Number(req.url.searchParams.get('offset')) - : 0; - return res(ctx.json(executions.slice(offset, offset + limit))); - }), - rest.get( - `${mockBaseUrl}/stackstorm/executions/63dcac3e18ba00e09e7bb3b6`, - (_req, res, ctx) => { - return res(ctx.json(executionWithDetails)); - }, - ), - rest.get(`${mockBaseUrl}/stackstorm/packs`, (_req, res, ctx) => { - return res(ctx.json(packs)); - }), - rest.get(`${mockBaseUrl}/stackstorm/actions`, (req, res, ctx) => { - const name = req.url.searchParams.get('pack'); - return res(ctx.json(name === 'core' ? actions : [])); - }), - ); - }; - - beforeEach(() => { - setupHandlers(); - client = StackstormClient.fromConfig( - new ConfigReader({ - stackstorm: { - webUrl: 'http://stackstorm.example.com:8080', - }, - }), - { - discoveryApi: discoveryApi, - fetchApi: new MockFetchApi(), - }, - ); - }); - - it('getExecutions should return executions with emulated pagination', async () => { - const got = await client.getExecutions(2, 1); - expect(got.length).toEqual(2); - expect(got).toMatchObject(executions.slice(1, 3)); - }); - - it('getExecution should return one execution', async () => { - const got = await client.getExecution('63dcac3e18ba00e09e7bb3b6'); - expect(got).toMatchObject(executionWithDetails); - }); - - it('getPacks should return list of all packs', async () => { - const got = await client.getPacks(); - expect(got.length).toEqual(packs.length); - expect(got).toMatchObject(packs); - }); - - it('getActions should return list of actions', async () => { - const got = await client.getActions('core'); - expect(got).toMatchObject(actions); - }); - - it('getExecutionHistoryUrl should return webUrl for executions', async () => { - const got = client.getExecutionHistoryUrl('123abc'); - expect(got).toEqual('http://stackstorm.example.com:8080/?#/history/123abc'); - }); - - it('getActionUrl should return webUrl for action', async () => { - const got = client.getActionUrl('core.shell'); - expect(got).toEqual( - 'http://stackstorm.example.com:8080/?#/actions/core.shell', - ); - }); -}); diff --git a/plugins/stackstorm/src/api/StackstormClient.ts b/plugins/stackstorm/src/api/StackstormClient.ts deleted file mode 100644 index 495384e8a5..0000000000 --- a/plugins/stackstorm/src/api/StackstormClient.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Action, Execution, Pack, StackstormApi } from './types'; -import { ConfigApi, DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; - -export class StackstormClient implements StackstormApi { - private readonly discoveryApi: DiscoveryApi; - private readonly fetchApi: FetchApi; - private readonly webUrl: string; - - private constructor({ - discoveryApi, - fetchApi, - webUrl, - }: { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - webUrl: string; - }) { - this.discoveryApi = discoveryApi; - this.fetchApi = fetchApi; - this.webUrl = webUrl; - } - - static fromConfig( - config: ConfigApi, - dependencies: { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - }, - ): StackstormClient { - return new StackstormClient({ - discoveryApi: dependencies.discoveryApi, - fetchApi: dependencies.fetchApi, - webUrl: config.getString('stackstorm.webUrl'), - }); - } - - private async get(input: string): Promise { - const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/stackstorm`; - const response = await this.fetchApi.fetch(`${apiUrl}${input}`, { - headers: { - 'Content-Type': 'application/json', - }, - }); - - if (!response.ok) throw await ResponseError.fromResponse(response); - return (await response.json()) as T; - } - - async getExecutions(limit?: number, offset?: number): Promise { - const params = { - limit: limit?.toString() || '10', - offset: offset?.toString() || '0', - include_attributes: - 'id,status,start_timestamp,action.ref,action.name,rule.ref', - parent: 'null', - }; - const path = `/executions?${new URLSearchParams(params)}`; - return this.get(path); - } - - async getExecution(id: string): Promise { - const path = `/executions/${encodeURIComponent(id)}`; - return this.get(path); - } - - async getPacks(): Promise { - return this.get('/packs'); - } - - async getActions(pack: string): Promise { - const params = { - include_attributes: 'id,ref,name,pack,description,runner_type', - pack: pack, - }; - const path = `/actions?${new URLSearchParams(params)}`; - return this.get(path); - } - - getExecutionHistoryUrl(id: string): string { - return `${this.webUrl}/?#/history/${encodeURIComponent(id)}`; - } - - getActionUrl(ref: string): string { - return `${this.webUrl}/?#/actions/${encodeURIComponent(ref)}`; - } -} diff --git a/plugins/stackstorm/src/api/index.ts b/plugins/stackstorm/src/api/index.ts deleted file mode 100644 index 0ce652e27b..0000000000 --- a/plugins/stackstorm/src/api/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { stackstormApiRef } from './types'; -export type { - Action, - Execution, - ExecutionLog, - Pack, - StackstormApi, -} from './types'; -export { StackstormClient } from './StackstormClient'; diff --git a/plugins/stackstorm/src/api/types.ts b/plugins/stackstorm/src/api/types.ts deleted file mode 100644 index 6ebf3d67a6..0000000000 --- a/plugins/stackstorm/src/api/types.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createApiRef } from '@backstage/core-plugin-api'; - -export const stackstormApiRef = createApiRef({ - id: 'plugin.stackstorm.service', -}); - -export type Execution = { - id: string; - action: Action; - status: string; - start_timestamp: string; - end_timestamp: string; - result: object; - parameters: object; - elapsed_seconds: number; - log: ExecutionLog[]; -}; - -export type ExecutionLog = { - status: string; - timestamp: string; -}; - -export type Action = { - id: string; - name: string; - ref: string; - pack: string; - description: string; - runner_type: string; -}; - -export type Pack = { - ref: string; - description: string; - version: string; -}; - -export interface StackstormApi { - getExecutions(limit: number, offset: number): Promise; - getExecution(id: string): Promise; - getPacks(): Promise; - getActions(pack: string): Promise; - getExecutionHistoryUrl(id: string): string; - getActionUrl(ref: string): string; -} diff --git a/plugins/stackstorm/src/components/ActionsList/ActionsList.test.tsx b/plugins/stackstorm/src/components/ActionsList/ActionsList.test.tsx deleted file mode 100644 index 2a65db427a..0000000000 --- a/plugins/stackstorm/src/components/ActionsList/ActionsList.test.tsx +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import React from 'react'; -import { Action, Pack, StackstormApi, stackstormApiRef } from '../../api'; -import { ActionsList, PackListItem } from './ActionsList'; - -const packs: Pack[] = [ - { - ref: 'chatops', - description: 'ChatOps integration pack', - version: '3.7.0', - }, - { - ref: 'core', - description: 'Basic core actions.', - version: '3.7.1', - }, -]; - -const actions: Action[] = [ - { - id: '62fe101b11935b6aaff4ff96', - name: 'announcement', - ref: 'core.announcement', - pack: 'core', - description: - 'Action that broadcasts the announcement to all stream consumers.', - runner_type: 'broadcast', - }, - { - id: '62fe101b11935b6aaff4ff97', - name: 'echo', - ref: 'core.echo', - pack: 'core', - description: - 'Action that executes the Linux echo command on the localhost.', - runner_type: 'local-shell-cmd', - }, -]; - -describe('ActionsList', () => { - const mockApi: jest.Mocked = { - getPacks: jest.fn().mockResolvedValue(packs), - getActions: jest.fn().mockResolvedValue(actions), - getActionUrl: jest - .fn() - .mockResolvedValue( - 'http://stackstorm.example.com:8080/?#/actions/core.action', - ), - } as any; - - it('should render all packs', async () => { - const { getByText } = await renderInTestApp( - - - , - ); - - packs.forEach(p => { - expect(getByText(p.ref)).toBeInTheDocument(); - expect(getByText(p.description)).toBeInTheDocument(); - }); - }); - - it('should render all pack actions', async () => { - const { getByText } = await renderInTestApp( - - {}} /> - , - ); - - actions.forEach(a => { - expect(getByText(a.name)).toBeInTheDocument(); - expect(getByText(a.runner_type)).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx b/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx deleted file mode 100644 index 1080f67373..0000000000 --- a/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React, { useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { Link, Progress, ResponseErrorPanel } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { - List, - ListItemText, - Collapse, - ListItem, - ListItemSecondaryAction, - ListItemIcon, -} from '@material-ui/core'; -import { makeStyles } from '@material-ui/core/styles'; -import ExpandMore from '@material-ui/icons/ExpandMore'; -import ExpandLess from '@material-ui/icons/ExpandLess'; -import { Action, Pack, stackstormApiRef } from '../../api'; - -const useStyles = makeStyles(theme => ({ - root: { - width: '100%', - backgroundColor: theme.palette.background.paper, - }, - actions: { - borderBottom: `2px solid ${theme.palette.divider}`, - }, - nested: { - paddingLeft: theme.spacing(8), - paddingRight: theme.spacing(4), - }, - icon: { - minWidth: '34px', - }, -})); - -type ActionItemsProps = { - pack: Pack; -}; - -export const ActionItems = ({ pack }: ActionItemsProps) => { - const classes = useStyles(); - const st2 = useApi(stackstormApiRef); - - const { value, loading, error } = useAsync(async (): Promise => { - const data = await st2.getActions(pack.ref); - return data; - }, []); - - if (loading) { - return ; - } else if (error) { - return ; - } - - return ( - - {(value || []).map(a => { - return ( - - - {a.runner_type} - - ); - })} - - ); -}; - -type PackListItemProps = { - pack: Pack; - opened: boolean; - onClick: (ref: string) => any; -}; - -export const PackListItem = ({ pack, opened, onClick }: PackListItemProps) => { - const classes = useStyles(); - - return ( - <> - onClick(pack.ref)}> - - {opened ? : } - - - - version: {pack.version} - - - - - - - ); -}; - -export const ActionsList = () => { - const st2 = useApi(stackstormApiRef); - - const classes = useStyles(); - const [expanded, setExpanded] = useState([]); - - const onClick = (ref: string) => { - setExpanded(refs => - refs.includes(ref) ? refs.filter(r => r !== ref) : refs.concat(ref), - ); - }; - - const { value, loading, error } = useAsync(async (): Promise => { - const data = await st2.getPacks(); - return data; - }, []); - - if (loading) { - return ; - } else if (error) { - return ; - } - - return ( - - {(value || []).map(p => { - return ( - - ); - })} - - ); -}; diff --git a/plugins/stackstorm/src/components/ActionsList/index.ts b/plugins/stackstorm/src/components/ActionsList/index.ts deleted file mode 100644 index 1606d1be3d..0000000000 --- a/plugins/stackstorm/src/components/ActionsList/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ActionsList } from './ActionsList'; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx deleted file mode 100644 index 53930d339f..0000000000 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import React from 'react'; -import { Execution, StackstormApi, stackstormApiRef } from '../../api'; -import { ExecutionPanel } from './ExecutionPanel'; - -const execution: Execution = { - id: '63dcac3e18ba00e09e7bb3b6', - action: { - name: 'post_message', - ref: 'chatops.post_message', - description: 'Post a message to stream for chatops', - pack: 'chatops', - runner_type: 'announcement', - id: '62fe101b11935b6aaff4ff92', - }, - status: 'succeeded', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: { - output: { - result: 'hello world!', - }, - }, - parameters: { - var: 'my funky partameter', - }, - elapsed_seconds: 2.2, - log: [ - { status: 'requested', timestamp: new Date().toISOString() }, - { status: 'succeeded', timestamp: new Date().toISOString() }, - ], -}; - -describe('ExecutionPanel', () => { - const mockApi: jest.Mocked = { - getExecution: jest.fn().mockResolvedValue(execution), - getExecutionHistoryUrl: jest - .fn() - .mockResolvedValue( - 'http://stackstorm.example.com:8080/?#/history/63dcac3e18ba00e09e7bb3b6', - ), - } as any; - - it('should render execution details', async () => { - const { getByText } = await renderInTestApp( - - - , - ); - - expect(getByText(execution.id)).toBeInTheDocument(); - expect(getByText(execution.status)).toBeInTheDocument(); - expect(getByText('"hello world!"')).toBeInTheDocument(); - expect(getByText('"my funky partameter"')).toBeInTheDocument(); - }); -}); diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx deleted file mode 100644 index 8a55c31246..0000000000 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { - CodeSnippet, - Progress, - ResponseErrorPanel, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { Execution, stackstormApiRef } from '../../api'; -import useAsync from 'react-use/lib/useAsync'; -import { - Button, - Card, - CardActions, - CardContent, - makeStyles, - Table, - TableBody, - TableCell, - TableRow, - Typography, - withStyles, -} from '@material-ui/core'; -import { Status } from './Status'; - -const useStyles = makeStyles(theme => ({ - table: { - maxWidth: '50%', - flex: 'i', - }, - title: { - paddingTop: theme.spacing(2), - fontSize: 14, - fontWeight: 'bold', - textTransform: 'uppercase', - }, - card: { - borderBottom: `2px solid ${theme.palette.divider}`, - }, -})); - -const THead = withStyles(() => ({ - root: { - paddingLeft: 0, - }, -}))(TableCell); - -const TRow = withStyles(theme => ({ - root: { - '&:nth-of-type(odd)': { - backgroundColor: theme.palette.background.paper, - }, - }, -}))(TableRow); - -const ExecutionCard = ({ e }: { e: Execution }) => { - const st2 = useApi(stackstormApiRef); - const classes = useStyles(); - - return ( - - -
- - - - Name - - {e.action.ref} - - - - Status - - - - - - - - Execution ID - - {e.id} - - - - Started - - {new Date(e.start_timestamp).toUTCString()} - - - - Finished - - {new Date(e.end_timestamp).toUTCString()} - - - - Execution Time - - {Math.round(e.elapsed_seconds)} s - - - - Runner - - {e.action.runner_type} - - -
- - Action Output - - - - Action Input - - - - - - - - ); -}; - -export const ExecutionPanel = ({ id }: { id: string }) => { - const st2 = useApi(stackstormApiRef); - - const { value, loading, error } = useAsync(async (): Promise => { - const data = await st2.getExecution(id); - return data; - }, []); - - if (loading) { - return ; - } else if (error) { - return ; - } - - return ; -}; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx deleted file mode 100644 index 6727f3cc56..0000000000 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import React from 'react'; -import { Execution, StackstormApi, stackstormApiRef } from '../../api'; -import { ExecutionsTable } from './ExecutionsTable'; - -const executions: Execution[] = [ - { - id: '63dcac3e18ba00e09e7bb3b6', - action: { - name: 'post_message', - ref: 'chatops.post_message', - description: 'Post a message to stream for chatops', - pack: 'chatops', - runner_type: 'announcement', - id: '62fe101b11935b6aaff4ff92', - }, - status: 'processing', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: {}, - parameters: {}, - elapsed_seconds: 2.2, - log: [], - }, - { - id: '62fe101b11935b6aaff4ff93', - action: { - name: 'post_result', - ref: 'chatops.post_result', - description: 'Post an execution result to stream for chatops', - pack: 'chatops', - runner_type: 'orquesta', - id: '62fe101b11935b6aaff4ff93', - }, - status: 'succeeded', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: {}, - parameters: {}, - elapsed_seconds: 18.5, - log: [], - }, - { - id: '63dcac3c9e0b4fe98f46becc', - action: { - name: 'run', - ref: 'shell.run', - description: 'Run shell script', - pack: 'shell', - runner_type: 'shell', - id: '63736caac3d8557c4d61883a', - }, - status: 'failed', - start_timestamp: new Date().toISOString(), - end_timestamp: new Date().toISOString(), - result: {}, - parameters: {}, - elapsed_seconds: 5.0, - log: [], - }, -]; - -describe('ExecutionsTable', () => { - const mockApi: jest.Mocked = { - getExecutions: jest.fn().mockResolvedValue(executions), - getExecutionHistoryUrl: jest - .fn() - .mockResolvedValue( - 'http://stackstorm.example.com:8080/?#/history/123abc', - ), - } as any; - - it('should render all executions', async () => { - const { getByText } = await renderInTestApp( - - - , - ); - - executions.forEach(e => { - expect(getByText(e.id)).toBeInTheDocument(); - expect(getByText(e.action.ref)).toBeInTheDocument(); - expect(getByText(e.status)).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx deleted file mode 100644 index f034cb64e8..0000000000 --- a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React, { useState } from 'react'; -import { - Link, - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { Execution, stackstormApiRef } from '../../api'; -import { Status } from './Status'; -import { ExecutionPanel } from './ExecutionPanel'; -import useAsync from 'react-use/lib/useAsync'; - -type DenseTableProps = { - executions: Execution[]; - loading: boolean; - page: number; - pageSize: number; - onPageChange: (page: number) => void; - onRowsPerPageChange: (rows: number) => void; -}; - -export const DenseTable = ({ - executions, - loading, - page, - pageSize, - onPageChange, - onRowsPerPageChange, -}: DenseTableProps) => { - const st2 = useApi(stackstormApiRef); - - const columns: TableColumn[] = [ - { - title: 'Status', - field: 'status', - render: e => , - }, - { - title: 'Time', - field: 'start_timestamp', - render: e => `${new Date(e.start_timestamp).toUTCString()}`, - }, - { title: 'Name', field: 'action.ref' }, - { - title: 'Execution ID', - field: 'id', - render: e => {e.id}, - }, - ]; - - const count = - pageSize > executions.length - ? (page + 1) * pageSize + executions.length - pageSize - : (page + 1) * pageSize + 1; - - return ( - { - return ; - }} - /> - ); -}; - -export const ExecutionsTable = () => { - const st2 = useApi(stackstormApiRef); - const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(10); - - const { value, loading, error } = useAsync(async (): Promise => { - const data = await st2.getExecutions(rowsPerPage, page * rowsPerPage); - return data; - }, [page, rowsPerPage, st2]); - - if (error) { - return ; - } - - return ( - - ); -}; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/Status.tsx b/plugins/stackstorm/src/components/ExecutionsTable/Status.tsx deleted file mode 100644 index 99a94df2c8..0000000000 --- a/plugins/stackstorm/src/components/ExecutionsTable/Status.tsx +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { - StatusOK, - StatusError, - StatusRunning, - StatusWarning, -} from '@backstage/core-components'; -import React from 'react'; - -export const Status = ({ status }: { status: string | undefined }) => { - if (status === undefined) return null; - const st = status.toLocaleLowerCase('en-US'); - switch (status) { - case 'succeeded': - case 'enabled': - case 'complete': - return ( - <> - {st} - - ); - case 'scheduled': - case 'running': - return ( - <> - {st} - - ); - case 'failed': - case 'error': - return ( - <> - {st} - - ); - default: - return ( - <> - {st} - - ); - } -}; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/index.ts b/plugins/stackstorm/src/components/ExecutionsTable/index.ts deleted file mode 100644 index 402d8e557d..0000000000 --- a/plugins/stackstorm/src/components/ExecutionsTable/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { ExecutionsTable } from './ExecutionsTable'; diff --git a/plugins/stackstorm/src/components/PacksTable/PacksTable.test.tsx b/plugins/stackstorm/src/components/PacksTable/PacksTable.test.tsx deleted file mode 100644 index 9de17e2f14..0000000000 --- a/plugins/stackstorm/src/components/PacksTable/PacksTable.test.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import React from 'react'; -import { Pack, StackstormApi, stackstormApiRef } from '../../api'; -import { PacksTable } from './PacksTable'; - -const packs: Pack[] = [ - { - ref: 'chatops', - description: 'ChatOps integration pack', - version: '3.7.0', - }, - { - ref: 'core', - description: 'Basic core actions.', - version: '3.7.1', - }, -]; - -describe('PacksTable', () => { - const mockApi: jest.Mocked = { - getPacks: jest.fn().mockResolvedValue(packs), - } as any; - - it('should render all packs', async () => { - const { getByText } = await renderInTestApp( - - - , - ); - - packs.forEach(p => { - expect(getByText(p.ref)).toBeInTheDocument(); - expect(getByText(p.description)).toBeInTheDocument(); - expect(getByText(p.version)).toBeInTheDocument(); - }); - }); -}); diff --git a/plugins/stackstorm/src/components/PacksTable/PacksTable.tsx b/plugins/stackstorm/src/components/PacksTable/PacksTable.tsx deleted file mode 100644 index 2167200e8e..0000000000 --- a/plugins/stackstorm/src/components/PacksTable/PacksTable.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { - Progress, - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import useAsync from 'react-use/lib/useAsync'; -import { useApi } from '@backstage/core-plugin-api'; -import { Pack, stackstormApiRef } from '../../api'; - -type DenseTableProps = { - packs: Pack[]; -}; - -export const DenseTable = ({ packs }: DenseTableProps) => { - const columns: TableColumn[] = [ - { title: 'Name', field: 'ref' }, - { title: 'Description', field: 'description' }, - { title: 'Version', field: 'version' }, - ]; - - return ( -
- ); -}; - -export const PacksTable = () => { - const st2 = useApi(stackstormApiRef); - - const { value, loading, error } = useAsync(async (): Promise => { - const data = await st2.getPacks(); - return data; - }, []); - - if (loading) { - return ; - } else if (error) { - return ; - } - - return ; -}; diff --git a/plugins/stackstorm/src/components/PacksTable/index.ts b/plugins/stackstorm/src/components/PacksTable/index.ts deleted file mode 100644 index 378e32a5d5..0000000000 --- a/plugins/stackstorm/src/components/PacksTable/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { PacksTable } from './PacksTable'; diff --git a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx deleted file mode 100644 index e3db4c0cac..0000000000 --- a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { StackstormHome } from './StackstormHome'; -import { screen } from '@testing-library/react'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { StackstormApi, stackstormApiRef } from '../../api'; - -describe('StackstormHome', () => { - const mockApi: jest.Mocked = { - getExecutions: jest.fn().mockResolvedValue([]), - getExecution: jest.fn().mockResolvedValue({}), - getPacks: jest.fn().mockResolvedValue([]), - getActions: jest.fn().mockResolvedValue([]), - } as any; - - it('should render', async () => { - await renderInTestApp( - - - , - ); - expect(screen.getByText('Welcome to StackStorm!')).toBeInTheDocument(); - }); - - it('should render props', async () => { - await renderInTestApp( - - Test Header Button]} - /> - , - ); - expect(screen.getByText('Test Title')).toBeInTheDocument(); - expect(screen.getByText('Test Subtitle')).toBeInTheDocument(); - expect(screen.getByText('Test Header Button')).toBeInTheDocument(); - }); -}); diff --git a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx deleted file mode 100644 index 1bb9031815..0000000000 --- a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React, { Fragment } from 'react'; -import { IconButton } from '@material-ui/core'; -import { - Header, - Page, - HeaderLabel, - TabbedLayout, - Content, -} from '@backstage/core-components'; -import LibraryBooks from '@material-ui/icons/LibraryBooks'; -import { ExecutionsTable } from '../ExecutionsTable'; -import { PacksTable } from '../PacksTable/PacksTable'; -import { ActionsList } from '../ActionsList'; - -/** - * @public - */ -export type StackstormHomeProps = { - title?: string; - subtitle?: string; - headerButtons?: React.ReactNode[]; -}; - -export const StackstormHome = (props: StackstormHomeProps) => ( - -
- {props.headerButtons ? ( - props.headerButtons.map((headerButton, idx) => ( - {headerButton} - )) - ) : ( - - - - )} - -
- - - - - - - - - - - - - - - - - -
-); diff --git a/plugins/stackstorm/src/components/StackstormHome/index.ts b/plugins/stackstorm/src/components/StackstormHome/index.ts deleted file mode 100644 index 7809223ede..0000000000 --- a/plugins/stackstorm/src/components/StackstormHome/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { StackstormHome, type StackstormHomeProps } from './StackstormHome'; diff --git a/plugins/stackstorm/src/index.ts b/plugins/stackstorm/src/index.ts deleted file mode 100644 index 6775a000fa..0000000000 --- a/plugins/stackstorm/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * A Backstage plugin that integrates towards StackStorm - * - * @packageDocumentation - */ - -export { stackstormPlugin, StackstormPage } from './plugin'; -export { type StackstormHomeProps } from './components/StackstormHome'; diff --git a/plugins/stackstorm/src/plugin.test.ts b/plugins/stackstorm/src/plugin.test.ts deleted file mode 100644 index 9ef2f438c1..0000000000 --- a/plugins/stackstorm/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { stackstormPlugin } from './plugin'; - -describe('stackstorm', () => { - it('should export plugin', () => { - expect(stackstormPlugin).toBeDefined(); - }); -}); diff --git a/plugins/stackstorm/src/plugin.ts b/plugins/stackstorm/src/plugin.ts deleted file mode 100644 index be4b9c065c..0000000000 --- a/plugins/stackstorm/src/plugin.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - configApiRef, - createApiFactory, - createPlugin, - createRoutableExtension, - discoveryApiRef, - fetchApiRef, -} from '@backstage/core-plugin-api'; -import { stackstormApiRef, StackstormClient } from './api'; -import { rootRouteRef } from './routes'; - -/** - * The Backstage plugin that holds stackstorm specific components - * - * @public - */ -export const stackstormPlugin = createPlugin({ - id: 'stackstorm', - apis: [ - createApiFactory({ - api: stackstormApiRef, - deps: { - configApi: configApiRef, - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - }, - factory: ({ configApi, discoveryApi, fetchApi }) => - StackstormClient.fromConfig(configApi, { - discoveryApi, - fetchApi, - }), - }), - ], - routes: { - root: rootRouteRef, - }, -}); - -/** - * A component to display a stackstorm home page - * - * @public - */ -export const StackstormPage = stackstormPlugin.provide( - createRoutableExtension({ - name: 'StackstormPage', - component: () => - import('./components/StackstormHome').then(m => m.StackstormHome), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/stackstorm/src/routes.ts b/plugins/stackstorm/src/routes.ts deleted file mode 100644 index 90cf7760bc..0000000000 --- a/plugins/stackstorm/src/routes.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'stackstorm', -}); diff --git a/plugins/stackstorm/src/setupTests.ts b/plugins/stackstorm/src/setupTests.ts deleted file mode 100644 index 865308e634..0000000000 --- a/plugins/stackstorm/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import '@testing-library/jest-dom'; diff --git a/plugins/tech-insights-backend-module-jsonfc/.eslintrc.js b/plugins/tech-insights-backend-module-jsonfc/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md deleted file mode 100644 index fce29ba2aa..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ /dev/null @@ -1,1097 +0,0 @@ -# @backstage/plugin-tech-insights-backend-module-jsonfc - -## 0.1.42-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/plugin-tech-insights-node@0.4.16-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.42-next.2 - -### Patch Changes - -- 25cfb76: Add support for the new backend system. - - A new backend module for the tech-insights backend - was added and exported as `default`. - - The module will register the `JsonRulesEngineFactCheckerFactory` - as `FactCheckerFactory`, loading checks from the config. - - You can use it with the new backend system like - - ```ts title="packages/backend/src/index.ts" - backend.add(import('@backstage/plugin-tech-insights-backend-module-jsonfc')); - ``` - -- bc72782: Support loading `TechInsightsJsonRuleCheck` instances from config. - - Uses the check `id` as key. - - Example: - - ```yaml title="app-config.yaml" - techInsights: - factChecker: - checks: - groupOwnerCheck: - type: json-rules-engine - name: Group Owner Check - description: Verifies that a group has been set as the spec.owner for this entity - factIds: - - entityOwnershipFactRetriever - rule: - conditions: - all: - - fact: hasGroupOwner - operator: equal - value: true - ``` - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/plugin-tech-insights-node@0.4.16-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.42-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.16-next.1 - -## 0.1.42-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/plugin-tech-insights-node@0.4.16-next.0 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.41 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/plugin-tech-insights-node@0.4.15 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.41-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.2 - - @backstage/plugin-tech-insights-node@0.4.15-next.2 - -## 0.1.41-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/plugin-tech-insights-node@0.4.15-next.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.41-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/plugin-tech-insights-node@0.4.15-next.0 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.40 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/plugin-tech-insights-node@0.4.14 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.40-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.14-next.3 - -## 0.1.40-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.14-next.2 - -## 0.1.40-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.14-next.1 - -## 0.1.40-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/plugin-tech-insights-node@0.4.14-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.39 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.13 - -## 0.1.39-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.2 - - @backstage/plugin-tech-insights-node@0.4.13-next.2 - -## 0.1.39-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/plugin-tech-insights-node@0.4.13-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.39-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.13-next.0 - -## 0.1.38 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-node@0.4.12 - - @backstage/config@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.38-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/plugin-tech-insights-node@0.4.12-next.2 - - @backstage/config@1.1.1-next.0 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.37-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/plugin-tech-insights-node@0.4.11-next.1 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.1.37-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.11-next.0 - -## 0.1.35 - -### Patch Changes - -- 51b801f743b2: Handle extracting facts from 'not' conditions too -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.9 - -## 0.1.35-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-tech-insights-common@0.2.12-next.0 - - @backstage/backend-common@0.19.5-next.3 - - @backstage/plugin-tech-insights-node@0.4.9-next.3 - -## 0.1.35-next.2 - -### Patch Changes - -- 51b801f743b2: Handle extracting facts from 'not' conditions too -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/plugin-tech-insights-node@0.4.9-next.2 - - @backstage/errors@1.2.1 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.1.35-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/plugin-tech-insights-node@0.4.9-next.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.1.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.8-next.0 - -## 0.1.32 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/plugin-tech-insights-node@0.4.6 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.1.32-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.2 - - @backstage/plugin-tech-insights-node@0.4.6-next.2 - -## 0.1.32-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/plugin-tech-insights-node@0.4.6-next.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.1.32-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.6-next.0 - -## 0.1.31 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/config@1.0.8 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.5 - -## 0.1.31-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/config@1.0.8 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.5-next.0 - -## 0.1.30 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/errors@1.2.0 - - @backstage/plugin-tech-insights-node@0.4.4 - - @backstage/config@1.0.8 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.1.30-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.2.0-next.0 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.4-next.2 - -## 0.1.30-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/errors@1.2.0-next.0 - - @backstage/plugin-tech-insights-node@0.4.4-next.1 - - @backstage/config@1.0.7 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.1.30-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.4-next.0 - -## 0.1.29 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/plugin-tech-insights-node@0.4.3 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.1.29-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/plugin-tech-insights-node@0.4.3-next.1 - - @backstage/config@1.0.7 - -## 0.1.29-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/plugin-tech-insights-node@0.4.3-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.1.28 - -### Patch Changes - -- 9cb1db6546a: When multiple fact retrievers are used for a check, allow for cases where only one returns a given fact -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/plugin-tech-insights-node@0.4.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.1.28-next.2 - -### Patch Changes - -- 9cb1db6546a: When multiple fact retrievers are used for a check, allow for cases where only one returns a given fact -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.2 - -## 0.1.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.1 - -## 0.1.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.0 - -## 0.1.27 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- Updated dependencies - - @backstage/backend-common@0.18.3 - - @backstage/errors@1.1.5 - - @backstage/config@1.0.7 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.1 - -## 0.1.27-next.2 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/plugin-tech-insights-node@0.4.1-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.1.27-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/backend-common@0.18.3-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.1-next.1 - -## 0.1.27-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.1-next.0 - -## 0.1.26 - -### Patch Changes - -- d6b912f963: Surface the cause of the json rules engine -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.26-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - - @backstage/plugin-tech-insights-node@0.4.0-next.2 - -## 0.1.26-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - - @backstage/plugin-tech-insights-node@0.4.0-next.1 - - @backstage/backend-common@0.18.2-next.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.1.26-next.0 - -### Patch Changes - -- d6b912f963: Surface the cause of the json rules engine -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - - @backstage/plugin-tech-insights-node@0.3.10-next.0 - -## 0.1.24 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.8 - -## 0.1.24-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/plugin-tech-insights-node@0.3.8-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.1.24-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.8-next.0 - -## 0.1.23 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/errors@1.1.4 - - @backstage/config@1.0.5 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.7 - -## 0.1.23-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - - @backstage/plugin-tech-insights-node@0.3.7-next.3 - -## 0.1.23-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/plugin-tech-insights-node@0.3.7-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.1.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/plugin-tech-insights-node@0.3.7-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.1.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/plugin-tech-insights-common@0.2.9-next.0 - - @backstage/plugin-tech-insights-node@0.3.7-next.0 - -## 0.1.22 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/plugin-tech-insights-node@0.3.6 - - @backstage/config@1.0.4 - - @backstage/errors@1.1.3 - - @backstage/plugin-tech-insights-common@0.2.8 - -## 0.1.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/plugin-tech-insights-node@0.3.6-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.1.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/plugin-tech-insights-node@0.3.6-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/plugin-tech-insights-node@0.3.5 - - @backstage/config@1.0.3 - - @backstage/errors@1.1.2 - - @backstage/plugin-tech-insights-common@0.2.7 - -## 0.1.21-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.2 - - @backstage/plugin-tech-insights-node@0.3.5-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/plugin-tech-insights-common@0.2.7-next.2 - -## 0.1.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.7-next.1 - - @backstage/plugin-tech-insights-node@0.3.5-next.1 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-tech-insights-node@0.3.5-next.0 - - @backstage/backend-common@0.15.2-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.0 - -## 0.1.20 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/plugin-tech-insights-node@0.3.4 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - -## 0.1.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/backend-common@0.15.1-next.3 - - @backstage/plugin-tech-insights-node@0.3.4-next.1 - -## 0.1.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - - @backstage/plugin-tech-insights-node@0.3.4-next.0 - -## 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 - -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.3 - - @backstage/plugin-tech-insights-common@0.2.5-next.0 - - @backstage/plugin-tech-insights-node@0.3.2-next.1 - -## 0.1.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.1 - - @backstage/errors@1.1.0-next.0 - -## 0.1.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - - @backstage/plugin-tech-insights-node@0.3.2-next.0 - -## 0.1.17 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0 - - @backstage/plugin-tech-insights-node@0.3.1 - -## 0.1.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - - @backstage/plugin-tech-insights-node@0.3.1-next.1 - -## 0.1.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.6-next.0 - - @backstage/plugin-tech-insights-node@0.3.1-next.0 - -## 0.1.16 - -### Patch Changes - -- 58e2c46151: Updated usages of `buildTechInsightsContext` in README. -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/plugin-tech-insights-node@0.3.0 - - @backstage/config@1.0.1 - -## 0.1.16-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/config@1.0.1-next.0 - - @backstage/plugin-tech-insights-node@0.3.0-next.2 - -## 0.1.16-next.1 - -### Patch Changes - -- 58e2c46151: Updated usages of `buildTechInsightsContext` in README. -- Updated dependencies - - @backstage/backend-common@0.13.3-next.1 - - @backstage/plugin-tech-insights-node@0.3.0-next.1 - -## 0.1.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - - @backstage/plugin-tech-insights-node@0.2.10-next.0 - -## 0.1.15 - -### Patch Changes - -- e0a51384ac: build(deps): bump `ajv` from 7.0.3 to 8.10.0 -- ab008a0988: Removes node-cron from tech-insights to utilize backend-tasks -- Updated dependencies - - @backstage/plugin-tech-insights-node@0.2.9 - - @backstage/backend-common@0.13.2 - -## 0.1.15-next.1 - -### Patch Changes - -- ab008a0988: Removes node-cron from tech-insights to utilize backend-tasks -- Updated dependencies - - @backstage/plugin-tech-insights-node@0.2.9-next.1 - - @backstage/backend-common@0.13.2-next.1 - -## 0.1.15-next.0 - -### Patch Changes - -- e0a51384ac: build(deps): bump `ajv` from 7.0.3 to 8.10.0 -- Updated dependencies - - @backstage/backend-common@0.13.2-next.0 - - @backstage/plugin-tech-insights-node@0.2.9-next.0 - -## 0.1.14 - -### Patch Changes - -- 89c7e47967: Minor README update -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/config@1.0.0 - - @backstage/errors@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.4 - - @backstage/plugin-tech-insights-node@0.2.8 - -## 0.1.13 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0 - - @backstage/plugin-tech-insights-node@0.2.7 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 - - @backstage/plugin-tech-insights-node@0.2.7-next.0 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.12.0 - - @backstage/plugin-tech-insights-node@0.2.6 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.11.0 - - @backstage/plugin-tech-insights-node@0.2.5 - -## 0.1.10 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/backend-common@0.10.9 - - @backstage/config@0.1.15 - - @backstage/errors@0.2.2 - - @backstage/plugin-tech-insights-common@0.2.3 - - @backstage/plugin-tech-insights-node@0.2.4 - -## 0.1.9 - -### Patch Changes - -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/backend-common@0.10.8 - - @backstage/errors@0.2.1 - - @backstage/config@0.1.14 - - @backstage/plugin-tech-insights-common@0.2.2 - - @backstage/plugin-tech-insights-node@0.2.3 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7 - - @backstage/plugin-tech-insights-node@0.2.2 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7-next.0 - - @backstage/plugin-tech-insights-node@0.2.2-next.0 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6 - - @backstage/plugin-tech-insights-node@0.2.1 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6-next.0 - - @backstage/plugin-tech-insights-node@0.2.1-next.0 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4 - - @backstage/config@0.1.13 - - @backstage/plugin-tech-insights-node@0.2.0 - -## 0.1.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4-next.0 - - @backstage/config@0.1.13-next.0 - - @backstage/plugin-tech-insights-node@0.2.0-next.0 - -## 0.1.5 - -### Patch Changes - -- a60eb0f0dd: adding new operation to run checks for multiple entities in one request -- Updated dependencies - - @backstage/config@0.1.12 - - @backstage/backend-common@0.10.3 - - @backstage/plugin-tech-insights-common@0.2.1 - - @backstage/errors@0.2.0 - -## 0.1.4 - -### Patch Changes - -- 8d00dc427c: ability to add custom operators -- Updated dependencies - - @backstage/backend-common@0.10.1 - -## 0.1.3 - -### Patch Changes - -- 6ff4408fa6: RunChecks endpoint now handles missing retriever data in checks. Instead of - showing server errors, the checks will be shown for checks whose retrievers have - data, and a warning will be shown if no checks are returned. -- Updated dependencies - - @backstage/backend-common@0.10.0 - - @backstage/plugin-tech-insights-node@0.1.2 - -## 0.1.2 - -### Patch Changes - -- c6c8b8e53e: Minor fixes in Readme to make the examples more directly usable. -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.0 - - @backstage/backend-common@0.9.12 - - @backstage/plugin-tech-insights-node@0.1.1 - -## 0.1.1 - -### Patch Changes - -- 2017de90da: Update README docs to use correct function/parameter names -- Updated dependencies - - @backstage/errors@0.1.5 - - @backstage/backend-common@0.9.11 diff --git a/plugins/tech-insights-backend-module-jsonfc/README.md b/plugins/tech-insights-backend-module-jsonfc/README.md deleted file mode 100644 index 33b3ad7718..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/README.md +++ /dev/null @@ -1,155 +0,0 @@ -# Tech Insights Backend JSON Rules engine fact checker module - -This is an extension to module to tech-insights-backend plugin, which provides basic framework and functionality to implement tech insights within Backstage. - -This module provides functionality to run checks against a [json-rules-engine](https://github.com/CacheControl/json-rules-engine) and provide boolean logic by simply building checks using JSON conditions. - -## Getting started - -To add this FactChecker into your Tech Insights you need to install the module into your backend application: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-tech-insights-backend-module-jsonfc -``` - -### Add to the backend - -```ts title="packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-tech-insights-backend-module-jsonfc')); -``` - -This setup requires checks to be provided using the config. - -### Add to the backend (old) - -Modify the `techInsights.ts` file to contain a reference to the FactCheckers implementation. - -```diff -+import { JsonRulesEngineFactCheckerFactory } from '@backstage/plugin-tech-insights-backend-module-jsonfc'; - -+const myFactCheckerFactory = new JsonRulesEngineFactCheckerFactory({ -+ checks: [], -+ logger: env.logger, -+}), - - const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - factRetrievers: [myFactRetrieverRegistration], -+ factCheckerFactory: myFactCheckerFactory - }); -``` - -By default, this implementation comes with an in-memory storage to store checks. You can inject an additional data store by adding an implementation of `TechInsightCheckRegistry` into the constructor options when creating a `JsonRulesEngineFactCheckerFactory`. That can be done as follows - -```diff - const myTechInsightCheckRegistry: TechInsightCheckRegistry = // snip - const myFactCheckerFactory = new JsonRulesEngineFactCheckerFactory({ - checks: [], - logger: env.logger, -+ checkRegistry: myTechInsightCheckRegistry - }), - -``` - -## Adding checks in code - -Checks for this FactChecker are constructed as [`json-rules-engine` compatible JSON rules](https://github.com/CacheControl/json-rules-engine/blob/master/docs/rules.md#conditions). A check could look like the following for example: - -```ts -import { - JSON_RULE_ENGINE_CHECK_TYPE, - TechInsightJsonRuleCheck, -} from '@backstage/plugin-tech-insights-backend-module-jsonfc'; - -export const exampleCheck: TechInsightJsonRuleCheck = { - id: 'demodatacheck', // Unique identifier of this check - name: 'demodatacheck', // A human readable name of this check to be displayed in the UI - type: JSON_RULE_ENGINE_CHECK_TYPE, // Type identifier of the check. Used to run logic against, determine persistence option to use and render correct components on the UI - description: 'A fact check for demoing purposes', // A description to be displayed in the UI - factIds: ['documentation-number-factretriever'], // References to fact ids that this check uses. See documentation on FactRetrievers for more information on these - rule: { - // The actual rule - conditions: { - all: [ - // 2 options are available, all and any conditions. - { - fact: 'examplenumberfact', // Reference to an individual fact to check against - operator: 'greaterThanInclusive', // Operator to use. See: https://github.com/CacheControl/json-rules-engine/blob/master/docs/rules.md#operators for more - value: 2, // The threshold value that the fact must satisfy - }, - ], - }, - }, - successMetadata: { - // Additional metadata to be returned if the check has passed - link: 'https://link.to.some.information.com', - }, - failureMetadata: { - // Additional metadata to be returned if the check has failed - link: 'https://sonar.mysonarqube.com/increasing-number-value', - }, -}; -``` - -## Adding checks in config - -Example: - -```yaml title="app-config.yaml" -techInsights: - factChecker: - checks: - groupOwnerCheck: - type: json-rules-engine - name: Group Owner Check - description: Verifies that a group has been set as the spec.owner for this entity - factIds: - - entityOwnershipFactRetriever - rule: - conditions: - all: - - fact: hasGroupOwner - operator: equal - value: true -``` - -### More than one `factIds` for a check. - -When more than one is supplied, the requested fact **MUST** be present in at least one of the fact retrievers. -The order of the fact retrievers defined in the `factIds` array has no bearing on the checks, the check will merge all facts from the various retrievers, and then check against latest fact . - -# Custom operators - -json-rules-engine supports a limited [number of built-in operators](https://github.com/CacheControl/json-rules-engine/blob/master/docs/rules.md#operators) that can be used in conditions. You can add your own operators by adding them to the `operators` array in the `JsonRulesEngineFactCheckerFactory` constructor. For example: - -```diff -+ import { Operator } from 'json-rules-engine'; - -const myFactCheckerFactory = new JsonRulesEngineFactCheckerFactory({ - checks: [], - logger: env.logger, -+ operators: [ new Operator("startsWith", (a, b) => a.startsWith(b) ] -}) -``` - -And you can then use it in your checks like this: - -```js -... -rule: { - conditions: { - any: [ - { - fact: 'version', - operator: 'startsWith', - value: '12', - }, - ], - }, -} -``` diff --git a/plugins/tech-insights-backend-module-jsonfc/api-report.md b/plugins/tech-insights-backend-module-jsonfc/api-report.md deleted file mode 100644 index 790aa0b666..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/api-report.md +++ /dev/null @@ -1,119 +0,0 @@ -## API Report File for "@backstage/plugin-tech-insights-backend-module-jsonfc" - -> 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 { BooleanCheckResult } from '@backstage/plugin-tech-insights-common'; -import { CheckResponse } from '@backstage/plugin-tech-insights-common'; -import { CheckValidationResponse } from '@backstage/plugin-tech-insights-node'; -import { Config } from '@backstage/config'; -import { FactChecker } from '@backstage/plugin-tech-insights-node'; -import { Logger } from 'winston'; -import { Operator } from 'json-rules-engine'; -import { TechInsightCheck } from '@backstage/plugin-tech-insights-node'; -import { TechInsightCheckRegistry } from '@backstage/plugin-tech-insights-node'; -import { TechInsightsStore } from '@backstage/plugin-tech-insights-node'; -import { TopLevelCondition } from 'json-rules-engine'; - -// @public (undocumented) -export type CheckCondition = { - operator: string; - fact: string; - factValue: any; - factResult: any; - result: boolean; -}; - -// @public (undocumented) -export const JSON_RULE_ENGINE_CHECK_TYPE = 'json-rules-engine'; - -// @public (undocumented) -export interface JsonRuleBooleanCheckResult extends BooleanCheckResult { - // (undocumented) - check: JsonRuleCheckResponse; -} - -// @public (undocumented) -export interface JsonRuleCheckResponse extends CheckResponse { - // (undocumented) - rule: { - conditions: ResponseTopLevelCondition & { - priority: number; - }; - }; -} - -// @public -export class JsonRulesEngineFactChecker - implements FactChecker -{ - constructor(options: JsonRulesEngineFactCheckerOptions); - // (undocumented) - getChecks(): Promise; - // (undocumented) - runChecks( - entity: string, - checks?: string[], - ): Promise; - // (undocumented) - validate(check: TechInsightJsonRuleCheck): Promise; -} - -// @public -export class JsonRulesEngineFactCheckerFactory { - constructor(options: JsonRulesEngineFactCheckerFactoryOptions); - // (undocumented) - construct(repository: TechInsightsStore): JsonRulesEngineFactChecker; - // (undocumented) - static fromConfig( - config: Config, - options: Omit, - ): JsonRulesEngineFactCheckerFactory; -} - -// @public -export type JsonRulesEngineFactCheckerFactoryOptions = { - checks: TechInsightJsonRuleCheck[]; - logger: Logger; - checkRegistry?: TechInsightCheckRegistry; - operators?: Operator[]; -}; - -// @public -export type JsonRulesEngineFactCheckerOptions = { - checks: TechInsightJsonRuleCheck[]; - repository: TechInsightsStore; - logger: Logger; - checkRegistry?: TechInsightCheckRegistry; - operators?: Operator[]; -}; - -// @public (undocumented) -export type ResponseTopLevelCondition = - | { - all: CheckCondition[]; - } - | { - any: CheckCondition[]; - }; - -// @public (undocumented) -export type Rule = { - conditions: TopLevelCondition; - name?: string; - priority?: number; -}; - -// @public (undocumented) -export interface TechInsightJsonRuleCheck extends TechInsightCheck { - // (undocumented) - rule: Rule; -} - -// @public -const techInsightsModuleJsonRulesEngineFactCheckerFactory: () => BackendFeature; -export default techInsightsModuleJsonRulesEngineFactCheckerFactory; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/tech-insights-backend-module-jsonfc/catalog-info.yaml b/plugins/tech-insights-backend-module-jsonfc/catalog-info.yaml deleted file mode 100644 index 38d99d940a..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-tech-insights-backend-module-jsonfc - title: '@backstage/plugin-tech-insights-backend-module-jsonfc' -spec: - lifecycle: experimental - type: backstage-backend-plugin-module - owner: xantier diff --git a/plugins/tech-insights-backend-module-jsonfc/config.json b/plugins/tech-insights-backend-module-jsonfc/config.json deleted file mode 100644 index b95b5e52bb..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/config.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "$schema": "https://backstage.io/schema/config-v1", - "type": "object", - "properties": { - "techInsights": { - "type": "object", - "properties": { - "factChecker": { - "type": "object", - "properties": { - "checks": { - "type": "object", - "additionalProperties": { - "$ref": "#/$defs/check" - } - } - } - } - } - } - }, - "$defs": { - "check": { - "type": "object", - "required": ["type", "name", "description", "factIds", "rule"], - "properties": { - "type": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "factIds": { - "type": "array", - "items": { - "type": "string" - } - }, - "rule": { - "$ref": "#/$defs/rule" - } - } - }, - "conditionProperties": { - "type": "object", - "required": ["fact", "operator", "value"], - "properties": { - "fact": { - "type": "string" - }, - "operator": { - "type": "string" - }, - "value": { - "oneOf": [ - { - "type": "object", - "required": ["fact"], - "properties": { - "fact": { - "type": "string" - } - } - }, - {} - ] - }, - "path": { - "type": "string" - }, - "name": { - "type": "string" - }, - "priority": { - "type": "number" - }, - "params": { - "type": "object", - "additionalProperties": true - } - } - }, - "conditionReference": { - "type": "object", - "required": ["condition"], - "properties": { - "condition": { - "type": "string" - }, - "name": { - "type": "string" - }, - "priority": { - "type": "number" - } - } - }, - "nestedCondition": { - "oneOf": [ - { - "$ref": "#/$defs/conditionProperties" - }, - { - "$ref": "#/$defs/topLevelCondition" - } - ] - }, - "rule": { - "type": "string", - "required": ["conditions"], - "properties": { - "conditions": { - "$ref": "#/$defs/topLevelCondition" - }, - "name": { - "type": "string" - }, - "priority": { - "type": "number" - }, - "successMetadata": { - "type": "object", - "additionalProperties": true - }, - "failureMetadata": { - "type": "object", - "additionalProperties": true - } - } - }, - "topLevelCondition": { - "oneOf": [ - { - "type": "object", - "required": ["all"], - "properties": { - "all": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/$defs/nestedCondition" - } - ] - } - } - } - }, - { - "type": "object", - "required": ["any"], - "properties": { - "any": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/$defs/nestedCondition" - } - ] - } - } - } - }, - { - "type": "object", - "required": ["not"], - "properties": { - "not": { - "$ref": "#/$defs/nestedCondition" - } - } - }, - { - "$ref": "#/$defs/conditionReference" - } - ] - } - } -} diff --git a/plugins/tech-insights-backend-module-jsonfc/knip-report.md b/plugins/tech-insights-backend-module-jsonfc/knip-report.md deleted file mode 100644 index 05aec4cd27..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused dependencies (2) - -| Name | Location | Severity | -| :--------------- | :----------- | :------- | -| @backstage/types | package.json | error | -| luxon | package.json | error | - diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json deleted file mode 100644 index c545a7f32c..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.42-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "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/tech-insights-backend-module-jsonfc" - }, - "keywords": [ - "backstage", - "tech-insights", - "scorecard" - ], - "scripts": { - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-tech-insights-common": "workspace:^", - "@backstage/plugin-tech-insights-node": "workspace:^", - "@backstage/types": "workspace:^", - "ajv": "^8.10.0", - "json-rules-engine": "^6.1.2", - "lodash": "^4.17.21", - "luxon": "^3.0.0", - "winston": "^3.2.1" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^" - }, - "files": [ - "config.json", - "dist" - ], - "configSchema": "config.json" -} diff --git a/plugins/tech-insights-backend-module-jsonfc/src/constants.ts b/plugins/tech-insights-backend-module-jsonfc/src/constants.ts deleted file mode 100644 index 5fd69a3fef..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/constants.ts +++ /dev/null @@ -1,20 +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. - */ - -/** - * @public - */ -export const JSON_RULE_ENGINE_CHECK_TYPE = 'json-rules-engine'; diff --git a/plugins/tech-insights-backend-module-jsonfc/src/index.ts b/plugins/tech-insights-backend-module-jsonfc/src/index.ts deleted file mode 100644 index 1c1e8ab77d..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/index.ts +++ /dev/null @@ -1,27 +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. - */ - -export { JSON_RULE_ENGINE_CHECK_TYPE } from './constants'; -export { techInsightsModuleJsonRulesEngineFactCheckerFactory as default } from './module'; -export * from './service'; -export type { - JsonRuleCheckResponse, - JsonRuleBooleanCheckResult, - TechInsightJsonRuleCheck, - ResponseTopLevelCondition, - Rule, - CheckCondition, -} from './types'; diff --git a/plugins/tech-insights-backend-module-jsonfc/src/module/index.ts b/plugins/tech-insights-backend-module-jsonfc/src/module/index.ts deleted file mode 100644 index 0fa167e883..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/module/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './techInsightsModuleJsonRulesEngineFactCheckerFactory'; diff --git a/plugins/tech-insights-backend-module-jsonfc/src/module/techInsightsModuleJsonRulesEngineFactCheckerFactory.test.ts b/plugins/tech-insights-backend-module-jsonfc/src/module/techInsightsModuleJsonRulesEngineFactCheckerFactory.test.ts deleted file mode 100644 index b6df48a8b2..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/module/techInsightsModuleJsonRulesEngineFactCheckerFactory.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; -import { techInsightsFactCheckerFactoryExtensionPoint } from '@backstage/plugin-tech-insights-node'; -import { JSON_RULE_ENGINE_CHECK_TYPE } from '../constants'; -import { techInsightsModuleJsonRulesEngineFactCheckerFactory } from './techInsightsModuleJsonRulesEngineFactCheckerFactory'; - -describe('techInsightsModuleJsonRulesEngineFactCheckerFactory', () => { - it('should register the factory', async () => { - const extensionPoint = { - setFactCheckerFactory: jest.fn(), - } satisfies Partial; - - await startTestBackend({ - extensionPoints: [ - [techInsightsFactCheckerFactoryExtensionPoint, extensionPoint], - ], - features: [ - techInsightsModuleJsonRulesEngineFactCheckerFactory(), - mockServices.logger.factory(), - mockServices.rootConfig.factory({ - data: { - techInsights: { - factChecker: { - checks: { - groupOwnerCheck: { - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'Group Owner Check', - description: - 'Verifies that a group has been set as the spec.owner for this entity', - factIds: ['entityOwnershipFactRetriever'], - rule: { - conditions: { - all: [ - { - fact: 'hasGroupOwner', - operator: 'equal', - value: true, - }, - ], - }, - }, - }, - }, - }, - }, - }, - }), - ], - }); - - expect(extensionPoint.setFactCheckerFactory).toHaveBeenCalled(); - }); -}); diff --git a/plugins/tech-insights-backend-module-jsonfc/src/module/techInsightsModuleJsonRulesEngineFactCheckerFactory.ts b/plugins/tech-insights-backend-module-jsonfc/src/module/techInsightsModuleJsonRulesEngineFactCheckerFactory.ts deleted file mode 100644 index 8527b91d9d..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/module/techInsightsModuleJsonRulesEngineFactCheckerFactory.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - coreServices, - createBackendModule, -} from '@backstage/backend-plugin-api'; -import { techInsightsFactCheckerFactoryExtensionPoint } from '@backstage/plugin-tech-insights-node'; -import { JsonRulesEngineFactCheckerFactory } from '../service'; - -/** - * Sets a JsonRulesEngineFactCheckerFactory as FactCheckerFactory - * loading checks from the config. - * - * @public - */ -export const techInsightsModuleJsonRulesEngineFactCheckerFactory = - createBackendModule({ - pluginId: 'tech-insights', - moduleId: 'json-rules-engine-fact-checker-factory', - register(env) { - env.registerInit({ - deps: { - config: coreServices.rootConfig, - logger: coreServices.logger, - techInsights: techInsightsFactCheckerFactoryExtensionPoint, - }, - async init({ config, logger, techInsights }) { - const winstonLogger = loggerToWinstonLogger(logger); - const factory = JsonRulesEngineFactCheckerFactory.fromConfig(config, { - logger: winstonLogger, - }); - techInsights.setFactCheckerFactory(factory); - }, - }); - }, - }); diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/CheckRegistry.ts b/plugins/tech-insights-backend-module-jsonfc/src/service/CheckRegistry.ts deleted file mode 100644 index dec84a8634..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/CheckRegistry.ts +++ /dev/null @@ -1,60 +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 { ConflictError, NotFoundError } from '@backstage/errors'; -import { - TechInsightCheck, - TechInsightCheckRegistry, -} from '@backstage/plugin-tech-insights-node'; - -export class DefaultCheckRegistry - implements TechInsightCheckRegistry -{ - private readonly checks = new Map(); - - constructor(checks: CheckType[]) { - checks.forEach(check => { - this.register(check); - }); - } - - async register(check: CheckType): Promise { - if (this.checks.has(check.id)) { - throw new ConflictError( - `Tech insight check with id ${check.id} has already been registered`, - ); - } - this.checks.set(check.id, check); - return check; - } - - async get(checkId: string): Promise { - const check = this.checks.get(checkId); - if (!check) { - throw new NotFoundError( - `Tech insight check with id '${checkId}' is not registered.`, - ); - } - return check; - } - async getAll(checks: string[]): Promise { - return Promise.all(checks.map(checkId => this.get(checkId))); - } - - async list(): Promise { - return [...this.checks.values()]; - } -} diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/JsonRulesEngineFactChecker.test.ts b/plugins/tech-insights-backend-module-jsonfc/src/service/JsonRulesEngineFactChecker.test.ts deleted file mode 100644 index 7fbc2e320b..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/JsonRulesEngineFactChecker.test.ts +++ /dev/null @@ -1,730 +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 { - TechInsightCheckRegistry, - TechInsightsStore, -} from '@backstage/plugin-tech-insights-node'; -import { - JSON_RULE_ENGINE_CHECK_TYPE, - JsonRulesEngineFactCheckerFactory, -} from '../index'; -import { getVoidLogger } from '@backstage/backend-common'; -import { TechInsightJsonRuleCheck } from '../types'; -import { Operator } from 'json-rules-engine'; - -const testChecks: Record = { - broken: [ - { - id: 'brokenTestCheck', - name: 'brokenTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Broken Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'largerThan', - value: 1, - }, - ], - }, - }, - }, - ], - broken2: [ - { - id: 'brokenTestCheck2', - name: 'brokenTestCheck2', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Second Broken Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - any: [ - { - fact: 'somefact', - operator: 'lessThan', - value: 1, - }, - ], - }, - }, - }, - ], - brokennotfound: [ - { - id: 'brokenTestCheckNotFound', - name: 'brokenTestCheckNotFound', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Third Broken Check For Testing', - factIds: ['non-existing-factretriever'], - rule: { - conditions: { - any: [ - { - fact: 'somefact', - operator: 'lessThan', - value: 1, - }, - ], - }, - }, - }, - ], - simple: [ - { - id: 'simpleTestCheck', - name: 'simpleTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Simple Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'lessThan', - value: 5, - }, - ], - }, - }, - }, - ], - - simple2: [ - { - id: 'simpleTestCheck2', - name: 'simpleTestCheck2', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Second Simple Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'greaterThan', - value: 2, - }, - ], - }, - }, - }, - ], - - twoRetrieversSame: [ - { - id: 'twoRetrieversSameCheck', - name: 'twoRetrieversSameCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Two Retriever Check For Testing', - factIds: [ - 'test-factretriever', - 'test-factretriever-same-fact', - 'non-existing-factretriever', - ], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'greaterThan', - value: 2, - }, - ], - }, - }, - }, - ], - - twoRetrieversDifferent: [ - { - id: 'twoRetrieversDifferentCheck', - name: 'twoRetrieversDifferentCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Two Retriever Check For Testing', - factIds: ['test-factretriever-different-fact', 'test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'greaterThan', - value: 2, - }, - ], - }, - }, - }, - ], - - twoRetrieversDifferentOrder: [ - { - id: 'twoRetrieversDifferentOrderCheck', - name: 'twoRetrieversDifferentOrderCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Two Retriever Check For Testing', - factIds: ['test-factretriever', 'test-factretriever-different-fact'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'greaterThan', - value: 2, - }, - ], - }, - }, - }, - ], - - twoRetrieversOnlyOneData: [ - { - id: 'twoRetrieversOnlyOneDataCheck', - name: 'twoRetrieversOnlyOneDataCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Two Retriever Check For Testing', - factIds: [ - 'test-factretriever', - 'test-factretriever-no-fact', - 'non-existing-factretriever', - ], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'greaterThan', - value: 2, - }, - ], - }, - }, - }, - ], - - customOperator: [ - { - id: 'customOperatorTestCheck', - name: 'customOperatorTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: 'Check For Testing using Custom Operator', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'isDivisibleBy', - value: 2, - }, - ], - }, - }, - }, - ], - - invalidCustomOperator: [ - { - id: 'invalidCustomOperatorTestCheck', - name: 'invalidCustomOperatorTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - description: - 'Check For Testing using a Custom Operator that is not registered', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - operator: 'isOdd', - value: 2, - }, - ], - }, - }, - }, - ], -}; - -const latestSchemasMock = jest.fn().mockImplementation(() => [ - { - version: '0.0.1', - id: 2, - ref: 'test-factretriever', - entityTypes: ['component'], - testnumberfact: { - type: 'integer', - description: '', - }, - }, - { - version: '0.0.1', - id: 3, - ref: 'test-factretriever-no-fact', - entityTypes: ['component'], - testnumberfact: { - type: 'integer', - description: '', - }, - }, - { - version: '0.0.1', - id: 4, - ref: 'test-factretriever-same-fact', - entityTypes: ['component'], - testnumberfact: { - type: 'integer', - description: '', - }, - }, - { - version: '0.0.1', - id: 5, - ref: 'test-factretriever-different-fact', - entityTypes: ['users'], - testnumberfact: { - type: 'integer', - description: '', - }, - }, -]); -const factsBetweenTimestampsByIdsMock = jest.fn(); -const latestFactsByIdsMock = jest - .fn() - .mockImplementation((factIds: string[]) => { - const facts = [ - { - id: 'test-factretriever-different-fact', - facts: { - testnumberfact: 1, - }, - }, - { - id: 'test-factretriever-same-fact', - facts: { - testnumberfact: 3, - }, - }, - { - id: 'test-factretriever', - facts: { - testnumberfact: 3, - }, - }, - { - id: 'test-factretriever-no-fact', - facts: {}, - }, - ]; - - const factResults = Object.fromEntries( - factIds - .map(factId => facts.filter(fact => fact.id === factId)) - .flat() - .map(fact => [fact.id, fact]), - ); - - return factResults; - }); -const mockCheckRegistry = { - getAll(checks: string[]) { - return checks.flatMap(check => testChecks[check]); - }, -} as unknown as TechInsightCheckRegistry; - -const mockRepository: TechInsightsStore = { - getLatestFactsByIds: latestFactsByIdsMock, - getFactsBetweenTimestampsByIds: factsBetweenTimestampsByIdsMock, - getLatestSchemas: latestSchemasMock, -} as unknown as TechInsightsStore; - -describe('JsonRulesEngineFactChecker', () => { - const factChecker = new JsonRulesEngineFactCheckerFactory({ - checkRegistry: mockCheckRegistry, - checks: [], - operators: [ - new Operator('isDivisibleBy', (a, b) => a % b === 0), - ], - logger: getVoidLogger(), - }).construct(mockRepository); - - describe('when running checks', () => { - it('should throw on incorrectly configured checks conditions', async () => { - const cur = async () => await factChecker.runChecks('a/a/a', ['broken']); - await expect(cur()).rejects.toThrow( - 'Failed to run rules engine, Unknown operator: largerThan', - ); - }); - - it('should handle cases where wrong facts are referenced', async () => { - const cur = async () => await factChecker.runChecks('a/a/a', ['broken2']); - await expect(cur()).rejects.toThrow( - 'Failed to run rules engine, Undefined fact: somefact', - ); - }); - - it('should skip checks where fact data is missing', async () => { - const skipped = async () => - await factChecker.runChecks('a/a/a', ['brokennotfound']); - await expect(skipped()).resolves.toEqual([]); - - const partial = async () => - await factChecker.runChecks('a/a/a', ['brokennotfound', 'simple']); - await expect(partial()).resolves.toEqual([ - expect.objectContaining({ - check: expect.objectContaining({ id: 'simpleTestCheck' }), - }), - ]); - }); - - it('should respond with result, facts, fact schemas and checks', async () => { - const results = await factChecker.runChecks('a/a/a', ['simple']); - expect(results).toHaveLength(1); - expect(results[0]).toMatchObject({ - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'simpleTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'simpleTestCheck', - description: 'Simple Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - factResult: 3, - operator: 'lessThan', - result: true, - value: 5, - }, - ], - priority: 1, - }, - }, - }, - }); - }); - - it('should respond with result, facts, fact schemas and checks for multiple retrievers', async () => { - const results = await factChecker.runChecks('a/a/a', [ - 'twoRetrieversSame', - ]); - expect(results).toHaveLength(1); - expect(results[0]).toMatchObject({ - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'twoRetrieversSameCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'twoRetrieversSameCheck', - description: 'Two Retriever Check For Testing', - factIds: [ - 'test-factretriever', - 'test-factretriever-same-fact', - 'non-existing-factretriever', - ], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - factResult: 3, - operator: 'greaterThan', - result: true, - value: 2, - }, - ], - priority: 1, - }, - }, - }, - }); - }); - - it('should respond with result, facts, fact schemas and checks for multiple retrievers with the last fact winning', async () => { - const results = await factChecker.runChecks('a/a/a', [ - 'twoRetrieversDifferent', - 'twoRetrieversDifferentOrder', - ]); - - expect(results).toHaveLength(2); - expect(results[0]).toMatchObject({ - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'twoRetrieversDifferentCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'twoRetrieversDifferentCheck', - description: 'Two Retriever Check For Testing', - factIds: ['test-factretriever-different-fact', 'test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - factResult: 3, - operator: 'greaterThan', - result: true, - value: 2, - }, - ], - priority: 1, - }, - }, - }, - }); - expect(results[1]).toMatchObject({ - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'twoRetrieversDifferentOrderCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'twoRetrieversDifferentOrderCheck', - description: 'Two Retriever Check For Testing', - factIds: ['test-factretriever', 'test-factretriever-different-fact'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - factResult: 3, - operator: 'greaterThan', - result: true, - value: 2, - }, - ], - priority: 1, - }, - }, - }, - }); - }); - - it('the ordering of the factIds do not effect the result, its just which fact is last.', async () => { - const resultsDIfferentFirst = await factChecker.runChecks('a/a/a', [ - 'twoRetrieversDifferent', - ]); - const resultsDIfferentSecond = await factChecker.runChecks('a/a/a', [ - 'twoRetrieversDifferentOrder', - ]); - - expect(resultsDIfferentFirst[0].result).not.toEqual( - resultsDIfferentSecond[0].result, - ); - }); - - it('should respond with result, facts, fact schemas and checks for multiple retrievers one without data', async () => { - const results = await factChecker.runChecks('a/a/a', [ - 'twoRetrieversOnlyOneData', - ]); - expect(results).toHaveLength(1); - expect(results[0]).toMatchObject({ - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'twoRetrieversOnlyOneDataCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'twoRetrieversOnlyOneDataCheck', - description: 'Two Retriever Check For Testing', - factIds: [ - 'test-factretriever', - 'test-factretriever-no-fact', - 'non-existing-factretriever', - ], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - factResult: 3, - operator: 'greaterThan', - result: true, - value: 2, - }, - ], - priority: 1, - }, - }, - }, - }); - }); - - it('should use custom operators when defined', async () => { - const results = await factChecker.runChecks('a/a/a', ['customOperator']); - expect(results).toHaveLength(1); - expect(results[0]).toMatchObject({ - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: false, - check: { - id: 'customOperatorTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'customOperatorTestCheck', - description: 'Check For Testing using Custom Operator', - factIds: ['test-factretriever'], - rule: { - conditions: { - all: [ - { - fact: 'testnumberfact', - factResult: 3, - operator: 'isDivisibleBy', - result: false, - value: 2, - }, - ], - priority: 1, - }, - }, - }, - }); - }); - - it('should gracefully handle multiple check at once', async () => { - const results = await factChecker.runChecks('a/a/a', [ - 'simple', - 'simple2', - ]); - expect(results).toMatchObject([ - { - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'simpleTestCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'simpleTestCheck', - description: 'Simple Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - priority: 1, - all: [ - { - operator: 'lessThan', - value: 5, - fact: 'testnumberfact', - factResult: 3, - result: true, - }, - ], - }, - }, - }, - }, - { - facts: { - testnumberfact: { - value: 3, - type: 'integer', - description: '', - }, - }, - result: true, - check: { - id: 'simpleTestCheck2', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'simpleTestCheck2', - description: 'Second Simple Check For Testing', - factIds: ['test-factretriever'], - rule: { - conditions: { - priority: 1, - all: [ - { - operator: 'greaterThan', - value: 2, - fact: 'testnumberfact', - factResult: 3, - result: true, - }, - ], - }, - }, - }, - }, - ]); - }); - }); - - describe('when validating checks', () => { - [testChecks.simple[0], testChecks.customOperator[0]].forEach(check => { - it(`should succeed on valid rule: ${check.name}`, async () => { - const validationResponse = await factChecker.validate(check); - expect(validationResponse.valid).toBeTruthy(); - }); - }); - - [testChecks.broken[0], testChecks.invalidCustomOperator[0]].forEach( - check => { - it(`should fail on broken rules: ${check.name}`, async () => { - const validationResponse = await factChecker.validate( - testChecks.broken[0], - ); - expect(validationResponse.valid).toBeFalsy(); - }); - }, - ); - }); -}); diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/JsonRulesEngineFactChecker.ts b/plugins/tech-insights-backend-module-jsonfc/src/service/JsonRulesEngineFactChecker.ts deleted file mode 100644 index 51609bc916..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/JsonRulesEngineFactChecker.ts +++ /dev/null @@ -1,400 +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 { Config } from '@backstage/config'; -import { isError } from '@backstage/errors'; -import { FactResponse } from '@backstage/plugin-tech-insights-common'; -import { - FactChecker, - TechInsightCheckRegistry, - FlatTechInsightFact, - TechInsightsStore, - CheckValidationResponse, -} from '@backstage/plugin-tech-insights-node'; -import Ajv, { SchemaObject } from 'ajv'; -import { - Engine, - EngineResult, - Operator, - TopLevelCondition, -} from 'json-rules-engine'; -import { pick } from 'lodash'; -import { Logger } from 'winston'; -import { JSON_RULE_ENGINE_CHECK_TYPE } from '../constants'; -import { JsonRuleBooleanCheckResult, TechInsightJsonRuleCheck } from '../types'; -import { DefaultCheckRegistry } from './CheckRegistry'; -import { readChecksFromConfig } from './config'; -import * as validationSchema from './validation-schema.json'; - -const noopEvent = { - type: 'noop', -}; - -/** - * @public - * Should actually be at-internal - * - * Constructor options for JsonRulesEngineFactChecker - */ -export type JsonRulesEngineFactCheckerOptions = { - checks: TechInsightJsonRuleCheck[]; - repository: TechInsightsStore; - logger: Logger; - checkRegistry?: TechInsightCheckRegistry; - operators?: Operator[]; -}; - -/** - * @public - * Should actually be at-internal - * - * FactChecker implementation using json-rules-engine - */ -export class JsonRulesEngineFactChecker - implements FactChecker -{ - private readonly checkRegistry: TechInsightCheckRegistry; - private repository: TechInsightsStore; - private readonly logger: Logger; - private readonly validationSchema: SchemaObject; - private readonly operators: Operator[]; - - constructor(options: JsonRulesEngineFactCheckerOptions) { - const { checks, repository, logger, checkRegistry, operators } = options; - - this.repository = repository; - this.logger = logger; - this.operators = operators || []; - this.validationSchema = JSON.parse(JSON.stringify(validationSchema)); - - this.operators.forEach(op => { - this.validationSchema.definitions.condition.properties.operator.anyOf.push( - { const: op.name }, - ); - }); - - checks.forEach(check => this.validate(check)); - this.checkRegistry = - checkRegistry ?? - new DefaultCheckRegistry(checks); - } - - async runChecks( - entity: string, - checks?: string[], - ): Promise { - const engine = new Engine(); - this.operators.forEach(op => { - engine.addOperator(op); - }); - - const techInsightChecks = checks - ? await this.checkRegistry.getAll(checks) - : await this.checkRegistry.list(); - const factIds = techInsightChecks.flatMap(it => it.factIds); - const facts = await this.repository.getLatestFactsByIds(factIds, entity); - - techInsightChecks.forEach(techInsightCheck => { - const rule = techInsightCheck.rule; - rule.name = techInsightCheck.id; - // Only run checks that have all the facts available: - const hasFacts = techInsightCheck.factIds.some(factId => facts[factId]); - if (hasFacts) { - engine.addRule({ ...techInsightCheck.rule, event: noopEvent }); - } else { - this.logger.debug( - `Skipping ${ - rule.name - } due to missing facts: ${techInsightCheck.factIds - .filter(factId => !facts[factId]) - .join(', ')}`, - ); - } - }); - const factValues = Object.values(facts).reduce( - (acc, it) => ({ ...acc, ...it.facts }), - {}, - ); - - try { - const results = await engine.run(factValues); - return await this.ruleEngineResultsToCheckResponse( - results, - techInsightChecks, - Object.values(facts), - ); - } catch (e) { - if (isError(e)) { - throw new Error(`Failed to run rules engine, ${e.message}`, { - cause: e, - }); - } - throw e; - } - } - - async validate( - check: TechInsightJsonRuleCheck, - ): Promise { - const ajv = new Ajv({ verbose: true }); - const validator = ajv.compile(this.validationSchema); - const isValidToSchema = validator(check.rule); - if (check.type !== JSON_RULE_ENGINE_CHECK_TYPE) { - const msg = `Only ${JSON_RULE_ENGINE_CHECK_TYPE} checks can be registered to this fact checker`; - this.logger.warn(msg); - return { - valid: false, - message: msg, - }; - } - if (!isValidToSchema) { - const msg = 'Failed to to validate conditions against JSON schema'; - this.logger.warn( - 'Failed to to validate conditions against JSON schema', - validator.errors, - ); - return { - valid: false, - message: msg, - errors: validator.errors ? validator.errors : undefined, - }; - } - - const existingSchemas = await this.repository.getLatestSchemas( - check.factIds, - ); - const references = this.retrieveIndividualFactReferences( - check.rule.conditions, - ); - const results = references.map(ref => ({ - ref, - result: existingSchemas.some(schema => schema.hasOwnProperty(ref)), - })); - const failedReferences = results.filter(it => !it.result); - failedReferences.forEach(it => { - this.logger.warn( - `Validation failed for check ${check.name}. Reference to value ${ - it.ref - } does not exists in referred fact schemas: ${check.factIds.join(',')}`, - ); - }); - const valid = failedReferences.length === 0; - return { - valid, - ...(!valid - ? { - message: `Check is referencing missing values from fact schemas: ${failedReferences - .map(it => it.ref) - .join(',')}`, - } - : {}), - }; - } - - getChecks(): Promise { - return this.checkRegistry.list(); - } - - private retrieveIndividualFactReferences( - condition: TopLevelCondition | { fact: string }, - ): string[] { - let results: string[] = []; - if ('all' in condition) { - results = results.concat( - condition.all.flatMap(con => - this.retrieveIndividualFactReferences(con), - ), - ); - } else if ('any' in condition) { - results = results.concat( - condition.any.flatMap(con => - this.retrieveIndividualFactReferences(con), - ), - ); - } else if ('not' in condition) { - results = results.concat( - this.retrieveIndividualFactReferences(condition.not), - ); - } else if ('condition' in condition) { - // ignore the ConditionReference type - } else { - results.push(condition.fact); - } - return results; - } - - private async ruleEngineResultsToCheckResponse( - results: EngineResult, - techInsightChecks: TechInsightJsonRuleCheck[], - facts: FlatTechInsightFact[], - ) { - return await Promise.all( - [ - ...(results.results && results.results), - ...(results.failureResults && results.failureResults), - ].map(async result => { - const techInsightCheck = techInsightChecks.find( - check => check.id === result.name, - ); - if (!techInsightCheck) { - // This should never happen, we just constructed these based on each other - throw new Error( - `Failed to determine tech insight check with id ${result.name}. Discrepancy between ran rule engine and configured checks.`, - ); - } - const factResponse = await this.constructFactInformationResponse( - facts, - techInsightCheck, - ); - return { - facts: factResponse, - result: result.result, - check: JsonRulesEngineFactChecker.constructCheckResponse( - techInsightCheck, - result, - ), - }; - }), - ); - } - - private static constructCheckResponse( - techInsightCheck: TechInsightJsonRuleCheck, - result: any, - ) { - const returnable = { - id: techInsightCheck.id, - type: techInsightCheck.type, - name: techInsightCheck.name, - description: techInsightCheck.description, - factIds: techInsightCheck.factIds, - metadata: result.result - ? techInsightCheck.successMetadata - : techInsightCheck.failureMetadata, - rule: { conditions: {} }, - }; - - if ('toJSON' in result) { - // Results from json-rules-engine serialize "wrong" since the objects are creating their own serialization implementations. - // 'toJSON' should always be present in the result object but it is missing from the types. - // Parsing the stringified representation into a plain object here to be able to serialize it later - // along with other items present in the returned response. - const rule = JSON.parse(result.toJSON()); - return { ...returnable, rule: pick(rule, ['conditions']) }; - } - return returnable; - } - - private async constructFactInformationResponse( - facts: FlatTechInsightFact[], - techInsightCheck: TechInsightJsonRuleCheck, - ): Promise { - const factSchemas = await this.repository.getLatestSchemas( - techInsightCheck.factIds, - ); - const schemas = factSchemas.reduce( - (acc, schema) => ({ ...acc, ...schema }), - {}, - ); - const individualFacts = this.retrieveIndividualFactReferences( - techInsightCheck.rule.conditions, - ); - const factValues = facts - .filter(factContainer => - techInsightCheck.factIds.includes(factContainer.id), - ) - .reduce( - (acc, factContainer) => ({ - ...acc, - ...pick(factContainer.facts, individualFacts), - }), - {}, - ); - return Object.entries(factValues).reduce((acc, [key, value]) => { - return { - ...acc, - [key]: { - value, - ...schemas[key], - }, - }; - }, {}); - } -} - -/** - * @public - * - * Constructor options for JsonRulesEngineFactCheckerFactory - * - * Implementation of checkRegistry is optional. - * If there is a need to use persistent storage for checks, it is recommended to inject a storage implementation here. - * Otherwise, an in-memory option is instantiated and used. - */ -export type JsonRulesEngineFactCheckerFactoryOptions = { - checks: TechInsightJsonRuleCheck[]; - logger: Logger; - checkRegistry?: TechInsightCheckRegistry; - operators?: Operator[]; -}; - -/** - * @public - * - * Factory to construct JsonRulesEngineFactChecker - * Can be constructed with optional implementation of CheckInsightCheckRegistry if needed. - * Otherwise, defaults to using in-memory CheckRegistry. - */ -export class JsonRulesEngineFactCheckerFactory { - private readonly checks: TechInsightJsonRuleCheck[]; - private readonly logger: Logger; - private readonly checkRegistry?: TechInsightCheckRegistry; - private readonly operators?: Operator[]; - - static fromConfig( - config: Config, - options: Omit, - ): JsonRulesEngineFactCheckerFactory { - const checks = readChecksFromConfig(config); - - return new JsonRulesEngineFactCheckerFactory({ - ...options, - checks, - }); - } - - constructor(options: JsonRulesEngineFactCheckerFactoryOptions) { - this.logger = options.logger; - this.checks = options.checks; - this.checkRegistry = options.checkRegistry; - this.operators = options.operators; - } - - /** - * @param repository - Implementation of TechInsightsStore. Used by the returned JsonRulesEngineFactChecker - * to retrieve fact and fact schema data - * @returns JsonRulesEngineFactChecker implementation - */ - construct(repository: TechInsightsStore) { - return new JsonRulesEngineFactChecker({ - checks: this.checks, - logger: this.logger, - checkRegistry: this.checkRegistry, - repository, - operators: this.operators, - }); - } -} diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/config.test.ts b/plugins/tech-insights-backend-module-jsonfc/src/service/config.test.ts deleted file mode 100644 index 732cc7f731..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/config.test.ts +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ConfigReader } from '@backstage/config'; -import { JSON_RULE_ENGINE_CHECK_TYPE } from '../constants'; -import { readChecksFromConfig } from './config'; - -describe('config', () => { - describe('readChecksFromConfig', () => { - it('no config return empty checks array', () => { - const config = new ConfigReader({}); - const checks = readChecksFromConfig(config); - - expect(checks).toHaveLength(0); - }); - - it('empty checks config return empty checks array', () => { - const config = new ConfigReader({ - techInsights: { - factChecker: {}, - }, - }); - const checks = readChecksFromConfig(config); - - expect(checks).toHaveLength(0); - }); - - it('with checks return parsed checks', () => { - const config = new ConfigReader({ - techInsights: { - factChecker: { - checks: { - fooCheck: { - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'Foo Check', - description: 'Verifies foo', - factIds: ['fooFactRetriever'], - rule: { - conditions: { - all: [ - { - fact: 'numFoo', - operator: 'greaterThanInclusive', - value: 1, - }, - { - fact: 'hasFoo', - operator: 'equal', - value: true, - }, - ], - }, - }, - }, - barCheck: { - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'Bar Check', - description: 'Verifies bar', - factIds: ['barFactRetriever'], - rule: { - conditions: { - any: [ - { - fact: 'barEnabled', - operator: 'equal', - value: false, - }, - { - fact: 'hasBar', - operator: 'equal', - value: true, - }, - ], - }, - }, - }, - bazCheck: { - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'Baz Check', - description: 'Verifies baz', - factIds: ['bazFactRetriever'], - rule: { - conditions: { - not: { - fact: 'bazConfig', - operator: 'equal', - value: { invalid: true }, - }, - }, - }, - }, - }, - }, - }, - }); - - const checks = readChecksFromConfig(config); - - expect(checks).toHaveLength(3); - expect(checks.map(check => check.id)).toEqual([ - 'fooCheck', - 'barCheck', - 'bazCheck', - ]); - - const fooCheck = checks.find(check => check.id === 'fooCheck')!; - expect(fooCheck.name).toEqual('Foo Check'); - expect(fooCheck.rule.conditions).toEqual({ - all: [ - { - fact: 'numFoo', - operator: 'greaterThanInclusive', - value: 1, - }, - { - fact: 'hasFoo', - operator: 'equal', - value: true, - }, - ], - }); - - const barCheck = checks.find(check => check.id === 'barCheck')!; - expect(barCheck.name).toEqual('Bar Check'); - expect(barCheck.rule.conditions).toEqual({ - any: [ - { - fact: 'barEnabled', - operator: 'equal', - value: false, - }, - { - fact: 'hasBar', - operator: 'equal', - value: true, - }, - ], - }); - - const bazCheck = checks.find(check => check.id === 'bazCheck')!; - expect(bazCheck.name).toEqual('Baz Check'); - expect(bazCheck.rule.conditions).toEqual({ - not: { - fact: 'bazConfig', - operator: 'equal', - value: { invalid: true }, - }, - }); - }); - }); -}); diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/config.ts b/plugins/tech-insights-backend-module-jsonfc/src/service/config.ts deleted file mode 100644 index 5c663d0d41..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/config.ts +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Config } from '@backstage/config'; -import { TopLevelCondition } from 'json-rules-engine'; -import { Rule, TechInsightJsonRuleCheck } from '../types'; - -// copy of non-exported `ConditionProperties` from 'json-rules-engine' -interface ConditionProperties { - fact: string; - operator: string; - value: { fact: string } | any; - path?: string; - priority?: number; - params?: Record; - name?: string; -} - -// copy of non-exported `NestedCondition` from 'json-rules-engine' -type NestedCondition = ConditionProperties | TopLevelCondition; - -function readRuleConditionProperties(config: Config): ConditionProperties { - const fact = config.getString('fact'); - const name = config.getOptionalString('name'); - const operator = config.getString('operator'); - const params = config.getOptionalConfig('params')?.get>(); - const path = config.getOptionalString('path'); - const priority = config.getOptionalNumber('priority'); - const value: { fact: string } | any = config.get('value'); - - return { - fact, - name, - operator, - params, - path, - priority, - value, - }; -} - -function readRuleNestedCondition(config: Config): NestedCondition { - if (config.has('fact')) { - return readRuleConditionProperties(config); - } - - return readRuleTopLevelCondition(config); -} - -function readRuleTopLevelCondition(config: Config): TopLevelCondition { - const base = { - name: config.getOptionalString('name'), - priority: config.getOptionalNumber('priority'), - }; - - if (config.has('all')) { - const all = config - .getConfigArray('all') - .map(conditionConfig => readRuleNestedCondition(conditionConfig)); - return { - ...base, - all, - }; - } - - if (config.has('any')) { - const any = config - .getConfigArray('any') - .map(conditionConfig => readRuleNestedCondition(conditionConfig)); - return { - ...base, - any, - }; - } - - if (config.has('not')) { - const not = readRuleNestedCondition(config.getConfig('not')); - return { - ...base, - not, - }; - } - - const condition = config.getString('condition'); - - return { - ...base, - condition, - }; -} - -function readRuleFromRuleConfig(config: Config): Rule { - const conditions = readRuleTopLevelCondition(config.getConfig('conditions')); - const name = config.getOptionalString('name'); - const priority = config.getOptionalNumber('priority'); - - return { - conditions, - name, - priority, - }; -} - -function readCheckFromCheckConfig( - id: string, - config: Config, -): TechInsightJsonRuleCheck { - const type = config.getString('type'); - const name = config.getString('name'); - const description = config.getString('description'); - const factIds = config.getStringArray('factIds'); - const successMetadata = config - .getOptionalConfig('successMetadata') - ?.get>(); - const failureMetadata = config - .getOptionalConfig('failureMetadata') - ?.get>(); - const rule = readRuleFromRuleConfig(config.getConfig('rule')); - - return { - description, - factIds, - failureMetadata, - id, - name, - rule, - successMetadata, - type, - }; -} - -export function readChecksFromConfig( - config: Config, -): TechInsightJsonRuleCheck[] { - const key = 'techInsights.factChecker.checks'; - if (!config.has(key)) { - return []; - } - - const checksConfig = config.getConfig(key); - const checks: TechInsightJsonRuleCheck[] = []; - checksConfig.keys().forEach(checkId => { - const checkConfig = checksConfig.getConfig(checkId); - - checks.push(readCheckFromCheckConfig(checkId, checkConfig)); - }); - - return checks; -} diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/index.ts b/plugins/tech-insights-backend-module-jsonfc/src/service/index.ts deleted file mode 100644 index 5670c138a1..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { - JsonRulesEngineFactCheckerFactory, - JsonRulesEngineFactChecker, -} from './JsonRulesEngineFactChecker'; - -export type { - JsonRulesEngineFactCheckerFactoryOptions, - JsonRulesEngineFactCheckerOptions, -} from './JsonRulesEngineFactChecker'; diff --git a/plugins/tech-insights-backend-module-jsonfc/src/service/validation-schema.json b/plugins/tech-insights-backend-module-jsonfc/src/service/validation-schema.json deleted file mode 100644 index 9020ba0735..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/service/validation-schema.json +++ /dev/null @@ -1,208 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema", - "$id": "https://github.com/CacheControl/json-rules-engine/rule-schema.json", - "type": "object", - "title": "Fact Checks", - "description": "Checks contain a set of conditions and a single event. When the engine is run, each check condition is evaluated and results returned", - "required": ["conditions"], - "properties": { - "conditions": { - "$ref": "#/definitions/conditions" - }, - "priority": { - "$id": "#/properties/priority", - "anyOf": [ - { - "type": "integer", - "minimum": 1 - } - ], - "title": "Priority", - "description": "Dictates when check should be run, relative to other check. Higher priority checks are run before lower priority checks. Checks with the same priority are run in parallel. Priority must be a positive, non-zero integer.", - "default": 1, - "examples": [1] - } - }, - "definitions": { - "conditions": { - "type": "object", - "title": "Conditions", - "description": "Check conditions are a combination of facts, operators, and values that determine whether the check is a success or a failure. The simplest form of a condition consists of a fact, an operator, and a value. When the engine runs, the operator is used to compare the fact against the value. Each check's conditions must have either an all or an any operator at its root, containing an array of conditions. The all operator specifies that all conditions contained within must be truthy for the check to be considered a success. The any operator only requires one condition to be truthy for the check to succeed.", - "default": {}, - "examples": [ - { - "all": [ - { - "value": true, - "fact": "displayMessage", - "operator": "equal" - } - ] - } - ], - "oneOf": [ - { - "required": ["any"] - }, - { - "required": ["all"] - } - ], - "properties": { - "any": { - "$ref": "#/definitions/conditionArray" - }, - "all": { - "$ref": "#/definitions/conditionArray" - } - } - }, - "conditionArray": { - "type": "array", - "title": "Condition Array", - "description": "An array of conditions with a possible recursive inclusion of another condition array.", - "default": [], - "items": { - "anyOf": [ - { - "$ref": "#/definitions/conditions" - }, - { - "$ref": "#/definitions/condition" - } - ] - } - }, - "condition": { - "type": "object", - "title": "Condition", - "description": "Check conditions are a combination of facts, operators, and values that determine whether the check is a success or a failure. The simplest form of a condition consists of a fact, an operator, and a value. When the engine runs, the operator is used to compare the fact against the value.", - "default": { - "fact": "my-fact", - "operator": "lessThanInclusive", - "value": 1 - }, - "examples": [ - { - "fact": "gameDuration", - "operator": "equal", - "value": 40.0 - }, - { - "value": 5.0, - "fact": "personalFoulCount", - "operator": "greaterThanInclusive" - }, - { - "fact": "product-price", - "operator": "greaterThan", - "path": "$.price", - "value": 100.0, - "params": { - "productId": "widget" - } - } - ], - "required": ["fact", "operator", "value"], - "properties": { - "fact": { - "type": "string", - "title": "Fact", - "description": "Facts are methods or constants registered with the engine prior to runtime and referenced within check conditions. Each fact method should be a pure function that may return a either computed value, or promise that resolves to a computed value. As check conditions are evaluated during runtime, they retrieve fact values dynamically and use the condition operator to compare the fact result with the condition value.", - "default": "", - "examples": ["gameDuration"] - }, - "operator": { - "type": "string", - "anyOf": [ - { - "const": "equal", - "title": "fact must equal value" - }, - { - "const": "notEqual", - "title": "fact must not equal value" - }, - { - "const": "lessThan", - "title": "fact must be less than value" - }, - { - "const": "lessThanInclusive", - "title": "fact must be less than or equal to value" - }, - { - "const": "greaterThan", - "title": "fact must be greater than value" - }, - { - "const": "greaterThanInclusive", - "title": "fact must be greater than or equal to value" - }, - { - "const": "in", - "title": "fact must be included in value (an array)" - }, - { - "const": "notIn", - "title": "fact must not be included in value (an array)" - }, - { - "const": "contains", - "title": "fact (an array) must include value" - }, - { - "const": "doesNotContain", - "title": "fact (an array) must not include value" - } - ], - "title": "Operator", - "description": "The operator compares the value returned by the fact to what is stored in the value property. If the result is truthy, the condition passes.", - "default": "", - "examples": ["equal"] - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object" - }, - { - "type": "array" - }, - { - "type": "number" - }, - { - "type": "boolean" - } - ], - "title": "Value", - "description": "The value the fact should be compared to.", - "default": 0, - "examples": [40] - }, - "params": { - "type": "object", - "title": "Event Params", - "description": "Optional helper params to make available to the event processor.", - "default": {}, - "examples": [ - { - "customProperty": "customValue" - } - ] - }, - "path": { - "type": "string", - "title": "Path", - "description": "For more complex data structures, writing a separate fact handler for each object property quickly becomes verbose and unwieldy. To address this, a path property may be provided to traverse fact data using json-path syntax. Json-path support is provided by jsonpath-plus", - "default": "", - "examples": ["$.price"] - } - } - } - } -} diff --git a/plugins/tech-insights-backend-module-jsonfc/src/setupTests.ts b/plugins/tech-insights-backend-module-jsonfc/src/setupTests.ts deleted file mode 100644 index a330613afb..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/setupTests.ts +++ /dev/null @@ -1,17 +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. - */ - -export {}; diff --git a/plugins/tech-insights-backend-module-jsonfc/src/types.ts b/plugins/tech-insights-backend-module-jsonfc/src/types.ts deleted file mode 100644 index 592fee248d..0000000000 --- a/plugins/tech-insights-backend-module-jsonfc/src/types.ts +++ /dev/null @@ -1,73 +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 { TopLevelCondition } from 'json-rules-engine'; -import { TechInsightCheck } from '@backstage/plugin-tech-insights-node'; -import { - BooleanCheckResult, - CheckResponse, -} from '@backstage/plugin-tech-insights-common'; - -/** - * @public - */ -export type Rule = { - conditions: TopLevelCondition; - name?: string; - priority?: number; -}; - -/** - * @public - */ -export interface TechInsightJsonRuleCheck extends TechInsightCheck { - rule: Rule; -} - -/** - * @public - */ -export type CheckCondition = { - operator: string; - fact: string; - factValue: any; - factResult: any; - result: boolean; -}; - -/** - * @public - */ -export type ResponseTopLevelCondition = - | { all: CheckCondition[] } - | { any: CheckCondition[] }; - -/** - * @public - */ -export interface JsonRuleCheckResponse extends CheckResponse { - rule: { - conditions: ResponseTopLevelCondition & { - priority: number; - }; - }; -} - -/** - * @public - */ -export interface JsonRuleBooleanCheckResult extends BooleanCheckResult { - check: JsonRuleCheckResponse; -} diff --git a/plugins/tech-insights-backend/.eslintrc.js b/plugins/tech-insights-backend/.eslintrc.js deleted file mode 100644 index f98046cfe0..0000000000 --- a/plugins/tech-insights-backend/.eslintrc.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { - rules: { - 'jest/expect-expect': [ - 'error', - { - assertFunctionNames: ['expect', 'request.**.expect'], - }, - ], - }, -}); diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md deleted file mode 100644 index 3e97bb8188..0000000000 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ /dev/null @@ -1,1755 +0,0 @@ -# @backstage/plugin-tech-insights-backend - -## 0.5.24-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/backend-tasks@0.5.15-next.3 - - @backstage/plugin-tech-insights-node@0.4.16-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/catalog-client@1.6.0-next.1 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.24-next.2 - -### Patch Changes - -- 7201af3: Add support for the new backend system. - - A new backend plugin for the tech-insights backend - was added and exported as `default`. - - You can use it with the new backend system like - - ```ts title="packages/backend/src/index.ts" - backend.add(import('@backstage/plugin-tech-insights-backend')); - ``` - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 341c2a2: Move `FactRetrieverRegistry` and `PersistenceContext` to `@backstage/plugin-tech-insights-node`. - - Original exports are marked as deprecated and re-export the moved types. - - Please replace uses like - - ```ts - import { - FactRetrieverRegistry, - PersistenceContext, - } from '@backstage/plugin-tech-insights-backend'; - ``` - - with - - ```ts - import { - FactRetrieverRegistry, - PersistenceContext, - } from '@backstage/plugin-tech-insights-node'; - ``` - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/plugin-tech-insights-node@0.4.16-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/backend-tasks@0.5.15-next.2 - - @backstage/config@1.1.1 - - @backstage/catalog-client@1.6.0-next.1 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.24-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/catalog-client@1.6.0-next.1 - - @backstage/backend-common@0.21.0-next.1 - - @backstage/backend-tasks@0.5.15-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.16-next.1 - -## 0.5.24-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/catalog-client@1.6.0-next.0 - - @backstage/backend-tasks@0.5.15-next.0 - - @backstage/plugin-tech-insights-node@0.4.16-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.23 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/catalog-client@1.5.2 - - @backstage/plugin-tech-insights-node@0.4.15 - - @backstage/backend-tasks@0.5.14 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.23-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.2 - - @backstage/backend-tasks@0.5.14-next.2 - - @backstage/plugin-tech-insights-node@0.4.15-next.2 - -## 0.5.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/backend-tasks@0.5.14-next.1 - - @backstage/plugin-tech-insights-node@0.4.15-next.1 - - @backstage/catalog-client@1.5.2-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/catalog-client@1.5.2-next.0 - - @backstage/plugin-tech-insights-node@0.4.15-next.0 - - @backstage/backend-tasks@0.5.14-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.22 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/catalog-client@1.5.0 - - @backstage/backend-tasks@0.5.13 - - @backstage/plugin-tech-insights-node@0.4.14 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.22-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-tasks@0.5.13-next.3 - - @backstage/catalog-client@1.5.0-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.14-next.3 - -## 0.5.22-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/catalog-client@1.5.0-next.1 - - @backstage/backend-tasks@0.5.13-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.14-next.2 - -## 0.5.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.5.0-next.0 - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-tasks@0.5.13-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.14-next.1 - -## 0.5.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-tasks@0.5.13-next.0 - - @backstage/plugin-tech-insights-node@0.4.14-next.0 - - @backstage/catalog-client@1.4.6 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.21 - -### Patch Changes - -- 013611b42e: `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support. -- 193ad022bb: Add `factRetrieverId` to the fact retriever's logger metadata. -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/backend-tasks@0.5.12 - - @backstage/catalog-client@1.4.6 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.13 - -## 0.5.21-next.2 - -### Patch Changes - -- [#20570](https://github.com/backstage/backstage/pull/20570) [`013611b42e`](https://github.com/backstage/backstage/commit/013611b42ed457fefa9bb85fddf416cf5e0c1f76) Thanks [@freben](https://github.com/freben)! - `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support. - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.2 - - @backstage/backend-tasks@0.5.12-next.2 - - @backstage/plugin-tech-insights-node@0.4.13-next.2 - -## 0.5.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-tasks@0.5.12-next.1 - - @backstage/plugin-tech-insights-node@0.4.13-next.1 - - @backstage/catalog-client@1.4.5 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.21-next.0 - -### Patch Changes - -- 193ad022bb: Add `factRetrieverId` to the fact retriever's logger metadata. -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-tasks@0.5.12-next.0 - - @backstage/catalog-client@1.4.5 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.13-next.0 - -## 0.5.20 - -### Patch Changes - -- cc7dddfa7f: Increase the maximum allowed length of an entity filter for tech insights fact schemas. -- Updated dependencies - - @backstage/backend-tasks@0.5.11 - - @backstage/backend-common@0.19.8 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/plugin-tech-insights-node@0.4.12 - - @backstage/catalog-client@1.4.5 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.20-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/errors@1.2.3-next.0 - - @backstage/backend-tasks@0.5.11-next.2 - - @backstage/plugin-tech-insights-node@0.4.12-next.2 - - @backstage/catalog-client@1.4.5-next.0 - - @backstage/config@1.1.1-next.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.19-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.10-next.1 - - @backstage/backend-common@0.19.7-next.1 - - @backstage/plugin-tech-insights-node@0.4.11-next.1 - - @backstage/config@1.1.0 - - @backstage/catalog-client@1.4.4 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.5.19-next.0 - -### Patch Changes - -- cc7dddfa7f: Increase the maximum allowed length of an entity filter for tech insights fact schemas. -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/backend-tasks@0.5.10-next.0 - - @backstage/catalog-client@1.4.4 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/plugin-tech-insights-node@0.4.11-next.0 - -## 0.5.17 - -### Patch Changes - -- cfc3ca6ce060: Changes needed to support MySQL -- 814feeed7343: Update to handle invalid luxon values -- Updated dependencies - - @backstage/backend-tasks@0.5.8 - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/catalog-client@1.4.4 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-node@0.4.9 - -## 0.5.17-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.4.4-next.2 - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-tech-insights-common@0.2.12-next.0 - - @backstage/types@1.1.1-next.0 - - @backstage/backend-common@0.19.5-next.3 - - @backstage/backend-tasks@0.5.8-next.3 - - @backstage/plugin-tech-insights-node@0.4.9-next.3 - -## 0.5.17-next.2 - -### Patch Changes - -- 814feeed7343: Update to handle invalid luxon values -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-tasks@0.5.8-next.2 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/plugin-tech-insights-node@0.4.9-next.2 - - @backstage/catalog-client@1.4.4-next.1 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.5.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-tasks@0.5.8-next.1 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/plugin-tech-insights-node@0.4.9-next.1 - - @backstage/catalog-client@1.4.4-next.0 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.5.16-next.0 - -### Patch Changes - -- cfc3ca6ce060: Changes needed to support MySQL -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/backend-tasks@0.5.7-next.0 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.8-next.0 - -## 0.5.14 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/backend-tasks@0.5.5 - - @backstage/plugin-tech-insights-node@0.4.6 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.5.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.5-next.2 - - @backstage/backend-common@0.19.2-next.2 - - @backstage/plugin-tech-insights-node@0.4.6-next.2 - -## 0.5.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/backend-tasks@0.5.5-next.1 - - @backstage/plugin-tech-insights-node@0.4.6-next.1 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.5.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/backend-tasks@0.5.5-next.0 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.6-next.0 - -## 0.5.13 - -### Patch Changes - -- 4edd1ef71453: semver upgrade to 7.5.3 -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/backend-tasks@0.5.4 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.5 - -## 0.5.13-next.1 - -### Patch Changes - -- 4edd1ef71453: semver upgrade to 7.5.3 -- Updated dependencies - - @backstage/backend-common@0.19.1-next.0 - - @backstage/backend-tasks@0.5.4-next.0 - - @backstage/catalog-client@1.4.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1-next.0 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.5-next.0 - -## 0.5.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/backend-tasks@0.5.4-next.0 - - @backstage/catalog-client@1.4.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - - @backstage/plugin-tech-insights-node@0.4.5-next.0 - -## 0.5.12 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/catalog-client@1.4.2 - - @backstage/types@1.1.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - - @backstage/backend-tasks@0.5.3 - - @backstage/plugin-tech-insights-node@0.4.4 - - @backstage/config@1.0.8 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.5.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/backend-tasks@0.5.3-next.2 - - @backstage/catalog-client@1.4.2-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.2.0-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.4-next.2 - -## 0.5.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/errors@1.2.0-next.0 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/backend-tasks@0.5.3-next.1 - - @backstage/plugin-tech-insights-node@0.4.4-next.1 - - @backstage/catalog-client@1.4.2-next.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.5.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.4.2-next.0 - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-tasks@0.5.3-next.0 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.4-next.0 - -## 0.5.11 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/backend-tasks@0.5.2 - - @backstage/plugin-tech-insights-node@0.4.3 - - @backstage/catalog-client@1.4.1 - - @backstage/catalog-model@1.3.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.5.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/backend-tasks@0.5.2-next.1 - - @backstage/plugin-tech-insights-node@0.4.3-next.1 - - @backstage/config@1.0.7 - -## 0.5.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/backend-tasks@0.5.2-next.0 - - @backstage/plugin-tech-insights-node@0.4.3-next.0 - - @backstage/catalog-client@1.4.1 - - @backstage/catalog-model@1.3.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.5.10 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/catalog-client@1.4.1 - - @backstage/backend-tasks@0.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/plugin-tech-insights-node@0.4.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.5.10-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/backend-common@0.18.4-next.2 - - @backstage/backend-tasks@0.5.1-next.2 - - @backstage/catalog-client@1.4.1-next.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.2 - -## 0.5.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/catalog-client@1.4.1-next.0 - - @backstage/backend-tasks@0.5.1-next.2 - - @backstage/catalog-model@1.2.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.2 - -## 0.5.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.1-next.1 - - @backstage/backend-common@0.18.4-next.1 - - @backstage/catalog-client@1.4.0 - - @backstage/catalog-model@1.2.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.1 - -## 0.5.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-tasks@0.5.1-next.0 - - @backstage/catalog-client@1.4.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.2-next.0 - -## 0.5.9 - -### Patch Changes - -- f244b589163: Add DB index to improve latency of latest fact query -- Updated dependencies - - @backstage/catalog-client@1.4.0 - - @backstage/backend-tasks@0.5.0 - - @backstage/backend-common@0.18.3 - - @backstage/errors@1.1.5 - - @backstage/catalog-model@1.2.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.1 - -## 0.5.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.0-next.2 - - @backstage/backend-common@0.18.3-next.2 - - @backstage/plugin-tech-insights-node@0.4.1-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.5.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/backend-common@0.18.3-next.1 - - @backstage/catalog-client@1.4.0-next.1 - - @backstage/backend-tasks@0.4.4-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/catalog-model@1.2.1-next.1 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.1-next.1 - -## 0.5.9-next.0 - -### Patch Changes - -- f244b58916: Add DB index to improve latency of latest fact query -- Updated dependencies - - @backstage/catalog-client@1.4.0-next.0 - - @backstage/backend-tasks@0.4.4-next.0 - - @backstage/backend-common@0.18.3-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.1-next.0 - -## 0.5.8 - -### Patch Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/plugin-tech-insights-node@0.4.0 - - @backstage/catalog-model@1.2.0 - - @backstage/backend-tasks@0.4.3 - - @backstage/catalog-client@1.3.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.5.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/backend-tasks@0.4.3-next.2 - - @backstage/catalog-client@1.3.1-next.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - - @backstage/plugin-tech-insights-node@0.4.0-next.2 - -## 0.5.8-next.1 - -### Patch Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - - @backstage/plugin-tech-insights-node@0.4.0-next.1 - - @backstage/backend-common@0.18.2-next.1 - - @backstage/backend-tasks@0.4.3-next.1 - - @backstage/catalog-client@1.3.1-next.0 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.5.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/backend-common@0.18.2-next.0 - - @backstage/catalog-client@1.3.1-next.0 - - @backstage/backend-tasks@0.4.3-next.0 - - @backstage/plugin-tech-insights-node@0.3.10-next.0 - -## 0.5.6 - -### Patch Changes - -- 7a38a31699: Complete check results run when a single check errors so that we don't block other checks from working due to an error in a single check -- 44c18b4d3f: Expose optional `persistenceContext` on `TechInsights` construction to enable integrators to provide their own database implementations for fact handling. -- b48317cfc6: Modifies database cleanup to remove all facts for entities instead of hand-picked ones only. Improves query execution a lot in large datasets. - Changes semantics of the lifecycle deletion logic slightly for cases were historical entities/facts, that are , not present in the application anymore, were kept forever instead of being cleaned up. The new implementation is more along the expected lines. -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/catalog-model@1.1.5 - - @backstage/catalog-client@1.3.0 - - @backstage/backend-tasks@0.4.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.8 - -## 0.5.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/backend-tasks@0.4.1-next.1 - - @backstage/catalog-client@1.3.0-next.2 - - @backstage/plugin-tech-insights-node@0.3.8-next.1 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.5.6-next.1 - -### Patch Changes - -- 7a38a31699: Complete check results run when a single check errors so that we don't block other checks from working due to an error in a single check -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/backend-tasks@0.4.1-next.0 - - @backstage/catalog-client@1.3.0-next.1 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.8-next.0 - -## 0.5.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/catalog-client@1.3.0-next.0 - - @backstage/backend-common@0.17.0 - - @backstage/backend-tasks@0.4.0 - - @backstage/config@1.0.5 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.7 - -## 0.5.5 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.2.0 - - @backstage/backend-common@0.17.0 - - @backstage/backend-tasks@0.4.0 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/catalog-model@1.1.4 - - @backstage/config@1.0.5 - - @backstage/plugin-tech-insights-common@0.2.9 - - @backstage/plugin-tech-insights-node@0.3.7 - -## 0.5.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.4.0-next.3 - - @backstage/backend-common@0.17.0-next.3 - - @backstage/catalog-client@1.2.0-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - - @backstage/plugin-tech-insights-node@0.3.7-next.3 - -## 0.5.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/backend-tasks@0.4.0-next.2 - - @backstage/plugin-tech-insights-node@0.3.7-next.2 - - @backstage/catalog-client@1.2.0-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.5.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/backend-tasks@0.4.0-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-node@0.3.7-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/catalog-client@1.2.0-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.5.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.2.0-next.0 - - @backstage/backend-common@0.16.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/backend-tasks@0.3.8-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/plugin-tech-insights-common@0.2.9-next.0 - - @backstage/plugin-tech-insights-node@0.3.7-next.0 - -## 0.5.4 - -### Patch Changes - -- f12e9e5b8c: Add Documentation on 404 Errors -- 06cf8f1cf2: Add a default delay to the fact retrievers to prevent cold-start errors -- 30e43717c7: Use `HumanDuration` from `@backstage/types` -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/backend-tasks@0.3.7 - - @backstage/catalog-model@1.1.3 - - @backstage/types@1.0.1 - - @backstage/plugin-tech-insights-node@0.3.6 - - @backstage/catalog-client@1.1.2 - - @backstage/config@1.0.4 - - @backstage/errors@1.1.3 - - @backstage/plugin-tech-insights-common@0.2.8 - -## 0.5.4-next.1 - -### Patch Changes - -- f12e9e5b8c: Add Documentation on 404 Errors -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/backend-tasks@0.3.7-next.1 - - @backstage/plugin-tech-insights-node@0.3.6-next.1 - - @backstage/catalog-client@1.1.2-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.5.4-next.0 - -### Patch Changes - -- 06cf8f1cf2: Add a default delay to the fact retrievers to prevent cold-start errors -- 30e43717c7: Use `HumanDuration` from `@backstage/types` -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/backend-tasks@0.3.7-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/plugin-tech-insights-node@0.3.6-next.0 - - @backstage/catalog-client@1.1.2-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.5.3 - -### Patch Changes - -- 296aea34da: The Tech Insights plugin supports running fact retrievers across multiple instances. Update the README to remove the stale instructions. -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- f7cbfb97ed: Modify router endpoint to handle singular and collections of request parameters similarly. -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/backend-common@0.15.2 - - @backstage/backend-tasks@0.3.6 - - @backstage/catalog-client@1.1.1 - - @backstage/plugin-tech-insights-node@0.3.5 - - @backstage/config@1.0.3 - - @backstage/errors@1.1.2 - - @backstage/plugin-tech-insights-common@0.2.7 - -## 0.5.3-next.2 - -### Patch Changes - -- 2d3a5f09ab: Use `response.json` rather than `response.send` where appropriate, as outlined in `SECURITY.md` -- Updated dependencies - - @backstage/backend-tasks@0.3.6-next.2 - - @backstage/backend-common@0.15.2-next.2 - - @backstage/plugin-tech-insights-node@0.3.5-next.2 - - @backstage/catalog-client@1.1.1-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/plugin-tech-insights-common@0.2.7-next.2 - -## 0.5.3-next.1 - -### Patch Changes - -- f7cbfb97ed: Modify router endpoint to handle singular and collections of request parameters similarly. -- Updated dependencies - - @backstage/catalog-client@1.1.1-next.1 - - @backstage/backend-common@0.15.2-next.1 - - @backstage/backend-tasks@0.3.6-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.7-next.1 - - @backstage/plugin-tech-insights-node@0.3.5-next.1 - -## 0.5.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/plugin-tech-insights-node@0.3.5-next.0 - - @backstage/catalog-client@1.1.1-next.0 - - @backstage/backend-common@0.15.2-next.0 - - @backstage/backend-tasks@0.3.6-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.0 - -## 0.5.2 - -### Patch Changes - -- 8872cc735d: Fixed a bug where the database option to skip migrations was ignored. -- 12c6a07c2a: Changed the description of the `techdocsAnnotationFactName` fact. -- 2e0689e536: Support for timeout in FactRetrieverRegistrationOptions -- 9e8e9f5243: Modify Tech insight initialization to expose FactRetrieverEngine. Enables users to trigger fact retrieval manually or reschedule retrievers on runtime. -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/plugin-tech-insights-node@0.3.4 - - @backstage/backend-tasks@0.3.5 - - @backstage/catalog-client@1.1.0 - - @backstage/catalog-model@1.1.1 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - -## 0.5.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.1.0-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/backend-common@0.15.1-next.3 - - @backstage/backend-tasks@0.3.5-next.1 - - @backstage/plugin-tech-insights-node@0.3.4-next.1 - -## 0.5.2-next.1 - -### Patch Changes - -- 12c6a07c2a: Changed the description of the `techdocsAnnotationFactName` fact. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.1 - -## 0.5.2-next.0 - -### Patch Changes - -- 8872cc735d: Fixed a bug where the database option to skip migrations was ignored. -- 2e0689e536: Support for timeout in FactRetrieverRegistrationOptions -- 9e8e9f5243: Modify Tech insight initialization to expose FactRetrieverEngine. Enables users to trigger fact retrieval manually or reschedule retrievers on runtime. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - - @backstage/plugin-tech-insights-node@0.3.4-next.0 - - @backstage/backend-tasks@0.3.5-next.0 - - @backstage/catalog-client@1.0.5-next.0 - -## 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 - -- 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 - -- 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-next.3 - - @backstage/catalog-client@1.0.4-next.2 - - @backstage/backend-tasks@0.3.3-next.3 - - @backstage/plugin-tech-insights-common@0.2.5-next.0 - - @backstage/plugin-tech-insights-node@0.3.2-next.1 - - @backstage/catalog-model@1.1.0-next.3 - -## 0.5.0-next.2 - -### Minor Changes - -- 818fa28d71: Allow FactRetrieverRegistry to be injected into buildTechInsightsContext so that we can override default registry implementation. - -### Patch Changes - -- 679b32172e: Updated dependency `knex` to `^2.0.0`. -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/backend-common@0.14.1-next.2 - - @backstage/backend-tasks@0.3.3-next.2 - -## 0.4.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/backend-common@0.14.1-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/backend-tasks@0.3.3-next.1 - - @backstage/catalog-client@1.0.4-next.1 - -## 0.4.2-next.0 - -### Patch Changes - -- 2ef58ab539: TechInsightsBackend: Added missing 'scheduler' to code examples -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/backend-tasks@0.3.3-next.0 - - @backstage/plugin-tech-insights-node@0.3.2-next.0 - - @backstage/catalog-client@1.0.4-next.0 - -## 0.4.1 - -### Patch Changes - -- 4fee8f59e3: Updated tech-insights fetch/latest endpoint to return the actual latest row based on the timestamp -- aa15229ec3: Introduce additional JsonValue types to be storable as facts. This enables the possibility to store more complex objects for fact checking purposes. The rules engine supports walking keyed object values directly to create rules and checks - - Modify facts database table to have a more restricted timestamp precision for cases where the postgres server isn't configured to contain such value. This fixes the issue where in some cases `maxItems` lifecycle condition didn't work as expected. - -- Updated dependencies - - @backstage/backend-tasks@0.3.2 - - @backstage/backend-common@0.14.0 - - @backstage/catalog-client@1.0.3 - - @backstage/catalog-model@1.0.3 - - @backstage/plugin-tech-insights-node@0.3.1 - -## 0.4.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - - @backstage/backend-tasks@0.3.2-next.2 - - @backstage/plugin-tech-insights-node@0.3.1-next.1 - -## 0.4.1-next.1 - -### Patch Changes - -- 4fee8f59e3: Updated tech-insights fetch/latest endpoint to return the actual latest row based on the timestamp -- Updated dependencies - - @backstage/backend-tasks@0.3.2-next.1 - - @backstage/backend-common@0.13.6-next.1 - - @backstage/catalog-client@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - -## 0.4.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.3.2-next.0 - - @backstage/backend-common@0.13.6-next.0 - - @backstage/plugin-tech-insights-node@0.3.1-next.0 - -## 0.4.0 - -### Minor Changes - -- 3333e20b27: **BREAKING**: The `buildTechInsightsContext` function now takes an additional - field in its options argument: `tokenManager`. This is an instance of - `TokenManager`, which can be found in your backend initialization code's - `env`. - - ```diff - const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - scheduler: env.scheduler, - + tokenManager: env.tokenManager, - factRetrievers: [ /* ... */ ], - }); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/backend-tasks@0.3.1 - - @backstage/plugin-tech-insights-node@0.3.0 - - @backstage/config@1.0.1 - - @backstage/catalog-client@1.0.2 - - @backstage/catalog-model@1.0.2 - -## 0.4.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/backend-tasks@0.3.1-next.1 - - @backstage/config@1.0.1-next.0 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/plugin-tech-insights-node@0.3.0-next.2 - - @backstage/catalog-client@1.0.2-next.0 - -## 0.4.0-next.1 - -### Minor Changes - -- 3333e20b27: **BREAKING**: The `buildTechInsightsContext` function now takes an additional - field in its options argument: `tokenManager`. This is an instance of - `TokenManager`, which can be found in your backend initialization code's - `env`. - - ```diff - const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - scheduler: env.scheduler, - + tokenManager: env.tokenManager, - factRetrievers: [ /* ... */ ], - }); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.1 - - @backstage/plugin-tech-insights-node@0.3.0-next.1 - -## 0.3.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - - @backstage/backend-tasks@0.3.1-next.0 - - @backstage/plugin-tech-insights-node@0.2.10-next.0 - -## 0.3.0 - -### Minor Changes - -- 231fee736b: This backend now uses the `@backstage/backend-tasks` package facilities for scheduling fact retrievers. - - **BREAKING**: The `buildTechInsightsContext` function now takes an additional field in its options argument: `scheduler`. This is an instance of `PluginTaskScheduler`, which can be found in your backend initialization code's `env`. - - ```diff - const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - + scheduler: env.scheduler, - factRetrievers: [ /* ... */ ], - }); - ``` - -### Patch Changes - -- 21de525ce9: Updated README.md with better install instructions -- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. -- 2fe58c7285: Improved the Tech-Insights documentation: - - - `lifecycle` examples used `ttl` when it should be `timeToLive` - - Added list of included FactRetrievers - - Added full backend example using all included FactRetrievers - - Added boolean scorecard example image showing results of backend example - -- Updated dependencies - - @backstage/backend-tasks@0.3.0 - - @backstage/catalog-model@1.0.1 - - @backstage/plugin-tech-insights-node@0.2.9 - - @backstage/backend-common@0.13.2 - - @backstage/catalog-client@1.0.1 - -## 0.3.0-next.2 - -### Patch Changes - -- 21de525ce9: Updated README.md with better install instructions -- Updated dependencies - - @backstage/backend-tasks@0.3.0-next.2 - - @backstage/catalog-model@1.0.1-next.1 - -## 0.3.0-next.1 - -### Minor Changes - -- 231fee736b: This backend now uses the `@backstage/backend-tasks` package facilities for scheduling fact retrievers. - - **BREAKING**: The `buildTechInsightsContext` function now takes an additional field in its options argument: `scheduler`. This is an instance of `PluginTaskScheduler`, which can be found in your backend initialization code's `env`. - - ```diff - const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - + scheduler: env.scheduler, - factRetrievers: [ /* ... */ ], - }); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.3.0-next.1 - - @backstage/plugin-tech-insights-node@0.2.9-next.1 - - @backstage/backend-common@0.13.2-next.1 - -## 0.2.11-next.0 - -### Patch Changes - -- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. -- 2fe58c7285: Improved the Tech-Insights documentation: - - - `lifecycle` examples used `ttl` when it should be `timeToLive` - - Added list of included FactRetrievers - - Added full backend example using all included FactRetrievers - - Added boolean scorecard example image showing results of backend example - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/backend-common@0.13.2-next.0 - - @backstage/catalog-client@1.0.1-next.0 - - @backstage/plugin-tech-insights-node@0.2.9-next.0 - -## 0.2.10 - -### Patch Changes - -- 89c7e47967: Minor README update -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/catalog-model@1.0.0 - - @backstage/catalog-client@1.0.0 - - @backstage/config@1.0.0 - - @backstage/errors@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.4 - - @backstage/plugin-tech-insights-node@0.2.8 - -## 0.2.9 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0 - - @backstage/catalog-model@0.13.0 - - @backstage/catalog-client@0.9.0 - - @backstage/plugin-tech-insights-node@0.2.7 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 - - @backstage/catalog-model@0.13.0-next.0 - - @backstage/catalog-client@0.9.0-next.0 - - @backstage/plugin-tech-insights-node@0.2.7-next.0 - -## 0.2.8 - -### Patch Changes - -- 36aa63022b: Use `CompoundEntityRef` instead of `EntityName`, and `getCompoundEntityRef` instead of `getEntityName`, from `@backstage/catalog-model`. -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/catalog-client@0.8.0 - - @backstage/backend-common@0.12.0 - - @backstage/plugin-tech-insights-node@0.2.6 - -## 0.2.7 - -### Patch Changes - -- 67a7c02d26: Remove usages of `EntityRef` and `parseEntityName` from `@backstage/catalog-model` -- 919cf2f836: Minor updates to match the new `targetRef` field of relations, and to stop consuming the `target` field -- Updated dependencies - - @backstage/backend-common@0.11.0 - - @backstage/catalog-model@0.11.0 - - @backstage/catalog-client@0.7.2 - - @backstage/plugin-tech-insights-node@0.2.5 - -## 0.2.6 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/backend-common@0.10.9 - - @backstage/catalog-client@0.7.1 - - @backstage/catalog-model@0.10.1 - - @backstage/config@0.1.15 - - @backstage/errors@0.2.2 - - @backstage/plugin-tech-insights-common@0.2.3 - - @backstage/plugin-tech-insights-node@0.2.4 - -## 0.2.5 - -### Patch Changes - -- c77c5c7eb6: Added `backstage.role` to `package.json` -- 538ca90790: Use updated type names from `@backstage/catalog-client` -- Updated dependencies - - @backstage/backend-common@0.10.8 - - @backstage/catalog-client@0.7.0 - - @backstage/errors@0.2.1 - - @backstage/catalog-model@0.10.0 - - @backstage/config@0.1.14 - - @backstage/plugin-tech-insights-common@0.2.2 - - @backstage/plugin-tech-insights-node@0.2.3 - -## 0.2.4 - -### Patch Changes - -- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 - - This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 - -- Updated dependencies - - @backstage/catalog-client@0.6.0 - - @backstage/backend-common@0.10.7 - - @backstage/plugin-tech-insights-node@0.2.2 - -## 0.2.4-next.0 - -### Patch Changes - -- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 - - This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 - -- Updated dependencies - - @backstage/backend-common@0.10.7-next.0 - - @backstage/plugin-tech-insights-node@0.2.2-next.0 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6 - - @backstage/plugin-tech-insights-node@0.2.1 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6-next.0 - - @backstage/plugin-tech-insights-node@0.2.1-next.0 - -## 0.2.2 - -### Patch Changes - -- bbb6622752: Update README to match config options. -- Updated dependencies - - @backstage/backend-common@0.10.5 - -## 0.2.1 - -### Patch Changes - -- ad0a7eb088: Fixed invalid access that caused an immediate crash with a `TypeError` when loading the package. - -## 0.2.0 - -### Minor Changes - -- dfd5e81721: BREAKING CHANGES: - - - The helper function to create a fact retriever registration is now expecting an object of configuration items instead of individual arguments. - Modify your `techInsights.ts` plugin configuration in `packages/backend/src/plugins/techInsights.ts` (or equivalent) the following way: - - ```diff - -createFactRetrieverRegistration( - - '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - - entityOwnershipFactRetriever, - -), - +createFactRetrieverRegistration({ - + cadence: '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - + factRetriever: entityOwnershipFactRetriever, - +}), - - ``` - - - `TechInsightsStore` interface has changed its signature of `insertFacts` method. If you have created your own implementation of either `TechInsightsDatabase` or `FactRetrieverEngine` you need to modify the implementation/call to this method to accept/pass-in an object instead if individual arguments. The interface now accepts an additional `lifecycle` argument which is optional (defined below). An example modification to fact retriever engine: - - ```diff - -await this.repository.insertFacts(factRetriever.id, facts); - +await this.repository.insertFacts({ - + id: factRetriever.id, - + facts, - + lifecycle, - +}); - ``` - - Adds a configuration option to fact retrievers to define lifecycle for facts the retriever persists. Possible values are either 'max items' or 'time-to-live'. The former will keep only n number of items in the database for each fact per entity. The latter will remove all facts that are older than the TTL value. - - Possible values: - - - `{ maxItems: 5 }` // Deletes all facts for the retriever/entity pair, apart from the last five - - `{ ttl: 1209600000 }` // (2 weeks) Deletes all facts older than 2 weeks for the retriever/entity pair - - `{ ttl: { weeks: 2 } }` // Deletes all facts older than 2 weeks for the retriever/entity pair - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4 - - @backstage/config@0.1.13 - - @backstage/plugin-tech-insights-node@0.2.0 - - @backstage/catalog-model@0.9.10 - - @backstage/catalog-client@0.5.5 - -## 0.2.0-next.0 - -### Minor Changes - -- dfd5e81721: BREAKING CHANGES: - - - The helper function to create a fact retriever registration is now expecting an object of configuration items instead of individual arguments. - Modify your `techInsights.ts` plugin configuration in `packages/backend/src/plugins/techInsights.ts` (or equivalent) the following way: - - ```diff - -createFactRetrieverRegistration( - - '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - - entityOwnershipFactRetriever, - -), - +createFactRetrieverRegistration({ - + cadence: '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - + factRetriever: entityOwnershipFactRetriever, - +}), - - ``` - - - `TechInsightsStore` interface has changed its signature of `insertFacts` method. If you have created your own implementation of either `TechInsightsDatabase` or `FactRetrieverEngine` you need to modify the implementation/call to this method to accept/pass-in an object instead if individual arguments. The interface now accepts an additional `lifecycle` argument which is optional (defined below). An example modification to fact retriever engine: - - ```diff - -await this.repository.insertFacts(factRetriever.id, facts); - +await this.repository.insertFacts({ - + id: factRetriever.id, - + facts, - + lifecycle, - +}); - ``` - - Adds a configuration option to fact retrievers to define lifecycle for facts the retriever persists. Possible values are either 'max items' or 'time-to-live'. The former will keep only n number of items in the database for each fact per entity. The latter will remove all facts that are older than the TTL value. - - Possible values: - - - `{ maxItems: 5 }` // Deletes all facts for the retriever/entity pair, apart from the last five - - `{ ttl: 1209600000 }` // (2 weeks) Deletes all facts older than 2 weeks for the retriever/entity pair - - `{ ttl: { weeks: 2 } }` // Deletes all facts older than 2 weeks for the retriever/entity pair - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4-next.0 - - @backstage/config@0.1.13-next.0 - - @backstage/plugin-tech-insights-node@0.2.0-next.0 - - @backstage/catalog-model@0.9.10-next.0 - - @backstage/catalog-client@0.5.5-next.0 - -## 0.1.5 - -### Patch Changes - -- 19f0f93504: Catch errors from a fact retriever and log them. -- 10f26e8883: Modify queries to perform better by filtering on sub-queries as well -- a60eb0f0dd: adding new operation to run checks for multiple entities in one request -- Updated dependencies - - @backstage/config@0.1.12 - - @backstage/backend-common@0.10.3 - - @backstage/plugin-tech-insights-common@0.2.1 - - @backstage/errors@0.2.0 - - @backstage/catalog-client@0.5.4 - - @backstage/catalog-model@0.9.9 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.0 - - @backstage/catalog-client@0.5.3 - - @backstage/plugin-tech-insights-node@0.1.2 - -## 0.1.3 - -### Patch Changes - -- b055a6addc: Align on usage of `cross-fetch` vs `node-fetch` in frontend vs backend packages, and remove some unnecessary imports of either one of them -- b5bd60fddc: Removed unnecessary check for specific server error in `@backstage plugin-tech-insights-backend`. -- c6c8b8e53e: Minor fixes in Readme to make the examples more directly usable. -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.0 - - @backstage/backend-common@0.9.12 - - @backstage/plugin-tech-insights-node@0.1.1 - -## 0.1.2 - -### Patch Changes - -- 2017de90da: Update README docs to use correct function/parameter names -- Updated dependencies - - @backstage/errors@0.1.5 - - @backstage/backend-common@0.9.11 - -## 0.1.1 - -### Patch Changes - -- 5c00e45045: Add catalog fact retrievers - - Add fact retrievers which generate facts related to the completeness - of entity data in the catalog. - -- Updated dependencies - - @backstage/catalog-client@0.5.2 - - @backstage/catalog-model@0.9.7 - - @backstage/backend-common@0.9.10 diff --git a/plugins/tech-insights-backend/README.md b/plugins/tech-insights-backend/README.md deleted file mode 100644 index 56b927a10e..0000000000 --- a/plugins/tech-insights-backend/README.md +++ /dev/null @@ -1,386 +0,0 @@ -# Tech Insights Backend - -This is the backend for the default Backstage Tech Insights feature. -This provides the API for the frontend tech insights, scorecards and fact visualization functionality, -as well as a framework to run fact retrievers and store fact values in to a data store. - -## Installation - -### Install the package - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-tech-insights-backend -``` - -### Adding the plugin to your `packages/backend` - -```ts title="packages/backend/src/index.ts" -backend.add(import('@backstage/plugin-tech-insights-backend')); -``` - -You can use the extension points [@backstage/plugin-tech-insights-node](../tech-insights-node) -to add your `FactRetriever` or set a `FactCheckerFactory`. - -The built-in `FactRetrievers`: - -- `entityMetadataFactRetriever` -- `entityOwnershipFactRetriever` -- `techdocsFactRetriever` - -`FactRetrievers` only get registered if they get configured: - -```yaml title="app-config.yaml" -techInsights: - factRetrievers: - entityOwnershipFactRetriever: - cadence: '*/15 * * * *' - lifecycle: { timeToLive: { weeks: 2 } } -``` - -### Adding the plugin to your `packages/backend` (old) - -You'll need to add the plugin to the router in your `backend` package. You can -do this by creating a file called `packages/backend/src/plugins/techInsights.ts`. An example content for `techInsights.ts` could be something like this. - -```ts -import { - createRouter, - buildTechInsightsContext, -} from '@backstage/plugin-tech-insights-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - scheduler: env.scheduler, - tokenManager: env.tokenManager, - factRetrievers: [], // Fact retrievers registrations you want tech insights to use - }); - - return await createRouter({ - ...(await builder), - logger: env.logger, - config: env.config, - }); -} -``` - -With the `techInsights.ts` router setup in place, add the router to -`packages/backend/src/index.ts`: - -```diff -+import techInsights from './plugins/techInsights'; - - async function main() { - ... - const createEnv = makeCreateEnv(config); - - const catalogEnv = useHotMemoize(module, () => createEnv('catalog')); -+ const techInsightsEnv = useHotMemoize(module, () => createEnv('tech_insights')); - - const apiRouter = Router(); -+ apiRouter.use('/tech-insights', await techInsights(techInsightsEnv)); - ... - apiRouter.use(notFoundHandler()); - } -``` - -### Adding fact retrievers - -At this point the Tech Insights backend is installed in your backend package, but -you will not have any fact retrievers present in your application. To have the implemented FactRetrieverEngine within this package to be able to retrieve and store fact data into the database, you need to add these. - -To create factRetrieverRegistration you need to implement `FactRetriever` interface defined in `@backstage/plugin-tech-insights-node` package (see [Creating fact retrievers](#creating-fact-retrievers) for details). After you have implemented this interface you can wrap that into a registration object like follows: - -```ts -import { createFactRetrieverRegistration } from '@backstage/plugin-tech-insights-backend'; - -const myFactRetriever = { - /** - * snip - */ -}; - -const myFactRetrieverRegistration = createFactRetrieverRegistration({ - cadence: '1 * 2 * * ', // On the first minute of the second day of the month - factRetriever: myFactRetriever, -}); -``` - -FactRetrieverRegistration also accepts an optional `lifecycle` configuration value. This can be either MaxItems or TTL (time to live). Valid options for this value are either a number for MaxItems or a Luxon duration like object for TTL. For example: - -```ts -const maxItems = { maxItems: 7 }; // Deletes all but 7 latest facts for each id/entity pair -const ttl = { timeToLive: 1209600000 }; // (2 weeks) Deletes items older than 2 weeks -const ttlWithAHumanReadableValue = { timeToLive: { weeks: 2 } }; // Deletes items older than 2 weeks -``` - -To register these fact retrievers to your application you can modify the example `techInsights.ts` file shown above like this: - -```diff -const builder = buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - scheduler: env.scheduler, -- factRetrievers: [], -+ factRetrievers: [myFactRetrieverRegistration], -}); -``` - -#### Running fact retrievers in a multi-instance installation - -The Tech Insights plugin utilizes the `PluginTaskScheduler` for scheduling tasks and coordinating the task invocation across instances. See [the PluginTaskScheduler documentation](https://backstage.io/docs/reference/backend-tasks.plugintaskscheduler) for more information. - -### Creating Fact Retrievers - -A Fact Retriever consist of four required and one optional parts: - -1. `id` - unique identifier of a fact retriever -2. `version`: A semver string indicating the current version of the schema and the handler -3. `schema` - A versioned schema defining the shape of data a fact retriever returns -4. `handler` - An asynchronous function handling the logic of retrieving and returning facts for an entity -5. `entityFilter` - (Optional) EntityFilter object defining the entity kinds, types and/or names this fact retriever handles - -An example implementation of a FactRetriever could for example be as follows: - -```ts -import { FactRetriever } from '@backstage/plugin-tech-insights-node'; - -const myFactRetriever: FactRetriever = { - id: 'documentation-number-factretriever', // unique identifier of the fact retriever - version: '0.1.1', // SemVer version number of this fact retriever schema. This should be incremented if the implementation changes - entityFilter: [{ kind: 'component' }], // EntityFilter to be used in the future (creating checks, graphs etc.) to figure out which entities this fact retrieves data for. - schema: { - // Name/identifier of an individual fact that this retriever returns - examplenumberfact: { - type: 'integer', // Type of the fact - description: 'A fact of a number', // Description of the fact - }, - }, - handler: async ctx => { - // Handler function that retrieves the fact - const { discovery, config, logger } = ctx; - const catalogClient = new CatalogClient({ - discoveryApi: discovery, - }); - const entities = await catalogClient.getEntities( - { - filter: [{ kind: 'component' }], - }, - { token }, - ); - /** - * snip: Do complex logic to retrieve facts from external system or calculate fact values - */ - - // Respond with an array of entity/fact values - return entities.items.map(it => { - return { - // Entity information that this fact relates to - entity: { - namespace: it.metadata.namespace, - kind: it.kind, - name: it.metadata.name, - }, - - // All facts that this retriever returns - facts: { - examplenumberfact: 2, // - }, - // (optional) timestamp to use as a Luxon DateTime object - }; - }); - }, -}; -``` - -### Adding a fact checker - -This module comes with a possibility to additionally add a fact checker and expose fact checking endpoints from the API. To be able to enable this feature you need to add a FactCheckerFactory implementation to be part of the `DefaultTechInsightsBuilder` constructor call. - -There is a default FactChecker implementation provided in module `@backstage/plugin-tech-insights-backend-module-jsonfc`. This implementation uses `json-rules-engine` as the underlying functionality to run checks. If you want to implement your own FactChecker, for example to be able to handle other than `boolean` result types, you can do so by implementing `FactCheckerFactory` and `FactChecker` interfaces from `@backstage/plugin-tech-insights-common` package. - -To add the default FactChecker into your Tech Insights you need to install the module into your backend application: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-tech-insights-backend-module-jsonfc -``` - -and modify the `techInsights.ts` file to contain a reference to the FactChecker implementation. - -```diff -+import { JsonRulesEngineFactCheckerFactory } from '@backstage/plugin-tech-insights-backend-module-jsonfc'; - -+const myFactCheckerFactory = new JsonRulesEngineFactCheckerFactory({ -+ checks: [], -+ logger: env.logger, -+}), - - const builder = new DefaultTechInsightsBuilder({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - factRetrievers: [myFactRetrieverRegistration], -+ factCheckerFactory: myFactCheckerFactory - }); -``` - -NOTE: You need a Fact Checker Factory to get access to the backend routes that will allow the facts to be checked. If you don't have a Fact Checker Factory you will see 404s and potentially other errors. - -To be able to run checks, you need to additionally add individual checks into your FactChecker implementation. For examples how to add these, you can check the documentation of the individual implementation of the FactChecker - -#### Modifying check persistence - -The default FactChecker implementation comes with an in-memory storage to store checks. You can inject an additional data store by adding an implementation of `TechInsightCheckRegistry` into the constructor options when creating a `JsonRulesEngineFactCheckerFactory`. That can be done as follows: - -```diff -const myTechInsightCheckRegistry: TechInsightCheckRegistry = // snip -const myFactCheckerFactory = new JsonRulesEngineFactCheckerFactory({ - checks: [], - logger: env.logger, -+ checkRegistry: myTechInsightCheckRegistry -}), - -``` - -## Included FactRetrievers - -There are three FactRetrievers that come out of the box with Tech Insights: - -- `entityMetadataFactRetriever`: Generates facts which indicate the completeness of entity metadata -- `entityOwnershipFactRetriever`: Generates facts which indicate the quality of data in the spec.owner field -- `techdocsFactRetriever`: Generates facts related to the completeness of techdocs configuration for entities - -## Backend Example - -Here's an example backend setup that will use the three included fact retrievers so you can get an idea of how this all works. This will be the entire contents of your `techInsights.ts` file found at `\packages\backend\src\plugins` as per [Adding the plugin to your `packages/backend`](#adding-the-plugin-to-your-packagesbackend) - -```ts -import { - createRouter, - buildTechInsightsContext, - createFactRetrieverRegistration, - entityOwnershipFactRetriever, - entityMetadataFactRetriever, - techdocsFactRetriever, -} from '@backstage/plugin-tech-insights-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; -import { - JsonRulesEngineFactCheckerFactory, - JSON_RULE_ENGINE_CHECK_TYPE, -} from '@backstage/plugin-tech-insights-backend-module-jsonfc'; - -const ttlTwoWeeks = { timeToLive: { weeks: 2 } }; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const techInsightsContext = await buildTechInsightsContext({ - logger: env.logger, - config: env.config, - database: env.database, - discovery: env.discovery, - tokenManager: env.tokenManager, - scheduler: env.scheduler, - factRetrievers: [ - createFactRetrieverRegistration({ - cadence: '0 */6 * * *', // Run every 6 hours - https://crontab.guru/#0_*/6_*_*_* - factRetriever: entityOwnershipFactRetriever, - lifecycle: ttlTwoWeeks, - }), - createFactRetrieverRegistration({ - cadence: '0 */6 * * *', - factRetriever: entityMetadataFactRetriever, - lifecycle: ttlTwoWeeks, - }), - createFactRetrieverRegistration({ - cadence: '0 */6 * * *', - factRetriever: techdocsFactRetriever, - lifecycle: ttlTwoWeeks, - }), - ], - factCheckerFactory: new JsonRulesEngineFactCheckerFactory({ - logger: env.logger, - checks: [ - { - id: 'groupOwnerCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'Group Owner Check', - description: - 'Verifies that a Group has been set as the owner for this entity', - factIds: ['entityOwnershipFactRetriever'], - rule: { - conditions: { - all: [ - { - fact: 'hasGroupOwner', - operator: 'equal', - value: true, - }, - ], - }, - }, - }, - { - id: 'titleCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'Title Check', - description: - 'Verifies that a Title, used to improve readability, has been set for this entity', - factIds: ['entityMetadataFactRetriever'], - rule: { - conditions: { - all: [ - { - fact: 'hasTitle', - operator: 'equal', - value: true, - }, - ], - }, - }, - }, - { - id: 'techDocsCheck', - type: JSON_RULE_ENGINE_CHECK_TYPE, - name: 'TechDocs Check', - description: - 'Verifies that TechDocs has been enabled for this entity', - factIds: ['techdocsFactRetriever'], - rule: { - conditions: { - all: [ - { - fact: 'hasAnnotationBackstageIoTechdocsRef', - operator: 'equal', - value: true, - }, - ], - }, - }, - }, - ], - }), - }); - - return await createRouter({ - ...techInsightsContext, - logger: env.logger, - config: env.config, - }); -} -``` diff --git a/plugins/tech-insights-backend/api-report.md b/plugins/tech-insights-backend/api-report.md deleted file mode 100644 index 631e792141..0000000000 --- a/plugins/tech-insights-backend/api-report.md +++ /dev/null @@ -1,136 +0,0 @@ -## API Report File for "@backstage/plugin-tech-insights-backend" - -> 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 { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { Config } from '@backstage/config'; -import { Duration } from 'luxon'; -import express from 'express'; -import { FactChecker } from '@backstage/plugin-tech-insights-node'; -import { FactCheckerFactory } from '@backstage/plugin-tech-insights-node'; -import { FactLifecycle } from '@backstage/plugin-tech-insights-node'; -import { FactRetriever } from '@backstage/plugin-tech-insights-node'; -import { FactRetrieverRegistration } from '@backstage/plugin-tech-insights-node'; -import { FactRetrieverRegistry as FactRetrieverRegistry_2 } from '@backstage/plugin-tech-insights-node'; -import { HumanDuration } from '@backstage/types'; -import { Logger } from 'winston'; -import { PersistenceContext as PersistenceContext_2 } from '@backstage/plugin-tech-insights-node'; -import { PluginDatabaseManager } from '@backstage/backend-common'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { PluginTaskScheduler } from '@backstage/backend-tasks'; -import { TechInsightCheck } from '@backstage/plugin-tech-insights-node'; -import { TokenManager } from '@backstage/backend-common'; - -// @public -export const buildTechInsightsContext: < - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, ->( - options: TechInsightsOptions, -) => Promise>; - -// @public -export function createFactRetrieverRegistration( - options: FactRetrieverRegistrationOptions, -): FactRetrieverRegistration; - -// @public -export function createRouter< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, ->(options: RouterOptions): Promise; - -// @public -export const entityMetadataFactRetriever: FactRetriever; - -// @public -export const entityOwnershipFactRetriever: FactRetriever; - -// @public -export interface FactRetrieverEngine { - getJobRegistration(ref: string): Promise; - schedule(): Promise; - triggerJob(ref: string): Promise; -} - -// @public (undocumented) -export type FactRetrieverRegistrationOptions = { - cadence: string; - factRetriever: FactRetriever; - lifecycle?: FactLifecycle; - timeout?: Duration | HumanDuration; - initialDelay?: Duration | HumanDuration; -}; - -// @public @deprecated (undocumented) -export type FactRetrieverRegistry = FactRetrieverRegistry_2; - -// @public -export const initializePersistenceContext: ( - database: PluginDatabaseManager, - options?: PersistenceContextOptions, -) => Promise; - -// @public @deprecated (undocumented) -export type PersistenceContext = PersistenceContext_2; - -// @public -export type PersistenceContextOptions = { - logger: Logger; -}; - -// @public -export interface RouterOptions< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - config: Config; - factChecker?: FactChecker; - logger: Logger; - persistenceContext: PersistenceContext_2; -} - -// @public -export const techdocsFactRetriever: FactRetriever; - -// @public (undocumented) -export type TechInsightsContext< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> = { - factChecker?: FactChecker; - persistenceContext: PersistenceContext_2; - factRetrieverEngine: FactRetrieverEngine; -}; - -// @public (undocumented) -export interface TechInsightsOptions< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - // (undocumented) - config: Config; - // (undocumented) - database: PluginDatabaseManager; - // (undocumented) - discovery: PluginEndpointDiscovery; - factCheckerFactory?: FactCheckerFactory; - factRetrieverRegistry?: FactRetrieverRegistry_2; - factRetrievers?: FactRetrieverRegistration[]; - // (undocumented) - logger: Logger; - persistenceContext?: PersistenceContext_2; - // (undocumented) - scheduler: PluginTaskScheduler; - // (undocumented) - tokenManager: TokenManager; -} - -// @public -const techInsightsPlugin: () => BackendFeature; -export default techInsightsPlugin; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/tech-insights-backend/catalog-info.yaml b/plugins/tech-insights-backend/catalog-info.yaml deleted file mode 100644 index ac3e86c4d6..0000000000 --- a/plugins/tech-insights-backend/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-tech-insights-backend - title: '@backstage/plugin-tech-insights-backend' -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: xantier diff --git a/plugins/tech-insights-backend/config.d.ts b/plugins/tech-insights-backend/config.d.ts deleted file mode 100644 index cb3602dc60..0000000000 --- a/plugins/tech-insights-backend/config.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { HumanDuration } from '@backstage/types'; - -export interface Config { - /** Configuration options for the tech-insights plugin */ - techInsights?: { - /** Configuration options for fact retrievers */ - factRetrievers?: { - /** Configuration for a fact retriever and its registration identified by its name. */ - [name: string]: { - /** A cron expression to indicate when the fact retriever should be triggered. */ - cadence: string; - /** Optional duration of the initial delay. */ - initialDelay?: HumanDuration; - /** Optional lifecycle definition indicating the cleanup logic of facts when this retriever is run. */ - lifecycle?: { timeToLive: HumanDuration } | { maxItems: number }; - /** Optional duration to determine how long the fact retriever should be allowed to run, defaults to 5 minutes. */ - timeout?: HumanDuration; - }; - }; - }; -} diff --git a/plugins/tech-insights-backend/knip-report.md b/plugins/tech-insights-backend/knip-report.md deleted file mode 100644 index 68e21a7a12..0000000000 --- a/plugins/tech-insights-backend/knip-report.md +++ /dev/null @@ -1,15 +0,0 @@ -# Knip report - -## Unused dependencies (2) - -| Name | Location | Severity | -| :--- | :----------- | :------- | -| uuid | package.json | error | -| yn | package.json | error | - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :-------------- | :----------- | :------- | -| wait-for-expect | package.json | error | - diff --git a/plugins/tech-insights-backend/migrations/202109061111_fact_schemas.js b/plugins/tech-insights-backend/migrations/202109061111_fact_schemas.js deleted file mode 100644 index 2521f6d8bb..0000000000 --- a/plugins/tech-insights-backend/migrations/202109061111_fact_schemas.js +++ /dev/null @@ -1,60 +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. - */ - -// @ts-check - -/** - * @param {import('knex').Knex} knex - */ -exports.up = async function up(knex) { - await knex.schema.createTable('fact_schemas', table => { - table.comment( - 'The table for tech insight fact schemas. Containing a versioned data model definition for a collection of facts.', - ); - table - .string('id') - .notNullable() - .comment('Identifier of the fact retriever plugin/package'); - table - .string('version') - .notNullable() - .comment('SemVer string defining the version of schema.'); - table - .string('entityFilter') - .nullable() - .comment( - 'A serialized entity filter object used to determine which entities this schema is applicable to.', - ); - table - .text('schema') - .notNullable() - .comment( - 'Fact schema defining the values/types what this version of the fact would contain.', - ); - table.primary(['id', 'version']); - table.index('id', 'fact_schema_id_idx'); - }); -}; - -/** - * @param {import('knex').Knex} knex - */ -exports.down = async function down(knex) { - await knex.schema.alterTable('fact_schemas', table => { - table.dropIndex([], 'fact_schema_id_idx'); - }); - await knex.schema.dropTable('fact_schemas'); -}; diff --git a/plugins/tech-insights-backend/migrations/202109061212_facts.js b/plugins/tech-insights-backend/migrations/202109061212_facts.js deleted file mode 100644 index 237d826869..0000000000 --- a/plugins/tech-insights-backend/migrations/202109061212_facts.js +++ /dev/null @@ -1,72 +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. - */ - -// @ts-check - -/** - * @param {import('knex').Knex} knex - */ -exports.up = async function up(knex) { - await knex.schema.createTable('facts', table => { - table.comment( - 'The table for tech insight fact collections. Contains facts for individual fact retriever namespace/ref.', - ); - table - .string('id') - .notNullable() - .comment('Unique identifier of the fact retriever plugin/package'); - table - .string('version') - .notNullable() - .comment( - 'SemVer string defining the version of schema this fact is based on.', - ); - table - .dateTime('timestamp') - .defaultTo(knex.fn.now()) - .notNullable() - .comment('The timestamp when this entry was created'); - table - .string('entity') - .notNullable() - .comment('Identifier of the entity these facts relate to'); - table - .text('facts') - .notNullable() - .comment( - 'Values of the fact collection stored as key-value pairs in JSON format.', - ); - - table - .foreign(['id', 'version']) - .references(['id', 'version']) - .inTable('fact_schemas'); - - table.index(['id', 'entity'], 'fact_id_entity_idx'); - table.index('id', 'fact_id_idx'); - }); -}; - -/** - * @param {import('knex').Knex} knex - */ -exports.down = async function down(knex) { - await knex.schema.alterTable('facts', table => { - table.dropIndex([], 'fact_id_idx'); - table.dropIndex([], 'fact_id_entity_idx'); - }); - await knex.schema.dropTable('facts'); -}; diff --git a/plugins/tech-insights-backend/migrations/2022060100821_facts_timestamp_precision.js b/plugins/tech-insights-backend/migrations/2022060100821_facts_timestamp_precision.js deleted file mode 100644 index ea889d3928..0000000000 --- a/plugins/tech-insights-backend/migrations/2022060100821_facts_timestamp_precision.js +++ /dev/null @@ -1,36 +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. - */ - -// @ts-check - -/** - * @param {import('knex').Knex} knex - */ -exports.up = async function up(knex) { - await knex.schema.alterTable('facts', table => { - table - .dateTime('timestamp', { precision: 0 }) - .defaultTo(knex.fn.now()) - .notNullable() - .comment('The timestamp when this entry was created') - .alter(); - }); -}; - -/** - * @param {import('knex').Knex} _knex - */ -exports.down = async function down(_knex) {}; diff --git a/plugins/tech-insights-backend/migrations/20230213170839_latest-facts-index.js b/plugins/tech-insights-backend/migrations/20230213170839_latest-facts-index.js deleted file mode 100644 index 94a589f59d..0000000000 --- a/plugins/tech-insights-backend/migrations/20230213170839_latest-facts-index.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const indexName = 'fact_id_entity_timestamp_idx'; -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = async knex => { - await knex.schema.alterTable('facts', table => { - table.index(['id', 'entity', 'timestamp'], indexName); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = async knex => { - await knex.schema.alterTable('facts', table => { - table.dropIndex(indexName); - }); -}; diff --git a/plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js b/plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js deleted file mode 100644 index 848fb25777..0000000000 --- a/plugins/tech-insights-backend/migrations/20230925145017_increase_filter_fact_schemas_size.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const factSchemasTable = 'fact_schemas'; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.up = async function up(knex) { - await knex.schema.alterTable(factSchemasTable, table => { - table.text('entityFilter').alter(); - }); -}; - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ -exports.down = async function down() { - await knex.schema.alterTable(factSchemasTable, table => { - table.string('entityFilter').alter(); - }); -}; diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json deleted file mode 100644 index e2b0798f16..0000000000 --- a/plugins/tech-insights-backend/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.24-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/tech-insights-backend" - }, - "keywords": [ - "backstage", - "tech-insights", - "reporting" - ], - "scripts": { - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/backend-tasks": "workspace:^", - "@backstage/catalog-client": "workspace:^", - "@backstage/catalog-model": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-tech-insights-common": "workspace:^", - "@backstage/plugin-tech-insights-node": "workspace:^", - "@backstage/types": "workspace:^", - "@types/express": "^4.17.6", - "@types/luxon": "^3.0.0", - "express": "^4.17.1", - "express-promise-router": "^4.1.0", - "knex": "^3.0.0", - "lodash": "^4.17.21", - "luxon": "^3.0.0", - "semver": "^7.5.3", - "uuid": "^8.3.2", - "winston": "^3.2.1", - "yn": "^4.0.0" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^", - "@types/semver": "^7.3.8", - "@types/supertest": "^2.0.8", - "supertest": "^6.1.3", - "wait-for-expect": "^3.0.2" - }, - "files": [ - "config.d.ts", - "dist", - "migrations/**/*.{js,d.ts}" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/tech-insights-backend/src/deprecated.ts b/plugins/tech-insights-backend/src/deprecated.ts deleted file mode 100644 index 1074e6f910..0000000000 --- a/plugins/tech-insights-backend/src/deprecated.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - FactRetrieverRegistry as FactRetrieverRegistry_, - PersistenceContext as PersistenceContext_, -} from '@backstage/plugin-tech-insights-node'; - -/** - * @public - * @deprecated Use FactRetrieverRegistry from `@backstage/plugin-tech-insights-node` instead. - */ -export type FactRetrieverRegistry = FactRetrieverRegistry_; - -/** - * @public - * @deprecated Use PersistenceContext from `@backstage/plugin-tech-insights-node` instead. - */ -export type PersistenceContext = PersistenceContext_; diff --git a/plugins/tech-insights-backend/src/index.ts b/plugins/tech-insights-backend/src/index.ts deleted file mode 100644 index a582a04ebf..0000000000 --- a/plugins/tech-insights-backend/src/index.ts +++ /dev/null @@ -1,19 +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. - */ - -export { techInsightsPlugin as default } from './plugin'; -export * from './deprecated'; -export * from './service'; diff --git a/plugins/tech-insights-backend/src/plugin/config.test.ts b/plugins/tech-insights-backend/src/plugin/config.test.ts deleted file mode 100644 index 09b4954583..0000000000 --- a/plugins/tech-insights-backend/src/plugin/config.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ConfigReader } from '@backstage/config'; -import { FactRetriever, TTL } from '@backstage/plugin-tech-insights-node'; -import { createFactRetrieverRegistrationFromConfig } from './config'; - -describe('config', () => { - const mockFactRetriever = jest.fn() as unknown as FactRetriever; - - describe('createFactRetrieverRegistrationFromConfig', () => { - it('no config return undefined', () => { - const config = new ConfigReader({}); - const registration = createFactRetrieverRegistrationFromConfig( - config, - 'any', - mockFactRetriever, - ); - - expect(registration).toBeUndefined(); - }); - - it('no entry for fact retriever return undefined', () => { - const config = new ConfigReader({ - techInsights: { - factRetrievers: {}, - }, - }); - const registration = createFactRetrieverRegistrationFromConfig( - config, - 'any', - mockFactRetriever, - ); - - expect(registration).toBeUndefined(); - }); - - it('with config for fact retriever return registration', () => { - const config = new ConfigReader({ - techInsights: { - factRetrievers: { - any: { - cadence: '*/15 * * * *', - lifecycle: { timeToLive: { weeks: 2 } }, - }, - }, - }, - }); - - const registration = createFactRetrieverRegistrationFromConfig( - config, - 'any', - mockFactRetriever, - ); - - expect(registration).toBeDefined(); - expect(registration!.cadence).toEqual('*/15 * * * *'); - expect((registration!.lifecycle! as TTL).timeToLive).toEqual({ - weeks: 2, - }); - }); - }); -}); diff --git a/plugins/tech-insights-backend/src/plugin/config.ts b/plugins/tech-insights-backend/src/plugin/config.ts deleted file mode 100644 index 25827fbbc5..0000000000 --- a/plugins/tech-insights-backend/src/plugin/config.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Config, readDurationFromConfig } from '@backstage/config'; -import { - FactLifecycle, - FactRetriever, - FactRetrieverRegistration, -} from '@backstage/plugin-tech-insights-node'; -import { - createFactRetrieverRegistration, - FactRetrieverRegistrationOptions, -} from '../service'; - -type FactRetrieverConfig = Omit< - FactRetrieverRegistrationOptions, - 'factRetriever' ->; - -function readLifecycleConfig( - config: Config | undefined, -): FactLifecycle | undefined { - if (!config) { - return undefined; - } - - if (config.has('maxItems')) { - return { - maxItems: config.getNumber('maxItems'), - }; - } - - return { - timeToLive: readDurationFromConfig(config.getConfig('timeToLive')), - }; -} - -function readFactRetrieverConfig( - config: Config, - name: string, -): FactRetrieverConfig | undefined { - const factRetrieverConfig = config.getOptionalConfig( - `techInsights.factRetrievers.${name}`, - ); - if (!factRetrieverConfig) { - return undefined; - } - - const cadence = factRetrieverConfig.getString('cadence'); - const initialDelay = factRetrieverConfig.has('initialDelay') - ? readDurationFromConfig(factRetrieverConfig.getConfig('initialDelay')) - : undefined; - const lifecycle = readLifecycleConfig( - factRetrieverConfig.getOptionalConfig('lifecycle'), - ); - const timeout = factRetrieverConfig.has('timeout') - ? readDurationFromConfig(factRetrieverConfig.getConfig('timeout')) - : undefined; - - return { - cadence, - initialDelay, - lifecycle, - timeout, - }; -} - -export function createFactRetrieverRegistrationFromConfig( - config: Config, - name: string, - factRetriever: FactRetriever, -): FactRetrieverRegistration | undefined { - const factRetrieverConfig = readFactRetrieverConfig(config, name); - - return factRetrieverConfig - ? createFactRetrieverRegistration({ - ...factRetrieverConfig, - factRetriever, - }) - : undefined; -} diff --git a/plugins/tech-insights-backend/src/plugin/index.ts b/plugins/tech-insights-backend/src/plugin/index.ts deleted file mode 100644 index dd13bde435..0000000000 --- a/plugins/tech-insights-backend/src/plugin/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './plugin'; diff --git a/plugins/tech-insights-backend/src/plugin/plugin.test.ts b/plugins/tech-insights-backend/src/plugin/plugin.test.ts deleted file mode 100644 index 66d06b827e..0000000000 --- a/plugins/tech-insights-backend/src/plugin/plugin.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; -import { techInsightsPlugin } from './plugin'; - -describe('techInsightsPlugin', () => { - it('should register tech-insights plugin and its router', async () => { - const httpRouterMock = mockServices.httpRouter.mock(); - - await startTestBackend({ - extensionPoints: [], - features: [ - techInsightsPlugin(), - httpRouterMock.factory, - mockServices.database.factory(), - mockServices.logger.factory(), - mockServices.rootConfig.factory({ - data: { - techInsights: { - factRetrievers: { - entityOwnershipFactRetriever: { - cadence: '*/15 * * * *', - lifecycle: { timeToLive: { weeks: 2 } }, - }, - }, - }, - }, - }), - mockServices.scheduler.factory(), - mockServices.tokenManager.factory(), - ], - }); - - expect(httpRouterMock.use).toHaveBeenCalledTimes(1); - }); -}); diff --git a/plugins/tech-insights-backend/src/plugin/plugin.ts b/plugins/tech-insights-backend/src/plugin/plugin.ts deleted file mode 100644 index 6da1ac1637..0000000000 --- a/plugins/tech-insights-backend/src/plugin/plugin.ts +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { - FactCheckerFactory, - FactRetriever, - FactRetrieverRegistration, - FactRetrieverRegistry, - PersistenceContext, - TechInsightCheck, - techInsightsFactCheckerFactoryExtensionPoint, - techInsightsFactRetrieverRegistryExtensionPoint, - techInsightsFactRetrieversExtensionPoint, - techInsightsPersistenceContextExtensionPoint, -} from '@backstage/plugin-tech-insights-node'; -import { - buildTechInsightsContext, - createRouter, - entityMetadataFactRetriever, - entityOwnershipFactRetriever, - techdocsFactRetriever, -} from '../service'; -import { createFactRetrieverRegistrationFromConfig } from './config'; - -/** - * The tech-insights backend plugin. - * - * @public - */ -export const techInsightsPlugin = createBackendPlugin({ - pluginId: 'tech-insights', - register(env) { - let factCheckerFactory: - | FactCheckerFactory - | undefined = undefined; - env.registerExtensionPoint(techInsightsFactCheckerFactoryExtensionPoint, { - setFactCheckerFactory< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, - >(factory: FactCheckerFactory): void { - factCheckerFactory = factory; - }, - }); - - let factRetrieverRegistry: FactRetrieverRegistry | undefined = undefined; - env.registerExtensionPoint( - techInsightsFactRetrieverRegistryExtensionPoint, - { - setFactRetrieverRegistry(registry: FactRetrieverRegistry): void { - factRetrieverRegistry = registry; - }, - }, - ); - - // initialized with built-in fact retrievers - // only added as registration if there is config for them - const addedFactRetrievers: Record = { - entityMetadataFactRetriever, - entityOwnershipFactRetriever, - techdocsFactRetriever, - }; - env.registerExtensionPoint(techInsightsFactRetrieversExtensionPoint, { - addFactRetrievers(factRetrievers: Record): void { - Object.entries(factRetrievers).forEach(([key, value]) => { - addedFactRetrievers[key] = value; - }); - }, - }); - - let persistenceContext: PersistenceContext | undefined = undefined; - env.registerExtensionPoint(techInsightsPersistenceContextExtensionPoint, { - setPersistenceContext(context: PersistenceContext): void { - persistenceContext = context; - }, - }); - - env.registerInit({ - deps: { - config: coreServices.rootConfig, - database: coreServices.database, - discovery: coreServices.discovery, - httpRouter: coreServices.httpRouter, - logger: coreServices.logger, - scheduler: coreServices.scheduler, - tokenManager: coreServices.tokenManager, - }, - async init({ - config, - database, - discovery, - httpRouter, - logger, - scheduler, - tokenManager, - }) { - const winstonLogger = loggerToWinstonLogger(logger); - const factRetrievers: FactRetrieverRegistration[] = Object.entries( - addedFactRetrievers, - ) - .map(([name, factRetriever]) => - createFactRetrieverRegistrationFromConfig( - config, - name, - factRetriever, - ), - ) - .filter(registration => registration) as FactRetrieverRegistration[]; - - const context = await buildTechInsightsContext({ - config, - database, - discovery, - factCheckerFactory, - factRetrieverRegistry, - factRetrievers, - logger: winstonLogger, - persistenceContext, - scheduler, - tokenManager, - }); - - httpRouter.use( - await createRouter({ - ...context, - config, - logger: winstonLogger, - }), - ); - }, - }); - }, -}); diff --git a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts b/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts deleted file mode 100644 index 3bbaf9edf5..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.test.ts +++ /dev/null @@ -1,237 +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 { - FactRetriever, - FactRetrieverRegistration, - FactRetrieverRegistry, - FactSchemaDefinition, - TechInsightFact, - TechInsightsStore, -} from '@backstage/plugin-tech-insights-node'; -import { - DefaultFactRetrieverEngine, - FactRetrieverEngine, -} from './FactRetrieverEngine'; -import { - DatabaseManager, - getVoidLogger, - ServerTokenManager, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; -import { TaskScheduler } from '@backstage/backend-tasks'; - -jest.setTimeout(60_000); - -const testFactRetriever: FactRetriever = { - id: 'test_factretriever', - version: '0.0.1', - title: 'Test 1', - description: 'testing', - entityFilter: [{ kind: 'component' }], - schema: { - testnumberfact: { - type: 'integer', - description: '', - }, - }, - handler: jest.fn(async () => { - return [ - { - entity: { - namespace: 'a', - kind: 'a', - name: 'a', - }, - facts: { - testnumberfact: 1, - }, - }, - ]; - }), -}; - -const defaultCadence = '1 * * * *'; - -describe('FactRetrieverEngine', () => { - let engine: FactRetrieverEngine; - type FactSchemaAssertionCallback = ( - factSchemaDefinition: FactSchemaDefinition, - ) => void; - - type FactInsertionAssertionCallback = ({ - facts, - id, - }: { - id: string; - facts: TechInsightFact[]; - }) => void; - - function createMockRepository( - insertCallback: FactInsertionAssertionCallback, - assertionCallback: FactSchemaAssertionCallback, - ): TechInsightsStore { - return { - async insertFacts(f: { facts: TechInsightFact[]; id: string }) { - insertCallback(f); - }, - async insertFactSchema(def: FactSchemaDefinition) { - assertionCallback(def); - }, - } as unknown as TechInsightsStore; - } - - function createMockFactRetrieverRegistry( - cadence?: string, - factRetriever?: FactRetriever, - ): FactRetrieverRegistry { - const cron = cadence ?? defaultCadence; - const retriever: FactRetriever = factRetriever - ? factRetriever - : testFactRetriever; - return { - listRetrievers(): FactRetriever[] { - return [retriever]; - }, - listRegistrations(): FactRetrieverRegistration[] { - return [{ factRetriever: retriever, cadence: cron }]; - }, - get: (_: string): FactRetrieverRegistration => { - return { factRetriever: retriever, cadence: cron }; - }, - } as unknown as FactRetrieverRegistry; - } - - const databases = TestDatabases.create({ - ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], - }); - - async function createEngine( - databaseId: TestDatabaseId, - insert: FactInsertionAssertionCallback, - schema: FactSchemaAssertionCallback, - cadence?: string, - factRetriever?: FactRetriever, - ): Promise { - const knex = await databases.init(databaseId); - const databaseManager: Partial = { - forPlugin: (_: string) => ({ - getClient: async () => knex, - }), - }; - const manager = databaseManager as DatabaseManager; - const scheduler = new TaskScheduler(manager, getVoidLogger()); - return await DefaultFactRetrieverEngine.create({ - factRetrieverContext: { - logger: getVoidLogger(), - config: ConfigReader.fromConfigs([]), - tokenManager: ServerTokenManager.noop(), - discovery: { - getBaseUrl: (_: string) => Promise.resolve('http://mock.url'), - getExternalBaseUrl: (_: string) => Promise.resolve('http://mock.url'), - }, - }, - factRetrieverRegistry: createMockFactRetrieverRegistry( - cadence, - factRetriever, - ), - repository: createMockRepository(insert, schema), - scheduler: scheduler.forPlugin('tech-insights'), - }); - } - - it.each(databases.eachSupportedId())( - 'Should update fact retriever schemas on initialization with %s', - async databaseId => { - const schemaAssertionCallback = jest.fn((def: FactSchemaDefinition) => { - expect(def.id).toEqual('test_factretriever'); - expect(def.version).toEqual('0.0.1'); - expect(def.entityFilter).toEqual([{ kind: 'component' }]); - expect(def.schema).toEqual({ - testnumberfact: { - type: 'integer', - description: '', - }, - }); - }); - - engine = await createEngine( - databaseId, - () => {}, - schemaAssertionCallback, - ); - expect(schemaAssertionCallback).toHaveBeenCalled(); - }, - ); - - it.each(databases.eachSupportedId())( - 'Should insert facts when scheduled step is run with %s', - async databaseId => { - function insertCallback({ - facts, - id, - }: { - id: string; - facts: TechInsightFact[]; - }) { - expect(facts).toHaveLength(1); - expect(id).toEqual('test_factretriever'); - expect(facts[0]).toEqual({ - entity: { - namespace: 'a', - kind: 'a', - name: 'a', - }, - facts: { - testnumberfact: 1, - }, - }); - } - - jest.useFakeTimers(); - - try { - const handler = jest.fn(); - engine = await createEngine( - databaseId, - insertCallback, - () => {}, - undefined, - { ...testFactRetriever, handler }, - ); - await engine.schedule(); - const job = await engine.getJobRegistration(testFactRetriever.id); - expect(job.cadence!!).toEqual(defaultCadence); - - await engine.triggerJob(job.factRetriever.id); - jest.advanceTimersByTime(5000); - - const handlerParam = await new Promise(resolve => - handler.mockImplementation(resolve), - ); - - await expect(handlerParam).toEqual( - expect.objectContaining({ - entityFilter: testFactRetriever.entityFilter, - }), - ); - } finally { - jest.useRealTimers(); - } - }, - ); -}); diff --git a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.ts b/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.ts deleted file mode 100644 index 04035ca8c7..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/FactRetrieverEngine.ts +++ /dev/null @@ -1,212 +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 { - FactLifecycle, - FactRetriever, - FactRetrieverContext, - FactRetrieverRegistration, - FactRetrieverRegistry, - TechInsightFact, - TechInsightsStore, -} from '@backstage/plugin-tech-insights-node'; -import { Logger } from 'winston'; -import { PluginTaskScheduler } from '@backstage/backend-tasks'; -import { Duration } from 'luxon'; - -function randomDailyCron() { - const rand = (min: number, max: number) => - Math.floor(Math.random() * (max - min + 1) + min); - return `${rand(0, 59)} ${rand(0, 23)} * * *`; -} - -function duration(startTimestamp: [number, number]): string { - const delta = process.hrtime(startTimestamp); - const seconds = delta[0] + delta[1] / 1e9; - return `${seconds.toFixed(1)}s`; -} - -/** - * @public - * - * FactRetrieverEngine responsible scheduling and running fact retrieval tasks. - */ -export interface FactRetrieverEngine { - /** - * Schedules fact retriever run cycles based on configuration provided in the registration. - * - * Default implementation uses backend-tasks to handle scheduling. This function can be called multiple - * times, where initial calls schedule the tasks and subsequent invocations update the schedules. - */ - schedule(): Promise; - - /** - * Provides possibility to manually run a fact retriever job and construct fact data - * - * @param ref - Reference to the task name stored in the executor database. By convention this is the fact retriever id - */ - triggerJob(ref: string): Promise; - - /** - * Exposes fact retriever job configuration information about previous and next runs and schedule - * - * @param ref - Reference to the task name stored in the executor database. By convention this is the fact retriever id - */ - getJobRegistration(ref: string): Promise; -} - -export class DefaultFactRetrieverEngine implements FactRetrieverEngine { - private constructor( - private readonly repository: TechInsightsStore, - private readonly factRetrieverRegistry: FactRetrieverRegistry, - private readonly factRetrieverContext: FactRetrieverContext, - private readonly logger: Logger, - private readonly scheduler: PluginTaskScheduler, - private readonly defaultCadence?: string, - private readonly defaultTimeout?: Duration, - private readonly defaultInitialDelay?: Duration, - ) {} - - static async create(options: { - repository: TechInsightsStore; - factRetrieverRegistry: FactRetrieverRegistry; - factRetrieverContext: FactRetrieverContext; - scheduler: PluginTaskScheduler; - defaultCadence?: string; - defaultTimeout?: Duration; - defaultInitialDelay?: Duration; - }) { - const { - repository, - factRetrieverRegistry, - factRetrieverContext, - scheduler, - defaultCadence, - defaultTimeout, - defaultInitialDelay, - } = options; - - const retrievers = await factRetrieverRegistry.listRetrievers(); - await Promise.all(retrievers.map(it => repository.insertFactSchema(it))); - - return new DefaultFactRetrieverEngine( - repository, - factRetrieverRegistry, - factRetrieverContext, - factRetrieverContext.logger, - scheduler, - defaultCadence, - defaultTimeout, - defaultInitialDelay, - ); - } - - async schedule() { - const registrations = await this.factRetrieverRegistry.listRegistrations(); - const newRegs: string[] = []; - - await Promise.all( - registrations.map(async registration => { - const { factRetriever, cadence, lifecycle, timeout, initialDelay } = - registration; - const cronExpression = - cadence || this.defaultCadence || randomDailyCron(); - const timeLimit = - timeout || this.defaultTimeout || Duration.fromObject({ minutes: 5 }); - const initialDelaySetting = - initialDelay || - this.defaultInitialDelay || - Duration.fromObject({ seconds: 5 }); - try { - await this.scheduler.scheduleTask({ - id: factRetriever.id, - frequency: { cron: cronExpression }, - fn: this.createFactRetrieverHandler(factRetriever, lifecycle), - timeout: timeLimit, - // We add a delay in order to prevent errors due to the - // fact that the backend is not yet online in a cold-start scenario - initialDelay: initialDelaySetting, - }); - newRegs.push(factRetriever.id); - } catch (e) { - this.logger.warn( - `Failed to schedule fact retriever ${factRetriever.id}, ${e}`, - ); - } - }), - ); - - this.logger.info( - `Scheduled ${newRegs.length}/${registrations.length} fact retrievers into the tech-insights engine`, - ); - } - - getJobRegistration(ref: string): Promise { - return this.factRetrieverRegistry.get(ref); - } - - async triggerJob(ref: string): Promise { - await this.scheduler.triggerTask(ref); - } - - private createFactRetrieverHandler( - factRetriever: FactRetriever, - lifecycle?: FactLifecycle, - ) { - return async () => { - const startTimestamp = process.hrtime(); - this.logger.info( - `Retrieving facts for fact retriever ${factRetriever.id}`, - ); - - let facts: TechInsightFact[] = []; - try { - facts = await factRetriever.handler({ - ...this.factRetrieverContext, - logger: this.logger.child({ factRetrieverId: factRetriever.id }), - entityFilter: factRetriever.entityFilter, - }); - this.logger.debug( - `Retrieved ${facts.length} facts for fact retriever ${ - factRetriever.id - } in ${duration(startTimestamp)}`, - ); - } catch (e) { - this.logger.error( - `Failed to retrieve facts for retriever ${factRetriever.id}`, - e, - ); - } - - try { - await this.repository.insertFacts({ - id: factRetriever.id, - facts, - lifecycle, - }); - this.logger.info( - `Stored ${facts.length} facts for fact retriever ${ - factRetriever.id - } in ${duration(startTimestamp)}`, - ); - } catch (e) { - this.logger.warn( - `Failed to insert facts for fact retriever ${factRetriever.id}`, - e, - ); - } - }; - } -} diff --git a/plugins/tech-insights-backend/src/service/fact/FactRetrieverRegistry.ts b/plugins/tech-insights-backend/src/service/fact/FactRetrieverRegistry.ts deleted file mode 100644 index 42caca6b20..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/FactRetrieverRegistry.ts +++ /dev/null @@ -1,75 +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 { - FactRetriever, - FactRetrieverRegistration, - FactRetrieverRegistry, -} from '@backstage/plugin-tech-insights-node'; -import { FactSchema } from '@backstage/plugin-tech-insights-common'; -import { ConflictError, NotFoundError } from '@backstage/errors'; - -/** - * A basic in memory fact retriever registry. - * - * You can replace this with a persistence based version using the FactRetrieverRegistry interface. - * - */ -export class DefaultFactRetrieverRegistry implements FactRetrieverRegistry { - private readonly retrievers = new Map(); - - constructor(retrievers: FactRetrieverRegistration[]) { - retrievers.forEach(r => { - this.registerSync(r); - }); - } - - registerSync(registration: FactRetrieverRegistration) { - if (this.retrievers.has(registration.factRetriever.id)) { - throw new ConflictError( - `Tech insight fact retriever with identifier '${registration.factRetriever.id}' has already been registered`, - ); - } - this.retrievers.set(registration.factRetriever.id, registration); - } - - async register(registration: FactRetrieverRegistration) { - this.registerSync(registration); - } - - async get(retrieverReference: string): Promise { - const registration = this.retrievers.get(retrieverReference); - if (!registration) { - throw new NotFoundError( - `Tech insight fact retriever with identifier '${retrieverReference}' is not registered.`, - ); - } - return registration; - } - - async listRetrievers(): Promise { - return [...this.retrievers.values()].map(it => it.factRetriever); - } - - async listRegistrations(): Promise { - return [...this.retrievers.values()]; - } - - async getSchemas(): Promise { - const retrievers = await this.listRetrievers(); - return retrievers.map(it => it.schema); - } -} diff --git a/plugins/tech-insights-backend/src/service/fact/createFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/createFactRetriever.ts deleted file mode 100644 index 2d715e5e4c..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/createFactRetriever.ts +++ /dev/null @@ -1,82 +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 { HumanDuration } from '@backstage/types'; -import { - FactLifecycle, - FactRetriever, - FactRetrieverRegistration, -} from '@backstage/plugin-tech-insights-node'; -import { Duration } from 'luxon'; - -/** - * @public - * - * @param cadence - cron expression to indicate when the fact retriever should be triggered - * @param factRetriever - Implementation of fact retriever consisting of at least id, version, schema and handler - * @param lifecycle - Optional lifecycle definition indicating the cleanup logic of facts when this retriever is run - * @param timeout - Optional duration to determine how long the fact retriever should be allowed to run, defaults to 5 minutes - * - */ -export type FactRetrieverRegistrationOptions = { - cadence: string; - factRetriever: FactRetriever; - lifecycle?: FactLifecycle; - timeout?: Duration | HumanDuration; - initialDelay?: Duration | HumanDuration; -}; - -/** - * @public - * - * A helper function to construct fact retriever registrations. - * @param cadence - Cron expression to indicate when the fact retriever should be triggered - * @param factRetriever - Implementation of fact retriever consisting of at least id, version, schema and handler - * @param lifecycle - Optional lifecycle definition indicating the cleanup logic of facts when this retriever is run - * @param timeout - Optional duration to determine how long the fact retriever should be allowed to run, defaults to 5 minutes - * @param initialDelay - Optional initial delay to determine how long the fact retriever should wait before the initial run, defaults to 5 seconds - * - * - * @remarks - * - * Cron expressions help: - * ┌────────────── second (optional) - # │ ┌──────────── minute - # │ │ ┌────────── hour - # │ │ │ ┌──────── day of month - # │ │ │ │ ┌────── month - # │ │ │ │ │ ┌──── day of week - # │ │ │ │ │ │ - # │ │ │ │ │ │ - # * * * * * * - * - * Valid lifecycle values: - * \{ ttl: \{ weeks: 2 \} \} -- This fact retriever will remove items that are older than 2 weeks when it is run - * \{ maxItems: 7 \} -- This fact retriever will leave 7 newest items in the database when it is run - * - */ -export function createFactRetrieverRegistration( - options: FactRetrieverRegistrationOptions, -): FactRetrieverRegistration { - const { cadence, factRetriever, lifecycle, timeout, initialDelay } = options; - return { - cadence, - factRetriever, - lifecycle, - timeout, - initialDelay, - }; -} diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts deleted file mode 100644 index 31400788b5..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.test.ts +++ /dev/null @@ -1,183 +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 { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { - PluginEndpointDiscovery, - getVoidLogger, - ServerTokenManager, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; -import { entityMetadataFactRetriever } from './entityMetadataFactRetriever'; - -const getEntitiesMock = jest.fn(); -jest.mock('@backstage/catalog-client', () => { - return { - CatalogClient: jest - .fn() - .mockImplementation(() => ({ getEntities: getEntitiesMock })), - }; -}); -const discovery: jest.Mocked = { - getBaseUrl: jest.fn(), - getExternalBaseUrl: jest.fn(), -}; - -const defaultEntityListResponse: GetEntitiesResponse = { - items: [ - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-owner', - description: 'service with an owner', - tags: ['a-tag'], - annotations: { - 'backstage.io/techdocs-ref': 'dir:.', - }, - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: 'team-a', - }, - relations: [ - { - type: RELATION_OWNED_BY, - targetRef: 'group:default/my-team', - }, - ], - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-incomplete-data', - description: '', - tags: [], - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: '', - }, - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-user-owner', - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: 'user:my-user', - }, - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'user-a', - }, - kind: 'User', - spec: { - memberOf: 'group-a', - }, - }, - ], -}; - -const handlerContext = { - discovery, - logger: getVoidLogger(), - config: ConfigReader.fromConfigs([]), - tokenManager: ServerTokenManager.noop(), -}; - -const entityFactRetriever = entityMetadataFactRetriever; - -describe('entityMetadataFactRetriever', () => { - beforeEach(() => { - getEntitiesMock.mockResolvedValue(defaultEntityListResponse); - }); - afterEach(() => { - getEntitiesMock.mockClear(); - }); - - describe('hasDescription', () => { - describe('where the entity has a description', () => { - it('returns true for hasDescription', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-owner'), - ).toMatchObject({ - facts: { - hasDescription: true, - }, - }); - }); - }); - describe('where the entity does not have a description', () => { - it('returns false for hasDescription', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect(facts.find(it => it.entity.name === 'user-a')).toMatchObject({ - facts: { - hasDescription: false, - }, - }); - }); - }); - describe('where the entity has an empty value for description', () => { - it('returns false for hasDescription', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-incomplete-data'), - ).toMatchObject({ - facts: { - hasDescription: false, - }, - }); - }); - }); - }); - describe('hasTags', () => { - describe('where the entity has tags', () => { - it('returns true for hasTags', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-owner'), - ).toMatchObject({ - facts: { - hasTags: true, - }, - }); - }); - }); - describe('where the entity has no tags', () => { - it('returns false for hasTags', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-incomplete-data'), - ).toMatchObject({ - facts: { - hasTags: false, - }, - }); - }); - }); - }); -}); diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts deleted file mode 100644 index 3103f9bdd5..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityMetadataFactRetriever.ts +++ /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 { - FactRetriever, - FactRetrieverContext, -} from '@backstage/plugin-tech-insights-node'; -import { CatalogClient } from '@backstage/catalog-client'; -import { Entity } from '@backstage/catalog-model'; -import isEmpty from 'lodash/isEmpty'; - -/** - * Generates facts which indicate the completeness of entity metadata. - * - * @public - */ -export const entityMetadataFactRetriever: FactRetriever = { - id: 'entityMetadataFactRetriever', - version: '0.0.1', - title: 'Entity Metadata', - description: - 'Generates facts which indicate the completeness of entity metadata', - schema: { - hasTitle: { - type: 'boolean', - description: 'The entity has a title in metadata', - }, - hasDescription: { - type: 'boolean', - description: 'The entity has a description in metadata', - }, - hasTags: { - type: 'boolean', - description: 'The entity has tags in metadata', - }, - }, - handler: async ({ - discovery, - entityFilter, - tokenManager, - }: FactRetrieverContext) => { - const { token } = await tokenManager.getToken(); - const catalogClient = new CatalogClient({ - discoveryApi: discovery, - }); - const entities = await catalogClient.getEntities( - { filter: entityFilter }, - { token }, - ); - - return entities.items.map((entity: Entity) => { - return { - entity: { - namespace: entity.metadata.namespace!, - kind: entity.kind, - name: entity.metadata.name, - }, - facts: { - hasTitle: Boolean(entity.metadata?.title), - hasDescription: Boolean(entity.metadata?.description), - hasTags: !isEmpty(entity.metadata?.tags), - }, - }; - }); - }, -}; diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts deleted file mode 100644 index 7a77ef91c4..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.test.ts +++ /dev/null @@ -1,196 +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 { entityOwnershipFactRetriever } from './entityOwnershipFactRetriever'; -import { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { - PluginEndpointDiscovery, - getVoidLogger, - ServerTokenManager, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; - -const getEntitiesMock = jest.fn(); -jest.mock('@backstage/catalog-client', () => { - return { - CatalogClient: jest - .fn() - .mockImplementation(() => ({ getEntities: getEntitiesMock })), - }; -}); -const discovery: jest.Mocked = { - getBaseUrl: jest.fn(), - getExternalBaseUrl: jest.fn(), -}; - -const defaultEntityListResponse: GetEntitiesResponse = { - items: [ - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-owner', - description: 'service with an owner', - tags: ['a-tag'], - annotations: { - 'backstage.io/techdocs-ref': 'dir:.', - }, - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: 'team-a', - }, - relations: [ - { - type: RELATION_OWNED_BY, - targetRef: 'group:default/team-a', - }, - ], - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-incomplete-data', - description: '', - tags: [], - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: '', - }, - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-user-owner', - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: 'user:my-user', - }, - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'user-a', - }, - kind: 'User', - spec: { - memberOf: 'group-a', - }, - }, - ], -}; - -const handlerContext = { - discovery, - logger: getVoidLogger(), - config: ConfigReader.fromConfigs([]), - tokenManager: ServerTokenManager.noop(), -}; - -const entityFactRetriever = entityOwnershipFactRetriever; - -describe('entityFactRetriever', () => { - beforeEach(() => { - getEntitiesMock.mockResolvedValue(defaultEntityListResponse); - }); - afterEach(() => { - getEntitiesMock.mockClear(); - }); - - describe('hasOwner', () => { - describe('where the entity has an owner in the spec', () => { - it('returns true for hasOwner', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-owner'), - ).toMatchObject({ - facts: { - hasOwner: true, - }, - }); - }); - }); - describe('where the entity has an empty value for owner in the spec', () => { - it('returns false for hasOwner', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-incomplete-data'), - ).toMatchObject({ - facts: { - hasOwner: false, - }, - }); - }); - }); - - describe('where the entity doesn not have an owner in the spec', () => { - it('returns false for hasOwner', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect(facts.find(it => it.entity.name === 'user-a')).toMatchObject({ - facts: { - hasOwner: false, - }, - }); - }); - }); - }); - describe('hasGroupOwner', () => { - describe('where the entity has an group as owner in the spec', () => { - it('returns true for hasGroupOwner', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-owner'), - ).toMatchObject({ - facts: { - hasGroupOwner: true, - }, - }); - }); - }); - describe('where the entity has a user as owner in the spec', () => { - it('returns false for hasGroupOwner', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-user-owner'), - ).toMatchObject({ - facts: { - hasGroupOwner: false, - }, - }); - }); - }); - describe('where the entity has an empty value for owner in the spec', () => { - it('returns false for hasGroupOwner', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-incomplete-data'), - ).toMatchObject({ - facts: { - hasGroupOwner: false, - }, - }); - }); - }); - }); -}); diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts deleted file mode 100644 index 974f1d30cd..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityOwnershipFactRetriever.ts +++ /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 { - FactRetriever, - FactRetrieverContext, -} from '@backstage/plugin-tech-insights-node'; -import { CatalogClient } from '@backstage/catalog-client'; -import { Entity } from '@backstage/catalog-model'; - -/** - * Generates facts which indicate the quality of data in the spec.owner field. - * - * @public - */ -export const entityOwnershipFactRetriever: FactRetriever = { - id: 'entityOwnershipFactRetriever', - version: '0.0.1', - title: 'Entity Ownership', - description: - 'Generates facts which indicate the quality of data in the spec.owner field', - entityFilter: [ - { kind: ['component', 'domain', 'system', 'api', 'resource', 'template'] }, - ], - schema: { - hasOwner: { - type: 'boolean', - description: 'The spec.owner field is set', - }, - hasGroupOwner: { - type: 'boolean', - description: 'The spec.owner field is set and refers to a group', - }, - }, - handler: async ({ - discovery, - entityFilter, - tokenManager, - }: FactRetrieverContext) => { - const { token } = await tokenManager.getToken(); - const catalogClient = new CatalogClient({ - discoveryApi: discovery, - }); - const entities = await catalogClient.getEntities( - { filter: entityFilter }, - { token }, - ); - - return entities.items.map((entity: Entity) => { - return { - entity: { - namespace: entity.metadata.namespace!, - kind: entity.kind, - name: entity.metadata.name, - }, - facts: { - hasOwner: Boolean(entity.spec?.owner), - hasGroupOwner: Boolean( - entity.spec?.owner && - !(entity.spec?.owner as string).startsWith('user:'), - ), - }, - }; - }); - }, -}; diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts deleted file mode 100644 index 5983a82e1d..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts +++ /dev/null @@ -1,19 +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. - */ - -export * from './entityMetadataFactRetriever'; -export * from './entityOwnershipFactRetriever'; -export * from './techdocsFactRetriever'; diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts deleted file mode 100644 index 0c70f6c9f1..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.test.ts +++ /dev/null @@ -1,149 +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 { techdocsFactRetriever } from './techdocsFactRetriever'; -import { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { - PluginEndpointDiscovery, - getVoidLogger, - ServerTokenManager, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { GetEntitiesResponse } from '@backstage/catalog-client'; - -const getEntitiesMock = jest.fn(); -jest.mock('@backstage/catalog-client', () => { - return { - CatalogClient: jest - .fn() - .mockImplementation(() => ({ getEntities: getEntitiesMock })), - }; -}); -const discovery: jest.Mocked = { - getBaseUrl: jest.fn(), - getExternalBaseUrl: jest.fn(), -}; - -const defaultEntityListResponse: GetEntitiesResponse = { - items: [ - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-owner', - description: 'service with an owner', - tags: ['a-tag'], - annotations: { - 'backstage.io/techdocs-ref': 'dir:.', - }, - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: 'team-a', - }, - relations: [ - { - type: RELATION_OWNED_BY, - targetRef: 'group:default/team-a', - }, - ], - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-incomplete-data', - description: '', - tags: [], - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: '', - }, - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'service-with-user-owner', - }, - kind: 'Component', - spec: { - type: 'service', - lifecycle: 'test', - owner: 'user:my-user', - }, - }, - { - apiVersion: 'backstage.io/v1beta1', - metadata: { - name: 'user-a', - }, - kind: 'User', - spec: { - memberOf: 'group-a', - }, - }, - ], -}; - -const handlerContext = { - discovery, - logger: getVoidLogger(), - config: ConfigReader.fromConfigs([]), - tokenManager: ServerTokenManager.noop(), -}; - -const entityFactRetriever = techdocsFactRetriever; - -describe('techdocsFactRetriever', () => { - beforeEach(() => { - getEntitiesMock.mockResolvedValue(defaultEntityListResponse); - }); - afterEach(() => { - getEntitiesMock.mockClear(); - }); - - describe('hasAnnotationBackstageIoTechdocsRef', () => { - describe('where the retriever is configured to check for the techdocs annotation', () => { - describe('where the entity has the techdocs annotation', () => { - it('returns true for hasAnnotationBackstageIoTechdocsRef', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-owner'), - ).toMatchObject({ - facts: { - hasAnnotationBackstageIoTechdocsRef: true, - }, - }); - }); - }); - describe('where the entity is missing the techdocs annotation', () => { - it('returns false for hasAnnotationBackstageIoTechdocsRef', async () => { - const facts = await entityFactRetriever.handler(handlerContext); - expect( - facts.find(it => it.entity.name === 'service-with-incomplete-data'), - ).toMatchObject({ - facts: { - hasAnnotationBackstageIoTechdocsRef: false, - }, - }); - }); - }); - }); - }); -}); diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts deleted file mode 100644 index bd07bb3ecc..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/techdocsFactRetriever.ts +++ /dev/null @@ -1,76 +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 { - FactRetriever, - FactRetrieverContext, -} from '@backstage/plugin-tech-insights-node'; -import { CatalogClient } from '@backstage/catalog-client'; -import { Entity } from '@backstage/catalog-model'; -import { entityHasAnnotation, generateAnnotationFactName } from './utils'; - -const techdocsAnnotation = 'backstage.io/techdocs-ref'; -const techdocsAnnotationFactName = - generateAnnotationFactName(techdocsAnnotation); - -/** - * Generates facts related to the completeness of techdocs configuration for entities. - * - * @public - */ -export const techdocsFactRetriever: FactRetriever = { - id: 'techdocsFactRetriever', - version: '0.0.1', - title: 'Tech Docs', - description: - 'Generates facts related to the completeness of techdocs configuration for entities', - schema: { - [techdocsAnnotationFactName]: { - type: 'boolean', - description: 'The entity has a TechDocs reference annotation', - }, - }, - handler: async ({ - discovery, - entityFilter, - tokenManager, - }: FactRetrieverContext) => { - const { token } = await tokenManager.getToken(); - const catalogClient = new CatalogClient({ - discoveryApi: discovery, - }); - const entities = await catalogClient.getEntities( - { filter: entityFilter }, - { token }, - ); - - return entities.items.map((entity: Entity) => { - return { - entity: { - namespace: entity.metadata.namespace!, - kind: entity.kind, - name: entity.metadata.name, - }, - facts: { - [techdocsAnnotationFactName]: entityHasAnnotation( - entity, - techdocsAnnotation, - ), - }, - }; - }); - }, -}; diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/utils.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/utils.ts deleted file mode 100644 index 0238721e99..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/utils.ts +++ /dev/null @@ -1,37 +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 camelCase from 'lodash/camelCase'; -import { Entity } from '@backstage/catalog-model'; -import { get } from 'lodash'; -import { - FactLifecycle, - MaxItems, - TTL, -} from '@backstage/plugin-tech-insights-node'; - -export const generateAnnotationFactName = (annotation: string) => - camelCase(`hasAnnotation-${annotation}`); - -export const entityHasAnnotation = (entity: Entity, annotation: string) => - Boolean(get(entity, ['metadata', 'annotations', annotation])); - -export const isTtl = (lifecycle: FactLifecycle): lifecycle is TTL => { - return !!(lifecycle as TTL).timeToLive; -}; - -export const isMaxItems = (lifecycle: FactLifecycle): lifecycle is MaxItems => { - return !!(lifecycle as MaxItems).maxItems; -}; diff --git a/plugins/tech-insights-backend/src/service/fact/index.ts b/plugins/tech-insights-backend/src/service/fact/index.ts deleted file mode 100644 index b3df648a8e..0000000000 --- a/plugins/tech-insights-backend/src/service/fact/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { createFactRetrieverRegistration } from './createFactRetriever'; -export type { FactRetrieverRegistrationOptions } from './createFactRetriever'; -export type { FactRetrieverEngine } from './FactRetrieverEngine'; -export * from './factRetrievers'; diff --git a/plugins/tech-insights-backend/src/service/index.ts b/plugins/tech-insights-backend/src/service/index.ts deleted file mode 100644 index 5306ad26d6..0000000000 --- a/plugins/tech-insights-backend/src/service/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './fact'; -export * from './persistence'; -export * from './router'; -export type { RouterOptions } from './router'; - -export { buildTechInsightsContext } from './techInsightsContextBuilder'; -export type { - TechInsightsOptions, - TechInsightsContext, -} from './techInsightsContextBuilder'; diff --git a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts deleted file mode 100644 index d778e84c79..0000000000 --- a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts +++ /dev/null @@ -1,622 +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 { DateTime, Duration } from 'luxon'; -import { TechInsightsStore } from '@backstage/plugin-tech-insights-node'; -import { Knex as KnexType, Knex } from 'knex'; -import { TestDatabases } from '@backstage/backend-test-utils'; -import { getVoidLogger } from '@backstage/backend-common'; -import { initializePersistenceContext } from './persistenceContext'; - -const factSchemas = [ - { - id: 'test-fact', - version: '0.0.1-test', - entityFilter: JSON.stringify([{ kind: 'component' }]), - schema: JSON.stringify({ - testNumberFact: { - type: 'integer', - description: 'Test fact with a number type', - }, - }), - }, -]; -const additionalFactSchemas = [ - { - id: 'test-fact', - version: '1.2.1-test', - entityFilter: JSON.stringify([{ kind: 'component' }]), - schema: JSON.stringify({ - testNumberFact: { - type: 'integer', - description: 'Test fact with a number type', - }, - testStringFact: { - type: 'string', - description: 'Test fact with a string type', - }, - }), - }, - { - id: 'test-fact', - version: '1.1.1-test', - entityFilter: JSON.stringify([{ kind: 'component' }]), - schema: JSON.stringify({ - testStringFact: { - type: 'string', - description: 'Test fact with a string type', - }, - }), - }, -]; - -const secondSchema = { - id: 'second-test-fact', - version: '0.0.1-test', - entityFilter: JSON.stringify([{ kind: 'service' }]), - schema: JSON.stringify({ - testStringFact: { - type: 'string', - description: 'Test fact with a string type', - }, - }), -}; - -const now = DateTime.now().toISO()!; -const shortlyInTheFuture = DateTime.now() - .plus(Duration.fromMillis(555)) - .toISO()!; -const farInTheFuture = DateTime.now() - .plus(Duration.fromMillis(555666777)) - .toISO()!; - -const facts = [ - { - timestamp: now, - id: 'test-fact', - version: '0.0.1-test', - entity: 'a:a/a', - facts: JSON.stringify({ - testNumberFact: 1, - }), - }, - { - timestamp: shortlyInTheFuture, - id: 'test-fact', - version: '0.0.1-test', - entity: 'a:a/a', - facts: JSON.stringify({ - testNumberFact: 2, - }), - }, -]; - -const additionalFacts = [ - { - timestamp: farInTheFuture, - id: 'test-fact', - version: '0.0.1-test', - entity: 'a:a/a', - facts: JSON.stringify({ - testNumberFact: 3, - }), - }, -]; - -const sameFactsDiffDateSchema = { - id: 'same-fact-diff-date-test', - version: '0.0.1-test', - entityFilter: JSON.stringify([{ kind: 'service' }]), - schema: JSON.stringify({ - testStringFact: { - type: 'string', - description: 'Test fact with a string type', - }, - }), -}; - -const sameFactsDiffDateNow = DateTime.now().toISO()!; -const sameFactsDiffDateNearFuture = DateTime.now() - .plus(Duration.fromMillis(555)) - .toISO()!; -const sameFactsDiffDateFuture = DateTime.now() - .plus(Duration.fromMillis(1000)) - .toISO()!; - -const multipleSameFacts = [ - { - timestamp: sameFactsDiffDateNow, - id: sameFactsDiffDateSchema.id, - version: '0.0.1-test', - entity: 'a:a/a', - facts: JSON.stringify({ - testNumberFact: 1, - }), - }, - { - timestamp: sameFactsDiffDateNearFuture, - id: sameFactsDiffDateSchema.id, - version: '0.0.1-test', - entity: 'a:a/a', - facts: JSON.stringify({ - testNumberFact: 2, - }), - }, - { - timestamp: sameFactsDiffDateFuture, - id: 'multiple-same-facts', - version: '0.0.1-test', - entity: 'a:a/a', - facts: JSON.stringify({ - testNumberFact: 3, - }), - }, -]; - -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(database, { - logger: getVoidLogger(), - }) - ).techInsightsStore; - }); - beforeEach(async () => { - await testDbClient.batchInsert('fact_schemas', factSchemas); - await testDbClient.batchInsert('facts', facts); - }); - afterEach(async () => { - await testDbClient('facts').delete(); - await testDbClient('fact_schemas').delete(); - }); - - const baseAssertionFact = { - id: 'test-fact', - entity: { namespace: 'a', kind: 'a', name: 'a' }, - timestamp: DateTime.fromISO(shortlyInTheFuture), - version: '0.0.1-test', - facts: { testNumberFact: 2 }, - }; - - it('should be able to return latest schema', async () => { - const schemas = await store.getLatestSchemas(); - expect(schemas[0]).toMatchObject({ - id: 'test-fact', - version: '0.0.1-test', - entityFilter: [{ kind: 'component' }], - testNumberFact: { - type: 'integer', - description: 'Test fact with a number type', - }, - }); - }); - - it('should return last schema based on semver', async () => { - await testDbClient.batchInsert('fact_schemas', additionalFactSchemas); - - const schemas = await store.getLatestSchemas(); - expect(schemas[0]).toMatchObject({ - id: 'test-fact', - version: '1.2.1-test', - entityFilter: [{ kind: 'component' }], - testNumberFact: { - type: 'integer', - description: 'Test fact with a number type', - }, - testStringFact: { - type: 'string', - description: 'Test fact with a string type', - }, - }); - }); - - it('should return multiple schemas if those exists', async () => { - await testDbClient.batchInsert('fact_schemas', [ - { - ...secondSchema, - id: 'second', - }, - ]); - - const schemas = await store.getLatestSchemas(); - expect(schemas).toHaveLength(2); - expect(schemas[0]).toMatchObject({ - id: 'test-fact', - version: '0.0.1-test', - entityFilter: [{ kind: 'component' }], - testNumberFact: { - type: 'integer', - description: 'Test fact with a number type', - }, - }); - expect(schemas[1]).toMatchObject({ - id: 'second', - version: '0.0.1-test', - entityFilter: [{ kind: 'service' }], - testStringFact: { - type: 'string', - description: 'Test fact with a string type', - }, - }); - }); - - it('should return latest facts only for the correct id', async () => { - const returnedFact = await store.getLatestFactsByIds( - ['test-fact'], - 'a:a/a', - ); - expect(returnedFact['test-fact']).toMatchObject(baseAssertionFact); - }); - - it('should return latest fact with multiple entries', async () => { - await testDbClient.batchInsert('fact_schemas', [sameFactsDiffDateSchema]); - await testDbClient.batchInsert( - 'facts', - multipleSameFacts.map(fact => ({ - ...fact, - id: sameFactsDiffDateSchema.id, - })), - ); - - const returnedFacts = await store.getLatestFactsByIds( - ['test-fact', sameFactsDiffDateSchema.id], - 'a:a/a', - ); - - expect(returnedFacts['test-fact']).toMatchObject({ - ...baseAssertionFact, - }); - - expect(returnedFacts[sameFactsDiffDateSchema.id]).toMatchObject({ - ...baseAssertionFact, - id: sameFactsDiffDateSchema.id, - timestamp: DateTime.fromISO(sameFactsDiffDateFuture), - facts: { testNumberFact: 3 }, - }); - }); - - it('should return latest facts for multiple ids', async () => { - await testDbClient.batchInsert('fact_schemas', [secondSchema]); - await testDbClient.batchInsert( - 'facts', - additionalFacts.map(fact => ({ - ...fact, - id: 'second-test-fact', - timestamp: farInTheFuture, - })), - ); - const returnedFacts = await store.getLatestFactsByIds( - ['test-fact', 'second-test-fact'], - 'a:a/a', - ); - - expect(returnedFacts['test-fact']).toMatchObject({ - ...baseAssertionFact, - }); - expect(returnedFacts['second-test-fact']).toMatchObject({ - ...baseAssertionFact, - id: 'second-test-fact', - timestamp: DateTime.fromISO(farInTheFuture), - facts: { testNumberFact: 3 }, - }); - }); - - it('should return facts correctly between time range', async () => { - await testDbClient.batchInsert('facts', additionalFacts); - const returnedFacts = await store.getFactsBetweenTimestampsByIds( - ['test-fact'], - 'a:a/a', - DateTime.fromISO(now), - DateTime.fromISO(shortlyInTheFuture).plus(Duration.fromMillis(10)), - ); - expect(returnedFacts['test-fact']).toHaveLength(2); - - expect(returnedFacts['test-fact'][0]).toMatchObject({ - ...baseAssertionFact, - timestamp: DateTime.fromISO(now), - facts: { testNumberFact: 1 }, - }); - expect(returnedFacts['test-fact'][1]).toMatchObject({ - ...baseAssertionFact, - }); - expect(returnedFacts['test-fact']).not.toContainEqual({ - ...baseAssertionFact, - timestamp: DateTime.fromISO(farInTheFuture), - facts: { testNumberFact: 3 }, - }); - }); - - it('should delete extraneous rows when MaxItems is defined. Should leave only n latest', async () => { - const deviledFact = (it: {}) => ({ - ...it, - facts: JSON.stringify({ - testNumberFact: 666, - }), - }); - await testDbClient.batchInsert('facts', additionalFacts.map(deviledFact)); - - const preInsertionFacts = await testDbClient('facts').select(); - expect(preInsertionFacts).toHaveLength(3); - - const timestamp = DateTime.now().plus(Duration.fromMillis(1111)); - const factToBeInserted = { - timestamp: timestamp, - entity: { - namespace: 'a', - kind: 'a', - name: 'a', - }, - facts: { - testNumberFact: 555, - }, - }; - const maxItems = 2; - await store.insertFacts({ - id: 'test-fact', - facts: [factToBeInserted], - lifecycle: { maxItems }, - }); - - const afterInsertionFacts = await testDbClient('facts').select(); - expect(afterInsertionFacts).toHaveLength(maxItems); - expect(afterInsertionFacts[0]).toMatchObject( - deviledFact(additionalFacts[0]), - ); - expect(afterInsertionFacts[1]).toMatchObject({ - id: 'test-fact', - version: '0.0.1-test', - timestamp: timestamp.toISO(), - entity: 'a:a/a', - facts: JSON.stringify({ testNumberFact: 555 }), - }); - }); - - it('should delete extraneous rows for each entity when MaxItems is defined. Should leave only n latest', async () => { - const deviledFact = (it: {}) => ({ - ...it, - facts: JSON.stringify({ - testNumberFact: 666, - }), - }); - await testDbClient.batchInsert('facts', additionalFacts.map(deviledFact)); - - const preInsertionFacts = await testDbClient('facts').select(); - - expect(preInsertionFacts).toHaveLength(3); - - await testDbClient.batchInsert( - 'facts', - preInsertionFacts.map(it => ({ ...it, entity: 'b:b/b' })), - ); - - const timestamp = DateTime.now().plus(Duration.fromMillis(1111)); - const factsToBeInserted = [ - { - timestamp: timestamp, - entity: { - namespace: 'a', - kind: 'a', - name: 'a', - }, - facts: { - testNumberFact: 555, - }, - }, - { - timestamp: timestamp, - entity: { - namespace: 'b', - kind: 'b', - name: 'b', - }, - facts: { - testNumberFact: 555, - }, - }, - ]; - const maxItems = 2; - await store.insertFacts({ - id: 'test-fact', - facts: factsToBeInserted, - lifecycle: { maxItems }, - }); - - const afterInsertionFacts = await testDbClient('facts').select(); - - const inserted = { - id: 'test-fact', - version: '0.0.1-test', - timestamp: timestamp.toISO(), - entity: 'a:a/a', - facts: JSON.stringify({ testNumberFact: 555 }), - }; - expect(afterInsertionFacts).toHaveLength(maxItems * 2); - expect(afterInsertionFacts[0]).toMatchObject( - deviledFact(additionalFacts[0]), - ); - - expect(afterInsertionFacts[1]).toMatchObject({ - ...deviledFact(additionalFacts[0]), - entity: 'b:b/b', - }); - expect(afterInsertionFacts[2]).toMatchObject(inserted); - expect(afterInsertionFacts[3]).toMatchObject({ - ...inserted, - entity: 'b:b/b', - }); - }); - - it('should delete extraneous rows when TTL is defined. Should leave only items with timestamp greater than TTL', async () => { - const oldStaledOutFact = (it: {}) => ({ - ...it, - facts: JSON.stringify({ - testNumberFact: 666, - }), - timestamp: DateTime.now().minus({ weeks: 3 }).toISO(), - }); - await testDbClient.batchInsert( - 'facts', - additionalFacts.map(oldStaledOutFact), - ); - - const preInsertionFacts = await testDbClient('facts').select(); - expect(preInsertionFacts).toHaveLength(3); - - const timestamp = DateTime.now().plus(Duration.fromMillis(1111)); - const factToBeInserted = { - timestamp: timestamp, - entity: { - namespace: 'a', - kind: 'a', - name: 'a', - }, - facts: { - testNumberFact: 555, - }, - }; - await store.insertFacts({ - id: 'test-fact', - facts: [factToBeInserted], - lifecycle: { timeToLive: { weeks: 2 } }, - }); - - const afterInsertionFacts = await testDbClient('facts') - .select() - .orderBy('timestamp', 'desc'); - expect(afterInsertionFacts).toHaveLength(3); - expect(afterInsertionFacts[0]).toMatchObject({ - id: 'test-fact', - version: '0.0.1-test', - timestamp: timestamp.toISO(), - entity: 'a:a/a', - facts: JSON.stringify({ testNumberFact: 555 }), - }); - expect(afterInsertionFacts[1]).toMatchObject(facts[1]); - expect(afterInsertionFacts[2]).toMatchObject(facts[0]); - - expect(afterInsertionFacts).not.toContainEqual( - oldStaledOutFact(additionalFacts[0]), - ); - }); - - it('should delete extraneous rows for each entity when TTL expired', async () => { - const oldStaledOutFact = (it: {}) => ({ - ...it, - facts: JSON.stringify({ - testNumberFact: 666, - }), - timestamp: DateTime.now().minus({ weeks: 3 }).toISO(), - }); - await testDbClient.batchInsert( - 'facts', - additionalFacts.map(oldStaledOutFact), - ); - - const preInsertionFacts = await testDbClient('facts').select(); - expect(preInsertionFacts).toHaveLength(3); - - await testDbClient.batchInsert( - 'facts', - preInsertionFacts.map(it => ({ ...it, entity: 'b:b/b' })), - ); - - const timestamp = DateTime.now().plus(Duration.fromMillis(1111)); - const factsToBeInserted = [ - { - timestamp: timestamp, - entity: { - namespace: 'a', - kind: 'a', - name: 'a', - }, - facts: { - testNumberFact: 555, - }, - }, - { - timestamp: timestamp, - entity: { - namespace: 'b', - kind: 'b', - name: 'b', - }, - facts: { - testNumberFact: 555, - }, - }, - ]; - await store.insertFacts({ - id: 'test-fact', - facts: factsToBeInserted, - lifecycle: { timeToLive: { weeks: 2 } }, - }); - - const afterInsertionFacts = await testDbClient('facts') - .select() - .orderBy('timestamp', 'desc'); - - expect(afterInsertionFacts).toHaveLength(6); - expect(afterInsertionFacts[0]).toMatchObject({ - id: 'test-fact', - version: '0.0.1-test', - timestamp: timestamp.toISO(), - entity: 'a:a/a', - facts: JSON.stringify({ testNumberFact: 555 }), - }); - expect(afterInsertionFacts[1]).toMatchObject({ - id: 'test-fact', - version: '0.0.1-test', - timestamp: timestamp.toISO(), - entity: 'b:b/b', - facts: JSON.stringify({ testNumberFact: 555 }), - }); - expect(afterInsertionFacts[2]).toMatchObject(facts[1]); - expect(afterInsertionFacts[3]).toMatchObject({ - ...facts[1], - entity: 'b:b/b', - }); - expect(afterInsertionFacts[4]).toMatchObject(facts[0]); - expect(afterInsertionFacts[5]).toMatchObject({ - ...facts[0], - entity: 'b:b/b', - }); - - expect(afterInsertionFacts).not.toContainEqual( - oldStaledOutFact(additionalFacts[0]), - ); - expect(afterInsertionFacts).not.toContainEqual({ - ...oldStaledOutFact(additionalFacts[0]), - entity: 'b:b/b', - }); - }); -}); diff --git a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts deleted file mode 100644 index 761a6bd273..0000000000 --- a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.ts +++ /dev/null @@ -1,281 +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 { Knex } from 'knex'; -import { - FactLifecycle, - FactSchemaDefinition, - FlatTechInsightFact, - TechInsightFact, - TechInsightsStore, -} from '@backstage/plugin-tech-insights-node'; -import { FactSchema } from '@backstage/plugin-tech-insights-common'; -import { rsort } from 'semver'; -import { groupBy, omit } from 'lodash'; -import { DateTime } from 'luxon'; -import { Logger } from 'winston'; -import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; -import { isMaxItems, isTtl } from '../fact/factRetrievers/utils'; - -type Transaction = Knex.Transaction; - -export type RawDbFactRow = { - id: string; - version: string; - timestamp: Date | string; - entity: string; - facts: string; -}; - -type RawDbFactSchemaRow = { - id: string; - version: string; - schema: string; - entityFilter?: string; -}; - -/** - * Default TechInsightsDatabase implementation. - * - * @internal - */ -export class TechInsightsDatabase implements TechInsightsStore { - private readonly CHUNK_SIZE = 50; - - constructor(private readonly db: Knex, private readonly logger: Logger) {} - - async getLatestSchemas(ids?: string[]): Promise { - const queryBuilder = this.db('fact_schemas'); - if (ids) { - queryBuilder.whereIn('id', ids); - } - const existingSchemas = await queryBuilder.orderBy('id', 'desc').select(); - - const groupedSchemas = groupBy(existingSchemas, 'id'); - return Object.values(groupedSchemas) - .map(schemas => { - const sorted = rsort(schemas.map(it => it.version)); - return schemas.find(it => it.version === sorted[0])!; - }) - .map((it: RawDbFactSchemaRow) => ({ - ...omit(it, 'schema'), - ...JSON.parse(it.schema), - entityFilter: it.entityFilter ? JSON.parse(it.entityFilter) : null, - })); - } - - async insertFactSchema(schemaDefinition: FactSchemaDefinition) { - const { id, version, schema, entityFilter } = schemaDefinition; - const existingSchemas = await this.db('fact_schemas') - .where({ id }) - .and.where({ version }) - .select(); - - if (!existingSchemas || existingSchemas.length === 0) { - await this.db('fact_schemas').insert({ - id, - version, - entityFilter: entityFilter ? JSON.stringify(entityFilter) : undefined, - schema: JSON.stringify(schema), - }); - } - } - - async insertFacts({ - id, - facts, - lifecycle, - }: { - id: string; - facts: TechInsightFact[]; - lifecycle?: FactLifecycle; - }): Promise { - if (facts.length === 0) return; - const currentSchema = await this.getLatestSchema(id); - const factRows = facts.map(it => { - const ts = it.timestamp?.toISO(); - return { - id, - version: currentSchema.version, - entity: stringifyEntityRef(it.entity), - facts: JSON.stringify(it.facts), - ...(ts && { timestamp: ts }), - }; - }); - - await this.db.transaction(async tx => { - await tx.batchInsert('facts', factRows, this.CHUNK_SIZE); - - if (lifecycle && isTtl(lifecycle)) { - const expiration = DateTime.now().minus(lifecycle.timeToLive); - await this.deleteExpiredFactsByDate(tx, id, expiration); - } - if (lifecycle && isMaxItems(lifecycle)) { - await this.deleteExpiredFactsByNumber(tx, id, lifecycle.maxItems); - } - }); - } - - async getLatestFactsByIds( - ids: string[], - entityTriplet: string, - ): Promise<{ [factId: string]: FlatTechInsightFact }> { - const results = await this.db('facts') - .where({ entity: entityTriplet }) - .and.whereIn('id', ids) - .join( - this.db('facts') - .max('timestamp as maxTimestamp') - .column('id as subId') - .where({ entity: entityTriplet }) - .and.whereIn('id', ids) - .groupBy('id') - .as('subQ'), - { - 'facts.id': 'subQ.subId', - 'facts.timestamp': 'subQ.maxTimestamp', - }, - ); - return this.dbFactRowsToTechInsightFacts(results); - } - - async getFactsBetweenTimestampsByIds( - ids: string[], - entityTriplet: string, - startDateTime: DateTime, - endDateTime: DateTime, - ): Promise<{ - [factId: string]: FlatTechInsightFact[]; - }> { - const results = await this.db('facts') - .where({ entity: entityTriplet }) - .and.whereIn('id', ids) - .and.whereBetween('timestamp', [ - startDateTime.toISO(), - endDateTime.toISO(), - ]); - - return groupBy( - results.map(it => { - const { namespace, kind, name } = parseEntityRef(it.entity); - const timestamp = - typeof it.timestamp === 'string' - ? DateTime.fromISO(it.timestamp) - : DateTime.fromJSDate(it.timestamp); - return { - id: it.id, - entity: { namespace, kind, name }, - timestamp, - version: it.version, - facts: JSON.parse(it.facts), - }; - }), - 'id', - ); - } - - private async getLatestSchema(id: string): Promise { - const existingSchemas = await this.db('fact_schemas') - .where({ id }) - .orderBy('id', 'desc') - .select(); - if (existingSchemas.length < 1) { - this.logger.warn(`No schema found for ${id}. `); - throw new Error(`No schema found for ${id}. `); - } - const sorted = rsort(existingSchemas.map(it => it.version)); - return existingSchemas.find(it => it.version === sorted[0])!; - } - - private async deleteExpiredFactsByDate( - tx: Transaction, - factRetrieverId: string, - timestamp: DateTime, - ) { - await tx('facts') - .where({ id: factRetrieverId }) - .and.where('timestamp', '<', timestamp.toISO()) - .delete(); - } - - private async deleteExpiredFactsByNumber( - tx: Transaction, - factRetrieverId: string, - maxItems: number, - ) { - const deletionFilterQuery = (subTx: Knex.QueryBuilder) => - subTx - .select(['id', 'entity', 'timestamp']) - .from('facts') - .where({ id: factRetrieverId }) - .and.whereIn('entity', db => - db.distinct('entity').where({ id: factRetrieverId }), - ) - .and.leftJoin( - joinTable => - joinTable - .select('*') - .from( - this.db('facts') - .column( - { fid: 'id' }, - { fentity: 'entity' }, - { ftimestamp: 'timestamp' }, - ) - .column( - this.db.raw( - 'row_number() over (partition by id, entity order by timestamp desc) as fact_rank', - ), - ) - .as('ranks'), - ) - .where('fact_rank', '<=', maxItems) - .as('filterjoin'), - joinClause => { - joinClause - .on('filterjoin.fid', 'facts.id') - .on('filterjoin.fentity', 'facts.entity') - .on('filterjoin.ftimestamp', 'facts.timestamp'); - }, - ) - .whereNull('filterjoin.fid'); - await tx('facts') - .whereIn(['id', 'entity', 'timestamp'], database => - deletionFilterQuery(database), - ) - .delete(); - } - - private dbFactRowsToTechInsightFacts(rows: RawDbFactRow[]) { - return rows.reduce((acc, it) => { - const { namespace, kind, name } = parseEntityRef(it.entity); - const timestamp = - typeof it.timestamp === 'string' - ? DateTime.fromISO(it.timestamp) - : DateTime.fromJSDate(it.timestamp); - return { - ...acc, - [it.id]: { - id: it.id, - entity: { namespace, kind, name }, - timestamp, - version: it.version, - facts: JSON.parse(it.facts), - }, - }; - }, {}); - } -} diff --git a/plugins/tech-insights-backend/src/service/persistence/index.ts b/plugins/tech-insights-backend/src/service/persistence/index.ts deleted file mode 100644 index d87f91e1b0..0000000000 --- a/plugins/tech-insights-backend/src/service/persistence/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { initializePersistenceContext } from './persistenceContext'; -export type { PersistenceContextOptions } from './persistenceContext'; diff --git a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts deleted file mode 100644 index 3ddae3197f..0000000000 --- a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts +++ /dev/null @@ -1,63 +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 { - getVoidLogger, - PluginDatabaseManager, - resolvePackagePath, -} from '@backstage/backend-common'; -import { Logger } from 'winston'; -import { TechInsightsDatabase } from './TechInsightsDatabase'; -import { PersistenceContext } from '@backstage/plugin-tech-insights-node'; - -const migrationsDir = resolvePackagePath( - '@backstage/plugin-tech-insights-backend', - 'migrations', -); - -/** - * A Container for persistence context initialization options - * - * @public - */ -export type PersistenceContextOptions = { - logger: Logger; -}; - -const defaultOptions: PersistenceContextOptions = { - logger: getVoidLogger(), -}; - -/** - * A factory function to construct persistence context for running implementation. - * - * @public - */ -export const initializePersistenceContext = async ( - database: PluginDatabaseManager, - options: PersistenceContextOptions = defaultOptions, -): Promise => { - const client = await database.getClient(); - - if (!database.migrations?.skip) { - await client.migrate.latest({ - directory: migrationsDir, - }); - } - - return { - techInsightsStore: new TechInsightsDatabase(client, options.logger), - }; -}; diff --git a/plugins/tech-insights-backend/src/service/router.test.ts b/plugins/tech-insights-backend/src/service/router.test.ts deleted file mode 100644 index bf4313748f..0000000000 --- a/plugins/tech-insights-backend/src/service/router.test.ts +++ /dev/null @@ -1,182 +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 { buildTechInsightsContext } from './techInsightsContextBuilder'; -import { createRouter } from './router'; -import { - DatabaseManager, - getVoidLogger, - PluginDatabaseManager, - ServerTokenManager, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import request from 'supertest'; -import express from 'express'; -import { - PersistenceContext, - TechInsightsStore, -} from '@backstage/plugin-tech-insights-node'; -import { DateTime } from 'luxon'; -import { Knex } from 'knex'; -import { TaskScheduler } from '@backstage/backend-tasks'; - -describe('Tech Insights router tests', () => { - let app: express.Express; - - const latestFactsByIdsMock = jest.fn(); - const factsBetweenTimestampsByIdsMock = jest.fn(); - const latestSchemasMock = jest.fn(); - - const mockPersistenceContext: PersistenceContext = { - techInsightsStore: { - getLatestFactsByIds: latestFactsByIdsMock, - getFactsBetweenTimestampsByIds: factsBetweenTimestampsByIdsMock, - getLatestSchemas: latestSchemasMock, - } as unknown as TechInsightsStore, - }; - - afterEach(() => { - jest.resetAllMocks(); - }); - - beforeAll(async () => { - const pluginDatabase: PluginDatabaseManager = { - getClient: () => { - return Promise.resolve({ - migrate: { - latest: () => {}, - }, - }) as unknown as Promise; - }, - }; - const databaseManager: Partial = { - forPlugin: () => pluginDatabase, - }; - const manager = databaseManager as DatabaseManager; - const techInsightsContext = await buildTechInsightsContext({ - database: pluginDatabase, - logger: getVoidLogger(), - factRetrievers: [], - scheduler: new TaskScheduler(manager, getVoidLogger()).forPlugin( - 'tech-insights', - ), - config: ConfigReader.fromConfigs([]), - discovery: { - getBaseUrl: (_: string) => Promise.resolve('http://mock.url'), - getExternalBaseUrl: (_: string) => Promise.resolve('http://mock.url'), - }, - tokenManager: ServerTokenManager.noop(), - }); - - const router = await createRouter({ - logger: getVoidLogger(), - config: ConfigReader.fromConfigs([]), - ...techInsightsContext, - persistenceContext: mockPersistenceContext, - }); - - app = express().use(router); - }); - describe('/fact-schemas', () => { - it('should be able to retrieve latest schemas', async () => { - await request(app).get('/fact-schemas').expect(200); - expect(latestSchemasMock).toHaveBeenCalled(); - }); - }); - - describe('/checks', () => { - it('should not contain check endpoints when checker not present', async () => { - await request(app).get('/checks').expect(404); - await request(app).post('/checks/a/a/a').expect(404); - }); - }); - - describe('/facts/latest', () => { - it('should be able to parse id request params for fact retrieval', async () => { - await request(app) - .get('/facts/latest') - .query({ - entity: 'a:a/a', - ids: ['firstId', 'secondId'], - }) - .expect(200); - expect(latestFactsByIdsMock).toHaveBeenCalledWith( - ['firstId', 'secondId'], - 'a:a/a', - ); - }); - it('should handle singular ids in query params correctly', async () => { - await request(app) - .get('/facts/latest') - .query({ - entity: 'a:a/a', - ids: ['secondId'], - }) - .expect(200); - expect(latestFactsByIdsMock).toHaveBeenCalledWith(['secondId'], 'a:a/a'); - }); - }); - - describe('/facts/range', () => { - it('should be able to parse datetime request params for fact retrieval', async () => { - await request(app) - .get('/facts/range') - .query({ - entity: 'a:a/a', - ids: ['firstId', 'secondId'], - startDatetime: '2021-12-12T12:12:12', - endDatetime: '2022-11-11T11:11:11', - }) - .expect(200); - expect(factsBetweenTimestampsByIdsMock).toHaveBeenCalledWith( - ['firstId', 'secondId'], - 'a:a/a', - DateTime.fromISO('2021-12-12T12:12:12.000+00:00'), - DateTime.fromISO('2022-11-11T11:11:11.000+00:00'), - ); - }); - - it('should respond gracefully on parsing errors', async () => { - await request(app) - .get('/facts/range') - .query({ - entity: 'a:a/a', - ids: ['firstId', 'secondId'], - startDatetime: '2021-12-1222T12:12:12', - endDatetime: '2022-1122-11T11:11:11', - }) - .expect(422); - expect(latestFactsByIdsMock).toHaveBeenCalledTimes(0); - }); - - it('should handle singular ids in query params correctly', async () => { - await request(app) - .get('/facts/range') - .query({ - entity: 'a:a/a', - ids: ['firstId'], - startDatetime: '2021-12-12T12:12:12', - endDatetime: '2022-11-11T11:11:11', - }) - .expect(200); - expect(factsBetweenTimestampsByIdsMock).toHaveBeenCalledWith( - ['firstId'], - 'a:a/a', - DateTime.fromISO('2021-12-12T12:12:12.000+00:00'), - DateTime.fromISO('2022-11-11T11:11:11.000+00:00'), - ); - }); - }); -}); diff --git a/plugins/tech-insights-backend/src/service/router.ts b/plugins/tech-insights-backend/src/service/router.ts deleted file mode 100644 index 53c1351ffa..0000000000 --- a/plugins/tech-insights-backend/src/service/router.ts +++ /dev/null @@ -1,196 +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 express from 'express'; -import Router from 'express-promise-router'; -import { Config } from '@backstage/config'; -import { - FactChecker, - PersistenceContext, - TechInsightCheck, -} from '@backstage/plugin-tech-insights-node'; - -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { Logger } from 'winston'; -import { DateTime } from 'luxon'; -import { - CompoundEntityRef, - parseEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { errorHandler } from '@backstage/backend-common'; -import { serializeError } from '@backstage/errors'; - -/** - * @public - * - * RouterOptions to construct TechInsights endpoints - * @typeParam CheckType - Type of the check for the fact checker this builder returns - * @typeParam CheckResultType - Type of the check result for the fact checker this builder returns - */ -export interface RouterOptions< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - /** - * Optional FactChecker implementation. If omitted, endpoints are not constructed - */ - factChecker?: FactChecker; - - /** - * TechInsights PersistenceContext. Should contain an implementation of TechInsightsStore - */ - persistenceContext: PersistenceContext; - - /** - * Backstage config object - */ - config: Config; - - /** - * Implementation of Winston logger - */ - logger: Logger; -} - -/** - * @public - * - * Constructs a tech-insights router. - * - * Exposes endpoints to handle facts - * Exposes optional endpoints to handle checks if a FactChecker implementation is passed in - * - * @param options - RouterOptions object - */ -export async function createRouter< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, ->(options: RouterOptions): Promise { - const router = Router(); - router.use(express.json()); - const { persistenceContext, factChecker, logger } = options; - const { techInsightsStore } = persistenceContext; - - if (factChecker) { - logger.info('Fact checker configured. Enabling fact checking endpoints.'); - router.get('/checks', async (_req, res) => { - return res.json(await factChecker.getChecks()); - }); - - router.post('/checks/run/:namespace/:kind/:name', async (req, res) => { - const { namespace, kind, name } = req.params; - const { checks }: { checks: string[] } = req.body; - const entityTriplet = stringifyEntityRef({ namespace, kind, name }); - const checkResult = await factChecker.runChecks(entityTriplet, checks); - return res.json(checkResult); - }); - - router.post('/checks/run', async (req, res) => { - const { - checks, - entities, - }: { checks: string[]; entities: CompoundEntityRef[] } = req.body; - const tasks = entities.map(async entity => { - const entityTriplet = - typeof entity === 'string' ? entity : stringifyEntityRef(entity); - try { - const results = await factChecker.runChecks(entityTriplet, checks); - return { - entity: entityTriplet, - results, - }; - } catch (e: any) { - const error = serializeError(e); - logger.error(`${error.name}: ${error.message}`); - return { - entity: entityTriplet, - error: error, - results: [], - }; - } - }); - const results = await Promise.all(tasks); - return res.json(results); - }); - } else { - logger.info( - 'Starting tech insights module without fact checking endpoints.', - ); - } - - router.get('/fact-schemas', async (req, res) => { - const ids = req.query.ids as string[]; - return res.json(await techInsightsStore.getLatestSchemas(ids)); - }); - - /** - * /facts/latest?entity=component:default/mycomponent&ids[]=factRetrieverId1&ids[]=factRetrieverId2 - */ - router.get('/facts/latest', async (req, res) => { - const { entity } = req.query; - const { namespace, kind, name } = parseEntityRef(entity as string); - - if (!req.query.ids) { - return res - .status(422) - .json({ error: 'Failed to parse ids from request' }); - } - const ids = [req.query.ids].flat() as string[]; - return res.json( - await techInsightsStore.getLatestFactsByIds( - ids, - stringifyEntityRef({ namespace, kind, name }), - ), - ); - }); - - /** - * /facts/range?entity=component:default/mycomponent&startDateTime=2021-12-24T01:23:45&endDateTime=2021-12-31T23:59:59&ids[]=factRetrieverId1&ids[]=factRetrieverId2 - */ - router.get('/facts/range', async (req, res) => { - const { entity } = req.query; - const { namespace, kind, name } = parseEntityRef(entity as string); - - if (!req.query.ids) { - return res - .status(422) - .json({ error: 'Failed to parse ids from request' }); - } - const ids = [req.query.ids].flat() as string[]; - const startDatetime = DateTime.fromISO(req.query.startDatetime as string); - const endDatetime = DateTime.fromISO(req.query.endDatetime as string); - if (!startDatetime.isValid || !endDatetime.isValid) { - return res.status(422).json({ - message: 'Failed to parse datetime from request', - field: !startDatetime.isValid ? 'startDateTime' : 'endDateTime', - value: !startDatetime.isValid ? startDatetime : endDatetime, - }); - } - const entityTriplet = stringifyEntityRef({ namespace, kind, name }); - return res.json( - await techInsightsStore.getFactsBetweenTimestampsByIds( - ids, - entityTriplet, - startDatetime, - endDatetime, - ), - ); - }); - - router.use(errorHandler()); - return router; -} diff --git a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.test.ts b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.test.ts deleted file mode 100644 index 7a274e6f96..0000000000 --- a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 { buildTechInsightsContext } from './techInsightsContextBuilder'; -import { - DatabaseManager, - getVoidLogger, - PluginDatabaseManager, - ServerTokenManager, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { TaskScheduler } from '@backstage/backend-tasks'; -import { DefaultFactRetrieverRegistry } from './fact/FactRetrieverRegistry'; -import { Knex } from 'knex'; - -jest.mock('./fact/FactRetrieverRegistry'); -jest.mock('./fact/FactRetrieverEngine', () => ({ - DefaultFactRetrieverEngine: { - create: jest.fn().mockResolvedValue({ - schedule: jest.fn(), - }), - }, -})); - -describe('buildTechInsightsContext', () => { - const pluginDatabase: PluginDatabaseManager = { - getClient: () => { - return Promise.resolve({ - migrate: { - latest: () => {}, - }, - }) as unknown as Promise; - }, - }; - const databaseManager: Partial = { - forPlugin: () => pluginDatabase, - }; - const manager = databaseManager as DatabaseManager; - const discoveryMock = { - getBaseUrl: (_: string) => Promise.resolve('http://mock.url'), - getExternalBaseUrl: (_: string) => Promise.resolve('http://mock.url'), - }; - const scheduler = new TaskScheduler(manager, getVoidLogger()).forPlugin( - 'tech-insights', - ); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('constructs the default FactRetrieverRegistry if factRetrievers but no factRetrieverRegistry are passed', () => { - buildTechInsightsContext({ - database: pluginDatabase, - logger: getVoidLogger(), - factRetrievers: [], - scheduler: scheduler, - config: ConfigReader.fromConfigs([]), - discovery: discoveryMock, - tokenManager: ServerTokenManager.noop(), - }); - expect(DefaultFactRetrieverRegistry).toHaveBeenCalledTimes(1); - }); - - it('uses factRetrieverRegistry implementation instead of the default FactRetrieverRegistry if it is passed in', () => { - const factRetrieverRegistryMock = {} as DefaultFactRetrieverRegistry; - - buildTechInsightsContext({ - database: pluginDatabase, - logger: getVoidLogger(), - factRetrievers: [], - factRetrieverRegistry: factRetrieverRegistryMock, - scheduler: scheduler, - config: ConfigReader.fromConfigs([]), - discovery: discoveryMock, - tokenManager: ServerTokenManager.noop(), - }); - expect(DefaultFactRetrieverRegistry).not.toHaveBeenCalled(); - }); -}); diff --git a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts deleted file mode 100644 index 4f49e0031b..0000000000 --- a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts +++ /dev/null @@ -1,179 +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 { - DefaultFactRetrieverEngine, - FactRetrieverEngine, -} from './fact/FactRetrieverEngine'; -import { Logger } from 'winston'; -import { DefaultFactRetrieverRegistry } from './fact/FactRetrieverRegistry'; -import { Config } from '@backstage/config'; -import { - PluginDatabaseManager, - PluginEndpointDiscovery, - TokenManager, -} from '@backstage/backend-common'; -import { - FactChecker, - FactCheckerFactory, - FactRetrieverRegistration, - FactRetrieverRegistry, - PersistenceContext, - TechInsightCheck, -} from '@backstage/plugin-tech-insights-node'; -import { initializePersistenceContext } from './persistence'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { PluginTaskScheduler } from '@backstage/backend-tasks'; - -/** - * @public - * @typeParam CheckType - Type of the check for the fact checker this builder returns - * @typeParam CheckResultType - Type of the check result for the fact checker this builder returns - * - * Configuration options to initialize TechInsightsBuilder. Generic types params are needed if FactCheckerFactory - * is included for FactChecker creation. - */ -export interface TechInsightsOptions< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - /** - * Optional collection of FactRetrieverRegistrations (required if no factRetrieverRegistry passed in). - * Used to register FactRetrievers and their schemas and schedule an execution loop for them. - * - * Not needed if passing in your own FactRetrieverRegistry implementation. Required otherwise. - */ - factRetrievers?: FactRetrieverRegistration[]; - - /** - * Optional factory exposing a `construct` method to initialize a FactChecker implementation - */ - factCheckerFactory?: FactCheckerFactory; - - /** - * Optional FactRetrieverRegistry implementation that replaces the default one. - * - * If passing this in you don't need to pass in factRetrievers also. - */ - factRetrieverRegistry?: FactRetrieverRegistry; - - /** - * Optional persistenceContext implementation that replaces the default one. - * This can be used to replace underlying database with a more suitable implementation if needed - */ - persistenceContext?: PersistenceContext; - - logger: Logger; - config: Config; - discovery: PluginEndpointDiscovery; - database: PluginDatabaseManager; - scheduler: PluginTaskScheduler; - tokenManager: TokenManager; -} - -/** - * @public - * @typeParam CheckType - Type of the check for the fact checker this builder returns - * @typeParam CheckResultType - Type of the check result for the fact checker this builder returns - * - * A container for exported implementations related to TechInsights. - * FactChecker is present if an optional FactCheckerFactory is included in the build stage. - */ -export type TechInsightsContext< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> = { - factChecker?: FactChecker; - persistenceContext: PersistenceContext; - factRetrieverEngine: FactRetrieverEngine; -}; - -/** - * @public - * - * Constructs needed persistence context, fact retriever engine - * and optionally fact checker implementations to be used in the tech insights module. - * - * @param options - Needed options to construct TechInsightsContext - * @returns TechInsightsContext with persistence implementations and optionally an implementation of a FactChecker - */ -export const buildTechInsightsContext = async < - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, ->( - options: TechInsightsOptions, -): Promise> => { - const { - factRetrievers, - factCheckerFactory, - config, - discovery, - database, - logger, - scheduler, - tokenManager, - } = options; - - const buildFactRetrieverRegistry = (): FactRetrieverRegistry => { - if (!options.factRetrieverRegistry) { - if (!factRetrievers) { - throw new Error( - 'Failed to build FactRetrieverRegistry because no factRetrievers found', - ); - } - return new DefaultFactRetrieverRegistry(factRetrievers); - } - return options.factRetrieverRegistry; - }; - - const factRetrieverRegistry = buildFactRetrieverRegistry(); - - const persistenceContext = - options.persistenceContext ?? - (await initializePersistenceContext(database, { - logger, - })); - - const factRetrieverEngine = await DefaultFactRetrieverEngine.create({ - scheduler, - repository: persistenceContext.techInsightsStore, - factRetrieverRegistry, - factRetrieverContext: { - config, - discovery, - logger, - tokenManager, - }, - }); - - await factRetrieverEngine.schedule(); - - if (factCheckerFactory) { - const factChecker = factCheckerFactory.construct( - persistenceContext.techInsightsStore, - ); - return { - persistenceContext, - factChecker, - factRetrieverEngine, - }; - } - - return { - persistenceContext, - factRetrieverEngine, - }; -}; diff --git a/plugins/tech-insights-backend/src/setupTests.ts b/plugins/tech-insights-backend/src/setupTests.ts deleted file mode 100644 index a330613afb..0000000000 --- a/plugins/tech-insights-backend/src/setupTests.ts +++ /dev/null @@ -1,17 +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. - */ - -export {}; diff --git a/plugins/tech-insights-common/.eslintrc.js b/plugins/tech-insights-common/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/tech-insights-common/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/tech-insights-common/CHANGELOG.md b/plugins/tech-insights-common/CHANGELOG.md deleted file mode 100644 index 15e8949b5c..0000000000 --- a/plugins/tech-insights-common/CHANGELOG.md +++ /dev/null @@ -1,184 +0,0 @@ -# @backstage/plugin-tech-insights-common - -## 0.2.12 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/types@1.1.1 - -## 0.2.12-next.0 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/types@1.1.1-next.0 - -## 0.2.11 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.1.0 - -## 0.2.10 - -### Patch Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -- Updated dependencies - - @backstage/types@1.0.2 - -## 0.2.10-next.0 - -### Patch Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -- Updated dependencies - - @backstage/types@1.0.2 - -## 0.2.9 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.2 - -## 0.2.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.2-next.1 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.2-next.0 - -## 0.2.8 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.1 - -## 0.2.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.1-next.0 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.0 - -## 0.2.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.0 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.0 - -## 0.2.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.0 - -## 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 - -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. - -## 0.2.4 - -### Patch Changes - -- Updated dependencies - - @backstage/types@1.0.0 - -## 0.2.3 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/types@0.1.3 - -## 0.2.2 - -### Patch Changes - -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/types@0.1.2 - -## 0.2.1 - -### Patch Changes - -- a60eb0f0dd: adding new operation to run checks for multiple entities in one request - -## 0.2.0 - -### Minor Changes - -- b5bd60fddc: Added new property 'result' in CheckResult in @backstage/plugin-tech-insights-common. This property is later used in `@backstage/plugin-tech-insights` package. diff --git a/plugins/tech-insights-common/README.md b/plugins/tech-insights-common/README.md deleted file mode 100644 index af14ef0e0d..0000000000 --- a/plugins/tech-insights-common/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Tech Insights Common - -Common types and functionalities for tech insights shared in an isomorphic manner between BE and FE implementations. diff --git a/plugins/tech-insights-common/api-report.md b/plugins/tech-insights-common/api-report.md deleted file mode 100644 index 51ef13a013..0000000000 --- a/plugins/tech-insights-common/api-report.md +++ /dev/null @@ -1,68 +0,0 @@ -## API Report File for "@backstage/plugin-tech-insights-common" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { DateTime } from 'luxon'; -import { JsonValue } from '@backstage/types'; - -// @public -export interface BooleanCheckResult extends CheckResult { - // (undocumented) - result: boolean; -} - -// @public -export type BulkCheckResponse = Array<{ - entity: string; - results: CheckResult[]; -}>; - -// @public -export interface CheckResponse { - description: string; - factIds: string[]; - id: string; - metadata?: Record; - name: string; - type: string; -} - -// @public -export type CheckResult = { - facts: FactResponse; - check: CheckResponse; - result: JsonValue; -}; - -// @public -export type FactResponse = { - [id: string]: { - id: string; - type: 'integer' | 'float' | 'string' | 'boolean' | 'datetime' | 'set'; - description: string; - value: number | string | boolean | DateTime | []; - since?: string; - metadata?: Record; - }; -}; - -// @public -export type FactSchema = { - [name: string]: { - type: - | 'integer' - | 'float' - | 'string' - | 'boolean' - | 'datetime' - | 'set' - | 'object'; - description: string; - since?: string; - metadata?: Record; - }; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/tech-insights-common/catalog-info.yaml b/plugins/tech-insights-common/catalog-info.yaml deleted file mode 100644 index 3f5cac294f..0000000000 --- a/plugins/tech-insights-common/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-tech-insights-common - title: '@backstage/plugin-tech-insights-common' -spec: - lifecycle: experimental - type: backstage-common-library - owner: maintainers diff --git a/plugins/tech-insights-common/knip-report.md b/plugins/tech-insights-common/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/tech-insights-common/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/tech-insights-common/package.json b/plugins/tech-insights-common/package.json deleted file mode 100644 index cef4b5c627..0000000000 --- a/plugins/tech-insights-common/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@backstage/plugin-tech-insights-common", - "version": "0.2.12", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "common-library" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/tech-insights-common" - }, - "keywords": [ - "backstage", - "tech-insights" - ], - "sideEffects": false, - "scripts": { - "start": "backstage-cli backend:dev", - "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" - }, - "dependencies": { - "@backstage/types": "workspace:^", - "@types/luxon": "^3.0.0", - "luxon": "^3.0.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/tech-insights-common/src/index.test.ts b/plugins/tech-insights-common/src/index.test.ts deleted file mode 100644 index 0c54118f9a..0000000000 --- a/plugins/tech-insights-common/src/index.test.ts +++ /dev/null @@ -1,24 +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 * as anything from './'; - -describe('tech-insights-common', () => { - // Types only - it('should exist', () => { - expect(anything).toBeTruthy(); - }); -}); diff --git a/plugins/tech-insights-common/src/index.ts b/plugins/tech-insights-common/src/index.ts deleted file mode 100644 index a74c1f16e9..0000000000 --- a/plugins/tech-insights-common/src/index.ts +++ /dev/null @@ -1,193 +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 { DateTime } from 'luxon'; -import { JsonValue } from '@backstage/types'; - -/** - * @public - * - * Response type for checks. - */ -export interface CheckResponse { - /** - * Identifier of the Check - */ - id: string; - /** - * Type identifier for the check. - * Can be used to determine storage options, logical routing to correct FactChecker implementation - * or to help frontend render correct component types based on this - */ - type: string; - /** - * Human readable name of the Check - */ - name: string; - /** - * Description of the Check - */ - description: string; - - /** - * A collection of references to fact rows used to run this checks against - */ - factIds: string[]; - - /** - * Metadata related to a check. - * Can contain links, additional description texts and other actionable data. - * - * Currently loosely typed, but in the future when patterns emerge, key shapes can be defined - */ - metadata?: Record; -} - -/** - * @public - * - * Individual fact response type. - * Keyed by the name of the fact - */ -export type FactResponse = { - [id: string]: { - /** - * Reference and unique identifier of the fact row - */ - id: string; - /** - * Type of the individual fact value - * - * Numbers are split into integers and floating point values. - * `set` indicates a collection of values - */ - type: 'integer' | 'float' | 'string' | 'boolean' | 'datetime' | 'set'; - - /** - * Description of the individual fact - */ - description: string; - - /** - * Actual value of the fact - */ - value: number | string | boolean | DateTime | []; - - /** - * An optional SemVer version identifying when this fact was added to the FactSchema - */ - since?: string; - - /** - * Metadata related to an individual fact. - * Can contain links, additional description texts and other actionable data. - * - * Currently loosely typed, but in the future when patterns emerge, key shapes can be defined - */ - metadata?: Record; - }; -}; - -/** - * Generic CheckResult - * - * Contains information about the facts used to calculate the check result - * and information about the check itself. Both may include metadata to be able to display additional information. - * A collection of these should be parseable by the frontend to display scorecards - * - * @public - */ -export type CheckResult = { - facts: FactResponse; - check: CheckResponse; - result: JsonValue; -}; - -/** - * CheckResult of type Boolean. - * - * @public - */ -export interface BooleanCheckResult extends CheckResult { - result: boolean; -} - -/** - * Response type for bulk check opretation. Contains a list of entities and their respective check results. - * - * @public - */ -export type BulkCheckResponse = Array<{ - entity: string; - results: CheckResult[]; -}>; - -/** - * A record type to specify individual fact shapes - * - * Used as part of a schema to validate, identify and generically construct usage implementations - * of individual fact values in the system. - * - * @public - */ -export type FactSchema = { - /** - * Name of the fact - */ - [name: string]: { - /** - * Type of the individual fact value - * - * Numbers are split into integers and floating point values. - * `set` indicates a collection of values, `object` indicates JSON serializable value - */ - type: - | 'integer' - | 'float' - | 'string' - | 'boolean' - | 'datetime' - | 'set' - | 'object'; - - /** - * A description of this individual fact value - */ - description: string; - - /** - * Optional semver string to indicate when this specific fact definition was added to the schema - */ - since?: string; - - /** - * Metadata related to an individual fact. - * Can contain links, additional description texts and other actionable data. - * - * Currently loosely typed, but in the future when patterns emerge, key shapes can be defined - * - * examples: - * ``` - * \{ - * link: 'https://sonarqube.mycompany.com/fix-these-issues', - * suggestion: 'To affect this value, you can do x, y, z', - * minValue: 0 - * \} - * ``` - */ - metadata?: Record; - }; -}; diff --git a/plugins/tech-insights-node/.eslintrc.js b/plugins/tech-insights-node/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/tech-insights-node/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md deleted file mode 100644 index 8efb3bb616..0000000000 --- a/plugins/tech-insights-node/CHANGELOG.md +++ /dev/null @@ -1,1129 +0,0 @@ -# @backstage/plugin-tech-insights-node - -## 0.4.16-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.16-next.2 - -### Patch Changes - -- 7201af3: Add support for the new backend system. - - A new backend plugin for the tech-insights backend - was added and exported as `default`. - - You can use it with the new backend system like - - ```ts title="packages/backend/src/index.ts" - backend.add(import('@backstage/plugin-tech-insights-backend')); - ``` - -- 341c2a2: Move `FactRetrieverRegistry` and `PersistenceContext` to `@backstage/plugin-tech-insights-node`. - - Original exports are marked as deprecated and re-export the moved types. - - Please replace uses like - - ```ts - import { - FactRetrieverRegistry, - PersistenceContext, - } from '@backstage/plugin-tech-insights-backend'; - ``` - - with - - ```ts - import { - FactRetrieverRegistry, - PersistenceContext, - } from '@backstage/plugin-tech-insights-node'; - ``` - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.15 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.15-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.2 - -## 0.4.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.15-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.14 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/backend-tasks@0.5.13 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.14-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-tasks@0.5.13-next.3 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/backend-tasks@0.5.13-next.2 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-tasks@0.5.13-next.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-tasks@0.5.13-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.13 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/backend-tasks@0.5.12 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.2 - - @backstage/backend-tasks@0.5.12-next.2 - -## 0.4.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-tasks@0.5.12-next.1 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-tasks@0.5.12-next.0 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.12 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.11 - - @backstage/backend-common@0.19.8 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/backend-tasks@0.5.11-next.2 - - @backstage/config@1.1.1-next.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.10-next.1 - - @backstage/backend-common@0.19.7-next.1 - - @backstage/config@1.1.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/backend-tasks@0.5.10-next.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.4.9 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.8 - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/types@1.1.1 - -## 0.4.9-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/plugin-tech-insights-common@0.2.12-next.0 - - @backstage/types@1.1.1-next.0 - - @backstage/backend-common@0.19.5-next.3 - - @backstage/backend-tasks@0.5.8-next.3 - -## 0.4.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-tasks@0.5.8-next.2 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-tasks@0.5.8-next.1 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/backend-tasks@0.5.7-next.0 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/backend-tasks@0.5.5 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.5-next.2 - - @backstage/backend-common@0.19.2-next.2 - -## 0.4.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/backend-tasks@0.5.5-next.1 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/backend-tasks@0.5.5-next.0 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.5 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1 - - @backstage/backend-tasks@0.5.4 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.1-next.0 - - @backstage/backend-tasks@0.5.4-next.0 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/types@1.1.0 - - @backstage/backend-tasks@0.5.3 - - @backstage/config@1.0.8 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.4.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/backend-tasks@0.5.3-next.2 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/backend-tasks@0.5.3-next.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-tasks@0.5.3-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/backend-tasks@0.5.2 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/backend-tasks@0.5.2-next.1 - - @backstage/config@1.0.7 - -## 0.4.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/backend-tasks@0.5.2-next.0 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/backend-tasks@0.5.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/backend-tasks@0.5.1-next.2 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.1-next.1 - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-tasks@0.5.1-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.0 - - @backstage/backend-common@0.18.3 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.0-next.2 - - @backstage/backend-common@0.18.3-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.4.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.1 - - @backstage/backend-tasks@0.4.4-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.4.4-next.0 - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.4.0 - -### Minor Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/backend-tasks@0.4.3 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - -## 0.4.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/backend-tasks@0.4.3-next.2 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - -## 0.4.0-next.1 - -### Minor Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - - @backstage/backend-common@0.18.2-next.1 - - @backstage/backend-tasks@0.4.3-next.1 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - -## 0.3.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - - @backstage/backend-tasks@0.4.3-next.0 - -## 0.3.8 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/backend-tasks@0.4.1 - - @backstage/config@1.0.6 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/backend-tasks@0.4.1-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/backend-tasks@0.4.1-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.7 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/backend-tasks@0.4.0 - - @backstage/types@1.0.2 - - @backstage/config@1.0.5 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.7-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.4.0-next.3 - - @backstage/backend-common@0.17.0-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/backend-tasks@0.4.0-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/backend-tasks@0.4.0-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/backend-tasks@0.3.8-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/plugin-tech-insights-common@0.2.9-next.0 - -## 0.3.6 - -### Patch Changes - -- 06cf8f1cf2: Add a default delay to the fact retrievers to prevent cold-start errors -- 30e43717c7: Use `HumanDuration` from `@backstage/types` -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/backend-tasks@0.3.7 - - @backstage/types@1.0.1 - - @backstage/config@1.0.4 - - @backstage/plugin-tech-insights-common@0.2.8 - -## 0.3.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/backend-tasks@0.3.7-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.3.6-next.0 - -### Patch Changes - -- 06cf8f1cf2: Add a default delay to the fact retrievers to prevent cold-start errors -- 30e43717c7: Use `HumanDuration` from `@backstage/types` -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/backend-tasks@0.3.7-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.3.5 - -### Patch Changes - -- 0963b4d5fb: Updated package role to be `node-library`. -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/backend-tasks@0.3.6 - - @backstage/config@1.0.3 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7 - -## 0.3.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.3.6-next.2 - - @backstage/backend-common@0.15.2-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.2 - -## 0.3.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/backend-tasks@0.3.6-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.1 - -## 0.3.5-next.0 - -### Patch Changes - -- 0963b4d5fb: Updated package role to be `node-library`. -- Updated dependencies - - @backstage/backend-common@0.15.2-next.0 - - @backstage/backend-tasks@0.3.6-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.0 - -## 0.3.4 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- 2e0689e536: Support for timeout in FactRetrieverRegistrationOptions -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/backend-tasks@0.3.5 - - @backstage/config@1.0.2 - -## 0.3.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/backend-common@0.15.1-next.3 - - @backstage/backend-tasks@0.3.5-next.1 - -## 0.3.4-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- 2e0689e536: Support for timeout in FactRetrieverRegistrationOptions -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - - @backstage/backend-tasks@0.3.5-next.0 - -## 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 - -- 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-next.3 - - @backstage/plugin-tech-insights-common@0.2.5-next.0 - -## 0.3.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - -## 0.3.1 - -### Patch Changes - -- aa15229ec3: Introduce additional JsonValue types to be storable as facts. This enables the possibility to store more complex objects for fact checking purposes. The rules engine supports walking keyed object values directly to create rules and checks - - Modify facts database table to have a more restricted timestamp precision for cases where the postgres server isn't configured to contain such value. This fixes the issue where in some cases `maxItems` lifecycle condition didn't work as expected. - -- Updated dependencies - - @backstage/backend-common@0.14.0 - -## 0.3.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - -## 0.3.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.6-next.0 - -## 0.3.0 - -### Minor Changes - -- 58e2c46151: **BREAKING**: The `FactRetrieverContext` type now contains an additional - field: `tokenManager`. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/config@1.0.1 - -## 0.3.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/config@1.0.1-next.0 - -## 0.3.0-next.1 - -### Minor Changes - -- 58e2c46151: **BREAKING**: The `FactRetrieverContext` type now contains an additional - field: `tokenManager`. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.1 - -## 0.2.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - -## 0.2.9 - -### Patch Changes - -- 231fee736b: Adds an optional timeout to fact retriever registrations to stop a task if it runs too long. -- Updated dependencies - - @backstage/backend-common@0.13.2 - -## 0.2.9-next.1 - -### Patch Changes - -- 231fee736b: Adds an optional timeout to fact retriever registrations to stop a task if it runs too long. -- Updated dependencies - - @backstage/backend-common@0.13.2-next.1 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.2-next.0 - -## 0.2.8 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/config@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.4 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0 - -## 0.2.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.12.0 - -## 0.2.5 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.11.0 - -## 0.2.4 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/backend-common@0.10.9 - - @backstage/config@0.1.15 - - @backstage/plugin-tech-insights-common@0.2.3 - -## 0.2.3 - -### Patch Changes - -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/backend-common@0.10.8 - - @backstage/config@0.1.14 - - @backstage/plugin-tech-insights-common@0.2.2 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7-next.0 - -## 0.2.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6 - -## 0.2.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6-next.0 - -## 0.2.0 - -### Minor Changes - -- dfd5e81721: BREAKING CHANGES: - - - The helper function to create a fact retriever registration is now expecting an object of configuration items instead of individual arguments. - Modify your `techInsights.ts` plugin configuration in `packages/backend/src/plugins/techInsights.ts` (or equivalent) the following way: - - ```diff - -createFactRetrieverRegistration( - - '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - - entityOwnershipFactRetriever, - -), - +createFactRetrieverRegistration({ - + cadende: '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - + factRetriever: entityOwnershipFactRetriever, - +}), - - ``` - - - `TechInsightsStore` interface has changed its signature of `insertFacts` method. If you have created your own implementation of either `TechInsightsDatabase` or `FactRetrieverEngine` you need to modify the implementation/call to this method to accept/pass-in an object instead if individual arguments. The interface now accepts an additional `lifecycle` argument which is optional (defined below). An example modification to fact retriever engine: - - ```diff - -await this.repository.insertFacts(factRetriever.id, facts); - +await this.repository.insertFacts({ - + id: factRetriever.id, - + facts, - + lifecycle, - +}); - ``` - - Adds a configuration option to fact retrievers to define lifecycle for facts the retriever persists. Possible values are either 'max items' or 'time-to-live'. The former will keep only n number of items in the database for each fact per entity. The latter will remove all facts that are older than the TTL value. - - Possible values: - - - `{ maxItems: 5 }` // Deletes all facts for the retriever/entity pair, apart from the last five - - `{ ttl: 1209600000 }` // (2 weeks) Deletes all facts older than 2 weeks for the retriever/entity pair - - `{ ttl: { weeks: 2 } }` // Deletes all facts older than 2 weeks for the retriever/entity pair - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4 - - @backstage/config@0.1.13 - -## 0.2.0-next.0 - -### Minor Changes - -- dfd5e81721: BREAKING CHANGES: - - - The helper function to create a fact retriever registration is now expecting an object of configuration items instead of individual arguments. - Modify your `techInsights.ts` plugin configuration in `packages/backend/src/plugins/techInsights.ts` (or equivalent) the following way: - - ```diff - -createFactRetrieverRegistration( - - '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - - entityOwnershipFactRetriever, - -), - +createFactRetrieverRegistration({ - + cadende: '1 1 1 * *', // Example cron, At 01:01 on day-of-month 1. - + factRetriever: entityOwnershipFactRetriever, - +}), - - ``` - - - `TechInsightsStore` interface has changed its signature of `insertFacts` method. If you have created your own implementation of either `TechInsightsDatabase` or `FactRetrieverEngine` you need to modify the implementation/call to this method to accept/pass-in an object instead if individual arguments. The interface now accepts an additional `lifecycle` argument which is optional (defined below). An example modification to fact retriever engine: - - ```diff - -await this.repository.insertFacts(factRetriever.id, facts); - +await this.repository.insertFacts({ - + id: factRetriever.id, - + facts, - + lifecycle, - +}); - ``` - - Adds a configuration option to fact retrievers to define lifecycle for facts the retriever persists. Possible values are either 'max items' or 'time-to-live'. The former will keep only n number of items in the database for each fact per entity. The latter will remove all facts that are older than the TTL value. - - Possible values: - - - `{ maxItems: 5 }` // Deletes all facts for the retriever/entity pair, apart from the last five - - `{ ttl: 1209600000 }` // (2 weeks) Deletes all facts older than 2 weeks for the retriever/entity pair - - `{ ttl: { weeks: 2 } }` // Deletes all facts older than 2 weeks for the retriever/entity pair - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4-next.0 - - @backstage/config@0.1.13-next.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.0 - - @backstage/backend-common@0.9.12 diff --git a/plugins/tech-insights-node/README.md b/plugins/tech-insights-node/README.md deleted file mode 100644 index 4065611837..0000000000 --- a/plugins/tech-insights-node/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Tech Insights Node - -Common types and functionalities for tech insights backend implementations to be shared between tech-insights-backend and individual implementations of FactRetrievers, FactCheckers and their persistence options. diff --git a/plugins/tech-insights-node/api-report.md b/plugins/tech-insights-node/api-report.md deleted file mode 100644 index 13056b5eaa..0000000000 --- a/plugins/tech-insights-node/api-report.md +++ /dev/null @@ -1,233 +0,0 @@ -## API Report File for "@backstage/plugin-tech-insights-node" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { Config } from '@backstage/config'; -import { DateTime } from 'luxon'; -import { Duration } from 'luxon'; -import { DurationLike } from 'luxon'; -import { ExtensionPoint } from '@backstage/backend-plugin-api'; -import { FactSchema } from '@backstage/plugin-tech-insights-common'; -import { HumanDuration } from '@backstage/types'; -import { JsonValue } from '@backstage/types'; -import { Logger } from 'winston'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { TokenManager } from '@backstage/backend-common'; - -// @public -export type CheckValidationResponse = { - valid: boolean; - message?: string; - errors?: unknown[]; -}; - -// @public -export interface FactChecker< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - getChecks(): Promise; - runChecks(entity: string, checks?: string[]): Promise; - validate(check: CheckType): Promise; -} - -// @public -export interface FactCheckerFactory< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - // (undocumented) - construct( - repository: TechInsightsStore, - ): FactChecker; -} - -// @public -export type FactLifecycle = TTL | MaxItems; - -// @public -export interface FactRetriever { - description?: string; - entityFilter?: - | Record[] - | Record; - handler: (ctx: FactRetrieverContext) => Promise; - id: string; - schema: FactSchema; - title?: string; - version: string; -} - -// @public -export type FactRetrieverContext = { - config: Config; - discovery: PluginEndpointDiscovery; - logger: Logger; - tokenManager: TokenManager; - entityFilter?: - | Record[] - | Record; -}; - -// @public -export type FactRetrieverRegistration = { - factRetriever: FactRetriever; - cadence?: string; - timeout?: Duration | HumanDuration; - lifecycle?: FactLifecycle; - initialDelay?: Duration | HumanDuration; -}; - -// @public (undocumented) -export interface FactRetrieverRegistry { - // (undocumented) - get(retrieverReference: string): Promise; - // (undocumented) - getSchemas(): Promise; - // (undocumented) - listRegistrations(): Promise; - // (undocumented) - listRetrievers(): Promise; - // (undocumented) - register(registration: FactRetrieverRegistration): Promise; -} - -// @public -export type FactSchemaDefinition = Omit; - -// @public -export type FlatTechInsightFact = TechInsightFact & { - id: string; -}; - -// @public -export type MaxItems = { - maxItems: number; -}; - -// @public -export type PersistenceContext = { - techInsightsStore: TechInsightsStore; -}; - -// @public -export interface TechInsightCheck { - description: string; - factIds: string[]; - failureMetadata?: Record; - id: string; - name: string; - successMetadata?: Record; - type: string; -} - -// @public -export interface TechInsightCheckRegistry { - // (undocumented) - get(checkId: string): Promise; - // (undocumented) - getAll(checks: string[]): Promise; - // (undocumented) - list(): Promise; - // (undocumented) - register(check: CheckType): Promise; -} - -// @public -export type TechInsightFact = { - entity: { - namespace: string; - kind: string; - name: string; - }; - facts: Record< - string, - | number - | string - | boolean - | DateTime - | number[] - | string[] - | boolean[] - | DateTime[] - | JsonValue - >; - timestamp?: DateTime; -}; - -// @public (undocumented) -export interface TechInsightsFactCheckerFactoryExtensionPoint { - // (undocumented) - setFactCheckerFactory< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, - >( - factory: FactCheckerFactory, - ): void; -} - -// @public -export const techInsightsFactCheckerFactoryExtensionPoint: ExtensionPoint; - -// @public (undocumented) -export interface TechInsightsFactRetrieverRegistryExtensionPoint { - // (undocumented) - setFactRetrieverRegistry(registry: FactRetrieverRegistry): void; -} - -// @public -export const techInsightsFactRetrieverRegistryExtensionPoint: ExtensionPoint; - -// @public (undocumented) -export interface TechInsightsFactRetrieversExtensionPoint { - // (undocumented) - addFactRetrievers(factRetrievers: Record): void; -} - -// @public -export const techInsightsFactRetrieversExtensionPoint: ExtensionPoint; - -// @public (undocumented) -export interface TechInsightsPersistenceContextExtensionPoint { - // (undocumented) - setPersistenceContext(context: PersistenceContext): void; -} - -// @public -export const techInsightsPersistenceContextExtensionPoint: ExtensionPoint; - -// @public -export interface TechInsightsStore { - getFactsBetweenTimestampsByIds( - ids: string[], - entity: string, - startDateTime: DateTime, - endDateTime: DateTime, - ): Promise<{ - [factRef: string]: FlatTechInsightFact[]; - }>; - // (undocumented) - getLatestFactsByIds( - ids: string[], - entity: string, - ): Promise<{ - [factRef: string]: FlatTechInsightFact; - }>; - getLatestSchemas(ids?: string[]): Promise; - insertFacts(options: { - id: string; - facts: TechInsightFact[]; - lifecycle?: FactLifecycle; - }): Promise; - insertFactSchema(schemaDefinition: FactSchemaDefinition): Promise; -} - -// @public -export type TTL = { - timeToLive: DurationLike; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/tech-insights-node/catalog-info.yaml b/plugins/tech-insights-node/catalog-info.yaml deleted file mode 100644 index 6f7bcc3eb9..0000000000 --- a/plugins/tech-insights-node/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-tech-insights-node - title: '@backstage/plugin-tech-insights-node' -spec: - lifecycle: experimental - type: backstage-node-library - owner: maintainers diff --git a/plugins/tech-insights-node/knip-report.md b/plugins/tech-insights-node/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/tech-insights-node/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json deleted file mode 100644 index 0785befb30..0000000000 --- a/plugins/tech-insights-node/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@backstage/plugin-tech-insights-node", - "version": "0.4.16-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "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": "plugins/tech-insights-node" - }, - "keywords": [ - "backstage", - "tech-insights" - ], - "scripts": { - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/plugin-tech-insights-common": "workspace:^", - "@backstage/types": "workspace:^", - "@types/luxon": "^3.0.0", - "luxon": "^3.0.0", - "winston": "^3.2.1" - }, - "devDependencies": { - "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/tech-insights-node/src/checks.ts b/plugins/tech-insights-node/src/checks.ts deleted file mode 100644 index e5f10aff6d..0000000000 --- a/plugins/tech-insights-node/src/checks.ts +++ /dev/null @@ -1,153 +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 { TechInsightsStore } from './persistence'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; - -/** - * A factory wrapper to construct FactChecker implementations. - * - * @public - * @typeParam CheckType - Implementation specific Check. Can extend TechInsightCheck with additional information - * @typeParam CheckResultType - Implementation specific result of a check. Can extend CheckResult with additional information - */ -export interface FactCheckerFactory< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - /** - * @param repository - TechInsightsStore - * @returns an implementation of a FactChecker for generic types defined in the factory - */ - construct( - repository: TechInsightsStore, - ): FactChecker; -} - -/** - * FactChecker interface - * - * A generic interface that can be implemented to create checkers for specific check and check return types. - * This is used especially when creating Scorecards and displaying results of rules when run against facts. - * - * @public - * @typeParam CheckType - Implementation specific Check. Can extend TechInsightCheck with additional information - * @typeParam CheckResultType - Implementation specific result of a check. Can extend CheckResult with additional information - */ -export interface FactChecker< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, -> { - /** - * Runs checks against an entity. - * - * @param entity - A reference to an entity to run checks against. In a format namespace/kind/name - * @param checks - A collection of checks to run against provided entity - * @returns - A collection containing check/fact information and the actual results of the check - */ - runChecks(entity: string, checks?: string[]): Promise; - - /** - * Retrieves all available checks that can be used to run checks against. - * The implementation can be just a piping through to CheckRegistry implementation if such is in use. - * - * @returns - A collection of checks - */ - getChecks(): Promise; - - /** - * Validates if check is valid and can be run with the current implementation - * - * @param check - The check to be validated - * @returns - Validation result - */ - validate(check: CheckType): Promise; -} - -/** - * Registry containing checks for tech insights. - * - * @public - * @typeParam CheckType - Implementation specific Check. Can extend TechInsightCheck with additional information - * - */ -export interface TechInsightCheckRegistry { - register(check: CheckType): Promise; - get(checkId: string): Promise; - getAll(checks: string[]): Promise; - list(): Promise; -} - -/** - * Generic definition of a check for Tech Insights - * - * @public - */ -export interface TechInsightCheck { - /** - * Unique identifier of the check - * - * Used to identify which checks to use when running checks. - */ - id: string; - - /** - * Type identifier for the check. - * Can be used to determine storage options, logical routing to correct FactChecker implementation - * or to help frontend render correct component types based on this - */ - type: string; - - /** - * Human readable name of the check, may be displayed in the UI - */ - name: string; - - /** - * Human readable description of the check, may be displayed in the UI - */ - description: string; - - /** - * A collection of string referencing fact rows that a check will be run against. - * - * References the fact container, aka fact retriever itself which may or may not contain multiple individual facts and values - */ - factIds: string[]; - - /** - * Metadata to be returned in case a check has been successfully evaluated - * Can contain links, description texts or other actionable items - */ - successMetadata?: Record; - - /** - * Metadata to be returned in case a check evaluation has ended in failure - * Can contain links, description texts or other actionable items - */ - failureMetadata?: Record; -} - -/** - * Validation response from CheckValidator - * - * May contain additional data for display purposes - * @public - */ -export type CheckValidationResponse = { - valid: boolean; - message?: string; - errors?: unknown[]; -}; diff --git a/plugins/tech-insights-node/src/extensionPoints.ts b/plugins/tech-insights-node/src/extensionPoints.ts deleted file mode 100644 index e1f581a840..0000000000 --- a/plugins/tech-insights-node/src/extensionPoints.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { FactCheckerFactory, TechInsightCheck } from './checks'; -import { FactRetriever, FactRetrieverRegistry } from './facts'; -import { PersistenceContext } from './persistence'; - -/** - * @public - */ -export interface TechInsightsFactRetrieversExtensionPoint { - addFactRetrievers(factRetrievers: Record): void; -} - -/** - * An extension point that allows other plugins or modules to add fact retrievers. - * - * @public - */ -export const techInsightsFactRetrieversExtensionPoint = - createExtensionPoint({ - id: 'tech-insights.fact-retrievers', - }); - -/** - * @public - */ -export interface TechInsightsFactCheckerFactoryExtensionPoint { - setFactCheckerFactory< - CheckType extends TechInsightCheck, - CheckResultType extends CheckResult, - >( - factory: FactCheckerFactory, - ): void; -} - -/** - * An extension point that allows other plugins or modules to set a FactCheckerFactory. - * - * @public - */ -export const techInsightsFactCheckerFactoryExtensionPoint = - createExtensionPoint({ - id: 'tech-insights.fact-checker-factory', - }); - -/** - * @public - */ -export interface TechInsightsFactRetrieverRegistryExtensionPoint { - setFactRetrieverRegistry(registry: FactRetrieverRegistry): void; -} - -/** - * An extension point that allows other plugins or modules to set a custom FactRetrieverRegistry. - * - * @public - */ -export const techInsightsFactRetrieverRegistryExtensionPoint = - createExtensionPoint({ - id: 'tech-insights.fact-retriever-registry', - }); - -/** - * @public - */ -export interface TechInsightsPersistenceContextExtensionPoint { - setPersistenceContext(context: PersistenceContext): void; -} - -/** - * An extension point that allows other plugins or modules to set a custom PersistenceContext. - * - * @public - */ -export const techInsightsPersistenceContextExtensionPoint = - createExtensionPoint({ - id: 'tech-insights.persistence-context', - }); diff --git a/plugins/tech-insights-node/src/facts.ts b/plugins/tech-insights-node/src/facts.ts deleted file mode 100644 index 9257ea789e..0000000000 --- a/plugins/tech-insights-node/src/facts.ts +++ /dev/null @@ -1,243 +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 { DateTime, Duration, DurationLike } from 'luxon'; -import { Config } from '@backstage/config'; -import { HumanDuration, JsonValue } from '@backstage/types'; -import { - PluginEndpointDiscovery, - TokenManager, -} from '@backstage/backend-common'; -import { FactSchema } from '@backstage/plugin-tech-insights-common'; -import { Logger } from 'winston'; - -/** - * A container for facts. The shape of the fact records needs to correspond to the FactSchema with same `ref` value. - * Each container contains a reference to an entity which can be a Backstage entity or a generic construct - * outside of backstage with same shape. - * - * Container may contain multiple individual facts and their values - * - * @public - */ -export type TechInsightFact = { - /** - * Entity reference that this fact relates to - */ - entity: { - namespace: string; - kind: string; - name: string; - }; - - /** - * A collection of fact values as key value pairs. - * - * Key indicates fact name as it is defined in FactSchema - */ - facts: Record< - string, - | number - | string - | boolean - | DateTime - | number[] - | string[] - | boolean[] - | DateTime[] - | JsonValue - >; - - /** - * Optional timestamp value which can be used to override retrieval time of the fact row. - * Otherwise when stored into data storage, defaults to current time - */ - timestamp?: DateTime; -}; - -/** - * Response type used when returning from database and API. - * Adds a field for ref for easier usage - * - * @public - */ -export type FlatTechInsightFact = TechInsightFact & { - /** - * Reference and unique identifier of the fact row - */ - id: string; -}; - -/** - * @public - * - * FactRetrieverContext injected into individual handler methods of FactRetriever implementations. - * The context can be used to construct logic to retrieve entities, contact integration points - * and fetch and calculate fact values from external sources. - */ -export type FactRetrieverContext = { - config: Config; - discovery: PluginEndpointDiscovery; - logger: Logger; - tokenManager: TokenManager; - entityFilter?: - | Record[] - | Record; -}; - -/** - * FactRetriever interface - * - * @public - */ -export interface FactRetriever { - /** - * A unique identifier of the retriever. - * Used to identify and store individual facts returned from this retriever - * and schemas defined by this retriever. - */ - id: string; - - /** - * Semver string indicating the version of this fact retriever - * This version is used to determine if the schema this fact retriever matches the data this fact retriever provides. - * - * Should be incremented on changes to returned data from the handler or if the schema changes. - */ - version: string; - - /** - * A short display title for the fact retriever to be used in the interface - */ - title?: string; - - /** - * A short display description for the fact retriever to be used in the interface. - */ - description?: string; - - /** - * Handler function that needs to be implemented to retrieve fact values for entities. - * - * @param ctx - FactRetrieverContext which can be used to retrieve config and contact integrations - * @returns - A collection of TechInsightFacts grouped by entities. - */ - handler: (ctx: FactRetrieverContext) => Promise; - - /** - * A fact schema defining the shape of data returned from the handler method for each entity - */ - schema: FactSchema; - - /** - * An optional object/array of objects of entity filters to indicate if this fact retriever is valid for an entity type. - * If omitted, the retriever should apply to all entities. - * - * Should be defined for example: - * \{ field: 'kind', values: \['component'\] \} - * \{ field: 'metadata.name', values: \['component-1', 'component-2'\] \} - */ - entityFilter?: - | Record[] - | Record; -} - -/** - * A Luxon duration like object for time to live value - * - * @public - * @example - * \{ timeToLive: 1209600000 \} - * \{ timeToLive: \{ weeks: 4 \} \} - * - */ -export type TTL = { timeToLive: DurationLike }; - -/** - * A maximum number for items to be kept in the database for each fact retriever/entity pair - * - * @public - * @example - * \{ maxItems: 10 \} - * - */ -export type MaxItems = { maxItems: number }; - -/** - * A fact lifecycle definition. Determines which strategy to use to purge expired facts from the database. - * - * @public - */ -export type FactLifecycle = TTL | MaxItems; - -/** - * A flat serializable structure for Facts. - * Containing information about fact schema, version, id, and entity filters - * - * @public - */ -export type FactSchemaDefinition = Omit; - -/** - * Registration of a fact retriever - * Used to add and schedule individual fact retrievers to the fact retriever engine. - * - * @public - */ -export type FactRetrieverRegistration = { - /** - * Actual FactRetriever implementation - */ - factRetriever: FactRetriever; - - /** - * Cron expression to indicate when the retriever should be triggered. - * Defaults to a random point in time every 24h - * - */ - cadence?: string; - - /** - * A duration to determine how long the fact retriever should be allowed to run, - * defaults to 5 minutes. - * - */ - timeout?: Duration | HumanDuration; - - /** - * Fact lifecycle definition - * - * If defined this value will be used to determine expired items which will deleted when this fact retriever is run - */ - lifecycle?: FactLifecycle; - - /** - * A duration to determine the initial delay for the fact retriever. Useful for cold start scenarios when e.g. the - * catalog backend is not yet available. Defaults to 5 seconds. - * - */ - initialDelay?: Duration | HumanDuration; -}; - -/** - * @public - */ -export interface FactRetrieverRegistry { - register(registration: FactRetrieverRegistration): Promise; - get(retrieverReference: string): Promise; - listRetrievers(): Promise; - listRegistrations(): Promise; - getSchemas(): Promise; -} diff --git a/plugins/tech-insights-node/src/index.test.ts b/plugins/tech-insights-node/src/index.test.ts deleted file mode 100644 index 5e5f8c9d77..0000000000 --- a/plugins/tech-insights-node/src/index.test.ts +++ /dev/null @@ -1,24 +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 * as anything from './'; - -describe('tech-insights-node', () => { - // Types only - it('should exist', () => { - expect(anything).toBeTruthy(); - }); -}); diff --git a/plugins/tech-insights-node/src/index.ts b/plugins/tech-insights-node/src/index.ts deleted file mode 100644 index c1c321f925..0000000000 --- a/plugins/tech-insights-node/src/index.ts +++ /dev/null @@ -1,20 +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. - */ - -export * from './checks'; -export * from './extensionPoints'; -export * from './facts'; -export * from './persistence'; diff --git a/plugins/tech-insights-node/src/persistence.ts b/plugins/tech-insights-node/src/persistence.ts deleted file mode 100644 index 391d23bae5..0000000000 --- a/plugins/tech-insights-node/src/persistence.ts +++ /dev/null @@ -1,98 +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 { - TechInsightFact, - FlatTechInsightFact, - FactSchemaDefinition, - FactLifecycle, -} from './facts'; -import { DateTime } from 'luxon'; -import { FactSchema } from '@backstage/plugin-tech-insights-common'; - -/** - * A Container for persistence related components in TechInsights - * - * @public - */ -export type PersistenceContext = { - techInsightsStore: TechInsightsStore; -}; - -/** - * TechInsights Database - * - * @public - */ -export interface TechInsightsStore { - /** - * Stores fact containers as rows into data store. - * Individual items in array correspond to a fact schema based on reference and entity based on entity identifier. - * - * Each row may contain multiple individual facts and values - * - * @param id - Unique identifier of the fact retriever these facts relate to - * @param facts - A collection of TechInsightFacts - * @param lifecycle - (Optional) Fact lifecycle object indicating the expiration logic for these items - */ - insertFacts(options: { - id: string; - facts: TechInsightFact[]; - lifecycle?: FactLifecycle; - }): Promise; - - /** - * @param ids - A collection of fact row identifiers - * @param entity - A string identifying an entity. In a format namespace/kind/name - * - * @returns - An object keyed by a fact reference and containing an individual TechInsightFact - */ - getLatestFactsByIds( - ids: string[], - entity: string, - ): Promise<{ [factRef: string]: FlatTechInsightFact }>; - - /** - * Retrieves fact values identified by fact row references for an individual entity. - * - * @param ids - A collection of fact row identifiers - * @param entity - A string identifying an entity. In a format namespace/kind/name - * @param startDateTime - DateTime object indicating start of the time frame - * @param endDateTime - DateTime object indicating start of the time frame - * - * @returns - An object keyed by a fact reference and containing a collection of TechInsightFacts matching the time frame - */ - getFactsBetweenTimestampsByIds( - ids: string[], - entity: string, - startDateTime: DateTime, - endDateTime: DateTime, - ): Promise<{ [factRef: string]: FlatTechInsightFact[] }>; - - /** - * Stores versioned fact schemas into data store - * - * @param schemaDefinition - FactSchemaDefinition containing id, version, schema and entityTypes. - */ - insertFactSchema(schemaDefinition: FactSchemaDefinition): Promise; - - /** - * Retrieves latest versions (as defined by semver) of fact schemas from the data store. - * - * @param ids - Collection of ids to return. If omitted, all Schemas should be returned. - * @returns - A collection of schemas - */ - getLatestSchemas(ids?: string[]): Promise; -} diff --git a/plugins/tech-insights-node/src/setupTests.ts b/plugins/tech-insights-node/src/setupTests.ts deleted file mode 100644 index a330613afb..0000000000 --- a/plugins/tech-insights-node/src/setupTests.ts +++ /dev/null @@ -1,17 +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. - */ - -export {}; diff --git a/plugins/tech-insights/.eslintrc.js b/plugins/tech-insights/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/tech-insights/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md deleted file mode 100644 index 14e982e068..0000000000 --- a/plugins/tech-insights/CHANGELOG.md +++ /dev/null @@ -1,1546 +0,0 @@ -# @backstage/plugin-tech-insights - -## 0.3.22-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.22-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.21 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.21-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.3.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.21-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.20 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.20-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/types@1.1.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.20-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.18 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 62b5922916: Internal theme type updates -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.18-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.3.18-next.1 - -### Patch Changes - -- 62b5922916: Internal theme type updates -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.18-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.17 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- 21f409d776: Export `ScorecardInfo` and `ScorecardsList` components to be able to use manually queried check results directly. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.17-next.2 - -### Patch Changes - -- 21f409d776: Export `ScorecardInfo` and `ScorecardsList` components to be able to use manually queried check results directly. -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - - @backstage/types@1.1.1 - - @backstage/plugin-tech-insights-common@0.2.12 - -## 0.3.16 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/plugin-tech-insights-common@0.2.12 - - @backstage/theme@0.4.2 - - @backstage/types@1.1.1 - -## 0.3.16-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/plugin-tech-insights-common@0.2.12-next.0 - - @backstage/theme@0.4.2-next.0 - - @backstage/types@1.1.1-next.0 - -## 0.3.16-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-catalog-react@1.8.3-next.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.13 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.3.13-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/catalog-model@1.4.1 - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.12 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - - @backstage/types@1.1.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.3.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/types@1.1.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.11 - -### Patch Changes - -- c03307ded3e6: The check description is now rendered with markdown. -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/types@1.1.0 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - - @backstage/plugin-tech-insights-common@0.2.11 - -## 0.3.11-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/types@1.0.2 - - @backstage/plugin-catalog-react@1.7.0-next.3 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.11-next.2 - -### Patch Changes - -- c03307ded3e6: The check description is now rendered with markdown. -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.3.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.10 - -### Patch Changes - -- 22963209d23: Added the possibility to customize the check description in the scorecard component. - - - The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. - - Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. - As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.3.10-next.1 - -### Patch Changes - -- 22963209d23: Added the possibility to customize the check description in the scorecard component. - - - The `CheckResultRenderer` type now exposes an optional `description` method that allows to overwrite the description with a different string or a React component for a provided check result. - - Until now only the `BooleanCheck` element could be overridden, but from now on it's also possible to override the description for a check. - As an example, the description could change depending on the check result. Refer to the [README](https://github.com/backstage/backstage/blob/master/plugins/tech-insights/README.md#adding-custom-rendering-components) file for more details - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.3.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.9 - -### Patch Changes - -- f538b9c5b83: The `Check` type now optionally includes the `failureMetadata` and `successMetadata` as returned by the `runChecks` call. -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.9-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.9-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.9-next.0 - -### Patch Changes - -- f538b9c5b83: The `Check` type now optionally includes the `failureMetadata` and `successMetadata` as returned by the `runChecks` call. -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.8 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.8-next.2 - -### Patch Changes - -- 65454876fb2: Minor API report tweaks -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.3.8-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.10 - -## 0.3.7 - -### Patch Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/plugin-tech-insights-common@0.2.10 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.3.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - - @backstage/plugin-catalog-react@1.3.0-next.2 - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - -## 0.3.7-next.1 - -### Patch Changes - -- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. - TechInsightsClient now implements method getFactSchemas(). - - **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - - These changes are **required** if you were importing this type directly. - - ```diff - - import { FactSchema } from '@backstage/plugin-tech-insights-node'; - + import { FactSchema } from '@backstage/plugin-tech-insights-common'; - ``` - -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.10-next.0 - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - -## 0.3.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.3.6 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - - @backstage/plugin-catalog-react@1.2.4-next.1 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.3.4 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/types@1.0.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-tech-insights-common@0.2.9 - -## 0.3.4-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.4-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.3 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/plugin-tech-insights-common@0.2.9-next.1 - -## 0.3.4-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-tech-insights-common@0.2.9-next.0 - -## 0.3.3 - -### Patch Changes - -- 7095e8bc03: Fixed bug when sending data by Post in `runChecks` and `runBulkChecks` functions of the `TechInsightsClient` class, the default `Content-Type` used was `plain/text` -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/types@1.0.1 - - @backstage/errors@1.1.3 - - @backstage/theme@0.2.16 - - @backstage/plugin-tech-insights-common@0.2.8 - -## 0.3.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.2.1-next.1 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.3.2-next.0 - -### Patch Changes - -- 7095e8bc03: Fixed bug when sending data by Post in `runChecks` and `runBulkChecks` functions of the `TechInsightsClient` class, the default `Content-Type` used was `plain/text` -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-tech-insights-common@0.2.8-next.0 - -## 0.3.1 - -### Patch Changes - -- f3d272cf57: Make sure to reload score card contents when props change -- a60a6807bd: making available the search for the last FACTS executed -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7 - -## 0.3.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.2 - -## 0.3.1-next.1 - -### Patch Changes - -- a60a6807bd: making available the search for the last FACTS executed -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.1 - -## 0.3.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/theme@0.2.16 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.7-next.0 - -## 0.3.0 - -### Minor Changes - -- f7e99ac1d8: Added the possibility to display check results of different types on a single scorecard. - - - **BREAKING** Removed the `getScorecardsDefinition` method from the `TechInsightsApi` interface. Added the `getCheckResultRenderers` method that returns rendering components for given types. - - **BREAKING** The `CheckResultRenderer` type now exposes the `component` factory method that creates a React component used to display a result of a provided check result. - - The `TechInsightsClient` constructor accepts now the optional `renderers` parameter that can be used to inject a custom renderer. - - **BREAKING** The `title` parameter in the `EntityTechInsightsScorecardContent` and `EntityTechInsightsScorecardCard` components is now mandatory. - - The `jsonRulesEngineCheckResultRenderer` used to render `json-rules-engine` check results is exported. - - The `BooleanCheck` component that can be used to render other check results types is also exported. - - If you were overriding the `getScorecardsDefinition` method to adjust the rendering of check results, you should now provide a custom renderer using `renderers` parameter in the `TechInsightsClient` class. - - See the [README](https://github.com/backstage/backstage/tree/master/plugins/tech-insights/README.md) for more details. - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 3f739be9d9: Minor API signatures cleanup -- 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters. -- 7d47def9c4: Removed dependency on `@types/jest`. -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - - @backstage/errors@1.1.1 - -## 0.3.0-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.3.0-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.3.0-next.1 - -### Minor Changes - -- f7e99ac1d8: Added the possibility to display check results of different types on a single scorecard. - - - **BREAKING** Removed the `getScorecardsDefinition` method from the `TechInsightsApi` interface. Added the `getCheckResultRenderers` method that returns rendering components for given types. - - **BREAKING** The `CheckResultRenderer` type now exposes the `component` factory method that creates a React component used to display a result of a provided check result. - - The `TechInsightsClient` constructor accepts now the optional `renderers` parameter that can be used to inject a custom renderer. - - **BREAKING** The `title` parameter in the `EntityTechInsightsScorecardContent` and `EntityTechInsightsScorecardCard` components is now mandatory. - - The `jsonRulesEngineCheckResultRenderer` used to render `json-rules-engine` check results is exported. - - The `BooleanCheck` component that can be used to render other check results types is also exported. - - If you were overriding the `getScorecardsDefinition` method to adjust the rendering of check results, you should now provide a custom renderer using `renderers` parameter in the `TechInsightsClient` class. - - See the [README](https://github.com/backstage/backstage/tree/master/plugins/tech-insights/README.md) for more details. - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters. -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.2.5-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/plugin-tech-insights-common@0.2.5-next.0 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.2.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.2.2 - -### Patch Changes - -- 09d2f4d179: Export TechInsightsClient so it may be extended by custom implementations -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.2.2-next.1 - -### Patch Changes - -- 09d2f4d179: Export TechInsightsClient so it may be extended by custom implementations -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.2.1 - -### Patch Changes - -- aa8db01acb: Add new component `EntityTechInsightsScorecardCard`, which can be used in the overview of the `EntityPage` page or display multiple individual `EntityTechInsightsScorecardCard` in `EntityLayout.Route`. -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.2.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.2.1-next.1 - -### Patch Changes - -- aa8db01acb: Add new component `EntityTechInsightsScorecardCard`, which can be used in the overview of the `EntityPage` page or display multiple individual `EntityTechInsightsScorecardCard` in `EntityLayout.Route`. -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.2.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.2.0 - -### Minor Changes - -- 567b13a84a: Add checksId option to EntityTechInsightsScorecardContent component - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- 2fe58c7285: Improved the Tech-Insights documentation: - - - `lifecycle` examples used `ttl` when it should be `timeToLive` - - Added list of included FactRetrievers - - Added full backend example using all included FactRetrievers - - Added boolean scorecard example image showing results of backend example - -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.2.0-next.1 - -### Minor Changes - -- 567b13a84a: Add checksId option to EntityTechInsightsScorecardContent component - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.1.14-next.0 - -### Patch Changes - -- 2fe58c7285: Improved the Tech-Insights documentation: - - - `lifecycle` examples used `ttl` when it should be `timeToLive` - - Added list of included FactRetrievers - - Added full backend example using all included FactRetrievers - - Added boolean scorecard example image showing results of backend example - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.1.13 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - - @backstage/errors@1.0.0 - - @backstage/types@1.0.0 - - @backstage/plugin-tech-insights-common@0.2.4 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.1.11 - -### Patch Changes - -- 36aa63022b: Use `CompoundEntityRef` instead of `EntityName`, and `getCompoundEntityRef` instead of `getEntityName`, from `@backstage/catalog-model`. -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.1.9 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/errors@0.2.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - - @backstage/types@0.1.2 - - @backstage/plugin-tech-insights-common@0.2.2 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.1.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.1.6 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.1.6-next.0 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.1.5 - -### Patch Changes - -- 34883f5c9e: Added possibility to pass customized title and description for the scorecards instead of using hardcoded ones. -- a60eb0f0dd: adding new operation to run checks for multiple entities in one request -- 48580d0fbb: fix React warning because of missing `key` prop -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/plugin-tech-insights-common@0.2.1 - - @backstage/errors@0.2.0 - - @backstage/catalog-model@0.9.9 - -## 0.1.4 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- 96fb10fe25: remove unnecessary http request when running all checks -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/plugin-catalog-react@0.6.10 - - @backstage/core-components@0.8.3 - -## 0.1.3 - -### Patch Changes - -- a86f5c1701: Fixed API auth in tech-insights plugin -- d83079fc11: Export `techInsightsApiRef` and associated types. -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.9 - -## 0.1.2 - -### Patch Changes - -- 6ff4408fa6: RunChecks endpoint now handles missing retriever data in checks. Instead of - showing server errors, the checks will be shown for checks whose retrievers have - data, and a warning will be shown if no checks are returned. -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.1.1 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.1.0 - -### Minor Changes - -- b5bd60fddc: New package containing UI components for the Tech Insights plugin. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-tech-insights-common@0.2.0 - - @backstage/core-components@0.7.6 - - @backstage/theme@0.2.14 - - @backstage/core-plugin-api@0.2.2 diff --git a/plugins/tech-insights/README.md b/plugins/tech-insights/README.md deleted file mode 100644 index 9145e892e7..0000000000 --- a/plugins/tech-insights/README.md +++ /dev/null @@ -1,152 +0,0 @@ -# Tech Insights - -This plugin provides the UI for the `@backstage/tech-insights-backend` plugin, in order to display results of the checks running following the rules and the logic defined in the `@backstage/tech-insights-backend` plugin itself. - -Main areas covered by this plugin currently are: - -- Providing an overview for default boolean checks in a form of Scorecards. - -- Providing an option to render different custom components based on type of the checks running in the backend. - -## Installation - -### Install the plugin - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-tech-insights -``` - -### Add boolean checks overview (Scorecards) page to the EntityPage: - -```tsx -// packages/app/src/components/catalog/EntityPage.tsx - -import { EntityTechInsightsScorecardContent } from '@backstage/plugin-tech-insights'; - -const serviceEntityPage = ( - - - {overviewContent} - - - {cicdContent} - - ... - - - - ... - -); -``` - -It is obligatory to pass `title` prop to `EntityTechInsightsScorecardContent`, `description` prop is optional. - -If you like to display multiple cards in a `EntityLayout.Route` use `EntityTechInsightsScorecardCard`. - -You can pass an array `checksId` as a prop with the [Fact Retrievers ids](../tech-insights-backend#creating-fact-retrievers) to limit which checks you want to show in this card. If you don't pass, the default value is show all checks. - -```tsx - -``` - -If you want to show checks in the overview of an entity use `EntityTechInsightsScorecardCard`. - -```tsx -// packages/app/src/components/catalog/EntityPage.tsx - -import { EntityTechInsightsScorecardCard } from '@backstage/plugin-tech-insights'; - -const overviewContent = ( - - {entityWarningContent} - - - - - - - ... - - - - -); -``` - -## Boolean Scorecard Example - -If you follow the [Backend Example](https://github.com/backstage/backstage/tree/master/plugins/tech-insights-backend#backend-example), once the needed facts have been generated the default boolean scorecard will look like this: - -![Boolean Scorecard Example](./docs/boolean-scorecard-example.png) - -## Adding custom rendering components - -Default scorecard implementation displays only `json-rules-engine` check results. If you would like to support different types, you need to inject custom rendering components to the `TechInsightsClient` constructor. - -```ts -// packages/app/src/apis.ts - -export const apis: AnyApiFactory[] = [ -... - createApiFactory({ - api: techInsightsApiRef, - deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, - factory: ({ discoveryApi, identityApi }) => - new TechInsightsClient({ - discoveryApi, - identityApi, - renderers: [ - jsonRulesEngineCheckResultRenderer, // default json-rules-engine renderer - myCustomBooleanRenderer, // custom renderer - ], - }), - }), -... -]; -``` - -```tsx -// packages/app/src/components/myCustomBooleanRenderer.tsx - -export const myCustomBooleanRenderer: CheckResultRenderer = { - type: 'boolean', - component: (checkResult: CheckResult) => ( - - ), -}; -``` - -It's also possible to customize the description. Both strings and React components are accepted. As an example, you would like -to display another information if the check has failed. In such cases, you could do something like the following: - -```tsx -// packages/app/src/components/myCustomBooleanRenderer.tsx - -export const myCustomBooleanRenderer: CheckResultRenderer = { - type: 'boolean', - component: (checkResult: CheckResult) => ( - - ), - description: (checkResult: CheckResult) => ( - <> - { - checkResult.result - ? checkResult.check.description // In case of success, return the same description - : `The check has failed! ${checkResult.check.description}` // Add a prefix text if the check failed - } - - ), -}; -``` diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md deleted file mode 100644 index 1e07c0fc69..0000000000 --- a/plugins/tech-insights/api-report.md +++ /dev/null @@ -1,144 +0,0 @@ -## API Report File for "@backstage/plugin-tech-insights" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { BulkCheckResponse } from '@backstage/plugin-tech-insights-common'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { CompoundEntityRef } from '@backstage/catalog-model'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { FactSchema } from '@backstage/plugin-tech-insights-common'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { JsonValue } from '@backstage/types'; -import { JSX as JSX_2 } from 'react'; -import { default as React_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export const BooleanCheck: (props: { - checkResult: CheckResult; -}) => React_2.JSX.Element; - -// @public -export type Check = { - id: string; - type: string; - name: string; - description: string; - factIds: string[]; - successMetadata?: Record; - failureMetadata?: Record; -}; - -// @public -export type CheckResultRenderer = { - type: string; - component: (check: CheckResult) => React_2.ReactElement; - description?: (check: CheckResult) => string | React_2.ReactElement; -}; - -// @public (undocumented) -export const EntityTechInsightsScorecardCard: (props: { - title: string; - description?: string | undefined; - checksId?: string[] | undefined; -}) => JSX_2.Element; - -// @public (undocumented) -export const EntityTechInsightsScorecardContent: (props: { - title: string; - description?: string | undefined; - checksId?: string[] | undefined; -}) => JSX_2.Element; - -// @public -export interface InsightFacts { - // (undocumented) - [factId: string]: { - timestamp: string; - version: string; - facts: Record; - }; -} - -// @public -export const jsonRulesEngineCheckResultRenderer: CheckResultRenderer; - -// @public (undocumented) -export const ScorecardInfo: (props: { - checkResults: CheckResult[]; - title: string; - description?: string | undefined; -}) => JSX_2.Element; - -// @public (undocumented) -export const ScorecardsList: (props: { - checkResults: CheckResult[]; -}) => JSX_2.Element; - -// @public -export interface TechInsightsApi { - // (undocumented) - getAllChecks(): Promise; - // (undocumented) - getCheckResultRenderers: (types: string[]) => CheckResultRenderer[]; - // (undocumented) - getFacts(entity: CompoundEntityRef, facts: string[]): Promise; - // (undocumented) - getFactSchemas(): Promise; - // (undocumented) - runBulkChecks( - entities: CompoundEntityRef[], - checks?: Check[], - ): Promise; - // (undocumented) - runChecks( - entityParams: CompoundEntityRef, - checks?: string[], - ): Promise; -} - -// @public -export const techInsightsApiRef: ApiRef; - -// @public (undocumented) -export class TechInsightsClient implements TechInsightsApi { - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - renderers?: CheckResultRenderer[]; - }); - // (undocumented) - getAllChecks(): Promise; - // (undocumented) - getCheckResultRenderers(types: string[]): CheckResultRenderer[]; - // (undocumented) - getFacts(entity: CompoundEntityRef, facts: string[]): Promise; - // (undocumented) - getFactSchemas(): Promise; - // (undocumented) - runBulkChecks( - entities: CompoundEntityRef[], - checks?: Check[], - ): Promise; - // (undocumented) - runChecks( - entityParams: CompoundEntityRef, - checks?: string[], - ): Promise; -} - -// @public (undocumented) -export const techInsightsPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/tech-insights/catalog-info.yaml b/plugins/tech-insights/catalog-info.yaml deleted file mode 100644 index 0c65b59d12..0000000000 --- a/plugins/tech-insights/catalog-info.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-tech-insights - title: '@backstage/plugin-tech-insights' -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/tech-insights/dev/index.tsx b/plugins/tech-insights/dev/index.tsx deleted file mode 100644 index c5deda2ea5..0000000000 --- a/plugins/tech-insights/dev/index.tsx +++ /dev/null @@ -1,63 +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 { createDevApp } from '@backstage/dev-utils'; -import { - techInsightsPlugin, - EntityTechInsightsScorecardContent, - techInsightsApiRef, - TechInsightsApi, - Check, -} from '../src'; -import { CompoundEntityRef, Entity } from '@backstage/catalog-model'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { checkResultRenderers, runChecksResponse } from './mocks'; - -const entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'random-name', - }, -} as Entity; - -createDevApp() - .registerPlugin(techInsightsPlugin) - .registerApi({ - api: techInsightsApiRef, - deps: {}, - factory: () => - ({ - getCheckResultRenderers: (_: string[]) => checkResultRenderers, - getAllChecks: async () => [], - runChecks: async (_: CompoundEntityRef, __?: string[]) => - runChecksResponse, - runBulkChecks: async (_: CompoundEntityRef[], __?: Check[]) => - '' as any, - getFacts: async (_: CompoundEntityRef, __: string[]) => '' as any, - getFactSchemas: async () => [], - } as TechInsightsApi), - }) - .addPage({ - element: ( - - - - ), - title: 'Root Page', - path: '/tech-insight-scorecard', - }) - .render(); diff --git a/plugins/tech-insights/dev/mocks.tsx b/plugins/tech-insights/dev/mocks.tsx deleted file mode 100644 index eec9b66054..0000000000 --- a/plugins/tech-insights/dev/mocks.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import React from 'react'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { BooleanCheck, CheckResultRenderer } from '../src'; - -export const runChecksResponse = [ - { - facts: { - 'fact-id': { - id: '1', - type: 'boolean', - description: 'fact description', - value: true, - }, - }, - check: { - id: 'fact-id', - type: 'boolean', - name: 'The check name', - description: `The check description \nusing markdown **bold** and a [link](https://backstage.io)`, - factIds: ['1'], - }, - result: true, - } as CheckResult, -]; - -export const checkResultRenderers = [ - { - type: 'boolean', - component: (check: CheckResult) => , - } as CheckResultRenderer, -]; diff --git a/plugins/tech-insights/docs/boolean-scorecard-example.png b/plugins/tech-insights/docs/boolean-scorecard-example.png deleted file mode 100644 index f7860afc2c..0000000000 Binary files a/plugins/tech-insights/docs/boolean-scorecard-example.png and /dev/null differ diff --git a/plugins/tech-insights/knip-report.md b/plugins/tech-insights/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/tech-insights/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json deleted file mode 100644 index b827799692..0000000000 --- a/plugins/tech-insights/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@backstage/plugin-tech-insights", - "version": "0.3.22-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/tech-insights" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@backstage/plugin-tech-insights-common": "workspace:^", - "@backstage/types": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "qs": "^6.9.4", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/tech-insights/src/api/TechInsightsApi.ts b/plugins/tech-insights/src/api/TechInsightsApi.ts deleted file mode 100644 index bb915e06dd..0000000000 --- a/plugins/tech-insights/src/api/TechInsightsApi.ts +++ /dev/null @@ -1,54 +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 { createApiRef } from '@backstage/core-plugin-api'; -import { - CheckResult, - BulkCheckResponse, - FactSchema, -} from '@backstage/plugin-tech-insights-common'; -import { Check, InsightFacts } from './types'; -import { CheckResultRenderer } from '../components/CheckResultRenderer'; -import { CompoundEntityRef } from '@backstage/catalog-model'; - -/** - * {@link @backstage/core-plugin-api#ApiRef} for the {@link TechInsightsApi} - * - * @public - */ -export const techInsightsApiRef = createApiRef({ - id: 'plugin.techinsights.service', -}); - -/** - * API client interface for the Tech Insights plugin - * - * @public - */ -export interface TechInsightsApi { - getCheckResultRenderers: (types: string[]) => CheckResultRenderer[]; - getAllChecks(): Promise; - runChecks( - entityParams: CompoundEntityRef, - checks?: string[], - ): Promise; - runBulkChecks( - entities: CompoundEntityRef[], - checks?: Check[], - ): Promise; - getFacts(entity: CompoundEntityRef, facts: string[]): Promise; - getFactSchemas(): Promise; -} diff --git a/plugins/tech-insights/src/api/TechInsightsClient.ts b/plugins/tech-insights/src/api/TechInsightsClient.ts deleted file mode 100644 index a1a2e7ff77..0000000000 --- a/plugins/tech-insights/src/api/TechInsightsClient.ts +++ /dev/null @@ -1,132 +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 { TechInsightsApi } from './TechInsightsApi'; -import { - BulkCheckResponse, - CheckResult, - FactSchema, -} from '@backstage/plugin-tech-insights-common'; -import { Check, InsightFacts } from './types'; -import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { - CompoundEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; - -import { - CheckResultRenderer, - jsonRulesEngineCheckResultRenderer, -} from '../components/CheckResultRenderer'; -import qs from 'qs'; - -/** @public */ -export class TechInsightsClient implements TechInsightsApi { - private readonly discoveryApi: DiscoveryApi; - private readonly identityApi: IdentityApi; - private readonly renderers?: CheckResultRenderer[]; - - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - renderers?: CheckResultRenderer[]; - }) { - this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; - this.renderers = options.renderers; - } - - async getFacts( - entity: CompoundEntityRef, - facts: string[], - ): Promise { - const query = qs.stringify({ - entity: stringifyEntityRef(entity), - ids: facts, - }); - return await this.api(`/facts/latest?${query}`); - } - - getCheckResultRenderers(types: string[]): CheckResultRenderer[] { - const renderers = this.renderers ?? [jsonRulesEngineCheckResultRenderer]; - return renderers.filter(d => types.includes(d.type)); - } - - async getAllChecks(): Promise { - return this.api('/checks'); - } - - async getFactSchemas(): Promise { - return this.api('/fact-schemas'); - } - - async runChecks( - entityParams: CompoundEntityRef, - checks?: string[], - ): Promise { - const { namespace, kind, name } = entityParams; - const requestBody = { checks }; - return this.api( - `/checks/run/${encodeURIComponent(namespace)}/${encodeURIComponent( - kind, - )}/${encodeURIComponent(name)}`, - { - method: 'POST', - body: JSON.stringify(requestBody), - }, - ); - } - - async runBulkChecks( - entities: CompoundEntityRef[], - checks?: Check[], - ): Promise { - const checkIds = checks ? checks.map(check => check.id) : []; - const requestBody = { - entities, - checks: checkIds.length > 0 ? checkIds : undefined, - }; - return this.api('/checks/run', { - method: 'POST', - body: JSON.stringify(requestBody), - }); - } - - private async api(path: string, init?: RequestInit): Promise { - const url = await this.discoveryApi.getBaseUrl('tech-insights'); - const { token } = await this.identityApi.getCredentials(); - - const headers: HeadersInit = new Headers(init?.headers); - if (!headers.has('content-type')) - headers.set('content-type', 'application/json'); - if (token && !headers.has('authorization')) { - headers.set('authorization', `Bearer ${token}`); - } - - const request = new Request(`${url}${path}`, { - ...init, - headers, - }); - - return fetch(request).then(async response => { - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } - return response.json() as Promise; - }); - } -} diff --git a/plugins/tech-insights/src/api/index.ts b/plugins/tech-insights/src/api/index.ts deleted file mode 100644 index 9f5545e671..0000000000 --- a/plugins/tech-insights/src/api/index.ts +++ /dev/null @@ -1,18 +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. - */ -export * from './TechInsightsApi'; -export * from './TechInsightsClient'; -export * from './types'; diff --git a/plugins/tech-insights/src/api/types.ts b/plugins/tech-insights/src/api/types.ts deleted file mode 100644 index b08f63ecc2..0000000000 --- a/plugins/tech-insights/src/api/types.ts +++ /dev/null @@ -1,80 +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 { JsonValue } from '@backstage/types'; - -/** - * Represents a single check defined on the TechInsights backend. - * - * @public - */ -export type Check = { - /** - * Unique identifier of the check - * - * Used to identify which checks to use when running checks. - */ - id: string; - - /** - * Type identifier for the check. - * Can be used to determine storage options, logical routing to correct FactChecker implementation - * or to help frontend render correct component types based on this - */ - type: string; - - /** - * Human readable name of the check, may be displayed in the UI - */ - name: string; - - /** - * Human readable description of the check, may be displayed in the UI - */ - description: string; - - /** - * A collection of string referencing fact rows that a check will be run against. - * - * References the fact container, aka fact retriever itself which may or may not contain multiple individual facts and values - */ - factIds: string[]; - - /** - * Metadata to be returned in case a check has been successfully evaluated - * Can contain links, description texts or other actionable items - */ - successMetadata?: Record; - - /** - * Metadata to be returned in case a check evaluation has ended in failure - * Can contain links, description texts or other actionable items - */ - failureMetadata?: Record; -}; - -/** - * Represents a Fact defined on the TechInsights backend. - * - * @public - */ -export interface InsightFacts { - [factId: string]: { - timestamp: string; - version: string; - facts: Record; - }; -} diff --git a/plugins/tech-insights/src/components/BooleanCheck/BooleanCheck.tsx b/plugins/tech-insights/src/components/BooleanCheck/BooleanCheck.tsx deleted file mode 100644 index 17758e8ee4..0000000000 --- a/plugins/tech-insights/src/components/BooleanCheck/BooleanCheck.tsx +++ /dev/null @@ -1,31 +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 CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; -import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; - -/** - * @public - */ -export const BooleanCheck = (props: { checkResult: CheckResult }) => { - return !!props.checkResult.result ? ( - - ) : ( - - ); -}; diff --git a/plugins/tech-insights/src/components/BooleanCheck/index.ts b/plugins/tech-insights/src/components/BooleanCheck/index.ts deleted file mode 100644 index 729ab4d62e..0000000000 --- a/plugins/tech-insights/src/components/BooleanCheck/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { BooleanCheck } from './BooleanCheck'; diff --git a/plugins/tech-insights/src/components/CheckResultRenderer.tsx b/plugins/tech-insights/src/components/CheckResultRenderer.tsx deleted file mode 100644 index 7db3c72c02..0000000000 --- a/plugins/tech-insights/src/components/CheckResultRenderer.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 { CheckResult } from '@backstage/plugin-tech-insights-common'; -import React from 'react'; -import { BooleanCheck } from './BooleanCheck'; - -/** - * Defines a react component that is responsible for rendering a result of a given type. - * - * @public - */ -export type CheckResultRenderer = { - type: string; - component: (check: CheckResult) => React.ReactElement; - description?: (check: CheckResult) => string | React.ReactElement; -}; - -/** - * Default renderer for json-rules-engine check results. - * - * @public - */ -export const jsonRulesEngineCheckResultRenderer: CheckResultRenderer = { - type: 'json-rules-engine', - component: (checkResult: CheckResult) => ( - - ), -}; diff --git a/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx b/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx deleted file mode 100644 index 4bbc283829..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx +++ /dev/null @@ -1,52 +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 useAsync from 'react-use/lib/useAsync'; -import { ErrorPanel, Progress } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { ScorecardInfo } from '../ScorecardsInfo'; -import { techInsightsApiRef } from '../../api/TechInsightsApi'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { getCompoundEntityRef } from '@backstage/catalog-model'; - -export const ScorecardsCard = (props: { - title: string; - description?: string; - checksId?: string[]; -}) => { - const { title, description, checksId } = props; - const api = useApi(techInsightsApiRef); - const { entity } = useEntity(); - const { value, loading, error } = useAsync( - async () => await api.runChecks(getCompoundEntityRef(entity), checksId), - [api, entity, JSON.stringify(checksId)], - ); - - if (loading) { - return ; - } else if (error) { - return ; - } - - return ( - - ); -}; diff --git a/plugins/tech-insights/src/components/ScorecardsCard/index.ts b/plugins/tech-insights/src/components/ScorecardsCard/index.ts deleted file mode 100644 index 1218d4d4cb..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsCard/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { ScorecardsCard } from './ScorecardsCard'; diff --git a/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.tsx b/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.tsx deleted file mode 100644 index f8871b87c1..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.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 React from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { Content, Page, Progress } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { ScorecardInfo } from '../ScorecardsInfo'; -import Alert from '@material-ui/lab/Alert'; -import { techInsightsApiRef } from '../../api/TechInsightsApi'; -import { makeStyles } from '@material-ui/core'; -import { useEntity } from '@backstage/plugin-catalog-react'; -import { getCompoundEntityRef } from '@backstage/catalog-model'; - -const useStyles = makeStyles(() => ({ - contentScorecards: { - paddingLeft: 0, - paddingRight: 0, - }, -})); - -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 } = getCompoundEntityRef(useEntity().entity); - const { value, loading, error } = useAsync( - async () => await api.runChecks({ namespace, kind, name }, checksId), - ); - - if (loading) { - return ; - } else if (error) { - return {error.message}; - } - - return ( - - - - - - ); -}; diff --git a/plugins/tech-insights/src/components/ScorecardsContent/index.ts b/plugins/tech-insights/src/components/ScorecardsContent/index.ts deleted file mode 100644 index fcdfb0b694..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsContent/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { ScorecardsContent } from './ScorecardContent'; diff --git a/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx b/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx deleted file mode 100644 index cfff074368..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx +++ /dev/null @@ -1,74 +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 { makeStyles, Grid, Typography } from '@material-ui/core'; -import { InfoCard } from '@backstage/core-components'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { Alert } from '@material-ui/lab'; -import { ScorecardsList } from '../ScorecardsList'; - -const useStyles = makeStyles(theme => ({ - subheader: { - fontWeight: 'bold', - paddingLeft: theme.spacing(0.5), - }, -})); - -const infoCard = ( - title: string, - description: string | undefined, - className: string, - element: JSX.Element, -) => ( - - - {description && ( - - {description} - - )} - - {element} - - - -); - -export const ScorecardInfo = (props: { - checkResults: CheckResult[]; - title: string; - description?: string; -}) => { - const { checkResults, title, description } = props; - const classes = useStyles(); - - if (!checkResults.length) { - return infoCard( - title, - description, - classes.subheader, - No checks have any data yet., - ); - } - - return infoCard( - title, - description, - classes.subheader, - , - ); -}; diff --git a/plugins/tech-insights/src/components/ScorecardsInfo/index.ts b/plugins/tech-insights/src/components/ScorecardsInfo/index.ts deleted file mode 100644 index 21928465e0..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsInfo/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { ScorecardInfo } from './ScorecardInfo'; diff --git a/plugins/tech-insights/src/components/ScorecardsList/ScorecardsList.tsx b/plugins/tech-insights/src/components/ScorecardsList/ScorecardsList.tsx deleted file mode 100644 index 1a9d04a9de..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsList/ScorecardsList.tsx +++ /dev/null @@ -1,70 +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 { useApi } from '@backstage/core-plugin-api'; -import { makeStyles, List, ListItem, ListItemText } from '@material-ui/core'; -import { techInsightsApiRef } from '../../api'; -import { CheckResult } from '@backstage/plugin-tech-insights-common'; -import { Alert } from '@material-ui/lab'; -import { MarkdownContent } from '@backstage/core-components'; - -const useStyles = makeStyles(theme => ({ - listItemText: { - paddingRight: theme.spacing(0.5), - }, -})); - -export const ScorecardsList = (props: { checkResults: CheckResult[] }) => { - const { checkResults } = props; - const classes = useStyles(); - const api = useApi(techInsightsApiRef); - - const types = [...new Set(checkResults.map(({ check }) => check.type))]; - const checkResultRenderers = api.getCheckResultRenderers(types); - - return ( - - {checkResults.map((result, index) => { - const description = checkResultRenderers.find( - renderer => renderer.type === result.check.type, - )?.description; - - return ( - - - ) - } - className={classes.listItemText} - /> - {checkResultRenderers - .find(({ type }) => type === result.check.type) - ?.component(result) ?? ( - Unknown type. - )} - - ); - })} - - ); -}; diff --git a/plugins/tech-insights/src/components/ScorecardsList/index.ts b/plugins/tech-insights/src/components/ScorecardsList/index.ts deleted file mode 100644 index cc4ad3557b..0000000000 --- a/plugins/tech-insights/src/components/ScorecardsList/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export { ScorecardsList } from './ScorecardsList'; diff --git a/plugins/tech-insights/src/index.ts b/plugins/tech-insights/src/index.ts deleted file mode 100644 index e7659e39d4..0000000000 --- a/plugins/tech-insights/src/index.ts +++ /dev/null @@ -1,28 +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. - */ -export { - techInsightsPlugin, - EntityTechInsightsScorecardContent, - EntityTechInsightsScorecardCard, - ScorecardInfo, - ScorecardsList, -} from './plugin'; - -export { techInsightsApiRef, TechInsightsClient } from './api'; -export type { TechInsightsApi, Check, InsightFacts } from './api'; -export { BooleanCheck } from './components/BooleanCheck'; -export { jsonRulesEngineCheckResultRenderer } from './components/CheckResultRenderer'; -export type { CheckResultRenderer } from './components/CheckResultRenderer'; diff --git a/plugins/tech-insights/src/plugin.test.ts b/plugins/tech-insights/src/plugin.test.ts deleted file mode 100644 index a4a9e6f308..0000000000 --- a/plugins/tech-insights/src/plugin.test.ts +++ /dev/null @@ -1,22 +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 { techInsightsPlugin } from './plugin'; - -describe('tech insights', () => { - it('should export plugin', () => { - expect(techInsightsPlugin).toBeDefined(); - }); -}); diff --git a/plugins/tech-insights/src/plugin.ts b/plugins/tech-insights/src/plugin.ts deleted file mode 100644 index 412d2a0a1d..0000000000 --- a/plugins/tech-insights/src/plugin.ts +++ /dev/null @@ -1,91 +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 { - createPlugin, - createRoutableExtension, - createApiFactory, - discoveryApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; -import { rootRouteRef } from './routes'; -import { techInsightsApiRef } from './api/TechInsightsApi'; -import { TechInsightsClient } from './api/TechInsightsClient'; - -/** - * @public - */ -export const techInsightsPlugin = createPlugin({ - id: 'tech-insights', - apis: [ - createApiFactory({ - api: techInsightsApiRef, - deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, - factory: ({ discoveryApi, identityApi }) => - new TechInsightsClient({ discoveryApi, identityApi }), - }), - ], - routes: { - root: rootRouteRef, - }, -}); - -/** - * @public - */ -export const ScorecardInfo = techInsightsPlugin.provide( - createRoutableExtension({ - name: 'ScorecardInfo', - component: () => - import('./components/ScorecardsInfo').then(m => m.ScorecardInfo), - mountPoint: rootRouteRef, - }), -); - -/** - * @public - */ -export const ScorecardsList = techInsightsPlugin.provide( - createRoutableExtension({ - name: 'ScorecardsList', - component: () => - import('./components/ScorecardsList').then(m => m.ScorecardsList), - mountPoint: rootRouteRef, - }), -); - -/** - * @public - */ -export const EntityTechInsightsScorecardContent = techInsightsPlugin.provide( - createRoutableExtension({ - name: 'EntityTechInsightsScorecardContent', - component: () => - import('./components/ScorecardsContent').then(m => m.ScorecardsContent), - mountPoint: rootRouteRef, - }), -); - -/** - * @public - */ -export const EntityTechInsightsScorecardCard = techInsightsPlugin.provide( - createRoutableExtension({ - name: 'EntityTechInsightsScorecardCard', - component: () => - import('./components/ScorecardsCard').then(m => m.ScorecardsCard), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/tech-insights/src/routes.ts b/plugins/tech-insights/src/routes.ts deleted file mode 100644 index b1b7900074..0000000000 --- a/plugins/tech-insights/src/routes.ts +++ /dev/null @@ -1,20 +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 { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'tech-insights', -}); diff --git a/plugins/tech-insights/src/setupTests.ts b/plugins/tech-insights/src/setupTests.ts deleted file mode 100644 index 7435872609..0000000000 --- a/plugins/tech-insights/src/setupTests.ts +++ /dev/null @@ -1,16 +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 '@testing-library/jest-dom'; diff --git a/plugins/tech-radar/.eslintrc.js b/plugins/tech-radar/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/tech-radar/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md deleted file mode 100644 index fb54c03bb3..0000000000 --- a/plugins/tech-radar/CHANGELOG.md +++ /dev/null @@ -1,1429 +0,0 @@ -# @backstage/plugin-tech-radar - -## 0.6.13-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/core-compat-api@0.2.0-next.3 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/frontend-plugin-api@0.6.0-next.3 - -## 0.6.13-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/frontend-plugin-api@0.6.0-next.2 - - @backstage/core-compat-api@0.2.0-next.2 - -## 0.6.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.6.0-next.1 - - @backstage/core-compat-api@0.2.0-next.1 - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - -## 0.6.13-next.0 - -### Patch Changes - -- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. -- Updated dependencies - - @backstage/core-compat-api@0.1.2-next.0 - - @backstage/frontend-plugin-api@0.5.1-next.0 - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - -## 0.6.12 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-compat-api@0.1.1 - - @backstage/frontend-plugin-api@0.5.0 - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - -## 0.6.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-compat-api@0.1.1-next.2 - - @backstage/frontend-plugin-api@0.4.1-next.2 - -## 0.6.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/core-compat-api@0.1.1-next.1 - - @backstage/frontend-plugin-api@0.4.1-next.1 - -## 0.6.12-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/frontend-plugin-api@0.4.1-next.0 - - @backstage/core-compat-api@0.1.1-next.0 - - @backstage/core-plugin-api@1.8.1 - -## 0.6.11 - -### Patch Changes - -- 03d0b6d: The `convertLegacyRouteRef` utility used by the alpha exports is now imported from `@backstage/core-compat-api`. -- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. -- 5814122: Updated `/alpha` exports to fit new naming patterns. -- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. -- Updated dependencies - - @backstage/core-compat-api@0.1.0 - - @backstage/core-plugin-api@1.8.1 - - @backstage/frontend-plugin-api@0.4.0 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - -## 0.6.11-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/core-compat-api@0.1.0-next.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/frontend-plugin-api@0.4.0-next.3 - - @backstage/theme@0.5.0-next.1 - -## 0.6.11-next.3 - -### Patch Changes - -- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. -- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. -- Updated dependencies - - @backstage/frontend-plugin-api@0.4.0-next.2 - - @backstage/theme@0.5.0-next.1 - - @backstage/core-compat-api@0.1.0-next.2 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - -## 0.6.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.4.0-next.1 - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/core-compat-api@0.0.1-next.1 - - @backstage/theme@0.5.0-next.0 - -## 0.6.11-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-compat-api@0.0.1-next.0 - -## 0.6.11-next.0 - -### Patch Changes - -- 03d0b6dcdc: The `convertLegacyRouteRef` utility used by the alpha exports is now imported from `@backstage/core-compat-api`. -- Updated dependencies - - @backstage/core-compat-api@0.0.2-next.0 - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/frontend-plugin-api@0.3.1-next.0 - -## 0.6.10 - -### Patch Changes - -- 68fc9dc60e: Updated alpha exports according to routing changes in `@backstage/frontend-plugin-api`. -- 6c2b872153: Add official support for React 18. -- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/frontend-plugin-api@0.3.0 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - -## 0.6.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/frontend-plugin-api@0.3.0-next.2 - -## 0.6.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.3.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.6.10-next.0 - -### Patch Changes - -- 68fc9dc60e: Updated alpha exports according to routing changes in `@backstage/frontend-plugin-api`. -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/frontend-plugin-api@0.3.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - -## 0.6.9 - -### Patch Changes - -- 0b55f773a7: Removed some unused dependencies -- c09d2fa1d6: Added experimental support for the declarative integration. -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/frontend-plugin-api@0.2.0 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/theme@0.4.3 - -## 0.6.9-next.2 - -### Patch Changes - -- 0b55f773a7: Removed some unused dependencies -- Updated dependencies - - @backstage/frontend-plugin-api@0.2.0-next.2 - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/theme@0.4.3-next.0 - -## 0.6.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/frontend-plugin-api@0.1.1-next.1 - - @backstage/core-components@0.13.6-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/theme@0.4.2 - -## 0.6.9-next.0 - -### Patch Changes - -- c09d2fa1d6: Added experimental support for the declarative integration. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/frontend-plugin-api@0.1.1-next.0 - - @backstage/theme@0.4.2 - -## 0.6.8 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- b45d0ac68191: Add names to blip entry links in the radar to improve accessibility -- 80b4d0b34f14: Fixed the width of the tech radar dialog so that the content fits -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 6d35e9ea2afa: Add description property for Rings which will be shown in the footer. -- 8cec7664e146: Removed `@types/node` dependency -- c357f62052af: Fixed `RadarTimeline` text formatting. -- Updated dependencies - - @backstage/core-components@0.13.5 - - @backstage/core-plugin-api@1.6.0 - - @backstage/theme@0.4.2 - -## 0.6.8-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- c357f62052af: Fixed `RadarTimeline` text formatting. -- Updated dependencies - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.6.8-next.2 - -### Patch Changes - -- b45d0ac68191: Add names to blip entry links in the radar to improve accessibility -- 6d35e9ea2afa: Add description property for Rings which will be shown in the footer. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/theme@0.4.1 - -## 0.6.8-next.1 - -### Patch Changes - -- 80b4d0b34f14: Fixed the width of the tech radar dialog so that the content fits -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/theme@0.4.1 - -## 0.6.8-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/theme@0.4.1 - -## 0.6.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - -## 0.6.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/theme@0.4.1 - -## 0.6.6 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - -## 0.6.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - -## 0.6.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - -## 0.6.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.3-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - -## 0.6.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - -## 0.6.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.1 - -## 0.6.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.6.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.6.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.6.4 - -### Patch Changes - -- be4fa53fab8: Fix description links when clicking entry in radar. -- Added the ability to display a timeline to each entry in the details box -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/core-components@0.13.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.6.4-next.2 - -### Patch Changes - -- be4fa53fab8: Fix description links when clicking entry in radar. -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.6.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.6.4-next.0 - -### Patch Changes - -- Added the ability to display a timeline to each entry in the details box -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/theme@0.2.19 - -## 0.6.3 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - -## 0.6.3-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.6.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/theme@0.2.19-next.0 - -## 0.6.3-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/theme@0.2.19-next.0 - -## 0.6.3-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - -## 0.6.2 - -### Patch Changes - -- e14dcfa4994: Update colors to match Zalando's tech radar, also add coloring on title and legend to match ring color. -- cb8ec97cdeb: Change black & white colors to be theme aware -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - -## 0.6.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.6.2-next.1 - -### Patch Changes - -- e14dcfa4994: Update colors to match Zalando's tech radar, also add coloring on title and legend to match ring color. -- cb8ec97cdeb: Change black & white colors to be theme aware -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - -## 0.6.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/theme@0.2.17 - -## 0.6.1 - -### Patch Changes - -- acf6c8c10b: Deprecate `RadarEntry.url` - use `RadarEntry.links` instead - - ```diff - - url: 'https://www.javascript.com/', - key: 'javascript', - id: 'javascript', - title: 'JavaScript', - quadrant: 'languages', - links: [ - + { - + url: 'https://www.javascript.com/', - + title: 'Learn more', - + }, - ], - ``` - -- 18024a231c: Allow to set additional links to the entry description. -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - -## 0.6.1-next.1 - -### Patch Changes - -- acf6c8c10b: Deprecate `RadarEntry.url` - use `RadarEntry.links` instead - - ```diff - - url: 'https://www.javascript.com/', - key: 'javascript', - id: 'javascript', - title: 'JavaScript', - quadrant: 'languages', - links: [ - + { - + url: 'https://www.javascript.com/', - + title: 'Learn more', - + }, - ], - ``` - -- Updated dependencies - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.6.1-next.0 - -### Patch Changes - -- 18024a231c: Allow to set additional links to the entry description. -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.6.0 - -### Minor Changes - -- 38fd519fc1: Add highlighting of legend item and show bubble on hover within the Tech Radar - -### Patch Changes - -- 27a5e90e97: Small updates to some paragraph components to ensure theme typography properties are inherited correctly. -- 80ce4e8c29: Small updates to some components to ensure theme typography properties are inherited correctly. -- Updated dependencies - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/theme@0.2.16 - -## 0.6.0-next.2 - -### Minor Changes - -- 38fd519fc1: Add highlighting of legend item and show bubble on hover within the Tech Radar - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/theme@0.2.16 - -## 0.5.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/theme@0.2.16 - -## 0.5.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/theme@0.2.16 - -## 0.5.20 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - -## 0.5.19 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/theme@0.2.16 - -## 0.5.19-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.5.19-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/theme@0.2.16 - -## 0.5.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/theme@0.2.16 - -## 0.5.19-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/theme@0.2.16 - -## 0.5.19-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/theme@0.2.16 - -## 0.5.18 - -### Patch Changes - -- 1f888af5f6: Fixed bug in Tech Radar where, on hover, the tech list quadrant would rerender and scroll top -- Updated dependencies - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/theme@0.2.16 - -## 0.5.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - -## 0.5.18-next.0 - -### Patch Changes - -- 1f888af5f6: Fixed bug in Tech Radar where, on hover, the tech list quadrant would rerender and scroll top -- Updated dependencies - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/theme@0.2.16 - -## 0.5.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/theme@0.2.16 - -## 0.5.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/theme@0.2.16 - -## 0.5.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/theme@0.2.16 - -## 0.5.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/theme@0.2.16 - -## 0.5.16 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - -## 0.5.16-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - -## 0.5.16-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.5.16-next.1 - -### Patch Changes - -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - -## 0.5.16-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - -## 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 - -- b8f608f1ec: Update tech-radar documentation on how to use an external json data source with dates. -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - -## 0.5.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/theme@0.2.16-next.1 - -## 0.5.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/theme@0.2.16-next.0 - -## 0.5.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.0 - -## 0.5.13 - -### Patch Changes - -- bb31e5489c: Updated dependency `d3-force` to `^3.0.0`. - Updated dependency `@types/d3-force` to `^3.0.0`. -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - -## 0.5.13-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - -## 0.5.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.0 - -## 0.5.12 - -### Patch Changes - -- 3588a77994: Rename `use` to `adopt`, to reflect Zalando Tech Radar regarding quadrants and add link to Zalando explanation. -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - -## 0.5.12-next.0 - -### Patch Changes - -- 3588a77994: Rename `use` to `adopt`, to reflect Zalando Tech Radar regarding quadrants and add link to Zalando explanation. -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - -## 0.5.11 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- f69789330a: Fix an issue where the Radar is not updated when switching between different radars -- Updated dependencies - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.5.11-next.2 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - -## 0.5.11-next.1 - -### Patch Changes - -- f69789330a: Fix an issue where the Radar is not updated when switching between different radars - -## 0.5.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.3-next.0 - -## 0.5.10 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - -## 0.5.9 - -### Patch Changes - -- bae72d6f4d: Tech Radar Ring names are now coloured from theme via theme.palette.text.primary (instead of a hard coded colour) -- Updated dependencies - - @backstage/core-components@0.9.1 - -## 0.5.9-next.0 - -### Patch Changes - -- bae72d6f4d: Tech Radar Ring names are now coloured from theme via theme.palette.text.primary (instead of a hard coded colour) -- Updated dependencies - - @backstage/core-components@0.9.1-next.0 - -## 0.5.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.5.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/core-plugin-api@0.7.0 - -## 0.5.6 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/theme@0.2.15 - -## 0.5.5 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - -## 0.5.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - -## 0.5.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - -## 0.5.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - -## 0.5.3 - -### Patch Changes - -- 021bba18c4: Update readme -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - -## 0.5.3-next.0 - -### Patch Changes - -- 021bba18c4: Update readme -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - -## 0.5.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - -## 0.5.1 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/core-components@0.8.3 - -## 0.5.0 - -### Minor Changes - -- 11b7761914: Add new property to enable open links in a new window/tab - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/core-components@0.8.2 - -## 0.4.13 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - -## 0.4.12 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.4.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.4.10 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - -## 0.4.9 - -### Patch Changes - -- c1ef701395: Added `SearchBar` to allow filtering and a scroll bar to display hidden tech -- 3c47ece3c3: Added documentation for exported symbols. -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - -## 0.4.8 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - -## 0.4.7 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/core-plugin-api@0.1.8 - -## 0.4.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.4.0 - -## 0.4.5 - -### Patch Changes - -- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - -## 0.4.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - -## 0.4.3 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.4.2 - -### Patch Changes - -- 846168da2: Add optional id prop passing it to the load API -- Updated dependencies - - @backstage/core-components@0.1.4 - -## 0.4.1 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - -## 0.4.0 - -### Minor Changes - -- 90a505a77: Migrating the Tech Radar to support using `ApiRefs` to load custom data. - - If you had a `getData` function, you'll now need to encapsulate that logic in a class that can override the `techRadarApiRef`. - - ```ts - // app/src/lib/MyClient.ts - import { - TechRadarApi, - TechRadarLoaderResponse, - } from '@backstage/plugin-tech-radar'; - - class MyOwnClient implements TechRadarApi { - async load(): Promise { - // here's where you would put you logic to load the response that was previously passed into getData - } - } - - // app/src/apis.ts - import { MyOwnClient } from './lib/MyClient'; - import { techRadarApiRef } from '@backstage/plugin-tech-radar'; - - export const apis: AnyApiFactory[] = [ - /* - ... - */ - createApiFactory(techRadarApiRef, new MyOwnClient()), - ]; - ``` - -### Patch Changes - -- Updated dependencies [e7c5e4b30] -- Updated dependencies [1cf1d351f] - - @backstage/theme@0.2.8 - - @backstage/core@0.7.12 - -## 0.3.11 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [889d89b6e] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - -## 0.3.10 - -### Patch Changes - -- b2e2ec753: Update README for composability -- Updated dependencies [f65adcde7] -- Updated dependencies [80888659b] -- Updated dependencies [7b8272fb7] - - @backstage/core@0.7.8 - - @backstage/theme@0.2.7 - -## 0.3.9 - -### Patch Changes - -- 184b02bef: Add markdown support for tech radar entry description -- Updated dependencies [d0d1c2f7b] -- Updated dependencies [5cafcf452] -- Updated dependencies [86a95ba67] -- Updated dependencies [e27cb6c45] - - @backstage/core@0.7.5 - -## 0.3.8 - -### Patch Changes - -- 34e6bb409: Map description in API RadarEntry to Entry - - The description in the Entry was mapped to the latest timeline entry, which is a changelog. This - change maps the description in the API to the entry. To maintain backwards compatibility it - will set the description to the last timeline entry if no description exists at the entry level. - -- b56815b40: Fixes issue where radar description dialog is not shown when the entry has an url external to the radar page -- Updated dependencies [8686eb38c] -- Updated dependencies [9ca0e4009] -- Updated dependencies [34ff49b0f] - - @backstage/core@0.7.2 - -## 0.3.7 - -### Patch Changes - -- Updated dependencies [40c0fdbaa] -- Updated dependencies [2a271d89e] -- Updated dependencies [bece09057] -- Updated dependencies [169f48deb] -- Updated dependencies [8a1566719] -- Updated dependencies [4c049a1a1] - - @backstage/core@0.7.0 - -## 0.3.6 - -### Patch Changes - -- 9f2b3a26e: Added a dialog box that will show up when a you click on link on the radar and display the description if provided. -- Updated dependencies [3a58084b6] -- Updated dependencies [e799e74d4] -- Updated dependencies [1407b34c6] -- Updated dependencies [9615e68fb] -- Updated dependencies [49f9b7346] -- Updated dependencies [3a58084b6] -- Updated dependencies [2c1f2a7c2] - - @backstage/core@0.6.3 - -## 0.3.5 - -### Patch Changes - -- 804502a5c: Migrated to new composability API, exporting the plugin instance as `techRadarPlugin` and the page as `TechRadarPage`. -- Updated dependencies [b51ee6ece] - - @backstage/core@0.6.1 - -## 0.3.4 - -### Patch Changes - -- 90c8f20b9: Fix mapping RadarEntry and Entry for moved and url attributes - Fix clicking of links in the radar legend -- Updated dependencies [12ece98cd] -- Updated dependencies [d82246867] -- Updated dependencies [c810082ae] -- Updated dependencies [5fa3bdb55] -- Updated dependencies [21e624ba9] -- Updated dependencies [da9f53c60] -- Updated dependencies [32c95605f] -- Updated dependencies [54c7d02f7] - - @backstage/core@0.6.0 - - @backstage/theme@0.2.3 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies [efd6ef753] -- Updated dependencies [a187b8ad0] - - @backstage/core@0.5.0 - -## 0.3.2 - -### Patch Changes - -- ab0892358: Remove test dependencies from production package list -- bc909178d: Updated example data in `README`. - -## 0.3.1 - -### Patch Changes - -- Updated dependencies [2527628e1] -- Updated dependencies [e1f4e24ef] -- Updated dependencies [1c69d4716] -- Updated dependencies [1665ae8bb] -- Updated dependencies [04f26f88d] -- Updated dependencies [ff243ce96] - - @backstage/core@0.4.0 - - @backstage/test-utils@0.1.5 - - @backstage/theme@0.2.2 - -## 0.3.0 - -### Minor Changes - -- a906f20e7: Added tech radar blip history backend support and normalized the data structure - -### Patch Changes - -- 3f05616bf: Make the footer color of the tech-radar work in both light and dark theme. -- Updated dependencies [7b37d65fd] -- Updated dependencies [4aca74e08] -- Updated dependencies [e8f69ba93] -- Updated dependencies [0c0798f08] -- Updated dependencies [0c0798f08] -- Updated dependencies [199237d2f] -- Updated dependencies [6627b626f] -- Updated dependencies [4577e377b] - - @backstage/core@0.3.0 - - @backstage/theme@0.2.1 - -## 0.2.0 - -### Minor Changes - -- 28edd7d29: Create backend plugin through CLI - -### Patch Changes - -- 782f3b354: add test case for Progress component -- 02c60b5f8: fix the horizontal scrolling issue in the RadarPage component -- Updated dependencies [819a70229] -- Updated dependencies [ae5983387] -- Updated dependencies [0d4459c08] -- Updated dependencies [482b6313d] -- Updated dependencies [1c60f716e] -- Updated dependencies [144c66d50] -- Updated dependencies [b79017fd3] -- Updated dependencies [6d97d2d6f] -- Updated dependencies [93a3fa3ae] -- Updated dependencies [782f3b354] -- Updated dependencies [2713f28f4] -- Updated dependencies [406015b0d] -- Updated dependencies [82759d3e4] -- Updated dependencies [ac8d5d5c7] -- Updated dependencies [ebca83d48] -- Updated dependencies [aca79334f] -- Updated dependencies [c0d5242a0] -- Updated dependencies [3beb5c9fc] -- Updated dependencies [754e31db5] -- Updated dependencies [1611c6dbc] - - @backstage/core@0.2.0 - - @backstage/theme@0.2.0 - - @backstage/test-utils@0.1.2 diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md deleted file mode 100644 index a28ced777e..0000000000 --- a/plugins/tech-radar/README.md +++ /dev/null @@ -1,261 +0,0 @@ -# @backstage/plugin-tech-radar - -Screenshot of Tech Radar plugin - -The Backstage integration for the Tech Radar based on [Zalando's Tech Radar](https://opensource.zalando.com/tech-radar/) open sourced on [GitHub](https://github.com/zalando/tech-radar). This is used at [Spotify](https://spotify.github.io) for visualizing the official guidelines of different areas of software development such as languages, frameworks, infrastructure and processes. - -Read the [blog post on backstage.io about the Tech Radar](https://backstage.io/blog/2020/05/14/tech-radar-plugin). - -## Purpose - -Zalando has a fantastic description [on their website](https://opensource.zalando.com/tech-radar/): - -> The Tech Radar is a tool to inspire and support engineering teams at Zalando to pick the best technologies for new projects; it provides a platform to share knowledge and experience in technologies, to reflect on technology decisions and continuously evolve our technology landscape. Based on the pioneering work of ThoughtWorks, our Tech Radar sets out the changes in technologies that are interesting in software development — changes that we think our engineering teams should pay attention to and consider using in their projects. - -It serves and scales well for teams and companies of all sizes that want to have alignment across dozens of technologies and visualize it in a simple way. - -## Getting Started - -The Tech Radar can be used in two ways: - -- **Simple (Recommended)** - This gives you an out-of-the-box Tech Radar experience. It lives on the `/tech-radar` URL of your Backstage installation. -- **Advanced** - This gives you the React UI component directly. It enables you to insert the Radar on your own layout or page for a more customized feel. - -### Install - -For either simple or advanced installations, you'll need to add the dependency using Yarn: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-tech-radar -``` - -### Configuration - -Modify your app routes to include the Router component exported from the tech radar, for example: - -```tsx -// In packages/app/src/App.tsx -import { TechRadarPage } from '@backstage/plugin-tech-radar'; - -const routes = ( - - {/* ...other routes */} - } - /> -``` - -If you'd like to configure it more, see the `TechRadarPageProps` and `TechRadarComponentProps` types for options: - -```ts -export type TechRadarPageProps = TechRadarComponentProps & { - title?: string; - subtitle?: string; - pageTitle?: string; -}; - -export interface TechRadarPageProps { - width: number; - height: number; - svgProps?: object; -} -``` - -### Radar properties - -When defining the radar entries you can see the available properties on the file [api](./src/api.ts) - -## Tech radar data model - -| Name | Type | Description | Required? | -| ----------- | ----------------------- | -------------------------------------------------------------------- | --------- | -| `title` | string | The title of the radar | Yes | -| `quadrants` | [quadrant[]](#quadrant) | The 4 quadrants of the radar, clockwise starting at the bottom right | Yes | -| `rings` | [ring[]](#ring) | The radar rings, starting from the inside | Yes | -| `entries` | [entry[]](#entry) | The radar entries | Yes | - -### quadrant - -| Name | Type | Description | Required? | -| ------ | ------ | ------------------------ | --------- | -| `id` | string | The id of the quadrant | Yes | -| `name` | string | The name of the quadrant | Yes | - -### ring - -| Name | Type | Description | Required? | -| ------------- | ------ | ------------------------------------------------- | --------- | -| `id` | string | The id of the ring | Yes | -| `name` | string | The name of the ring | Yes | -| `color` | string | The color of the ring and entries inside the ring | Yes | -| `description` | string | Description of the Ring | No | - -### entry - -| Name | Type | Description | Required? | -| ------------- | ----------------------- | ----------------------------------------------- | --------- | -| `id` | string | The unique id from the entry | Yes | -| `title` | string | The title that is shown in the radar | Yes | -| `description` | string | The full description of the entry | No | -| key | string | The entry key | Yes | -| `url` | string | The URL to the entry internal or external page | No | -| `quadrant` | string | The name of the quadrant connected to the entry | Yes | -| `timeline` | [timeline[]](#timeline) | Requires minimal one timeline entry | Yes | - -### timeline - -| Name | Type | Description | Required? | -| ------------- | ------ | ------------------------------------------------------------- | --------- | -| `moved` | number | Possible values are: -1 (moved out), 0 (stayed), 1 (moved in) | Yes | -| `ringId` | string | The ring id | Yes | -| `date` | string | Date in format (YYYY-MM-dd) | Yes | -| `description` | string | A long description | Yes | - -### Sample - -This is a sample on how the JSON file could look like. -The TS example can be found [here](src/sample.ts). - -```JSON -{ - "title": "Title of your Tech radar", - "quadrants": [ - { - "id": "1", - "name": "Bottom right" - }, - { - "id": "2", - "name": "Bottom left" - }, - { - "id": "3", - "name": "Top left" - }, - { - "id": "4", - "name": "Top right" - } - ], - "rings": [ - { - "id": "adopt", - "name": "ADOPT", - "color": "#93c47d" - }, - { - "id": "trial", - "name": "TRIAL", - "color": "#93d2c2" - }, - { - "id": "assess", - "name": "ASSESS", - "color": "#fbdb84" - }, - { - "id": "hold", - "name": "HOLD", - "color": "#efafa9" - } - ], - "entries": [ - { - "id": "typescript", - "title": "Typescript", - "description": "Long description for Typescript", - "key": "typescript", - "url": "#", - "quadrant": "1", - "timeline": [ - { - "moved": 0, - "ringId": "trial", - "date": "2022-02-06", - "description": "Long description for trial" - }, - { - "moved": 1, - "ringId": "adopt", - "date": "2022-02-08", - "description": "Long description for adopt" - } - ] - }, - ... - ] -} -``` - -## Frequently Asked Questions - -### Who created the Tech Radar? - -[ThoughtWorks](https://thoughtworks.com/radar) created the Tech Radar concept, and [Zalando created the visualization](https://opensource.zalando.com/tech-radar/) that we use at Spotify and in this plugin. - -### How do I load in my own data? - -The `TechRadar` plugin uses the `techRadarApiRef` to get a client which implements the `TechRadarApi` interface. The default sample one is located [here](https://github.com/backstage/backstage/blob/master/plugins/tech-radar/src/sample.ts). To load your own data, you'll need to provide a class that implements the `TechRadarApi` and override the `techRadarApiRef` in the `app/src/apis.ts`. - -```ts -// app/src/lib/MyClient.ts -import { - TechRadarApi, - TechRadarLoaderResponse, -} from '@backstage/plugin-tech-radar'; - -export class MyOwnClient implements TechRadarApi { - async load(id: string | undefined): Promise { - // if needed id prop can be used to fetch the correct data - - const data = await fetch('https://mydata.json').then(res => res.json()); - - // For example, this converts the timeline dates into date objects - return { - ...data, - entries: data.entries.map(entry => ({ - ...entry, - timeline: entry.timeline.map(timeline => ({ - ...timeline, - date: new Date(timeline.date), - })), - })), - }; - } -} - -// app/src/apis.ts -import { MyOwnClient } from './lib/MyClient'; -import { techRadarApiRef } from '@backstage/plugin-tech-radar'; - -export const apis: AnyApiFactory[] = [ - /* - ... - */ - createApiFactory(techRadarApiRef, new MyOwnClient()), -]; -``` - -### How do I write tests? - -You can use the `svgProps` option to pass custom React props to the `` element we create for the Tech Radar. This complements well with the `data-testid` attribute and the `@testing-library/react` library we use in Backstage. - -```tsx - - -// Then, in your tests... -// const { getByTestId } = render(...); -// expect(getByTestId('tech-radar-svg')).toBeInTheDocument(); -``` - -### How do I support multiple radars - -The `TechRadarPage` and `TechRadarComponent` components both take an optional `id` prop which is subsequently passed to the `load` method of the API to distinguish which radar's data to load. diff --git a/plugins/tech-radar/api-report-alpha.md b/plugins/tech-radar/api-report-alpha.md deleted file mode 100644 index 34b035296e..0000000000 --- a/plugins/tech-radar/api-report-alpha.md +++ /dev/null @@ -1,33 +0,0 @@ -## API Report File for "@backstage/plugin-tech-radar" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; -import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; -import { RouteRef } from '@backstage/frontend-plugin-api'; - -// @alpha (undocumented) -const _default: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -export default _default; - -// @alpha (undocumented) -export const techRadarApi: ExtensionDefinition<{}>; - -// @alpha (undocumented) -export const techRadarPage: ExtensionDefinition<{ - height: number; - width: number; - title: string; - path: string; - subtitle: string; - pageTitle: string; -}>; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/tech-radar/api-report.md b/plugins/tech-radar/api-report.md deleted file mode 100644 index 178fc202cd..0000000000 --- a/plugins/tech-radar/api-report.md +++ /dev/null @@ -1,113 +0,0 @@ -## API Report File for "@backstage/plugin-tech-radar" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { default as React_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public -export enum MovedState { - Down = -1, - NoChange = 0, - Up = 1, -} - -// @public -export interface RadarEntry { - description?: string; - id: string; - key: string; - links?: Array; - quadrant: string; - timeline: Array; - title: string; - // @deprecated - url?: string; -} - -// @public -export interface RadarEntryLink { - title: string; - url: string; -} - -// @public -export interface RadarEntrySnapshot { - date: Date; - description?: string; - moved?: MovedState; - ringId: string; -} - -// @public -export function RadarPage(props: TechRadarPageProps): React_2.JSX.Element; - -// @public -export interface RadarQuadrant { - id: string; - name: string; -} - -// @public -export interface RadarRing { - color: string; - description?: string; - id: string; - name: string; -} - -// @public @deprecated (undocumented) -export const Router: typeof RadarPage; - -// @public -export interface TechRadarApi { - load: (id: string | undefined) => Promise; -} - -// @public -export const techRadarApiRef: ApiRef; - -// @public -export function TechRadarComponent( - props: TechRadarComponentProps, -): React_2.JSX.Element; - -// @public -export interface TechRadarComponentProps { - height: number; - id?: string; - searchText?: string; - svgProps?: object; - width: number; -} - -// @public -export interface TechRadarLoaderResponse { - entries: RadarEntry[]; - quadrants: RadarQuadrant[]; - rings: RadarRing[]; -} - -// @public -export const TechRadarPage: RadarPage; - -// @public -export interface TechRadarPageProps extends TechRadarComponentProps { - pageTitle?: string; - subtitle?: string; - title?: string; -} - -// @public -const techRadarPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -export { techRadarPlugin as plugin }; -export { techRadarPlugin }; -``` diff --git a/plugins/tech-radar/catalog-info.yaml b/plugins/tech-radar/catalog-info.yaml deleted file mode 100644 index ea88b4e264..0000000000 --- a/plugins/tech-radar/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-tech-radar - title: '@backstage/plugin-tech-radar' - description: A Backstage plugin that lets you display a Tech Radar for your organization -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/tech-radar/dev/index.tsx b/plugins/tech-radar/dev/index.tsx deleted file mode 100644 index f796b400b2..0000000000 --- a/plugins/tech-radar/dev/index.tsx +++ /dev/null @@ -1,27 +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 { createDevApp } from '@backstage/dev-utils'; -import { techRadarPlugin, TechRadarPage } from '../src'; - -createDevApp() - .registerPlugin(techRadarPlugin) - .addPage({ - title: 'Tech Radar', - element: , - }) - .render(); diff --git a/plugins/tech-radar/docs/screenshot.png b/plugins/tech-radar/docs/screenshot.png deleted file mode 100644 index 8c1261e57a..0000000000 Binary files a/plugins/tech-radar/docs/screenshot.png and /dev/null differ diff --git a/plugins/tech-radar/knip-report.md b/plugins/tech-radar/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/tech-radar/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json deleted file mode 100644 index b01120eec1..0000000000 --- a/plugins/tech-radar/package.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "name": "@backstage/plugin-tech-radar", - "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.6.13-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/tech-radar" - }, - "keywords": [ - "backstage" - ], - "exports": { - ".": "./src/index.ts", - "./alpha": "./src/alpha.tsx", - "./package.json": "./package.json" - }, - "typesVersions": { - "*": { - "alpha": [ - "src/alpha.tsx" - ], - "package.json": [ - "package.json" - ] - } - }, - "sideEffects": false, - "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/core-compat-api": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/frontend-plugin-api": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "color": "^4.0.1", - "d3-force": "^3.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/frontend-test-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@testing-library/user-event": "^14.0.0", - "@types/color": "^3.0.1", - "@types/d3-force": "^3.0.0" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/tech-radar/src/alpha.test.tsx b/plugins/tech-radar/src/alpha.test.tsx deleted file mode 100644 index 71e5ab8df5..0000000000 --- a/plugins/tech-radar/src/alpha.test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createExtensionTester } from '@backstage/frontend-test-utils'; -import { screen } from '@testing-library/react'; -import { techRadarPage, techRadarApi } from './alpha'; - -describe('TechRadarPage', () => { - beforeAll(() => { - Object.defineProperty(window.SVGElement.prototype, 'getBBox', { - value: () => ({ width: 100, height: 100 }), - configurable: true, - }); - }); - - it('renders without exploding', async () => { - createExtensionTester(techRadarPage).add(techRadarApi).render(); - - await expect(screen.findByText('Tech Radar')).resolves.toBeInTheDocument(); - }); -}); diff --git a/plugins/tech-radar/src/alpha.tsx b/plugins/tech-radar/src/alpha.tsx deleted file mode 100644 index 54e209fae3..0000000000 --- a/plugins/tech-radar/src/alpha.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createApiFactory } from '@backstage/core-plugin-api'; -import { - createApiExtension, - createPageExtension, - createPlugin, - createSchemaFromZod, -} from '@backstage/frontend-plugin-api'; -import React from 'react'; -import { techRadarApiRef } from './api'; -import { SampleTechRadarApi } from './sample'; -import { - compatWrapper, - convertLegacyRouteRef, - convertLegacyRouteRefs, -} from '@backstage/core-compat-api'; -import { rootRouteRef } from './plugin'; - -/** @alpha */ -export const techRadarPage = createPageExtension({ - defaultPath: '/tech-radar', - routeRef: convertLegacyRouteRef(rootRouteRef), - configSchema: createSchemaFromZod(z => - z.object({ - title: z.string().default('Tech Radar'), - subtitle: z - .string() - .default('Pick the recommended technologies for your projects'), - pageTitle: z.string().default('Company Radar'), - path: z.string().default('/tech-radar'), - width: z.number().default(1500), - height: z.number().default(800), - }), - ), - loader: ({ config }) => - import('./components').then(m => - compatWrapper(), - ), -}); - -/** @alpha */ -export const techRadarApi = createApiExtension({ - factory: createApiFactory(techRadarApiRef, new SampleTechRadarApi()), -}); - -/** @alpha */ -export default createPlugin({ - id: 'tech-radar', - extensions: [techRadarPage, techRadarApi], - routes: convertLegacyRouteRefs({ - root: rootRouteRef, - }), -}); diff --git a/plugins/tech-radar/src/api.ts b/plugins/tech-radar/src/api.ts deleted file mode 100644 index 53fbb0bb15..0000000000 --- a/plugins/tech-radar/src/api.ts +++ /dev/null @@ -1,228 +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 { ApiRef, createApiRef } from '@backstage/core-plugin-api'; - -/** - * {@link @backstage/core-plugin-api#ApiRef} for the {@link TechRadarApi} - * - * @public - */ -export const techRadarApiRef: ApiRef = createApiRef( - { - id: 'plugin.techradar.service', - }, -); - -/** - * Tech Radar API responsible for loading data for the plugin - * - * @remarks - * - * This should be implemented by user, as {@link https://github.com/backstage/backstage/blob/master/plugins/tech-radar/src/sample.ts | default} - * serves only some static data for example purposes - * - * @public - */ -export interface TechRadarApi { - /** - * Loads the TechRadar response data to pass through to the TechRadar component. - * Takes the id prop of the TechRadarComponent or TechRadarPage to distinguish between multiple radars if needed - */ - load: (id: string | undefined) => Promise; -} - -/* - * Types related to the Radar's visualization. - */ - -/** - * Tech Radar Ring which indicates stage of {@link RadarEntry} - * - * @public - */ -export interface RadarRing { - /** - * ID of the Ring - */ - id: string; - /** - * Display name of the Ring - */ - name: string; - /** - * Color used for entries in particular Ring - * - * @remarks - * - * Supports any value parseable by {@link https://www.npmjs.com/package/color-string | color-string} - */ - color: string; - /** - * Description of the Ring - */ - description?: string; -} - -/** - * Tech Radar Quadrant which represent area/topic of {@link RadarEntry} - * - * @public - */ -export interface RadarQuadrant { - /** - * ID of the Quadrant - */ - id: string; - /** - * Display name of the Quadrant - */ - name: string; -} - -/** - * Single link in {@link RadarEntry} - * - * @public - */ -export interface RadarEntryLink { - /** - * URL of the link - */ - url: string; - /** - * Display name of the link - */ - title: string; -} - -/** - * Single Entry in Tech Radar - * - * @public - */ -export interface RadarEntry { - /** - * React key to use for this Entry - */ - key: string; - /** - * ID of this Radar Entry - */ - id: string; - /** - * ID of {@link RadarQuadrant} this Entry belongs to - */ - quadrant: string; - /** - * Display name of the Entry - */ - title: string; - /** - * User-clickable URL when rendered in Radar - * - * @remarks - * - * You can use `#` if you don't want to provide any other url - * - * @deprecated Use {@link RadarEntry.links} instead - */ - url?: string; - /** - * History of the Entry moving through {@link RadarRing} - */ - timeline: Array; - /** - * Description of the Entry - */ - description?: string; - /** - * User-clickable links to provide more information about the Entry - */ - links?: Array; -} - -/** - * State of {@link RadarEntry} at given point in time - * - * @public - */ -export interface RadarEntrySnapshot { - /** - * Point in time when change happened - */ - date: Date; - /** - * ID of {@link RadarRing} - */ - ringId: string; - /** - * Description of change - */ - description?: string; - /** - * Indicates trend compared to previous snapshot - */ - moved?: MovedState; -} - -/** - * Indicates how {@link RadarEntry} moved though {@link RadarRing} on {@link RadarEntry.timeline} - * - * @public - */ -export enum MovedState { - /** - * Moved down - */ - Down = -1, - /** - * Didn't move - */ - NoChange = 0, - /** - * Move up - */ - Up = 1, -} - -/* - * Types related to data collection for the Radar. - */ - -/** - * Response from {@link TechRadarApi} - * - * @public - */ -export interface TechRadarLoaderResponse { - /** - * Quadrant of Tech Radar. Should be 4 - */ - quadrants: RadarQuadrant[]; - /** - * Rings of Tech Radar - */ - rings: RadarRing[]; - /** - * Entries visualised in Tech Radar - */ - entries: RadarEntry[]; -} - -/* - * Set up the Radar as a Backstage component. - */ diff --git a/plugins/tech-radar/src/components/Radar/Radar.test.tsx b/plugins/tech-radar/src/components/Radar/Radar.test.tsx deleted file mode 100644 index b76eb20a16..0000000000 --- a/plugins/tech-radar/src/components/Radar/Radar.test.tsx +++ /dev/null @@ -1,57 +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 { renderInTestApp } from '@backstage/test-utils'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import Radar, { Props } from './Radar'; - -const minProps: Props = { - width: 500, - height: 200, - quadrants: [{ id: 'languages', name: 'Languages' }], - rings: [{ id: 'use', name: 'USE', color: '#93c47d' }], - entries: [ - { - id: 'typescript', - title: 'TypeScript', - quadrant: { id: 'languages', name: 'Languages' }, - moved: 0, - ring: { id: 'use', name: 'USE', color: '#93c47d' }, - url: '#', - }, - ], -}; - -describe('Radar', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render', async () => { - const rendered = await renderInTestApp(); - - const svg = rendered.container.querySelector('svg'); - expect(svg).not.toBeNull(); - expect(svg!.getAttribute('width')).toEqual('500'); - expect(svg!.getAttribute('height')).toEqual('200'); - }); -}); diff --git a/plugins/tech-radar/src/components/Radar/Radar.tsx b/plugins/tech-radar/src/components/Radar/Radar.tsx deleted file mode 100644 index 55b8a01784..0000000000 --- a/plugins/tech-radar/src/components/Radar/Radar.tsx +++ /dev/null @@ -1,86 +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, { useMemo, useRef, useState } from 'react'; -import type { Entry, Quadrant, Ring } from '../../utils/types'; -import RadarPlot from '../RadarPlot'; -import { adjustEntries, adjustQuadrants, adjustRings } from './utils'; - -export type Props = { - width: number; - height: number; - quadrants: Quadrant[]; - rings: Ring[]; - entries: Entry[]; - svgProps?: object; -}; - -const Radar = ({ - width, - height, - quadrants, - rings, - entries, - ...props -}: Props): JSX.Element => { - // Radius with optional buffer for the footer if rings have descriptions - const radius = - Math.min(width, height) / 2 - - (rings.some(ring => ring.description) ? 16 : 0); - - // State - const [activeEntry, setActiveEntry] = useState(); - const node = useRef(null); - - // Adjusted props - const adjustedQuadrants = useMemo( - () => adjustQuadrants(quadrants, radius, width, height), - [quadrants, radius, width, height], - ); - const adjustedRings = useMemo( - () => adjustRings(rings, radius), - [radius, rings], - ); - const adjustedEntries = useMemo( - () => - adjustEntries( - entries, - adjustedQuadrants, - adjustedRings, - radius, - activeEntry, - ), - [entries, adjustedQuadrants, adjustedRings, radius, activeEntry], - ); - - return ( - - setActiveEntry(entry)} - onEntryMouseLeave={() => setActiveEntry(undefined)} - /> - - ); -}; - -export default Radar; diff --git a/plugins/tech-radar/src/components/Radar/index.ts b/plugins/tech-radar/src/components/Radar/index.ts deleted file mode 100644 index df08587f08..0000000000 --- a/plugins/tech-radar/src/components/Radar/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './Radar'; diff --git a/plugins/tech-radar/src/components/Radar/utils.ts b/plugins/tech-radar/src/components/Radar/utils.ts deleted file mode 100644 index 5c32207268..0000000000 --- a/plugins/tech-radar/src/components/Radar/utils.ts +++ /dev/null @@ -1,181 +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 color from 'color'; -import { forceCollide, forceSimulation } from 'd3-force'; -import Segment from '../../utils/segment'; -import type { Entry, Quadrant, Ring } from '../../utils/types'; - -export const adjustQuadrants = ( - quadrants: Quadrant[], - radius: number, - width: number, - height: number, -) => { - /* - 0 1 2 3 ← x stops index - │ │ │ │ ↓ y stops index - ┼───────────┼─────────────────────────────┼───────────┼─0 - │ │ . -- ~~~ -- . │ │ - │ │ .-~ ~-. │ │ - │ │ / \ │ │ - │ │ / \ │ │ - ┼───────────┼─────────────────────────────┼───────────┼─1 - ┼───────────┼─────────────────────────────┼───────────┼─2 - │ │ | | │ │ - │ │ \ / │ │ - │ │ \ / │ │ - │ │ `-. .-' │ │ - │ │ ~- . ___ . -~ │ │ - ┼───────────┼─────────────────────────────┼───────────┼─3 - */ - - const margin = 16; - const xStops = [ - margin, - width / 2 - radius - margin, - width / 2 + radius + margin, - width - margin, - ]; - const yStops = [margin, height / 2 - margin, height / 2, height - margin]; - - // The quadrant parameters correspond to Q[0..3] above. They are in this order because of the - // original Zalando code; maybe we should refactor them to be in reverse order? - const legendParams = [ - { - x: xStops[2], - y: yStops[2], - width: xStops[3] - xStops[2], - height: yStops[3] - yStops[2], - }, - { - x: xStops[0], - y: yStops[2], - width: xStops[1] - xStops[0], - height: yStops[3] - yStops[2], - }, - { - x: xStops[0], - y: yStops[0], - width: xStops[1] - xStops[0], - height: yStops[1] - yStops[0], - }, - { - x: xStops[2], - y: yStops[0], - width: xStops[3] - xStops[2], - height: yStops[1] - yStops[0], - }, - ]; - - return quadrants.map((quadrant, index) => { - const legendParam = legendParams[index % 4]; - - return { - ...quadrant, - index, - radialMin: (index * Math.PI) / 2, - radialMax: ((index + 1) * Math.PI) / 2, - offsetX: index % 4 === 0 || index % 4 === 3 ? 1 : -1, - offsetY: index % 4 === 0 || index % 4 === 1 ? 1 : -1, - legendX: legendParam.x, - legendY: legendParam.y, - legendWidth: legendParam.width, - legendHeight: legendParam.height, - }; - }); -}; - -export const adjustEntries = ( - entries: Entry[], - quadrants: Quadrant[], - rings: Ring[], - radius: number, - activeEntry?: Entry, -): Entry[] => { - let seed = 42; - const adjustedEntries = entries.map((entry, index) => { - const quadrant = quadrants.find(q => { - const match = - typeof entry.quadrant === 'object' ? entry.quadrant.id : entry.quadrant; - return q.id === match; - }); - const ring = rings.find(r => { - const match = typeof entry.ring === 'object' ? entry.ring.id : entry.ring; - return r.id === match; - }); - - if (!quadrant) { - throw new Error( - `Unknown quadrant ${entry.quadrant} for entry ${entry.id}!`, - ); - } - if (!ring) { - throw new Error(`Unknown ring ${entry.ring} for entry ${entry.id}!`); - } - const segment = new Segment(quadrant, ring, radius, () => seed++); - const point = segment?.random(); - - return { - ...entry, - index: index, - quadrant: quadrant, - ring: ring, - segment, - x: point.x, - y: point.y, - color: - activeEntry && entry.id === activeEntry?.id - ? entry.ring.color - : color(entry.ring.color).desaturate(0.5).lighten(0.1).string(), - active: activeEntry && entry.id === activeEntry?.id ? true : false, - }; - }); - - const simulation = forceSimulation() - .nodes(adjustedEntries) - .velocityDecay(0.19) - .force('collision', forceCollide().radius(12).strength(0.85)) - .stop(); - - for ( - let i = 0, - n = Math.ceil( - Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay()), - ); - i < n; - ++i - ) { - simulation.tick(); - - for (const entry of adjustedEntries) { - if (entry.segment) { - entry.x = entry.segment.clipx(entry); - entry.y = entry.segment.clipy(entry); - } - } - } - - return adjustedEntries; -}; - -export const adjustRings = (rings: Ring[], radius: number) => - rings.map((ring, index) => ({ - ...ring, - index, - outerRadius: ((index + 2) / (rings.length + 1)) * radius, - innerRadius: ((index === 0 ? 0 : index + 1) / (rings.length + 1)) * radius, - })); diff --git a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.test.tsx b/plugins/tech-radar/src/components/RadarBubble/RadarBubble.test.tsx deleted file mode 100644 index ab8070c146..0000000000 --- a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.test.tsx +++ /dev/null @@ -1,48 +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 { renderInTestApp } from '@backstage/test-utils'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import RadarBubble, { Props } from './RadarBubble'; - -const minProps: Props = { - visible: true, - text: 'RadarBubble', - x: 2, - y: 2, -}; - -describe('RadarBubble', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText(minProps.text)).toBeInTheDocument(); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx b/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx deleted file mode 100644 index a904b981ca..0000000000 --- a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx +++ /dev/null @@ -1,116 +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, { useRef, useLayoutEffect } from 'react'; -import { makeStyles } from '@material-ui/core'; - -export type Props = { - visible: boolean; - text: string; - x: number; - y: number; -}; - -const useStyles = makeStyles(theme => ({ - bubble: { - pointerEvents: 'none', - userSelect: 'none', - opacity: 0, - }, - visibleBubble: { - pointerEvents: 'none', - userSelect: 'none', - opacity: 0.8, - }, - background: { - fill: '#333', - }, - text: { - pointerEvents: 'none', - userSelect: 'none', - fontSize: '10px', - fill: theme.palette.common.white, - }, -})); - -const RadarBubble = (props: Props): JSX.Element => { - const classes = useStyles(props); - const { visible, text } = props; - - const textElem = useRef(null); - const svgElem = useRef(null); - const rectElem = useRef(null); - const pathElem = useRef(null); - - const updatePosition = () => { - if (textElem.current) { - const { x, y } = props; - const bbox = textElem.current.getBBox(); - const marginX = 5; - const marginY = 4; - - if (svgElem.current) { - svgElem.current.setAttribute( - 'transform', - `translate(${x - bbox.width / 2}, ${y - bbox.height - marginY})`, - ); - } - - if (rectElem.current) { - rectElem.current.setAttribute('x', String(-marginX)); - rectElem.current.setAttribute('y', String(-bbox.height)); - rectElem.current.setAttribute( - 'width', - String(bbox.width + 2 * marginX), - ); - rectElem.current.setAttribute('height', String(bbox.height + marginY)); - } - - if (pathElem.current) { - pathElem.current.setAttribute( - 'transform', - `translate(${bbox.width / 2 - marginX}, ${marginY - 1})`, - ); - } - } - }; - - useLayoutEffect(() => { - updatePosition(); - }); - - return ( - - - - {text} - - - - ); -}; - -export default RadarBubble; diff --git a/plugins/tech-radar/src/components/RadarBubble/index.ts b/plugins/tech-radar/src/components/RadarBubble/index.ts deleted file mode 100644 index 5c6a519d5e..0000000000 --- a/plugins/tech-radar/src/components/RadarBubble/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './RadarBubble'; diff --git a/plugins/tech-radar/src/components/RadarComponent.test.tsx b/plugins/tech-radar/src/components/RadarComponent.test.tsx deleted file mode 100644 index 4bb207a1de..0000000000 --- a/plugins/tech-radar/src/components/RadarComponent.test.tsx +++ /dev/null @@ -1,95 +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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; - -import GetBBoxPolyfill from '../utils/polyfills/getBBox'; -import { RadarComponent } from './RadarComponent'; -import { TechRadarLoaderResponse, techRadarApiRef, TechRadarApi } from '../api'; - -import { errorApiRef } from '@backstage/core-plugin-api'; - -describe('RadarComponent', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - class MockClient implements TechRadarApi { - constructor(private delay = 0) {} - async load(): Promise { - await new Promise(resolve => setTimeout(resolve, this.delay)); - return { - entries: [], - quadrants: [], - rings: [], - }; - } - } - - it('should render a progress bar', async () => { - jest.useFakeTimers(); - - const { findByTestId } = await renderInTestApp( - - - , - ); - - jest.advanceTimersByTime(250); - await expect(findByTestId('progress')).resolves.toBeInTheDocument(); - - jest.advanceTimersByTime(250); - await expect(findByTestId('tech-radar-svg')).resolves.toBeInTheDocument(); - - jest.useRealTimers(); - }); - - it('should call the errorApi if load fails', async () => { - const errorApi = { post: jest.fn() }; - const mockClient = new MockClient(); - jest - .spyOn(mockClient, 'load') - .mockRejectedValue(new Error('404 Page Not Found')); - - const { queryByTestId } = await renderInTestApp( - - - , - ); - - expect(errorApi.post).toHaveBeenCalledTimes(1); - expect(errorApi.post).toHaveBeenCalledWith(new Error('404 Page Not Found')); - expect(queryByTestId('tech-radar-svg')).not.toBeInTheDocument(); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarComponent.tsx b/plugins/tech-radar/src/components/RadarComponent.tsx deleted file mode 100644 index 9437501405..0000000000 --- a/plugins/tech-radar/src/components/RadarComponent.tsx +++ /dev/null @@ -1,150 +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 { Progress } from '@backstage/core-components'; -import { errorApiRef, useApi } from '@backstage/core-plugin-api'; -import React, { useEffect } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { - type RadarEntry, - techRadarApiRef, - type TechRadarLoaderResponse, -} from '../api'; -import Radar from '../components/Radar'; -import type { Entry } from '../utils/types'; - -const useTechRadarLoader = (id: string | undefined) => { - const errorApi = useApi(errorApiRef); - const techRadarApi = useApi(techRadarApiRef); - - const { error, value, loading } = useAsync( - async () => techRadarApi.load(id), - [techRadarApi, id], - ); - - useEffect(() => { - if (error) { - errorApi.post(error); - } - }, [error, errorApi]); - - return { loading, value, error }; -}; - -function matchFilter(filter?: string): (entry: RadarEntry) => boolean { - const terms = filter - ?.toLocaleLowerCase('en-US') - .split(/\s/) - .map(e => e.trim()) - .filter(Boolean); - - if (!terms?.length) { - return () => true; - } - - return entry => { - const text = `${entry.title} ${ - entry.timeline[0]?.description || '' - }`.toLocaleLowerCase('en-US'); - return terms.every(term => text.includes(term)); - }; -} - -/** - * Properties of {@link TechRadarComponent} - * - * @public - */ -export interface TechRadarComponentProps { - /** - * ID of this Tech Radar - * - * @remarks - * - * Used when there are multiple Tech Radars and passed to {@link TechRadarApi.load} - */ - id?: string; - /** - * Width of Tech Radar - */ - width: number; - /** - * Height of Tech Radar - */ - height: number; - /** - * Custom React props to the `` element created for Tech Radar - */ - svgProps?: object; - /** - * Text to filter {@link RadarEntry} inside Tech Radar - */ - searchText?: string; -} - -/** - * Main React component of Tech Radar - * - * @remarks - * - * For advanced use cases. Typically, you want to use {@link TechRadarPage} - * - * @public - */ -export function RadarComponent(props: TechRadarComponentProps) { - const { loading, error, value: data } = useTechRadarLoader(props.id); - - const mapToEntries = ( - loaderResponse: TechRadarLoaderResponse, - ): Array => { - return loaderResponse.entries - .filter(matchFilter(props.searchText)) - .map(entry => ({ - id: entry.key, - quadrant: loaderResponse.quadrants.find(q => q.id === entry.quadrant)!, - title: entry.title, - ring: loaderResponse.rings.find( - r => r.id === entry.timeline[0].ringId, - )!, - timeline: entry.timeline.map(e => { - return { - date: e.date, - ring: loaderResponse.rings.find(a => a.id === e.ringId)!, - description: e.description, - moved: e.moved, - }; - }), - moved: entry.timeline[0].moved, - description: entry.description || entry.timeline[0].description, - url: entry.url, - links: entry.links, - })); - }; - - return ( - <> - {loading && } - {!loading && !error && data && ( - - )} - - ); -} diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx deleted file mode 100644 index dd6cd66f87..0000000000 --- a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.test.tsx +++ /dev/null @@ -1,51 +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 { screen } from '@testing-library/react'; - -import { Props, RadarDescription } from './RadarDescription'; -import { renderInTestApp } from '@backstage/test-utils'; -import { Ring } from '../../utils/types'; - -const ring: Ring = { - id: 'example-ring', - name: 'example-ring', - color: 'red', -}; - -const minProps: Props = { - open: true, - title: 'example-title', - description: 'example-description', - timeline: [ - { date: new Date(), ring: ring, description: 'test timeline 1' }, - { date: new Date(), ring: ring, description: 'test timeline 2' }, - ], - links: [{ url: 'https://example.com/docs', title: 'example-link' }], - onClose: () => {}, -}; - -describe('RadarDescription', () => { - it('should render', async () => { - await renderInTestApp(); - - const radarDescription = screen.getByTestId('radar-description'); - expect(radarDescription).toBeInTheDocument(); - expect(screen.getByText(String(minProps.description))).toBeInTheDocument(); - expect(screen.getByText(String('example-link'))).toBeInTheDocument(); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx b/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx deleted file mode 100644 index 7e2dabc3d4..0000000000 --- a/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx +++ /dev/null @@ -1,94 +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 Dialog from '@material-ui/core/Dialog'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import { Button, DialogActions, DialogContent } from '@material-ui/core'; -import LinkIcon from '@material-ui/icons/Link'; -import { Link, MarkdownContent } from '@backstage/core-components'; -import { isValidUrl } from '../../utils/components'; -import type { EntrySnapshot } from '../../utils/types'; -import { RadarTimeline } from '../RadarTimeline'; - -export type Props = { - open: boolean; - onClose: () => void; - title: string; - description: string; - timeline?: EntrySnapshot[]; - url?: string; - links?: Array<{ url: string; title: string }>; -}; - -const RadarDescription = (props: Props): JSX.Element => { - function showDialogActions( - url: string | undefined, - links: Array<{ url: string; title: string }> | undefined, - ): Boolean { - return isValidUrl(url) || Boolean(links && links.length > 0); - } - - const { open, onClose, title, description, timeline, url, links } = props; - - return ( - - - {title} - - - - - - {showDialogActions(url, links) && ( - - {links?.map(link => ( - } - key={link.url} - > - {link.title} - - ))} - {isValidUrl(url) && ( - } - key={url} - > - LEARN MORE - - )} - - )} - - ); -}; - -export { RadarDescription }; diff --git a/plugins/tech-radar/src/components/RadarDescription/index.ts b/plugins/tech-radar/src/components/RadarDescription/index.ts deleted file mode 100644 index 493083d25f..0000000000 --- a/plugins/tech-radar/src/components/RadarDescription/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { RadarDescription } from './RadarDescription'; -export type { Props } from './RadarDescription'; diff --git a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx deleted file mode 100644 index 2935b29534..0000000000 --- a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.test.tsx +++ /dev/null @@ -1,108 +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 { screen, within } from '@testing-library/react'; -import { renderInTestApp } from '@backstage/test-utils'; -import userEvent from '@testing-library/user-event'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import RadarEntry, { Props } from './RadarEntry'; - -const minProps: Props = { - x: 2, - y: 2, - value: 2, - color: 'red', - entryId: 'Typescript', -}; - -const optionalProps: Props = { - ...minProps, - title: 'example-title', - description: 'example-description', -}; - -describe('RadarEntry', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render link only', async () => { - await renderInTestApp( - - - , - ); - - const radarEntry = screen.getByTestId('radar-entry'); - const { x, y } = minProps; - expect(radarEntry).toBeInTheDocument(); - expect(radarEntry.getAttribute('transform')).toBe(`translate(${x}, ${y})`); - expect(screen.getByText(String(minProps.value))).toBeInTheDocument(); - expect( - within(radarEntry) - .getByText(String(minProps.value)) - .getAttribute('aria-labelledby'), - ).toBe(minProps.entryId); - }); - - it('should render with description', async () => { - await renderInTestApp( - - - , - ); - - await userEvent.click(screen.getByRole('button')); - - const radarEntry = screen.getByTestId('radar-entry'); - expect(radarEntry).toBeInTheDocument(); - - const radarDescription = screen.getByTestId('radar-description'); - expect(radarDescription).toBeInTheDocument(); - expect(screen.getByText(String(minProps.value))).toBeInTheDocument(); - expect( - within(radarEntry) - .getByText(String(minProps.value)) - .getAttribute('aria-labelledby'), - ).toBe(minProps.entryId); - }); - - it('should render blip with url equal to # if description present', async () => { - const withUrl = { - ...optionalProps, - url: 'http://backstage.io', - }; - await renderInTestApp( - - - , - ); - - expect(screen.getByRole('button')).toHaveAttribute('href', '#'); - const radarEntry = screen.getByTestId('radar-entry'); - expect( - within(radarEntry) - .getByText(String(minProps.value)) - .getAttribute('aria-labelledby'), - ).toBe(minProps.entryId); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx b/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx deleted file mode 100644 index 996b8d1040..0000000000 --- a/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx +++ /dev/null @@ -1,147 +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'; -import { WithLink } from '../../utils/components'; -import { RadarDescription } from '../RadarDescription'; -import type { EntrySnapshot } from '../../utils/types'; - -export type Props = { - x: number; - y: number; - entryId: string; - value: number; - color: string; - url?: string; - links?: Array<{ title: string; url: string }>; - moved?: number; - description?: string; - timeline?: EntrySnapshot[]; - title?: string; - onMouseEnter?: (event: React.MouseEvent) => void; - onMouseLeave?: (event: React.MouseEvent) => void; - onClick?: (event: React.MouseEvent) => void; -}; - -const useStyles = makeStyles(theme => ({ - text: { - pointerEvents: 'none', - userSelect: 'none', - fontSize: '9px', - fill: theme.palette.common.white, - textAnchor: 'middle', - }, - - link: { - cursor: 'pointer', - }, -})); - -const makeBlip = (color: string, moved?: number) => { - const style = { fill: color }; - - let blip = ; - if (moved && moved > 0) { - blip = ; // triangle pointing up - } else if (moved && moved < 0) { - blip = ; // triangle pointing down - } - - return blip; -}; - -const RadarEntry = (props: Props): JSX.Element => { - const classes = useStyles(props); - const [open, setOpen] = React.useState(false); - - const { - moved, - description, - timeline, - title, - color, - url, - links, - value, - entryId, - x, - y, - onMouseEnter, - onMouseLeave, - onClick, - } = props; - - const blip = makeBlip(color, moved); - - const handleClickOpen = () => { - setOpen(true); - }; - - const handleClose = () => { - setOpen(false); - }; - - const toggle = () => { - setOpen(!open); - }; - - return ( - - {' '} - {open && ( - - )} - {description ? ( - // eslint-disable-next-line jsx-a11y/anchor-is-valid - - {blip} - - ) : ( - - {blip} - - )} - - {value} - - - ); -}; - -export default RadarEntry; diff --git a/plugins/tech-radar/src/components/RadarEntry/index.ts b/plugins/tech-radar/src/components/RadarEntry/index.ts deleted file mode 100644 index fe21171c71..0000000000 --- a/plugins/tech-radar/src/components/RadarEntry/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './RadarEntry'; diff --git a/plugins/tech-radar/src/components/RadarFooter/RadarFooter.test.tsx b/plugins/tech-radar/src/components/RadarFooter/RadarFooter.test.tsx deleted file mode 100644 index df56e2ad2c..0000000000 --- a/plugins/tech-radar/src/components/RadarFooter/RadarFooter.test.tsx +++ /dev/null @@ -1,48 +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 { renderInTestApp } from '@backstage/test-utils'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import RadarFooter, { Props } from './RadarFooter'; - -const minProps: Props = { - x: 2, - y: 2, -}; - -describe('RadarFooter', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - const radarFooter = rendered.getByTestId('radar-footer'); - const { x, y } = minProps; - expect(radarFooter).toBeInTheDocument(); - expect(radarFooter.getAttribute('transform')).toBe(`translate(${x}, ${y})`); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarFooter/RadarFooter.tsx b/plugins/tech-radar/src/components/RadarFooter/RadarFooter.tsx deleted file mode 100644 index e20c07bb00..0000000000 --- a/plugins/tech-radar/src/components/RadarFooter/RadarFooter.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 { makeStyles } from '@material-ui/core'; - -export type Props = { - x: number; - y: number; - spaces?: number; - labels?: Array; -}; - -const onespace = '\u00a0'; - -const useStyles = makeStyles(theme => ({ - text: { - pointerEvents: 'none', - userSelect: 'none', - fontSize: '10px', - fill: theme.palette.text.secondary, - }, -})); - -const RadarFooter = (props: Props): JSX.Element => { - const { x, y, spaces = 5, labels } = props; - const classes = useStyles(props); - const space = onespace.repeat(spaces); - - return ( - - {`▲ moved up${space}▼ moved down`} - {labels && space} - {labels?.join(space)} - - ); -}; - -export default RadarFooter; diff --git a/plugins/tech-radar/src/components/RadarFooter/index.ts b/plugins/tech-radar/src/components/RadarFooter/index.ts deleted file mode 100644 index 2738fdc029..0000000000 --- a/plugins/tech-radar/src/components/RadarFooter/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './RadarFooter'; diff --git a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.test.tsx b/plugins/tech-radar/src/components/RadarGrid/RadarGrid.test.tsx deleted file mode 100644 index e8896ec9e0..0000000000 --- a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.test.tsx +++ /dev/null @@ -1,59 +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 { renderInTestApp } from '@backstage/test-utils'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import RadarGrid, { Props } from './RadarGrid'; - -const minProps: Props = { - radius: 5, - rings: [{ id: 'use', name: 'USE', color: '#93c47d' }], -}; - -describe('RadarGrid', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByTestId('radar-grid-x-line')).toBeInTheDocument(); - expect(rendered.getByTestId('radar-grid-y-line')).toBeInTheDocument(); - }); - - it('should have the correct text color', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByTestId('radar-ring-heading')).toHaveStyle({ - fill: '#93c47d', - }); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx b/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx deleted file mode 100644 index 8f4f8acc78..0000000000 --- a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx +++ /dev/null @@ -1,106 +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'; -import type { Ring } from '../../utils/types'; - -export type Props = { - radius: number; - rings: Ring[]; -}; - -const useStyles = makeStyles( - theme => ({ - ring: { - fill: 'none', - stroke: '#bbb', - strokeWidth: '1px', - }, - axis: { - fill: 'none', - stroke: '#bbb', - strokeWidth: '1px', - }, - text: { - pointerEvents: 'none', - userSelect: 'none', - fill: theme.palette.text.primary, - fontSize: '25px', - fontWeight: 800, - opacity: 0.7, - }, - }), - { name: 'PluginTechRadarGrid' }, -); - -// A component for the background grid of the radar, with axes, rings etc. It will render around the origin, i.e. -// assume that (0, 0) is in the middle of the drawing. -const RadarGrid = (props: Props) => { - const { radius, rings } = props; - const classes = useStyles(props); - - const makeRingNode = (ringIndex: number, ringRadius?: number) => [ - , - - {rings[ringIndex].name} - , - ]; - - const axisNodes = [ - // X axis - , - // Y axis - , - ]; - - const ringNodes = rings - .map(r => r.outerRadius) - .map((ringRadius, ringIndex) => makeRingNode(ringIndex, ringRadius)); - - return <>{axisNodes.concat(...ringNodes)}; -}; - -export default RadarGrid; diff --git a/plugins/tech-radar/src/components/RadarGrid/index.ts b/plugins/tech-radar/src/components/RadarGrid/index.ts deleted file mode 100644 index 07e809209e..0000000000 --- a/plugins/tech-radar/src/components/RadarGrid/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './RadarGrid'; diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.test.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.test.tsx deleted file mode 100644 index 70cd2d0244..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.test.tsx +++ /dev/null @@ -1,74 +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 { renderInTestApp } from '@backstage/test-utils'; -import React from 'react'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import RadarLegend from './RadarLegend'; -import { RadarLegendProps } from './types'; - -const minProps: RadarLegendProps = { - quadrants: [{ id: 'languages', name: 'Languages' }], - rings: [{ id: 'use', name: 'USE', color: '#93c47d' }], - entries: [ - { - id: 'typescript', - title: 'TypeScript', - quadrant: { id: 'languages', name: 'Languages' }, - moved: 0, - ring: { id: 'use', name: 'USE', color: '#93c47d' }, - url: '#', - }, - ], -}; - -describe('RadarLegend', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByTestId('radar-legend')).toBeInTheDocument(); - expect(rendered.getAllByTestId('radar-quadrant')).toHaveLength(1); - expect(rendered.getAllByTestId('radar-ring')).toHaveLength(1); - }); - - it('should have the correct ring text color', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByTestId('radar-legend')).toBeInTheDocument(); - - const legend = rendered.getByTestId('radar-legend-heading'); - expect(legend).toHaveStyle({ - color: '#93c47d', - }); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx deleted file mode 100644 index 0a7a69b73c..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 { makeStyles } from '@material-ui/core'; -import React from 'react'; -import { RadarLegendQuadrant } from './RadarLegendQuadrant'; -import { RadarLegendProps } from './types'; -import { setupSegments } from './utils'; - -const useStyles = makeStyles(theme => ({ - quadrant: { - height: '100%', - width: '100%', - overflowY: 'auto', - scrollbarWidth: 'thin', - }, - quadrantHeading: { - pointerEvents: 'none', - userSelect: 'none', - marginTop: 0, - marginBottom: theme.spacing(2), - fontSize: '18px', - }, - rings: { - columns: 3, - }, - ring: { - breakInside: 'avoid-column', - pageBreakInside: 'avoid', - '-webkit-column-break-inside': 'avoid', - fontSize: '12px', - marginBottom: theme.spacing(2), - }, - ringEmpty: { - color: theme.palette.text.secondary, - fontSize: '12px', - }, - ringHeading: { - pointerEvents: 'none', - userSelect: 'none', - marginTop: 0, - marginBottom: theme.spacing(1), - fontSize: '12px', - fontWeight: 800, - }, - ringList: { - listStylePosition: 'inside', - marginTop: 0, - paddingLeft: 0, - fontVariantNumeric: 'proportional-nums', - '-moz-font-feature-settings': 'pnum', - '-webkit-font-feature-settings': 'pnum', - 'font-feature-settings': 'pnum', - }, - entry: { - pointerEvents: 'visiblePainted', - userSelect: 'none', - fontSize: '11px', - }, - activeEntry: { - pointerEvents: 'visiblePainted', - userSelect: 'none', - fontSize: '11px', - background: '#6f6f6f', - color: theme.palette.common.white, - }, - entryLink: { - pointerEvents: 'visiblePainted', - cursor: 'pointer', - }, -})); - -const RadarLegend = ({ - quadrants, - rings, - entries, - onEntryMouseEnter, - onEntryMouseLeave, - ...props -}: RadarLegendProps): JSX.Element => { - const classes = useStyles(props); - - return ( - - {quadrants.map(quadrant => ( - - ))} - - ); -}; - -export default RadarLegend; diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx deleted file mode 100644 index 11443769f2..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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 { ClassNameMap } from '@material-ui/core/styles/withStyles'; -import Typography from '@material-ui/core/Typography'; -import React from 'react'; -import { WithLink } from '../../utils/components'; -import { RadarDescription } from '../RadarDescription'; -import type { EntrySnapshot } from '../../utils/types'; - -type RadarLegendLinkProps = { - entryId: string; - url?: string; - description?: string; - title?: string; - classes: ClassNameMap; - active?: boolean; - links: Array<{ url: string; title: string }>; - timeline: EntrySnapshot[]; -}; - -export const RadarLegendLink = ({ - entryId, - url, - description, - title, - classes, - active, - links, - timeline, -}: RadarLegendLinkProps) => { - const [open, setOpen] = React.useState(false); - - const handleClickOpen = () => { - setOpen(true); - }; - - const handleClose = () => { - setOpen(false); - }; - - const toggle = () => { - setOpen(!open); - }; - - if (description) { - return ( - <> - - - {title} - - - {open && ( - - )} - - ); - } - return ( - - - {title} - - - ); -}; diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx deleted file mode 100644 index 60a5870348..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 { ClassNameMap } from '@material-ui/core/styles/withStyles'; -import React from 'react'; -import { Quadrant, Ring } from '../../utils/types'; -import { RadarLegendRing } from './RadarLegendRing'; -import { RadarLegendProps, Segments } from './types'; -import { getSegment } from './utils'; - -type RadarLegendQuadrantProps = { - segments: Segments; - quadrant: Quadrant; - rings: Ring[]; - classes: ClassNameMap; - onEntryMouseEnter: RadarLegendProps['onEntryMouseEnter']; - onEntryMouseLeave: RadarLegendProps['onEntryMouseLeave']; -}; - -export const RadarLegendQuadrant = ({ - segments, - quadrant, - rings, - classes, - onEntryMouseEnter, - onEntryMouseLeave, -}: RadarLegendQuadrantProps) => { - return ( - -
-

{quadrant.name}

-
- {rings.map(ring => ( - - ))} -
-
-
- ); -}; diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegendRing.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegendRing.tsx deleted file mode 100644 index 8942efa08e..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegendRing.tsx +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 { ClassNameMap } from '@material-ui/core/styles/withStyles'; -import Typography from '@material-ui/core/Typography/Typography'; -import React from 'react'; -import { Entry, Ring } from '../../utils/types'; -import { RadarLegendLink } from './RadarLegendLink'; -import { RadarLegendProps } from './types'; - -type RadarLegendRingProps = { - ring: Ring; - entries: Entry[]; - classes: ClassNameMap; - onEntryMouseEnter?: RadarLegendProps['onEntryMouseEnter']; - onEntryMouseLeave?: RadarLegendProps['onEntryMouseEnter']; -}; - -export const RadarLegendRing = ({ - ring, - entries, - classes, - onEntryMouseEnter, - onEntryMouseLeave, -}: RadarLegendRingProps) => { - return ( -
-

- {ring.name} -

- {entries.length === 0 ? ( - - (empty) - - ) : ( -
    - {entries.map(entry => ( -
  1. onEntryMouseEnter(entry)) - } - onMouseLeave={ - onEntryMouseLeave && (() => onEntryMouseLeave(entry)) - } - > - -
  2. - ))} -
- )} -
- ); -}; diff --git a/plugins/tech-radar/src/components/RadarLegend/index.ts b/plugins/tech-radar/src/components/RadarLegend/index.ts deleted file mode 100644 index 317121a5c6..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './RadarLegend'; diff --git a/plugins/tech-radar/src/components/RadarLegend/types.ts b/plugins/tech-radar/src/components/RadarLegend/types.ts deleted file mode 100644 index cdac1bfe9d..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/types.ts +++ /dev/null @@ -1,29 +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 { Entry, Quadrant, Ring } from '../../utils/types'; - -export type Segments = { - [k: number]: { [k: number]: Entry[] }; -}; - -export type RadarLegendProps = { - quadrants: Quadrant[]; - rings: Ring[]; - entries: Entry[]; - onEntryMouseEnter?: (entry: Entry) => void; - onEntryMouseLeave?: (entry: Entry) => void; -}; diff --git a/plugins/tech-radar/src/components/RadarLegend/utils.ts b/plugins/tech-radar/src/components/RadarLegend/utils.ts deleted file mode 100644 index 0c2d7eb8f0..0000000000 --- a/plugins/tech-radar/src/components/RadarLegend/utils.ts +++ /dev/null @@ -1,63 +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 { Entry, Quadrant, Ring } from '../../utils/types'; -import { Segments } from './types'; - -export const setupSegments = (entries: Entry[]) => { - const segments: Segments = {}; - - for (const entry of entries) { - const quadrantIndex = entry.quadrant.index; - const ringIndex = entry.ring.index; - let quadrantData: { [k: number]: Entry[] } = {}; - if (quadrantIndex !== undefined) { - if (segments[quadrantIndex] === undefined) { - segments[quadrantIndex] = {}; - } - - quadrantData = segments[quadrantIndex]; - } - - let ringData = []; - if (ringIndex !== undefined) { - if (quadrantData[ringIndex] === undefined) { - quadrantData[ringIndex] = []; - } - - ringData = quadrantData[ringIndex]; - } - - ringData.push(entry); - } - - return segments; -}; - -export const getSegment = ( - segmented: Segments, - quadrant: Quadrant, - ring: Ring, - ringOffset = 0, -) => { - const quadrantIndex = quadrant.index; - const ringIndex = ring.index; - const segmentedData = - quadrantIndex === undefined ? {} : segmented[quadrantIndex] || {}; - return ringIndex === undefined - ? [] - : segmentedData[ringIndex + ringOffset] || []; -}; diff --git a/plugins/tech-radar/src/components/RadarPage.test.tsx b/plugins/tech-radar/src/components/RadarPage.test.tsx deleted file mode 100644 index 20ef707b8e..0000000000 --- a/plugins/tech-radar/src/components/RadarPage.test.tsx +++ /dev/null @@ -1,158 +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 { - MockErrorApi, - TestApiProvider, - renderInTestApp, -} from '@backstage/test-utils'; -import { act, screen, waitFor } from '@testing-library/react'; -import React from 'react'; -import GetBBoxPolyfill from '../utils/polyfills/getBBox'; -import { RadarPage } from './RadarPage'; -import { TechRadarLoaderResponse, techRadarApiRef, TechRadarApi } from '../api'; - -import { errorApiRef } from '@backstage/core-plugin-api'; - -describe('RadarPage', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - class MockClient implements TechRadarApi { - async load(): Promise { - return { - entries: [], - quadrants: [], - rings: [], - }; - } - } - - const mockClient = new MockClient(); - - it('should render a progress bar', async () => { - class SlowClient implements TechRadarApi { - async load(): Promise { - await new Promise(resolve => setTimeout(resolve, 1000)); - return { - entries: [], - quadrants: [], - rings: [], - }; - } - } - - const techRadarProps = { - width: 1200, - height: 800, - svgProps: { 'data-testid': 'tech-radar-svg' }, - }; - - await renderInTestApp( - - - , - ); - - await act(async () => { - await new Promise(resolve => setTimeout(resolve, 300)); - }); - - expect(screen.getByTestId('progress')).toBeInTheDocument(); - - await screen.findByTestId('tech-radar-svg'); - }); - - it('should render a header with a svg', async () => { - const techRadarProps = { - width: 1200, - height: 800, - svgProps: { 'data-testid': 'tech-radar-svg' }, - }; - jest.spyOn(mockClient, 'load'); - - await renderInTestApp( - - - , - ); - - await expect( - screen.findByTestId('tech-radar-svg'), - ).resolves.toBeInTheDocument(); - expect( - screen.getByText('Pick the recommended technologies for your projects'), - ).toBeInTheDocument(); - expect(mockClient.load).toHaveBeenCalledWith(undefined); - }); - - it('should call load with id', async () => { - const techRadarProps = { - width: 1200, - height: 800, - svgProps: { 'data-testid': 'tech-radar-svg' }, - id: 'myId', - }; - jest.spyOn(mockClient, 'load'); - - await renderInTestApp( - - - , - ); - - await expect( - screen.findByTestId('tech-radar-svg'), - ).resolves.toBeInTheDocument(); - expect(mockClient.load).toHaveBeenCalledWith('myId'); - }); - - it('should call the errorApi if load fails', async () => { - const errorApi = new MockErrorApi({ collect: true }); - - jest - .spyOn(mockClient, 'load') - .mockRejectedValue(new Error('404 Page Not Found')); - - const techRadarProps = { - width: 1200, - height: 800, - svgProps: { 'data-testid': 'tech-radar-svg' }, - }; - - const { queryByTestId } = await renderInTestApp( - - - , - ); - - await waitFor(() => !queryByTestId('progress')); - - expect(errorApi.getErrors()).toEqual([ - { error: new Error('404 Page Not Found'), context: undefined }, - ]); - expect(queryByTestId('tech-radar-svg')).not.toBeInTheDocument(); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarPage.tsx b/plugins/tech-radar/src/components/RadarPage.tsx deleted file mode 100644 index a7ea538977..0000000000 --- a/plugins/tech-radar/src/components/RadarPage.tsx +++ /dev/null @@ -1,103 +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 { - Content, - ContentHeader, - Header, - Page, - SupportButton, - Link, -} from '@backstage/core-components'; -import { Grid, Input, makeStyles } from '@material-ui/core'; -import Typography from '@material-ui/core/Typography'; -import React from 'react'; -import { RadarComponent, type TechRadarComponentProps } from './RadarComponent'; - -const useStyles = makeStyles(() => ({ - overflowXScroll: { - overflowX: 'scroll', - }, -})); - -/** - * Properties for {@link TechRadarPage} - * - * @public - */ -export interface TechRadarPageProps extends TechRadarComponentProps { - /** - * Title - */ - title?: string; - /** - * Subtitle - */ - subtitle?: string; - /** - * Page Title - */ - pageTitle?: string; -} - -/** - * Main Page of Tech Radar - * - * @public - */ -export function RadarPage(props: TechRadarPageProps) { - const { - title = 'Tech Radar', - subtitle = 'Pick the recommended technologies for your projects', - pageTitle = 'Company Radar', - ...componentProps - } = props; - const classes = useStyles(); - const [searchText, setSearchText] = React.useState(''); - - return ( - -
- - - setSearchText(e.target.value)} - /> - - - This is used for visualizing the official guidelines of different - areas of software development such as languages, frameworks, - infrastructure and processes. You can find an explanation for the - radar at{' '} - - Zalando Tech Radar - - . - - - - - - - - - - - ); -} diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.test.tsx b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.test.tsx deleted file mode 100644 index 7557755ed2..0000000000 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.test.tsx +++ /dev/null @@ -1,63 +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 { renderInTestApp } from '@backstage/test-utils'; -import GetBBoxPolyfill from '../../utils/polyfills/getBBox'; - -import RadarPlot, { Props } from './RadarPlot'; - -const minProps: Props = { - width: 500, - height: 200, - radius: 50, - quadrants: [{ id: 'languages', name: 'Languages' }], - rings: [{ id: 'use', name: 'USE', color: '#93c47d' }], - entries: [ - { - id: 'typescript', - title: 'TypeScript', - quadrant: { id: 'languages', name: 'Languages' }, - moved: 0, - ring: { id: 'use', name: 'USE', color: '#93c47d' }, - url: '#', - }, - ], -}; - -describe('RadarPlot', () => { - beforeAll(() => { - GetBBoxPolyfill.create(0, 0, 1000, 500); - }); - - afterAll(() => { - GetBBoxPolyfill.remove(); - }); - - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByTestId('radar-plot')).toBeInTheDocument(); - expect(rendered.getByTestId('radar-legend')).toBeInTheDocument(); - expect(rendered.getByTestId('radar-footer')).toBeInTheDocument(); - expect(rendered.getByTestId('radar-bubble')).toBeInTheDocument(); - expect(rendered.getAllByTestId('radar-entry')).toHaveLength(1); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx deleted file mode 100644 index 56fd029eee..0000000000 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.tsx +++ /dev/null @@ -1,108 +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 type { Quadrant, Ring, Entry } from '../../utils/types'; - -import RadarGrid from '../RadarGrid'; -import RadarEntry from '../RadarEntry'; -import RadarBubble from '../RadarBubble'; -import RadarFooter from '../RadarFooter'; -import RadarLegend from '../RadarLegend'; - -export type Props = { - width: number; - height: number; - radius: number; - rings: Ring[]; - quadrants: Quadrant[]; - entries: Entry[]; - activeEntry?: Entry; - onEntryMouseEnter?: (entry: Entry) => void; - onEntryMouseLeave?: (entry: Entry) => void; -}; - -// A component that draws the radar circle. -const RadarPlot = (props: Props): JSX.Element => { - const { - width, - height, - radius, - quadrants, - rings, - entries, - activeEntry, - onEntryMouseEnter, - onEntryMouseLeave, - } = props; - - return ( - - onEntryMouseEnter(entry)) - } - onEntryMouseLeave={ - onEntryMouseLeave && (entry => onEntryMouseLeave(entry)) - } - /> - - - ring.description) ? 2 : undefined} - labels={ - rings - .map( - ring => ring.description && `${ring.name}: ${ring.description}`, - ) - .filter(e => e) as string[] - } - /> - {entries.map(entry => ( - onEntryMouseEnter(entry))} - onMouseLeave={onEntryMouseLeave && (() => onEntryMouseLeave(entry))} - /> - ))} - - - - ); -}; - -export default RadarPlot; diff --git a/plugins/tech-radar/src/components/RadarPlot/index.ts b/plugins/tech-radar/src/components/RadarPlot/index.ts deleted file mode 100644 index 5ee1b44c8f..0000000000 --- a/plugins/tech-radar/src/components/RadarPlot/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default } from './RadarPlot'; diff --git a/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.test.tsx b/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.test.tsx deleted file mode 100644 index e5142a7af2..0000000000 --- a/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.test.tsx +++ /dev/null @@ -1,43 +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 { screen } from '@testing-library/react'; - -import { Props, RadarTimeline } from './RadarTimeline'; -import { renderInTestApp } from '@backstage/test-utils'; -import { Ring } from '../../utils/types'; - -const ring: Ring = { - id: 'example-ring', - name: 'example-ring', - color: 'red', -}; - -const minProps: Props = { - timeline: [ - { date: new Date(), ring: ring, description: 'test timeline 1' }, - { date: new Date(), ring: ring, description: 'test timeline 2' }, - ], -}; - -describe('RadarDescription', () => { - it('should render', async () => { - await renderInTestApp(); - expect(screen.getByText(String('test timeline 1'))).toBeInTheDocument(); - expect(screen.getByText(String('test timeline 2'))).toBeInTheDocument(); - }); -}); diff --git a/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx b/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx deleted file mode 100644 index e54c4a499e..0000000000 --- a/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx +++ /dev/null @@ -1,99 +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 type { EntrySnapshot } from '../../utils/types'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableContainer from '@material-ui/core/TableContainer'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; - -import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward'; -import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward'; -import AdjustIcon from '@material-ui/icons/Adjust'; - -import { MovedState } from '../../api'; - -export type Props = { - timeline?: EntrySnapshot[]; -}; - -const RadarTimeline = (props: Props): JSX.Element => { - const { timeline } = props; - - return ( - <> - - History - - -
- - - Moved in direction - Moved to ring - Moved on date - Description - - - - {timeline?.length === 0 && ( - - - No Timeline - - - )} - {timeline?.map(timeEntry => ( - - - {timeEntry.moved === MovedState.Up ? : ''} - {timeEntry.moved === MovedState.Down ? ( - - ) : ( - '' - )} - {timeEntry.moved === MovedState.NoChange ? ( - - ) : ( - '' - )} - - - {timeEntry.ring.name ? timeEntry.ring.name : ''} - - - {timeEntry.date.toLocaleDateString() - ? timeEntry.date.toLocaleDateString() - : ''} - - - {timeEntry.description ? timeEntry.description : ''} - - - ))} - -
- - - ); -}; - -export { RadarTimeline }; diff --git a/plugins/tech-radar/src/components/RadarTimeline/index.ts b/plugins/tech-radar/src/components/RadarTimeline/index.ts deleted file mode 100644 index cdf156ce24..0000000000 --- a/plugins/tech-radar/src/components/RadarTimeline/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { RadarTimeline } from './RadarTimeline'; -export type { Props } from './RadarTimeline'; diff --git a/plugins/tech-radar/src/components/index.ts b/plugins/tech-radar/src/components/index.ts deleted file mode 100644 index a2a9f8271f..0000000000 --- a/plugins/tech-radar/src/components/index.ts +++ /dev/null @@ -1,19 +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. - */ - -export { RadarComponent as TechRadarComponent } from './RadarComponent'; -export type { TechRadarComponentProps } from './RadarComponent'; -export * from './RadarPage'; diff --git a/plugins/tech-radar/src/index.ts b/plugins/tech-radar/src/index.ts deleted file mode 100644 index 0ea02cabe5..0000000000 --- a/plugins/tech-radar/src/index.ts +++ /dev/null @@ -1,43 +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. - */ - -/** - * A Backstage plugin that lets you display a Tech Radar for your organization - * - * @packageDocumentation - */ - -import { RadarPage } from './components'; - -export { - techRadarPlugin, - techRadarPlugin as plugin, - TechRadarPage, -} from './plugin'; - -export * from './components'; - -/** - * @deprecated Use plugin extensions instead - * - * @public - */ -export const Router = RadarPage; - -/** - * The TypeScript API for configuring Tech Radar. - */ -export * from './api'; diff --git a/plugins/tech-radar/src/plugin.test.ts b/plugins/tech-radar/src/plugin.test.ts deleted file mode 100644 index da061bebe1..0000000000 --- a/plugins/tech-radar/src/plugin.test.ts +++ /dev/null @@ -1,23 +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 { techRadarPlugin } from './plugin'; - -describe('tech-radar', () => { - it('should export plugin', () => { - expect(techRadarPlugin).toBeDefined(); - }); -}); diff --git a/plugins/tech-radar/src/plugin.ts b/plugins/tech-radar/src/plugin.ts deleted file mode 100644 index 3a8e0a5f2d..0000000000 --- a/plugins/tech-radar/src/plugin.ts +++ /dev/null @@ -1,58 +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 { techRadarApiRef } from './api'; -import { SampleTechRadarApi } from './sample'; -import { - createPlugin, - createRouteRef, - createRoutableExtension, - createApiFactory, -} from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'tech-radar', -}); - -/** - * Tech Radar plugin instance - * - * @public - */ -export const techRadarPlugin = createPlugin({ - id: 'tech-radar', - routes: { - root: rootRouteRef, - }, - apis: [createApiFactory(techRadarApiRef, new SampleTechRadarApi())], -}); - -/** - * Main Tech Radar Page - * - * @remarks - * - * Uses {@link TechRadarPageProps} as props - * - * @public - */ -export const TechRadarPage = techRadarPlugin.provide( - createRoutableExtension({ - name: 'TechRadarPage', - component: () => import('./components/RadarPage').then(m => m.RadarPage), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/tech-radar/src/sample.ts b/plugins/tech-radar/src/sample.ts deleted file mode 100644 index 77a7101f64..0000000000 --- a/plugins/tech-radar/src/sample.ts +++ /dev/null @@ -1,230 +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 { - RadarRing, - RadarQuadrant, - RadarEntry, - TechRadarLoaderResponse, - TechRadarApi, -} from './api'; - -const rings = new Array(); -rings.push({ - id: 'adopt', - name: 'ADOPT', - color: '#5BA300', - description: - 'Commodi accusantium culpa sed itaque excepturi rem eum nulla possimus.', -}); -rings.push({ - id: 'trial', - name: 'TRIAL', - color: '#009EB0', - description: 'Recusandae possimus ipsum dolores.', -}); -rings.push({ - id: 'assess', - name: 'ASSESS', - color: '#C7BA00', - description: - 'In asperiores repellat error recusandae et adipisci laborum porro.', -}); -rings.push({ - id: 'hold', - name: 'HOLD', - color: '#E09B96', - description: 'Esse mollitia in.', -}); - -const quadrants = new Array(); -quadrants.push({ id: 'infrastructure', name: 'Infrastructure' }); -quadrants.push({ id: 'frameworks', name: 'Frameworks' }); -quadrants.push({ id: 'languages', name: 'Languages' }); -quadrants.push({ id: 'process', name: 'Process' }); - -const entries = new Array(); -entries.push({ - timeline: [ - { - moved: 0, - ringId: 'adopt', - date: new Date('2020-08-06'), - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua', - }, - ], - key: 'javascript', - id: 'javascript', - title: 'JavaScript', - quadrant: 'languages', - links: [ - { - url: 'https://www.javascript.com/', - title: 'Learn more', - }, - { - url: 'https://www.typescriptlang.org/', - title: 'TypeScript', - }, - ], - description: - 'Excepteur **sint** occaecat *cupidatat* non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n```ts\nconst x = "3";\n```\n', -}); -entries.push({ - timeline: [ - { - moved: -1, - ringId: 'adopt', - date: new Date('2020-08-06'), - description: - 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat', - }, - ], - key: 'typescript', - id: 'typescript', - title: 'TypeScript', - quadrant: 'languages', - description: - 'Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat', -}); -entries.push({ - timeline: [ - { - moved: 1, - ringId: 'adopt', - date: new Date('2020-08-06'), - description: - 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur', - }, - ], - links: [ - { - url: 'https://webpack.js.org/', - title: 'Learn more', - }, - ], - key: 'webpack', - id: 'webpack', - title: 'Webpack', - quadrant: 'frameworks', -}); -entries.push({ - timeline: [ - { - moved: 0, - ringId: 'adopt', - date: new Date('2020-08-06'), - }, - ], - links: [ - { - url: 'https://reactjs.org/', - title: 'Learn more', - }, - ], - key: 'react', - id: 'react', - title: 'React', - quadrant: 'frameworks', -}); -entries.push({ - timeline: [ - { - moved: 0, - ringId: 'adopt', - date: new Date('2020-08-06'), - }, - ], - key: 'code-reviews', - id: 'code-reviews', - title: 'Code Reviews', - quadrant: 'process', -}); -entries.push({ - timeline: [ - { - moved: 0, - ringId: 'assess', - date: new Date('2020-08-06'), - }, - ], - key: 'mob-programming', - id: 'mob-programming', - title: 'Mob Programming', - quadrant: 'process', -}); -entries.push({ - timeline: [ - { - moved: 0, - ringId: 'adopt', - date: new Date('2020-08-06'), - }, - ], - key: 'docs-like-code', - id: 'docs-like-code', - title: 'Docs-like-code', - quadrant: 'process', -}); -entries.push({ - timeline: [ - { - ringId: 'hold', - date: new Date('2020-08-06'), - }, - ], - key: 'force-push', - id: 'force-push', - title: 'Force push to master', - quadrant: 'process', -}); -entries.push({ - timeline: [ - { - ringId: 'adopt', - date: new Date('2020-08-06'), - description: 'long description', - }, - { - ringId: 'trial', - date: new Date('2020-07-05'), - description: 'long description', - }, - ], - links: [ - { - url: 'https://github.com', - title: 'Learn more', - }, - ], - key: 'github-actions', - id: 'github-actions', - title: 'GitHub Actions', - quadrant: 'infrastructure', -}); - -export const mock: TechRadarLoaderResponse = { - entries, - quadrants, - rings, -}; - -export class SampleTechRadarApi implements TechRadarApi { - async load() { - return mock; - } -} diff --git a/plugins/tech-radar/src/setupTests.ts b/plugins/tech-radar/src/setupTests.ts deleted file mode 100644 index 963c0f188b..0000000000 --- a/plugins/tech-radar/src/setupTests.ts +++ /dev/null @@ -1,17 +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 '@testing-library/jest-dom'; diff --git a/plugins/tech-radar/src/utils/components.tsx b/plugins/tech-radar/src/utils/components.tsx deleted file mode 100644 index 53d64065f6..0000000000 --- a/plugins/tech-radar/src/utils/components.tsx +++ /dev/null @@ -1,41 +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 { Link } from '@backstage/core-components'; -import React from 'react'; - -type WithLinkProps = { - url?: string; - className: string; - children: React.ReactNode; -}; - -export function isValidUrl(url: string | undefined): url is string { - return Boolean(url && url !== '#' && url.length > 0); -} - -export const WithLink = ({ - url, - className, - children, -}: WithLinkProps): JSX.Element => - isValidUrl(url) ? ( - - {children} - - ) : ( - <>{children} - ); diff --git a/plugins/tech-radar/src/utils/polyfills/getBBox.ts b/plugins/tech-radar/src/utils/polyfills/getBBox.ts deleted file mode 100644 index 6e52995e80..0000000000 --- a/plugins/tech-radar/src/utils/polyfills/getBBox.ts +++ /dev/null @@ -1,51 +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. - */ - -// For testing with Jest and JSDOM -// SVGGElement.prototype.getBBox to calculate boundaries. -// JSDOM doesn't support this: https://github.com/jsdom/jsdom/issues/1664 -class GetBBoxPolyfill { - static exists(): boolean { - return typeof (window.Element.prototype as any).getBBox !== 'undefined'; - } - - static create( - x: number = 0, - y: number = 0, - width: number = 1000, - height: number = 500, - ): void { - if (this.exists()) { - return; - } - - Object.defineProperty(window.Element.prototype, 'getBBox', { - writable: false, - configurable: true, - value: () => ({ x, y, width, height }), - }); - } - - static remove(): void { - if (!this.exists()) { - return; - } - - delete (window.Element.prototype as any).getBBox; - } -} - -export default GetBBoxPolyfill; diff --git a/plugins/tech-radar/src/utils/segment.js b/plugins/tech-radar/src/utils/segment.js deleted file mode 100644 index a87ef20360..0000000000 --- a/plugins/tech-radar/src/utils/segment.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export default class Segment { - constructor(quadrant, ring, radius, nextSeed) { - this.nextSeed = nextSeed; - this.polarMin = { - t: quadrant.radialMin, - r: ring.innerRadius, - }; - this.polarMax = { - t: quadrant.radialMax, - r: ring.outerRadius, - }; - this.cartesianMin = { - x: 15 * quadrant.offsetX, - y: 15 * quadrant.offsetY, - }; - this.cartesianMax = { - x: radius * quadrant.offsetX, - y: radius * quadrant.offsetY, - }; - } - - clipx(d) { - const c = boundedBox(d, this.cartesianMin, this.cartesianMax); - const p = boundedRing(polar(c), this.polarMin.r + 15, this.polarMax.r - 15); - d.x = cartesian(p).x; - return d.x; - } - - clipy(d) { - const c = boundedBox(d, this.cartesianMin, this.cartesianMax); - const p = boundedRing(polar(c), this.polarMin.r + 15, this.polarMax.r - 15); - d.y = cartesian(p).y; - return d.y; - } - - random() { - return cartesian({ - t: this._randomBetween(this.polarMin.t, this.polarMax.t), - r: this._normalBetween(this.polarMin.r, this.polarMax.r), - }); - } - - // custom random number generator, to make random sequence reproducible - // source: https://stackoverflow.com/questions/521295 - _random() { - const x = Math.sin(this.nextSeed()) * 10000; - return x - Math.floor(x); - } - - _randomBetween(min, max) { - return min + this._random() * (max - min); - } - - _normalBetween(min, max) { - return min + (this._random() + this._random()) * 0.5 * (max - min); - } -} - -function polar({ x, y }) { - return { - t: Math.atan2(y, x), - r: Math.sqrt(x * x + y * y), - }; -} - -function cartesian({ r, t }) { - return { - x: r * Math.cos(t), - y: r * Math.sin(t), - }; -} - -function boundedInterval(value, min, max) { - const low = Math.min(min, max); - const high = Math.max(min, max); - return Math.min(Math.max(value, low), high); -} - -function boundedRing(polarValue, rMin, rMax) { - return { - t: polarValue.t, - r: boundedInterval(polarValue.r, rMin, rMax), - }; -} - -function boundedBox(point, min, max) { - return { - x: boundedInterval(point.x, min.x, max.x), - y: boundedInterval(point.y, min.y, max.y), - }; -} diff --git a/plugins/tech-radar/src/utils/types.ts b/plugins/tech-radar/src/utils/types.ts deleted file mode 100644 index 4ab236765d..0000000000 --- a/plugins/tech-radar/src/utils/types.ts +++ /dev/null @@ -1,85 +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 { MovedState } from '../api'; - -// Parameters for a ring; its index in an array determines how close to the center this ring is. -export type Ring = { - id: string; - index?: number; - name: string; - color: string; - outerRadius?: number; - innerRadius?: number; - description?: string; -}; - -// Parameters for a quadrant (there should be exactly 4 of course) -export type Quadrant = { - id: string; - index?: number; - name: string; - legendX?: number; - legendY?: number; - legendWidth?: number; - legendHeight?: number; - radialMin?: number; - radialMax?: number; - offsetX?: number; - offsetY?: number; -}; - -export type Segment = { - clipx: Function; - clipy: Function; - random: Function; -}; - -export type Entry = { - id: string; - index?: number; - x?: number; - y?: number; - color?: string; - segment?: Segment; - // The quadrant where this entry belongs - quadrant: Quadrant; - // The ring where this entry belongs - ring: Ring; - // The label that's shown in the legend and on hover - title: string; - // An URL to a longer description as to why this entry is where it is - url?: string; - links?: Array<{ title: string; url: string }>; - // How this entry has recently moved; -1 for "down", +1 for "up", 0 for not moved - moved?: MovedState; - // Most recent description to display in the UI - description?: string; - active?: boolean; - timeline?: Array; -}; - -export type EntrySnapshot = { - date: Date; - ring: Ring; - description?: string; - moved?: MovedState; -}; - -// The same as Entry except quadrant/ring are declared by their string ID instead of being the actual objects -export type DeclaredEntry = Entry & { - quadrant: string; - ring: string; -}; diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 4e66d20476..4ce9d18415 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,177 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.32-next.0 + +### Patch Changes + +- 2f13862: Fix bug in TechDocsAddonTester when jest.resetAllMocks is called between tests +- Updated dependencies + - @backstage/plugin-catalog@1.19.1-next.0 + - @backstage/plugin-techdocs@1.10.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/test-utils@1.5.5-next.0 + - @backstage/plugin-search-react@1.7.11-next.0 + +## 1.0.31 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog@1.19.0 + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/test-utils@1.5.4 + - @backstage/plugin-techdocs@1.10.4 + - @backstage/integration-react@1.1.26 + +## 1.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0-next.1 + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/test-utils@1.5.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-techdocs@1.10.4-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.19.0-next.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/test-utils@1.5.3 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-techdocs@1.10.4-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.0.30 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/plugin-techdocs@1.10.3 + - @backstage/plugin-catalog@1.18.2 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.3 + +## 1.0.29 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.1 + - @backstage/core-app-api@1.12.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/plugin-search-react@1.7.8 + - @backstage/plugin-techdocs@1.10.2 + - @backstage/plugin-catalog@1.18.1 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.2 + +## 1.0.28 + +### Patch Changes + +- 3f14e9f: Mock the new issue user cookie api method. +- 62bcaf8: Use the new generic refresh user cookie provider. +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-catalog@1.18.0 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/core-app-api@1.12.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/test-utils@1.5.1 + - @backstage/plugin-search-react@1.7.7 + +## 1.0.28-next.2 + +### Patch Changes + +- 3f14e9f: Mock the new issue user cookie api method. +- Updated dependencies + - @backstage/plugin-techdocs@1.10.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/plugin-catalog@1.18.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/test-utils@1.5.1-next.1 + +## 1.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/plugin-catalog@1.17.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/test-utils@1.5.1-next.1 + - @backstage/plugin-techdocs@1.10.1-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + +## 1.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-catalog@1.17.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/plugin-techdocs@1.10.1-next.0 + - @backstage/test-utils@1.5.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/core-app-api@1.12.1-next.0 + +## 1.0.27 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/plugin-catalog@1.17.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/core-app-api@1.12.0 + - @backstage/test-utils@1.5.0 + - @backstage/plugin-techdocs@1.10.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/integration-react@1.1.24 + ## 1.0.27-next.3 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 8e8467929a..ac7d3cb752 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,36 +1,39 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.27-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "version": "1.0.32-next.0", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-addons-test-utils" }, - "keywords": [ - "backstage", - "techdocs" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-app-api": "workspace:^", @@ -45,18 +48,15 @@ "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "testing-library__dom": "^7.29.4-beta.1" }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@testing-library/dom": "^10.0.0", + "@testing-library/jest-dom": "^6.0.0" + }, "peerDependencies": { - "@testing-library/react": "^12.1.3 || ^13.0.0 || ^14.0.0", + "@testing-library/react": "^15.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0" - }, - "files": [ - "dist" - ] + } } diff --git a/plugins/techdocs-addons-test-utils/src/test-utils.tsx b/plugins/techdocs-addons-test-utils/src/test-utils.tsx index 518e469e1e..2066acbb48 100644 --- a/plugins/techdocs-addons-test-utils/src/test-utils.tsx +++ b/plugins/techdocs-addons-test-utils/src/test-utils.tsx @@ -24,7 +24,11 @@ import { act, render } from '@testing-library/react'; import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; import { FlatRoutes } from '@backstage/core-app-api'; -import { ApiRef } from '@backstage/core-plugin-api'; +import { + ApiRef, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; import { TechDocsAddons, @@ -45,26 +49,6 @@ if (!global.TextEncoder) { const { renderToStaticMarkup } = require('react-dom/server') as typeof import('react-dom/server'); -const techdocsApi = { - getTechDocsMetadata: jest.fn(), - getEntityMetadata: jest.fn(), -}; - -const techdocsStorageApi = { - getApiOrigin: jest.fn(), - getBaseUrl: jest.fn(), - getEntityDocs: jest.fn(), - syncEntityDocs: jest.fn(), -}; - -const searchApi = { - query: jest.fn().mockResolvedValue({ results: [] }), -}; - -const scmIntegrationsApi = { - fromConfig: jest.fn().mockReturnValue({}), -}; - /** @ignore */ type TechDocsAddonTesterTestApiPair = TApi extends infer TImpl ? readonly [ApiRef, Partial] @@ -199,7 +183,49 @@ export class TechDocsAddonTester { * App instance, using the given Addon(s). */ build() { + const techdocsApi = { + getTechDocsMetadata: jest.fn(), + getEntityMetadata: jest.fn(), + getCookie: jest.fn().mockReturnValue({ + // Expires in 10 minutes + expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(), + }), + }; + + const techdocsStorageApi = { + getApiOrigin: jest.fn(), + getBaseUrl: jest.fn(), + getEntityDocs: jest.fn(), + syncEntityDocs: jest.fn(), + }; + + const searchApi = { + query: jest.fn().mockResolvedValue({ results: [] }), + }; + + const scmIntegrationsApi = { + fromConfig: jest.fn().mockReturnValue({}), + }; + + const discoveryApi = { + getBaseUrl: jest + .fn() + .mockResolvedValue('https://backstage.example.com/api/techdocs'), + }; + + const fetchApi = { + fetch: jest.fn().mockResolvedValue({ + ok: true, + json: jest.fn().mockResolvedValue({ + // Expires in 10 minutes + expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(), + }), + }), + }; + const apis: TechdocsAddonTesterApis = [ + [fetchApiRef, fetchApi], + [discoveryApiRef, discoveryApi], [techdocsApiRef, techdocsApi], [techdocsStorageApiRef, techdocsStorageApi], [searchApiRef, searchApi], diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 6ea20dea39..86056032a6 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,216 @@ # @backstage/plugin-techdocs-backend +## 1.10.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/catalog-client@1.6.5-next.0 + - @backstage/plugin-catalog-common@1.0.23-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.23-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/plugin-permission-common@0.7.13 + +## 1.10.4 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- c884b9a: Use the default cookie endpoints added automatically when a cookie policy is set. +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-search-backend-module-techdocs@0.1.22 + - @backstage/catalog-client@1.6.4 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## 1.10.4-next.1 + +### Patch Changes + +- c884b9a: Use the default cookie endpoints added automatically when a cookie policy is set. +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-client@1.6.4-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## 1.10.4-next.0 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.22-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-client@1.6.3 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## 1.10.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.3 + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.21 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## 1.10.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.2 + - @backstage/backend-common@0.21.5 + - @backstage/plugin-techdocs-node@1.12.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.20 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-catalog-common@1.0.22 + - @backstage/plugin-permission-common@0.7.13 + +## 1.10.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-techdocs@0.1.19 + +## 1.10.0 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- 3f14e9f: Migrate plugin to use the new auth services. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/plugin-permission-common@0.7.13 + - @backstage/plugin-search-backend-module-techdocs@0.1.18 + - @backstage/catalog-client@1.6.1 + - @backstage/catalog-model@1.4.5 + - @backstage/plugin-catalog-common@1.0.22 + +## 1.10.0-next.2 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- 3f14e9f: Migrate plugin to use the new auth services. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/catalog-client@1.6.1-next.1 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + +## 1.9.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/plugin-permission-common@0.7.13-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.1.18-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.1 + +## 1.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/plugin-permission-common@0.7.13-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.17-next.0 + - @backstage/catalog-client@1.6.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-catalog-common@1.0.22-next.0 + +## 1.9.3 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.14 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration@1.9.0 + - @backstage/catalog-client@1.6.0 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-catalog-common@1.0.21 + - @backstage/plugin-permission-common@0.7.12 + ## 1.9.3-next.3 ### Patch Changes diff --git a/plugins/techdocs-backend/api-report.md b/plugins/techdocs-backend/api-report.md index 9e9a42c388..ec3c2ada82 100644 --- a/plugins/techdocs-backend/api-report.md +++ b/plugins/techdocs-backend/api-report.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogClient } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; @@ -11,6 +12,7 @@ import { DocsBuildStrategy as DocsBuildStrategy_2 } from '@backstage/plugin-tech import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { GeneratorBuilder } from '@backstage/plugin-techdocs-node'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { Knex } from 'knex'; import { Logger } from 'winston'; import { Permission } from '@backstage/plugin-permission-common'; @@ -65,6 +67,8 @@ export type OutOfTheBoxDeploymentOptions = { docsBuildStrategy?: DocsBuildStrategy_2; buildLogTransport?: winston.transport; catalogClient?: CatalogClient; + httpAuth?: HttpAuthService; + auth?: AuthService; }; // @public @@ -77,6 +81,8 @@ export type RecommendedDeploymentOptions = { docsBuildStrategy?: DocsBuildStrategy_2; buildLogTransport?: winston.transport; catalogClient?: CatalogClient; + httpAuth?: HttpAuthService; + auth?: AuthService; }; // @public diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 4568c443e4..bd3cee3ad6 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,18 +1,31 @@ { "name": "@backstage/plugin-techdocs-backend", + "version": "1.10.5-next.0", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.9.3-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "backend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage", + "techdocs" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/techdocs-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,27 +36,18 @@ ] } }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/techdocs-backend" - }, - "keywords": [ - "backstage", - "techdocs" + "files": [ + "dist", + "config.d.ts" ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -75,9 +79,5 @@ "msw": "^1.0.0", "supertest": "^6.1.3" }, - "files": [ - "dist", - "config.d.ts" - ], "configSchema": "config.d.ts" } diff --git a/plugins/techdocs-backend/src/plugin.ts b/plugins/techdocs-backend/src/plugin.ts index f139cf3c3a..6f670abfa9 100644 --- a/plugins/techdocs-backend/src/plugin.ts +++ b/plugins/techdocs-backend/src/plugin.ts @@ -15,9 +15,9 @@ */ import { + cacheToPluginCacheManager, DockerContainerRunner, loggerToWinstonLogger, - cacheToPluginCacheManager, } from '@backstage/backend-common'; import { coreServices, @@ -26,10 +26,15 @@ import { import { DocsBuildStrategy, - Preparers, Generators, + PreparerBase, + Preparers, Publisher, + RemoteProtocol, techdocsBuildsExtensionPoint, + TechdocsGenerator, + techdocsGeneratorExtensionPoint, + techdocsPreparerExtensionPoint, } from '@backstage/plugin-techdocs-node'; import Docker from 'dockerode'; import { createRouter } from '@backstage/plugin-techdocs-backend'; @@ -51,6 +56,29 @@ export const techdocsPlugin = createBackendPlugin({ }, }); + let customTechdocsGenerator: TechdocsGenerator | undefined; + env.registerExtensionPoint(techdocsGeneratorExtensionPoint, { + setTechdocsGenerator(generator: TechdocsGenerator) { + if (customTechdocsGenerator) { + throw new Error('TechdocsGenerator may only be set once'); + } + + customTechdocsGenerator = generator; + }, + }); + + const customPreparers = new Map(); + env.registerExtensionPoint(techdocsPreparerExtensionPoint, { + registerPreparer(protocol: RemoteProtocol, preparer: PreparerBase) { + if (customPreparers.has(protocol)) { + throw new Error( + `Preparer for protocol ${protocol} is already registered`, + ); + } + customPreparers.set(protocol, preparer); + }, + }); + env.registerInit({ deps: { config: coreServices.rootConfig, @@ -59,14 +87,28 @@ export const techdocsPlugin = createBackendPlugin({ http: coreServices.httpRouter, discovery: coreServices.discovery, cache: coreServices.cache, + httpAuth: coreServices.httpAuth, + auth: coreServices.auth, }, - async init({ config, logger, urlReader, http, discovery, cache }) { + async init({ + config, + logger, + urlReader, + http, + discovery, + cache, + httpAuth, + auth, + }) { const winstonLogger = loggerToWinstonLogger(logger); // Preparers are responsible for fetching source files for documentation. const preparers = await Preparers.fromConfig(config, { reader: urlReader, logger: winstonLogger, }); + for (const [protocol, preparer] of customPreparers.entries()) { + preparers.register(protocol, preparer); + } // Docker client (conditionally) used by the generators, based on techdocs.generators config. const dockerClient = new Docker(); @@ -76,6 +118,7 @@ export const techdocsPlugin = createBackendPlugin({ const generators = await Generators.fromConfig(config, { logger: winstonLogger, containerRunner, + customGenerator: customTechdocsGenerator, }); // Publisher is used for @@ -100,8 +143,15 @@ export const techdocsPlugin = createBackendPlugin({ publisher, config, discovery, + httpAuth, + auth, }), ); + + http.addAuthPolicy({ + path: '/static', + allow: 'user-cookie', + }); }, }); }, diff --git a/plugins/techdocs-backend/src/service/router.ts b/plugins/techdocs-backend/src/service/router.ts index 00aea0b0dd..b6f95d4e1b 100644 --- a/plugins/techdocs-backend/src/service/router.ts +++ b/plugins/techdocs-backend/src/service/router.ts @@ -16,6 +16,7 @@ import { PluginEndpointDiscovery, PluginCacheManager, + createLegacyAuthAdapters, } from '@backstage/backend-common'; import { CatalogClient } from '@backstage/catalog-client'; import { stringifyEntityRef } from '@backstage/catalog-model'; @@ -37,6 +38,7 @@ import { createCacheMiddleware, TechDocsCache } from '../cache'; import { CachedEntityLoader } from './CachedEntityLoader'; import { DefaultDocsBuildStrategy } from './DefaultDocsBuildStrategy'; import * as winston from 'winston'; +import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api'; /** * Required dependencies for running TechDocs in the "out-of-the-box" @@ -56,6 +58,8 @@ export type OutOfTheBoxDeploymentOptions = { docsBuildStrategy?: DocsBuildStrategy; buildLogTransport?: winston.transport; catalogClient?: CatalogClient; + httpAuth?: HttpAuthService; + auth?: AuthService; }; /** @@ -73,6 +77,8 @@ export type RecommendedDeploymentOptions = { docsBuildStrategy?: DocsBuildStrategy; buildLogTransport?: winston.transport; catalogClient?: CatalogClient; + httpAuth?: HttpAuthService; + auth?: AuthService; }; /** @@ -106,6 +112,9 @@ export async function createRouter( ): Promise { const router = Router(); const { publisher, config, logger, discovery } = options; + + const { auth, httpAuth } = createLegacyAuthAdapters(options); + const catalogClient = options.catalogClient ?? new CatalogClient({ discoveryApi: discovery }); const docsBuildStrategy = @@ -140,7 +149,13 @@ export async function createRouter( router.get('/metadata/techdocs/:namespace/:kind/:name', async (req, res) => { const { kind, namespace, name } = req.params; const entityName = { kind, namespace, name }; - const token = getBearerToken(req.headers.authorization); + + const credentials = await httpAuth.credentials(req); + + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); // Verify that the related entity exists and the current user has permission to view it. const entity = await entityLoader.load(entityName, token); @@ -173,7 +188,13 @@ export async function createRouter( router.get('/metadata/entity/:namespace/:kind/:name', async (req, res) => { const { kind, namespace, name } = req.params; const entityName = { kind, namespace, name }; - const token = getBearerToken(req.headers.authorization); + + const credentials = await httpAuth.credentials(req); + + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); const entity = await entityLoader.load(entityName, token); @@ -205,7 +226,13 @@ export async function createRouter( // If a build is required, responds with a success when finished router.get('/sync/:namespace/:kind/:name', async (req, res) => { const { kind, namespace, name } = req.params; - const token = getBearerToken(req.headers.authorization); + + const credentials = await httpAuth.credentials(req); + + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); const entity = await entityLoader.load({ kind, namespace, name }, token); @@ -264,7 +291,15 @@ export async function createRouter( async (req, _res, next) => { const { kind, namespace, name } = req.params; const entityName = { kind, namespace, name }; - const token = getBearerToken(req.headers.authorization); + + const credentials = await httpAuth.credentials(req, { + allowLimitedAccess: true, + }); + + const { token } = await auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: 'catalog', + }); const entity = await entityLoader.load(entityName, token); @@ -290,10 +325,6 @@ export async function createRouter( return router; } -function getBearerToken(header?: string): string | undefined { - return header?.match(/(?:Bearer)\s+(\S+)/i)?.[1]; -} - /** * Create an event-stream response that emits the events 'log', 'error', and 'finish'. * diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index b10451bc14..d577b465b5 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,121 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + +## 1.1.9 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + +## 1.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration@1.9.1 + +## 1.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/plugin-techdocs-react@1.2.1 + - @backstage/integration-react@1.1.25 + - @backstage/core-plugin-api@1.9.1 + - @backstage/integration@1.9.1 + +## 1.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/core-components@0.14.1 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/core-plugin-api@1.9.1 + +## 1.1.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/core-plugin-api@1.9.1-next.1 + +## 1.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + +## 1.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + +## 1.1.5 + +### Patch Changes + +- ab9c9eb: Fixed the value label text color in dark mode for the TextSize addon. +- 09cedb9: Updated dependency `@react-hookz/web` to `^24.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 131ffdc: Fix position of the ReportIssue component when is displaying at the top of the container. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/integration-react@1.1.24 + ## 1.1.5-next.3 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 447a3a1755..793018b1e1 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", + "version": "1.1.10-next.0", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.1.5-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin-module" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "frontend-plugin-module" - }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-module-addons-contrib" }, - "keywords": [ - "backstage", - "techdocs" - ], + "license": "Apache-2.0", "sideEffects": false, + "main": "src/index.ts", + "types": "src/index.ts", + "files": [ + "dist" + ], "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", + "lint": "backstage-cli package lint", "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" + "postpack": "backstage-cli package postpack", + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-components": "workspace:^", @@ -45,21 +48,18 @@ "git-url-parse": "^14.0.0", "photoswipe": "^5.3.7" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/plugin-techdocs-addons-test-utils": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@types/react": "^16.13.1 || ^17.0.0" }, - "files": [ - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/techdocs-module-addons-contrib/src/setupTests.ts b/plugins/techdocs-module-addons-contrib/src/setupTests.ts index 56b9b18321..228079bc19 100644 --- a/plugins/techdocs-module-addons-contrib/src/setupTests.ts +++ b/plugins/techdocs-module-addons-contrib/src/setupTests.ts @@ -16,3 +16,28 @@ import '@testing-library/jest-dom'; Element.prototype.scrollIntoView = jest.fn(); + +type Listener = (event: { data: any }) => void; + +global.BroadcastChannel = jest + .fn() + .mockImplementation((_channelName: string) => { + let listeners: Listener[] = []; + return { + postMessage: jest.fn((message: any) => { + // Simulate message event for all listeners + listeners.forEach(listener => listener({ data: message })); + }), + addEventListener: jest.fn((event: string, listener: Listener) => { + if (event === 'message') { + listeners.push(listener); + } + }), + removeEventListener: jest.fn((event: string, listener: Listener) => { + if (event === 'message') { + listeners = listeners.filter(l => l !== listener); + } + }), + close: jest.fn(), + }; + }); diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 05bf695c5f..73fae3afe0 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,177 @@ # @backstage/plugin-techdocs-node +## 1.12.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## 1.12.3 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/integration@1.10.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.11 + +## 1.12.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## 1.12.3-next.0 + +### Patch Changes + +- 8e28c88: Allow overriding default techdocs preparers with new `TechdocsPreparerExtensionPoint` +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/integration@1.10.0-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.11 + +## 1.12.2 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/integration-aws-node@0.1.12 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-search-common@1.2.11 + +## 1.12.1 + +### Patch Changes + +- 81a995f: Updated dependency `aws-sdk-client-mock` to `^4.0.0`. +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/integration-aws-node@0.1.11 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/plugin-search-common@1.2.11 + +## 1.12.0 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- 5b4f565: Fix handling of default plugins that have configuration +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/integration-aws-node@0.1.10 + +## 1.12.0-next.2 + +### Minor Changes + +- 718b734: Create extension point `TechdocsGeneratorExtensionPoint` to allow adding a custom generator + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.11.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-aws-node@0.1.10-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.11.5-next.0 + +### Patch Changes + +- 5b4f565: Fix handling of default plugins that have configuration +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/integration-aws-node@0.1.10-next.0 + +## 1.11.2 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- 77e3050: Update to a newer version of `@trendyol-js/openstack-swift-sdk` +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/catalog-model@1.4.4 + - @backstage/integration-aws-node@0.1.9 + - @backstage/integration@1.9.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.10 + ## 1.11.2-next.3 ### Patch Changes diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index 5203d30faa..4e79ee712c 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -72,6 +72,7 @@ export class Generators implements GeneratorBuilder { options: { logger: Logger; containerRunner: ContainerRunner; + customGenerator?: TechdocsGenerator; }, ): Promise; get(entity: Entity): GeneratorBase; @@ -272,6 +273,15 @@ export class TechdocsGenerator implements GeneratorBase { run(options: GeneratorRunOptions): Promise; } +// @public +export interface TechdocsGeneratorExtensionPoint { + // (undocumented) + setTechdocsGenerator(generator: TechdocsGenerator): void; +} + +// @public +export const techdocsGeneratorExtensionPoint: ExtensionPoint; + // @public export type TechDocsMetadata = { site_name: string; @@ -281,6 +291,15 @@ export type TechDocsMetadata = { files?: string[]; }; +// @public +export interface TechdocsPreparerExtensionPoint { + // (undocumented) + registerPreparer(protocol: RemoteProtocol, preparer: PreparerBase): void; +} + +// @public +export const techdocsPreparerExtensionPoint: ExtensionPoint; + // @public export const transformDirLocation: ( entity: Entity, diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 7046ea0f8c..0c590816e7 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,42 +1,42 @@ { "name": "@backstage/plugin-techdocs-node", + "version": "1.12.4-next.0", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.11.2-next.3", - "main": "src/index.ts", - "types": "src/index.ts", + "backstage": { + "role": "node-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "node-library" - }, + "keywords": [ + "techdocs", + "backstage" + ], "homepage": "https://backstage.io", + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-node" }, - "keywords": [ - "techdocs", - "backstage" - ], "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" - }, - "bugs": { - "url": "https://github.com/backstage/backstage/issues" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@aws-sdk/client-s3": "^3.350.0", @@ -76,7 +76,7 @@ "@types/mime-types": "^2.1.0", "@types/recursive-readdir": "^2.2.0", "@types/supertest": "^2.0.8", - "aws-sdk-client-mock": "^3.0.0", + "aws-sdk-client-mock": "^4.0.0", "supertest": "^6.1.3" } } diff --git a/plugins/techdocs-node/src/extensions.ts b/plugins/techdocs-node/src/extensions.ts index c3a048b4e2..ed292a3b17 100644 --- a/plugins/techdocs-node/src/extensions.ts +++ b/plugins/techdocs-node/src/extensions.ts @@ -15,6 +15,7 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { DocsBuildStrategy } from './techdocsTypes'; +import { PreparerBase, RemoteProtocol, TechdocsGenerator } from './stages'; /** * Extension point type for configuring Techdocs builds. @@ -34,3 +35,41 @@ export const techdocsBuildsExtensionPoint = createExtensionPoint({ id: 'techdocs.builds', }); + +/** + * Extension point type for configuring a custom Techdocs generator + * + * @public + */ +export interface TechdocsGeneratorExtensionPoint { + setTechdocsGenerator(generator: TechdocsGenerator): void; +} + +/** + * Extension point for configuring a custom Techdocs generator + * + * @public + */ +export const techdocsGeneratorExtensionPoint = + createExtensionPoint({ + id: 'techdocs.generator', + }); + +/** + * Extension point type for configuring a custom Techdocs preparer + * + * @public + */ +export interface TechdocsPreparerExtensionPoint { + registerPreparer(protocol: RemoteProtocol, preparer: PreparerBase): void; +} + +/** + * Extension point for configuring a custom Techdocs preparer + * + * @public + */ +export const techdocsPreparerExtensionPoint = + createExtensionPoint({ + id: 'techdocs.preparer', + }); diff --git a/plugins/techdocs-node/src/index.ts b/plugins/techdocs-node/src/index.ts index 640bd09ce0..b2efadf423 100644 --- a/plugins/techdocs-node/src/index.ts +++ b/plugins/techdocs-node/src/index.ts @@ -25,5 +25,9 @@ export * from './helpers'; export * from './techdocsTypes'; export { techdocsBuildsExtensionPoint, + techdocsGeneratorExtensionPoint, + techdocsPreparerExtensionPoint, type TechdocsBuildsExtensionPoint, + type TechdocsGeneratorExtensionPoint, + type TechdocsPreparerExtensionPoint, } from './extensions'; diff --git a/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_additional_plugins_with_config.yml b/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_additional_plugins_with_config.yml new file mode 100644 index 0000000000..6c945162d7 --- /dev/null +++ b/plugins/techdocs-node/src/stages/generate/__fixtures__/mkdocs_with_additional_plugins_with_config.yml @@ -0,0 +1,9 @@ +site_name: Test site name +site_description: Test site description +docs_dir: docs/ +plugins: + - not-techdocs-core + - also-not-techdocs-core + - custom-plugin: + with: + configuration: 1 diff --git a/plugins/techdocs-node/src/stages/generate/generators.ts b/plugins/techdocs-node/src/stages/generate/generators.ts index 630fccfa44..603c714370 100644 --- a/plugins/techdocs-node/src/stages/generate/generators.ts +++ b/plugins/techdocs-node/src/stages/generate/generators.ts @@ -40,11 +40,16 @@ export class Generators implements GeneratorBuilder { */ static async fromConfig( config: Config, - options: { logger: Logger; containerRunner: ContainerRunner }, + options: { + logger: Logger; + containerRunner: ContainerRunner; + customGenerator?: TechdocsGenerator; + }, ): Promise { const generators = new Generators(); - const techdocsGenerator = TechdocsGenerator.fromConfig(config, options); + const techdocsGenerator = + options.customGenerator ?? TechdocsGenerator.fromConfig(config, options); generators.register('techdocs', techdocsGenerator); return generators; diff --git a/plugins/techdocs-node/src/stages/generate/helpers.test.ts b/plugins/techdocs-node/src/stages/generate/helpers.test.ts index 24d9b3effb..1b47cfb05c 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.test.ts @@ -81,6 +81,12 @@ const mkdocsYmlWithoutPlugins = fs.readFileSync( const mkdocsYmlWithAdditionalPlugins = fs.readFileSync( resolvePath(__filename, '../__fixtures__/mkdocs_with_additional_plugins.yml'), ); +const mkdocsYmlWithAdditionalPluginsWithConfig = fs.readFileSync( + resolvePath( + __filename, + '../__fixtures__/mkdocs_with_additional_plugins_with_config.yml', + ), +); const mkdocsYmlWithEnvTag = fs.readFileSync( resolvePath(__filename, '../__fixtures__/mkdocs_with_env_tag.yml'), ); @@ -321,6 +327,8 @@ describe('helpers', () => { 'mkdocs_with_techdocs_plugin.yml': mkdocsYmlWithTechdocsPlugins, 'mkdocs_without_plugins.yml': mkdocsYmlWithoutPlugins, 'mkdocs_with_additional_plugins.yml': mkdocsYmlWithAdditionalPlugins, + 'mkdocs_with_additional_plugins_with_config.yml': + mkdocsYmlWithAdditionalPluginsWithConfig, }); }); it('should not add additional plugins if techdocs exists already in mkdocs file', async () => { @@ -386,6 +394,28 @@ describe('helpers', () => { expect(parsedYml.plugins).toContain('techdocs-core'); expect(parsedYml.plugins).toContain('custom-plugin'); }); + it('should not overwrite config when defaults are added', async () => { + await patchMkdocsYmlWithPlugins( + mockDir.resolve('mkdocs_with_additional_plugins_with_config.yml'), + mockLogger, + ['techdocs-core', 'custom-plugin'], + ); + + const updatedMkdocsYml = await fs.readFile( + mockDir.resolve('mkdocs_with_additional_plugins_with_config.yml'), + ); + const parsedYml = yaml.load(updatedMkdocsYml.toString()) as { + plugins: object[]; + }; + expect(parsedYml.plugins).toHaveLength(4); + expect(parsedYml.plugins).toContain('techdocs-core'); + // we want our original object with its properties to be preserved, and for the basic string form of the plugin + // to NOT be added as well. + expect(parsedYml.plugins).not.toContain('custom-plugin'); + expect(parsedYml.plugins).toContainEqual({ + 'custom-plugin': { with: { configuration: 1 } }, + }); + }); }); describe('patchIndexPreBuild', () => { diff --git a/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts index 945aab3884..762a1c267a 100644 --- a/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts +++ b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts @@ -153,21 +153,30 @@ export const patchMkdocsYmlWithPlugins = async ( defaultPlugins: string[] = ['techdocs-core'], ) => { await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => { - // Modify mkdocs.yaml to contain the required default plugins + // Modify mkdocs.yaml to contain the required default plugins. + // If no plugins are defined we can just return the defaults. if (!('plugins' in mkdocsYml)) { mkdocsYml.plugins = defaultPlugins; return true; } - if ( - mkdocsYml.plugins && - !defaultPlugins.every(plugin => mkdocsYml.plugins!.includes(plugin)) - ) { - mkdocsYml.plugins = [ - ...new Set([...mkdocsYml.plugins, ...defaultPlugins]), - ]; - return true; - } - return false; + // Otherwise, check each default plugin and include it if necessary. + let changesMade = false; + + defaultPlugins.forEach(dp => { + // if the plugin isn't there as a string, and isn't there as an object (which may itself contain extra config) + // then we need to add it + if ( + !( + mkdocsYml.plugins!.includes(dp) || + mkdocsYml.plugins!.some(p => p.hasOwnProperty(dp)) + ) + ) { + mkdocsYml.plugins = [...new Set([...mkdocsYml.plugins!, dp])]; + changesMade = true; + } + }); + + return changesMade; }); }; diff --git a/plugins/techdocs-react/.eslintrc.js b/plugins/techdocs-react/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/techdocs-react/.eslintrc.js +++ b/plugins/techdocs-react/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 3b31750bed..95f7bd8eaa 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,129 @@ # @backstage/plugin-techdocs-react +## 1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + +## 1.2.3 + +### Patch Changes + +- b450af3: Added ESLint rule `no-top-level-material-ui-4-imports` in the Techdocs-react plugin to migrate the Material UI imports. +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- Updated dependencies + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/version-bridge@1.0.8 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + +## 1.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## 1.2.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.7 + +## 1.2.1 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.7 + +## 1.2.0 + +### Minor Changes + +- 3f14e9f: Create a new api method for issuing user cookie. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/catalog-model@1.4.5 + - @backstage/core-plugin-api@1.9.1 + - @backstage/version-bridge@1.0.7 + +## 1.2.0-next.2 + +### Minor Changes + +- 3f14e9f: Create a new api method for issuing user cookie. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/version-bridge@1.0.7 + +## 1.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/version-bridge@1.0.7 + +## 1.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/version-bridge@1.0.7 + +## 1.1.16 + +### Patch Changes + +- 9aac2b0: Use `--cwd` as the first `yarn` argument +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0 + - @backstage/catalog-model@1.4.4 + - @backstage/core-plugin-api@1.9.0 + - @backstage/config@1.1.1 + - @backstage/version-bridge@1.0.7 + ## 1.1.16-next.2 ### Patch Changes diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/api-report.md index 93456b7586..c158bbd81e 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/api-report.md @@ -4,7 +4,7 @@ ```ts import { ApiRef } from '@backstage/core-plugin-api'; -import { AsyncState } from 'react-use/lib/useAsync'; +import { AsyncState } from 'react-use/esm/useAsync'; import { ComponentType } from 'react'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; @@ -65,6 +65,10 @@ export interface TechDocsApi { // (undocumented) getApiOrigin(): Promise; // (undocumented) + getCookie(): Promise<{ + expiresAt: string; + }>; + // (undocumented) getEntityMetadata( entityId: CompoundEntityRef, ): Promise; diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 245c1521b3..4431c8f107 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,37 +1,40 @@ { "name": "@backstage/plugin-techdocs-react", + "version": "1.2.4-next.0", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.1.16-next.2", + "backstage": { + "role": "web-library" + }, "publishConfig": { "access": "public", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "web-library" - }, + "keywords": [ + "backstage", + "techdocs" + ], "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", "directory": "plugins/techdocs-react" }, - "keywords": [ - "backstage", - "techdocs" - ], "license": "Apache-2.0", + "sideEffects": false, "main": "src/index.ts", "types": "src/index.ts", - "sideEffects": false, + "files": [ + "dist" + ], "scripts": { "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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" + "start": "backstage-cli package start", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -47,20 +50,16 @@ "react-helmet": "6.1.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@backstage/theme": "workspace:^", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" + "@testing-library/react": "^15.0.0" }, - "files": [ - "alpha", - "dist" - ] + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + } } diff --git a/plugins/techdocs-react/src/api.ts b/plugins/techdocs-react/src/api.ts index 6d726fae01..c53481fe31 100644 --- a/plugins/techdocs-react/src/api.ts +++ b/plugins/techdocs-react/src/api.ts @@ -24,6 +24,7 @@ import { TechDocsEntityMetadata, TechDocsMetadata } from './types'; * @public */ export interface TechDocsApi { + getCookie(): Promise<{ expiresAt: string }>; getApiOrigin(): Promise; getTechDocsMetadata(entityId: CompoundEntityRef): Promise; getEntityMetadata( diff --git a/plugins/techdocs-react/src/component.tsx b/plugins/techdocs-react/src/component.tsx index 48d3138321..0388aafed8 100644 --- a/plugins/techdocs-react/src/component.tsx +++ b/plugins/techdocs-react/src/component.tsx @@ -22,7 +22,8 @@ import React, { } from 'react'; import { create } from 'jss'; -import { StylesProvider, jssPreset } from '@material-ui/styles'; +import StylesProvider from '@material-ui/styles/StylesProvider'; +import jssPreset from '@material-ui/styles/jssPreset'; import { Progress } from '@backstage/core-components'; diff --git a/plugins/techdocs-react/src/context.test.tsx b/plugins/techdocs-react/src/context.test.tsx index bcab445729..a923b3c528 100644 --- a/plugins/techdocs-react/src/context.test.tsx +++ b/plugins/techdocs-react/src/context.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { renderHook, act, waitFor } from '@testing-library/react'; -import { ThemeProvider } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core/styles'; import { lightTheme } from '@backstage/theme'; import { diff --git a/plugins/techdocs-react/src/context.tsx b/plugins/techdocs-react/src/context.tsx index 608dbc59b3..43fdada98e 100644 --- a/plugins/techdocs-react/src/context.tsx +++ b/plugins/techdocs-react/src/context.tsx @@ -23,8 +23,8 @@ import React, { ReactNode, useEffect, } from 'react'; -import useAsync, { AsyncState } from 'react-use/lib/useAsync'; -import useAsyncRetry from 'react-use/lib/useAsyncRetry'; +import useAsync, { AsyncState } from 'react-use/esm/useAsync'; +import useAsyncRetry from 'react-use/esm/useAsyncRetry'; import { CompoundEntityRef, diff --git a/plugins/techdocs/.eslintrc.js b/plugins/techdocs/.eslintrc.js index e2a53a6ad2..e487f765b2 100644 --- a/plugins/techdocs/.eslintrc.js +++ b/plugins/techdocs/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index d5e34fd467..a1d4d9c7ee 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,252 @@ # @backstage/plugin-techdocs +## 1.10.5-next.0 + +### Patch Changes + +- d2cc139: Update path in Readme for Plugin Techdocs to show the correct setup information. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## 1.10.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-auth-react@0.1.0 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-auth-react@0.0.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.10.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/plugin-techdocs-react@1.2.1 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/plugin-search-react@1.7.8 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.2 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.1 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- 62bcaf8: Use the new generic refresh user cookie provider. +- 28f27f0: Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5. +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-react@0.0.1 + - @backstage/theme@0.5.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-search-react@1.7.7 + +## 1.10.1-next.2 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## 1.10.0 + +### Minor Changes + +- af4d147: Updated the styling for `` tags to avoid word break. + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-search-common@1.2.10 + ## 1.10.0-next.3 ### Patch Changes @@ -48,7 +295,7 @@ ### Minor Changes -- af4d147: Updated the styling for tags to avoid word break. +- af4d147: Updated the styling for `` tags to avoid word break. ### Patch Changes diff --git a/plugins/techdocs/README.md b/plugins/techdocs/README.md index 6524651bf5..ddc73e650f 100644 --- a/plugins/techdocs/README.md +++ b/plugins/techdocs/README.md @@ -10,4 +10,4 @@ Refer to our [configuration reference](../../docs/features/techdocs/configuratio ### TechDocs Storage API -The default setup of TechDocs assumes that your documentation is accessed by reading a page with the format of `///`. This can be configured by [implementing a new techdocs storage API](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-implement-your-own-techdocs-apis). +The default setup of TechDocs assumes that your documentation is accessed by reading a page with the format of `///`. This can be configured by [implementing a new techdocs storage API](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-implement-your-own-techdocs-apis). diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index f351996654..06b972bf5f 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -9,7 +9,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import { CSSProperties } from '@material-ui/styles'; +import { CSSProperties } from '@material-ui/styles/withStyles'; import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { FetchApi } from '@backstage/core-plugin-api'; @@ -29,7 +29,7 @@ import { TechDocsApi as TechDocsApi_2 } from '@backstage/plugin-techdocs-react'; import { TechDocsEntityMetadata as TechDocsEntityMetadata_2 } from '@backstage/plugin-techdocs-react'; import { TechDocsMetadata as TechDocsMetadata_2 } from '@backstage/plugin-techdocs-react'; import { TechDocsStorageApi as TechDocsStorageApi_2 } from '@backstage/plugin-techdocs-react'; -import { ToolbarProps } from '@material-ui/core'; +import { ToolbarProps } from '@material-ui/core/Toolbar'; import { UserListFilterKind } from '@backstage/plugin-catalog-react'; // @public @@ -259,6 +259,10 @@ export class TechDocsClient implements TechDocsApi_2 { discoveryApi: DiscoveryApi; // (undocumented) getApiOrigin(): Promise; + // (undocumented) + getCookie(): Promise<{ + expiresAt: string; + }>; getEntityMetadata( entityId: CompoundEntityRef, ): Promise; diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index f2dcc4e346..46e24c8a44 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,18 +1,32 @@ { "name": "@backstage/plugin-techdocs", + "version": "1.10.5-next.0", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.10.0-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "backstage": { + "role": "frontend-plugin" + }, "publishConfig": { "access": "public" }, + "keywords": [ + "backstage", + "techdocs" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/techdocs" + }, + "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -23,28 +37,18 @@ ] } }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/techdocs" - }, - "keywords": [ - "backstage", - "techdocs" + "files": [ + "dist", + "config.d.ts" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/catalog-model": "workspace:^", @@ -56,6 +60,7 @@ "@backstage/frontend-plugin-api": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/integration-react": "workspace:^", + "@backstage/plugin-auth-react": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-search-react": "workspace:^", @@ -74,28 +79,24 @@ "react-helmet": "6.1.0", "react-use": "^17.2.4" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/core-app-api": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "@types/dompurify": "^3.0.0", "@types/event-source-polyfill": "^1.0.0", "canvas": "^2.10.2" }, - "files": [ - "dist", - "config.d.ts" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": "config.d.ts" } diff --git a/plugins/techdocs/src/client.ts b/plugins/techdocs/src/client.ts index 8680e14468..ae81ecdaaa 100644 --- a/plugins/techdocs/src/client.ts +++ b/plugins/techdocs/src/client.ts @@ -51,6 +51,18 @@ export class TechDocsClient implements TechDocsApi { this.fetchApi = options.fetchApi; } + public async getCookie(): Promise<{ expiresAt: string }> { + const apiOrigin = await this.getApiOrigin(); + const requestUrl = `${apiOrigin}/cookie`; + const response = await this.fetchApi.fetch(`${requestUrl}`, { + credentials: 'include', + }); + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + return await response.json(); + } + async getApiOrigin(): Promise { return await this.discoveryApi.getBaseUrl('techdocs'); } diff --git a/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx b/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx index 8843249291..d2947b5f64 100644 --- a/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx +++ b/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx @@ -23,7 +23,10 @@ import { ItemCardGrid, ItemCardHeader, } from '@backstage/core-components'; -import { Card, CardActions, CardContent, CardMedia } from '@material-ui/core'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import CardMedia from '@material-ui/core/CardMedia'; import React from 'react'; /** diff --git a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.tsx b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.tsx index b86dde8226..2f62c24646 100644 --- a/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.tsx +++ b/plugins/techdocs/src/home/components/Grids/EntityListDocsGrid.tsx @@ -28,7 +28,7 @@ import { useEntityList, useEntityOwnership, } from '@backstage/plugin-catalog-react'; -import { Typography } from '@material-ui/core'; +import Typography from '@material-ui/core/Typography'; import React from 'react'; /** diff --git a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx index 89ee236029..c0b39878cd 100644 --- a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; +import useCopyToClipboard from 'react-use/esm/useCopyToClipboard'; import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; diff --git a/plugins/techdocs/src/home/components/Tables/EntityListDocsTable.tsx b/plugins/techdocs/src/home/components/Tables/EntityListDocsTable.tsx index 0042cc9418..563bec4d22 100644 --- a/plugins/techdocs/src/home/components/Tables/EntityListDocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/EntityListDocsTable.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; +import useCopyToClipboard from 'react-use/esm/useCopyToClipboard'; import { capitalize } from 'lodash'; import { CodeSnippet, diff --git a/plugins/techdocs/src/home/components/Tables/actions.tsx b/plugins/techdocs/src/home/components/Tables/actions.tsx index e722a9929b..c95dd8b94c 100644 --- a/plugins/techdocs/src/home/components/Tables/actions.tsx +++ b/plugins/techdocs/src/home/components/Tables/actions.tsx @@ -17,7 +17,7 @@ import React from 'react'; import ShareIcon from '@material-ui/icons/Share'; import { DocsTableRow } from './types'; -import { withStyles } from '@material-ui/styles'; +import { withStyles } from '@material-ui/core/styles'; import Star from '@material-ui/icons/Star'; import StarBorder from '@material-ui/icons/StarBorder'; diff --git a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx index 7023560e83..70bd946256 100644 --- a/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx +++ b/plugins/techdocs/src/home/components/TechDocsCustomHome.tsx @@ -15,9 +15,9 @@ */ import React, { useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { makeStyles } from '@material-ui/core'; -import { CSSProperties } from '@material-ui/styles'; +import useAsync from 'react-use/esm/useAsync'; +import { makeStyles } from '@material-ui/core/styles'; +import { CSSProperties } from '@material-ui/styles/withStyles'; import { CATALOG_FILTER_EXISTS, catalogApiRef, diff --git a/plugins/techdocs/src/reader/components/TechDocsBuildLogs.tsx b/plugins/techdocs/src/reader/components/TechDocsBuildLogs.tsx index 01e638e59c..483c60d607 100644 --- a/plugins/techdocs/src/reader/components/TechDocsBuildLogs.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsBuildLogs.tsx @@ -15,16 +15,12 @@ */ import { LogViewer } from '@backstage/core-components'; -import { - Button, - createStyles, - Drawer, - Grid, - IconButton, - makeStyles, - Theme, - Typography, -} from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import Drawer from '@material-ui/core/Drawer'; +import Grid from '@material-ui/core/Grid'; +import IconButton from '@material-ui/core/IconButton'; +import Typography from '@material-ui/core/Typography'; +import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; import Close from '@material-ui/icons/Close'; import React, { useState } from 'react'; diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.test.tsx index f732afd31d..ed8b05c661 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.test.tsx @@ -34,7 +34,11 @@ import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; import { FlatRoutes } from '@backstage/core-app-api'; import { Page } from '@backstage/core-components'; -import { configApiRef } from '@backstage/core-plugin-api'; +import { + configApiRef, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; const mockEntityMetadata = { locationMetadata: { @@ -59,10 +63,12 @@ const mockTechDocsMetadata = { const getEntityMetadata = jest.fn(); const getTechDocsMetadata = jest.fn(); +const getCookie = jest.fn(); const techdocsApiMock = { getEntityMetadata, getTechDocsMetadata, + getCookie, }; const techdocsStorageApiMock: jest.Mocked = { @@ -74,6 +80,22 @@ const techdocsStorageApiMock: jest.Mocked = { syncEntityDocs: jest.fn(), }; +const discoveryApiMock = { + getBaseUrl: jest + .fn() + .mockResolvedValue('https://localhost:7000/api/techdocs'), +}; + +const fetchApiMock = { + fetch: jest.fn().mockResolvedValue({ + ok: true, + json: jest.fn().mockResolvedValue({ + // Expires in 10 minutes + expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(), + }), + }), +}; + const PageMock = () => { const { namespace, kind, name } = useParams(); return <>{`PageMock: ${namespace}#${kind}#${name}`}; @@ -94,6 +116,8 @@ const Wrapper = ({ children }: { children: React.ReactNode }) => { return ( ', () => { beforeEach(() => { getEntityMetadata.mockResolvedValue(mockEntityMetadata); getTechDocsMetadata.mockResolvedValue(mockTechDocsMetadata); + getCookie.mockResolvedValue({ + // Expires in 10 minutes + expiresAt: new Date(Date.now() + 10 * 60 * 1000).toISOString(), + }); }); afterEach(() => { - jest.resetAllMocks(); + jest.clearAllMocks(); }); beforeEach(() => { diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx index e81a455cea..b1b9ecb13b 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx @@ -36,6 +36,8 @@ import { useRouteRefParams, } from '@backstage/core-plugin-api'; +import { CookieAuthRefreshProvider } from '@backstage/plugin-auth-react'; + /* An explanation for the multiple ways of customizing the TechDocs reader page Please refer to this page on the microsite for the latest recommended approach: @@ -177,29 +179,33 @@ export const TechDocsReaderPage = (props: TechDocsReaderPageProps) => { // As explained above, "page" is configuration 4 and is 1 return ( - - {(page as JSX.Element) || } - + + + {(page as JSX.Element) || } + + ); } // As explained above, a render function is configuration 3 and React element is 2 return ( - - {({ metadata, entityMetadata, onReady }) => ( -
- - {children instanceof Function - ? children({ - entityRef, - techdocsMetadataValue: metadata.value, - entityMetadataValue: entityMetadata.value, - onReady, - }) - : children} - -
- )} -
+ + + {({ metadata, entityMetadata, onReady }) => ( +
+ + {children instanceof Function + ? children({ + entityRef, + techdocsMetadataValue: metadata.value, + entityMetadataValue: entityMetadata.value, + onReady, + }) + : children} + +
+ )} +
+
); }; diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx index 670653ce6b..d8e87c3686 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { renderHook, waitFor } from '@testing-library/react'; -import { ThemeProvider } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core/styles'; import { lightTheme } from '@backstage/theme'; import { TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx index f4c5ad8745..3692ed22d3 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx @@ -16,7 +16,8 @@ import React, { useCallback, useEffect } from 'react'; -import { makeStyles, Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; import { TechDocsShadowDom, diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.tsx index 744fd8c732..edcc90359d 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContentAddons.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { Portal } from '@material-ui/core'; +import Portal from '@material-ui/core/Portal'; import { useTechDocsAddons, TechDocsAddonLocations as locations, diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx index 3d12718986..de2460a543 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx @@ -16,7 +16,8 @@ import { useCallback, useEffect, useState } from 'react'; -import { useTheme, useMediaQuery } from '@material-ui/core'; +import useMediaQuery from '@material-ui/core/useMediaQuery'; +import { useTheme } from '@material-ui/core/styles'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { useAnalytics, useApi } from '@backstage/core-plugin-api'; @@ -71,7 +72,7 @@ export const useTechDocsReaderDom = ( const [dom, setDom] = useState(null); const isStyleLoading = useShadowDomStylesLoading(dom); - const updateSidebarPosition = useCallback(() => { + const updateSidebarPositionAndHeight = useCallback(() => { if (!dom) return; const sidebars = dom.querySelectorAll('.md-sidebar'); @@ -92,7 +93,18 @@ export const useTechDocsReaderDom = ( if (domTop < pageTop) { domTop = pageTop; } - element.style.top = `${Math.max(domTop, 0) + tabsHeight}px`; + + const scrollbarTopPx = Math.max(domTop, 0) + tabsHeight; + + element.style.top = `${scrollbarTopPx}px`; + + // set scrollbar height to ensure all links can be seen when content is small + const footer = dom.querySelector('.md-container > .md-footer'); + // if no footer, fallback to using the bottom of the window + const scrollbarEndPx = + footer?.getBoundingClientRect().top ?? window.innerHeight; + + element.style.height = `${scrollbarEndPx - scrollbarTopPx}px`; } // show the sidebar only after updating its position @@ -101,13 +113,17 @@ export const useTechDocsReaderDom = ( }, [dom, isMobileMedia]); useEffect(() => { - window.addEventListener('resize', updateSidebarPosition); - window.addEventListener('scroll', updateSidebarPosition, true); + window.addEventListener('resize', updateSidebarPositionAndHeight); + window.addEventListener('scroll', updateSidebarPositionAndHeight, true); return () => { - window.removeEventListener('resize', updateSidebarPosition); - window.removeEventListener('scroll', updateSidebarPosition, true); + window.removeEventListener('resize', updateSidebarPositionAndHeight); + window.removeEventListener( + 'scroll', + updateSidebarPositionAndHeight, + true, + ); }; - }, [dom, updateSidebarPosition]); + }, [dom, updateSidebarPositionAndHeight]); // dynamically set width of footer to accommodate for pinning of the sidebar const updateFooterWidth = useCallback(() => { @@ -129,10 +145,15 @@ export const useTechDocsReaderDom = ( useEffect(() => { if (!isStyleLoading) { updateFooterWidth(); - updateSidebarPosition(); + updateSidebarPositionAndHeight(); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [state, isStyleLoading, updateFooterWidth, updateSidebarPosition]); + }, [ + state, + isStyleLoading, + updateFooterWidth, + updateSidebarPositionAndHeight, + ]); // a function that performs transformations that are executed prior to adding it to the DOM const preRender = useCallback( diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index d84c5c5347..ea3cf0f334 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -17,9 +17,8 @@ import React, { PropsWithChildren, useEffect } from 'react'; import Helmet from 'react-helmet'; -import { Grid } from '@material-ui/core'; -import { Skeleton } from '@material-ui/lab'; -import { useTheme } from '@material-ui/core/styles'; +import Grid from '@material-ui/core/Grid'; +import Skeleton from '@material-ui/lab/Skeleton'; import CodeIcon from '@material-ui/icons/Code'; import { @@ -65,11 +64,6 @@ export type TechDocsReaderPageHeaderProps = PropsWithChildren<{ export const TechDocsReaderPageHeader = ( props: TechDocsReaderPageHeaderProps, ) => { - const { - palette: { - common: { white }, - }, - } = useTheme(); const { children } = props; const addons = useTechDocsAddons(); const configApi = useApi(configApiRef); @@ -142,12 +136,7 @@ export const TechDocsReaderPageHeader = ( + diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx index 85f04655fd..64faaa1ea3 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx @@ -16,15 +16,13 @@ import React, { MouseEvent, useState, useCallback } from 'react'; -import { - Box, - makeStyles, - Toolbar, - ToolbarProps, - Menu, - Tooltip, - IconButton, -} from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; +import IconButton from '@material-ui/core/IconButton'; +import Toolbar from '@material-ui/core/Toolbar'; +import { ToolbarProps } from '@material-ui/core/Toolbar'; +import Tooltip from '@material-ui/core/Tooltip'; +import Menu from '@material-ui/core/Menu'; +import Box from '@material-ui/core/Box'; import SettingsIcon from '@material-ui/icons/Settings'; import { diff --git a/plugins/techdocs/src/reader/components/TechDocsStateIndicator.tsx b/plugins/techdocs/src/reader/components/TechDocsStateIndicator.tsx index 772c92aeff..f27b8e5430 100644 --- a/plugins/techdocs/src/reader/components/TechDocsStateIndicator.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsStateIndicator.tsx @@ -15,8 +15,10 @@ */ import React from 'react'; -import { CircularProgress, Button, makeStyles } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; +import Alert from '@material-ui/lab/Alert'; import { TechDocsBuildLogs } from './TechDocsBuildLogs'; import { TechDocsNotFound } from './TechDocsNotFound'; diff --git a/plugins/techdocs/src/reader/components/useRawPage.ts b/plugins/techdocs/src/reader/components/useRawPage.ts index 311f8554a9..eee5770b6b 100644 --- a/plugins/techdocs/src/reader/components/useRawPage.ts +++ b/plugins/techdocs/src/reader/components/useRawPage.ts @@ -14,8 +14,8 @@ * limitations under the License. */ import { CompoundEntityRef } from '@backstage/catalog-model'; -import useAsyncRetry from 'react-use/lib/useAsyncRetry'; -import { AsyncState } from 'react-use/lib/useAsync'; +import useAsyncRetry from 'react-use/esm/useAsyncRetry'; +import { AsyncState } from 'react-use/esm/useAsync'; import { techdocsStorageApiRef } from '../../api'; import { useApi } from '@backstage/core-plugin-api'; diff --git a/plugins/techdocs/src/reader/components/useReaderState.ts b/plugins/techdocs/src/reader/components/useReaderState.ts index c9dc9b5dbf..251ae6e3d5 100644 --- a/plugins/techdocs/src/reader/components/useReaderState.ts +++ b/plugins/techdocs/src/reader/components/useReaderState.ts @@ -16,8 +16,8 @@ import { useApi } from '@backstage/core-plugin-api'; import { useMemo, useReducer, useRef } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import useAsyncRetry from 'react-use/lib/useAsyncRetry'; +import useAsync from 'react-use/esm/useAsync'; +import useAsyncRetry from 'react-use/esm/useAsyncRetry'; import { techdocsStorageApiRef } from '@backstage/plugin-techdocs-react'; /** diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts index 604957d5cd..a4acbd8ec8 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.test.ts @@ -18,7 +18,7 @@ import { createTestShadowDom } from '../../test-utils'; import { copyToClipboard } from './copyToClipboard'; import { lightTheme } from '@backstage/theme'; import { act, waitFor } from '@testing-library/react'; -import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; +import { default as useCopyToClipboardUnmocked } from 'react-use/esm/useCopyToClipboard'; const clipboardSpy = jest.fn(); Object.defineProperty(window.navigator, 'clipboard', { @@ -27,20 +27,17 @@ Object.defineProperty(window.navigator, 'clipboard', { }, }); -jest.mock('react-use/lib/useCopyToClipboard', () => { - const original = jest.requireActual('react-use/lib/useCopyToClipboard'); +const useCopyToClipboard = jest.mocked(useCopyToClipboardUnmocked); - return { - __esModule: true, - default: jest.fn().mockImplementation(original.default), - }; -}); +jest.mock('react-use/esm/useCopyToClipboard', () => + jest.fn().mockImplementation(() => [{ noUserInteraction: false }, jest.fn()]), +); describe('copyToClipboard', () => { it('calls navigator.clipboard.writeText when clipboard button has been clicked', async () => { - const spy = useCopyToClipboard as jest.Mock; + const spy = useCopyToClipboard; const copy = jest.fn(); - spy.mockReturnValue([{}, copy]); + spy.mockReturnValue([{ noUserInteraction: false }, copy]); const expectedClipboard = 'function foo() {return "bar";}'; diff --git a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx index 1fd9d179a3..70868baa21 100644 --- a/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx +++ b/plugins/techdocs/src/reader/transformers/copyToClipboard.tsx @@ -16,16 +16,13 @@ import React, { useState, useCallback } from 'react'; import { renderReactElement } from './renderReactElement'; -import { - withStyles, - Theme, - ThemeProvider, - SvgIcon, - Tooltip, -} from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/core/styles'; +import SvgIcon from '@material-ui/core/SvgIcon'; +import Tooltip from '@material-ui/core/Tooltip'; +import { withStyles, Theme } from '@material-ui/core/styles'; import IconButton from '@material-ui/core/IconButton'; import type { Transformer } from './transformer'; -import useCopyToClipboard from 'react-use/lib/useCopyToClipboard'; +import useCopyToClipboard from 'react-use/esm/useCopyToClipboard'; const CopyToClipboardTooltip = withStyles(theme => ({ tooltip: { diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/types.ts b/plugins/techdocs/src/reader/transformers/styles/rules/types.ts index defdc4ad90..e2747ad85a 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/types.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Theme } from '@material-ui/core'; +import { Theme } from '@material-ui/core/styles'; /** * A Backstage sidebar object that contains properties such as its pin state. diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts index 07a667ed8e..a858d17354 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { alpha, lighten } from '@material-ui/core'; +import { alpha, lighten } from '@material-ui/core/styles'; import { RuleOptions } from './types'; export default ({ theme }: RuleOptions) => ` diff --git a/plugins/techdocs/src/reader/transformers/styles/transformer.ts b/plugins/techdocs/src/reader/transformers/styles/transformer.ts index dee77fb1ed..b1b1b437c2 100644 --- a/plugins/techdocs/src/reader/transformers/styles/transformer.ts +++ b/plugins/techdocs/src/reader/transformers/styles/transformer.ts @@ -15,7 +15,7 @@ */ import { useCallback, useMemo } from 'react'; -import { useTheme } from '@material-ui/core'; +import { useTheme } from '@material-ui/core/styles'; import { useSidebarPinState } from '@backstage/core-components'; import { Transformer } from '../transformer'; import { rules } from './rules'; diff --git a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.test.tsx b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.test.tsx index 7ebdd6c340..15444fca9e 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.test.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.test.tsx @@ -15,8 +15,8 @@ */ import React from 'react'; -import { render } from '@testing-library/react'; import { TechDocsSearchResultListItem } from './TechDocsSearchResultListItem'; +import { renderInTestApp } from '@backstage/test-utils'; // Using canvas to render text.. jest.mock('react-text-truncate', () => { @@ -46,7 +46,7 @@ const validResultWithTitle = { describe('TechDocsSearchResultListItem test', () => { it('should render search doc passed in', async () => { - const { findByText } = render( + const { findByText } = await renderInTestApp( , ); @@ -61,7 +61,7 @@ describe('TechDocsSearchResultListItem test', () => { }); it('should use title if defined', async () => { - const { findByText } = render( + const { findByText } = await renderInTestApp( { }); it('should use entity title if defined', async () => { - const { findByText } = render( + const { findByText } = await renderInTestApp( , ); diff --git a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx index eae4ee7ce9..4f7deab47c 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx @@ -15,7 +15,9 @@ */ import React, { PropsWithChildren, ReactNode } from 'react'; -import { ListItemIcon, ListItemText, makeStyles } from '@material-ui/core'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemText from '@material-ui/core/ListItemText'; +import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; import { Link } from '@backstage/core-components'; import { ResultHighlight } from '@backstage/plugin-search-common'; diff --git a/plugins/todo-backend/.eslintrc.js b/plugins/todo-backend/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/todo-backend/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/todo-backend/.snyk b/plugins/todo-backend/.snyk deleted file mode 100644 index da6c67e8e2..0000000000 --- a/plugins/todo-backend/.snyk +++ /dev/null @@ -1,10 +0,0 @@ -# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. -version: v1.22.1 -# ignores vulnerabilities until expiry date; change duration by modifying expiry date -ignore: - SNYK-JS-ANSIREGEX-1583908: - - 'leasot@12.0.0 > strip-ansi@6.0.0 > ansi-regex@5.0.0': - reason: This vulnerability only affects the leasot CLI, which is not used by todo backend - expires: 2022-03-06T17:18:55.019Z - created: 2021-09-06T17:18:55.027Z -patch: {} diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md deleted file mode 100644 index d86768dc91..0000000000 --- a/plugins/todo-backend/CHANGELOG.md +++ /dev/null @@ -1,1534 +0,0 @@ -# @backstage/plugin-todo-backend - -## 0.3.8-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/repo-tools@0.6.0-next.3 - - @backstage/integration@1.9.0-next.1 - - @backstage/plugin-catalog-node@1.6.2-next.3 - - @backstage/backend-openapi-utils@0.1.3-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/catalog-client@1.6.0-next.1 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.3.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/repo-tools@0.6.0-next.2 - - @backstage/backend-common@0.21.0-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/backend-openapi-utils@0.1.3-next.2 - - @backstage/plugin-catalog-node@1.6.2-next.2 - - @backstage/config@1.1.1 - - @backstage/catalog-client@1.6.0-next.1 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - - @backstage/integration@1.9.0-next.0 - -## 0.3.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/catalog-client@1.6.0-next.1 - - @backstage/backend-plugin-api@0.6.10-next.1 - - @backstage/backend-common@0.21.0-next.1 - - @backstage/integration@1.9.0-next.0 - - @backstage/backend-openapi-utils@0.1.3-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-catalog-node@1.6.2-next.1 - -## 0.3.8-next.0 - -### Patch Changes - -- 126c2f9: Updates the OpenAPI spec to use plugin as `info.title` instead of package name. -- 04907c3: Updates the OpenAPI specification title to plugin ID instead of package name. -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/backend-openapi-utils@0.1.3-next.0 - - @backstage/catalog-client@1.6.0-next.0 - - @backstage/plugin-catalog-node@1.6.2-next.0 - - @backstage/backend-plugin-api@0.6.10-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0 - -## 0.3.7 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/catalog-client@1.5.2 - - @backstage/backend-plugin-api@0.6.9 - - @backstage/backend-openapi-utils@0.1.2 - - @backstage/plugin-catalog-node@1.6.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0 - -## 0.3.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - - @backstage/backend-common@0.20.1-next.2 - - @backstage/backend-openapi-utils@0.1.2-next.2 - - @backstage/plugin-catalog-node@1.6.1-next.2 - -## 0.3.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/integration@1.8.0 - - @backstage/config@1.1.1 - - @backstage/backend-openapi-utils@0.1.2-next.1 - - @backstage/backend-plugin-api@0.6.9-next.1 - - @backstage/catalog-client@1.5.2-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/plugin-catalog-node@1.6.1-next.1 - -## 0.3.7-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/catalog-client@1.5.2-next.0 - - @backstage/backend-openapi-utils@0.1.2-next.0 - - @backstage/plugin-catalog-node@1.6.1-next.0 - - @backstage/backend-plugin-api@0.6.9-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0 - -## 0.3.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/plugin-catalog-node@1.6.0 - - @backstage/catalog-client@1.5.0 - - @backstage/backend-openapi-utils@0.1.1 - - @backstage/integration@1.8.0 - - @backstage/backend-plugin-api@0.6.8 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.3.6-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-openapi-utils@0.1.1-next.3 - - @backstage/backend-plugin-api@0.6.8-next.3 - - @backstage/catalog-client@1.5.0-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0-next.1 - - @backstage/plugin-catalog-node@1.6.0-next.3 - -## 0.3.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-node@1.6.0-next.2 - - @backstage/backend-common@0.20.0-next.2 - - @backstage/catalog-client@1.5.0-next.1 - - @backstage/backend-openapi-utils@0.1.1-next.2 - - @backstage/backend-plugin-api@0.6.8-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/integration@1.8.0-next.1 - -## 0.3.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.5.0-next.0 - - @backstage/integration@1.8.0-next.1 - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-openapi-utils@0.1.1-next.1 - - @backstage/backend-plugin-api@0.6.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-catalog-node@1.5.1-next.1 - -## 0.3.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-openapi-utils@0.1.1-next.0 - - @backstage/integration@1.8.0-next.0 - - @backstage/plugin-catalog-node@1.5.1-next.0 - - @backstage/backend-plugin-api@0.6.8-next.0 - - @backstage/catalog-client@1.4.6 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.3.5 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-node@1.5.0 - - @backstage/integration@1.7.2 - - @backstage/backend-common@0.19.9 - - @backstage/backend-plugin-api@0.6.7 - - @backstage/catalog-client@1.4.6 - - @backstage/backend-openapi-utils@0.1.0 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.3.5-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - - @backstage/backend-common@0.19.9-next.2 - - @backstage/backend-openapi-utils@0.1.0-next.2 - - @backstage/plugin-catalog-node@1.5.0-next.2 - -## 0.3.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-node@1.5.0-next.1 - - @backstage/integration@1.7.2-next.0 - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-openapi-utils@0.1.0-next.1 - - @backstage/backend-plugin-api@0.6.7-next.1 - - @backstage/catalog-client@1.4.5 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.3.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-openapi-utils@0.1.0-next.0 - - @backstage/backend-common@0.19.9-next.0 - - @backstage/integration@1.7.1 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/catalog-client@1.4.5 - - @backstage/catalog-model@1.4.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-catalog-node@1.4.8-next.0 - -## 0.3.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/integration@1.7.1 - - @backstage/plugin-catalog-node@1.4.7 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/backend-openapi-utils@0.0.5 - - @backstage/backend-plugin-api@0.6.6 - - @backstage/catalog-client@1.4.5 - - @backstage/config@1.1.1 - -## 0.3.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/integration@1.7.1-next.1 - - @backstage/errors@1.2.3-next.0 - - @backstage/backend-openapi-utils@0.0.5-next.0 - - @backstage/plugin-catalog-node@1.4.7-next.2 - - @backstage/backend-plugin-api@0.6.6-next.2 - - @backstage/catalog-client@1.4.5-next.0 - - @backstage/config@1.1.1-next.0 - -## 0.3.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-node@1.4.6-next.1 - - @backstage/backend-common@0.19.7-next.1 - - @backstage/backend-plugin-api@0.6.5-next.1 - - @backstage/config@1.1.0 - - @backstage/backend-openapi-utils@0.0.4 - - @backstage/catalog-client@1.4.4 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/integration@1.7.1-next.0 - -## 0.3.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.7.1-next.0 - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/backend-openapi-utils@0.0.4 - - @backstage/backend-plugin-api@0.6.5-next.0 - - @backstage/catalog-client@1.4.4 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/plugin-catalog-node@1.4.6-next.0 - -## 0.3.1 - -### Minor Changes - -- 71114ac50e02: **BREAKING**: The export for the new backend system has been moved to be the `default` export. - - For example, if you are currently importing the plugin using the following pattern: - - ```ts - import { examplePlugin } from '@backstage/plugin-example-backend'; - - backend.add(examplePlugin); - ``` - - It should be migrated to this: - - ```ts - backend.add(import('@backstage/plugin-example-backend')); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/catalog-client@1.4.4 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/integration@1.7.0 - - @backstage/backend-plugin-api@0.6.3 - - @backstage/plugin-catalog-node@1.4.4 - - @backstage/backend-openapi-utils@0.0.4 - -## 0.3.0 - -Skipped due to publishing issues. - -## 0.3.0-next.3 - -### Minor Changes - -- 71114ac50e02: **BREAKING**: The export for the new backend system has been moved to be the `default` export. - - For example, if you are currently importing the plugin using the following pattern: - - ```ts - import { examplePlugin } from '@backstage/plugin-example-backend'; - - backend.add(examplePlugin); - ``` - - It should be migrated to this: - - ```ts - backend.add(import('@backstage/plugin-example-backend')); - ``` - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.4.4-next.2 - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/integration@1.7.0-next.3 - - @backstage/backend-plugin-api@0.6.3-next.3 - - @backstage/backend-common@0.19.5-next.3 - - @backstage/backend-openapi-utils@0.0.4-next.0 - - @backstage/plugin-catalog-node@1.4.4-next.3 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/plugin-catalog-node@1.4.4-next.2 - - @backstage/integration@1.7.0-next.2 - - @backstage/backend-plugin-api@0.6.3-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/backend-openapi-utils@0.0.3 - - @backstage/catalog-client@1.4.4-next.1 - - @backstage/errors@1.2.1 - -## 0.2.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/integration@1.7.0-next.1 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/backend-plugin-api@0.6.3-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/plugin-catalog-node@1.4.4-next.1 - - @backstage/catalog-client@1.4.4-next.0 - - @backstage/backend-openapi-utils@0.0.3 - - @backstage/errors@1.2.1 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/integration@1.7.0-next.0 - - @backstage/backend-openapi-utils@0.0.3 - - @backstage/backend-plugin-api@0.6.2-next.0 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-node@1.4.3-next.0 - -## 0.2.0 - -### Minor Changes - -- ebeb77586975: Now performs request validation based on OpenAPI schema through `@backstage/backend-openapi-utils`. Error responses for invalid input, like `"a"` instead of a number, may have changed. - -### Patch Changes - -- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config` -- ad3fb5401729: Fixed a bug where filter queries from the frontend would always fail validation. -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/backend-plugin-api@0.6.0 - - @backstage/backend-openapi-utils@0.0.3 - - @backstage/plugin-catalog-node@1.4.1 - - @backstage/integration@1.6.0 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.2.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.0-next.2 - - @backstage/backend-common@0.19.2-next.2 - - @backstage/plugin-catalog-node@1.4.1-next.2 - -## 0.2.0-next.1 - -### Patch Changes - -- 629cbd194a87: Use `coreServices.rootConfig` instead of `coreService.config` -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/backend-openapi-utils@0.0.3-next.1 - - @backstage/plugin-catalog-node@1.4.1-next.1 - - @backstage/backend-plugin-api@0.6.0-next.1 - - @backstage/integration@1.5.1 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.2.0-next.0 - -### Minor Changes - -- ebeb77586975: Now performs request validation based on OpenAPI schema through `@backstage/backend-openapi-utils`. Error responses for invalid input, like `"a"` instead of a number, may have changed. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-openapi-utils@0.0.3-next.0 - - @backstage/backend-common@0.19.2-next.0 - - @backstage/backend-plugin-api@0.5.5-next.0 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/integration@1.5.1 - - @backstage/plugin-catalog-node@1.4.1-next.0 - -## 0.1.44 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/plugin-catalog-node@1.4.0 - - @backstage/backend-plugin-api@0.5.4 - - @backstage/catalog-client@1.4.3 - - @backstage/catalog-model@1.4.1 - - @backstage/config@1.0.8 - - @backstage/integration@1.5.1 - -## 0.1.44-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/plugin-catalog-node@1.4.0-next.0 - - @backstage/backend-plugin-api@0.5.4-next.0 - - @backstage/catalog-client@1.4.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/config@1.0.8 - - @backstage/integration@1.5.1-next.0 - -## 0.1.43 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/catalog-client@1.4.2 - - @backstage/integration@1.5.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - - @backstage/backend-plugin-api@0.5.3 - - @backstage/plugin-catalog-node@1.3.7 - - @backstage/config@1.0.8 - -## 0.1.43-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/backend-plugin-api@0.5.3-next.2 - - @backstage/catalog-client@1.4.2-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.2.0-next.0 - - @backstage/integration@1.5.0-next.0 - - @backstage/plugin-catalog-node@1.3.7-next.2 - -## 0.1.43-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/integration@1.5.0-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/backend-plugin-api@0.5.3-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/plugin-catalog-node@1.3.7-next.1 - - @backstage/catalog-client@1.4.2-next.1 - - @backstage/config@1.0.7 - -## 0.1.43-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.4.2-next.0 - - @backstage/plugin-catalog-node@1.3.7-next.0 - - @backstage/backend-common@0.18.6-next.0 - - @backstage/integration@1.4.5 - - @backstage/config@1.0.7 - - @backstage/backend-plugin-api@0.5.3-next.0 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.1.42 - -### Patch Changes - -- 901f1ada325: Added OpenAPI schema -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/integration@1.4.5 - - @backstage/plugin-catalog-node@1.3.6 - - @backstage/backend-plugin-api@0.5.2 - - @backstage/catalog-client@1.4.1 - - @backstage/catalog-model@1.3.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.42-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/plugin-catalog-node@1.3.6-next.1 - - @backstage/backend-plugin-api@0.5.2-next.1 - - @backstage/config@1.0.7 - -## 0.1.42-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/integration@1.4.5-next.0 - - @backstage/plugin-catalog-node@1.3.6-next.0 - - @backstage/backend-plugin-api@0.5.2-next.0 - - @backstage/catalog-client@1.4.1 - - @backstage/catalog-model@1.3.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.41 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/catalog-client@1.4.1 - - @backstage/catalog-model@1.3.0 - - @backstage/integration@1.4.4 - - @backstage/plugin-catalog-node@1.3.5 - - @backstage/backend-plugin-api@0.5.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.1.41-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/backend-common@0.18.4-next.2 - - @backstage/backend-plugin-api@0.5.1-next.2 - - @backstage/catalog-client@1.4.1-next.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/integration@1.4.4-next.0 - - @backstage/plugin-catalog-node@1.3.5-next.3 - -## 0.1.41-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/catalog-client@1.4.1-next.0 - - @backstage/backend-plugin-api@0.5.1-next.2 - - @backstage/catalog-model@1.2.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/integration@1.4.4-next.0 - - @backstage/plugin-catalog-node@1.3.5-next.2 - -## 0.1.41-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.4.4-next.0 - - @backstage/backend-common@0.18.4-next.1 - - @backstage/backend-plugin-api@0.5.1-next.1 - - @backstage/catalog-client@1.4.0 - - @backstage/catalog-model@1.2.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/plugin-catalog-node@1.3.5-next.1 - -## 0.1.41-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/integration@1.4.3 - - @backstage/backend-plugin-api@0.5.1-next.0 - - @backstage/catalog-client@1.4.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/plugin-catalog-node@1.3.5-next.0 - -## 0.1.40 - -### Patch Changes - -- 4120513412a: todo-backend is now exposed as a plugin which uses the new plugin system -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/catalog-client@1.4.0 - - @backstage/backend-common@0.18.3 - - @backstage/errors@1.1.5 - - @backstage/plugin-catalog-node@1.3.4 - - @backstage/backend-plugin-api@0.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/integration@1.4.3 - - @backstage/config@1.0.7 - -## 0.1.40-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/backend-plugin-api@0.4.1-next.2 - - @backstage/plugin-catalog-node@1.3.4-next.2 - - @backstage/config@1.0.7-next.0 - - @backstage/integration@1.4.3-next.0 - -## 0.1.40-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/backend-common@0.18.3-next.1 - - @backstage/catalog-client@1.4.0-next.1 - - @backstage/integration@1.4.3-next.0 - - @backstage/backend-plugin-api@0.4.1-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/catalog-model@1.2.1-next.1 - - @backstage/plugin-catalog-node@1.3.4-next.1 - -## 0.1.40-next.0 - -### Patch Changes - -- 4120513412: todo-backend is now exposed as a plugin which uses the new plugin system -- Updated dependencies - - @backstage/catalog-client@1.4.0-next.0 - - @backstage/backend-plugin-api@0.4.1-next.0 - - @backstage/backend-common@0.18.3-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/plugin-catalog-node@1.3.4-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - -## 0.1.39 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/catalog-model@1.2.0 - - @backstage/catalog-client@1.3.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - -## 0.1.39-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/catalog-client@1.3.1-next.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - -## 0.1.39-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/catalog-client@1.3.1-next.0 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - -## 0.1.39-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/backend-common@0.18.2-next.0 - - @backstage/catalog-client@1.3.1-next.0 - -## 0.1.37 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/catalog-model@1.1.5 - - @backstage/catalog-client@1.3.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2 - -## 0.1.37-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/catalog-client@1.3.0-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2-next.0 - -## 0.1.37-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/catalog-client@1.3.0-next.1 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.2-next.0 - -## 0.1.37-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/catalog-client@1.3.0-next.0 - - @backstage/backend-common@0.17.0 - - @backstage/config@1.0.5 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.1 - -## 0.1.36 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/catalog-client@1.2.0 - - @backstage/backend-common@0.17.0 - - @backstage/errors@1.1.4 - - @backstage/integration@1.4.1 - - @backstage/catalog-model@1.1.4 - - @backstage/config@1.0.5 - -## 0.1.36-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.3 - - @backstage/catalog-client@1.2.0-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/integration@1.4.1-next.1 - -## 0.1.36-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/catalog-client@1.2.0-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/integration@1.4.1-next.1 - -## 0.1.36-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/integration@1.4.1-next.1 - - @backstage/catalog-client@1.2.0-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.1.36-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/catalog-client@1.2.0-next.0 - - @backstage/backend-common@0.16.1-next.0 - - @backstage/integration@1.4.1-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - -## 0.1.35 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/integration@1.4.0 - - @backstage/catalog-model@1.1.3 - - @backstage/catalog-client@1.1.2 - - @backstage/config@1.0.4 - - @backstage/errors@1.1.3 - -## 0.1.35-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/catalog-client@1.1.2-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/integration@1.4.0-next.0 - -## 0.1.35-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/integration@1.4.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/catalog-client@1.1.2-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.1.34 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/backend-common@0.15.2 - - @backstage/catalog-client@1.1.1 - - @backstage/config@1.0.3 - - @backstage/errors@1.1.2 - - @backstage/integration@1.3.2 - -## 0.1.34-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.2 - - @backstage/catalog-client@1.1.1-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/integration@1.3.2-next.2 - -## 0.1.34-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.1.1-next.1 - - @backstage/backend-common@0.15.2-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/integration@1.3.2-next.1 - -## 0.1.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/catalog-client@1.1.1-next.0 - - @backstage/backend-common@0.15.2-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/integration@1.3.2-next.0 - -## 0.1.33 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/integration@1.3.1 - - @backstage/catalog-client@1.1.0 - - @backstage/catalog-model@1.1.1 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - -## 0.1.33-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@1.1.0-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/integration@1.3.1-next.2 - - @backstage/backend-common@0.15.1-next.3 - -## 0.1.33-next.1 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.2 - - @backstage/integration@1.3.1-next.1 - - @backstage/catalog-client@1.0.5-next.1 - -## 0.1.33-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - - @backstage/catalog-client@1.0.5-next.0 - - @backstage/integration@1.3.1-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.3 - - @backstage/catalog-client@1.0.4-next.2 - - @backstage/integration@1.2.2-next.3 - - @backstage/catalog-model@1.1.0-next.3 - -## 0.1.31-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/backend-common@0.14.1-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/catalog-client@1.0.4-next.1 - - @backstage/integration@1.2.2-next.1 - -## 0.1.31-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/integration@1.2.2-next.0 - - @backstage/catalog-client@1.0.4-next.0 - -## 0.1.30 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/backend-common@0.14.0 - - @backstage/integration@1.2.1 - - @backstage/catalog-client@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.1.30-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - - @backstage/integration@1.2.1-next.2 - -## 0.1.30-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/backend-common@0.13.6-next.1 - - @backstage/catalog-client@1.0.3-next.0 - - @backstage/integration@1.2.1-next.1 - - @backstage/catalog-model@1.0.3-next.0 - -## 0.1.30-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.6-next.0 - - @backstage/integration@1.2.1-next.0 - -## 0.1.29 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/integration@1.2.0 - - @backstage/config@1.0.1 - - @backstage/catalog-client@1.0.2 - - @backstage/catalog-model@1.0.2 - -## 0.1.29-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/config@1.0.1-next.0 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/integration@1.2.0-next.1 - - @backstage/catalog-client@1.0.2-next.0 - -## 0.1.29-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - - @backstage/integration@1.2.0-next.0 - -## 0.1.28 - -### Patch Changes - -- 5da036264b: Fix method to get source-location. -- Updated dependencies - - @backstage/integration@1.1.0 - - @backstage/catalog-model@1.0.1 - - @backstage/backend-common@0.13.2 - - @backstage/catalog-client@1.0.1 - -## 0.1.28-next.2 - -### Patch Changes - -- 5da036264b: Fix method to get source-location. -- Updated dependencies - - @backstage/backend-common@0.13.2-next.2 - - @backstage/integration@1.1.0-next.2 - -## 0.1.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@1.1.0-next.1 - - @backstage/backend-common@0.13.2-next.1 - -## 0.1.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/backend-common@0.13.2-next.0 - - @backstage/integration@1.0.1-next.0 - - @backstage/catalog-client@1.0.1-next.0 - -## 0.1.27 - -### Patch Changes - -- 89c7e47967: Minor README update -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/catalog-model@1.0.0 - - @backstage/integration@1.0.0 - - @backstage/catalog-client@1.0.0 - - @backstage/config@1.0.0 - - @backstage/errors@1.0.0 - -## 0.1.26 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0 - - @backstage/catalog-model@0.13.0 - - @backstage/catalog-client@0.9.0 - -## 0.1.26-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 - - @backstage/catalog-model@0.13.0-next.0 - - @backstage/catalog-client@0.9.0-next.0 - -## 0.1.25 - -### Patch Changes - -- 899f196af5: Use `getEntityByRef` instead of `getEntityByName` in the catalog client -- 36aa63022b: Use `CompoundEntityRef` instead of `EntityName`, and `getCompoundEntityRef` instead of `getEntityName`, from `@backstage/catalog-model`. -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/catalog-client@0.8.0 - - @backstage/backend-common@0.12.0 - - @backstage/integration@0.8.0 - -## 0.1.24 - -### Patch Changes - -- 67a7c02d26: Remove usages of `EntityRef` and `parseEntityName` from `@backstage/catalog-model` -- 6e1cbc12a6: Updated according to the new `getEntityFacets` catalog API method -- be9e010da0: Add support to exclude certain folders in `todo` plugin. - - You can add function by configuring your own exclusion logic, for example: - - ```ts - import { - TodoScmReader, - createTodoParser, - } from '@backstage/plugin-todo-backend'; - - // ... - - const todoReader = TodoScmReader.fromConfig(config, { - logger, - reader, - filePathFilter: (filePath: string): boolean => { - ... - YOUR LOGIC HERE - }, - }); - ``` - -- Updated dependencies - - @backstage/backend-common@0.11.0 - - @backstage/catalog-model@0.11.0 - - @backstage/catalog-client@0.7.2 - - @backstage/integration@0.7.5 - -## 0.1.23 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/backend-common@0.10.9 - - @backstage/catalog-client@0.7.1 - - @backstage/catalog-model@0.10.1 - - @backstage/config@0.1.15 - - @backstage/errors@0.2.2 - - @backstage/integration@0.7.4 - -## 0.1.22 - -### Patch Changes - -- c77c5c7eb6: Added `backstage.role` to `package.json` -- edbc03814a: Replace usage of `serializeEntityRef` with `stringifyEntityRef` -- deaf6065db: Adapt to the new `CatalogApi.getLocationByRef` -- 216725b434: Updated to use new names for `parseLocationRef` and `stringifyLocationRef` -- 27eccab216: Replaces use of deprecated catalog-model constants. -- Updated dependencies - - @backstage/backend-common@0.10.8 - - @backstage/catalog-client@0.7.0 - - @backstage/errors@0.2.1 - - @backstage/integration@0.7.3 - - @backstage/catalog-model@0.10.0 - - @backstage/config@0.1.14 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-client@0.6.0 - - @backstage/backend-common@0.10.7 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.7-next.0 - -## 0.1.20 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6 - -## 0.1.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6-next.0 - -## 0.1.19 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@0.7.2 - - @backstage/backend-common@0.10.4 - - @backstage/config@0.1.13 - - @backstage/catalog-model@0.9.10 - - @backstage/catalog-client@0.5.5 - -## 0.1.19-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4-next.0 - - @backstage/config@0.1.13-next.0 - - @backstage/catalog-model@0.9.10-next.0 - - @backstage/catalog-client@0.5.5-next.0 - - @backstage/integration@0.7.2-next.0 - -## 0.1.18 - -### Patch Changes - -- 2260702efd: Properly exported all referenced types -- Updated dependencies - - @backstage/config@0.1.12 - - @backstage/integration@0.7.1 - - @backstage/backend-common@0.10.3 - - @backstage/errors@0.2.0 - - @backstage/catalog-client@0.5.4 - - @backstage/catalog-model@0.9.9 - -## 0.1.17 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.1 - - @backstage/integration@0.7.0 - -## 0.1.16 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.0 - - @backstage/catalog-client@0.5.3 - -## 0.1.15 - -### Patch Changes - -- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly -- Updated dependencies - - @backstage/backend-common@0.9.13 - -## 0.1.14 - -### Patch Changes - -- b055a6addc: Align on usage of `cross-fetch` vs `node-fetch` in frontend vs backend packages, and remove some unnecessary imports of either one of them -- Updated dependencies - - @backstage/integration@0.6.10 - - @backstage/backend-common@0.9.12 - -## 0.1.13 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.9.4 - - @backstage/backend-common@0.9.6 - - @backstage/catalog-client@0.5.0 - - @backstage/integration@0.6.7 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@0.6.5 - - @backstage/catalog-client@0.4.0 - - @backstage/catalog-model@0.9.3 - - @backstage/backend-common@0.9.4 - - @backstage/config@0.1.10 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.9.0 - - @backstage/integration@0.6.2 - - @backstage/config@0.1.8 - -## 0.1.10 - -### Patch Changes - -- 0b34dc7a3: Ignore images and files that are larger than 200KB. -- Updated dependencies - - @backstage/backend-common@0.8.10 - - @backstage/config@0.1.7 - - @backstage/integration@0.6.1 - -## 0.1.9 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@0.6.0 - - @backstage/backend-common@0.8.9 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/integration@0.5.8 - - @backstage/catalog-model@0.9.0 - - @backstage/backend-common@0.8.5 - - @backstage/catalog-client@0.3.16 - -## 0.1.7 - -### Patch Changes - -- a6a0ba7ff: Bump `leasot` dependency from 11.5.0 to 12.0.0, removing support for Node.js version 10. -- Updated dependencies - - @backstage/backend-common@0.8.3 - - @backstage/catalog-model@0.8.3 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies [0fd4ea443] -- Updated dependencies [add62a455] -- Updated dependencies [704875e26] - - @backstage/integration@0.5.4 - - @backstage/catalog-client@0.3.12 - - @backstage/catalog-model@0.8.0 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies [22fd8ce2a] -- Updated dependencies [10c008a3a] -- Updated dependencies [f9fb4a205] -- Updated dependencies [16be1d093] - - @backstage/backend-common@0.8.0 - - @backstage/catalog-model@0.7.9 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies [e0bfd3d44] -- Updated dependencies [38ca05168] -- Updated dependencies [d8b81fd28] -- Updated dependencies [d1b1306d9] - - @backstage/backend-common@0.7.0 - - @backstage/integration@0.5.2 - - @backstage/catalog-model@0.7.8 - - @backstage/config@0.1.5 - - @backstage/catalog-client@0.3.11 - -## 0.1.3 - -### Patch Changes - -- 676ede643: Added the `getOriginLocationByEntity` and `removeLocationById` methods to the catalog client -- Updated dependencies [676ede643] -- Updated dependencies [b196a4569] -- Updated dependencies [8488a1a96] -- Updated dependencies [37e3a69f5] - - @backstage/catalog-client@0.3.9 - - @backstage/catalog-model@0.7.5 - - @backstage/backend-common@0.6.1 - -## 0.1.2 - -### Patch Changes - -- 36d933ec5: Forward authorization on todo backend requests - -## 0.1.1 - -### Patch Changes - -- Updated dependencies [8686eb38c] -- Updated dependencies [8686eb38c] -- Updated dependencies [0434853a5] -- Updated dependencies [8686eb38c] - - @backstage/catalog-client@0.3.8 - - @backstage/backend-common@0.6.0 - - @backstage/config@0.1.4 diff --git a/plugins/todo-backend/README.md b/plugins/todo-backend/README.md deleted file mode 100644 index 0aec607b93..0000000000 --- a/plugins/todo-backend/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# @backstage/plugin-todo-backend - -Backend for the `@backstage/plugin-todo` plugin. Assists in scanning for and listing `// TODO` comments in source code repositories. - -## Installation - -Install the `@backstage/plugin-todo-backend` package in your backend packages, and then integrate the plugin using the following default setup for `src/plugins/todo.ts`: - -```ts -import { Router } from 'express'; -import { CatalogClient } from '@backstage/catalog-client'; -import { - createRouter, - TodoReaderService, - TodoScmReader, -} from '@backstage/plugin-todo-backend'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const todoReader = TodoScmReader.fromConfig(env.config, { - logger: env.logger, - reader: env.reader, - }); - - const catalogClient = new CatalogClient({ - discoveryApi: env.discovery, - }); - - const todoService = new TodoReaderService({ - todoReader, - catalogClient, - }); - - return await createRouter({ todoService }); -} -``` - -And then add to `packages/backend/src/index.ts`: - -```js -// In packages/backend/src/index.ts -import todo from './plugins/todo'; -// ... -async function main() { - // ... - const todoEnv = useHotMemoize(module, () => createEnv('todo')); - // ... - apiRouter.use('/todo', await todo(todoEnv)); -``` - -## Scanned Files - -The included `TodoReaderService` and `TodoScmReader` works by getting the entity source location from the catalog. - -The location source code is determined automatically. In case of the source code of the component is not in the same place of the entity YAML file, you can explicitly set the value of the [`backstage.io/source-location`](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiosource-location) annotation of the entity, and if that is missing it falls back to the [`backstage.io/managed-by-location `](https://backstage.io/docs/features/software-catalog/well-known-annotations#backstageiomanaged-by-location) annotation. Only `url` locations are currently supported, meaning locally configured `file` locations won't work. Also note that dot-files and folders are ignored. - -## Parser Configuration - -The `TodoScmReader` accepts a `TodoParser` option, which can be used to configure your own parser. The default one is based on [Leasot](https://github.com/pgilad/leasot) and supports a wide range of languages. You can add to the list of supported tags by configuring your own version of the built-in parser, for example: - -```ts -import { - TodoScmReader, - createTodoParser, -} from '@backstage/plugin-todo-backend'; - -// ... - -const todoReader = TodoScmReader.fromConfig(env.config, { - logger: env.logger, - reader: env.reader, - parser: createTodoParser({ - additionalTags: ['NOTE', 'XXX'], - }), -}); -``` diff --git a/plugins/todo-backend/api-report.md b/plugins/todo-backend/api-report.md deleted file mode 100644 index 3244b397eb..0000000000 --- a/plugins/todo-backend/api-report.md +++ /dev/null @@ -1,156 +0,0 @@ -## API Report File for "@backstage/plugin-todo-backend" - -> 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 { CatalogApi } from '@backstage/catalog-client'; -import { CompoundEntityRef } from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; -import express from 'express'; -import { Logger } from 'winston'; -import { ScmIntegrations } from '@backstage/integration'; -import { ServiceRef } from '@backstage/backend-plugin-api'; -import { UrlReader } from '@backstage/backend-common'; - -// @public (undocumented) -export function createRouter(options: RouterOptions): Promise; - -// @public (undocumented) -export function createTodoParser(options?: TodoParserOptions): TodoParser; - -// @public (undocumented) -export type ListTodosRequest = { - entity?: CompoundEntityRef; - offset?: number; - limit?: number; - orderBy?: { - field: 'text' | 'tag' | 'author' | 'viewUrl' | 'repoFilePath'; - direction: 'asc' | 'desc'; - }; - filters?: { - field: 'text' | 'tag' | 'author' | 'viewUrl' | 'repoFilePath'; - value: string; - }[]; -}; - -// @public (undocumented) -export type ListTodosResponse = { - items: TodoItem[]; - totalCount: number; - offset: number; - limit: number; -}; - -// @public (undocumented) -export type ReadTodosOptions = { - url: string; -}; - -// @public (undocumented) -export type ReadTodosResult = { - items: TodoItem[]; -}; - -// @public (undocumented) -export interface RouterOptions { - // (undocumented) - todoService: TodoService; -} - -// @public (undocumented) -export type TodoItem = { - text: string; - tag: string; - author?: string; - viewUrl?: string; - lineNumber?: number; - repoFilePath?: string; -}; - -// @public (undocumented) -export type TodoParser = (ctx: TodoParserContext) => TodoParserResult[]; - -// @public (undocumented) -export type TodoParserContext = { - content: string; - path: string; -}; - -// @public (undocumented) -export type TodoParserOptions = { - additionalTags?: string[]; -}; - -// @public (undocumented) -export type TodoParserResult = { - text: string; - tag: string; - author?: string; - lineNumber: number; -}; - -// @public -const todoPlugin: () => BackendFeature; -export default todoPlugin; - -// @public (undocumented) -export interface TodoReader { - readTodos(options: ReadTodosOptions): Promise; -} - -// @public (undocumented) -export class TodoReaderService implements TodoService { - constructor(options: TodoReaderServiceOptions); - // (undocumented) - listTodos( - req: ListTodosRequest, - options?: { - token?: string; - }, - ): Promise; -} - -// @public (undocumented) -export type TodoReaderServiceOptions = { - todoReader: TodoReader; - catalogClient: CatalogApi; - maxPageSize?: number; - defaultPageSize?: number; -}; - -// @public (undocumented) -export const todoReaderServiceRef: ServiceRef; - -// @public (undocumented) -export class TodoScmReader implements TodoReader { - constructor(options: TodoScmReaderOptions); - // (undocumented) - static fromConfig( - config: Config, - options: Omit, - ): TodoScmReader; - // (undocumented) - readTodos(options: ReadTodosOptions): Promise; -} - -// @public (undocumented) -export type TodoScmReaderOptions = { - logger: Logger; - reader: UrlReader; - integrations: ScmIntegrations; - parser?: TodoParser; - filePathFilter?: (filePath: string) => boolean; -}; - -// @public (undocumented) -export interface TodoService { - // (undocumented) - listTodos( - req: ListTodosRequest, - options?: { - token?: string; - }, - ): Promise; -} -``` diff --git a/plugins/todo-backend/catalog-info.yaml b/plugins/todo-backend/catalog-info.yaml deleted file mode 100644 index 6406a6baae..0000000000 --- a/plugins/todo-backend/catalog-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-todo-backend - title: '@backstage/plugin-todo-backend' - description: >- - A Backstage backend plugin that lets you browse TODO comments in your source - code -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: maintainers diff --git a/plugins/todo-backend/knip-report.md b/plugins/todo-backend/knip-report.md deleted file mode 100644 index 76a01fd533..0000000000 --- a/plugins/todo-backend/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused dependencies (2) - -| Name | Location | Severity | -| :-------------------- | :----------- | :------- | -| @backstage/repo-tools | package.json | error | -| yn | package.json | error | - diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json deleted file mode 100644 index 1c16436a12..0000000000 --- a/plugins/todo-backend/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@backstage/plugin-todo-backend", - "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.3.8-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/todo-backend" - }, - "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", - "generate": "backstage-repo-tools package schema openapi generate --server" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/backend-openapi-utils": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/catalog-client": "workspace:^", - "@backstage/catalog-model": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/integration": "workspace:^", - "@backstage/plugin-catalog-node": "workspace:^", - "@backstage/repo-tools": "workspace:^", - "@types/express": "^4.17.6", - "express": "^4.17.1", - "leasot": "^12.0.0", - "winston": "^3.2.1", - "yn": "^4.0.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/supertest": "^2.0.8", - "supertest": "^6.1.3" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/todo-backend/src/index.ts b/plugins/todo-backend/src/index.ts deleted file mode 100644 index 58a8336ca2..0000000000 --- a/plugins/todo-backend/src/index.ts +++ /dev/null @@ -1,25 +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. - */ - -/** - * A Backstage backend plugin that lets you browse TODO comments in your source code - * - * @packageDocumentation - */ - -export * from './lib'; -export * from './service'; -export { todoPlugin as default } from './plugin'; diff --git a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.test.ts b/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.test.ts deleted file mode 100644 index 1f2b79a55f..0000000000 --- a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.test.ts +++ /dev/null @@ -1,280 +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 { - getVoidLogger, - ReadTreeResponse, - UrlReader, -} from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { NotFoundError, NotModifiedError } from '@backstage/errors'; -import { ScmIntegrations } from '@backstage/integration'; -import { createTodoParser } from './createTodoParser'; -import { TodoScmReader } from './TodoScmReader'; - -function mockReader(): jest.Mocked { - return { - read: jest.fn(), - readTree: jest.fn(), - search: jest.fn(), - readUrl: jest.fn(), - } as jest.Mocked; -} - -describe('TodoScmReader', () => { - it('should be created from config', () => { - const todoReader = TodoScmReader.fromConfig(new ConfigReader({}), { - logger: getVoidLogger(), - reader: mockReader(), - }); - expect(todoReader).toEqual(expect.any(TodoScmReader)); - }); - - it('should read TODOs', async () => { - const reader = mockReader(); - const todoReader = new TodoScmReader({ - logger: getVoidLogger(), - reader, - integrations: ScmIntegrations.fromConfig(new ConfigReader({})), - }); - - reader.readTree.mockResolvedValueOnce({ - etag: 'my-etag', - files: async () => [ - { - content: async () => Buffer.from('// TODO: my-todo', 'utf8'), - path: 'my-folder/my-file.js', - }, - ], - } as ReadTreeResponse); - - const url = 'https://github.com/backstage/backstage/catalog-info.yaml'; - const expected = { - items: [ - { - text: 'my-todo', - tag: 'TODO', - lineNumber: 1, - repoFilePath: 'my-folder/my-file.js', - viewUrl: - 'https://github.com/backstage/backstage/my-folder/my-file.js#L1', - }, - ], - }; - - // These two reads should only result in a single call to readTree - await expect( - Promise.all([ - todoReader.readTodos({ url }), - todoReader.readTodos({ url }), - ]), - ).resolves.toEqual([expected, expected]); - - expect(reader.readTree).toHaveBeenCalledTimes(1); - expect(reader.readTree).toHaveBeenCalledWith( - 'https://github.com/backstage/backstage/catalog-info.yaml', - { - etag: undefined, - filter: expect.any(Function), - }, - ); - - // Filter function should filter out dotfiles - const filterFunc = reader.readTree.mock.calls[0][1]!.filter!; - expect(filterFunc('my-file.js')).toBe(true); - expect(filterFunc('my-folder/my-file.js')).toBe(true); - expect(filterFunc('.my-file.js')).toBe(false); - expect(filterFunc('.my-folder/my-file.js')).toBe(false); - expect(filterFunc('my-folder/.my-file.js')).toBe(false); - - // A NotModifiedError should return a cached result - reader.readTree.mockRejectedValueOnce(new NotModifiedError('nope')); - await expect(todoReader.readTodos({ url })).resolves.toEqual(expected); - - expect(reader.readTree).toHaveBeenCalledTimes(2); - expect(reader.readTree).toHaveBeenLastCalledWith( - 'https://github.com/backstage/backstage/catalog-info.yaml', - { - etag: 'my-etag', - filter: expect.any(Function), - }, - ); - - // Other errors should re-throw - reader.readTree.mockRejectedValueOnce(new NotFoundError('not found')); - await expect(todoReader.readTodos({ url })).rejects.toThrow('not found'); - }); - - it('should use custom parser', async () => { - const parser = jest.fn(createTodoParser({ additionalTags: ['XXX'] })); - const reader = mockReader(); - const todoReader = new TodoScmReader({ - logger: getVoidLogger(), - reader, - parser, - integrations: ScmIntegrations.fromConfig(new ConfigReader({})), - }); - - reader.readTree.mockResolvedValueOnce({ - files: async () => [ - { - content: async () => Buffer.from('-- XXX: my-todo', 'utf8'), - path: 'my-file.lua', - }, - ], - } as ReadTreeResponse); - - await expect( - todoReader.readTodos({ - url: 'https://github.com/backstage/backstage/catalog-info.yaml', - }), - ).resolves.toEqual({ - items: [ - { - text: 'my-todo', - tag: 'XXX', - lineNumber: 1, - repoFilePath: 'my-file.lua', - viewUrl: 'https://github.com/backstage/backstage/my-file.lua#L1', - }, - ], - }); - expect(parser).toHaveBeenCalledTimes(1); - expect(parser).toHaveBeenCalledWith({ - content: '-- XXX: my-todo', - path: 'my-file.lua', - }); - }); - - it('should log and ignore parser errors', async () => { - const logger = getVoidLogger(); - const errorSpy = jest.spyOn(logger, 'error'); - const reader = mockReader(); - const todoReader = new TodoScmReader({ - logger, - reader, - parser() { - throw new Error('failed to parse'); - }, - integrations: ScmIntegrations.fromConfig(new ConfigReader({})), - }); - - reader.readTree.mockResolvedValueOnce({ - files: async () => [ - { - content: async () => Buffer.from('# XXX: my-todo', 'utf8'), - path: 'my-file.sh', - }, - ], - } as ReadTreeResponse); - - await expect( - todoReader.readTodos({ - url: 'https://github.com/o/r/catalog-info.yaml', - }), - ).resolves.toEqual({ items: [] }); - expect(errorSpy).toHaveBeenCalledWith( - 'Failed to parse TODO in https://github.com/o/r/catalog-info.yaml at my-file.sh, Error: failed to parse', - ); - }); - - it('should not filter out exclude folders', async () => { - const reader = mockReader(); - const filePathFilter = jest.fn(() => true); - - const todoReader = new TodoScmReader({ - logger: getVoidLogger(), - reader, - integrations: ScmIntegrations.fromConfig(new ConfigReader({})), - filePathFilter, - }); - reader.readTree.mockResolvedValueOnce({ - files: async () => [ - { - content: async () => Buffer.from('// TODO: my-todo', 'utf8'), - path: 'my-folder/my-file.js', - }, - ], - } as ReadTreeResponse); - await expect( - todoReader.readTodos({ - url: 'https://github.com/backstage/backstage/catalog-info.yaml', - }), - ).resolves.toEqual({ - items: [ - { - text: 'my-todo', - tag: 'TODO', - lineNumber: 1, - repoFilePath: 'my-folder/my-file.js', - viewUrl: - 'https://github.com/backstage/backstage/my-folder/my-file.js#L1', - }, - ], - }); - expect(reader.readTree).toHaveBeenCalledTimes(1); - expect(reader.readTree).toHaveBeenCalledWith( - 'https://github.com/backstage/backstage/catalog-info.yaml', - { - etag: undefined, - filter: expect.any(Function), - }, - ); - // Filter function should filter out exclude folders - const filterFunc = reader.readTree.mock.calls[0][1]!.filter!; - expect(filterFunc('my-file.js')).toBe(true); - expect(filterFunc('my-folder/my-file.js')).toBe(true); - }); - - it('should filter out exclude folders', async () => { - const reader = mockReader(); - const filePathFilter = jest.fn(() => false); - - const todoReader = new TodoScmReader({ - logger: getVoidLogger(), - reader, - integrations: ScmIntegrations.fromConfig(new ConfigReader({})), - filePathFilter, - }); - reader.readTree.mockResolvedValueOnce({ - files: async () => [ - { - content: async () => Buffer.from('// TODO: my-todo', 'utf8'), - path: '', - }, - ], - } as ReadTreeResponse); - await expect( - todoReader.readTodos({ - url: 'https://github.com/backstage/backstage/catalog-info.yaml', - }), - ).resolves.toEqual({ - items: [], - }); - expect(reader.readTree).toHaveBeenCalledTimes(1); - expect(reader.readTree).toHaveBeenCalledWith( - 'https://github.com/backstage/backstage/catalog-info.yaml', - { - etag: undefined, - filter: expect.any(Function), - }, - ); - // Filter function should filter out exclude folders - const filterFunc = reader.readTree.mock.calls[0][1]!.filter!; - expect(filterFunc('my-file.js')).toBe(false); - expect(filterFunc('my-folder/my-file.js')).toBe(false); - }); -}); diff --git a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts b/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts deleted file mode 100644 index 2ce1771ecb..0000000000 --- a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts +++ /dev/null @@ -1,197 +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 { loggerToWinstonLogger, UrlReader } from '@backstage/backend-common'; -import { ScmIntegrations } from '@backstage/integration'; -import { Logger } from 'winston'; - -import { - ReadTodosOptions, - ReadTodosResult, - TodoItem, - TodoParser, - TodoReader, -} from './types'; -import { Config } from '@backstage/config'; -import { createTodoParser } from './createTodoParser'; -import path from 'path'; -import { - coreServices, - createServiceFactory, - createServiceRef, -} from '@backstage/backend-plugin-api'; - -const excludedExtensions = [ - '.png', - '.svg', - '.jpg', - '.jpeg', - '.gif', - '.raw', - '.lock', - '.ico', -]; -const MAX_FILE_SIZE = 200000; - -/** @public */ -export type TodoScmReaderOptions = { - logger: Logger; - reader: UrlReader; - integrations: ScmIntegrations; - parser?: TodoParser; - filePathFilter?: (filePath: string) => boolean; -}; - -type CacheItem = { - etag: string; - result: ReadTodosResult; -}; - -/** @public */ -export class TodoScmReader implements TodoReader { - private readonly logger: Logger; - private readonly reader: UrlReader; - private readonly parser: TodoParser; - private readonly integrations: ScmIntegrations; - private readonly filePathFilter: (filePath: string) => boolean; - - private readonly cache = new Map(); - private readonly inFlightReads = new Map>(); - - static fromConfig( - config: Config, - options: Omit, - ) { - return new TodoScmReader({ - ...options, - integrations: ScmIntegrations.fromConfig(config), - }); - } - - constructor(options: TodoScmReaderOptions) { - this.logger = options.logger; - this.reader = options.reader; - this.parser = options.parser ?? createTodoParser(); - this.integrations = options.integrations; - this.filePathFilter = options.filePathFilter ?? (() => true); - } - - async readTodos(options: ReadTodosOptions): Promise { - const { url } = options; - const inFlightRead = this.inFlightReads.get(url); - if (inFlightRead) { - return inFlightRead.then(read => read.result); - } - - const cacheItem = this.cache.get(url); - const newRead = this.doReadTodos({ url }, cacheItem?.etag).catch(error => { - if (cacheItem && error.name === 'NotModifiedError') { - return cacheItem; - } - throw error; - }); - - this.inFlightReads.set(url, newRead); - try { - const newCacheItem = await newRead; - this.cache.set(url, newCacheItem); - return newCacheItem.result; - } finally { - this.inFlightReads.delete(url); - } - } - - private async doReadTodos( - options: ReadTodosOptions, - etag?: string, - ): Promise { - const { url } = options; - const filePathFilter = this.filePathFilter; - const tree = await this.reader.readTree(url, { - etag, - filter(filePath, info) { - const extname = path.extname(filePath); - if (info && info.size > MAX_FILE_SIZE) { - return false; - } - return ( - !filePath.startsWith('.') && - !filePath.includes('/.') && - !excludedExtensions.includes(extname) && - filePathFilter(filePath) - ); - }, - }); - - const files = await tree.files(); - this.logger.info(`Read ${files.length} files from ${url}`); - - const todos = new Array(); - for (const file of files) { - const content = await file.content(); - try { - const items = this.parser({ - path: file.path, - content: content.toString('utf8'), - }); - - todos.push( - ...items.map(({ lineNumber, text, tag, author }) => ({ - text, - tag, - author, - lineNumber, - repoFilePath: file.path, - viewUrl: this.integrations.resolveUrl({ - url: file.path, - base: url, - lineNumber, - }), - })), - ); - } catch (error) { - this.logger.error( - `Failed to parse TODO in ${url} at ${file.path}, ${error}`, - ); - } - } - - return { result: { items: todos }, etag: tree.etag }; - } -} - -/** - * @public - */ -export const todoReaderServiceRef = createServiceRef({ - id: 'todo.todoReader', - defaultFactory: async service => - createServiceFactory({ - service, - deps: { - reader: coreServices.urlReader, - config: coreServices.rootConfig, - logger: coreServices.logger, - }, - factory: async ({ reader, config, logger }) => { - const winstonLogger = loggerToWinstonLogger(logger); - return TodoScmReader.fromConfig(config, { - logger: winstonLogger, - reader, - }); - }, - }), -}); diff --git a/plugins/todo-backend/src/lib/TodoReader/createTodoParser.test.ts b/plugins/todo-backend/src/lib/TodoReader/createTodoParser.test.ts deleted file mode 100644 index c828d84b51..0000000000 --- a/plugins/todo-backend/src/lib/TodoReader/createTodoParser.test.ts +++ /dev/null @@ -1,127 +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 { createTodoParser } from './createTodoParser'; - -const comment = '//'; // just so we don't have all of these should up as TODOs :D - -describe('createTodoParser', () => { - it('should create a parser that parses TODOs', () => { - const parser = createTodoParser(); - - const output = parser({ - path: 'my-file.js', - content: ` - ${comment} TODO(user1): todo 1 - ${comment}TODO(user2): todo 2 - ${comment}todo: todo 3 - ${comment}@todo: todo 4 - - ${comment}@fixme(user5): todo 5 - ${comment} @TODO: todo 6 /user6 - ${comment} FIXME: todo 7 /user7 - `, - }); - expect(output).toEqual([ - { - text: 'todo 1', - author: 'user1', - lineNumber: 2, - tag: 'TODO', - }, - { - text: 'todo 2', - author: 'user2', - lineNumber: 3, - tag: 'TODO', - }, - { - text: 'todo 3', - lineNumber: 4, - tag: 'TODO', - }, - { - text: 'todo 4', - lineNumber: 5, - tag: 'TODO', - }, - { - text: 'todo 5', - author: 'user5', - lineNumber: 7, - tag: 'FIXME', - }, - { - text: 'todo 6', - author: 'user6', - lineNumber: 8, - tag: 'TODO', - }, - { - text: 'todo 7', - author: 'user7', - lineNumber: 9, - tag: 'FIXME', - }, - ]); - }); - - it('should support custom tags', () => { - const content = ` - ${comment} TODO: todo 1 - ${comment} MYTAG: todo 2 - ${comment} MYTAG(user): todo 3 - `; - expect( - createTodoParser()({ - path: 'my-file.js', - content, - }), - ).toEqual([{ text: 'todo 1', tag: 'TODO', lineNumber: 2 }]); - expect( - createTodoParser({ additionalTags: ['MYTAG'] })({ - path: 'my-file.js', - content, - }), - ).toEqual([ - { text: 'todo 1', tag: 'TODO', lineNumber: 2 }, - { text: 'todo 2', tag: 'MYTAG', lineNumber: 3 }, - { text: 'todo 3', author: 'user', tag: 'MYTAG', lineNumber: 4 }, - ]); - }); - - it('should support multiple languages', () => { - const parser = createTodoParser(); - - const content = ` - -- TODO: todo 1 - # TODO: todo 2 - ${comment} TODO: todo 3 - ${comment[0]}* TODO: todo 4 */ - `; - const todo1 = { text: 'todo 1', tag: 'TODO', lineNumber: 2 }; - const todo2 = { text: 'todo 2', tag: 'TODO', lineNumber: 3 }; - const todo3 = { text: 'todo 3', tag: 'TODO', lineNumber: 4 }; - const todo4 = { text: 'todo 4', tag: 'TODO', lineNumber: 5 }; - - expect(parser({ path: 'f.py', content })).toEqual([todo2]); - expect(parser({ path: 'f.lua', content })).toEqual([todo1]); - expect(parser({ path: 'f.java', content })).toEqual([todo3, todo4]); - expect(parser({ path: 'f.sh', content })).toEqual([todo2]); - expect(parser({ path: 'f.sql', content })).toEqual([todo1, todo3, todo4]); - expect(parser({ path: 'f.json', content })).toEqual([]); - }); -}); diff --git a/plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts b/plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts deleted file mode 100644 index 720efe316b..0000000000 --- a/plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts +++ /dev/null @@ -1,46 +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 { extname } from 'path'; -import { parse } from 'leasot'; -import { TodoParser } from './types'; - -/** @public */ -export type TodoParserOptions = { - /** Custom tags to support in addition to TODO and FIXME */ - additionalTags?: string[]; -}; - -/** @public */ -export function createTodoParser(options: TodoParserOptions = {}): TodoParser { - return ({ content, path }) => { - try { - const comments = parse(content, { - customTags: options.additionalTags, - extension: extname(path), - }); - - return comments.map(comment => ({ - text: comment.text, - tag: comment.tag, - author: comment.ref || undefined, - lineNumber: comment.line, - })); - } catch /* ignore unsupported extensions */ { - return []; - } - }; -} diff --git a/plugins/todo-backend/src/lib/TodoReader/index.ts b/plugins/todo-backend/src/lib/TodoReader/index.ts deleted file mode 100644 index a325fcbe65..0000000000 --- a/plugins/todo-backend/src/lib/TodoReader/index.ts +++ /dev/null @@ -1,29 +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. - */ - -export { TodoScmReader, todoReaderServiceRef } from './TodoScmReader'; -export type { TodoScmReaderOptions } from './TodoScmReader'; -export { createTodoParser } from './createTodoParser'; -export type { TodoParserOptions } from './createTodoParser'; -export type { - TodoItem, - TodoReader, - ReadTodosOptions, - ReadTodosResult, - TodoParser, - TodoParserContext, - TodoParserResult, -} from './types'; diff --git a/plugins/todo-backend/src/lib/TodoReader/types.ts b/plugins/todo-backend/src/lib/TodoReader/types.ts deleted file mode 100644 index 628a78f0c2..0000000000 --- a/plugins/todo-backend/src/lib/TodoReader/types.ts +++ /dev/null @@ -1,77 +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. - */ - -/** @public */ -export type TodoItem = { - /** The contents of the TODO comment */ - text: string; - - /** The tag used, e.g. TODO, FIXME */ - tag: string; - - /** References author, if any */ - author?: string; - - /** URL used to view the file */ - viewUrl?: string; - - /** The line number of the file that the TODO occurs at */ - lineNumber?: number; - - /** The path of the file containing the TODO within the repo */ - repoFilePath?: string; -}; - -/** @public */ -export type ReadTodosOptions = { - /** - * Base URLs defining the root at which to search for TODOs - */ - url: string; -}; - -/** @public */ -export type ReadTodosResult = { - /** - * TODO items found at the given locations - */ - items: TodoItem[]; -}; - -/** @public */ -export interface TodoReader { - /** - * Searches for TODO items in code at a given location - */ - readTodos(options: ReadTodosOptions): Promise; -} - -/** @public */ -export type TodoParserContext = { - content: string; - path: string; -}; - -/** @public */ -export type TodoParserResult = { - text: string; - tag: string; - author?: string; - lineNumber: number; -}; - -/** @public */ -export type TodoParser = (ctx: TodoParserContext) => TodoParserResult[]; diff --git a/plugins/todo-backend/src/lib/index.ts b/plugins/todo-backend/src/lib/index.ts deleted file mode 100644 index 90a887de66..0000000000 --- a/plugins/todo-backend/src/lib/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export * from './TodoReader'; diff --git a/plugins/todo-backend/src/lib/utils.ts b/plugins/todo-backend/src/lib/utils.ts deleted file mode 100644 index 63bf754f01..0000000000 --- a/plugins/todo-backend/src/lib/utils.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { InputError } from '@backstage/errors'; - -export const parseOrderByParam = ( - str: unknown, - allowedFields: T, -): { field: T[number]; direction: 'asc' | 'desc' } | undefined => { - if (str === undefined) { - return undefined; - } - if (typeof str !== 'string') { - throw new InputError(`invalid orderBy query, must be a string`); - } - const [field, direction] = str.split('='); - if (!field) { - throw new InputError(`invalid orderBy query, field name is empty`); - } - if (direction !== 'asc' && direction !== 'desc') { - throw new InputError( - `invalid orderBy query, order direction must be 'asc' or 'desc'`, - ); - } - - if (field && !allowedFields.includes(field)) { - throw new InputError( - `invalid orderBy field, must be one of ${allowedFields.join(', ')}`, - ); - } - return { field, direction }; -}; - -export const parseFilterParam = ( - str: unknown, - allowedFields: T, -): { field: T[number]; value: string }[] | undefined => { - if (str === undefined) { - return undefined; - } - - const filters = new Array<{ field: T[number]; value: string }>(); - - const strs = [str].flat(); - for (const filterStr of strs) { - if (typeof filterStr !== 'string') { - throw new InputError( - `invalid filter query, must be a string or list of strings`, - ); - } - const splitIndex = filterStr.indexOf('='); - if (splitIndex <= 0) { - throw new InputError( - `invalid filter query, must separate field from value using '='`, - ); - } - - const field = filterStr.slice(0, splitIndex); - if (!allowedFields.includes(field)) { - throw new InputError( - `invalid filter field, must be one of ${allowedFields.join(', ')}`, - ); - } - - const value = filterStr.slice(splitIndex + 1); - if (!value) { - throw new InputError(`invalid filter query, value may not be empty`); - } - filters.push({ field, value }); - } - - return filters; -}; - -export const getBearerToken = (header?: string): string | undefined => { - return header?.match(/Bearer\s+(\S+)/i)?.[1]; -}; diff --git a/plugins/todo-backend/src/plugin.ts b/plugins/todo-backend/src/plugin.ts deleted file mode 100644 index 640ea1a0ce..0000000000 --- a/plugins/todo-backend/src/plugin.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendPlugin, - coreServices, -} from '@backstage/backend-plugin-api'; - -import { todoServiceRef } from './service/TodoReaderService'; -import { createRouter } from './service/router'; - -/** - * The Todos plugin is responsible for aggregating todo comments within source. - * @public - */ -export const todoPlugin = createBackendPlugin({ - pluginId: 'todo', - register(env) { - env.registerInit({ - deps: { - todoReader: todoServiceRef, - http: coreServices.httpRouter, - }, - async init({ http, todoReader }) { - http.use( - await createRouter({ - todoService: todoReader, - }), - ); - }, - }); - }, -}); diff --git a/plugins/todo-backend/src/schema/openapi.generated.ts b/plugins/todo-backend/src/schema/openapi.generated.ts deleted file mode 100644 index 238be2fe5b..0000000000 --- a/plugins/todo-backend/src/schema/openapi.generated.ts +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// ****************************************************************** -// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * -// ****************************************************************** -import { createValidatedOpenApiRouter } from '@backstage/backend-openapi-utils'; - -export const spec = { - openapi: '3.0.3', - info: { - title: 'todo', - version: '1', - description: - 'The Backstage backend plugin that provides source code todo comment browsing.', - license: { - name: 'Apache-2.0', - url: 'http://www.apache.org/licenses/LICENSE-2.0.html', - }, - contact: {}, - }, - servers: [ - { - url: '/', - }, - ], - components: { - examples: {}, - headers: {}, - parameters: {}, - requestBodies: {}, - responses: {}, - schemas: { - TodoItem: { - type: 'object', - properties: { - text: { - type: 'string', - description: 'The contents of the TODO comment', - }, - tag: { - type: 'string', - description: 'The tag used, e.g. TODO, FIXME', - }, - author: { - type: 'string', - description: 'References author, if any', - }, - viewUrl: { - type: 'string', - description: 'URL used to view the file', - }, - lineNumber: { - type: 'integer', - description: 'The line number of the file that the TODO occurs at', - }, - repoFilePath: { - type: 'string', - description: - 'The path of the file containing the TODO within the repo', - }, - }, - required: ['text', 'tag'], - additionalProperties: false, - }, - }, - securitySchemes: { - JWT: { - type: 'http', - scheme: 'bearer', - bearerFormat: 'JWT', - }, - }, - }, - paths: { - '/v1/todos': { - get: { - operationId: 'ListTodos', - responses: { - '200': { - description: 'Ok', - content: { - 'application/json': { - schema: { - type: 'object', - properties: { - items: { - type: 'array', - items: { - $ref: '#/components/schemas/TodoItem', - }, - }, - totalCount: { - type: 'integer', - }, - offset: { - type: 'integer', - }, - limit: { - type: 'integer', - }, - }, - required: ['items', 'totalCount', 'offset', 'limit'], - additionalProperties: false, - }, - }, - }, - }, - '400': { - description: 'Bad request', - content: { - 'application/json': { - schema: { - type: 'object', - properties: { - error: { - type: 'object', - properties: { - message: { - type: 'string', - }, - }, - }, - }, - }, - }, - }, - }, - }, - security: [ - {}, - { - JWT: [], - }, - ], - parameters: [ - { - name: 'entity', - in: 'query', - required: false, - allowReserved: true, - schema: { - type: 'string', - minLength: 1, - description: 'A reference to the entity to list TODO items for', - }, - }, - { - name: 'orderBy', - in: 'query', - required: false, - schema: { - type: 'string', - pattern: '^(text|tag|author|viewUrl|repoFilePath)=(asc|desc)$', - description: - 'The field and direction used to sort the listed TODO items', - }, - }, - { - name: 'filter', - in: 'query', - required: false, - allowReserved: true, - schema: { - type: 'array', - description: - 'A list of filters used to narrow down the listed TODO items', - items: { - type: 'string', - pattern: '^(text|tag|author|viewUrl|repoFilePath)=.+$', - }, - }, - }, - { - name: 'offset', - in: 'query', - required: false, - schema: { - type: 'integer', - minimum: 0, - description: 'The offset at which to start listing TODO items', - }, - }, - { - name: 'limit', - in: 'query', - required: false, - schema: { - type: 'integer', - minimum: 1, - description: 'The number of TODO items to list', - }, - }, - ], - }, - }, - }, -} as const; -export const createOpenApiRouter = async ( - options?: Parameters['1'], -) => createValidatedOpenApiRouter(spec, options); diff --git a/plugins/todo-backend/src/schema/openapi.yaml b/plugins/todo-backend/src/schema/openapi.yaml deleted file mode 100644 index 7408927b99..0000000000 --- a/plugins/todo-backend/src/schema/openapi.yaml +++ /dev/null @@ -1,134 +0,0 @@ -openapi: 3.0.3 - -info: - title: todo - version: '1' - description: The Backstage backend plugin that provides source code todo comment browsing. - license: - name: Apache-2.0 - url: http://www.apache.org/licenses/LICENSE-2.0.html - contact: {} - -servers: - - url: / - -components: - examples: {} - headers: {} - parameters: {} - requestBodies: {} - responses: {} - schemas: - TodoItem: - type: object - properties: - text: - type: string - description: The contents of the TODO comment - tag: - type: string - description: The tag used, e.g. TODO, FIXME - author: - type: string - description: References author, if any - viewUrl: - type: string - description: URL used to view the file - lineNumber: - type: integer - description: The line number of the file that the TODO occurs at - repoFilePath: - type: string - description: The path of the file containing the TODO within the repo - required: - - text - - tag - additionalProperties: false - securitySchemes: - JWT: - type: http - scheme: bearer - bearerFormat: JWT -paths: - /v1/todos: - get: - operationId: ListTodos - responses: - '200': - description: Ok - content: - application/json: - schema: - type: object - properties: - items: - type: array - items: - $ref: '#/components/schemas/TodoItem' - totalCount: - type: integer - offset: - type: integer - limit: - type: integer - required: - - items - - totalCount - - offset - - limit - additionalProperties: false - '400': - description: Bad request - content: - application/json: - schema: - type: object - properties: - error: - type: object - properties: - message: - type: string - security: - - {} - - JWT: [] - parameters: - - name: entity - in: query - required: false - allowReserved: true - schema: - type: string - minLength: 1 - description: A reference to the entity to list TODO items for - - name: orderBy - in: query - required: false - schema: - type: string - pattern: '^(text|tag|author|viewUrl|repoFilePath)=(asc|desc)$' - description: The field and direction used to sort the listed TODO items - - name: filter - in: query - required: false - allowReserved: true - schema: - type: array - description: A list of filters used to narrow down the listed TODO items - items: - type: string - pattern: '^(text|tag|author|viewUrl|repoFilePath)=.+$' - - name: offset - in: query - required: false - schema: - type: integer - minimum: 0 - description: The offset at which to start listing TODO items - - name: limit - in: query - required: false - schema: - type: integer - minimum: 1 - description: The number of TODO items to list diff --git a/plugins/todo-backend/src/service/TodoReaderService.test.ts b/plugins/todo-backend/src/service/TodoReaderService.test.ts deleted file mode 100644 index 3f68636a05..0000000000 --- a/plugins/todo-backend/src/service/TodoReaderService.test.ts +++ /dev/null @@ -1,372 +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 { CatalogApi } from '@backstage/catalog-client'; -import { Entity } from '@backstage/catalog-model'; -import { TodoItem, TodoReader } from '../lib'; -import { TodoReaderService } from './TodoReaderService'; - -const entityName = { - kind: 'Component', - namespace: 'default', - name: 'my-component', -}; - -const mockEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'my-component', - annotations: { - 'backstage.io/managed-by-location': - 'url:https://github.com/backstage/backstage/blob/master/catalog-info.yaml', - }, - }, - spec: { - type: 'library', - }, -}; - -function mockCatalogClient(entity?: Entity): jest.Mocked { - const mock = { - addLocation: jest.fn(), - getEntities: jest.fn(), - getEntityByRef: jest.fn(), - getEntityByName: jest.fn(), - getLocationByRef: jest.fn(), - getLocationById: jest.fn(), - removeLocationById: jest.fn(), - removeEntityByUid: jest.fn(), - refreshEntity: jest.fn(), - getEntityAncestors: jest.fn(), - getEntityFacets: jest.fn(), - validateEntity: jest.fn(), - }; - if (entity) { - mock.getEntityByRef.mockReturnValue(entity); - } - return mock as Partial> as jest.Mocked; -} - -function mockTodoReader(items?: TodoItem[]): jest.Mocked { - const mock = { - readTodos: jest.fn(), - }; - if (items) { - mock.readTodos.mockReturnValue({ items }); - } - return mock; -} - -function makeTodo(text: string, extra?: Partial): TodoItem { - return { text, tag: 'TODO', ...extra }; -} - -describe('TodoReaderService', () => { - it('should be created', () => { - const service = new TodoReaderService({ - todoReader: mockTodoReader(), - catalogClient: mockCatalogClient(), - }); - expect(service.listTodos).toEqual(expect.any(Function)); - }); - - it('should list 0 todos', async () => { - const todoReader = mockTodoReader([]); - const catalogClient = mockCatalogClient(mockEntity); - const service = new TodoReaderService({ todoReader, catalogClient }); - - await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [], - totalCount: 0, - offset: 0, - limit: 10, - }); - expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(entityName, { - token: undefined, - }); - }); - - it('should list, order, and filter todos', async () => { - const todo1 = makeTodo('todo1'); - const todo2 = makeTodo('todo2', { author: 'foo' }); - const todo3 = makeTodo('todo3', { - author: 'bar', - repoFilePath: 'a/b/c.js', - }); - const todo4 = makeTodo('todo4', { author: 'baz', viewUrl: 'example.com' }); - const todo5 = makeTodo('todo5', { tag: 'FIXME' }); - - const todoReader = mockTodoReader([todo1, todo2, todo3, todo4, todo5]); - const catalogClient = mockCatalogClient({ - ...mockEntity, - metadata: { - ...mockEntity.metadata, - annotations: { - ['backstage.io/source-location']: - 'url:https://github.com/backstage/backstage/blob/master/catalog-info.yaml', - }, - }, - }); - const service = new TodoReaderService({ todoReader, catalogClient }); - - await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [todo1, todo2, todo3, todo4, todo5], - totalCount: 5, - offset: 0, - limit: 10, - }); - - await expect( - service.listTodos({ entity: entityName, limit: 3 }), - ).resolves.toEqual({ - items: [todo1, todo2, todo3], - totalCount: 5, - offset: 0, - limit: 3, - }); - - await expect( - service.listTodos({ entity: entityName, offset: 2 }), - ).resolves.toEqual({ - items: [todo3, todo4, todo5], - totalCount: 5, - offset: 2, - limit: 10, - }); - - await expect( - service.listTodos({ - entity: entityName, - orderBy: { field: 'author', direction: 'asc' }, - }), - ).resolves.toEqual({ - items: [todo3, todo4, todo2, todo1, todo5], - totalCount: 5, - offset: 0, - limit: 10, - }); - - await expect( - service.listTodos({ - entity: entityName, - orderBy: { field: 'author', direction: 'desc' }, - offset: -2, - }), - ).resolves.toEqual({ - items: [todo2, todo4, todo3, todo1, todo5], - totalCount: 5, - offset: 0, - limit: 10, - }); - - await expect( - service.listTodos({ - entity: entityName, - orderBy: { field: 'text', direction: 'desc' }, - offset: 2, - limit: 2, - }), - ).resolves.toEqual({ - items: [todo3, todo2], - totalCount: 5, - offset: 2, - limit: 2, - }); - - await expect( - service.listTodos({ - entity: entityName, - filters: [{ field: 'text', value: '*4' }], - }), - ).resolves.toEqual({ items: [todo4], totalCount: 1, offset: 0, limit: 10 }); - - await expect( - service.listTodos({ - entity: entityName, - filters: [{ field: 'author', value: 'ba*' }], - }), - ).resolves.toEqual({ - items: [todo3, todo4], - totalCount: 2, - offset: 0, - limit: 10, - }); - - await expect( - service.listTodos({ - entity: entityName, - filters: [{ field: 'author', value: 'ba*' }], - limit: 1, - }), - ).resolves.toEqual({ items: [todo3], totalCount: 2, offset: 0, limit: 1 }); - - await expect( - service.listTodos({ - entity: entityName, - filters: [ - { field: 'author', value: 'ba*' }, - { field: 'tag', value: 'FIXME' }, - ], - }), - ).resolves.toEqual({ items: [], totalCount: 0, offset: 0, limit: 10 }); - - await expect( - service.listTodos({ - entity: entityName, - filters: [{ field: 'tag', value: 'FIXME' }], - limit: 500, - }), - ).resolves.toEqual({ items: [todo5], totalCount: 1, offset: 0, limit: 50 }); - - await expect( - service.listTodos({ entity: entityName, limit: -5 }), - ).resolves.toEqual({ items: [], totalCount: 5, offset: 0, limit: 0 }); - }); - - it('should have configurable pagination', async () => { - const todo1 = makeTodo('todo1'); - const todo2 = makeTodo('todo2'); - const todo3 = makeTodo('todo3'); - const todo4 = makeTodo('todo4'); - const todo5 = makeTodo('todo5'); - - const todoReader = mockTodoReader([todo1, todo2, todo3, todo4, todo5]); - const catalogClient = mockCatalogClient(mockEntity); - const service = new TodoReaderService({ - todoReader, - catalogClient, - defaultPageSize: 2, - maxPageSize: 3, - }); - - await expect(service.listTodos({ entity: entityName })).resolves.toEqual({ - items: [todo1, todo2], - totalCount: 5, - offset: 0, - limit: 2, - }); - await expect( - service.listTodos({ entity: entityName, limit: 1 }), - ).resolves.toEqual({ - items: [todo1], - totalCount: 5, - offset: 0, - limit: 1, - }); - await expect( - service.listTodos({ entity: entityName, limit: 3 }), - ).resolves.toEqual({ - items: [todo1, todo2, todo3], - totalCount: 5, - offset: 0, - limit: 3, - }); - await expect( - service.listTodos({ entity: entityName, limit: 4 }), - ).resolves.toEqual({ - items: [todo1, todo2, todo3], - totalCount: 5, - offset: 0, - limit: 3, - }); - }); - - it('should require an entity', async () => { - const service = new TodoReaderService({ - todoReader: mockTodoReader(), - catalogClient: mockCatalogClient(), - }); - await expect(service.listTodos({})).rejects.toThrow( - 'Entity filter is required to list TODOs', - ); - }); - - it('should throw if entity is not found', async () => { - const todoReader = mockTodoReader([]); - const catalogClient = mockCatalogClient(); - const service = new TodoReaderService({ todoReader, catalogClient }); - - await expect(service.listTodos({ entity: entityName })).rejects.toEqual( - expect.objectContaining({ - name: 'NotFoundError', - message: 'Entity not found, component:default/my-component', - }), - ); - expect(catalogClient.getEntityByRef).toHaveBeenCalledWith(entityName, { - token: undefined, - }); - }); - - it('should not throw if entity does not have a location', async () => { - const todoReader = mockTodoReader([]); - const catalogClient = mockCatalogClient({ - ...mockEntity, - metadata: { ...mockEntity.metadata, annotations: undefined }, - }); - const service = new TodoReaderService({ todoReader, catalogClient }); - - await expect(service.listTodos({ entity: entityName })).rejects.toEqual( - expect.objectContaining({ - name: 'Error', - message: "Entity 'component:default/my-component' is missing location", - }), - ); - }); - - it('should throw if entity has an invalid location', async () => { - const todoReader = mockTodoReader([]); - const catalogClient = mockCatalogClient({ - ...mockEntity, - metadata: { - ...mockEntity.metadata, - annotations: { - ['backstage.io/managed-by-location']: - 'file:../managed-by-location.yaml', - }, - }, - }); - const service = new TodoReaderService({ todoReader, catalogClient }); - - await expect(service.listTodos({ entity: entityName })).rejects.toEqual( - expect.objectContaining({ - name: 'InputError', - message: `Invalid entity location type for component:default/my-component, got 'file' for location ../managed-by-location.yaml`, - }), - ); - }); - - it('should throw if entity has an invalid source location', async () => { - const todoReader = mockTodoReader([]); - const catalogClient = mockCatalogClient({ - ...mockEntity, - metadata: { - ...mockEntity.metadata, - annotations: { - ['backstage.io/source-location']: 'file:../source-location.yaml', - }, - }, - }); - const service = new TodoReaderService({ todoReader, catalogClient }); - - await expect(service.listTodos({ entity: entityName })).rejects.toEqual( - expect.objectContaining({ - name: 'InputError', - message: `Invalid entity location type for component:default/my-component, got 'file' for location ../source-location.yaml`, - }), - ); - }); -}); diff --git a/plugins/todo-backend/src/service/TodoReaderService.ts b/plugins/todo-backend/src/service/TodoReaderService.ts deleted file mode 100644 index 6ce38709f1..0000000000 --- a/plugins/todo-backend/src/service/TodoReaderService.ts +++ /dev/null @@ -1,159 +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 { InputError, NotFoundError } from '@backstage/errors'; -import { CatalogApi } from '@backstage/catalog-client'; -import { - getEntitySourceLocation, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { - createServiceFactory, - createServiceRef, - ServiceRef, -} from '@backstage/backend-plugin-api'; -import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; - -import { TodoReader, todoReaderServiceRef } from '../lib'; -import { ListTodosRequest, ListTodosResponse, TodoService } from './types'; - -const DEFAULT_DEFAULT_PAGE_SIZE = 10; -const DEFAULT_MAX_PAGE_SIZE = 50; - -/** @public */ -export type TodoReaderServiceOptions = { - todoReader: TodoReader; - catalogClient: CatalogApi; - maxPageSize?: number; - defaultPageSize?: number; -}; - -function wildcardRegex(str: string): RegExp { - const pattern = str - .replace(/[.+?^${}()|[\]\\]/g, '\\$&') - .replace(/\*/g, '.*'); - return new RegExp(`^${pattern}$`, 'i'); -} - -/** @public */ -export class TodoReaderService implements TodoService { - private readonly todoReader: TodoReader; - private readonly catalogClient: CatalogApi; - private readonly maxPageSize: number; - private readonly defaultPageSize: number; - - constructor(options: TodoReaderServiceOptions) { - this.todoReader = options.todoReader; - this.catalogClient = options.catalogClient; - this.maxPageSize = options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE; - this.defaultPageSize = options.defaultPageSize ?? DEFAULT_DEFAULT_PAGE_SIZE; - } - - async listTodos( - req: ListTodosRequest, - options?: { token?: string }, - ): Promise { - if (!req.entity) { - throw new InputError('Entity filter is required to list TODOs'); - } - const token = options?.token; - const entity = await this.catalogClient.getEntityByRef(req.entity, { - token, - }); - if (!entity) { - throw new NotFoundError( - `Entity not found, ${stringifyEntityRef(req.entity)}`, - ); - } - const entitySourceLocation = getEntitySourceLocation(entity); - if (entitySourceLocation.type !== 'url') { - throw new InputError( - `Invalid entity location type for ${stringifyEntityRef(entity)}, got '${ - entitySourceLocation.type - }' for location ${entitySourceLocation.target}`, - ); - } - const url = entitySourceLocation.target; - const todos = await this.todoReader.readTodos({ url }); - - let limit = req.limit ?? this.defaultPageSize; - if (limit < 0) { - limit = 0; - } else if (limit > this.maxPageSize) { - limit = this.maxPageSize; - } - - let offset = req.offset ?? 0; - if (offset < 0) { - offset = 0; - } - - let items = todos.items; - const { orderBy, filters } = req; - - if (filters) { - for (const { field, value } of filters) { - const pattern = wildcardRegex(value); - items = items.filter(item => item[field]?.match(pattern)); - } - } - - if (orderBy) { - const dir = orderBy.direction === 'asc' ? 1 : -1; - const field = orderBy.field; - items = items.slice().sort((item1, item2) => { - const field1 = item1[field]; - const field2 = item2[field]; - - if (field1 && field2) { - return dir * field1.localeCompare(field2, 'en-US'); - } else if (field1 && !field2) { - return -1; - } else if (!field1 && field2) { - return 1; - } - return 0; - }); - } - - return { - items: items.slice(offset, offset + limit), - totalCount: items.length, - offset, - limit, - }; - } -} - -export const todoServiceRef: ServiceRef = - createServiceRef({ - id: 'todo.client', - defaultFactory: async service => - createServiceFactory({ - service, - deps: { - catalogApi: catalogServiceRef, - todoReader: todoReaderServiceRef, - }, - async factory({ catalogApi, todoReader }) { - const todoReaderService = new TodoReaderService({ - catalogClient: catalogApi, - todoReader, - }); - return todoReaderService; - }, - }), - }); diff --git a/plugins/todo-backend/src/service/index.ts b/plugins/todo-backend/src/service/index.ts deleted file mode 100644 index 380d95dbe1..0000000000 --- a/plugins/todo-backend/src/service/index.ts +++ /dev/null @@ -1,21 +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. - */ - -export { createRouter } from './router'; -export type { RouterOptions } from './router'; -export type { TodoService, ListTodosRequest, ListTodosResponse } from './types'; -export { TodoReaderService } from './TodoReaderService'; -export type { TodoReaderServiceOptions } from './TodoReaderService'; diff --git a/plugins/todo-backend/src/service/router.test.ts b/plugins/todo-backend/src/service/router.test.ts deleted file mode 100644 index 64f894a147..0000000000 --- a/plugins/todo-backend/src/service/router.test.ts +++ /dev/null @@ -1,246 +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 express from 'express'; -import request from 'supertest'; -import { errorHandler } from '@backstage/backend-common'; - -import { createRouter } from './router'; -import { parseFilterParam, parseOrderByParam } from '../lib/utils'; -import { TodoService } from './types'; - -const mockListBody = { - items: [{ text: 'my todo', tag: 'TODO' }], - totalCount: 1, - offset: 0, - limit: 10, -}; - -function matchErrorResponse(status: number, name: string, message: string) { - return { - status, - body: expect.objectContaining({ - error: { name, message }, - response: { - statusCode: status, - }, - }), - }; -} - -describe('createRouter', () => { - let app: express.Express; - const mockService: jest.Mocked = { - listTodos: jest.fn(), - }; - - beforeAll(async () => { - const router = await createRouter({ - todoService: mockService, - }); - app = express().use(router).use(errorHandler()); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('GET /todos', () => { - it('returns list without query', async () => { - mockService.listTodos.mockResolvedValueOnce(mockListBody); - - const response = await request(app).get('/v1/todos'); - expect(response.status).toEqual(200); - expect(response.body).toEqual(mockListBody); - expect(mockService.listTodos).toHaveBeenCalledWith( - { - entity: undefined, - offset: undefined, - limit: undefined, - }, - { token: undefined }, - ); - }); - - it('forwards auth token', async () => { - mockService.listTodos.mockResolvedValueOnce(mockListBody); - - const response = await request(app) - .get('/v1/todos') - .set('Authorization', 'Bearer secret'); - expect(response.status).toEqual(200); - expect(response.body).toEqual(mockListBody); - expect(mockService.listTodos).toHaveBeenCalledWith( - { - entity: undefined, - offset: undefined, - limit: undefined, - }, - { token: 'secret' }, - ); - }); - - it('forwards pagination query', async () => { - mockService.listTodos.mockResolvedValueOnce(mockListBody); - - const response = await request(app).get('/v1/todos?offset=5&limit=3'); - expect(response.status).toEqual(200); - expect(response.body).toEqual(mockListBody); - expect(mockService.listTodos).toHaveBeenCalledWith( - { - entity: undefined, - offset: 5, - limit: 3, - }, - { token: undefined }, - ); - }); - - it('forwards entity query', async () => { - mockService.listTodos.mockResolvedValueOnce(mockListBody); - - const response = await request(app).get( - '/v1/todos?entity=component:my-component', - ); - expect(response.status).toEqual(200); - expect(response.body).toEqual(mockListBody); - expect(mockService.listTodos).toHaveBeenCalledWith( - { - entity: { - name: 'my-component', - kind: 'component', - namespace: 'default', - }, - offset: undefined, - limit: undefined, - }, - { token: undefined }, - ); - }); - - it('forwards filter query', async () => { - mockService.listTodos.mockResolvedValueOnce(mockListBody); - - const response = await request(app).get('/v1/todos?filter=text=*borked*'); - expect(response.status).toEqual(200); - expect(response.body).toEqual(mockListBody); - expect(mockService.listTodos).toHaveBeenCalledWith( - { - entity: undefined, - offset: undefined, - limit: undefined, - filters: [{ field: 'text', value: '*borked*' }], - }, - { token: undefined }, - ); - }); - - it('rejects invalid queries', async () => { - request(app) - .get('/v1/todos?entity=k:n&entity=k:n') - .expect(400) - .expect( - matchErrorResponse( - 400, - 'InputError', - 'entity query must be a string', - ), - ); - - request(app) - .get('/v1/todos?entity=:n') - .expect(400) - .expect( - matchErrorResponse( - 400, - 'InputError', - 'Invalid entity ref, TypeError: Entity reference ":n" was not on the form [:][/]', - ), - ); - - request(app) - .get('/v1/todos?offset=1.5') - .expect(400) - .expect( - matchErrorResponse( - 400, - 'InputError', - 'invalid offset query, not an integer', - ), - ); - - expect(mockService.listTodos).not.toHaveBeenCalled(); - }); - }); -}); - -describe('parseOrderByParam', () => { - it('should parse a param', () => { - expect(parseOrderByParam('a=asc', ['a'])).toEqual({ - field: 'a', - direction: 'asc', - }); - expect(parseOrderByParam('a=desc', ['a'])).toEqual({ - field: 'a', - direction: 'desc', - }); - }); - - it('should reject invalid params', () => { - expect(() => parseOrderByParam(['a=asc'], ['a'])).toThrow( - 'invalid orderBy query, must be a string', - ); - expect(() => parseOrderByParam('a=desc', ['b', 'c'])).toThrow( - 'invalid orderBy field, must be one of b, c', - ); - expect(() => parseOrderByParam('b=down', ['a'])).toThrow( - `invalid orderBy query, order direction must be 'asc' or 'desc'`, - ); - expect(() => parseOrderByParam('=asc', ['a'])).toThrow( - 'invalid orderBy query, field name is empty', - ); - }); -}); - -describe('parseFilterParam', () => { - it('should parse a param', () => { - expect(parseFilterParam('a=b', ['a'])).toEqual([ - { field: 'a', value: 'b' }, - ]); - expect(parseFilterParam(['a=b=c', 'c=d*'], ['a', 'c'])).toEqual([ - { field: 'a', value: 'b=c' }, - { field: 'c', value: 'd*' }, - ]); - }); - - it('should reject invalid params', () => { - expect(() => parseFilterParam({ a: 'a=b' }, ['a'])).toThrow( - 'invalid filter query, must be a string or list of strings', - ); - expect(() => parseFilterParam('a=b', ['b', 'c'])).toThrow( - 'invalid filter field, must be one of b, c', - ); - expect(() => parseFilterParam('b', ['a'])).toThrow( - `invalid filter query, must separate field from value using '='`, - ); - expect(() => parseFilterParam('=a', ['a'])).toThrow( - `invalid filter query, must separate field from value using '='`, - ); - expect(() => parseFilterParam('a=', ['a'])).toThrow( - 'invalid filter query, value may not be empty', - ); - }); -}); diff --git a/plugins/todo-backend/src/service/router.ts b/plugins/todo-backend/src/service/router.ts deleted file mode 100644 index 53b0a02668..0000000000 --- a/plugins/todo-backend/src/service/router.ts +++ /dev/null @@ -1,75 +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 { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model'; -import { InputError } from '@backstage/errors'; -import express from 'express'; -import { type TodoService, TODO_FIELDS } from './types'; -import { - getBearerToken, - parseFilterParam, - parseOrderByParam, -} from '../lib/utils'; -import { createOpenApiRouter } from '../schema/openapi.generated'; - -/** @public */ -export interface RouterOptions { - todoService: TodoService; -} - -/** @public */ -export async function createRouter( - options: RouterOptions, -): Promise { - const router = await createOpenApiRouter(); - router.use(express.json()); - const { todoService } = options; - - router.get('/v1/todos', async (req, res) => { - const { offset, limit } = req.query; - const orderBy = parseOrderByParam(req.query.orderBy, TODO_FIELDS); - const filters = parseFilterParam(req.query.filter, TODO_FIELDS); - - const entityRef = req.query.entity; - if (entityRef && typeof entityRef !== 'string') { - throw new InputError(`entity query must be a string`); - } - let entity: CompoundEntityRef | undefined = undefined; - if (entityRef) { - try { - entity = parseEntityRef(entityRef); - } catch (error) { - throw new InputError(`Invalid entity ref, ${error}`); - } - } - - const todos = await todoService.listTodos( - { - entity, - offset, - limit, - orderBy, - filters, - }, - { - token: getBearerToken(req.headers.authorization), - }, - ); - res.json(todos); - }); - - return router; -} diff --git a/plugins/todo-backend/src/service/types.ts b/plugins/todo-backend/src/service/types.ts deleted file mode 100644 index ab15e20027..0000000000 --- a/plugins/todo-backend/src/service/types.ts +++ /dev/null @@ -1,58 +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 { CompoundEntityRef } from '@backstage/catalog-model'; -import { TodoItem } from '../lib'; - -/** @public */ -export type ListTodosRequest = { - entity?: CompoundEntityRef; - offset?: number; - limit?: number; - orderBy?: { - field: 'text' | 'tag' | 'author' | 'viewUrl' | 'repoFilePath'; - direction: 'asc' | 'desc'; - }; - filters?: { - field: 'text' | 'tag' | 'author' | 'viewUrl' | 'repoFilePath'; - /** Value to filter by, with '*' used as wildcard */ - value: string; - }[]; -}; - -/** @public */ -export type ListTodosResponse = { - items: TodoItem[]; - totalCount: number; - offset: number; - limit: number; -}; - -/** @public */ -export interface TodoService { - listTodos( - req: ListTodosRequest, - options?: { token?: string }, - ): Promise; -} - -export const TODO_FIELDS = [ - 'text', - 'tag', - 'author', - 'viewUrl', - 'repoFilePath', -] as const; diff --git a/plugins/todo/.eslintrc.js b/plugins/todo/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/todo/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md deleted file mode 100644 index add572fa00..0000000000 --- a/plugins/todo/CHANGELOG.md +++ /dev/null @@ -1,1420 +0,0 @@ -# @backstage/plugin-todo - -## 0.2.34-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.2.34-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.2.34-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/errors@1.2.3 - -## 0.2.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.2.33 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.2.33-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.2.33-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.2.33-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.2.32 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.2.32-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.2.32-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.2.32-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.2.32-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.2.30 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export. -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.2.30-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.2.30-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - -## 0.2.30-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 8613ba3928: Switched to using `"exports"` field for `/alpha` subpath export. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.2.28 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - -## 0.2.28-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - -## 0.2.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.2.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.2.27 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.2.26 - -Skipped due to publishing issues. - -## 0.2.26-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.2.26-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.26-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.25-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.2.23 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.2.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.22 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.2.22-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - -## 0.2.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.2.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.2.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - -## 0.2.21-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.2.21-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.2.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.2.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.2.20 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.2.20-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.2.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.2.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19 - -## 0.2.19 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.2.19-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.2.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.2.19-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.2.19-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - -## 0.2.18 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.2.18-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.2.18-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.2.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 - -## 0.2.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/errors@1.1.4 - -## 0.2.17-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.2.17-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.2.16 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.16-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.16-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.2.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.2.14 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.14-next.4 - -### Patch Changes - -- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.14-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.2.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.14-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.2.13 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/errors@1.1.3 - - @backstage/theme@0.2.16 - -## 0.2.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.2.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.2.12 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - - @backstage/theme@0.2.16 - -## 0.2.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/theme@0.2.16 - -## 0.2.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.2.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/theme@0.2.16 - -## 0.2.11 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- 7d47def9c4: Removed dependency on `@types/jest`. -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - - @backstage/errors@1.1.1 - -## 0.2.11-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.2.11-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.2.11-next.1 - -### Patch Changes - -- 817f3196f6: Updated React Router dependencies to be peer dependencies. -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - - @backstage/plugin-catalog-react@1.1.4-next.1 - -## 0.2.11-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.2.9-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.2.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.2.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.2.8 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 - -## 0.2.8-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - - @backstage/catalog-model@1.0.3-next.0 - - @backstage/plugin-catalog-react@1.1.1-next.1 - -## 0.2.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1-next.0 - - @backstage/core-components@0.9.5-next.0 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - - @backstage/plugin-catalog-react@1.1.0 - - @backstage/catalog-model@1.0.2 - -## 0.2.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.1 - - @backstage/plugin-catalog-react@1.1.0-next.2 - - @backstage/catalog-model@1.0.2-next.0 - - @backstage/core-plugin-api@1.0.2-next.1 - -## 0.2.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - - @backstage/plugin-catalog-react@1.1.0-next.1 - -## 0.2.7-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.0-next.0 - -## 0.2.6 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/plugin-catalog-react@1.0.1 - - @backstage/catalog-model@1.0.1 - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.2.6-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.3 - -## 0.2.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.0.1-next.0 - - @backstage/plugin-catalog-react@1.0.1-next.0 - - @backstage/core-components@0.9.3-next.0 - -## 0.2.5 - -### Patch Changes - -- 89c7e47967: Minor README update -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/plugin-catalog-react@1.0.0 - - @backstage/catalog-model@1.0.0 - - @backstage/errors@1.0.0 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0 - - @backstage/core-components@0.9.1 - - @backstage/catalog-model@0.13.0 - -## 0.2.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.9.0-next.0 - - @backstage/core-components@0.9.1-next.0 - - @backstage/catalog-model@0.13.0-next.0 - -## 0.2.3 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@0.12.0 - - @backstage/core-components@0.9.0 - - @backstage/plugin-catalog-react@0.8.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.2.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/plugin-catalog-react@0.7.0 - - @backstage/catalog-model@0.11.0 - - @backstage/core-plugin-api@0.7.0 - -## 0.2.1 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- 27eccab216: Replaces use of deprecated catalog-model constants. -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/errors@0.2.1 - - @backstage/plugin-catalog-react@0.6.15 - - @backstage/catalog-model@0.10.0 - - @backstage/theme@0.2.15 - -## 0.2.0 - -### Minor Changes - -- 323f48704d: **BREAKING**: The `EntityTodoContent` is now a routable extension. This means it must be rendered within a route, but that's most likely already the case for most apps. The mount point `RouteRef` is available via `todoPlugin.routes.entityContent`. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - - @backstage/plugin-catalog-react@0.6.14 - -## 0.2.0-next.0 - -### Minor Changes - -- 323f48704d: **BREAKING**: The `EntityTodoContent` is now a routable extension. This means it must be rendered within a route, but that's most likely already the case for most apps. The mount point `RouteRef` is available via `todoPlugin.routes.entityContent`. - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - - @backstage/plugin-catalog-react@0.6.14-next.0 - -## 0.1.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - - @backstage/plugin-catalog-react@0.6.13 - -## 0.1.21-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - - @backstage/plugin-catalog-react@0.6.13-next.0 - -## 0.1.20 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- 751e0ceb2a: Apply fix from the 0.1.19 patch release -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - - @backstage/plugin-catalog-react@0.6.12 - - @backstage/catalog-model@0.9.10 - -## 0.1.19-next.0 - -### Patch Changes - -- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - - @backstage/plugin-catalog-react@0.6.12-next.0 - - @backstage/catalog-model@0.9.10-next.0 - -## 0.1.18 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/plugin-catalog-react@0.6.11 - - @backstage/errors@0.2.0 - - @backstage/catalog-model@0.9.9 - -## 0.1.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/plugin-catalog-react@0.6.8 - - @backstage/core-components@0.8.2 - -## 0.1.16 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- dcd1a0c3f4: Minor improvement to the API reports, by not unpacking arguments directly -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - - @backstage/plugin-catalog-react@0.6.5 - -## 0.1.15 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/catalog-model@0.9.7 - - @backstage/plugin-catalog-react@0.6.4 - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.1.14 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.6.0 - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.1.13 - -### Patch Changes - -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - - @backstage/plugin-catalog-react@0.5.2 - - @backstage/catalog-model@0.9.4 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - - @backstage/plugin-catalog-react@0.5.1 - -## 0.1.11 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - - @backstage/plugin-catalog-react@0.5.0 - - @backstage/catalog-model@0.9.3 - -## 0.1.10 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/plugin-catalog-react@0.4.6 - - @backstage/core-plugin-api@0.1.8 - -## 0.1.9 - -### Patch Changes - -- a3734ba27: Fix TodoList table column widths -- b07378742: All types are now properly documented and exported. -- Updated dependencies - - @backstage/core-components@0.4.1 - - @backstage/catalog-model@0.9.2 - - @backstage/errors@0.1.2 - - @backstage/core-plugin-api@0.1.7 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.4.5 - - @backstage/core-components@0.4.0 - - @backstage/catalog-model@0.9.1 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - - @backstage/plugin-catalog-react@0.4.1 - -## 0.1.6 - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/plugin-catalog-react@0.4.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@0.3.0 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.1.5 - - @backstage/catalog-model@0.9.0 - - @backstage/plugin-catalog-react@0.2.6 - -## 0.1.3 - -### Patch Changes - -- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. -- Updated dependencies - - @backstage/core-plugin-api@0.1.3 - - @backstage/catalog-model@0.8.4 - - @backstage/plugin-catalog-react@0.2.4 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies [add62a455] -- Updated dependencies [cc592248b] -- Updated dependencies [17c497b81] -- Updated dependencies [704875e26] - - @backstage/catalog-model@0.8.0 - - @backstage/core@0.7.11 - - @backstage/plugin-catalog-react@0.2.0 - -## 0.1.1 - -### Patch Changes - -- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 -- 675a569a9: chore: bump `react-use` dependency in all packages -- Updated dependencies [062bbf90f] -- Updated dependencies [10c008a3a] -- Updated dependencies [889d89b6e] -- Updated dependencies [16be1d093] -- Updated dependencies [3f988cb63] -- Updated dependencies [675a569a9] - - @backstage/core@0.7.9 - - @backstage/plugin-catalog-react@0.1.6 - - @backstage/catalog-model@0.7.9 diff --git a/plugins/todo/README.md b/plugins/todo/README.md deleted file mode 100644 index fd3a7f4733..0000000000 --- a/plugins/todo/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# @backstage/plugin-todo - -This plugin lists `// TODO` comments in source code. It currently exports a single component extension for use on entity pages. - -## Setup - -1. Run: - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-todo -yarn --cwd packages/backend add @backstage/plugin-todo-backend -``` - -2. Add the plugin backend: - -In a new file named `todo.ts` under `backend/src/plugins`: - -```js -import { Router } from 'express'; -import { CatalogClient } from '@backstage/catalog-client'; -import { - createRouter, - TodoReaderService, - TodoScmReader, -} from '@backstage/plugin-todo-backend'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const todoReader = TodoScmReader.fromConfig(env.config, { - logger: env.logger, - reader: env.reader, - }); - - const catalogClient = new CatalogClient({ - discoveryApi: env.discovery, - }); - - const todoService = new TodoReaderService({ - todoReader, - catalogClient, - }); - - return await createRouter({ todoService }); -} -``` - -And then add to `packages/backend/src/index.ts`: - -```js -// In packages/backend/src/index.ts -import todo from './plugins/todo'; -// ... -async function main() { - // ... - const todoEnv = useHotMemoize(module, () => createEnv('todo')); - // ... - apiRouter.use('/todo', await todo(todoEnv)); -``` - -3. Add the plugin as a tab to your service entities: - -```jsx -// In packages/app/src/components/catalog/EntityPage.tsx -import { EntityTodoContent } from '@backstage/plugin-todo'; - -const serviceEntityPage = ( - - {/* other tabs... */} - - - -``` - -## Format - -The default parser uses [Leasot](https://github.com/pgilad/leasot), which supports a wide range of languages. By default it supports the `TODO` and `FIXME` tags, along with `@` prefix and author reference through with either a `()` suffix or trailing `/`. For more information on how to configure the parser, see `@backstage/plugin-todo-backend`. - -Below are some examples of formats that are supported by default: - -```ts -// TODO: Ideally this would be working - -// TODO(Rugvip): Not sure why this works, investigate - -// @todo: This worked last Monday /Rugvip - -// FIXME Nobody knows why this is here -``` - -Note that trailing comments are not supported, the following TODO would not be listed: - -```ts -function reverse(str: string) { - return str.reverse(); // TODO: optimize -} -``` - -The scanner also ignores all dot-files and directories, meaning TODOs inside of those will not be listed. - -## Extensions - -| name | description | -| ------------------- | ------------------------------------------------------------------------------- | -| `EntityTodoContent` | Content for an entity page, showing a table of TODO items for the given entity. | diff --git a/plugins/todo/api-report.md b/plugins/todo/api-report.md deleted file mode 100644 index 215d1730bc..0000000000 --- a/plugins/todo/api-report.md +++ /dev/null @@ -1,90 +0,0 @@ -## API Report File for "@backstage/plugin-todo" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { IdentityApi } from '@backstage/core-plugin-api'; -import { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public -export const EntityTodoContent: () => JSX_2.Element; - -// @public -export interface TodoApi { - listTodos(options: TodoListOptions): Promise; -} - -// @public -export const todoApiRef: ApiRef; - -// @public -export class TodoClient implements TodoApi { - constructor(options: TodoClientOptions); - // (undocumented) - listTodos(options: TodoListOptions): Promise; -} - -// @public -export interface TodoClientOptions { - // (undocumented) - discoveryApi: DiscoveryApi; - // (undocumented) - identityApi: IdentityApi; -} - -// @public -export type TodoItem = { - text: string; - tag: string; - author?: string; - viewUrl?: string; - lineNumber?: number; - repoFilePath?: string; -}; - -// @public -export type TodoListFields = - | 'text' - | 'tag' - | 'author' - | 'viewUrl' - | 'repoFilePath'; - -// @public -export type TodoListOptions = { - entity?: Entity; - offset?: number; - limit?: number; - orderBy?: { - field: TodoListFields; - direction: 'asc' | 'desc'; - }; - filters?: { - field: TodoListFields; - value: string; - }[]; -}; - -// @public -export type TodoListResult = { - items: TodoItem[]; - totalCount: number; - offset: number; - limit: number; -}; - -// @public -export const todoPlugin: BackstagePlugin< - { - entityContent: RouteRef; - }, - {} ->; -``` diff --git a/plugins/todo/catalog-info.yaml b/plugins/todo/catalog-info.yaml deleted file mode 100644 index 4ab6c9c927..0000000000 --- a/plugins/todo/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-todo - title: '@backstage/plugin-todo' - description: A Backstage plugin that lets you browse TODO comments in your source code -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/todo/dev/index.tsx b/plugins/todo/dev/index.tsx deleted file mode 100644 index 375c89e4a4..0000000000 --- a/plugins/todo/dev/index.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 { Entity, ANNOTATION_LOCATION } from '@backstage/catalog-model'; -import { createDevApp } from '@backstage/dev-utils'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import OnlineIcon from '@material-ui/icons/Cloud'; -import OfflineIcon from '@material-ui/icons/Storage'; -import React from 'react'; -import { EntityTodoContent, todoApiRef, todoPlugin } from '../src'; - -import { Content, Header, HeaderLabel, Page } from '@backstage/core-components'; -import { TestApiProvider } from '@backstage/test-utils'; - -const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'backstage', - annotations: { - [ANNOTATION_LOCATION]: - 'https://github.com/backstage/backstage/blob/master/catalog-info.yaml', - }, - }, - spec: { - type: 'library', - }, -}; - -const mockedApi = { - listTodos: async () => ({ - items: [ - { - text: 'Make sure this works', - tag: 'TODO', - author: 'Rugvip', - viewUrl: 'https://github.com/backstage/backstage', - }, - ], - totalCount: 15, - offset: 0, - limit: 10, - }), -}; - -createDevApp() - .registerPlugin(todoPlugin) - .addPage({ - element: ( - - - -
- -
- - - -
-
-
- ), - title: 'Entity Todo Content', - icon: OfflineIcon, - }) - .addPage({ - element: ( - - -
- -
- - - -
-
- ), - title: 'Backend Connected', - icon: OnlineIcon, - }) - .render(); diff --git a/plugins/todo/knip-report.md b/plugins/todo/knip-report.md deleted file mode 100644 index ba9c1dddc5..0000000000 --- a/plugins/todo/knip-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Knip report - -## Unused devDependencies (2) - -| Name | Location | Severity | -| :--------------------- | :----------- | :------- | -| @testing-library/react | package.json | error | -| @testing-library/dom | package.json | error | - diff --git a/plugins/todo/package.json b/plugins/todo/package.json deleted file mode 100644 index c550a8071c..0000000000 --- a/plugins/todo/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@backstage/plugin-todo", - "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.34-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/todo" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/catalog-model": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/icons": "^4.9.1", - "@types/react": "^16.13.1 || ^17.0.0" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0" - }, - "files": [ - "dist", - "alpha" - ] -} diff --git a/plugins/todo/src/api/TodoClient.ts b/plugins/todo/src/api/TodoClient.ts deleted file mode 100644 index 4bfd5b77e5..0000000000 --- a/plugins/todo/src/api/TodoClient.ts +++ /dev/null @@ -1,85 +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 { stringifyEntityRef } from '@backstage/catalog-model'; -import { ResponseError } from '@backstage/errors'; -import { TodoApi, TodoListOptions, TodoListResult } from './types'; -import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; - -/** - * Options for creating a todo client. - * - * @public - */ -export interface TodoClientOptions { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; -} - -/** - * An implementation of the TodoApi that talks to the todo plugin backend. - * - * @public - */ -export class TodoClient implements TodoApi { - private readonly discoveryApi: DiscoveryApi; - private readonly identityApi: IdentityApi; - - constructor(options: TodoClientOptions) { - this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; - } - - async listTodos(options: TodoListOptions): Promise { - const { entity, offset, limit, orderBy, filters } = options; - const baseUrl = await this.discoveryApi.getBaseUrl('todo'); - const { token } = await this.identityApi.getCredentials(); - - const query = new URLSearchParams(); - if (entity) { - query.set('entity', stringifyEntityRef(entity)); - } - if (typeof offset === 'number') { - query.set('offset', String(offset)); - } - if (typeof limit === 'number') { - query.set('limit', String(limit)); - } - if (orderBy) { - query.set('orderBy', `${orderBy.field}=${orderBy.direction}`); - } - if (filters) { - for (const filter of filters) { - query.append('filter', `${filter.field}=${filter.value}`); - } - } - - const res = await fetch(`${baseUrl}/v1/todos?${query}`, { - headers: token - ? { - Authorization: `Bearer ${token}`, - } - : undefined, - }); - - if (!res.ok) { - throw await ResponseError.fromResponse(res); - } - - const data: TodoListResult = await res.json(); - return data; - } -} diff --git a/plugins/todo/src/api/index.ts b/plugins/todo/src/api/index.ts deleted file mode 100644 index b1d9792c95..0000000000 --- a/plugins/todo/src/api/index.ts +++ /dev/null @@ -1,26 +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. - */ - -export { TodoClient } from './TodoClient'; -export type { TodoClientOptions } from './TodoClient'; -export { todoApiRef } from './types'; -export type { - TodoApi, - TodoListOptions, - TodoListResult, - TodoItem, - TodoListFields, -} from './types'; diff --git a/plugins/todo/src/api/types.ts b/plugins/todo/src/api/types.ts deleted file mode 100644 index 51b846a30f..0000000000 --- a/plugins/todo/src/api/types.ts +++ /dev/null @@ -1,110 +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 { Entity } from '@backstage/catalog-model'; -import { createApiRef } from '@backstage/core-plugin-api'; - -/** - * TodoItem represents a single TODO comment in source code. - * - * @public - */ -export type TodoItem = { - /** The contents of the TODO comment */ - text: string; - - /** The tag used, e.g. TODO, FIXME */ - tag: string; - - /** References author, if any */ - author?: string; - - /** URL used to view the file */ - viewUrl?: string; - - /** The line number of the file that the TODO occurs at */ - lineNumber?: number; - - /** The path of the file containing the TODO within the repo */ - repoFilePath?: string; -}; - -/** - * Fields that can be used to filter or order todo items. - * - * @public - */ -export type TodoListFields = - | 'text' - | 'tag' - | 'author' - | 'viewUrl' - | 'repoFilePath'; - -/** - * Options used to list todo items. - * - * @public - */ -export type TodoListOptions = { - entity?: Entity; - offset?: number; - limit?: number; - orderBy?: { - field: TodoListFields; - direction: 'asc' | 'desc'; - }; - filters?: { - field: TodoListFields; - /** Value to filter by, with '*' used as wildcard */ - value: string; - }[]; -}; - -/** - * The result of listing todos. - * - * @public - */ -export type TodoListResult = { - items: TodoItem[]; - totalCount: number; - offset: number; - limit: number; -}; - -/** - * The API used by the todo-plugin to list todos. - * - * @public - */ -export interface TodoApi { - /** - * Lists todo items. - * - * @public - */ - listTodos(options: TodoListOptions): Promise; -} - -/** - * ApiRef for the TodoApi. - * - * @public - */ -export const todoApiRef = createApiRef({ - id: 'plugin.todo.api', -}); diff --git a/plugins/todo/src/components/TodoList/TodoList.test.tsx b/plugins/todo/src/components/TodoList/TodoList.test.tsx deleted file mode 100644 index 15d4334610..0000000000 --- a/plugins/todo/src/components/TodoList/TodoList.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 { Entity } from '@backstage/catalog-model'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { renderWithEffects, TestApiProvider } from '@backstage/test-utils'; -import React from 'react'; -import { TodoApi, todoApiRef } from '../../api'; -import { TodoList } from './TodoList'; - -describe('TodoList', () => { - it('should render', async () => { - const mockApi: jest.Mocked = { - listTodos: jest.fn().mockResolvedValue({ - items: [ - { - text: 'My TODO', - tag: 'FIXME', - viewUrl: 'https://example.com', - repoFilePath: '/my-file.js', - }, - ], - totalCount: 1, - limit: 10, - offset: 0, - }), - }; - const mockEntity = { - metadata: { name: 'mock' }, - kind: 'MockKind', - } as Entity; - - const rendered = await renderWithEffects( - - - - - , - ); - - await expect(rendered.findByText('FIXME')).resolves.toBeInTheDocument(); - }); -}); diff --git a/plugins/todo/src/components/TodoList/TodoList.tsx b/plugins/todo/src/components/TodoList/TodoList.tsx deleted file mode 100644 index 653f825f6a..0000000000 --- a/plugins/todo/src/components/TodoList/TodoList.tsx +++ /dev/null @@ -1,123 +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 { useEntity } from '@backstage/plugin-catalog-react'; -import React, { useState } from 'react'; -import { todoApiRef } from '../../api'; -import { TodoItem, TodoListOptions } from '../../api/types'; - -import { - Table, - TableColumn, - OverflowTooltip, - Link, - ResponseErrorPanel, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; - -const PAGE_SIZE = 10; - -const columns: TableColumn[] = [ - { - title: 'Tag', - field: 'tag', - width: '10%', - filtering: false, - }, - { - title: 'Text', - field: 'text', - width: '55%', - highlight: true, - render: ({ text }) => , - }, - { - title: 'File', - field: 'repoFilePath', - width: '25%', - render: ({ viewUrl, repoFilePath }) => - viewUrl ? ( - - - - ) : ( - - ), - }, - { - title: 'Author', - field: 'author', - width: '10%', - render: ({ author }) => , - }, -]; - -export const TodoList = () => { - const { entity } = useEntity(); - const todoApi = useApi(todoApiRef); - const [error, setError] = useState(); - - if (error) { - return ; - } - - return ( - - title="TODOs" - options={{ - search: false, - pageSize: PAGE_SIZE, - padding: 'dense', - sorting: true, - draggable: false, - paging: true, - filtering: true, - debounceInterval: 500, - filterCellStyle: { padding: '0 16px 0 20px' }, - }} - columns={columns} - data={async query => { - try { - const page = query?.page ?? 0; - const pageSize = query?.pageSize ?? PAGE_SIZE; - const result = await todoApi.listTodos({ - entity, - offset: page * pageSize, - limit: pageSize, - orderBy: - query?.orderBy && - ({ - field: query.orderBy.field, - direction: query.orderDirection, - } as TodoListOptions['orderBy']), - filters: query?.filters?.map(filter => ({ - field: filter.column.field!, - value: `*${filter.value}*`, - })) as TodoListOptions['filters'], - }); - return { - data: result.items, - totalCount: result.totalCount, - page: Math.floor(result.offset / result.limit), - }; - } catch (loadingError) { - setError(loadingError); - return { data: [], totalCount: 0, page: 0 }; - } - }} - /> - ); -}; diff --git a/plugins/todo/src/components/TodoList/index.ts b/plugins/todo/src/components/TodoList/index.ts deleted file mode 100644 index d3f09de9fa..0000000000 --- a/plugins/todo/src/components/TodoList/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { TodoList } from './TodoList'; diff --git a/plugins/todo/src/index.ts b/plugins/todo/src/index.ts deleted file mode 100644 index 3cd8d1f5c1..0000000000 --- a/plugins/todo/src/index.ts +++ /dev/null @@ -1,32 +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. - */ - -/** - * A Backstage plugin that lets you browse TODO comments in your source code - * - * @packageDocumentation - */ - -export { todoApiRef, TodoClient } from './api'; -export type { - TodoApi, - TodoListOptions, - TodoListResult, - TodoItem, - TodoListFields, - TodoClientOptions, -} from './api'; -export { todoPlugin, EntityTodoContent } from './plugin'; diff --git a/plugins/todo/src/plugin.test.tsx b/plugins/todo/src/plugin.test.tsx deleted file mode 100644 index 571a41e657..0000000000 --- a/plugins/todo/src/plugin.test.tsx +++ /dev/null @@ -1,67 +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 { Route, Routes } from 'react-router-dom'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { todoPlugin, EntityTodoContent } from './plugin'; -import { todoApiRef } from './api'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; - -describe('todo', () => { - it('should export plugin', () => { - expect(todoPlugin).toBeDefined(); - }); - - it('should render EntityTodoContent', async () => { - const rendered = await renderInTestApp( - ({ - items: [ - { - tag: 'FIXME', - text: 'Make sure this test works', - }, - ], - limit: 10, - offset: 0, - totalCount: 1, - }), - }, - ], - ]} - > - - - } /> - - - , - ); - - await expect(rendered.findByText('FIXME')).resolves.toBeInTheDocument(); - }); -}); diff --git a/plugins/todo/src/plugin.ts b/plugins/todo/src/plugin.ts deleted file mode 100644 index d74acfb02c..0000000000 --- a/plugins/todo/src/plugin.ts +++ /dev/null @@ -1,61 +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 { todoApiRef, TodoClient } from './api'; -import { - createApiFactory, - createPlugin, - createRoutableExtension, - discoveryApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; -import { rootRouteRef } from './routes'; - -/** - * The Todo plugin instance. - * - * @public - */ -export const todoPlugin = createPlugin({ - id: 'todo', - apis: [ - createApiFactory({ - api: todoApiRef, - deps: { - identityApi: identityApiRef, - discoveryApi: discoveryApiRef, - }, - factory({ identityApi, discoveryApi }) { - return new TodoClient({ identityApi, discoveryApi }); - }, - }), - ], - routes: { - entityContent: rootRouteRef, - }, -}); - -/** - * An extension for displaying the list of todos on an entity page. - * - * @public - */ -export const EntityTodoContent = todoPlugin.provide( - createRoutableExtension({ - name: 'EntityTodoContent', - component: () => import('./components/TodoList').then(m => m.TodoList), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/todo/src/routes.ts b/plugins/todo/src/routes.ts deleted file mode 100644 index 01d8d9f354..0000000000 --- a/plugins/todo/src/routes.ts +++ /dev/null @@ -1,20 +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 { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'todo', -}); diff --git a/plugins/todo/src/setupTests.ts b/plugins/todo/src/setupTests.ts deleted file mode 100644 index 7435872609..0000000000 --- a/plugins/todo/src/setupTests.ts +++ /dev/null @@ -1,16 +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 '@testing-library/jest-dom'; diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 4da1c31e54..7aa3b634d1 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,137 @@ # @backstage/plugin-user-settings-backend +## 0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.13-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/backend-plugin-api@0.6.18-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/backend-plugin-api@0.6.17 + - @backstage/plugin-auth-node@0.4.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/backend-plugin-api@0.6.17-next.1 + - @backstage/plugin-auth-node@0.4.12-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.0 + - @backstage/backend-plugin-api@0.6.17-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-node@0.4.12-next.0 + +## 0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.4.11 + - @backstage/backend-common@0.21.6 + - @backstage/backend-plugin-api@0.6.16 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-auth-node@0.4.10 + - @backstage/backend-plugin-api@0.6.15 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/plugin-auth-node@0.4.9 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/backend-plugin-api@0.6.14 + - @backstage/types@1.1.1 + +## 0.2.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.4-next.2 + - @backstage/plugin-auth-node@0.4.9-next.2 + - @backstage/backend-plugin-api@0.6.14-next.2 + - @backstage/config@1.2.0-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/backend-plugin-api@0.6.14-next.1 + - @backstage/plugin-auth-node@0.4.9-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-auth-node@0.4.8-next.0 + - @backstage/errors@1.2.4-next.0 + - @backstage/backend-plugin-api@0.6.13-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/types@1.1.1 + +## 0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/plugin-auth-node@0.4.4 + - @backstage/backend-plugin-api@0.6.10 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.2.9-next.3 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index 9cdb959df1..b8e9949bcf 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,21 +1,27 @@ { "name": "@backstage/plugin-user-settings-backend", + "version": "0.2.17-next.0", "description": "The Backstage backend plugin to manage user settings", - "version": "0.2.9-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", "backstage": { "role": "backend-plugin" }, "publishConfig": { "access": "public" }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/user-settings-backend" + }, + "license": "Apache-2.0", "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -26,20 +32,18 @@ ] } }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/user-settings-backend" - }, + "files": [ + "dist", + "migrations" + ], "scripts": { - "start": "backstage-cli package start", "build": "backstage-cli package build", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -60,10 +64,5 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" - }, - "files": [ - "dist", - "migrations", - "alpha" - ] + } } diff --git a/plugins/user-settings/.eslintrc.js b/plugins/user-settings/.eslintrc.js index e2a53a6ad2..a2d8179106 100644 --- a/plugins/user-settings/.eslintrc.js +++ b/plugins/user-settings/.eslintrc.js @@ -1 +1,5 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 85079772a8..95fbfa85eb 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,178 @@ # @backstage/plugin-user-settings +## 0.8.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/types@1.1.1 + +## 0.8.5 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-app-api@1.12.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.8.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.12.4-next.0 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.1 + +## 0.8.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-app-api@1.12.3 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-react@1.11.3-next.0 + +## 0.8.4 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/core-app-api@1.12.3 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## 0.8.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/core-app-api@1.12.2 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/types@1.1.1 + +## 0.8.2 + +### Patch Changes + +- ee584af: Added ESLint rule `no-top-level-material-ui-4-imports` in the `user-settings` plugin to migrate the Material UI imports. +- Updated dependencies + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/core-app-api@1.12.1 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/types@1.1.1 + +## 0.8.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## 0.8.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-app-api@1.12.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/types@1.1.1 + +## 0.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-app-api@1.12.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + - @backstage/types@1.1.1 + +## 0.8.1 + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- d5b14a0: conditionally rendering the user name and email in user settings page +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/core-app-api@1.12.0 + - @backstage/theme@0.5.1 + - @backstage/core-plugin-api@1.9.0 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + ## 0.8.1-next.3 ### Patch Changes diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index b92677f8ce..d485320fe8 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -24,7 +24,7 @@ import { RouteRef } from '@backstage/core-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; import { StorageApi } from '@backstage/core-plugin-api'; import { StorageValueSnapshot } from '@backstage/core-plugin-api'; -import { TabProps } from '@material-ui/core'; +import { TabProps } from '@material-ui/core/Tab'; // @public (undocumented) export const DefaultProviderSettings: (props: { diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 10afb0db5b..40c1b0772f 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,15 +1,31 @@ { "name": "@backstage/plugin-user-settings", + "version": "0.8.6-next.0", "description": "A Backstage plugin that provides a settings page", - "version": "0.8.1-next.3", - "main": "src/index.ts", - "types": "src/index.ts", + "backstage": { + "role": "frontend-plugin" + }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "backstage" + ], + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/user-settings" + }, "license": "Apache-2.0", + "sideEffects": false, "exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.tsx", "./package.json": "./package.json" }, + "main": "src/index.ts", + "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ @@ -20,30 +36,17 @@ ] } }, - "publishConfig": { - "access": "public" - }, - "backstage": { - "role": "frontend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/user-settings" - }, - "keywords": [ - "backstage" + "files": [ + "dist" ], - "sideEffects": false, "scripts": { "build": "backstage-cli package build", - "start": "backstage-cli package start", + "clean": "backstage-cli package clean", "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", + "test": "backstage-cli package test" }, "dependencies": { "@backstage/core-app-api": "workspace:^", @@ -62,25 +65,22 @@ "react-use": "^17.2.4", "zen-observable": "^0.10.0" }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/dev-utils": "workspace:^", "@backstage/plugin-catalog": "workspace:^", "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^15.0.0", "@testing-library/user-event": "^14.0.0", "msw": "^1.0.0" }, - "files": [ - "dist" - ], + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, "configSchema": { "$schema": "https://backstage.io/schema/config-v1", "title": "@backstage/user-settings", diff --git a/plugins/user-settings/src/components/AuthProviders/EmptyProviders.tsx b/plugins/user-settings/src/components/AuthProviders/EmptyProviders.tsx index 082cb5e8ac..952ba3af30 100644 --- a/plugins/user-settings/src/components/AuthProviders/EmptyProviders.tsx +++ b/plugins/user-settings/src/components/AuthProviders/EmptyProviders.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { Button, Typography } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; import { CodeSnippet, EmptyState } from '@backstage/core-components'; const EXAMPLE = `auth: diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx index 07e9b4aa55..c09dac5985 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { makeStyles, Avatar, Theme } from '@material-ui/core'; +import Avatar from '@material-ui/core/Avatar'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import { sidebarConfig } from '@backstage/core-components'; const useStyles = makeStyles(theme => ({ diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index e9a710036f..07afd8083e 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -15,16 +15,14 @@ */ import React, { useEffect, useState } from 'react'; -import { - Button, - Grid, - ListItem, - ListItemIcon, - ListItemSecondaryAction, - ListItemText, - Tooltip, - Typography, -} from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import Grid from '@material-ui/core/Grid'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemText from '@material-ui/core/ListItemText'; +import Tooltip from '@material-ui/core/Tooltip'; +import Typography from '@material-ui/core/Typography'; import { ApiRef, SessionApi, diff --git a/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.tsx b/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.tsx index d23716c2bf..e83440e0c5 100644 --- a/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.tsx +++ b/plugins/user-settings/src/components/AuthProviders/UserSettingsAuthProviders.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { List } from '@material-ui/core'; +import List from '@material-ui/core/List'; import { EmptyProviders } from './EmptyProviders'; import { DefaultProviderSettings } from './DefaultProviderSettings'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx index 243e348319..e31c9f26fd 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx @@ -34,7 +34,7 @@ describe('', () => { it('should render the settings page with 3 tabs', async () => { const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(3); }); @@ -48,7 +48,7 @@ describe('', () => { , ); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); }); @@ -63,7 +63,7 @@ describe('', () => { , ); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); }); diff --git a/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx b/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx index 0e2b911978..55c70ba7a2 100644 --- a/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx +++ b/plugins/user-settings/src/components/FeatureFlags/EmptyFlags.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { Button, Typography } from '@material-ui/core'; +import Button from '@material-ui/core/Button'; +import Typography from '@material-ui/core/Typography'; import { CodeSnippet, EmptyState } from '@backstage/core-components'; const EXAMPLE = `import { createPlugin } from '@backstage/core-plugin-api'; diff --git a/plugins/user-settings/src/components/FeatureFlags/FeatureFlagsItem.tsx b/plugins/user-settings/src/components/FeatureFlags/FeatureFlagsItem.tsx index a5f0d480cb..96f8166c4a 100644 --- a/plugins/user-settings/src/components/FeatureFlags/FeatureFlagsItem.tsx +++ b/plugins/user-settings/src/components/FeatureFlags/FeatureFlagsItem.tsx @@ -15,13 +15,11 @@ */ import React from 'react'; -import { - ListItem, - ListItemText, - ListItemIcon, - Switch, - Tooltip, -} from '@material-ui/core'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import Switch from '@material-ui/core/Switch'; +import Tooltip from '@material-ui/core/Tooltip'; import { FeatureFlag } from '@backstage/core-plugin-api'; type Props = { diff --git a/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx b/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx index 60b951ab60..1522001ac5 100644 --- a/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx +++ b/plugins/user-settings/src/components/FeatureFlags/UserSettingsFeatureFlags.tsx @@ -15,13 +15,11 @@ */ import React, { useCallback, useState } from 'react'; -import { - List, - TextField, - IconButton, - Grid, - Typography, -} from '@material-ui/core'; +import List from '@material-ui/core/List'; +import TextField from '@material-ui/core/TextField'; +import IconButton from '@material-ui/core/IconButton'; +import Grid from '@material-ui/core/Grid'; +import Typography from '@material-ui/core/Typography'; import { EmptyFlags } from './EmptyFlags'; import { FlagItem } from './FeatureFlagsItem'; import { diff --git a/plugins/user-settings/src/components/General/UserSettingsAppearanceCard.tsx b/plugins/user-settings/src/components/General/UserSettingsAppearanceCard.tsx index 8a32c0bd9b..b8e3c44672 100644 --- a/plugins/user-settings/src/components/General/UserSettingsAppearanceCard.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsAppearanceCard.tsx @@ -15,7 +15,7 @@ */ import { InfoCard, useSidebarPinState } from '@backstage/core-components'; -import { List } from '@material-ui/core'; +import List from '@material-ui/core/List'; import React from 'react'; import { UserSettingsPinToggle } from './UserSettingsPinToggle'; import { UserSettingsThemeToggle } from './UserSettingsThemeToggle'; diff --git a/plugins/user-settings/src/components/General/UserSettingsGeneral.tsx b/plugins/user-settings/src/components/General/UserSettingsGeneral.tsx index 8dde87ba5c..6c663ed1bc 100644 --- a/plugins/user-settings/src/components/General/UserSettingsGeneral.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsGeneral.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Grid } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; import React from 'react'; import { UserSettingsProfileCard } from './UserSettingsProfileCard'; import { UserSettingsAppearanceCard } from './UserSettingsAppearanceCard'; diff --git a/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx b/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx index 15c6e9ea9c..1e3ba793f6 100644 --- a/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx @@ -19,15 +19,13 @@ import { useTranslationRef, appLanguageApiRef, } from '@backstage/core-plugin-api/alpha'; -import { - ListItem, - ListItemText, - ListItemSecondaryAction, - makeStyles, -} from '@material-ui/core'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import { makeStyles } from '@material-ui/core/styles'; import { userSettingsTranslationRef } from '../../translation'; import { useApi } from '@backstage/core-plugin-api'; -import useObservable from 'react-use/lib/useObservable'; +import useObservable from 'react-use/esm/useObservable'; import { Select } from '@backstage/core-components'; const useStyles = makeStyles(theme => ({ diff --git a/plugins/user-settings/src/components/General/UserSettingsMenu.tsx b/plugins/user-settings/src/components/General/UserSettingsMenu.tsx index c83bdd5b74..8ef2f380f3 100644 --- a/plugins/user-settings/src/components/General/UserSettingsMenu.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsMenu.tsx @@ -15,7 +15,10 @@ */ import React from 'react'; -import { IconButton, ListItemIcon, Menu, MenuItem } from '@material-ui/core'; +import IconButton from '@material-ui/core/IconButton'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; import SignOutIcon from '@material-ui/icons/MeetingRoom'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import { diff --git a/plugins/user-settings/src/components/General/UserSettingsPinToggle.tsx b/plugins/user-settings/src/components/General/UserSettingsPinToggle.tsx index a06b079e8e..95317147cf 100644 --- a/plugins/user-settings/src/components/General/UserSettingsPinToggle.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsPinToggle.tsx @@ -15,13 +15,11 @@ */ import React from 'react'; -import { - ListItem, - ListItemSecondaryAction, - ListItemText, - Switch, - Tooltip, -} from '@material-ui/core'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import ListItemText from '@material-ui/core/ListItemText'; +import Switch from '@material-ui/core/Switch'; +import Tooltip from '@material-ui/core/Tooltip'; import { useSidebarPinState } from '@backstage/core-components'; /** @public */ diff --git a/plugins/user-settings/src/components/General/UserSettingsProfileCard.tsx b/plugins/user-settings/src/components/General/UserSettingsProfileCard.tsx index c96d2bb21e..c04710650c 100644 --- a/plugins/user-settings/src/components/General/UserSettingsProfileCard.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsProfileCard.tsx @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Grid, Typography } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import Typography from '@material-ui/core/Typography'; import React from 'react'; import { UserSettingsSignInAvatar } from './UserSettingsSignInAvatar'; import { UserSettingsMenu } from './UserSettingsMenu'; diff --git a/plugins/user-settings/src/components/General/UserSettingsSignInAvatar.tsx b/plugins/user-settings/src/components/General/UserSettingsSignInAvatar.tsx index 85c616ec72..80621d1a53 100644 --- a/plugins/user-settings/src/components/General/UserSettingsSignInAvatar.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsSignInAvatar.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; -import { makeStyles, Avatar, Theme } from '@material-ui/core'; +import Avatar from '@material-ui/core/Avatar'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import { useUserProfile } from '../useUserProfileInfo'; import { sidebarConfig } from '@backstage/core-components'; diff --git a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx index 37d91ecae0..cfa9873531 100644 --- a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx @@ -15,17 +15,15 @@ */ import React, { cloneElement } from 'react'; -import useObservable from 'react-use/lib/useObservable'; +import useObservable from 'react-use/esm/useObservable'; import AutoIcon from '@material-ui/icons/BrightnessAuto'; import ToggleButton from '@material-ui/lab/ToggleButton'; import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup'; -import { - ListItem, - ListItemText, - ListItemSecondaryAction, - Tooltip, - makeStyles, -} from '@material-ui/core'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import Tooltip from '@material-ui/core/Tooltip'; +import { makeStyles } from '@material-ui/core/styles'; import { appThemeApiRef, useApi } from '@backstage/core-plugin-api'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { userSettingsTranslationRef } from '../../translation'; diff --git a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx index 9855fdd048..c17333571d 100644 --- a/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx +++ b/plugins/user-settings/src/components/SettingsLayout/SettingsLayout.tsx @@ -15,7 +15,7 @@ */ import React from 'react'; -import { TabProps } from '@material-ui/core'; +import { TabProps } from '@material-ui/core/Tab'; import { Header, Page, diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx index 8f2efa73f4..f6be87f14f 100644 --- a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx @@ -36,7 +36,7 @@ describe('', () => { it('should render the default settings page with 3 tabs', async () => { const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(3); }); @@ -49,7 +49,7 @@ describe('', () => { (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); }); @@ -63,7 +63,7 @@ describe('', () => { (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); const user = userEvent.setup(); @@ -86,7 +86,7 @@ describe('', () => { (useOutlet as jest.Mock).mockReturnValue(customLayout); const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(2); expect(tabs[0].textContent).toEqual('General'); expect(tabs[1].textContent).toEqual('Advanced'); diff --git a/plugins/user-settings/src/components/useUserProfileInfo.ts b/plugins/user-settings/src/components/useUserProfileInfo.ts index 8b2a41a55f..ee4578cd6b 100644 --- a/plugins/user-settings/src/components/useUserProfileInfo.ts +++ b/plugins/user-settings/src/components/useUserProfileInfo.ts @@ -21,7 +21,7 @@ import { useApi, } from '@backstage/core-plugin-api'; import { useEffect } from 'react'; -import useAsync from 'react-use/lib/useAsync'; +import useAsync from 'react-use/esm/useAsync'; /** @public */ export const useUserProfile = () => { diff --git a/plugins/vault-backend/.eslintrc.js b/plugins/vault-backend/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/vault-backend/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md deleted file mode 100644 index b68b02d405..0000000000 --- a/plugins/vault-backend/CHANGELOG.md +++ /dev/null @@ -1,985 +0,0 @@ -# @backstage/plugin-vault-backend - -## 0.4.3-next.3 - -### Patch Changes - -- 8472188: Added or fixed the `repository` field in `package.json`. -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/backend-tasks@0.5.15-next.3 - - @backstage/plugin-vault-node@0.1.3-next.3 - - @backstage/backend-plugin-api@0.6.10-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.4.3-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/backend-plugin-api@0.6.10-next.2 - - @backstage/backend-tasks@0.5.15-next.2 - - @backstage/plugin-vault-node@0.1.3-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.4.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.1 - - @backstage/backend-common@0.21.0-next.1 - - @backstage/backend-tasks@0.5.15-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.3-next.1 - -## 0.4.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/backend-tasks@0.5.15-next.0 - - @backstage/backend-plugin-api@0.6.10-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.3-next.0 - -## 0.4.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/backend-plugin-api@0.6.9 - - @backstage/backend-tasks@0.5.14 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.2 - -## 0.4.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - - @backstage/backend-common@0.20.1-next.2 - - @backstage/plugin-vault-node@0.1.2-next.2 - - @backstage/backend-tasks@0.5.14-next.2 - -## 0.4.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/backend-tasks@0.5.14-next.1 - - @backstage/backend-plugin-api@0.6.9-next.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.2-next.1 - -## 0.4.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/backend-plugin-api@0.6.9-next.0 - - @backstage/backend-tasks@0.5.14-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.2-next.0 - -## 0.4.1 - -### Patch Changes - -- b7de76a: Updated to test using PostgreSQL 12 and 16 -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/backend-tasks@0.5.13 - - @backstage/backend-plugin-api@0.6.8 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.1 - -## 0.4.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/backend-plugin-api@0.6.8-next.3 - - @backstage/backend-tasks@0.5.13-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.1-next.3 - -## 0.4.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/backend-plugin-api@0.6.8-next.2 - - @backstage/backend-tasks@0.5.13-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.1-next.2 - -## 0.4.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/backend-plugin-api@0.6.8-next.1 - - @backstage/backend-tasks@0.5.13-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.1-next.1 - -## 0.4.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/backend-tasks@0.5.13-next.0 - - @backstage/backend-plugin-api@0.6.8-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.1-next.0 - -## 0.4.0 - -### Minor Changes - -- a873a32a1f: Added support for the [new backend system](https://backstage.io/docs/backend-system/). - - In your `packages/backend/src/index.ts` make the following changes: - - ```diff - import { createBackend } from '@backstage/backend-defaults'; - const backend = createBackend(); - // ... other feature additions - + backend.add(import('@backstage/plugin-vault-backend'); - backend.start(); - ``` - - If you use the new backend system, the token renewal task can be defined via configuration file: - - ```diff - vault: - baseUrl: - token: - schedule: - + frequency: ... - + timeout: ... - + # Other schedule options, such as scope or initialDelay - ``` - - If the `schedule` is omitted or set to `false` no token renewal task will be scheduled. - If the value of `schedule` is set to `true` the renew will be scheduled hourly (the default). - In other cases (like in the diff above), the defined schedule will be used. - - **DEPRECATIONS**: The interface `VaultApi` and the type `VaultSecret` are now deprecated. Import them from `@backstage/plugin-vault-node`. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-vault-node@0.1.0 - - @backstage/backend-common@0.19.9 - - @backstage/backend-plugin-api@0.6.7 - - @backstage/backend-tasks@0.5.12 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.4.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - - @backstage/backend-common@0.19.9-next.2 - - @backstage/backend-tasks@0.5.12-next.2 - - @backstage/plugin-vault-node@0.1.0-next.2 - -## 0.4.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/backend-tasks@0.5.12-next.1 - - @backstage/backend-plugin-api@0.6.7-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/plugin-vault-node@0.1.0-next.1 - -## 0.4.0-next.0 - -### Minor Changes - -- a873a32a1f: Added support for the [new backend system](https://backstage.io/docs/backend-system/). - - In your `packages/backend/src/index.ts` make the following changes: - - ```diff - import { createBackend } from '@backstage/backend-defaults'; - const backend = createBackend(); - // ... other feature additions - + backend.add(import('@backstage/plugin-vault-backend'); - backend.start(); - ``` - - If you use the new backend system, the token renewal task can be defined via configuration file: - - ```diff - vault: - baseUrl: - token: - schedule: - + frequency: ... - + timeout: ... - + # Other schedule options, such as scope or initialDelay - ``` - - If the `schedule` is omitted or set to `false` no token renewal task will be scheduled. - If the value of `schedule` is set to `true` the renew will be scheduled hourly (the default). - In other cases (like in the diff above), the defined schedule will be used. - - **DEPRECATIONS**: The interface `VaultApi` and the type `VaultSecret` are now deprecated. Import them from `@backstage/plugin-vault-node`. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-vault-node@0.1.0-next.0 - - @backstage/backend-common@0.19.9-next.0 - - @backstage/backend-plugin-api@0.6.7-next.0 - - @backstage/backend-tasks@0.5.12-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - -## 0.3.11 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.11 - - @backstage/backend-common@0.19.8 - - @backstage/errors@1.2.3 - - @backstage/config@1.1.1 - -## 0.3.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/backend-tasks@0.5.11-next.2 - - @backstage/config@1.1.1-next.0 - -## 0.3.10-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.10-next.1 - - @backstage/backend-common@0.19.7-next.1 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.3.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/backend-tasks@0.5.10-next.0 - - @backstage/errors@1.2.2 - -## 0.3.8 - -### Patch Changes - -- 858a18800870: Added ability to override vault secret engine value on catalog entity level using annotation `vault.io/secrets-engine` -- Updated dependencies - - @backstage/backend-tasks@0.5.8 - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - -## 0.3.7 - -Skipped due to publishing issues. - -## 0.3.7-next.3 - -### Patch Changes - -- 858a18800870: Added ability to override vault secret engine value on catalog entity level using annotation `vault.io/secrets-engine` -- Updated dependencies - - @backstage/config@1.1.0-next.2 - - @backstage/errors@1.2.2-next.0 - - @backstage/backend-common@0.19.5-next.3 - - @backstage/backend-tasks@0.5.8-next.3 - -## 0.3.7-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-tasks@0.5.8-next.2 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/errors@1.2.1 - -## 0.3.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-tasks@0.5.8-next.1 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/errors@1.2.1 - -## 0.3.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/backend-tasks@0.5.7-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.3.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/backend-tasks@0.5.5 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.3.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.5-next.2 - - @backstage/backend-common@0.19.2-next.2 - -## 0.3.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/backend-tasks@0.5.5-next.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.3.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/backend-tasks@0.5.5-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - -## 0.3.3 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/backend-tasks@0.5.4 - - @backstage/config@1.0.8 - -## 0.3.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/backend-tasks@0.5.4-next.0 - - @backstage/config@1.0.8 - -## 0.3.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/errors@1.2.0 - - @backstage/backend-tasks@0.5.3 - - @backstage/config@1.0.8 - -## 0.3.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/backend-tasks@0.5.3-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.2.0-next.0 - -## 0.3.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/errors@1.2.0-next.0 - - @backstage/backend-tasks@0.5.3-next.1 - - @backstage/config@1.0.7 - -## 0.3.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-tasks@0.5.3-next.0 - - @backstage/errors@1.1.5 - -## 0.3.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/backend-tasks@0.5.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.3.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/backend-tasks@0.5.2-next.1 - - @backstage/config@1.0.7 - -## 0.3.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/backend-tasks@0.5.2-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.3.0 - -### Minor Changes - -- 5e959c9eb62: Allow generic Vault clients to be passed into the builder - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/backend-tasks@0.5.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.3.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/backend-tasks@0.5.1-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.3.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.1-next.1 - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - -## 0.3.0-next.0 - -### Minor Changes - -- 5e959c9eb62: Allow generic Vault clients to be passed into the builder - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/backend-tasks@0.5.1-next.0 - - @backstage/errors@1.1.5 - -## 0.2.10 - -### Patch Changes - -- 66b3a3956b8: Ignore the `eslint` error -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/backend-tasks@0.5.0 - - @backstage/backend-common@0.18.3 - - @backstage/errors@1.1.5 - - @backstage/config@1.0.7 - -## 0.2.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.5.0-next.2 - - @backstage/backend-common@0.18.3-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.2.10-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/backend-common@0.18.3-next.1 - - @backstage/backend-tasks@0.4.4-next.1 - - @backstage/config@1.0.7-next.0 - -## 0.2.10-next.0 - -### Patch Changes - -- 66b3a3956b: Ignore the `eslint` error -- Updated dependencies - - @backstage/backend-tasks@0.4.4-next.0 - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.2.8 - -### Patch Changes - -- 5b7cd5580d: Moving the backend-test-utils to devDependencies. -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/backend-tasks@0.4.3 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.2.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-test-utils@0.1.34-next.2 - - @backstage/backend-common@0.18.2-next.2 - - @backstage/backend-tasks@0.4.3-next.2 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.2.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/backend-tasks@0.4.3-next.1 - - @backstage/backend-test-utils@0.1.34-next.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.2.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-test-utils@0.1.34-next.0 - - @backstage/backend-common@0.18.2-next.0 - - @backstage/backend-tasks@0.4.3-next.0 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/backend-test-utils@0.1.32 - - @backstage/backend-tasks@0.4.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - -## 0.2.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-test-utils@0.1.32-next.2 - - @backstage/backend-common@0.18.0-next.1 - - @backstage/backend-tasks@0.4.1-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - -## 0.2.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-test-utils@0.1.32-next.1 - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/backend-tasks@0.4.1-next.0 - - @backstage/errors@1.1.4 - -## 0.2.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/backend-tasks@0.4.0 - - @backstage/backend-test-utils@0.1.32-next.0 - - @backstage/config@1.0.5 - - @backstage/errors@1.1.4 - -## 0.2.5 - -### Patch Changes - -- 568ae02463: Added (optional) config `vault.publicUrl` as alternative to `vault.baseUrl` for `editUrl` and `showUrl` in case `vault.baseUrl` is internal -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 7a3d2688ed: Use `express-promise-router` to catch errors properly. - Add `403` error as a known one. It will now return a `NotAllowed` error. -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/backend-tasks@0.4.0 - - @backstage/backend-test-utils@0.1.31 - - @backstage/errors@1.1.4 - - @backstage/config@1.0.5 - -## 0.2.5-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.4.0-next.3 - - @backstage/backend-common@0.17.0-next.3 - - @backstage/backend-test-utils@0.1.31-next.4 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/backend-tasks@0.4.0-next.2 - - @backstage/backend-test-utils@0.1.31-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.2 - -### Patch Changes - -- 568ae02463: Added (optional) config `vault.publicUrl` as alternative to `vault.baseUrl` for `editUrl` and `showUrl` in case `vault.baseUrl` is internal -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/backend-test-utils@0.1.31-next.2 - - @backstage/backend-tasks@0.4.0-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/backend-tasks@0.4.0-next.1 - - @backstage/backend-test-utils@0.1.31-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.2.5-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- 7a3d2688ed: Use `express-promise-router` to catch errors properly. - Add `403` error as a known one. It will now return a `NotAllowed` error. -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/backend-test-utils@0.1.31-next.0 - - @backstage/backend-tasks@0.3.8-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - -## 0.2.4 - -### Patch Changes - -- 687237da4c: Added `errorHandler()` middleware to `router` to prevent crashes caused by fatal errors in plugin backend -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/backend-tasks@0.3.7 - - @backstage/backend-test-utils@0.1.30 - - @backstage/config@1.0.4 - - @backstage/errors@1.1.3 - -## 0.2.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/backend-tasks@0.3.7-next.1 - - @backstage/backend-test-utils@0.1.30-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.2.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/backend-tasks@0.3.7-next.0 - - @backstage/backend-test-utils@0.1.30-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.2.3 - -### Patch Changes - -- 9c595302cb: Normalize on winston version ^3.2.1 -- dae0bbe522: VaultBuilder.tsx renamed to VaultBuilder in order for module to be correctly loaded. -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/backend-test-utils@0.1.29 - - @backstage/backend-tasks@0.3.6 - - @backstage/config@1.0.3 - - @backstage/errors@1.1.2 - -## 0.2.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.3.6-next.2 - - @backstage/backend-common@0.15.2-next.2 - - @backstage/backend-test-utils@0.1.29-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/errors@1.1.2-next.2 - -## 0.2.3-next.1 - -### Patch Changes - -- dae0bbe522: VaultBuilder.tsx renamed to VaultBuilder in order for module to be correctly loaded. -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/backend-tasks@0.3.6-next.1 - - @backstage/backend-test-utils@0.1.29-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/errors@1.1.2-next.1 - -## 0.2.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-test-utils@0.1.29-next.0 - - @backstage/backend-common@0.15.2-next.0 - - @backstage/backend-tasks@0.3.6-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/errors@1.1.2-next.0 - -## 0.2.2 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- 148568b5c2: Switched to using node-fetch instead of cross-fetch as is standard for our backend packages -- 60b85d8ade: Updated dependency `helmet` to `^6.0.0`. - - Please note that these policies are no longer applied by default: - - helmet.contentSecurityPolicy no longer sets block-all-mixed-content directive by default - helmet.expectCt is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/backend-tasks@0.3.5 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - - @backstage/backend-test-utils@0.1.28 - -## 0.2.2-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/backend-test-utils@0.1.28-next.3 - - @backstage/backend-common@0.15.1-next.3 - - @backstage/backend-tasks@0.3.5-next.1 - -## 0.2.2-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.2 - - @backstage/backend-test-utils@0.1.28-next.2 - -## 0.2.2-next.1 - -### Patch Changes - -- 148568b5c2: Switched to using node-fetch instead of cross-fetch as is standard for our backend packages -- 60b85d8ade: Updated dependency `helmet` to `^6.0.0`. - - Please note that these policies are no longer applied by default: - - helmet.contentSecurityPolicy no longer sets block-all-mixed-content directive by default - helmet.expectCt is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. - -- Updated dependencies - - @backstage/backend-common@0.15.1-next.1 - - @backstage/backend-test-utils@0.1.28-next.1 - -## 0.2.2-next.0 - -### Patch Changes - -- 3f739be9d9: Minor API signatures cleanup -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - - @backstage/backend-tasks@0.3.5-next.0 - - @backstage/backend-test-utils@0.1.28-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.3 - - @backstage/backend-test-utils@0.1.26-next.3 - - @backstage/backend-tasks@0.3.3-next.3 - -## 0.2.0-next.2 - -### Patch Changes - -- 7ee4abdcc9: Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths -- Updated dependencies - - @backstage/backend-common@0.14.1-next.2 - - @backstage/backend-tasks@0.3.3-next.2 - - @backstage/backend-test-utils@0.1.26-next.2 - -## 0.2.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/backend-tasks@0.3.3-next.1 - - @backstage/backend-test-utils@0.1.26-next.1 - -## 0.2.0-next.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 - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - - @backstage/backend-tasks@0.3.3-next.0 - - @backstage/backend-test-utils@0.1.26-next.0 - -## 0.1.0 - -### Minor Changes - -- 7c310a5bc2: First implementation for the backend vault plugin. For more information refer to its `README.md`. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-tasks@0.3.2 - - @backstage/backend-common@0.14.0 - - @backstage/backend-test-utils@0.1.25 diff --git a/plugins/vault-backend/README.md b/plugins/vault-backend/README.md deleted file mode 100644 index 2c7dd06e52..0000000000 --- a/plugins/vault-backend/README.md +++ /dev/null @@ -1,183 +0,0 @@ -# @backstage/plugin-vault-backend - -A backend for [Vault](https://www.vaultproject.io/), this plugin adds a few routes that are used by the frontend plugin to fetch the information from Vault. - -## Introduction - -Vault is an identity-based secrets and encryption management system. A secret is anything that you want to tightly control access to, such as API encryption keys, passwords, or certificates. Vault provides encryption services that are gated by authentication and authorization methods. - -This plugins allows you to view all the available secrets at a certain location, and redirect you to the official UI so backstage can rely on LIST permissions, which is safer. - -## Getting started - -To get started, first you need a running instance of Vault. You can follow [this tutorial](https://learn.hashicorp.com/tutorials/vault/getting-started-intro?in=vault/getting-started) to install vault and start your server locally. - -1. When your Vault instance is up and running, then you will need to install the plugin into your app: - - ```bash - # From your Backstage root directory - yarn --cwd packages/backend add @backstage/plugin-vault-backend - ``` - -2. Create a file in `src/plugins/vault.ts` and add a reference to it in `src/index.ts`: - - ```typescript - // In packages/backend/src/plugins/vault.ts - import { createRouter } from '@backstage/plugin-vault-backend'; - import { Router } from 'express'; - import { PluginEnvironment } from '../types'; - - export default async function createPlugin( - env: PluginEnvironment, - ): Promise { - return await createRouter({ - logger: env.logger, - config: env.config, - scheduler: env.scheduler, - }); - } - ``` - - ```diff - diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts - index f2b14b2..2c64f47 100644 - --- a/packages/backend/src/index.ts - +++ b/packages/backend/src/index.ts - @@ -22,6 +22,7 @@ import { Config } from '@backstage/config'; - import app from './plugins/app'; - +import vault from './plugins/vault'; - import scaffolder from './plugins/scaffolder'; - @@ -56,6 +57,7 @@ async function main() { - const authEnv = useHotMemoize(module, () => createEnv('auth')); - + const vaultEnv = useHotMemoize(module, () => createEnv('vault')); - const proxyEnv = useHotMemoize(module, () => createEnv('proxy')); - @@ -63,6 +65,7 @@ async function main() { - - const apiRouter = Router(); - apiRouter.use('/catalog', await catalog(catalogEnv)); - + apiRouter.use('/vault', await vault(vaultEnv)); - apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv)); - ``` - -3. Add some extra configurations in your [`app-config.yaml`](https://github.com/backstage/backstage/blob/master/app-config.yaml). - - ```yaml - vault: - baseUrl: http://your-internal-vault-url.svc - publicUrl: https://your-vault-url.example.com - token: - secretEngine: 'customSecretEngine' # Optional. By default it uses 'secrets'. Can be overwritten by the annotation of the entity - kvVersion: # Optional. The K/V version that your instance is using. The available options are '1' or '2' - schedule: # Optional. If the token renewal is enabled this schedule will be used instead of the hourly one - frequency: { hours: 1 } - timeout: { hours: 1 } - ``` - -4. Get a `VAULT_TOKEN` with **LIST** permissions, as it's enough for the plugin. You can check [this tutorial](https://learn.hashicorp.com/tutorials/vault/tokens) for more info. - -5. If you also want to use the `renew` functionality, you need to attach the following block to your custom policy, so that Backstage can perform a token-renew: - ``` - # Allow tokens to renew themselves - path "auth/token/renew-self" { - capabilities = ["update"] - } - ``` - -## New Backend System - -The Vault backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: - -In your `packages/backend/src/index.ts` make the following changes: - -```diff - import { createBackend } from '@backstage/backend-defaults'; - const backend = createBackend(); - // ... other feature additions -+ backend.add(import('@backstage/plugin-vault-backend'); - backend.start(); -``` - -The token renewal is enabled automatically in the new backend system depending on the `app-config.yaml`. If the `schedule` is not defined there, no -task will be executed. If you want to use the default renewal scheduler (which runs hourly), set `schedule: true`. In case you want a custom schedule -just use a configuration like the one set above. - -## Integration with the Catalog - -The plugin can be integrated into each Component in the catalog. To allow listing the available secrets a new annotation must be added to the `catalog-info.yaml`: - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - # ... - annotations: - vault.io/secrets-path: path/to/secrets -``` - -The path is relative to your secrets engine folder. So if you want to get the secrets for backstage and you have the following directory structure: - - . - ├── ... - ├── secrets # Your secret engine name (usually it is `secrets`) - │ ├── test # Folder with test secrets - │ │ ├── backstage # In this folder there are secrets for Backstage - │ ├── other # Other folder with more secrets inside - │ └── folder # And another folder - └── ... - -You will set the `vault.io/secret-path` to `test/backstage`. If the folder `backstage` contains other sub-folders, the plugin will fetch the secrets inside them and adapt the **View** and **Edit** URLs to point to the correct place. - -In case you need to support different secret engines for entities of the catalog you can provide optional annotation to the entity in `catalog-info.yaml`: - -```diff - apiVersion: backstage.io/v1alpha1 - kind: Component - metadata: - # ... - annotations: - vault.io/secrets-path: path/to/secrets -+ vault.io/secrets-engine: customSecretEngine # Optional. By default it uses the 'secretEngine' value from your app-config. -``` - -That will overwrite the default secret engine from the configuration. - -## Renew token - -In a secure Vault instance, it's usual that the tokens are refreshed after some time. In order to always have a valid token to fetch the secrets, it might be necessary to execute a renew action after some time. By default this is deactivated, but it can be easily activated and configured to be executed periodically (hourly by default, but customizable by the user within the app-config.yaml file). In order to do that, modify your `src/plugins/vault.ts` file to look like this one: - -```typescript -import { VaultBuilder } from '@backstage/plugin-vault-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const builder = await VaultBuilder.createBuilder({ - logger: env.logger, - config: env.config, - scheduler: env.scheduler, - }).enableTokenRenew( - env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 10 }, - timeout: { minutes: 1 }, - }), - ); - - const { router } = builder.build(); - - return router; -} -``` - -If the `taskRunner` is not set when calling the `enableTokenRenew`, the plugin will automatically check what is set in the `app-config.yaml` file. Refer to [the new backend system setup](#new-backend-system) for more information about it. - -## Features - -- List the secrets present in a certain path -- Use different secret engines for different entities -- Open a link to view the secret -- Open a link to edit the secret -- Renew the token automatically with a defined periodicity - -The secrets cannot be edited/viewed from within Backstage to make it more secure. Backstage will only have permissions to LIST data from Vault or to renew its own token if that is needed. And the user who wants to edit/view a certain secret needs the correct permissions to do so. diff --git a/plugins/vault-backend/api-report.md b/plugins/vault-backend/api-report.md deleted file mode 100644 index 4002db5084..0000000000 --- a/plugins/vault-backend/api-report.md +++ /dev/null @@ -1,92 +0,0 @@ -## API Report File for "@backstage/plugin-vault-backend" - -> 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 { Config } from '@backstage/config'; -import express from 'express'; -import { Logger } from 'winston'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { PluginTaskScheduler } from '@backstage/backend-tasks'; -import { TaskRunner } from '@backstage/backend-tasks'; - -// @public -export function createRouter(options: RouterOptions): express.Router; - -// @public -export interface RouterOptions { - // (undocumented) - config: Config; - // (undocumented) - logger: Logger; - // (undocumented) - scheduler: PluginTaskScheduler; -} - -// @public @deprecated -export interface VaultApi { - getFrontendSecretsUrl(): string; - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; - renewToken?(): Promise; -} - -// @public -export class VaultBuilder { - constructor(env: VaultEnvironment); - build(): VaultBuilderReturn; - static createBuilder(env: VaultEnvironment): VaultBuilder; - enableTokenRenew(schedule?: TaskRunner): Promise; - setVaultClient(vaultApi: VaultApi): this; -} - -// @public -export type VaultBuilderReturn = { - router: express.Router; -}; - -// @public -export class VaultClient implements VaultApi { - constructor(options: { config: Config }); - // (undocumented) - getFrontendSecretsUrl(): string; - // (undocumented) - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; - // (undocumented) - renewToken(): Promise; -} - -// @public -export interface VaultEnvironment { - // (undocumented) - config: Config; - // (undocumented) - logger: LoggerService; - // (undocumented) - scheduler: PluginTaskScheduler; -} - -// @public -const vaultPlugin: () => BackendFeature; -export default vaultPlugin; - -// @public @deprecated -export type VaultSecret = { - name: string; - path: string; - showUrl: string; - editUrl: string; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/vault-backend/catalog-info.yaml b/plugins/vault-backend/catalog-info.yaml deleted file mode 100644 index d4fd503873..0000000000 --- a/plugins/vault-backend/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-vault-backend - title: '@backstage/plugin-vault-backend' - description: A Backstage backend plugin that integrates towards Vault -spec: - lifecycle: experimental - type: backstage-backend-plugin - owner: maintainers diff --git a/plugins/vault-backend/config.d.ts b/plugins/vault-backend/config.d.ts deleted file mode 100644 index 58369e638d..0000000000 --- a/plugins/vault-backend/config.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 { TaskScheduleDefinitionConfig } from '@backstage/backend-tasks'; - -/** Configuration for the Vault plugin */ -export interface Config { - vault?: { - /** - * The baseUrl for your Vault instance. - * @visibility frontend - */ - baseUrl: string; - - /** - * The publicUrl for your Vault instance (Optional). - * @visibility frontend - */ - publicUrl?: string; - - /** - * The token used by Backstage to access Vault. - * @visibility secret - */ - token: string; - - /** - * The secret engine name where in vault. Defaults to `secrets`. - */ - secretEngine?: string; - - /** - * The version of the K/V API. Defaults to `2`. - */ - kvVersion?: 1 | 2; - - /** - * If set to true, the default schedule (hourly) will be used. If a - * different schedule is set, this will be used instead. - * */ - schedule?: TaskScheduleDefinitionConfig | boolean; - }; -} diff --git a/plugins/vault-backend/knip-report.md b/plugins/vault-backend/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/vault-backend/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json deleted file mode 100644 index 065614ae9d..0000000000 --- a/plugins/vault-backend/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@backstage/plugin-vault-backend", - "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.4.3-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/vault-backend" - }, - "keywords": [ - "backstage", - "vault" - ], - "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": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/backend-tasks": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-vault-node": "workspace:^", - "@types/express": "*", - "compression": "^1.7.4", - "cors": "^2.8.5", - "express": "^4.17.1", - "express-promise-router": "^4.1.0", - "helmet": "^6.0.0", - "node-fetch": "^2.6.7", - "p-limit": "^3.1.0", - "winston": "^3.2.1", - "yn": "^5.0.0" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^", - "@types/compression": "^1.7.2", - "@types/supertest": "^2.0.8", - "msw": "^1.0.0", - "supertest": "^6.1.6" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts" -} diff --git a/plugins/vault-backend/src/config/config.test.ts b/plugins/vault-backend/src/config/config.test.ts deleted file mode 100644 index a061d0f784..0000000000 --- a/plugins/vault-backend/src/config/config.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 { getVaultConfig } from './config'; - -describe('GetVaultConfig', () => { - it('fails by missing keys', () => { - expect(() => getVaultConfig(new ConfigReader({}))).toThrow(); - expect(() => - getVaultConfig( - new ConfigReader({ - vault: {}, - }), - ), - ).toThrow(); - }); - - it('loads default params', () => { - const config = new ConfigReader({ - vault: { - baseUrl: 'http://www.example.com', - token: '123', - }, - }); - - const vaultConfig = getVaultConfig(config); - expect(vaultConfig).toStrictEqual({ - baseUrl: 'http://www.example.com', - publicUrl: undefined, - token: '123', - kvVersion: 2, - secretEngine: 'secrets', - }); - }); - - it('loads custom params', () => { - const config = new ConfigReader({ - vault: { - baseUrl: 'http://www.example.com', - token: '123', - kvVersion: 1, - secretEngine: 'test', - }, - }); - - const vaultConfig = getVaultConfig(config); - expect(vaultConfig).toStrictEqual({ - baseUrl: 'http://www.example.com', - publicUrl: undefined, - token: '123', - kvVersion: 1, - secretEngine: 'test', - }); - }); -}); diff --git a/plugins/vault-backend/src/config/config.ts b/plugins/vault-backend/src/config/config.ts deleted file mode 100644 index 159fee0447..0000000000 --- a/plugins/vault-backend/src/config/config.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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'; - -/** - * The configuration needed for the vault-backend plugin - * - * @public - */ -export interface VaultConfig { - /** - * The baseUrl for your Vault instance. - */ - baseUrl: string; - - /** - * The publicUrl for your Vault instance (Optional). - */ - publicUrl?: string; - - /** - * The token used by Backstage to access Vault. - */ - token: string; - - /** - * The secret engine name where in vault. Defaults to `secrets`. - */ - secretEngine: string; - - /** - * The version of the K/V API. Defaults to `2`. - */ - kvVersion: number; -} - -/** - * Extract the Vault config from a config object - * - * @public - * - * @param config - The config object to extract from - */ -export function getVaultConfig(config: Config): VaultConfig { - return { - baseUrl: config.getString('vault.baseUrl'), - publicUrl: config.getOptionalString('vault.publicUrl'), - token: config.getString('vault.token'), - kvVersion: config.getOptionalNumber('vault.kvVersion') ?? 2, - secretEngine: config.getOptionalString('vault.secretEngine') ?? 'secrets', - }; -} diff --git a/plugins/vault-backend/src/config/index.ts b/plugins/vault-backend/src/config/index.ts deleted file mode 100644 index a7eab2d9f0..0000000000 --- a/plugins/vault-backend/src/config/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ - -/* - * 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 './config'; diff --git a/plugins/vault-backend/src/index.ts b/plugins/vault-backend/src/index.ts deleted file mode 100644 index c5fea00642..0000000000 --- a/plugins/vault-backend/src/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from './service/router'; -export * from './service/VaultBuilder'; -export * from './service/vaultApi'; -export { vaultPlugin as default } from './service/plugin'; diff --git a/plugins/vault-backend/src/run.ts b/plugins/vault-backend/src/run.ts deleted file mode 100644 index 0a3ed2b7f0..0000000000 --- a/plugins/vault-backend/src/run.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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/vault-backend/src/service/VaultBuilder.ts b/plugins/vault-backend/src/service/VaultBuilder.ts deleted file mode 100644 index 471064392f..0000000000 --- a/plugins/vault-backend/src/service/VaultBuilder.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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 { InputError } from '@backstage/errors'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import express from 'express'; -import Router from 'express-promise-router'; -import { VaultApi, VaultClient } from './vaultApi'; -import { - PluginTaskScheduler, - TaskRunner, - TaskScheduleDefinition, - TaskScheduleDefinitionConfig, - readTaskScheduleDefinitionFromConfig, -} from '@backstage/backend-tasks'; -import { errorHandler } from '@backstage/backend-common'; - -/** - * Environment values needed by the VaultBuilder - * @public - */ -export interface VaultEnvironment { - logger: LoggerService; - config: Config; - scheduler: PluginTaskScheduler; -} - -/** - * The object returned by the VaultBuilder.build() function - * @public - */ -export type VaultBuilderReturn = { - router: express.Router; -}; - -/** - * Implementation for Vault. It creates the routing and initializes the backend - * to allow the use of the Vault's frontend plugin. - * @public - */ -export class VaultBuilder { - private vaultApi?: VaultApi; - - /** - * Creates a new instance of the VaultBuilder. - * - * @param env - The backstage environment - * @returns A new instance of the VaultBuilder - */ - static createBuilder(env: VaultEnvironment) { - return new VaultBuilder(env); - } - - constructor(private readonly env: VaultEnvironment) {} - - /** - * Builds the routes for Vault. - * - * @returns The router configured for Vault - */ - public build(): VaultBuilderReturn { - const { logger, config } = this.env; - - logger.info('Initializing Vault backend'); - - if (!config.has('vault')) { - logger.warn( - 'Failed to initialize Vault backend: vault config is missing', - ); - return { - router: Router(), - }; - } - - this.vaultApi = this.vaultApi ?? new VaultClient(this.env); - - const router = this.buildRouter(this.vaultApi); - - return { - router: router, - }; - } - - /** - * Overwrites the current vault client. - * - * @param vaultApi - The new Vault client - * @returns - */ - public setVaultClient(vaultApi: VaultApi) { - this.vaultApi = vaultApi; - return this; - } - - /** - * Enables the token renewal for Vault. The schedule if configured in the app-config.yaml file. - * If not set, the renewal is executed hourly - * - * @returns - */ - public async enableTokenRenew(schedule?: TaskRunner) { - const taskRunner = schedule - ? schedule - : this.env.scheduler.createScheduledTaskRunner(this.getConfigSchedule()); - - await taskRunner.run({ - id: 'refresh-vault-token', - fn: async () => { - this.env.logger.info('Renewing Vault token'); - const vaultApi = this.vaultApi ?? new VaultClient(this.env); - await vaultApi.renewToken?.(); - }, - }); - return this; - } - - private getConfigSchedule(): TaskScheduleDefinition { - const schedule = this.env.config.getOptional< - TaskScheduleDefinitionConfig | boolean - >('vault.schedule'); - - const scheduleCfg = - schedule !== undefined && schedule !== false - ? { - frequency: { hours: 1 }, - timeout: { hours: 1 }, - } - : readTaskScheduleDefinitionFromConfig( - this.env.config.getConfig('vault.schedule'), - ); - - return scheduleCfg; - } - - /** - * Builds the backend routes for Vault. - * - * @param vaultApi - The Vault client used to list the secrets. - * @returns The generated backend router - */ - private buildRouter(vaultApi: VaultApi): express.Router { - const router = Router(); - router.use(express.json()); - - router.get('/health', (_, res) => { - res.json({ status: 'ok' }); - }); - - router.get('/v1/secrets/:path', async (req, res) => { - const { path } = req.params; - const { engine } = req.query; - - if (typeof path !== 'string') { - throw new InputError(`Invalid path: ${path}`); - } - if (engine && typeof engine !== 'string') { - throw new InputError(`Invalid engine: ${engine}`); - } - - const secrets = await vaultApi.listSecrets(path, { - secretEngine: engine, - }); - res.json({ items: secrets }); - }); - - router.use(errorHandler()); - return router; - } -} diff --git a/plugins/vault-backend/src/service/plugin.test.tsx b/plugins/vault-backend/src/service/plugin.test.tsx deleted file mode 100644 index cc9fdaa0a7..0000000000 --- a/plugins/vault-backend/src/service/plugin.test.tsx +++ /dev/null @@ -1,22 +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 { vaultPlugin } from './plugin'; - -describe('vault', () => { - it('should export the vault plugin', () => { - expect(vaultPlugin).toBeDefined(); - }); -}); diff --git a/plugins/vault-backend/src/service/plugin.ts b/plugins/vault-backend/src/service/plugin.ts deleted file mode 100644 index cf9d2cf87b..0000000000 --- a/plugins/vault-backend/src/service/plugin.ts +++ /dev/null @@ -1,74 +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 { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { VaultApi, vaultExtensionPoint } from '@backstage/plugin-vault-node'; -import { VaultBuilder } from './VaultBuilder'; -import { TaskScheduleDefinitionConfig } from '@backstage/backend-tasks'; - -/** - * Vault backend plugin - * - * @public - */ -export const vaultPlugin = createBackendPlugin({ - pluginId: 'vault', - register(env) { - let client: VaultApi | undefined; - - env.registerExtensionPoint(vaultExtensionPoint, { - setClient(vaultClient) { - if (client) { - throw new Error('The vault client has been already set'); - } - client = vaultClient; - }, - }); - - env.registerInit({ - deps: { - logger: coreServices.logger, - config: coreServices.rootConfig, - scheduler: coreServices.scheduler, - httpRouter: coreServices.httpRouter, - }, - async init({ logger, config, scheduler, httpRouter }) { - let builder = VaultBuilder.createBuilder({ - logger, - config, - scheduler, - }); - - if (client) { - builder = builder.setVaultClient(client); - } - - const scheduleCfg = config.getOptional< - boolean | TaskScheduleDefinitionConfig - >('vault.schedule'); - if (scheduleCfg !== undefined && scheduleCfg !== false) { - builder = await builder.enableTokenRenew(); - } - - const { router } = builder.build(); - httpRouter.use(router); - }, - }); - }, -}); diff --git a/plugins/vault-backend/src/service/router.test.ts b/plugins/vault-backend/src/service/router.test.ts deleted file mode 100644 index 3fb78a6e8d..0000000000 --- a/plugins/vault-backend/src/service/router.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { getVoidLogger, DatabaseManager } from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import express from 'express'; -import request from 'supertest'; -import { TestDatabases } from '@backstage/backend-test-utils'; -import { TaskScheduler } from '@backstage/backend-tasks'; - -import { createRouter } from './router'; - -describe('createRouter', () => { - let app: express.Express; - const databases = TestDatabases.create({ - ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], - }); - - beforeAll(async () => { - const knex = await databases.init('SQLITE_3'); - const databaseManager: Partial = { - forPlugin: (_: string) => ({ - getClient: async () => knex, - }), - }; - const manager = databaseManager as DatabaseManager; - const scheduler = new TaskScheduler(manager, getVoidLogger()); - - const router = createRouter({ - logger: getVoidLogger(), - config: new ConfigReader({ - vault: { - baseUrl: 'https://www.example.com', - token: '1234567890', - }, - }), - scheduler: scheduler.forPlugin('vault'), - }); - app = express().use(router); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('GET /health', () => { - it('returns ok', async () => { - const response = await request(app).get('/health'); - - expect(response.status).toEqual(200); - expect(response.body).toEqual({ status: 'ok' }); - }); - }); -}); diff --git a/plugins/vault-backend/src/service/router.ts b/plugins/vault-backend/src/service/router.ts deleted file mode 100644 index 45e2ca8c86..0000000000 --- a/plugins/vault-backend/src/service/router.ts +++ /dev/null @@ -1,44 +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 { PluginTaskScheduler } from '@backstage/backend-tasks'; -import { Config } from '@backstage/config'; -import express from 'express'; -import { Logger } from 'winston'; -import { VaultBuilder } from './VaultBuilder'; - -/** - * Options for the router creation. - * @public - */ -export interface RouterOptions { - logger: Logger; - config: Config; - scheduler: PluginTaskScheduler; -} - -/** - * Creates the routes used for Vault. - * - * @param options - The options used for the Vault's router creation - * @returns The router for Vault - * @public - */ -export function createRouter(options: RouterOptions): express.Router { - const { router } = VaultBuilder.createBuilder(options).build(); - - return router; -} diff --git a/plugins/vault-backend/src/service/standaloneApplication.ts b/plugins/vault-backend/src/service/standaloneApplication.ts deleted file mode 100644 index c0a011c61c..0000000000 --- a/plugins/vault-backend/src/service/standaloneApplication.ts +++ /dev/null @@ -1,76 +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 { - errorHandler, - notFoundHandler, - requestLoggingHandler, - DatabaseManager, - getVoidLogger, -} from '@backstage/backend-common'; -import compression from 'compression'; -import cors from 'cors'; -import express from 'express'; -import helmet from 'helmet'; -import { Logger } from 'winston'; -import { createRouter } from './router'; -import { ConfigReader } from '@backstage/config'; - -// Think this file will probably go away once we move to backend system -// And restructure into the /dev folder -// eslint-disable-next-line @backstage/no-undeclared-imports -import { TestDatabases } from '@backstage/backend-test-utils'; -import { TaskScheduler } from '@backstage/backend-tasks'; - -export interface ApplicationOptions { - enableCors: boolean; - logger: Logger; -} - -export async function createStandaloneApplication( - options: ApplicationOptions, -): Promise { - const { enableCors, logger } = options; - const config = new ConfigReader({}); - const app = express(); - - const databases = TestDatabases.create({ - ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], - }); - const knex = await databases.init('SQLITE_3'); - const databaseManager: Partial = { - forPlugin: (_: string) => ({ - getClient: async () => knex, - }), - }; - const manager = databaseManager as DatabaseManager; - const scheduler = new TaskScheduler(manager, getVoidLogger()).forPlugin( - 'vault', - ); - - app.use(helmet()); - if (enableCors) { - app.use(cors()); - } - app.use(compression()); - app.use(express.json()); - app.use(requestLoggingHandler()); - app.use('/', createRouter({ logger, config, scheduler })); - app.use(notFoundHandler()); - app.use(errorHandler()); - - return app; -} diff --git a/plugins/vault-backend/src/service/standaloneServer.ts b/plugins/vault-backend/src/service/standaloneServer.ts deleted file mode 100644 index 8d42b1d4c8..0000000000 --- a/plugins/vault-backend/src/service/standaloneServer.ts +++ /dev/null @@ -1,50 +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 { Server } from 'http'; -import { Logger } from 'winston'; -import { createStandaloneApplication } from './standaloneApplication'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'vault-backend' }); - - logger.debug('Creating application...'); - const app = await createStandaloneApplication({ - enableCors: options.enableCors, - logger, - }); - - logger.debug('Starting application server...'); - return await new Promise((resolve, reject) => { - const server = app.listen(options.port, (err?: Error) => { - if (err) { - reject(err); - return; - } - - logger.info(`Listening on port ${options.port}`); - resolve(server); - }); - }); -} diff --git a/plugins/vault-backend/src/service/vaultApi.test.ts b/plugins/vault-backend/src/service/vaultApi.test.ts deleted file mode 100644 index 47c7c5a252..0000000000 --- a/plugins/vault-backend/src/service/vaultApi.test.ts +++ /dev/null @@ -1,120 +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 { setupRequestMockHandlers } from '@backstage/backend-test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { VaultSecret, VaultClient, VaultSecretList } from './vaultApi'; -import { ConfigReader } from '@backstage/config'; - -describe('VaultApi', () => { - let api: VaultClient; - - const server = setupServer(); - setupRequestMockHandlers(server); - - const mockBaseUrl = 'https://api-vault.com'; - const config = new ConfigReader({ - vault: { - baseUrl: mockBaseUrl, - token: '1234567890', - }, - }); - - const mockListResult: VaultSecretList = { - data: { - keys: ['secret::one', 'secret::two'], - }, - }; - const mockListResultEmpty: VaultSecretList = { - data: { - keys: [], - }, - }; - - const mockSecretsResult = ( - secretEngine: string = 'secrets', - ): VaultSecret[] => { - return [ - { - name: 'secret::one', - path: 'test/success', - editUrl: `${mockBaseUrl}/ui/vault/secrets/${secretEngine}/edit/test/success/secret::one`, - showUrl: `${mockBaseUrl}/ui/vault/secrets/${secretEngine}/show/test/success/secret::one`, - }, - { - name: 'secret::two', - path: 'test/success', - editUrl: `${mockBaseUrl}/ui/vault/secrets/${secretEngine}/edit/test/success/secret::two`, - showUrl: `${mockBaseUrl}/ui/vault/secrets/${secretEngine}/show/test/success/secret::two`, - }, - ]; - }; - - const setupHandlers = () => { - server.use( - rest.get( - `${mockBaseUrl}/v1/secrets/metadata/test/success`, - (_, res, ctx) => { - return res(ctx.json(mockListResult)); - }, - ), - rest.get(`${mockBaseUrl}/v1/kv/metadata/test/success`, (_, res, ctx) => { - return res(ctx.json(mockListResult)); - }), - rest.get( - `${mockBaseUrl}/v1/secrets/metadata/test/error`, - (_, res, ctx) => { - return res(ctx.json(mockListResultEmpty)); - }, - ), - rest.post(`${mockBaseUrl}/v1/auth/token/renew-self`, (_, res, ctx) => { - return res(ctx.json({ auth: { client_token: '0987654321' } })); - }), - ); - }; - - beforeEach(() => { - setupHandlers(); - api = new VaultClient({ config }); - }); - - it('should return secrets', async () => { - const secrets = await api.listSecrets('test/success'); - expect(secrets).toEqual(mockSecretsResult()); - }); - - it('should return secrets for custom engine', async () => { - const secrets = await api.listSecrets('test/success', { - secretEngine: 'kv', - }); - expect(secrets).toEqual(mockSecretsResult('kv')); - }); - - it('should return empty secret list', async () => { - const secrets = await api.listSecrets('test/error'); - expect(secrets).toEqual([]); - }); - - it('should return success token renew', async () => { - expect(await api.renewToken()).toBe(undefined); - }); - - it('should render frontend url', () => { - const url = api.getFrontendSecretsUrl(); - expect(url).toEqual(`${mockBaseUrl}/ui/vault/secrets/secrets`); - }); -}); diff --git a/plugins/vault-backend/src/service/vaultApi.ts b/plugins/vault-backend/src/service/vaultApi.ts deleted file mode 100644 index 789cdeeda5..0000000000 --- a/plugins/vault-backend/src/service/vaultApi.ts +++ /dev/null @@ -1,185 +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 { Config } from '@backstage/config'; -import { NotAllowedError, NotFoundError } from '@backstage/errors'; -import fetch from 'node-fetch'; -import plimit from 'p-limit'; -import { getVaultConfig, VaultConfig } from '../config'; - -/** - * Object received as a response from the Vault API when fetching secrets - * @internal - */ -export type VaultSecretList = { - data: { - keys: string[]; - }; -}; - -/** - * Object containing the secret name and some links - * @public - * @deprecated Use the interface from `@backstage/plugin-vault-node` - */ -export type VaultSecret = { - name: string; - path: string; - showUrl: string; - editUrl: string; -}; - -/** - * Object received as response when the token is renewed using the Vault API - */ -type RenewTokenResponse = { - auth: { - client_token: string; - }; -}; - -/** - * Interface for the Vault API - * @public - * @deprecated Use the interface from `@backstage/plugin-vault-node` - */ -export interface VaultApi { - /** - * Returns the URL to access the Vault UI with the defined config. - */ - getFrontendSecretsUrl(): string; - - /** - * Returns a list of secrets used to show in a table. - * @param secretPath - The path where the secrets are stored in Vault - * @param options - Additional options to be passed to the Vault API, allows to override vault default settings in app config file - */ - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; - - /** - * Optional, to renew the token used to list the secrets. Throws an - * error if the token renewal went wrong. - */ - renewToken?(): Promise; -} - -/** - * Implementation of the Vault API to list secrets and renew the token if necessary - * @public - */ -export class VaultClient implements VaultApi { - private vaultConfig: VaultConfig; - private readonly limit = plimit(5); - - constructor(options: { config: Config }) { - this.vaultConfig = getVaultConfig(options.config); - } - - private async callApi( - path: string, - query: { [key in string]: any }, - method: string = 'GET', - ): Promise { - const url = new URL(path, this.vaultConfig.baseUrl); - const response = await fetch( - `${url.toString()}?${new URLSearchParams(query).toString()}`, - { - method, - headers: { - Accept: 'application/json', - 'X-Vault-Token': this.vaultConfig.token, - }, - }, - ); - if (response.ok) { - return (await response.json()) as T; - } else if (response.status === 404) { - throw new NotFoundError(`No secrets found in path '${path}'`); - } else if (response.status === 403) { - throw new NotAllowedError(response.statusText); - } - throw new Error( - `Unexpected error while fetching secrets from path '${path}'`, - ); - } - - getFrontendSecretsUrl(): string { - return `${this.vaultConfig.baseUrl}/ui/vault/secrets/${this.vaultConfig.secretEngine}`; - } - - async listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise { - const mount = options?.secretEngine || this.vaultConfig.secretEngine; - - const listUrl = - this.vaultConfig.kvVersion === 2 - ? `v1/${encodeURIComponent(mount)}/metadata/${secretPath}` - : `v1/${encodeURIComponent(mount)}/${secretPath}`; - const result = await this.limit(() => - this.callApi(listUrl, { list: true }), - ); - - const secrets: VaultSecret[] = []; - - await Promise.all( - result.data.keys.map(async secret => { - if (secret.endsWith('/')) { - secrets.push( - ...(await this.limit(() => - this.listSecrets(`${secretPath}/${secret.slice(0, -1)}`, { - secretEngine: mount, - }), - )), - ); - } else { - const vaultUrl = - this.vaultConfig.publicUrl || this.vaultConfig.baseUrl; - secrets.push({ - name: secret, - path: secretPath, - editUrl: `${vaultUrl}/ui/vault/secrets/${encodeURIComponent( - mount, - )}/edit/${secretPath}/${secret}`, - showUrl: `${vaultUrl}/ui/vault/secrets/${encodeURIComponent( - mount, - )}/show/${secretPath}/${secret}`, - }); - } - }), - ); - - return secrets; - } - - async renewToken(): Promise { - const result = await this.callApi( - 'v1/auth/token/renew-self', - {}, - 'POST', - ); - - this.vaultConfig.token = result.auth.client_token; - } -} diff --git a/plugins/vault-backend/src/setupTests.ts b/plugins/vault-backend/src/setupTests.ts deleted file mode 100644 index d3232290a7..0000000000 --- a/plugins/vault-backend/src/setupTests.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export {}; diff --git a/plugins/vault-node/.eslintrc.js b/plugins/vault-node/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/vault-node/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/vault-node/CHANGELOG.md b/plugins/vault-node/CHANGELOG.md deleted file mode 100644 index 6d10f71d35..0000000000 --- a/plugins/vault-node/CHANGELOG.md +++ /dev/null @@ -1,131 +0,0 @@ -# @backstage/plugin-vault-node - -## 0.1.3-next.3 - -### Patch Changes - -- 8472188: Added or fixed the `repository` field in `package.json`. -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.3 - -## 0.1.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.2 - -## 0.1.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.1 - -## 0.1.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.10-next.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9 - -## 0.1.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.2 - -## 0.1.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.1 - -## 0.1.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.9-next.0 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.8 - -## 0.1.1-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.8-next.3 - -## 0.1.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.8-next.2 - -## 0.1.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.8-next.1 - -## 0.1.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.8-next.0 - -## 0.1.0 - -### Minor Changes - -- 7a41bcf2af: Initial version of the `plugin-vault-node`` package. It contains the extension point definitions - for the vault backend, as well as some types that will be deprecated in the backend plugin. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7 - -## 0.1.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.2 - -## 0.1.0-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.1 - -## 0.1.0-next.0 - -### Minor Changes - -- 7a41bcf2af: Initial version of the `plugin-vault-node`` package. It contains the extension point definitions - for the vault backend, as well as some types that will be deprecated in the backend plugin. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.7-next.0 diff --git a/plugins/vault-node/README.md b/plugins/vault-node/README.md deleted file mode 100644 index 5f777e792b..0000000000 --- a/plugins/vault-node/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @backstage/plugin-vault-node - -Houses types and utilities for building the vault modules diff --git a/plugins/vault-node/api-report.md b/plugins/vault-node/api-report.md deleted file mode 100644 index d0e0a29f8f..0000000000 --- a/plugins/vault-node/api-report.md +++ /dev/null @@ -1,38 +0,0 @@ -## API Report File for "@backstage/plugin-vault-node" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ExtensionPoint } from '@backstage/backend-plugin-api'; - -// @public -export interface VaultApi { - getFrontendSecretsUrl(): string; - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; - renewToken?(): Promise; -} - -// @public -export interface VaultExtensionPoint { - // (undocumented) - setClient(vaultClient: VaultApi): void; -} - -// @public -export const vaultExtensionPoint: ExtensionPoint; - -// @public -export type VaultSecret = { - name: string; - path: string; - showUrl: string; - editUrl: string; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/vault-node/catalog-info.yaml b/plugins/vault-node/catalog-info.yaml deleted file mode 100644 index 6b6c8b84ad..0000000000 --- a/plugins/vault-node/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-vault-node - title: '@backstage/plugin-vault-node' - description: Node.js library for the vault plugin -spec: - lifecycle: experimental - type: backstage-node-library - owner: maintainers diff --git a/plugins/vault-node/knip-report.md b/plugins/vault-node/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/plugins/vault-node/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/plugins/vault-node/package.json b/plugins/vault-node/package.json deleted file mode 100644 index 5a53fb07c5..0000000000 --- a/plugins/vault-node/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@backstage/plugin-vault-node", - "description": "Node.js library for the vault plugin", - "version": "0.1.3-next.3", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/vault-node" - }, - "backstage": { - "role": "node-library" - }, - "scripts": { - "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-plugin-api": "workspace:^" - }, - "devDependencies": { - "@backstage/cli": "workspace:^" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/vault-node/src/api/index.ts b/plugins/vault-node/src/api/index.ts deleted file mode 100644 index 92cb965d75..0000000000 --- a/plugins/vault-node/src/api/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export * from './types'; diff --git a/plugins/vault-node/src/api/types.ts b/plugins/vault-node/src/api/types.ts deleted file mode 100644 index 9969fb001b..0000000000 --- a/plugins/vault-node/src/api/types.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Object containing the secret name and some links - * @public - */ -export type VaultSecret = { - name: string; - path: string; - showUrl: string; - editUrl: string; -}; - -/** - * Interface for the Vault API - * @public - */ -export interface VaultApi { - /** - * Returns the URL to access the Vault UI with the defined config. - */ - getFrontendSecretsUrl(): string; - - /** - * Returns a list of secrets used to show in a table. - * @param secretPath - The path where the secrets are stored in Vault - * @param options - Additional options to be passed to the Vault API, allows to override vault default settings in app config file - */ - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; - - /** - * Optional, to renew the token used to list the secrets. Throws an - * error if the token renewal went wrong. - */ - renewToken?(): Promise; -} diff --git a/plugins/vault-node/src/extensions.ts b/plugins/vault-node/src/extensions.ts deleted file mode 100644 index efe4ba6223..0000000000 --- a/plugins/vault-node/src/extensions.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { VaultApi } from './api'; - -/** - * Extension point for vault. - * - * @public - */ -export interface VaultExtensionPoint { - setClient(vaultClient: VaultApi): void; -} - -/** - * Extension point for vault. - * - * @public - */ -export const vaultExtensionPoint = createExtensionPoint({ - id: 'vault.configuration', -}); diff --git a/plugins/vault-node/src/index.ts b/plugins/vault-node/src/index.ts deleted file mode 100644 index 070f2cf64d..0000000000 --- a/plugins/vault-node/src/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { type VaultExtensionPoint, vaultExtensionPoint } from './extensions'; -export type { VaultApi, VaultSecret } from './api'; diff --git a/plugins/vault-node/src/setupTests.ts b/plugins/vault-node/src/setupTests.ts deleted file mode 100644 index 4b9026cde5..0000000000 --- a/plugins/vault-node/src/setupTests.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export {}; diff --git a/plugins/vault/.eslintrc.js b/plugins/vault/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/vault/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md deleted file mode 100644 index 9664864ab3..0000000000 --- a/plugins/vault/CHANGELOG.md +++ /dev/null @@ -1,1017 +0,0 @@ -# @backstage/plugin-vault - -## 0.1.25-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/plugin-catalog-react@1.10.0-next.3 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.1.25-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/plugin-catalog-react@1.10.0-next.2 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.1.25-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/catalog-model@1.4.4-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/plugin-catalog-react@1.9.4-next.1 - - @backstage/errors@1.2.3 - -## 0.1.25-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.4-next.0 - - @backstage/core-components@0.13.10 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.1.24 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/plugin-catalog-react@1.9.3 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.24-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.3-next.2 - -## 0.1.24-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/plugin-catalog-react@1.9.3-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.24-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/plugin-catalog-react@1.9.3-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.1.23 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/plugin-catalog-react@1.9.2 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.23-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.3 - -## 0.1.23-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.2 - - @backstage/catalog-model@1.4.3 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.1.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/plugin-catalog-react@1.9.2-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.1.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/plugin-catalog-react@1.9.2-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.21 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0 - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.21-next.2 - -### Patch Changes - -- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - - @backstage/plugin-catalog-react@1.9.0-next.2 - -## 0.1.21-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.9.0-next.1 - - @backstage/core-components@0.13.8-next.1 - - @backstage/catalog-model@1.4.3 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - -## 0.1.21-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/plugin-catalog-react@1.9.0-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - -## 0.1.20 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5 - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/catalog-model@1.4.3 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - -## 0.1.20-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/catalog-model@1.4.3-next.0 - - @backstage/plugin-catalog-react@1.8.5-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - -## 0.1.20-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/plugin-catalog-react@1.8.5-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.20-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.5-next.0 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/catalog-model@1.4.2 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.19 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- 858a18800870: Added ability to override vault secret engine value on catalog entity level using annotation `vault.io/secrets-engine` -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4 - - @backstage/core-components@0.13.5 - - @backstage/catalog-model@1.4.2 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.1.18 - -Skipped due to publishing issues. - -## 0.1.18-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 858a18800870: Added ability to override vault secret engine value on catalog entity level using annotation `vault.io/secrets-engine` -- Updated dependencies - - @backstage/catalog-model@1.4.2-next.2 - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/plugin-catalog-react@1.8.4-next.3 - - @backstage/theme@0.4.2-next.0 - -## 0.1.18-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/plugin-catalog-react@1.8.4-next.2 - - @backstage/catalog-model@1.4.2-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.18-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.4-next.1 - - @backstage/core-components@0.13.5-next.1 - - @backstage/catalog-model@1.4.2-next.0 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.17-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - - @backstage/plugin-catalog-react@1.8.3-next.0 - -## 0.1.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/plugin-catalog-react@1.8.1 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.1-next.1 - -## 0.1.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/plugin-catalog-react@1.8.1-next.0 - - @backstage/catalog-model@1.4.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.1.14 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/plugin-catalog-react@1.8.0 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - - @backstage/catalog-model@1.4.1 - -## 0.1.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.8.0-next.2 - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/errors@1.2.1-next.0 - -## 0.1.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - - @backstage/plugin-catalog-react@1.7.1-next.1 - -## 0.1.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/catalog-model@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.1-next.0 - -## 0.1.13 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/plugin-catalog-react@1.7.0 - - @backstage/catalog-model@1.4.0 - - @backstage/errors@1.2.0 - -## 0.1.13-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/catalog-model@1.4.0-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.3 - -## 0.1.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.2 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.1.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/plugin-catalog-react@1.7.0-next.1 - - @backstage/catalog-model@1.4.0-next.0 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.1.13-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.7.0-next.0 - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.1.12 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/plugin-catalog-react@1.6.0 - - @backstage/core-components@0.13.1 - - @backstage/catalog-model@1.3.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.1.12-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/plugin-catalog-react@1.6.0-next.2 - - @backstage/core-plugin-api@1.5.1 - -## 0.1.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/plugin-catalog-react@1.6.0-next.1 - -## 0.1.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.6.0-next.0 - - @backstage/core-components@0.13.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19 - -## 0.1.11 - -### Patch Changes - -- 7c7f8d38a51: Use `fetchApi` instead of raw `fetch` in order to pass auth header if necessary. -- 29ba8267d69: Updated dependency `@material-ui/lab` to `4.0.0-alpha.61`. -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/plugin-catalog-react@1.5.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/catalog-model@1.3.0 - - @backstage/errors@1.1.5 - -## 0.1.11-next.3 - -### Patch Changes - -- 7c7f8d38a51: Use `fetchApi` instead of raw `fetch` in order to pass auth header if necessary. -- Updated dependencies - - @backstage/plugin-catalog-react@1.5.0-next.3 - - @backstage/catalog-model@1.3.0-next.0 - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.1.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/plugin-catalog-react@1.4.1-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.1.11-next.1 - -### Patch Changes - -- 29ba8267d69: Updated dependency `@material-ui/lab` to `4.0.0-alpha.61`. -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.1 - - @backstage/theme@0.2.19-next.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - -## 0.1.11-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/plugin-catalog-react@1.4.1-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - -## 0.1.10 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/plugin-catalog-react@1.4.0 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/catalog-model@1.2.1 - - @backstage/theme@0.2.18 - -## 0.1.10-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/plugin-catalog-react@1.4.0-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.1.10-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - - @backstage/plugin-catalog-react@1.4.0-next.1 - - @backstage/catalog-model@1.2.1-next.1 - -## 0.1.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.4.0-next.0 - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/catalog-model@1.2.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 - -## 0.1.9 - -### Patch Changes - -- fd7a77b9c4: Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API. -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/catalog-model@1.2.0 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/plugin-catalog-react@1.3.0 - - @backstage/errors@1.1.4 - -## 0.1.9-next.2 - -### Patch Changes - -- fd7a77b9c4: Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API. -- Updated dependencies - - @backstage/catalog-model@1.2.0-next.1 - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.3.0-next.2 - -## 0.1.9-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/plugin-catalog-react@1.3.0-next.1 - - @backstage/catalog-model@1.1.6-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.9-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.3.0-next.0 - - @backstage/catalog-model@1.1.6-next.0 - -## 0.1.8 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5 - - @backstage/plugin-catalog-react@1.2.4 - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.8-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/plugin-catalog-react@1.2.4-next.2 - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.8-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.1 - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.4-next.1 - -## 0.1.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.5-next.0 - - @backstage/plugin-catalog-react@1.2.4-next.0 - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - - @backstage/plugin-catalog-react@1.2.3 - -## 0.1.6 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/plugin-catalog-react@1.2.2 - - @backstage/catalog-model@1.1.4 - - @backstage/theme@0.2.16 - -## 0.1.6-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/plugin-catalog-react@1.2.2-next.4 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.1.6-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.2-next.3 - -## 0.1.6-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/plugin-catalog-react@1.2.2-next.2 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.1.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/plugin-catalog-react@1.2.2-next.1 - - @backstage/catalog-model@1.1.4-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.1.6-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/plugin-catalog-react@1.2.2-next.0 - - @backstage/catalog-model@1.1.4-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1 - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/catalog-model@1.1.3 - - @backstage/errors@1.1.3 - - @backstage/theme@0.2.16 - -## 0.1.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - - @backstage/plugin-catalog-react@1.2.1-next.1 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.1-next.0 - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/catalog-model@1.1.3-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2 - - @backstage/plugin-catalog-react@1.2.0 - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - - @backstage/theme@0.2.16 - -## 0.1.4-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.2 - - @backstage/catalog-model@1.1.2-next.2 - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/theme@0.2.16 - -## 0.1.4-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.2.0-next.1 - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/catalog-model@1.1.2-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/catalog-model@1.1.2-next.0 - - @backstage/core-components@0.11.2-next.0 - - @backstage/plugin-catalog-react@1.1.5-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/theme@0.2.16 - -## 0.1.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/plugin-catalog-react@1.1.4 - - @backstage/catalog-model@1.1.1 - - @backstage/errors@1.1.1 - -## 0.1.3-next.2 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.4-next.2 - - @backstage/catalog-model@1.1.1-next.0 - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.1.3-next.1 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.1.3-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - - @backstage/plugin-catalog-react@1.1.4-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - - @backstage/catalog-model@1.1.0-next.3 - - @backstage/plugin-catalog-react@1.1.2-next.3 - -## 0.1.1-next.2 - -### Patch Changes - -- 7ee4abdcc9: Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/catalog-model@1.1.0-next.2 - - @backstage/theme@0.2.16-next.1 - - @backstage/plugin-catalog-react@1.1.2-next.2 - -## 0.1.1-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/catalog-model@1.1.0-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/theme@0.2.16-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.1 - -## 0.1.1-next.0 - -### Patch Changes - -- 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/catalog-model@1.1.0-next.0 - - @backstage/core-components@0.9.6-next.0 - - @backstage/plugin-catalog-react@1.1.2-next.0 - -## 0.1.0 - -### Minor Changes - -- 7c310a5bc2: First implementation of the frontend vault plugin. For more information refer to its `README.md`. - -### Patch Changes - -- Updated dependencies - - @backstage/plugin-catalog-react@1.1.1 - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - - @backstage/catalog-model@1.0.3 diff --git a/plugins/vault/README.md b/plugins/vault/README.md deleted file mode 100644 index fe86a30bd2..0000000000 --- a/plugins/vault/README.md +++ /dev/null @@ -1,112 +0,0 @@ -# @backstage/plugin-vault - -A frontend for [Vault](https://www.vaultproject.io/), this plugin allows you to display a list of secrets in a certain path inside your vault instance. There are also some useful links to edit and/or view them using the official UI. - -![Screenshot of the vault plugin table](images/vault-table.png) - -## Introduction - -Vault is an identity-based secrets and encryption management system. A secret is anything that you want to tightly control access to, such as API encryption keys, passwords, or certificates. Vault provides encryption services that are gated by authentication and authorization methods. - -This plugins allows you to view all the available secrets at a certain location, and redirect you to the official UI so backstage can rely on LIST permissions, which is safer. - -## Getting started - -To get started, first you need a running instance of Vault. You can follow [this tutorial](https://learn.hashicorp.com/tutorials/vault/getting-started-intro?in=vault/getting-started) to install vault and start your server locally. - -1. When your Vault instance is up and running, then you will need to install the plugin into your app: - - ```bash - # From your Backstage root directory - yarn --cwd packages/app add @backstage/plugin-vault - ``` - -2. Add the Vault card to the overview tab on the EntityPage: - - ```typescript - // In packages/app/src/components/catalog/EntityPage.tsx - import { EntityVaultCard } from '@backstage/plugin-vault'; - - const overviewContent = ( - - {/* ...other content */} - - - - ); - ``` - -3. Add some extra configurations in your [`app-config.yaml`](https://github.com/backstage/backstage/blob/master/app-config.yaml). - - ```yaml - vault: - baseUrl: http://your-vault-url - token: - secretEngine: 'customSecretEngine' # Optional. By default it uses 'secrets'. Can be overwritten by the annotation of the entity - kvVersion: # Optional. The K/V version that your instance is using. The available options are '1' or '2' - ``` - -4. Get a `VAULT_TOKEN` with **LIST** permissions, as it's enough for the plugin. You can check [this tutorial](https://learn.hashicorp.com/tutorials/vault/tokens) for more info. - -5. If you also want to use the `renew` functionality, you need to attach the following block to your custom policy, so that Backstage can perform a token-renew: - ``` - # Allow tokens to renew themselves - path "auth/token/renew-self" { - capabilities = ["update"] - } - ``` - -## Integration with the Catalog - -The plugin can be integrated into each Component in the catalog. To allow listing the available secrets a new annotation must be added to the `catalog-info.yaml`: - -```yaml -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - # ... - annotations: - vault.io/secrets-path: path/to/secrets - vault.io/secrets-engine: customSecretEngine # Optional. By default it uses the 'secretEngine' value from your app-config. -``` - -The path is relative to your secrets engine folder. So if you want to get the secrets for backstage and you have the following directory structure: - - . - ├── ... - ├── secrets # Your secret engine name (usually it is `secrets`) - │ ├── test # Folder with test secrets - │ │ ├── backstage # In this folder there are secrets for Backstage - │ ├── other # Other folder with more secrets inside - │ └── folder # And another folder - └── ... - -You will set the `vault.io/secret-path` to `test/backstage`. If the folder `backstage` contains other sub-folders, the plugin will fetch the secrets inside them and adapt the **View** and **Edit** URLs to point to the correct place. - -If the annotation is missing for a certain component, then the card will show some information to the user: - -![Screenshot of the vault plugin with missing annotation](images/annotation-missing.png) - -In case you need to support different secret engines for entities of the catalog you can provide optional annotation to the entity in `catalog-info.yaml`: - -```diff - apiVersion: backstage.io/v1alpha1 - kind: Component - metadata: - # ... - annotations: - vault.io/secrets-path: path/to/secrets -+ vault.io/secrets-engine: customSecretEngine # Optional. By default it uses 'secertEngine' value from configuration. -``` - -That will overwrite the default secret engine from the configuration. - -## Features - -- List the secrets present in a certain path -- Use different secret engines for different components -- Open a link to view the secret -- Open a link to edit the secret -- Renew the token automatically with a defined periodicity - -The secrets cannot be edited/viewed from within Backstage to make it more secure. Backstage will only have permissions to LIST data from Vault. And the user who wants to edit/view a certain secret needs the correct permissions to do so. diff --git a/plugins/vault/api-report.md b/plugins/vault/api-report.md deleted file mode 100644 index 59bcb1c527..0000000000 --- a/plugins/vault/api-report.md +++ /dev/null @@ -1,47 +0,0 @@ -## API Report File for "@backstage/plugin-vault" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -/// - -import { ApiRef } from '@backstage/core-plugin-api'; -import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { Entity } from '@backstage/catalog-model'; -import { JSX as JSX_2 } from 'react'; - -// @public -export const EntityVaultCard: () => JSX_2.Element; - -// @public -export function isVaultAvailable(entity: Entity): boolean; - -// @public (undocumented) -export const VAULT_SECRET_PATH_ANNOTATION = 'vault.io/secrets-path'; - -// @public -export interface VaultApi { - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; -} - -// @public (undocumented) -export const vaultApiRef: ApiRef; - -// @public -export const vaultPlugin: BackstagePlugin<{}, {}>; - -// @public -export type VaultSecret = { - name: string; - path: string; - showUrl: string; - editUrl: string; -}; - -// (No @packageDocumentation comment for this package) -``` diff --git a/plugins/vault/catalog-info.yaml b/plugins/vault/catalog-info.yaml deleted file mode 100644 index 3f9d97ea09..0000000000 --- a/plugins/vault/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-vault - title: '@backstage/plugin-vault' - description: A Backstage plugin that integrates towards Vault -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/vault/dev/index.tsx b/plugins/vault/dev/index.tsx deleted file mode 100644 index 8d902e14c5..0000000000 --- a/plugins/vault/dev/index.tsx +++ /dev/null @@ -1,86 +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 { Entity } from '@backstage/catalog-model'; -import { Content, Header, HeaderLabel, Page } from '@backstage/core-components'; -import { createDevApp } from '@backstage/dev-utils'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; -import { TestApiProvider } from '@backstage/test-utils'; -import { Box, Typography } from '@material-ui/core'; -import SomeIcon from '@material-ui/icons/Storage'; -import React from 'react'; -import { VaultApi, vaultApiRef } from '../src/api'; -import { EntityVaultCard } from '../src/components/EntityVaultCard'; -import { EntityVaultTable } from '../src/components/EntityVaultTable'; -import { VAULT_SECRET_PATH_ANNOTATION } from '../src/constants'; -import { vaultPlugin } from '../src/plugin'; - -const entity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'backstage', - annotations: { [VAULT_SECRET_PATH_ANNOTATION]: 'a/b' }, - }, - spec: { - type: 'service', - }, -}; - -const mockedApi: VaultApi = { - async listSecrets() { - return [ - { - name: 'a::b', - path: '', - editUrl: 'https://example.com', - showUrl: 'https://example.com', - }, - { - name: 'c::d', - path: '', - editUrl: 'https://example.com', - showUrl: 'https://example.com', - }, - ]; - }, -}; - -createDevApp() - .registerPlugin(vaultPlugin) - .addPage({ - element: ( - - - -
- -
- - As a card - - - As a table - - -
-
-
- ), - title: 'Vault', - icon: SomeIcon, - }) - .render(); diff --git a/plugins/vault/images/annotation-missing.png b/plugins/vault/images/annotation-missing.png deleted file mode 100644 index 1d0be0c99b..0000000000 Binary files a/plugins/vault/images/annotation-missing.png and /dev/null differ diff --git a/plugins/vault/images/vault-table.png b/plugins/vault/images/vault-table.png deleted file mode 100644 index 18a4b22dc5..0000000000 Binary files a/plugins/vault/images/vault-table.png and /dev/null differ diff --git a/plugins/vault/knip-report.md b/plugins/vault/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/vault/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/vault/package.json b/plugins/vault/package.json deleted file mode 100644 index 395d4f7811..0000000000 --- a/plugins/vault/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@backstage/plugin-vault", - "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.25-next.3", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/vault" - }, - "keywords": [ - "backstage", - "vault" - ], - "sideEffects": false, - "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": "workspace:^", - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/plugin-catalog-react": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-use": "^17.2.4" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "msw": "^1.0.0" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/vault/src/api.test.ts b/plugins/vault/src/api.test.ts deleted file mode 100644 index 7ecd09b6f4..0000000000 --- a/plugins/vault/src/api.test.ts +++ /dev/null @@ -1,116 +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 { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; -import { VaultSecret, VaultClient } from './api'; -import { UrlPatternDiscovery } from '@backstage/core-app-api'; - -describe('api', () => { - let api: VaultClient; - let fetchApiSpy: jest.SpyInstance>; - - const server = setupServer(); - setupRequestMockHandlers(server); - - const mockBaseUrl = 'https://api-vault.com/api/vault'; - const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - const fetchApi = new MockFetchApi(); - - const mockSecretsResult: { items: VaultSecret[] } = { - items: [ - { - name: 'secret::one', - path: 'test/success', - editUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/edit/test/success/secret::one`, - showUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/show/test/success/secret::one`, - }, - { - name: 'secret::two', - path: 'test/success', - editUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/edit/test/success/secret::two`, - showUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/show/test/success/secret::two`, - }, - ], - }; - - const setupHandlers = () => { - server.use( - rest.get(`${mockBaseUrl}/v1/secrets/:path`, (req, res, ctx) => { - const { path } = req.params; - if (path === 'test/success') { - return res(ctx.json(mockSecretsResult)); - } else if (path === 'test/empty') { - return res(ctx.json({ items: [] })); - } else if (path === 'test/not-found') { - return res(ctx.status(404)); - } - return res(ctx.status(400)); - }), - rest.get(`${mockBaseUrl}/v1/secrets/`, (_req, res, ctx) => { - return res(ctx.json(mockSecretsResult)); - }), - ); - }; - - beforeEach(() => { - setupHandlers(); - - api = new VaultClient({ discoveryApi, fetchApi }); - fetchApiSpy = jest.spyOn(fetchApi, 'fetch'); - }); - - it('should return secrets', async () => { - expect(await api.listSecrets('test/success')).toEqual( - mockSecretsResult.items, - ); - expect(fetchApiSpy).toHaveBeenCalledWith( - `${mockBaseUrl}/v1/secrets/test%2Fsuccess?`, - expect.anything(), - ); - }); - - it('should return secrets with custom engine', async () => { - expect( - await api.listSecrets('test/success', { secretEngine: 'kv' }), - ).toEqual(mockSecretsResult.items); - expect(fetchApiSpy).toHaveBeenCalledWith( - `${mockBaseUrl}/v1/secrets/test%2Fsuccess?engine=kv`, - expect.anything(), - ); - }); - - it('should return empty secret list', async () => { - expect(await api.listSecrets('test/empty')).toEqual([]); - }); - - it('should return all the secrets if no path defined', async () => { - expect(await api.listSecrets('')).toEqual(mockSecretsResult.items); - }); - - it('should throw an error if the Vault API responds with an HTTP 404', async () => { - await expect(api.listSecrets('test/not-found')).rejects.toThrow( - "No secrets found in path 'v1/secrets/test%2Fnot-found'", - ); - }); - - it('should throw an error if the Vault API responds with a non-successful HTTP status code', async () => { - await expect(api.listSecrets('test/error')).rejects.toThrow( - 'Request failed with 400 Error', - ); - }); -}); diff --git a/plugins/vault/src/api.ts b/plugins/vault/src/api.ts deleted file mode 100644 index f01823ff22..0000000000 --- a/plugins/vault/src/api.ts +++ /dev/null @@ -1,117 +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 { - DiscoveryApi, - createApiRef, - FetchApi, -} from '@backstage/core-plugin-api'; -import { NotFoundError, ResponseError } from '@backstage/errors'; - -/** - * @public - */ -export const vaultApiRef = createApiRef({ - id: 'plugin.vault.service', -}); - -/** - * Object containing the secret name and some links. - * @public - */ -export type VaultSecret = { - name: string; - path: string; - showUrl: string; - editUrl: string; -}; - -/** - * Interface for the VaultApi. - * @public - */ -export interface VaultApi { - /** - * Returns a list of secrets used to show in a table. - * @param secretPath - The path where the secrets are stored in Vault - * @param options - Additional options to be passed to the Vault API, allows to override vault default settings in app config file - */ - listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise; -} - -/** - * Default implementation of the VaultApi. - * @public - */ -export class VaultClient implements VaultApi { - private readonly discoveryApi: DiscoveryApi; - private readonly fetchApi: FetchApi; - - constructor({ - discoveryApi, - fetchApi, - }: { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - }) { - this.discoveryApi = discoveryApi; - this.fetchApi = fetchApi; - } - - private async callApi( - path: string, - query: { [key in string]: any }, - ): Promise { - const apiUrl = `${await this.discoveryApi.getBaseUrl('vault')}`; - const response = await this.fetchApi.fetch( - `${apiUrl}/${path}?${new URLSearchParams(query).toString()}`, - { - headers: { - Accept: 'application/json', - }, - }, - ); - if (response.ok) { - return (await response.json()) as T; - } else if (response.status === 404) { - throw new NotFoundError(`No secrets found in path '${path}'`); - } - throw await ResponseError.fromResponse(response); - } - - async listSecrets( - secretPath: string, - options?: { - secretEngine?: string; - }, - ): Promise { - const query: { [key in string]: any } = {}; - const { secretEngine } = options || {}; - if (secretEngine) { - query.engine = secretEngine; - } - - const result = await this.callApi<{ items: VaultSecret[] }>( - `v1/secrets/${encodeURIComponent(secretPath)}`, - query, - ); - return result.items; - } -} diff --git a/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx b/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx deleted file mode 100644 index 9450ddc41d..0000000000 --- a/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.test.tsx +++ /dev/null @@ -1,52 +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 { setupServer } from 'msw/node'; -import { setupRequestMockHandlers } from '@backstage/test-utils'; -import { ComponentEntity } from '@backstage/catalog-model'; -import { render } from '@testing-library/react'; -import { EntityVaultCard } from './EntityVaultCard'; -import { EntityProvider } from '@backstage/plugin-catalog-react'; - -describe('EntityVaultCard', () => { - const server = setupServer(); - setupRequestMockHandlers(server); - const entityAnnotationMissing: ComponentEntity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'test', - description: 'This is the description', - }, - spec: { - lifecycle: 'production', - owner: 'owner', - type: 'service', - }, - }; - - it('should render missing entity annotation', async () => { - const rendered = render( - - - , - ); - expect( - rendered.getByText(/Add the annotation to your Component YAML/), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.tsx b/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.tsx deleted file mode 100644 index ec21dfb114..0000000000 --- a/plugins/vault/src/components/EntityVaultCard/EntityVaultCard.tsx +++ /dev/null @@ -1,35 +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 { - useEntity, - MissingAnnotationEmptyState, -} from '@backstage/plugin-catalog-react'; -import { isVaultAvailable } from '../../conditions'; -import { VAULT_SECRET_PATH_ANNOTATION } from '../../constants'; -import { EntityVaultTable } from '../EntityVaultTable'; - -export const EntityVaultCard = () => { - const { entity } = useEntity(); - - if (isVaultAvailable(entity)) { - return ; - } - return ( - - ); -}; diff --git a/plugins/vault/src/components/EntityVaultCard/index.ts b/plugins/vault/src/components/EntityVaultCard/index.ts deleted file mode 100644 index 0b91f6dde4..0000000000 --- a/plugins/vault/src/components/EntityVaultCard/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { EntityVaultCard } from './EntityVaultCard'; diff --git a/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx b/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx deleted file mode 100644 index 5e191df9eb..0000000000 --- a/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.test.tsx +++ /dev/null @@ -1,168 +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 { setupServer } from 'msw/node'; -import { - MockFetchApi, - setupRequestMockHandlers, - TestApiRegistry, -} from '@backstage/test-utils'; -import { ComponentEntity } from '@backstage/catalog-model'; -import { renderInTestApp } from '@backstage/test-utils'; -import { EntityVaultTable } from './EntityVaultTable'; -import { ApiProvider, UrlPatternDiscovery } from '@backstage/core-app-api'; -import { VaultSecret, vaultApiRef, VaultClient } from '../../api'; -import { rest } from 'msw'; - -describe('EntityVaultTable', () => { - let vaultClient: VaultClient; - let apis: TestApiRegistry; - let listSecretsSpy: jest.SpyInstance>; - - const server = setupServer(); - setupRequestMockHandlers(server); - const mockBaseUrl = 'https://api-vault.com/api/vault'; - const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - const fetchApi = new MockFetchApi(); - - const entity = (secretPath: string, secretEngine?: string | undefined) => { - const annotations: Record = { - 'vault.io/secrets-path': secretPath, - }; - if (secretEngine) { - annotations['vault.io/secrets-engine'] = secretEngine; - } - - return { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'test', - description: 'This is the description', - annotations, - }, - spec: { - lifecycle: 'production', - owner: 'owner', - type: 'service', - }, - } as ComponentEntity; - }; - - const entityOk = entity('test/success'); - const entityOkWithEngine = entity('test/success', 'kv'); - const entityEmpty = entity('test/empty'); - const entityNotOk = entity('test/error'); - - const mockSecretsResult: { items: VaultSecret[] } = { - items: [ - { - name: 'secret::one', - path: 'test/success', - editUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/edit/test/success/secret::one`, - showUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/show/test/success/secret::one`, - }, - { - name: 'secret::two', - path: 'test/success', - editUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/edit/test/success/secret::two`, - showUrl: `${mockBaseUrl}/ui/vault/secrets/secrets/show/test/success/secret::two`, - }, - ], - }; - - const setupHandlers = () => { - server.use( - rest.get(`${mockBaseUrl}/v1/secrets/:path`, (req, res, ctx) => { - const { path } = req.params; - if (path === 'test/success') { - return res(ctx.json(mockSecretsResult)); - } else if (path === 'test/empty') { - return res(ctx.json([])); - } - return res(ctx.status(400)); - }), - ); - }; - - beforeEach(() => { - jest.resetAllMocks(); - vaultClient = new VaultClient({ discoveryApi, fetchApi }); - apis = TestApiRegistry.from([vaultApiRef, vaultClient]); - listSecretsSpy = jest.spyOn(vaultClient, 'listSecrets'); - }); - - it('should render secrets', async () => { - setupHandlers(); - const rendered = await renderInTestApp( - - - , - ); - - expect(await rendered.findAllByText(/secret::one/)).toBeDefined(); - expect(await rendered.findAllByText(/secret::two/)).toBeDefined(); - - expect(listSecretsSpy).toHaveBeenCalledTimes(1); - expect(listSecretsSpy).toHaveBeenCalledWith('test/success', { - secretEngine: undefined, - }); - }); - - it('should render secrets with custom engine', async () => { - setupHandlers(); - const rendered = await renderInTestApp( - - - , - ); - - expect(await rendered.findAllByText(/secret::one/)).toBeDefined(); - expect(await rendered.findAllByText(/secret::two/)).toBeDefined(); - - expect(listSecretsSpy).toHaveBeenCalledTimes(1); - expect(listSecretsSpy).toHaveBeenCalledWith('test/success', { - secretEngine: 'kv', - }); - }); - - it('should render no secrets found', async () => { - setupHandlers(); - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText(/No secrets found/)).toBeInTheDocument(); - }); - - it('should surface an appropriate error when the Vault API responds unsuccessfully', async () => { - setupHandlers(); - const rendered = await renderInTestApp( - - - , - ); - - expect( - rendered.getByText( - /Unexpected error while fetching secrets from path \'test\/error\'\: Request failed with 400 Error/, - ), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.tsx b/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.tsx deleted file mode 100644 index 4d169611ca..0000000000 --- a/plugins/vault/src/components/EntityVaultTable/EntityVaultTable.tsx +++ /dev/null @@ -1,120 +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 { Entity } from '@backstage/catalog-model'; -import { Link, Table, TableColumn } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { Box, Typography } from '@material-ui/core'; -import Edit from '@material-ui/icons/Edit'; -import Visibility from '@material-ui/icons/Visibility'; -import Alert from '@material-ui/lab/Alert'; -import useAsync from 'react-use/lib/useAsync'; -import { VaultSecret, vaultApiRef } from '../../api'; -import { - VAULT_SECRET_ENGINE_ANNOTATION, - VAULT_SECRET_PATH_ANNOTATION, -} from '../../constants'; - -export const vaultSecretConfig = (entity: Entity) => { - const secretPath = - entity.metadata.annotations?.[VAULT_SECRET_PATH_ANNOTATION]; - const secretEngine = - entity.metadata.annotations?.[VAULT_SECRET_ENGINE_ANNOTATION]; - - return { secretPath, secretEngine }; -}; - -export const EntityVaultTable = ({ entity }: { entity: Entity }) => { - const vaultApi = useApi(vaultApiRef); - const { secretPath, secretEngine } = vaultSecretConfig(entity); - if (!secretPath) { - throw Error( - `The secret path is undefined. Please, define the annotation ${VAULT_SECRET_PATH_ANNOTATION}`, - ); - } - - const { value, loading, error } = useAsync(async (): Promise< - VaultSecret[] - > => { - return vaultApi.listSecrets(secretPath, { secretEngine }); - }, []); - - const columns: TableColumn[] = [ - { title: 'Secret', field: 'secret', highlight: true }, - { title: 'View URL', field: 'view', width: '10%' }, - { title: 'Edit URL', field: 'edit', width: '10%' }, - ]; - - const data = (value || []).map(secret => { - const secretName = `${secret.path.replace(`${secretPath}/`, '')}/${ - secret.name - }`; - - return { - secret: secretName, - view: ( - - - - ), - edit: ( - - - - ), - }; - }); - - if (error) { - return ( - - Unexpected error while fetching secrets from path '{secretPath}':{' '} - {error.message} - - ); - } - - return ( - - - No secrets found for {entity.metadata.name} in {secretPath} - - - } - /> - ); -}; diff --git a/plugins/vault/src/components/EntityVaultTable/index.tsx b/plugins/vault/src/components/EntityVaultTable/index.tsx deleted file mode 100644 index eeb8440b5c..0000000000 --- a/plugins/vault/src/components/EntityVaultTable/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { EntityVaultTable } from './EntityVaultTable'; diff --git a/plugins/vault/src/conditions.ts b/plugins/vault/src/conditions.ts deleted file mode 100644 index 091c7117c2..0000000000 --- a/plugins/vault/src/conditions.ts +++ /dev/null @@ -1,29 +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 { Entity } from '@backstage/catalog-model'; -import { VAULT_SECRET_PATH_ANNOTATION } from './constants'; - -/** - * Checks if an entity contains the annotation for Vault. - * @param entity - The entity to check if the annotation exists - * @returns If the annotation exists or not - * @public - */ -export function isVaultAvailable(entity: Entity): boolean { - return Boolean( - entity.metadata.annotations?.hasOwnProperty(VAULT_SECRET_PATH_ANNOTATION), - ); -} diff --git a/plugins/vault/src/constants.ts b/plugins/vault/src/constants.ts deleted file mode 100644 index a71a1c104f..0000000000 --- a/plugins/vault/src/constants.ts +++ /dev/null @@ -1,24 +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. - */ - -/** - * @public - */ -export const VAULT_SECRET_ENGINE_ANNOTATION = 'vault.io/secrets-engine'; -/** - * @public - */ -export const VAULT_SECRET_PATH_ANNOTATION = 'vault.io/secrets-path'; diff --git a/plugins/vault/src/index.ts b/plugins/vault/src/index.ts deleted file mode 100644 index f69a787963..0000000000 --- a/plugins/vault/src/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { vaultPlugin, EntityVaultCard } from './plugin'; -export { isVaultAvailable } from './conditions'; -export { VAULT_SECRET_PATH_ANNOTATION } from './constants'; -export { vaultApiRef } from './api'; -export type { VaultApi, VaultSecret } from './api'; diff --git a/plugins/vault/src/plugin.test.ts b/plugins/vault/src/plugin.test.ts deleted file mode 100644 index b6c5a9c9a0..0000000000 --- a/plugins/vault/src/plugin.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { vaultPlugin } from './plugin'; - -describe('vault', () => { - it('should export plugin', () => { - expect(vaultPlugin).toBeDefined(); - }); -}); diff --git a/plugins/vault/src/plugin.ts b/plugins/vault/src/plugin.ts deleted file mode 100644 index f62a8a73e4..0000000000 --- a/plugins/vault/src/plugin.ts +++ /dev/null @@ -1,65 +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 { - createApiFactory, - createComponentExtension, - createPlugin, - DiscoveryApi, - discoveryApiRef, - FetchApi, - fetchApiRef, -} from '@backstage/core-plugin-api'; - -import { vaultApiRef, VaultClient } from './api'; - -/** - * The vault plugin. - * @public - */ -export const vaultPlugin = createPlugin({ - id: 'vault', - apis: [ - createApiFactory({ - api: vaultApiRef, - deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, - factory: ({ - discoveryApi, - fetchApi, - }: { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - }) => - new VaultClient({ - discoveryApi, - fetchApi, - }), - }), - ], -}); - -/** - * Card used to show the list of Vault secrets. - * @public - */ -export const EntityVaultCard = vaultPlugin.provide( - createComponentExtension({ - name: 'EntityVaultCard', - component: { - lazy: () => - import('./components/EntityVaultCard').then(m => m.EntityVaultCard), - }, - }), -); diff --git a/plugins/vault/src/routes.ts b/plugins/vault/src/routes.ts deleted file mode 100644 index 40743b524f..0000000000 --- a/plugins/vault/src/routes.ts +++ /dev/null @@ -1,20 +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 { createRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'vault', -}); diff --git a/plugins/vault/src/setupTests.ts b/plugins/vault/src/setupTests.ts deleted file mode 100644 index 28a35d2b06..0000000000 --- a/plugins/vault/src/setupTests.ts +++ /dev/null @@ -1,16 +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 '@testing-library/jest-dom'; diff --git a/plugins/xcmetrics/.eslintrc.js b/plugins/xcmetrics/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/xcmetrics/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md deleted file mode 100644 index 792bb95e42..0000000000 --- a/plugins/xcmetrics/CHANGELOG.md +++ /dev/null @@ -1,1156 +0,0 @@ -# @backstage/plugin-xcmetrics - -## 0.2.48-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.2 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.2.48-next.1 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 8fe56a8: Widen `@types/react` dependency range to include version 18. -- Updated dependencies - - @backstage/core-components@0.14.0-next.1 - - @backstage/core-plugin-api@1.9.0-next.1 - - @backstage/errors@1.2.3 - -## 0.2.48-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.14.0-next.0 - - @backstage/core-plugin-api@1.8.3-next.0 - - @backstage/errors@1.2.3 - -## 0.2.47 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10 - - @backstage/core-plugin-api@1.8.2 - - @backstage/errors@1.2.3 - -## 0.2.47-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.2-next.0 - - @backstage/core-components@0.13.10-next.1 - - @backstage/errors@1.2.3 - -## 0.2.47-next.0 - -### Patch Changes - -- 4016f21: Remove some unused dependencies -- Updated dependencies - - @backstage/core-components@0.13.10-next.0 - - @backstage/core-plugin-api@1.8.1 - - @backstage/errors@1.2.3 - -## 0.2.46 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1 - - @backstage/core-components@0.13.9 - - @backstage/theme@0.5.0 - - @backstage/errors@1.2.3 - -## 0.2.46-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.3 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.1 - -## 0.2.46-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.5.0-next.1 - - @backstage/core-components@0.13.9-next.2 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - -## 0.2.46-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.9-next.1 - - @backstage/core-plugin-api@1.8.1-next.1 - - @backstage/errors@1.2.3 - - @backstage/theme@0.5.0-next.0 - -## 0.2.46-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.8.1-next.0 - - @backstage/core-components@0.13.9-next.0 - - @backstage/theme@0.5.0-next.0 - - @backstage/errors@1.2.3 - -## 0.2.45 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- 62b5922916: Internal theme type updates -- Updated dependencies - - @backstage/core-components@0.13.8 - - @backstage/core-plugin-api@1.8.0 - - @backstage/theme@0.4.4 - - @backstage/errors@1.2.3 - -## 0.2.45-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.8-next.2 - -## 0.2.45-next.1 - -### Patch Changes - -- 62b5922916: Internal theme type updates -- Updated dependencies - - @backstage/core-components@0.13.8-next.1 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.4-next.0 - -## 0.2.45-next.0 - -### Patch Changes - -- 6c2b872153: Add official support for React 18. -- Updated dependencies - - @backstage/core-components@0.13.7-next.0 - - @backstage/core-plugin-api@1.8.0-next.0 - - @backstage/theme@0.4.4-next.0 - - @backstage/errors@1.2.3 - -## 0.2.44 - -### Patch Changes - -- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. -- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.7.0 - - @backstage/core-components@0.13.6 - - @backstage/errors@1.2.3 - - @backstage/theme@0.4.3 - -## 0.2.44-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.2 - - @backstage/core-plugin-api@1.7.0-next.1 - - @backstage/errors@1.2.3-next.0 - - @backstage/theme@0.4.3-next.0 - -## 0.2.44-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.6-next.1 - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.2.44-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.7.0-next.0 - - @backstage/core-components@0.13.6-next.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.2.43 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- 8cec7664e146: Removed `@types/node` dependency -- 814feeed7343: Update to handle invalid luxon values -- Updated dependencies - - @backstage/core-components@0.13.5 - - @backstage/core-plugin-api@1.6.0 - - @backstage/errors@1.2.2 - - @backstage/theme@0.4.2 - -## 0.2.42 - -Skipped due to publishing issues. - -## 0.2.42-next.3 - -### Patch Changes - -- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. -- Updated dependencies - - @backstage/core-components@0.13.5-next.3 - - @backstage/core-plugin-api@1.6.0-next.3 - - @backstage/errors@1.2.2-next.0 - - @backstage/theme@0.4.2-next.0 - -## 0.2.42-next.2 - -### Patch Changes - -- 8cec7664e146: Removed `@types/node` dependency -- 814feeed7343: Update to handle invalid luxon values -- Updated dependencies - - @backstage/core-components@0.13.5-next.2 - - @backstage/core-plugin-api@1.6.0-next.2 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.42-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.5-next.1 - - @backstage/core-plugin-api@1.6.0-next.1 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.42-next.0 - -### Patch Changes - -- 482bb5c0bbf8: Moved `@types/react` to be a regular dependency -- Updated dependencies - - @backstage/core-plugin-api@1.6.0-next.0 - - @backstage/core-components@0.13.5-next.0 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.41 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- 3d86be999fdf: Prefer simple `theme.spacing` without string interpolation -- Updated dependencies - - @backstage/core-components@0.13.4 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.41-next.1 - -### Patch Changes - -- 12a8c94eda8d: Add package repository and homepage metadata -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.41-next.0 - -### Patch Changes - -- 3d86be999fdf: Prefer simple `theme.spacing` without string interpolation -- Updated dependencies - - @backstage/core-components@0.13.4-next.0 - - @backstage/core-plugin-api@1.5.3 - - @backstage/errors@1.2.1 - - @backstage/theme@0.4.1 - -## 0.2.40 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1 - - @backstage/errors@1.2.1 - - @backstage/core-components@0.13.3 - - @backstage/core-plugin-api@1.5.3 - -## 0.2.40-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.1 - - @backstage/core-plugin-api@1.5.3-next.1 - - @backstage/core-components@0.13.3-next.2 - - @backstage/errors@1.2.1-next.0 - -## 0.2.40-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.1-next.0 - - @backstage/core-components@0.13.3-next.1 - - @backstage/core-plugin-api@1.5.3-next.0 - -## 0.2.40-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/core-components@0.13.3-next.0 - - @backstage/core-plugin-api@1.5.2 - - @backstage/theme@0.4.0 - -## 0.2.39 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.5.2 - - @backstage/core-components@0.13.2 - - @backstage/theme@0.4.0 - - @backstage/errors@1.2.0 - -## 0.2.39-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.2-next.3 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/errors@1.2.0-next.0 - - @backstage/theme@0.4.0-next.1 - -## 0.2.39-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.1 - - @backstage/core-components@0.13.2-next.2 - - @backstage/core-plugin-api@1.5.2-next.0 - -## 0.2.39-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.0-next.0 - - @backstage/core-components@0.13.2-next.1 - - @backstage/core-plugin-api@1.5.2-next.0 - - @backstage/theme@0.4.0-next.0 - -## 0.2.39-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.4.0-next.0 - - @backstage/core-components@0.13.2-next.0 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.2.38 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0 - - @backstage/core-components@0.13.1 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.2.38-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/theme@0.3.0-next.0 - - @backstage/core-components@0.13.1-next.1 - - @backstage/core-plugin-api@1.5.1 - -## 0.2.38-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.1-next.0 - - @backstage/core-plugin-api@1.5.1 - -## 0.2.37 - -### Patch Changes - -- 55a969fe574: Bumped `recharts` dependency to `^2.5.0`. -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.13.0 - - @backstage/theme@0.2.19 - - @backstage/core-plugin-api@1.5.1 - - @backstage/errors@1.1.5 - -## 0.2.37-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.13.0-next.3 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.2.37-next.2 - -### Patch Changes - -- 55a969fe574: Bumped `recharts` dependency to `^2.5.0`. -- Updated dependencies - - @backstage/core-components@0.12.6-next.2 - - @backstage/core-plugin-api@1.5.1-next.1 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.19-next.0 - -## 0.2.37-next.1 - -### Patch Changes - -- e0c6e8b9c3c: Update peer dependencies -- Updated dependencies - - @backstage/core-components@0.12.6-next.1 - - @backstage/core-plugin-api@1.5.1-next.0 - - @backstage/theme@0.2.19-next.0 - - @backstage/errors@1.1.5 - -## 0.2.37-next.0 - -### Patch Changes - -- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) -- Updated dependencies - - @backstage/core-components@0.12.6-next.0 - - @backstage/core-plugin-api@1.5.0 - - @backstage/errors@1.1.5 - - @backstage/theme@0.2.18 - -## 0.2.36 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5 - - @backstage/errors@1.1.5 - - @backstage/core-plugin-api@1.5.0 - - @backstage/theme@0.2.18 - -## 0.2.36-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.5-next.2 - - @backstage/core-plugin-api@1.5.0-next.2 - -## 0.2.36-next.1 - -### Patch Changes - -- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. -- Updated dependencies - - @backstage/core-components@0.12.5-next.1 - - @backstage/errors@1.1.5-next.0 - - @backstage/core-plugin-api@1.4.1-next.1 - - @backstage/theme@0.2.18-next.0 - -## 0.2.36-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.4.1-next.0 - - @backstage/core-components@0.12.5-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.17 - -## 0.2.35 - -### Patch Changes - -- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend -- Updated dependencies - - @backstage/core-components@0.12.4 - - @backstage/theme@0.2.17 - - @backstage/core-plugin-api@1.4.0 - - @backstage/errors@1.1.4 - -## 0.2.35-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.1 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.35-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.4-next.0 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.34 - -### Patch Changes - -- 27a5e90e97: Small updates to some paragraph components to ensure theme typography properties are inherited correctly. -- Updated dependencies - - @backstage/core-components@0.12.3 - - @backstage/core-plugin-api@1.3.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.34-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.3.0-next.1 - - @backstage/core-components@0.12.3-next.2 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.34-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.1 - - @backstage/core-plugin-api@1.2.1-next.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.34-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.3-next.0 - - @backstage/core-plugin-api@1.2.0 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.33 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.2 - -## 0.2.32 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.2.0 - - @backstage/core-components@0.12.1 - - @backstage/errors@1.1.4 - - @backstage/theme@0.2.16 - -## 0.2.32-next.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.4 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.32-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.3 - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.32-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@1.2.0-next.2 - - @backstage/core-components@0.12.1-next.2 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.32-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.1-next.1 - - @backstage/core-plugin-api@1.1.1-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/theme@0.2.16 - -## 0.2.32-next.0 - -### Patch Changes - -- 3280711113: Updated dependency `msw` to `^0.49.0`. -- Updated dependencies - - @backstage/core-components@0.12.1-next.0 - - @backstage/core-plugin-api@1.1.1-next.0 - - @backstage/errors@1.1.4-next.0 - - @backstage/theme@0.2.16 - -## 0.2.31 - -### Patch Changes - -- 7573b65232: Internal refactor of imports to avoid circular dependencies -- 43afded227: Updated recharts to v2.0.0 and fixed typing issues -- dcf9e728de: Removed an unused and hidden build details route. -- Updated dependencies - - @backstage/core-components@0.12.0 - - @backstage/core-plugin-api@1.1.0 - - @backstage/errors@1.1.3 - - @backstage/theme@0.2.16 - -## 0.2.31-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.12.0-next.1 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.2.31-next.0 - -### Patch Changes - -- 7573b65232: Internal refactor of imports to avoid circular dependencies -- 43afded227: Updated recharts to v2.0.0 and fixed typing issues -- dcf9e728de: Removed an unused and hidden build details route. -- Updated dependencies - - @backstage/core-components@0.12.0-next.0 - - @backstage/core-plugin-api@1.1.0-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/theme@0.2.16 - -## 0.2.30 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2 - - @backstage/core-plugin-api@1.0.7 - - @backstage/errors@1.1.2 - - @backstage/theme@0.2.16 - -## 0.2.30-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.2 - - @backstage/core-plugin-api@1.0.7-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/theme@0.2.16 - -## 0.2.30-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.1 - - @backstage/core-plugin-api@1.0.7-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/theme@0.2.16 - -## 0.2.30-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.11.2-next.0 - - @backstage/core-plugin-api@1.0.7-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/theme@0.2.16 - -## 0.2.29 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- d669d89206: Minor API signatures cleanup -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-components@0.11.1 - - @backstage/core-plugin-api@1.0.6 - - @backstage/errors@1.1.1 - -## 0.2.29-next.3 - -### Patch Changes - -- 7d47def9c4: Removed dependency on `@types/jest`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.3 - - @backstage/core-plugin-api@1.0.6-next.3 - - @backstage/errors@1.1.1-next.0 - -## 0.2.29-next.2 - -### Patch Changes - -- 667d917488: Updated dependency `msw` to `^0.47.0`. -- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. -- Updated dependencies - - @backstage/core-components@0.11.1-next.2 - - @backstage/core-plugin-api@1.0.6-next.2 - -## 0.2.29-next.1 - -### Patch Changes - -- d669d89206: Minor API signatures cleanup -- Updated dependencies - - @backstage/core-components@0.11.1-next.1 - - @backstage/core-plugin-api@1.0.6-next.1 - -## 0.2.29-next.0 - -### Patch Changes - -- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.6-next.0 - - @backstage/core-components@0.11.1-next.0 - -## 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 - -- a70869e775: Updated dependency `msw` to `^0.43.0`. -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/core-plugin-api@1.0.4-next.0 - - @backstage/core-components@0.10.0-next.3 - -## 0.2.27-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.10.0-next.2 - - @backstage/theme@0.2.16-next.1 - -## 0.2.27-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.1 - - @backstage/errors@1.1.0-next.0 - - @backstage/theme@0.2.16-next.0 - -## 0.2.27-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.6-next.0 - -## 0.2.26 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5 - - @backstage/core-plugin-api@1.0.3 - -## 0.2.26-next.1 - -### Patch Changes - -- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. -- Updated dependencies - - @backstage/core-components@0.9.5-next.1 - - @backstage/core-plugin-api@1.0.3-next.0 - -## 0.2.26-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.5-next.0 - -## 0.2.25 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4 - - @backstage/core-plugin-api@1.0.2 - -## 0.2.25-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.4-next.0 - - @backstage/core-plugin-api@1.0.2-next.0 - -## 0.2.24 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3 - - @backstage/core-plugin-api@1.0.1 - -## 0.2.24-next.1 - -### Patch Changes - -- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 -- 230ad0826f: Bump to using `@types/node` v16 -- Updated dependencies - - @backstage/core-components@0.9.3-next.2 - - @backstage/core-plugin-api@1.0.1-next.0 - -## 0.2.24-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.3-next.0 - -## 0.2.23 - -### Patch Changes - -- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 -- f24ef7864e: Minor typo fixes -- Updated dependencies - - @backstage/core-components@0.9.2 - - @backstage/core-plugin-api@1.0.0 - - @backstage/errors@1.0.0 - -## 0.2.22 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.1 - -## 0.2.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.1-next.0 - -## 0.2.21 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.9.0 - - @backstage/core-plugin-api@0.8.0 - -## 0.2.20 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.10 - - @backstage/core-plugin-api@0.7.0 - -## 0.2.19 - -### Patch Changes - -- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/core-components@0.8.9 - - @backstage/core-plugin-api@0.6.1 - - @backstage/errors@0.2.1 - - @backstage/theme@0.2.15 - -## 0.2.18 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8 - -## 0.2.18-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.8-next.0 - -## 0.2.17 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7 - -## 0.2.17-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.7-next.0 - -## 0.2.16 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.5 - - @backstage/core-plugin-api@0.6.0 - -## 0.2.16-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.5-next.0 - - @backstage/core-plugin-api@0.6.0-next.0 - -## 0.2.15 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.8.4 - - @backstage/core-plugin-api@0.5.0 - - @backstage/errors@0.2.0 - -## 0.2.14 - -### Patch Changes - -- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. -- Updated dependencies - - @backstage/core-plugin-api@0.4.1 - - @backstage/core-components@0.8.3 - -## 0.2.13 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.4.0 - - @backstage/core-components@0.8.2 - -## 0.2.12 - -### Patch Changes - -- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. -- 343ef34599: Handle a case where XCode data from backend (before 0.0.8) could be missing -- Updated dependencies - - @backstage/core-components@0.8.0 - - @backstage/core-plugin-api@0.3.0 - -## 0.2.11 - -### Patch Changes - -- af09b1e059: Fix bug where invalid build statuses led to crashes -- Updated dependencies - - @backstage/core-components@0.7.6 - - @backstage/theme@0.2.14 - - @backstage/core-plugin-api@0.2.2 - -## 0.2.10 - -### Patch Changes - -- a125278b81: Refactor out the deprecated path and icon from RouteRefs -- Updated dependencies - - @backstage/core-components@0.7.4 - - @backstage/core-plugin-api@0.2.0 - -## 0.2.9 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.7.0 - - @backstage/theme@0.2.11 - -## 0.2.8 - -### Patch Changes - -- ca0559444c: Avoid usage of `.to*Case()`, preferring `.toLocale*Case('en-US')` instead. -- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. -- Updated dependencies - - @backstage/core-components@0.6.1 - - @backstage/core-plugin-api@0.1.10 - -## 0.2.7 - -### Patch Changes - -- Updated dependencies - - @backstage/core-plugin-api@0.1.9 - - @backstage/core-components@0.6.0 - -## 0.2.6 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.5.0 - -## 0.2.5 - -### Patch Changes - -- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. -- Updated dependencies - - @backstage/core-components@0.4.2 - - @backstage/core-plugin-api@0.1.8 - -## 0.2.4 - -### Patch Changes - -- Updated dependencies - - @backstage/core-components@0.4.0 - -## 0.2.3 - -### Patch Changes - -- eed15251e: Enable browsing detailed build information such as host configuration, errors, warnings, metadata and a timeline for all targets -- 8ee9aa066: Internal refactoring -- Updated dependencies - - @backstage/core-components@0.3.2 - - @backstage/theme@0.2.10 - -## 0.2.2 - -### Patch Changes - -- 8bedb75ae: Update Luxon dependency to 2.x -- Updated dependencies - - @backstage/core-components@0.3.1 - - @backstage/core-plugin-api@0.1.6 - -## 0.2.1 - -### Patch Changes - -- f6f664357: New page for browsing all builds with filtering and pagination capabilities -- Updated dependencies - - @backstage/core-components@0.3.0 - - @backstage/core-plugin-api@0.1.5 - -## 0.2.0 - -### Minor Changes - -- 616e10e94: New data in form of trend lines, status timeline and other is added to the dashboard of XCMetrics to give a better understanding of how the build system is behaving. - -### Patch Changes - -- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. - - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` - - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. - - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` - - `onChangePage` has been renamed to `onPageChange` - - Migration guide is here: https://material-table-core.com/docs/breaking-changes -- Updated dependencies - - @backstage/core-components@0.2.0 - - @backstage/core-plugin-api@0.1.4 - - @backstage/theme@0.2.9 diff --git a/plugins/xcmetrics/README.md b/plugins/xcmetrics/README.md deleted file mode 100644 index 0823cbbb24..0000000000 --- a/plugins/xcmetrics/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# XCMetrics - -[XCMetrics](https://xcmetrics.io) is a tool for collecting build metrics from XCode. -With this plugin, you can view data from XCMetrics directly in Backstage. - -![XCMetrics-overview](./docs/XCMetrics-overview.png) - -## Getting started - -```bash -# From your Backstage root directory -yarn --cwd packages/app add @backstage/plugin-xcmetrics -``` - -In `packages/app/src/App.tsx`, add the following: - -```ts -import { XcmetricsPage } from '@backstage/plugin-xcmetrics'; -``` - -```tsx - - {/* Other routes... */} - } /> - -``` - -Add the URL to your XCMetrics backend instance in `app-config.yaml` like so: - -```yaml -proxy: - ... - '/xcmetrics': - target: http://127.0.0.1:8080/v1 -``` - -Start Backstage and navigate to `/xcmetrics` to view your build metrics! diff --git a/plugins/xcmetrics/api-report.md b/plugins/xcmetrics/api-report.md deleted file mode 100644 index 94a2d4afcd..0000000000 --- a/plugins/xcmetrics/api-report.md +++ /dev/null @@ -1,22 +0,0 @@ -## API Report File for "@backstage/plugin-xcmetrics" - -> 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 { JSX as JSX_2 } from 'react'; -import { RouteRef } from '@backstage/core-plugin-api'; - -// @public (undocumented) -export const XcmetricsPage: () => JSX_2.Element; - -// @public (undocumented) -export const xcmetricsPlugin: BackstagePlugin< - { - root: RouteRef; - }, - {} ->; -``` diff --git a/plugins/xcmetrics/catalog-info.yaml b/plugins/xcmetrics/catalog-info.yaml deleted file mode 100644 index 5550198a2f..0000000000 --- a/plugins/xcmetrics/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-plugin-xcmetrics - title: '@backstage/plugin-xcmetrics' - description: A Backstage plugin that shows XCode build metrics for your components -spec: - lifecycle: experimental - type: backstage-frontend-plugin - owner: maintainers diff --git a/plugins/xcmetrics/dev/index.tsx b/plugins/xcmetrics/dev/index.tsx deleted file mode 100644 index f6663dd33d..0000000000 --- a/plugins/xcmetrics/dev/index.tsx +++ /dev/null @@ -1,27 +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 { createDevApp } from '@backstage/dev-utils'; -import { xcmetricsPlugin, XcmetricsPage } from '../src/plugin'; - -createDevApp() - .registerPlugin(xcmetricsPlugin) - .addPage({ - element: , - title: 'Root Page', - path: '/xcmetrics', - }) - .render(); diff --git a/plugins/xcmetrics/docs/XCMetrics-overview.png b/plugins/xcmetrics/docs/XCMetrics-overview.png deleted file mode 100644 index 764bfa9836..0000000000 Binary files a/plugins/xcmetrics/docs/XCMetrics-overview.png and /dev/null differ diff --git a/plugins/xcmetrics/knip-report.md b/plugins/xcmetrics/knip-report.md deleted file mode 100644 index 8d850953c7..0000000000 --- a/plugins/xcmetrics/knip-report.md +++ /dev/null @@ -1,8 +0,0 @@ -# Knip report - -## Unused devDependencies (1) - -| Name | Location | Severity | -| :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | - diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json deleted file mode 100644 index 0389d72a00..0000000000 --- a/plugins/xcmetrics/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@backstage/plugin-xcmetrics", - "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.48-next.2", - "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" - }, - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "plugins/xcmetrics" - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "start": "backstage-cli package start", - "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" - }, - "dependencies": { - "@backstage/core-components": "workspace:^", - "@backstage/core-plugin-api": "workspace:^", - "@backstage/errors": "workspace:^", - "@material-ui/core": "^4.12.2", - "@material-ui/icons": "^4.9.1", - "@material-ui/lab": "4.0.0-alpha.61", - "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "lodash": "^4.17.21", - "luxon": "^3.0.0", - "react-use": "^17.2.4", - "recharts": "^2.5.0" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0", - "react-router-dom": "6.0.0-beta.0 || ^6.3.0" - }, - "devDependencies": { - "@backstage/cli": "workspace:^", - "@backstage/dev-utils": "workspace:^", - "@backstage/test-utils": "workspace:^", - "@testing-library/dom": "^9.0.0", - "@testing-library/jest-dom": "^6.0.0", - "@testing-library/react": "^14.0.0", - "@testing-library/user-event": "^14.0.0", - "@types/luxon": "^3.0.0" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/xcmetrics/src/api/XcmetricsClient.ts b/plugins/xcmetrics/src/api/XcmetricsClient.ts deleted file mode 100644 index 37baa949d4..0000000000 --- a/plugins/xcmetrics/src/api/XcmetricsClient.ts +++ /dev/null @@ -1,145 +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 { DiscoveryApi } from '@backstage/core-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { DateTime } from 'luxon'; -import { - Build, - BuildCount, - BuildError, - BuildFilters, - BuildHost, - BuildMetadata, - BuildResponse, - BuildStatusResult, - BuildTime, - BuildWarning, - PaginationResult, - XcmetricsApi, -} from './types'; - -interface Options { - discoveryApi: DiscoveryApi; -} - -export class XcmetricsClient implements XcmetricsApi { - private readonly discoveryApi: DiscoveryApi; - - constructor(options: Options) { - this.discoveryApi = options.discoveryApi; - } - - async getBuild(id: string): Promise { - const response = await this.get(`/build/${id}`); - return (await response.json()) as BuildResponse; - } - - async getBuilds(limit: number = 10): Promise { - const response = await this.get(`/build?per=${limit}`); - return ((await response.json()) as PaginationResult).items; - } - - async getFilteredBuilds( - filters: BuildFilters, - page?: number, - perPage?: number, - ): Promise> { - const response = await this.post('/build/filter', { - from: DateTime.fromISO(filters.from) - .startOf('day') - .toISO({ suppressMilliseconds: true }), - to: DateTime.fromISO(filters.to) - .endOf('day') - .startOf('second') - .toISO({ suppressMilliseconds: true }), - status: filters.buildStatus, - projectName: filters.project, - page, - per: perPage, - }); - - return (await response.json()) as PaginationResult; - } - - async getBuildCounts(days: number): Promise { - const response = await this.get(`/statistics/build/count?days=${days}`); - return (await response.json()) as BuildCount[]; - } - - async getBuildErrors(buildId: string): Promise { - const response = await this.get(`/build/error/${buildId}`); - return (await response.json()) as BuildError[]; - } - - async getBuildHost(buildId: string): Promise { - const response = await this.get(`/build/host/${buildId}`); - return (await response.json()) as BuildHost; - } - - async getBuildMetadata(buildId: string): Promise { - const response = await this.get(`/build/metadata/${buildId}`); - return ((await response.json()) as Record<'metadata', BuildMetadata>) - .metadata; - } - - async getBuildTimes(days: number): Promise { - const response = await this.get(`/statistics/build/time?days=${days}`); - return (await response.json()) as BuildTime[]; - } - - async getBuildStatuses(limit: number): Promise { - const response = await this.get(`/statistics/build/status?per=${limit}`); - return ((await response.json()) as PaginationResult) - .items; - } - - async getBuildWarnings(buildId: string): Promise { - const response = await this.get(`/build/warning/${buildId}`); - return (await response.json()) as BuildWarning[]; - } - - async getProjects(): Promise { - const response = await this.get('/build/project'); - return (await response.json()) as string[]; - } - - private async get(path: string): Promise { - const baseUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/xcmetrics`; - const response = await fetch(`${baseUrl}${path}`); - - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } - - return response; - } - - private async post(path: string, body: Object): Promise { - const baseUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/xcmetrics`; - const response = await fetch(`${baseUrl}${path}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(body), - }); - - if (!response.ok) { - throw await ResponseError.fromResponse(response); - } - - return response; - } -} diff --git a/plugins/xcmetrics/src/api/__mocks__/XcmetricsClient.ts b/plugins/xcmetrics/src/api/__mocks__/XcmetricsClient.ts deleted file mode 100644 index 765be721c6..0000000000 --- a/plugins/xcmetrics/src/api/__mocks__/XcmetricsClient.ts +++ /dev/null @@ -1,231 +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 { - Build, - BuildCount, - BuildError, - BuildFilters, - BuildHost, - BuildMetadata, - BuildStatusResult, - BuildTime, - BuildWarning, - Target, - XcmetricsApi, - Xcode, -} from '../types'; - -const MOCK_BUILD_ID = 'buildId'; - -export const mockBuild: Build = { - userid: 'userid1', - warningCount: 1, - duration: 1, - startTimestamp: '2021-01-01T00:00:00Z', - isCi: true, - startTimestampMicroseconds: 0, - category: '', - endTimestampMicroseconds: 10000, - day: '2021-01-01', - compilationEndTimestamp: '2021-01-01T00:00:01Z', - tag: '', - projectName: 'ProjectName', - compilationEndTimestampMicroseconds: 1, - errorCount: 1, - id: MOCK_BUILD_ID, - buildStatus: 'succeeded', - compilationDuration: 1, - schema: 'SchemaName', - compiledCount: 1, - endTimestamp: '2021-01-01T00:00:01Z', - userid256: 'userId256', - machineName: 'Example_Machine', - wasSuspended: true, -}; - -export const mockBuildCount: BuildCount = { - day: '2021-07-10', - builds: 10, - errors: 1, -}; - -export const mockBuildError: BuildError = { - detail: `\/Users\/\/myproject\/Sources\/MyClass.m:241:97:// / error: instance method 'fetch' not found ; did you mean 'fetchIt'?\r - myclass:[self.myService fetch]\r ^~~~~~~~~~~~~~\r fetch\r - 1 error generated.\r"`, - characterRangeEnd: 13815, - id: '3E6EF185-6AC1-4E95-87E8-E305F41916E9', - endingColumn: 97, - parentIdentifier: 'MyMac_34580469-5792-40F3-BEFB-7C5925996F23_8860', - day: '2020-11-02T00:00:00Z', - type: 'clangError', - title: 'Instance method "fetch" not found ; did you mean "fetchIt"?', - endingLine: 241, - severity: 2, - startingLine: 241, - parentType: 'step', - buildIdentifier: MOCK_BUILD_ID, - startingColumn: 97, - characterRangeStart: 0, - documentURL: 'file:///Users//myproject/Sources/MyClass.m', -}; - -export const mockBuildHost: BuildHost = { - id: '9DD5508D-4AD9-4C1C-AB7C-45BC2183EC51', - swapFreeMb: 1615.25, - hostOsFamily: 'Darwin', - isVirtual: false, - uptimeSeconds: 1602055187, - hostModel: 'MacBookPro14,2', - hostOsVersion: '10.15.7', - day: '2020-10-26T00:00:00Z', - cpuCount: 4, - swapTotalMb: 7168, - hostOs: 'Mac OS X', - hostArchitecture: 'x86_64', - memoryTotalMb: 16384, - timezone: 'CET', - cpuModel: 'Intel(R) Core(TM) i7-7567U CPU @ 3.50GHz', - buildIdentifier: MOCK_BUILD_ID, - memoryFreeMb: 24.5234375, - cpuSpeedGhz: 3.5, -}; - -export const mockBuildMetadata: BuildMetadata = { - anotherKey: '42', - thirdKey: 'Third value', - aKey: 'value1', -}; - -export const mockBuildTime: BuildTime = { - day: '2021-07-10', - durationP50: 1.1, - durationP95: 2.1, - totalDuration: 3.1, -}; -export const mockBuildStatus: BuildStatusResult = { - id: MOCK_BUILD_ID, - buildStatus: 'succeeded', -}; - -export const mockBuildWarning: BuildWarning = { - detail: null, - characterRangeEnd: 9817, - documentURL: 'file:///Users//myproject/Sources/MyViewController.m', - endingColumn: 22, - id: '5F2011AC-F87F-4EDC-BBC6-2BBA3D789EB3', - parentIdentifier: 'MyMac_34580469-5792-40F3-BEFB-7C5925996F23_1845', - day: '2020-11-02T00:00:00Z', - type: 'deprecatedWarning', - title: - "'dimsBackgroundDuringPresentation' is deprecated: first deprecated in iOS 12.0", - endingLine: 235, - severity: 1, - startingLine: 235, - parentType: 'step', - clangFlag: '[-Wdeprecated-declarations]', - startingColumn: 22, - buildIdentifier: MOCK_BUILD_ID, - characterRangeStart: 0, -}; - -export const mockTarget: Target = { - id: 'MyMac_34580469-5792-40F3-BEFB-7C5925996F23_1992', - category: 'noop', - startTimestamp: '2020-11-02T10:59:09Z', - compilationEndTimestampMicroseconds: 1604314749.2909288, - endTimestampMicroseconds: 1604314982.298002, - endTimestamp: '2020-11-02T11:03:02Z', - fetchedFromCache: false, - errorCount: 0, - day: '2020-11-02T00:00:00Z', - warningCount: 0, - compilationEndTimestamp: '2020-11-02T10:59:09Z', - compilationDuration: 0, - compiledCount: 0, - duration: 0.000233007, - buildIdentifier: MOCK_BUILD_ID, - name: 'Model', - startTimestampMicroseconds: 1604314749.2909288, -}; - -export const mockXcode: Xcode = { - buildNumber: '12A7209', - id: '6354C87F-0ADC-4354-929C-02EBE545E099', - buildIdentifier: MOCK_BUILD_ID, - day: '2020-11-02T00:00:00Z', - version: '1200', -}; - -export const mockBuildResponse = { - build: mockBuild, - targets: [mockTarget], - xcode: mockXcode, -}; - -export const XcmetricsClient: XcmetricsApi = { - getBuild: (_id: string) => { - return Promise.resolve(mockBuildResponse); - }, - getBuilds: () => { - return Promise.resolve([ - { ...mockBuild, id: '1' }, - { ...mockBuild, id: '2', userid: 'userid2' }, - ]); - }, - getFilteredBuilds: ( - _filters: BuildFilters, - _page?: number, - _perPage?: number, - ) => { - return Promise.resolve({ - items: [ - mockBuild, - { ...mockBuild, buildStatus: 'failed', projectName: 'ProjectName2' }, - ], - metadata: { - per: 10, - total: 2, - page: 1, - }, - }); - }, - getBuildErrors: (buildId: string) => { - return Promise.resolve([{ ...mockBuildError, buildIdentifier: buildId }]); - }, - getBuildCounts: () => { - return Promise.resolve([mockBuildCount, mockBuildCount]); - }, - getBuildHost: (buildId: string) => { - return Promise.resolve({ ...mockBuildHost, buildIdentifier: buildId }); - }, - getBuildMetadata: (_buildId: string) => { - return Promise.resolve(mockBuildMetadata); - }, - getBuildStatuses: (limit: number) => { - return Promise.resolve([mockBuild].slice(0, limit)); - }, - getBuildTimes: (days: number) => { - return Promise.resolve([mockBuildTime, mockBuildTime].slice(0, days)); - }, - getBuildWarnings: (buildId: string) => { - return Promise.resolve([{ ...mockBuildWarning, buildIdentifier: buildId }]); - }, - getProjects: () => { - return Promise.resolve([mockBuild.projectName]); - }, -}; diff --git a/plugins/xcmetrics/src/api/index.ts b/plugins/xcmetrics/src/api/index.ts deleted file mode 100644 index c184dc950d..0000000000 --- a/plugins/xcmetrics/src/api/index.ts +++ /dev/null @@ -1,18 +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. - */ - -export * from './types'; -export * from './XcmetricsClient'; diff --git a/plugins/xcmetrics/src/api/types.ts b/plugins/xcmetrics/src/api/types.ts deleted file mode 100644 index b4656e9478..0000000000 --- a/plugins/xcmetrics/src/api/types.ts +++ /dev/null @@ -1,196 +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 { createApiRef } from '@backstage/core-plugin-api'; - -export type BuildStatus = 'succeeded' | 'failed' | 'stopped'; - -export type Build = { - userid: string; - warningCount: number; - duration: number; - startTimestamp: string; - isCi: boolean; - startTimestampMicroseconds: number; - category: string; - endTimestampMicroseconds: number; - day: string; - compilationEndTimestamp: string; - tag: string; - projectName: string; - compilationEndTimestampMicroseconds: number; - errorCount: number; - id: string; - buildStatus: BuildStatus; - compilationDuration: number; - schema: string; - compiledCount: number; - endTimestamp: string; - userid256: string; - machineName: string; - wasSuspended: boolean; -}; - -export type BuildStatusResult = Pick; - -export type BuildCount = { - day: string; - errors: number; - builds: number; -}; - -export type BuildError = { - detail: string; - characterRangeEnd: number; - id: string; - endingColumn: number; - parentIdentifier: string; - day: string; - type: string; - title: string; - endingLine: number; - severity: number; - startingLine: number; - parentType: string; - buildIdentifier: string; - startingColumn: number; - characterRangeStart: number; - documentURL: string; -}; - -export type BuildHost = { - id: string; - swapFreeMb: number; - hostOsFamily: string; - isVirtual: boolean; - uptimeSeconds: number; - hostModel: string; - hostOsVersion: string; - day: string; - cpuCount: number; - swapTotalMb: number; - hostOs: string; - hostArchitecture: string; - memoryTotalMb: number; - timezone: string; - cpuModel: string; - buildIdentifier: string; - memoryFreeMb: number; - cpuSpeedGhz: number; -}; - -export type BuildMetadata = { - [key: string]: string; -}; - -export type BuildTime = { - day: string; - durationP50: number; - durationP95: number; - totalDuration: number; -}; - -export type BuildWarning = { - detail: string | null; - characterRangeEnd: number; - documentURL: string; - endingColumn: number; - id: string; - parentIdentifier: string; - day: string; - type: string; - title: string; - endingLine: number; - severity: number; - startingLine: number; - parentType: string; - clangFlag: string; - startingColumn: number; - buildIdentifier: string; - characterRangeStart: number; -}; - -export type PaginationResult = { - items: T[]; - metadata: { - per: number; - total: number; - page: number; - }; -}; - -export type Target = { - id: string; - category: string; - startTimestamp: string; - compilationEndTimestampMicroseconds: number; - endTimestampMicroseconds: number; - endTimestamp: string; - fetchedFromCache: boolean; - errorCount: number; - day: string; - warningCount: number; - compilationEndTimestamp: string; - compilationDuration: number; - compiledCount: number; - duration: number; - buildIdentifier: string; - name: string; - startTimestampMicroseconds: number; -}; - -export type Xcode = { - buildNumber: string; - id: string; - buildIdentifier: string; - day: string; - version: string; -}; - -export type BuildResponse = { - build: Build; - targets: Target[]; - xcode?: Xcode; // Can be undefined if XCMetrics version < v0.0.8 -}; - -export type BuildFilters = { - from: string; // ISO Date (e.g. "2021-01-01") - to: string; // ISO Date (e.g. "2021-01-02") - buildStatus?: BuildStatus; - project?: string; -}; - -export interface XcmetricsApi { - getBuild(id: string): Promise; - getBuilds(limit?: number): Promise; - getFilteredBuilds( - filters: BuildFilters, - page?: number, - perPage?: number, - ): Promise>; - getBuildErrors(buildId: string): Promise; - getBuildCounts(days: number): Promise; - getBuildHost(buildId: string): Promise; - getBuildMetadata(buildId: string): Promise; - getBuildTimes(days: number): Promise; - getBuildStatuses(limit: number): Promise; - getBuildWarnings(buildId: string): Promise; - getProjects(): Promise; -} - -export const xcmetricsApiRef = createApiRef({ - id: 'plugin.xcmetrics.api', -}); diff --git a/plugins/xcmetrics/src/components/Accordion/Accordion.test.tsx b/plugins/xcmetrics/src/components/Accordion/Accordion.test.tsx deleted file mode 100644 index 404cf09294..0000000000 --- a/plugins/xcmetrics/src/components/Accordion/Accordion.test.tsx +++ /dev/null @@ -1,51 +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 { renderInTestApp } from '@backstage/test-utils'; -import { Accordion } from './Accordion'; -import userEvent from '@testing-library/user-event'; - -describe('Accordion', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - , - ); - - expect(rendered.getByText('heading')).toBeInTheDocument(); - expect(rendered.getByText('secondaryHeading')).toBeInTheDocument(); - }); - - it('should show content when clicked', async () => { - const rendered = await renderInTestApp( - - Content - , - ); - - expect(rendered.getByText('Content')).not.toBeVisible(); - - await userEvent.click(rendered.getByRole('button')); - expect(await rendered.findByText('Content')).toBeVisible(); - }); -}); diff --git a/plugins/xcmetrics/src/components/Accordion/Accordion.tsx b/plugins/xcmetrics/src/components/Accordion/Accordion.tsx deleted file mode 100644 index 5c418de496..0000000000 --- a/plugins/xcmetrics/src/components/Accordion/Accordion.tsx +++ /dev/null @@ -1,69 +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 { - Accordion as MuiAccordion, - AccordionSummary as MuiAccordionSummary, - Typography, - AccordionDetails, - makeStyles, - createStyles, -} from '@material-ui/core'; -import React, { PropsWithChildren } from 'react'; -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; - -const useStyles = makeStyles(theme => - createStyles({ - heading: { - flexBasis: '33.33%', - flexShrink: 0, - }, - secondaryHeading: { - color: theme.palette.text.secondary, - }, - }), -); - -interface AccordionProps { - id: string; - heading: string; - secondaryHeading?: string | number; - disabled?: boolean; - unmountOnExit?: boolean; -} - -export const Accordion = (props: PropsWithChildren) => { - const classes = useStyles(); - - return ( - - } - aria-controls={`${props.id}-content`} - id={`${props.id}-header`} - > - {props.heading} - - {props.secondaryHeading} - - - {props.children} - - ); -}; diff --git a/plugins/xcmetrics/src/components/Accordion/index.ts b/plugins/xcmetrics/src/components/Accordion/index.ts deleted file mode 100644 index 4bb2e58df9..0000000000 --- a/plugins/xcmetrics/src/components/Accordion/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { Accordion } from './Accordion'; diff --git a/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx b/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx deleted file mode 100644 index c26c101143..0000000000 --- a/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.test.tsx +++ /dev/null @@ -1,111 +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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { BuildDetails, withRequest } from './BuildDetails'; -import { xcmetricsApiRef } from '../../api'; - -jest.mock('../../api/XcmetricsClient'); -const client = require('../../api/XcmetricsClient'); - -jest.mock('../Accordion', () => ({ - Accordion: ({ heading }: { heading: string }) => ( -
accordion-{heading}
- ), -})); - -jest.mock('../BuildTimeline', () => ({ - BuildTimeline: () => 'BuildTimeline', -})); - -describe('BuildDetails', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText('accordion-Host')).toBeInTheDocument(); - expect(rendered.getByText('accordion-Errors')).toBeInTheDocument(); - expect(rendered.getByText('accordion-Warnings')).toBeInTheDocument(); - expect(rendered.getByText('accordion-Metadata')).toBeInTheDocument(); - expect(rendered.getByText('accordion-Timeline')).toBeInTheDocument(); - - expect(rendered.getByText(client.mockBuild.id)).toBeInTheDocument(); - expect( - rendered.getByText(client.mockBuild.projectName), - ).toBeInTheDocument(); - expect(rendered.getByText(client.mockBuild.schema)).toBeInTheDocument(); - }); - - it('should render if xcode data is not present', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect( - rendered.getByText('Xcode').parentNode?.childNodes[1].textContent, - ).toEqual('Unknown'); - }); -}); - -describe('BuildDetails with request', () => { - const BuildDetailsWithRequest = withRequest(BuildDetails); - - it('should fetch the build and render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText(client.mockBuild.id)).toBeInTheDocument(); - }); - - it('should show an error when API not responding', async () => { - const errorMessage = 'MockErrorMessage'; - client.XcmetricsClient.getBuild = jest - .fn() - .mockRejectedValue({ message: errorMessage }); - - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText(errorMessage)).toBeInTheDocument(); - }); - - it('should show a message when no build is returned from the API', async () => { - client.XcmetricsClient.getBuild = jest.fn().mockReturnValue(undefined); - - const rendered = await renderInTestApp( - - - , - ); - - expect( - rendered.getByText(`Could not load build ${client.mockBuild.id}`), - ).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.tsx b/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.tsx deleted file mode 100644 index 86db3be858..0000000000 --- a/plugins/xcmetrics/src/components/BuildDetails/BuildDetails.tsx +++ /dev/null @@ -1,202 +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 { createStyles, Divider, Grid, makeStyles } from '@material-ui/core'; -import React from 'react'; -import { BuildResponse, xcmetricsApiRef } from '../../api'; -import { Progress, StructuredMetadataTable } from '@backstage/core-components'; -import { Alert } from '@material-ui/lab'; -import useAsync from 'react-use/lib/useAsync'; -import { useApi } from '@backstage/core-plugin-api'; -import { formatDuration, formatStatus, formatTime } from '../../utils'; -import { StatusIcon } from '../StatusIcon'; -import { Accordion } from '../Accordion'; -import { BuildTimeline } from '../BuildTimeline'; -import { PreformattedText } from '../PreformattedText'; - -const useStyles = makeStyles(theme => - createStyles({ - divider: { - marginTop: theme.spacing(2), - marginBottom: theme.spacing(2), - }, - }), -); - -interface BuildDetailsProps { - buildData: BuildResponse; - showId?: boolean; -} - -export const BuildDetails = ({ - buildData: { build, targets, xcode }, - showId, -}: BuildDetailsProps) => { - const classes = useStyles(); - const client = useApi(xcmetricsApiRef); - const hostResult = useAsync( - async () => client.getBuildHost(build.id), - [build.id], - ); - const errorsResult = useAsync( - async () => client.getBuildErrors(build.id), - [build.id], - ); - const warningsResult = useAsync( - async () => client.getBuildWarnings(build.id), - [build.id], - ); - const metadataResult = useAsync( - async () => client.getBuildMetadata(build.id), - [build.id], - ); - - const buildDetails = { - project: build.projectName, - schema: build.schema, - category: build.category, - userId: build.userid, - 'started at': formatTime(build.startTimestamp), - 'ended at': formatTime(build.endTimestamp), - duration: formatDuration(build.duration), - status: ( - <> - - {formatStatus(build.buildStatus)} - - ), - xcode: xcode ? `${xcode.version} (${xcode.buildNumber})` : 'Unknown', - CI: build.isCi, - }; - - return ( - - - - - - - {hostResult.loading && } - {!hostResult.loading && hostResult.value && ( - - )} - - - -
- {errorsResult.loading && } - {!errorsResult.loading && - errorsResult.value?.map((error, idx) => ( -
- - {idx !== errorsResult.value.length - 1 && ( - - )} -
- ))} -
-
- - -
- {warningsResult.loading && } - {!warningsResult.loading && - warningsResult.value?.map((warning, idx) => ( -
- - {idx !== warningsResult.value.length - 1 && ( - - )} -
- ))} -
-
- - - {metadataResult.loading && } - {!metadataResult.loading && metadataResult.value && ( - - )} - - - - - -
-
- ); -}; - -type WithRequestProps = Omit & { - buildId: string; -}; - -export const withRequest = - (Component: typeof BuildDetails) => - ({ buildId, ...props }: WithRequestProps) => { - const client = useApi(xcmetricsApiRef); - const { - value: buildResponse, - loading, - error, - } = useAsync(async () => client.getBuild(buildId), []); - - if (loading) { - return ; - } - - if (error) { - return {error.message}; - } - - if (!buildResponse) { - return Could not load build {buildId}; - } - - return ; - }; diff --git a/plugins/xcmetrics/src/components/BuildDetails/index.ts b/plugins/xcmetrics/src/components/BuildDetails/index.ts deleted file mode 100644 index c2511b248e..0000000000 --- a/plugins/xcmetrics/src/components/BuildDetails/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { BuildDetails, withRequest } from './BuildDetails'; diff --git a/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx b/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx deleted file mode 100644 index ee22647b2b..0000000000 --- a/plugins/xcmetrics/src/components/BuildList/BuildList.test.tsx +++ /dev/null @@ -1,78 +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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { BuildList } from './BuildList'; -import { xcmetricsApiRef } from '../../api'; -import userEvent from '@testing-library/user-event'; - -jest.mock('../../api/XcmetricsClient'); -const client = require('../../api/XcmetricsClient'); - -jest.mock('../BuildListFilter', () => ({ - BuildListFilter: () => 'BuildListFilter', -})); - -jest.mock('../BuildDetails', () => ({ - withRequest: (component: any) => component, - BuildDetails: () => 'BuildDetails', -})); - -describe('BuildList', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText('Builds')).toBeInTheDocument(); - expect( - rendered.getByText(client.mockBuild.projectName), - ).toBeInTheDocument(); - }); - - it('should show build details', async () => { - const rendered = await renderInTestApp( - - - , - ); - - await userEvent.click( - ( - await rendered.findAllByLabelText('Detail panel visiblity toggle') - )[0], - ); - expect(await rendered.findByText('BuildDetails')).toBeInTheDocument(); - }); - - it('should show errors', async () => { - const message = 'error'; - client.XcmetricsClient.getFilteredBuilds = jest - .fn() - .mockRejectedValue({ message }); - - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText(message)).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/BuildList/BuildList.tsx b/plugins/xcmetrics/src/components/BuildList/BuildList.tsx deleted file mode 100644 index 85eee6009d..0000000000 --- a/plugins/xcmetrics/src/components/BuildList/BuildList.tsx +++ /dev/null @@ -1,94 +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, { useRef, useState } from 'react'; -import { Table } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { BuildFilters, xcmetricsApiRef } from '../../api'; -import { createStyles, Grid, makeStyles } from '@material-ui/core'; -import { BuildListFilter as Filters } from '../BuildListFilter'; -import { DateTime } from 'luxon'; -import { buildPageColumns } from '../BuildTableColumns'; -import { BuildDetails, withRequest } from '../BuildDetails'; - -const useStyles = makeStyles(theme => - createStyles({ - detailPanel: { - padding: theme.spacing(2), - backgroundColor: theme.palette.background.paper, - }, - }), -); - -export const BuildList = () => { - const classes = useStyles(); - const client = useApi(xcmetricsApiRef); - const tableRef = useRef(); - - const initialFilters = { - from: DateTime.now().minus({ years: 1 }).toISODate()!, - to: DateTime.now().toISODate()!, - }; - - const [filters, setFilters] = useState(initialFilters); - - const handleFilterChange = (values: BuildFilters) => { - setFilters(values); - tableRef.current?.onQueryChange(); - }; - - return ( - - -
{ - return new Promise((resolve, reject) => { - if (!query) return; - client - .getFilteredBuilds( - filters, - query.page + 1, // Page is 0-indexed in Table - query.pageSize, - ) - .then(result => { - resolve({ - data: result.items, - page: result.metadata.page - 1, - totalCount: result.metadata.total, - }); - }) - .catch(reason => reject(reason)); - }); - }} - detailPanel={rowData => { - const BuildDetailsWithRequest = withRequest(BuildDetails); - return ( -
- -
- ); - }} - /> - - ); -}; diff --git a/plugins/xcmetrics/src/components/BuildList/index.ts b/plugins/xcmetrics/src/components/BuildList/index.ts deleted file mode 100644 index 12b44d01be..0000000000 --- a/plugins/xcmetrics/src/components/BuildList/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { BuildList } from './BuildList'; diff --git a/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx b/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx deleted file mode 100644 index bc81b57882..0000000000 --- a/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.test.tsx +++ /dev/null @@ -1,151 +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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import userEvent from '@testing-library/user-event'; -import { BuildListFilter } from './BuildListFilter'; -import { BuildFilters, xcmetricsApiRef } from '../../api'; -import { RenderResult, within } from '@testing-library/react'; - -jest.mock('../../api/XcmetricsClient'); -const client = require('../../api/XcmetricsClient'); - -jest.mock('../DatePicker', () => ({ - DatePicker: () => 'DatePicker', -})); - -const initialValues = { - from: '2020-07-30', - to: '2021-07-30', -}; - -const renderWithFiltersVisible = async ( - callback?: (filters: BuildFilters) => void, -) => { - const rendered = await renderInTestApp( - - - , - ); - - await userEvent.click(rendered.getByLabelText('show filters')); - return rendered; -}; - -const setStatusFilter = async (rendered: RenderResult, option: string) => { - const statusSelect = rendered.getAllByTestId('select')[0]; - await userEvent.click(within(statusSelect).getByRole('button')); - await userEvent.click((await rendered.findAllByText(option))[0]); -}; - -const setProjectFilter = async (rendered: RenderResult, option: string) => { - const statusSelect = rendered.getAllByTestId('select')[1]; - await userEvent.click(within(statusSelect).getByRole('button')); - const options = await rendered.findAllByText(option); - await userEvent.click(options[options.length - 1]); -}; - -describe('BuildListFilter', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText('Filters (0)')).toBeInTheDocument(); - }); - - it('should toggle between showing and hiding filters', async () => { - const rendered = await renderWithFiltersVisible(); - - expect((await rendered.findAllByText('DatePicker')).length).toEqual(2); - expect(await rendered.findByText('Status')).toBeInTheDocument(); - expect(await rendered.findByText('Project')).toBeInTheDocument(); - - await userEvent.click(rendered.getByLabelText('hide filters')); - expect(rendered.queryByText('DatePicker')).toBeNull(); - expect(rendered.queryByText('Status')).toBeNull(); - expect(rendered.queryByText('Project')).toBeNull(); - }); - - it('should load projects', async () => { - const callback = jest.fn(); - const rendered = await renderWithFiltersVisible(callback); - await userEvent.click((await rendered.findAllByText('All'))[1]); - - expect( - await rendered.findByText(client.mockBuild.projectName), - ).toBeInTheDocument(); - }); - - it('should call back with a status when status is selected', async () => { - const callback = jest.fn(); - const rendered = await renderWithFiltersVisible(callback); - - await setStatusFilter(rendered, 'Succeeded'); - expect(callback).toHaveBeenCalledWith({ - ...initialValues, - buildStatus: 'succeeded', - }); - - await setStatusFilter(rendered, 'All'); - expect(callback).toHaveBeenCalledWith(initialValues); - }); - - it('should call back with a project when project is selected', async () => { - const callback = jest.fn(); - const rendered = await renderWithFiltersVisible(callback); - - await setProjectFilter(rendered, client.mockBuild.projectName); - expect(callback).toHaveBeenCalledWith({ - ...initialValues, - project: client.mockBuild.projectName, - }); - - await setProjectFilter(rendered, 'All'); - expect(callback).toHaveBeenCalledWith(initialValues); - }); - - it('should display a count of active (changed) filters', async () => { - const rendered = await renderWithFiltersVisible(); - - await setStatusFilter(rendered, 'Failed'); - await setProjectFilter(rendered, client.mockBuild.projectName); - - expect(await rendered.findByText('Filters (2)')).toBeInTheDocument(); - }); - - it('should clear all filters', async () => { - const callback = jest.fn(); - const rendered = await renderWithFiltersVisible(callback); - - await setStatusFilter(rendered, 'Failed'); - await setProjectFilter(rendered, client.mockBuild.projectName); - - callback.mockClear(); - await userEvent.click(await rendered.findByText('Clear all')); - - expect(callback).toHaveBeenCalledWith(initialValues); - expect(await rendered.findByText('Filters (0)')).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.tsx b/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.tsx deleted file mode 100644 index ce2a2f4c05..0000000000 --- a/plugins/xcmetrics/src/components/BuildListFilter/BuildListFilter.tsx +++ /dev/null @@ -1,157 +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, { useEffect, useState } from 'react'; -import { makeStyles, IconButton, Grid, Button } from '@material-ui/core'; -import FilterList from '@material-ui/icons/FilterList'; -import { InfoCard, Select } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { BuildFilters, BuildStatus, xcmetricsApiRef } from '../../api'; -import { DatePicker } from '../DatePicker'; - -const toSelectItems = (strings: string[]) => { - return strings.map(str => ({ label: str, value: str })); -}; - -const useStyles = makeStyles(theme => ({ - filtersContent: { - padding: theme.spacing(2, 2, 2, 2.5), - }, -})); - -type FilterOption = T | 'all'; - -interface FiltersProps { - initialValues: BuildFilters; - onFilterChange: (filters: BuildFilters) => void; -} - -export const BuildListFilter = ({ - onFilterChange, - initialValues, -}: FiltersProps) => { - const client = useApi(xcmetricsApiRef); - const classes = useStyles(); - const [open, setOpen] = useState(false); - const [values, setValues] = useState(initialValues); - - useEffect(() => onFilterChange(values), [onFilterChange, values]); - - const numFilters = Object.keys(values).reduce((sum, key) => { - const filtersKey = key as keyof BuildFilters; - return sum + Number(values[filtersKey] !== initialValues[filtersKey]); - }, 0); - - const title = ( - <> - setOpen(!open)} - aria-label={`${open ? 'hide' : 'show'} filters`} - > - - - Filters ({numFilters}) - {!!numFilters && ( - - )} - - ); - - const statusItems: { label: string; value: FilterOption }[] = [ - { label: 'All', value: 'all' }, - { label: 'Succeeded', value: 'succeeded' }, - { label: 'Failed', value: 'failed' }, - { label: 'Stopped', value: 'stopped' }, - ]; - - const { value: projects, loading } = useAsync(async () => { - return client.getProjects(); - }, []); - - const content = ( - - - setValues({ ...values, from: date })} - /> - - - setValues({ ...values, to: date })} - /> - - - undefined} - /> - ) : ( -
- Latest Builds - - - } - /> - - - - - - - - - ); -}; diff --git a/plugins/xcmetrics/src/components/Overview/index.ts b/plugins/xcmetrics/src/components/Overview/index.ts deleted file mode 100644 index 77685905e9..0000000000 --- a/plugins/xcmetrics/src/components/Overview/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { Overview } from './Overview'; diff --git a/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx b/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx deleted file mode 100644 index 1aa5fd4060..0000000000 --- a/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.test.tsx +++ /dev/null @@ -1,81 +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 { OverviewTrends } from './OverviewTrends'; -import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { xcmetricsApiRef } from '../../api'; -import userEvent from '@testing-library/user-event'; - -jest.mock('../../api/XcmetricsClient'); -const client = require('../../api/XcmetricsClient'); - -describe('OverviewTrends', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - expect(rendered.getByText('Trends for')).toBeInTheDocument(); - expect(rendered.getAllByText('Build Count').length).toEqual(3); - expect(rendered.getByText('Avg. Build Time (P50)')).toBeInTheDocument(); - }); - - it('should render empty state', async () => { - const api = client.XcmetricsClient; - api.getBuildCounts = jest.fn().mockResolvedValue([]); - - const rendered = await renderInTestApp( - - - , - ); - expect(rendered.getByText('--')).toBeInTheDocument(); - }); - - it('should change number of days when select is changed', async () => { - const rendered = await renderInTestApp( - - - , - ); - - await userEvent.click(rendered.getByText('14 days')); - await userEvent.click(await rendered.findByText('30 days')); - expect(await rendered.findByText('30 days')).toBeInTheDocument(); - }); - - it('should show errors when API not responding', async () => { - const api = client.XcmetricsClient; - const buildCountError = 'MockBuildCountErrorMessage'; - const buildTimesError = 'MockBuildTimesErrorMessage'; - - api.getBuildCounts = jest - .fn() - .mockRejectedValue({ message: buildCountError }); - api.getBuildTimes = jest - .fn() - .mockRejectedValue({ message: buildTimesError }); - - const rendered = await renderInTestApp( - - - , - ); - expect(rendered.getByText(buildCountError)).toBeInTheDocument(); - expect(rendered.getByText(buildTimesError)).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.tsx b/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.tsx deleted file mode 100644 index e6a1601e37..0000000000 --- a/plugins/xcmetrics/src/components/OverviewTrends/OverviewTrends.tsx +++ /dev/null @@ -1,150 +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 { Grid, makeStyles, useTheme } from '@material-ui/core'; -import React, { useState } from 'react'; -import { Progress, Select } from '@backstage/core-components'; -import { Trend } from '../Trend'; -import { Alert, AlertTitle } from '@material-ui/lab'; -import { xcmetricsApiRef } from '../../api'; -import useAsync from 'react-use/lib/useAsync'; -import { useApi } from '@backstage/core-plugin-api'; -import { DataValueGridItem } from '../DataValue'; -import { - formatDuration, - formatPercentage, - getAverageDuration, - getErrorRatios, - getValues, - sumField, -} from '../../utils'; - -const useStyles = makeStyles({ - spacingTop: { - marginTop: 8, - }, - spacingVertical: { - marginTop: 8, - marginBottom: 8, - }, -}); - -const DAYS_SELECT_ITEMS = [ - { label: '7 days', value: 7 }, - { label: '14 days', value: 14 }, - { label: '30 days', value: 30 }, - { label: '60 days', value: 60 }, -]; - -export const OverviewTrends = () => { - const [days, setDays] = useState(14); - const theme = useTheme(); - const classes = useStyles(); - const client = useApi(xcmetricsApiRef); - const buildCountsResult = useAsync( - async () => client.getBuildCounts(days), - [days], - ); - const buildTimesResult = useAsync( - async () => client.getBuildTimes(days), - [days], - ); - - if (buildCountsResult.loading && buildTimesResult.loading) { - return ; - } - - const sumBuilds = sumField(b => b.builds, buildCountsResult.value); - const sumErrors = sumField(b => b.errors, buildCountsResult.value); - const errorRate = sumBuilds && sumErrors ? sumErrors / sumBuilds : undefined; - - const averageBuildDurationP50 = getAverageDuration( - buildTimesResult.value, - b => b.durationP50, - ); - const averageBuildDurationP95 = getAverageDuration( - buildTimesResult.value, - b => b.durationP95, - ); - const totalBuildTime = sumField(t => t.totalDuration, buildTimesResult.value); - - return ( - <> -
- - - - - - - - - - - - - - -
Started{new Date(value.build.startTimestamp).toLocaleString()}
Duration{formatDuration(value.build.duration)}
Status{formatStatus(value.build.buildStatus)}
- ); -}; - -interface StatusCellProps { - buildStatus?: BuildStatusResult; - size: number; - spacing: number; -} - -type StatusStyle = { - [key in BuildStatus]: any; -}; - -const useStyles = makeStyles(theme => ({ - root: { - width: ({ size }) => size, - height: ({ size }) => size, - marginRight: ({ spacing }) => spacing, - marginBottom: ({ spacing }) => spacing, - backgroundColor: theme.palette.grey[600], - '&:hover': { - transform: 'scale(1.2)', - }, - }, - ...({ - succeeded: { - backgroundColor: - theme.palette.type === 'light' - ? theme.palette.success.light - : theme.palette.success.main, - }, - } as StatusStyle), // Make sure that key matches a status - ...({ - failed: { - backgroundColor: theme.palette.error[theme.palette.type], - }, - } as StatusStyle), - ...({ - stopped: { - backgroundColor: theme.palette.warning[theme.palette.type], - }, - } as StatusStyle), -})); - -export const StatusCell = (props: StatusCellProps) => { - const classes = useStyles(props); - const { buildStatus } = props; - - if (!buildStatus) { - return
; - } - - return ( - } - enterNextDelay={500} - arrow - > -
- - ); -}; diff --git a/plugins/xcmetrics/src/components/StatusCell/index.ts b/plugins/xcmetrics/src/components/StatusCell/index.ts deleted file mode 100644 index 60008aeacf..0000000000 --- a/plugins/xcmetrics/src/components/StatusCell/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { StatusCell } from './StatusCell'; diff --git a/plugins/xcmetrics/src/components/StatusIcon/StatusIcon.test.tsx b/plugins/xcmetrics/src/components/StatusIcon/StatusIcon.test.tsx deleted file mode 100644 index 0801a34b48..0000000000 --- a/plugins/xcmetrics/src/components/StatusIcon/StatusIcon.test.tsx +++ /dev/null @@ -1,42 +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 { renderInTestApp } from '@backstage/test-utils'; -import { StatusIcon } from './StatusIcon'; -import { BuildStatus } from '../../api'; - -describe('StatusIcon', () => { - it('should render', async () => { - let rendered = await renderInTestApp( - , - ); - expect(rendered.getByLabelText('Status ok')).toBeInTheDocument(); - - rendered = await renderInTestApp(); - expect(rendered.getByLabelText('Status error')).toBeInTheDocument(); - - rendered = await renderInTestApp(); - expect(rendered.getByLabelText('Status warning')).toBeInTheDocument(); - }); - - it('should render invalid statuses', async () => { - const rendered = await renderInTestApp( - , - ); - expect(rendered.getByLabelText('Status aborted')).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/StatusIcon/StatusIcon.tsx b/plugins/xcmetrics/src/components/StatusIcon/StatusIcon.tsx deleted file mode 100644 index f28b5e4fe4..0000000000 --- a/plugins/xcmetrics/src/components/StatusIcon/StatusIcon.tsx +++ /dev/null @@ -1,36 +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 { - StatusAborted, - StatusError, - StatusOK, - StatusWarning, -} from '@backstage/core-components'; -import { BuildStatus } from '../../api'; - -const STATUS_ICONS: { [key in BuildStatus]: JSX.Element } = { - succeeded: , - failed: , - stopped: , -}; - -interface StatusIconProps { - buildStatus: BuildStatus; -} - -export const StatusIcon = ({ buildStatus }: StatusIconProps) => - STATUS_ICONS[buildStatus] ?? ; diff --git a/plugins/xcmetrics/src/components/StatusIcon/index.ts b/plugins/xcmetrics/src/components/StatusIcon/index.ts deleted file mode 100644 index 597caaca89..0000000000 --- a/plugins/xcmetrics/src/components/StatusIcon/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { StatusIcon } from './StatusIcon'; diff --git a/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx b/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx deleted file mode 100644 index f18d322b43..0000000000 --- a/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.test.tsx +++ /dev/null @@ -1,35 +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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { StatusMatrix } from './StatusMatrix'; -import { xcmetricsApiRef } from '../../api'; - -jest.mock('../../api/XcmetricsClient'); -const client = require('../../api/XcmetricsClient'); - -describe('StatusMatrix', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - const cell = rendered.getByTestId(client.mockBuild.id); - expect(cell).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.tsx b/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.tsx deleted file mode 100644 index 4c5af54017..0000000000 --- a/plugins/xcmetrics/src/components/StatusMatrix/StatusMatrix.tsx +++ /dev/null @@ -1,89 +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 { makeStyles } from '@material-ui/core'; -import { xcmetricsApiRef } from '../../api'; -import useAsync from 'react-use/lib/useAsync'; -import useMeasure from 'react-use/lib/useMeasure'; -import { cn } from '../../utils'; -import { useApi } from '@backstage/core-plugin-api'; -import { Alert } from '@material-ui/lab'; -import { StatusCell } from '../StatusCell'; - -const CELL_SIZE = 12; -const CELL_MARGIN = 4; -const MAX_ROWS = 4; - -const useStyles = makeStyles(theme => ({ - root: { - marginTop: 8, - display: 'flex', - flexWrap: 'wrap', - width: '100%', - }, - loading: { - animation: `$loadingOpacity 900ms ${theme.transitions.easing.easeInOut}`, - animationIterationCount: 'infinite', - }, - '@keyframes loadingOpacity': { - '0%': { opacity: 0.3 }, - '100%': { opacity: 0.8 }, - }, -})); - -export const StatusMatrix = () => { - const classes = useStyles(); - const [measureRef, { width: rootWidth }] = useMeasure(); - const client = useApi(xcmetricsApiRef); - const { - value: builds, - loading, - error, - } = useAsync(async () => client.getBuildStatuses(300), []); - - if (error) { - return {error.message}; - } - - const cols = Math.trunc(rootWidth / (CELL_SIZE + CELL_MARGIN)) || 1; - - return ( -
- {loading && - [...new Array(cols * MAX_ROWS)].map((_, index) => { - return ( - - ); - })} - - {builds && - builds - .slice(0, cols * MAX_ROWS) - .map((buildStatus, index) => ( - - ))} -
- ); -}; diff --git a/plugins/xcmetrics/src/components/StatusMatrix/index.ts b/plugins/xcmetrics/src/components/StatusMatrix/index.ts deleted file mode 100644 index f112dcc26c..0000000000 --- a/plugins/xcmetrics/src/components/StatusMatrix/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { StatusMatrix } from './StatusMatrix'; diff --git a/plugins/xcmetrics/src/components/Trend/Trend.test.tsx b/plugins/xcmetrics/src/components/Trend/Trend.test.tsx deleted file mode 100644 index 07085150a5..0000000000 --- a/plugins/xcmetrics/src/components/Trend/Trend.test.tsx +++ /dev/null @@ -1,37 +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 { Trend } from './Trend'; -import { renderInTestApp } from '@backstage/test-utils'; - -describe('Trend', () => { - it('should render', async () => { - const data = [1, 2, 3, 4]; - const title = 'testTitle'; - const rendered = await renderInTestApp( - , - ); - expect(await rendered.findAllByText('testTitle')).toBeTruthy(); - }); - - it('should render empty state', async () => { - const title = 'testTitle'; - const rendered = await renderInTestApp( - , - ); - expect(await rendered.findAllByText('testTitle')).toBeTruthy(); - }); -}); diff --git a/plugins/xcmetrics/src/components/Trend/Trend.tsx b/plugins/xcmetrics/src/components/Trend/Trend.tsx deleted file mode 100644 index 575872e813..0000000000 --- a/plugins/xcmetrics/src/components/Trend/Trend.tsx +++ /dev/null @@ -1,41 +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 { TrendLine } from '@backstage/core-components'; -import { Typography } from '@material-ui/core'; - -interface TrendProps { - data?: number[]; - title: string; - color: string; -} - -export const Trend = ({ data, title, color }: TrendProps) => { - const emptyData = [0, 0]; - const max = Math.max(...(data ?? emptyData)); - - return ( - <> - {title} - - - ); -}; diff --git a/plugins/xcmetrics/src/components/Trend/index.ts b/plugins/xcmetrics/src/components/Trend/index.ts deleted file mode 100644 index 5e32e2fe3c..0000000000 --- a/plugins/xcmetrics/src/components/Trend/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { Trend } from './Trend'; diff --git a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx b/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx deleted file mode 100644 index b4beeefe4e..0000000000 --- a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.test.tsx +++ /dev/null @@ -1,57 +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 { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; -import { XcmetricsLayout } from './XcmetricsLayout'; -import { xcmetricsApiRef } from '../../api'; -import userEvent from '@testing-library/user-event'; - -jest.mock('../../api/XcmetricsClient'); -const client = require('../../api/XcmetricsClient'); - -jest.mock('../Overview', () => ({ - Overview: () => 'OverviewComponent', -})); - -jest.mock('../BuildList', () => ({ - BuildList: () => 'BuildList', -})); - -describe('XcmetricsLayout', () => { - it('should render', async () => { - const rendered = await renderInTestApp( - - - , - ); - - expect(rendered.getByText('Overview')).toBeInTheDocument(); - expect(rendered.getByText('Builds')).toBeInTheDocument(); - - expect(rendered.getByText('OverviewComponent')).toBeInTheDocument(); - }); - - it('should show a list of builds when the Builds tab is selected', async () => { - const rendered = await renderInTestApp( - - - , - ); - - await userEvent.click(rendered.getByText('Builds')); - expect(await rendered.findByText('BuildList')).toBeInTheDocument(); - }); -}); diff --git a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx b/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx deleted file mode 100644 index b2c6ca6ec8..0000000000 --- a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx +++ /dev/null @@ -1,61 +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, { ReactChild } from 'react'; -import { - Content, - Header, - HeaderLabel, - Page, - TabbedLayout, -} from '@backstage/core-components'; -import { Overview } from '../Overview'; -import { buildsRouteRef } from '../../routes'; -import { BuildList } from '../BuildList'; - -export interface TabConfig { - path: string; - title: string; - component: ReactChild; -} - -const TABS: TabConfig[] = [ - { - path: '/', - title: 'Overview', - component: , - }, - { - path: buildsRouteRef.path, - title: 'Builds', - component: , - }, -]; - -export const XcmetricsLayout = () => ( - -
- - -
- - {TABS.map(tab => ( - - {tab.component} - - ))} - -
-); diff --git a/plugins/xcmetrics/src/components/XcmetricsLayout/index.ts b/plugins/xcmetrics/src/components/XcmetricsLayout/index.ts deleted file mode 100644 index aa7cd4b8dc..0000000000 --- a/plugins/xcmetrics/src/components/XcmetricsLayout/index.ts +++ /dev/null @@ -1,16 +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. - */ -export { XcmetricsLayout } from './XcmetricsLayout'; diff --git a/plugins/xcmetrics/src/index.ts b/plugins/xcmetrics/src/index.ts deleted file mode 100644 index fc0bb0e55a..0000000000 --- a/plugins/xcmetrics/src/index.ts +++ /dev/null @@ -1,23 +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. - */ - -/** - * A Backstage plugin that shows XCode build metrics for your components - * - * @packageDocumentation - */ - -export { xcmetricsPlugin, XcmetricsPage } from './plugin'; diff --git a/plugins/xcmetrics/src/plugin.test.ts b/plugins/xcmetrics/src/plugin.test.ts deleted file mode 100644 index a390e8aeb7..0000000000 --- a/plugins/xcmetrics/src/plugin.test.ts +++ /dev/null @@ -1,23 +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 { XcmetricsPage, xcmetricsPlugin } from './plugin'; - -describe('xcmetrics', () => { - it('should export plugin', () => { - expect(xcmetricsPlugin).toBeDefined(); - expect(XcmetricsPage).toBeDefined(); - }); -}); diff --git a/plugins/xcmetrics/src/plugin.ts b/plugins/xcmetrics/src/plugin.ts deleted file mode 100644 index ffa72d1ff3..0000000000 --- a/plugins/xcmetrics/src/plugin.ts +++ /dev/null @@ -1,52 +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 { - createApiFactory, - createPlugin, - createRoutableExtension, - discoveryApiRef, -} from '@backstage/core-plugin-api'; -import { xcmetricsApiRef, XcmetricsClient } from './api'; -import { rootRouteRef } from './routes'; - -/** @public */ -export const xcmetricsPlugin = createPlugin({ - id: 'xcmetrics', - routes: { - root: rootRouteRef, - }, - apis: [ - createApiFactory({ - api: xcmetricsApiRef, - deps: { - discoveryApi: discoveryApiRef, - }, - factory({ discoveryApi }) { - return new XcmetricsClient({ discoveryApi }); - }, - }), - ], -}); - -/** @public */ -export const XcmetricsPage = xcmetricsPlugin.provide( - createRoutableExtension({ - name: 'XcmetricsPage', - component: () => - import('./components/XcmetricsLayout').then(m => m.XcmetricsLayout), - mountPoint: rootRouteRef, - }), -); diff --git a/plugins/xcmetrics/src/routes.ts b/plugins/xcmetrics/src/routes.ts deleted file mode 100644 index 81934c860f..0000000000 --- a/plugins/xcmetrics/src/routes.ts +++ /dev/null @@ -1,26 +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 { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; - -export const rootRouteRef = createRouteRef({ - id: 'xcmetrics', -}); - -export const buildsRouteRef = createSubRouteRef({ - id: 'xcmetrics-builds', - parent: rootRouteRef, - path: '/builds', -}); diff --git a/plugins/xcmetrics/src/setupTests.ts b/plugins/xcmetrics/src/setupTests.ts deleted file mode 100644 index 7435872609..0000000000 --- a/plugins/xcmetrics/src/setupTests.ts +++ /dev/null @@ -1,16 +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 '@testing-library/jest-dom'; diff --git a/plugins/xcmetrics/src/utils/array.ts b/plugins/xcmetrics/src/utils/array.ts deleted file mode 100644 index 9e3e2d1d4d..0000000000 --- a/plugins/xcmetrics/src/utils/array.ts +++ /dev/null @@ -1,33 +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. - */ - -export const sumField = ( - field: (element: T) => number, - arr?: T[], -) => { - return arr?.reduce((sum, current) => sum + field(current), 0); -}; - -export const getValues = ( - field: (element: T) => number, - arr?: T[], -) => { - if (!arr?.length) { - return undefined; - } - - return arr.map(element => field(element)); -}; diff --git a/plugins/xcmetrics/src/utils/buildData.ts b/plugins/xcmetrics/src/utils/buildData.ts deleted file mode 100644 index bbfcbcbf57..0000000000 --- a/plugins/xcmetrics/src/utils/buildData.ts +++ /dev/null @@ -1,42 +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 { formatDuration } from './format'; -import { BuildCount, BuildTime } from '../api'; - -export const getErrorRatios = (buildCounts?: BuildCount[]) => { - if (!buildCounts?.length) { - return undefined; - } - - return buildCounts.map(counts => - counts.builds === 0 ? 0 : counts.errors / counts.builds, - ); -}; - -export const getAverageDuration = ( - buildTimes: BuildTime[] | undefined, - field: (b: BuildTime) => number, -) => { - if (!buildTimes?.length) { - return undefined; - } - - return formatDuration( - buildTimes.reduce((sum, current) => sum + field(current), 0) / - buildTimes.length, - ); -}; diff --git a/plugins/xcmetrics/src/utils/classnames.ts b/plugins/xcmetrics/src/utils/classnames.ts deleted file mode 100644 index 48b7d3b438..0000000000 --- a/plugins/xcmetrics/src/utils/classnames.ts +++ /dev/null @@ -1,22 +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. - */ - -type ClassName = string | false | undefined | null; - -export const classNames = (...args: ClassName[]) => - args.filter(c => !!c).join(' '); - -export const cn = classNames; diff --git a/plugins/xcmetrics/src/utils/format.ts b/plugins/xcmetrics/src/utils/format.ts deleted file mode 100644 index b89cf97e42..0000000000 --- a/plugins/xcmetrics/src/utils/format.ts +++ /dev/null @@ -1,52 +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 { DateTime, Duration } from 'luxon'; -import { BuildStatus } from '../api'; -import upperFirst from 'lodash/upperFirst'; - -export const formatDuration = (seconds: number) => { - const duration = Duration.fromObject({ - seconds: seconds, - }).shiftTo('hours', 'minutes', 'seconds', 'milliseconds'); - - if (duration.hours + duration.minutes + duration.seconds === 0) { - return `${Math.round(duration.milliseconds)} ms`; - } - - const h = duration.hours ? `${duration.hours} h` : ''; - const m = duration.minutes ? `${duration.minutes} m` : ''; - const s = duration.hours < 12 ? `${duration.seconds ?? 0} s` : ''; - - return `${h} ${m} ${s}`; -}; - -export const formatSecondsInterval = ([start, end]: [number, number]) => { - return `${Math.round(start * 100) / 100} s - ${ - Math.round(end * 100) / 100 - } s`; -}; - -export const formatTime = (timestamp: string) => { - return DateTime.fromISO(timestamp).toLocaleString( - DateTime.DATETIME_SHORT_WITH_SECONDS, - ); -}; - -export const formatPercentage = (number: number) => { - return `${Math.round(number * 100)} %`; -}; - -export const formatStatus = (status: BuildStatus) => upperFirst(status); diff --git a/plugins/xcmetrics/src/utils/index.ts b/plugins/xcmetrics/src/utils/index.ts deleted file mode 100644 index f487041e25..0000000000 --- a/plugins/xcmetrics/src/utils/index.ts +++ /dev/null @@ -1,19 +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. - */ -export * from './array'; -export * from './buildData'; -export * from './format'; -export * from './classnames'; diff --git a/plugins/xcmetrics/src/utils/utils.test.ts b/plugins/xcmetrics/src/utils/utils.test.ts deleted file mode 100644 index a6a324e533..0000000000 --- a/plugins/xcmetrics/src/utils/utils.test.ts +++ /dev/null @@ -1,88 +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 { classNames, getValues, sumField } from './'; -import { getAverageDuration, getErrorRatios } from './buildData'; - -describe('utils', () => { - describe('classNames', () => { - it('should concatinate strings', () => { - expect(classNames('class1', 'class2', 'class3')).toEqual( - 'class1 class2 class3', - ); - }); - - it('should not include values null, undefined or empty strings', () => { - expect(classNames('class1', undefined, null, '')).toEqual('class1'); - }); - - it('should handle strings with boolean expressions', () => { - expect(classNames(true && 'class1', false && 'class2', false)).toEqual( - 'class1', - ); - }); - }); - - describe('sumFields', () => { - it('should sum the given field', () => { - expect(sumField(e => e.a, [{ a: 1 }, { a: 1 }, { a: 1, b: 10 }])).toEqual( - 3, - ); - expect(sumField(e => (e as any).field)).toBeUndefined(); - }); - }); - - describe('getValues', () => { - it('should return the values of the specified field', () => { - expect(getValues(e => e.a, [{ a: 1 }, { a: 2, b: 10 }])).toEqual([1, 2]); - expect(getValues(e => (e as any).field)).toBeUndefined(); - expect(getValues(e => e.field, [] as { field: any }[])).toBeUndefined(); - }); - }); - - describe('getErrorRatios', () => { - it('should return the ratio between errors and builds', () => { - expect( - getErrorRatios([{ day: '2021-01-01', errors: 10, builds: 1 }]), - ).toEqual([10]); - expect( - getErrorRatios([{ day: '2021-01-01', errors: 0, builds: 0 }]), - ).toEqual([0]); - expect(getErrorRatios()).toBeUndefined(); - }); - }); - - describe('getAverageDuration', () => { - it('should return the average duration', () => { - const data = [ - { - day: '2021-01-01', - durationP50: 3.0, - durationP95: 0, - totalDuration: 0, - }, - { - day: '2021-01-01', - durationP50: 1.0, - durationP95: 0, - totalDuration: 0, - }, - ]; - expect(getAverageDuration(data, e => e.durationP50)).toMatch('2 s'); - expect(getAverageDuration([], e => e.durationP50)).toBeUndefined(); - }); - }); -}); diff --git a/scripts/check-docs-quality.js b/scripts/check-docs-quality.js index 119dd6bef4..9a9336b3e9 100755 --- a/scripts/check-docs-quality.js +++ b/scripts/check-docs-quality.js @@ -32,7 +32,11 @@ const IGNORED_WHEN_LISTING = [ /^docs[/\\]reference[/\\]/, ]; -const IGNORED_WHEN_EXPLICIT = [/^.*[/\\]knip-report\.md$/]; +const IGNORED_WHEN_EXPLICIT = [ + /^ADOPTERS\.md$/, + /^OWNERS\.md$/, + /^.*[/\\]knip-report\.md$/, +]; const rootDir = resolvePath(__dirname, '..'); @@ -120,7 +124,6 @@ async function main() { const relativePaths = absolutePaths .map(path => relativePath(rootDir, path)) .filter(path => !IGNORED_WHEN_EXPLICIT.some(pattern => pattern.test(path))); - const success = await runVale( relativePaths.length === 0 ? await listFiles() : relativePaths, ); diff --git a/scripts/generate-merge-message.js b/scripts/generate-merge-message.js index f691c92c79..7592115e47 100755 --- a/scripts/generate-merge-message.js +++ b/scripts/generate-merge-message.js @@ -57,10 +57,18 @@ function getReleaseSchedule() { const firstReleaseYear = 2022; const firstReleaseMonth = 2; + // for any releases that are off schedule (i.e. v1.25.0 was released + // in the same month as v1.24.0), we need to adjust the release date + const offScheduleReleases = [25]; + return Array(100) .fill(0) .map((_, i) => { - const date = getReleaseOfMonth(firstReleaseYear, firstReleaseMonth + i); + const modifier = offScheduleReleases.filter(v => i >= v).length; + const date = getReleaseOfMonth( + firstReleaseYear, + firstReleaseMonth + i - modifier, + ); return { version: `1.${i}.0`, date }; }); } diff --git a/scripts/list-backend-feature.js b/scripts/list-backend-feature.js new file mode 100644 index 0000000000..53cff217b1 --- /dev/null +++ b/scripts/list-backend-feature.js @@ -0,0 +1,86 @@ +#!/usr/bin/env node +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const fs = require('fs-extra'); +const { getPackages } = require('@manypkg/get-packages'); +const { resolve, join } = require('path'); +const arrayToTable = require('array-to-table'); + +async function main(args) { + const rootPath = resolve(__dirname, '..'); + const { packages } = await getPackages(rootPath); + + const backendFeatureReports = []; + + for (const pkg of packages) { + pkgRole = pkg.packageJson.backstage?.role; + + if (pkgRole === 'backend-plugin' || pkgRole === 'backend-plugin-module') { + const backendFeatureReport = { + package: undefined, + role: undefined, + migrated: undefined, + alpha: undefined, + readme: undefined, + }; + backendFeatureReport.package = pkg.packageJson.name; + backendFeatureReport.role = pkgRole; + backendFeatureReport.readme = `[README](${pkg.packageJson.repository.url}/blob/master/${pkg.packageJson.repository.directory}/README.md)`; + const apiReportPath = join(pkg.dir, 'api-report.md'); + const apiReport = (await fs.readFile(apiReportPath)).toString(); + // console.log(apiReport) + if ( + apiReport.includes( + "import { BackendFeature } from '@backstage/backend-plugin-api';", + ) + ) { + backendFeatureReport.migrated = true; + backendFeatureReport.alpha = false; + } + + const apiReportAlphaPath = join(pkg.dir, 'api-report-alpha.md'); + if (fs.existsSync(apiReportAlphaPath)) { + const apiReportAlpha = ( + await fs.readFile(apiReportAlphaPath) + ).toString(); + if ( + apiReportAlpha.includes( + "import { BackendFeature } from '@backstage/backend-plugin-api';", + ) + ) { + backendFeatureReport.migrated = true; + backendFeatureReport.alpha = true; + } + } + + backendFeatureReports.push(backendFeatureReport); + } + } + + const table = args.includes('--table'); + + if (table) { + console.log(arrayToTable(backendFeatureReports)); + } else { + console.log(backendFeatureReports); + } +} + +main(process.argv.slice(2)).catch(error => { + console.error(error.stack || error); + process.exit(1); +}); diff --git a/scripts/list-no-top-level-material-ui-4-imports.js b/scripts/list-no-top-level-material-ui-4-imports.js new file mode 100644 index 0000000000..a963b0c0b2 --- /dev/null +++ b/scripts/list-no-top-level-material-ui-4-imports.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const fs = require('fs-extra'); +const { getPackages } = require('@manypkg/get-packages'); +const { resolve, join } = require('path'); + +async function main() { + const rootPath = resolve(__dirname, '..'); + const { packages } = await getPackages(rootPath); + + for (const pkg of packages) { + pkgRole = pkg.packageJson.backstage?.role; + if (pkgRole === 'frontend-plugin' || pkgRole === 'web-library') { + const depKeys = Object.keys(pkg.packageJson.dependencies); + if (depKeys.findIndex(d => d.includes('@material-ui')) !== -1) { + const eslintrcPath = join(pkg.dir, '.eslintrc.js'); + const targetEslintrc = (await fs.readFile(eslintrcPath)).toString(); + if ( + !targetEslintrc.includes( + "'@backstage/no-top-level-material-ui-4-imports': 'error'", + ) + ) { + console.log(pkg.packageJson.name); + } + } + } + } +} + +main(process.argv.slice(2)).catch(error => { + console.error(error.stack || error); + process.exit(1); +}); diff --git a/scripts/patch-release-for-pr.js b/scripts/patch-release-for-pr.js index c450743799..04bfe4284e 100755 --- a/scripts/patch-release-for-pr.js +++ b/scripts/patch-release-for-pr.js @@ -169,9 +169,11 @@ async function main(args) { body: 'This release fixes an issue where', title: `Patch release of ${prNumbers.map(nr => `#${nr}`).join(', ')}`, }); - console.log( - `https://github.com/backstage/backstage/compare/${patchBranch}...${branchName}?${params}`, - ); + + const url = `https://github.com/backstage/backstage/compare/${patchBranch}...${branchName}?${params}`; + console.log(`Opening ${url} ...`); + + await run('open', url); } main(process.argv.slice(2)).catch(error => { diff --git a/scripts/snyk-github-issue-sync.ts b/scripts/snyk-github-issue-sync.ts index ea7d42a2a4..21bb852b5f 100755 --- a/scripts/snyk-github-issue-sync.ts +++ b/scripts/snyk-github-issue-sync.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env yarn ts-node --transpile-only +#!/usr/bin/env node --require @backstage/cli/config/nodeTransform.cjs /* * Copyright 2021 The Backstage Authors * diff --git a/scripts/sort-package-json.mjs b/scripts/sort-package-json.mjs new file mode 100644 index 0000000000..e1e0745326 --- /dev/null +++ b/scripts/sort-package-json.mjs @@ -0,0 +1,40 @@ +#!/usr/bin/env node +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import sortPackage from 'sort-package-json'; +import fs from 'fs-extra'; + +const sortOrder = [ + 'name', + 'version', + 'description', + 'backstage', + 'publishConfig', + // ...and whatever is not in here, goes in the library's default order +]; + +const files = process.argv.slice(2).filter(arg => !arg.startsWith('--')); + +for (const file of files) { + const originalPackage = JSON.parse(fs.readFileSync(file).toString()); + const sortedPackage = JSON.stringify( + sortPackage(originalPackage, { sortOrder }), + null, + 2, + ); + fs.writeFileSync(file, `${sortedPackage}\n`); +} diff --git a/scripts/copyright-header.txt b/scripts/templates/copyright-header.txt similarity index 100% rename from scripts/copyright-header.txt rename to scripts/templates/copyright-header.txt diff --git a/scripts/templates/knex-migration.stub.js b/scripts/templates/knex-migration.stub.js new file mode 100644 index 0000000000..abed7526cd --- /dev/null +++ b/scripts/templates/knex-migration.stub.js @@ -0,0 +1,33 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = async function up(knex) { + // await knex.schema... +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async function down(knex) { + // await knex.schema... +}; diff --git a/scripts/verify-links.js b/scripts/verify-links.js index f685af191b..94ffc497cd 100755 --- a/scripts/verify-links.js +++ b/scripts/verify-links.js @@ -78,6 +78,9 @@ async function verifyUrl(basePath, absUrl, docPages) { } if (basePath.startsWith('.changeset/')) { + if (absUrl.match(/^https?:\/\//)) { + return undefined; + } return { url, basePath, problem: 'out-of-changeset' }; } diff --git a/scripts/verify-release.js b/scripts/verify-release.js new file mode 100755 index 0000000000..fe181eddac --- /dev/null +++ b/scripts/verify-release.js @@ -0,0 +1,75 @@ +#!/usr/bin/env node +/* eslint-disable @backstage/no-undeclared-imports */ +/* + * 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. + */ + +// This script is used to verify that the branch that we're patching is correct, and that we're not patching branches like master + +const { execFile: execFileCb } = require('child_process'); +const { resolve: resolvePath } = require('path'); +const { promises: fs } = require('fs'); +const { promisify } = require('util'); +const semver = require('semver'); + +const baseRef = process.env.GITHUB_BASE_REF || 'master'; + +const execFile = promisify(execFileCb); + +async function runPlain(cmd, ...args) { + try { + const { stdout } = await execFile(cmd, args, { shell: true }); + return stdout.trim(); + } catch (error) { + if (error.stderr) { + process.stderr.write(error.stderr); + } + if (!error.code) { + throw error; + } + throw new Error( + `Command '${[cmd, ...args].join(' ')}' failed with code ${error.code}`, + ); + } +} + +async function main() { + process.cwd(resolvePath(__dirname, '..')); + + const oldContent = await runPlain( + 'git', + 'show', + `origin/${baseRef}:package.json`, + ); + + const { version: oldVersion } = JSON.parse(oldContent); + const { version: newVersion } = JSON.parse( + await fs.readFile('package.json', 'utf8'), + ); + + if (oldVersion === newVersion) { + return; + } + + const versionDiff = semver.diff(oldVersion, newVersion); + if (baseRef === 'master' && versionDiff === 'patch') { + throw new Error('Refusing to release a patch bump on the master branch'); + } +} + +main().catch(error => { + console.error(error.stack); + process.exit(1); +}); diff --git a/storybook/.storybook/apis.js b/storybook/.storybook/apis.js index 37cc8eb605..905c5f2dc8 100644 --- a/storybook/.storybook/apis.js +++ b/storybook/.storybook/apis.js @@ -24,6 +24,9 @@ import { featureFlagsApiRef, } from '@backstage/core-plugin-api'; +import { translationApiRef } from '@backstage/core-plugin-api/alpha'; +import { MockTranslationApi } from '@backstage/test-utils/alpha'; + const configApi = new ConfigReader({}); const featureFlagsApi = new LocalStorageFeatureFlags(); const alertApi = new AlertApiForwarder(); @@ -55,6 +58,7 @@ const oktaAuthApi = OktaAuth.create({ basePath: '/auth/', oauthRequestApi, }); +const translationApi = MockTranslationApi.create(); export const apis = [ [configApiRef, configApi], @@ -67,4 +71,5 @@ export const apis = [ [githubAuthApiRef, githubAuthApi], [gitlabAuthApiRef, gitlabAuthApi], [oktaAuthApiRef, oktaAuthApi], + [translationApiRef, translationApi], ]; diff --git a/storybook/.storybook/main.js b/storybook/.storybook/main.js index 3d92237438..cb5f364a32 100644 --- a/storybook/.storybook/main.js +++ b/storybook/.storybook/main.js @@ -11,7 +11,6 @@ const BACKSTAGE_CORE_STORIES = [ 'plugins/search', 'plugins/search-react', 'plugins/home', - 'plugins/stack-overflow', 'plugins/catalog-react', ]; diff --git a/storybook/.storybook/webpack-plugin-fail-build-on-warning.js b/storybook/.storybook/webpack-plugin-fail-build-on-warning.js index 005507bf09..b94fb2d3b9 100644 --- a/storybook/.storybook/webpack-plugin-fail-build-on-warning.js +++ b/storybook/.storybook/webpack-plugin-fail-build-on-warning.js @@ -36,6 +36,7 @@ class WebpackPluginFailBuildOnWarning { 'AssetsOverSizeLimitWarning', 'EntrypointsOverSizeLimitWarning', 'NoAsyncChunksWarning', + 'ModuleDependencyWarning', // @testing-library/react added support for React 19 which throws a warning https://github.com/testing-library/react-testing-library/pull/1294/files ]); /* Entry point for the Webpack plugin. */ diff --git a/storybook/yarn.lock b/storybook/yarn.lock index e59970f4f7..14a0fc7ee9 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2842,90 +2842,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-darwin-arm64@npm:1.4.1" +"@swc/core-darwin-arm64@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-darwin-arm64@npm:1.5.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-darwin-x64@npm:1.4.1" +"@swc/core-darwin-x64@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-darwin-x64@npm:1.5.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.4.1" +"@swc/core-linux-arm-gnueabihf@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm64-gnu@npm:1.4.1" +"@swc/core-linux-arm64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm64-gnu@npm:1.5.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm64-musl@npm:1.4.1" +"@swc/core-linux-arm64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm64-musl@npm:1.5.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-x64-gnu@npm:1.4.1" +"@swc/core-linux-x64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-x64-gnu@npm:1.5.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-x64-musl@npm:1.4.1" +"@swc/core-linux-x64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-x64-musl@npm:1.5.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-arm64-msvc@npm:1.4.1" +"@swc/core-win32-arm64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-arm64-msvc@npm:1.5.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-ia32-msvc@npm:1.4.1" +"@swc/core-win32-ia32-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-ia32-msvc@npm:1.5.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-x64-msvc@npm:1.4.1" +"@swc/core-win32-x64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-x64-msvc@npm:1.5.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.4.1 - resolution: "@swc/core@npm:1.4.1" + version: 1.5.0 + resolution: "@swc/core@npm:1.5.0" dependencies: - "@swc/core-darwin-arm64": 1.4.1 - "@swc/core-darwin-x64": 1.4.1 - "@swc/core-linux-arm-gnueabihf": 1.4.1 - "@swc/core-linux-arm64-gnu": 1.4.1 - "@swc/core-linux-arm64-musl": 1.4.1 - "@swc/core-linux-x64-gnu": 1.4.1 - "@swc/core-linux-x64-musl": 1.4.1 - "@swc/core-win32-arm64-msvc": 1.4.1 - "@swc/core-win32-ia32-msvc": 1.4.1 - "@swc/core-win32-x64-msvc": 1.4.1 + "@swc/core-darwin-arm64": 1.5.0 + "@swc/core-darwin-x64": 1.5.0 + "@swc/core-linux-arm-gnueabihf": 1.5.0 + "@swc/core-linux-arm64-gnu": 1.5.0 + "@swc/core-linux-arm64-musl": 1.5.0 + "@swc/core-linux-x64-gnu": 1.5.0 + "@swc/core-linux-x64-musl": 1.5.0 + "@swc/core-win32-arm64-msvc": 1.5.0 + "@swc/core-win32-ia32-msvc": 1.5.0 + "@swc/core-win32-x64-msvc": 1.5.0 "@swc/counter": ^0.1.2 "@swc/types": ^0.1.5 peerDependencies: @@ -2954,7 +2954,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 3549b4a0ba8201be2dd39954ef8375df5d028da5688a68211dc5cbf69ff7a43533e9ffd36f629095f51555552f4df52116384ef779d5ec45c2b9de938e651d57 + checksum: 1abab0b57755020b60ebf2557629c23c65c3546e4cd80f9d02fbdf208d4169c9300a0229c088081b43a01e630c9d86d02f8c240c9fc2842eaed2a517770fcd1d languageName: node linkType: hard @@ -3250,13 +3250,13 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/ast@npm:1.11.6" +"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/ast@npm:1.12.1" dependencies: "@webassemblyjs/helper-numbers": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - checksum: 38ef1b526ca47c210f30975b06df2faf1a8170b1636ce239fc5738fc231ce28389dd61ecedd1bacfc03cbe95b16d1af848c805652080cb60982836eb4ed2c6cf + checksum: 31bcc64147236bd7b1b6d29d1f419c1f5845c785e1e42dc9e3f8ca2e05a029e9393a271b84f3a5bff2a32d35f51ff59e2181a6e5f953fe88576acd6750506202 languageName: node linkType: hard @@ -3274,10 +3274,10 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-buffer@npm:1.11.6" - checksum: b14d0573bf680d22b2522e8a341ec451fddd645d1f9c6bd9012ccb7e587a2973b86ab7b89fe91e1c79939ba96095f503af04369a3b356c8023c13a5893221644 +"@webassemblyjs/helper-buffer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.12.1" + checksum: c3ffb723024130308db608e86e2bdccd4868bbb62dffb0a9a1530606496f79c87f8565bd8e02805ce64912b71f1a70ee5fb00307258b0c082c3abf961d097eca languageName: node linkType: hard @@ -3299,15 +3299,15 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.11.6" +"@webassemblyjs/helper-wasm-section@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - checksum: b2cf751bf4552b5b9999d27bbb7692d0aca75260140195cb58ea6374d7b9c2dc69b61e10b211a0e773f66209c3ddd612137ed66097e3684d7816f854997682e9 + "@webassemblyjs/wasm-gen": 1.12.1 + checksum: c19810cdd2c90ff574139b6d8c0dda254d42d168a9e5b3d353d1bc085f1d7164ccd1b3c05592a45a939c47f7e403dc8d03572bb686642f06a3d02932f6f0bc8f languageName: node linkType: hard @@ -3336,68 +3336,68 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-edit@npm:1.11.6" +"@webassemblyjs/wasm-edit@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/helper-wasm-section": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-opt": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - "@webassemblyjs/wast-printer": 1.11.6 - checksum: 29ce75870496d6fad864d815ebb072395a8a3a04dc9c3f4e1ffdc63fc5fa58b1f34304a1117296d8240054cfdbc38aca88e71fb51483cf29ffab0a61ef27b481 + "@webassemblyjs/helper-wasm-section": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-opt": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + "@webassemblyjs/wast-printer": 1.12.1 + checksum: ae23642303f030af888d30c4ef37b08dfec7eab6851a9575a616e65d1219f880d9223913a39056dd654e49049d76e97555b285d1f7e56935047abf578cce0692 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-gen@npm:1.11.6" +"@webassemblyjs/wasm-gen@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: a645a2eecbea24833c3260a249704a7f554ef4a94c6000984728e94bb2bc9140a68dfd6fd21d5e0bbb09f6dfc98e083a45760a83ae0417b41a0196ff6d45a23a + checksum: 5787626bb7f0b033044471ddd00ce0c9fe1ee4584e8b73e232051e3a4c99ba1a102700d75337151c8b6055bae77eefa4548960c610a5e4a504e356bd872138ff languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-opt@npm:1.11.6" +"@webassemblyjs/wasm-opt@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - checksum: b4557f195487f8e97336ddf79f7bef40d788239169aac707f6eaa2fa5fe243557c2d74e550a8e57f2788e70c7ae4e7d32f7be16101afe183d597b747a3bdd528 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + checksum: 0e8fa8a0645304a1e18ff40d3db5a2e9233ebaa169b19fcc651d6fc9fe2cac0ce092ddee927318015ae735d9cd9c5d97c0cafb6a51dcd2932ac73587b62df991 languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.11.6, @webassemblyjs/wasm-parser@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-parser@npm:1.11.6" +"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-api-error": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: 8200a8d77c15621724a23fdabe58d5571415cda98a7058f542e670ea965dd75499f5e34a48675184947c66f3df23adf55df060312e6d72d57908e3f049620d8a + checksum: 176015de3551ac068cd4505d837414f258d9ade7442bd71efb1232fa26c9f6d7d4e11a5c816caeed389943f409af7ebff6899289a992d7a70343cb47009d21a8 languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wast-printer@npm:1.11.6" +"@webassemblyjs/wast-printer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wast-printer@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@xtuc/long": 4.2.2 - checksum: d2fa6a4c427325ec81463e9c809aa6572af6d47f619f3091bf4c4a6fc34f1da3df7caddaac50b8e7a457f8784c62cd58c6311b6cb69b0162ccd8d4c072f79cf8 + checksum: 2974b5dda8d769145ba0efd886ea94a601e61fb37114c14f9a9a7606afc23456799af652ac3052f284909bd42edc3665a76bc9b50f95f0794c053a8a1757b713 languageName: node linkType: hard @@ -4096,23 +4096,23 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.0": - version: 1.20.0 - resolution: "body-parser@npm:1.20.0" +"body-parser@npm:1.20.2": + version: 1.20.2 + resolution: "body-parser@npm:1.20.2" dependencies: bytes: 3.1.2 - content-type: ~1.0.4 + content-type: ~1.0.5 debug: 2.6.9 depd: 2.0.0 destroy: 1.2.0 http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.10.3 - raw-body: 2.5.1 + qs: 6.11.0 + raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 12fffdeac82fe20dddcab7074215d5156e7d02a69ae90cbe9fee1ca3efa2f28ef52097cbea76685ee0a1509c71d85abd0056a08e612c09077cad6277a644cf88 + checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 languageName: node linkType: hard @@ -4751,10 +4751,10 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4": - version: 1.0.4 - resolution: "content-type@npm:1.0.4" - checksum: 3d93585fda985d1554eca5ebd251994327608d2e200978fdbfba21c0c679914d5faf266d17027de44b34a72c7b0745b18584ecccaa7e1fdfb6a68ac7114f12e0 +"content-type@npm:~1.0.4, content-type@npm:~1.0.5": + version: 1.0.5 + resolution: "content-type@npm:1.0.5" + checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 languageName: node linkType: hard @@ -4774,10 +4774,10 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.5.0": - version: 0.5.0 - resolution: "cookie@npm:0.5.0" - checksum: 1f4bd2ca5765f8c9689a7e8954183f5332139eb72b6ff783d8947032ec1fdf43109852c178e21a953a30c0dd42257828185be01b49d1eb1a67fd054ca588a180 +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 languageName: node linkType: hard @@ -5357,13 +5357,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": - version: 5.15.0 - resolution: "enhanced-resolve@npm:5.15.0" +"enhanced-resolve@npm:^5.16.0": + version: 5.16.0 + resolution: "enhanced-resolve@npm:5.16.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 + checksum: ccfd01850ecf2aa51e8554d539973319ff7d8a539ef1e0ba3460a0ccad6223c4ef6e19165ee64161b459cd8a48df10f52af4434c60023c65fde6afa32d475f7e languageName: node linkType: hard @@ -5661,15 +5661,15 @@ __metadata: linkType: hard "express@npm:^4.17.1": - version: 4.18.1 - resolution: "express@npm:4.18.1" + version: 4.19.2 + resolution: "express@npm:4.19.2" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.0 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: ~1.0.4 - cookie: 0.5.0 + cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 @@ -5685,7 +5685,7 @@ __metadata: parseurl: ~1.3.3 path-to-regexp: 0.1.7 proxy-addr: ~2.0.7 - qs: 6.10.3 + qs: 6.11.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 send: 0.18.0 @@ -5695,7 +5695,7 @@ __metadata: type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: c3d44c92e48226ef32ec978becfedb0ecf0ca21316bfd33674b3c5d20459840584f2325726a4f17f33d9c99f769636f728982d1c5433a5b6fe6eb95b8cf0c854 + checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 languageName: node linkType: hard @@ -6128,7 +6128,7 @@ __metadata: "fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 - resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" dependencies: node-gyp: latest conditions: os=darwin @@ -6387,10 +6387,10 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": - version: 4.2.10 - resolution: "graceful-fs@npm:4.2.10" - checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 languageName: node linkType: hard @@ -6948,9 +6948,9 @@ __metadata: linkType: hard "ip@npm:^2.0.0": - version: 2.0.0 - resolution: "ip@npm:2.0.0" - checksum: cfcfac6b873b701996d71ec82a7dd27ba92450afdb421e356f44044ed688df04567344c36cbacea7d01b1c39a4c732dc012570ebe9bebfb06f27314bca625349 + version: 2.0.1 + resolution: "ip@npm:2.0.1" + checksum: d765c9fd212b8a99023a4cde6a558a054c298d640fec1020567494d257afd78ca77e37126b1a3ef0e053646ced79a816bf50621d38d5e768cdde0431fa3b0d35 languageName: node linkType: hard @@ -8283,6 +8283,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea + languageName: node + linkType: hard + "minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": version: 2.1.2 resolution: "minizlib@npm:2.1.2" @@ -9493,16 +9500,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.10.3": - version: 6.10.3 - resolution: "qs@npm:6.10.3" - dependencies: - side-channel: ^1.0.4 - checksum: 0fac5e6c7191d0295a96d0e83c851aeb015df7e990e4d3b093897d3ac6c94e555dbd0a599739c84d7fa46d7fee282d94ba76943983935cf33bba6769539b8019 - languageName: node - linkType: hard - -"qs@npm:^6.10.0": +"qs@npm:6.11.0, qs@npm:^6.10.0": version: 6.11.0 resolution: "qs@npm:6.11.0" dependencies: @@ -9541,15 +9539,15 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.1": - version: 2.5.1 - resolution: "raw-body@npm:2.5.1" +"raw-body@npm:2.5.2": + version: 2.5.2 + resolution: "raw-body@npm:2.5.2" dependencies: bytes: 3.1.2 http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 - checksum: 5362adff1575d691bb3f75998803a0ffed8c64eabeaa06e54b4ada25a0cd1b2ae7f4f5ec46565d1bec337e08b5ac90c76eaa0758de6f72a633f025d754dec29e + checksum: ba1583c8d8a48e8fbb7a873fdbb2df66ea4ff83775421bfe21ee120140949ab048200668c47d9ae3880012f6e217052690628cf679ddfbd82c9fc9358d574676 languageName: node linkType: hard @@ -10060,7 +10058,7 @@ __metadata: "resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.3.2#~builtin": version: 1.22.1 - resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b" + resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=c3c19d" dependencies: is-core-module: ^2.9.0 path-parse: ^1.0.7 @@ -10951,16 +10949,16 @@ __metadata: linkType: hard "tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.1.11 - resolution: "tar@npm:6.1.11" + version: 6.2.1 + resolution: "tar@npm:6.2.1" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 - minipass: ^3.0.0 + minipass: ^5.0.0 minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: a04c07bb9e2d8f46776517d4618f2406fb977a74d914ad98b264fc3db0fe8224da5bec11e5f8902c5b9bcb8ace22d95fbe3c7b36b8593b7dfc8391a25898f32f + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c languageName: node linkType: hard @@ -11231,11 +11229,11 @@ __metadata: "typescript@patch:typescript@~4.9.0#~builtin": version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=a1c5e5" + resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=289587" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20 + checksum: 1f8f3b6aaea19f0f67cba79057674ba580438a7db55057eb89cc06950483c5d632115c14077f6663ea76fd09fce3c190e6414bb98582ec80aa5a4eaf345d5b68 languageName: node linkType: hard @@ -11637,13 +11635,13 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:^2.2.0, watchpack@npm:^2.4.0": - version: 2.4.0 - resolution: "watchpack@npm:2.4.0" +"watchpack@npm:^2.2.0, watchpack@npm:^2.4.1": + version: 2.4.1 + resolution: "watchpack@npm:2.4.1" dependencies: glob-to-regexp: ^0.4.1 graceful-fs: ^4.1.2 - checksum: 23d4bc58634dbe13b86093e01c6a68d8096028b664ab7139d58f0c37d962d549a940e98f2f201cecdabd6f9c340338dc73ef8bf094a2249ef582f35183d1a131 + checksum: 5b0179348655dcdf19cac7cb4ff923fdc024d630650c0bf6bec8899cf47c60e19d4f810a88dba692ed0e7f684cf0fcffea86efdbf6c35d81f031e328043b7fab languageName: node linkType: hard @@ -11756,24 +11754,24 @@ __metadata: linkType: hard "webpack@npm:^5.73.0": - version: 5.90.2 - resolution: "webpack@npm:5.90.2" + version: 5.91.0 + resolution: "webpack@npm:5.91.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 - "@webassemblyjs/ast": ^1.11.5 - "@webassemblyjs/wasm-edit": ^1.11.5 - "@webassemblyjs/wasm-parser": ^1.11.5 + "@webassemblyjs/ast": ^1.12.1 + "@webassemblyjs/wasm-edit": ^1.12.1 + "@webassemblyjs/wasm-parser": ^1.12.1 acorn: ^8.7.1 acorn-import-assertions: ^1.9.0 browserslist: ^4.21.10 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.15.0 + enhanced-resolve: ^5.16.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 glob-to-regexp: ^0.4.1 - graceful-fs: ^4.2.9 + graceful-fs: ^4.2.11 json-parse-even-better-errors: ^2.3.1 loader-runner: ^4.2.0 mime-types: ^2.1.27 @@ -11781,14 +11779,14 @@ __metadata: schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.10 - watchpack: ^2.4.0 + watchpack: ^2.4.1 webpack-sources: ^3.2.3 peerDependenciesMeta: webpack-cli: optional: true bin: webpack: bin/webpack.js - checksum: 4af55f314c3610e0b17afd01960c4cf9d8d90c87a58ef7d7dc7a0a019f48e2bba4eff63b02d9da56fc61df5b04af0d66b3fa4ec82937a780d37a64db84c643fe + checksum: f1073715dbb1ed5c070affef293d800a867708bcbc5aba4d8baee87660e0cf53c55966a6f36fab078d1d6c9567cdcd0a9086bdfb607cab87ea68c6449791b9a3 languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index 3394871837..9a940a725a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -105,30 +105,6 @@ __metadata: languageName: node linkType: hard -"@apollo/explorer@npm:^3.0.0": - version: 3.6.0 - resolution: "@apollo/explorer@npm:3.6.0" - dependencies: - "@types/whatwg-mimetype": ^3.0.0 - graphql-ws: ^5.9.0 - subscriptions-transport-ws: ^0.11.0 - whatwg-mimetype: ^3.0.0 - zen-observable-ts: ^1.1.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - use-deep-compare-effect: ^1.8.1 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - use-deep-compare-effect: - optional: true - checksum: 0617cd1995cb8a63e25ee93204e09f6210a9031ca7942a7c74b9ac74677072fd6242d1479110d9a756c013589626706766380788e9b07dc63a18b494f581406c - languageName: node - linkType: hard - "@ardatan/sync-fetch@npm:^0.0.1": version: 0.0.1 resolution: "@ardatan/sync-fetch@npm:0.0.1" @@ -138,35 +114,35 @@ __metadata: languageName: node linkType: hard -"@asyncapi/avro-schema-parser@npm:^3.0.9": - version: 3.0.9 - resolution: "@asyncapi/avro-schema-parser@npm:3.0.9" +"@asyncapi/avro-schema-parser@npm:^3.0.15": + version: 3.0.15 + resolution: "@asyncapi/avro-schema-parser@npm:3.0.15" dependencies: - "@asyncapi/parser": ^3.0.2 + "@asyncapi/parser": ^3.0.7 "@types/json-schema": ^7.0.11 avsc: ^5.7.6 - checksum: db451bc9413a9caef2e45f577dbc04c0e2f94183793ab791979384e900716b2af9d77db15251128b4316b6a87bdb4be6405fb12d3712a21a6f6d3e71256a18e4 + checksum: 474189dfa61dba6bdd1a7ef4c6f88bd91458bebba0ef0f2238df917f12c2636115b6b50ee1a3e21307689e20cc4364ab02e7d87ab1915d031a9969a93fdc486d languageName: node linkType: hard -"@asyncapi/openapi-schema-parser@npm:^3.0.10": - version: 3.0.10 - resolution: "@asyncapi/openapi-schema-parser@npm:3.0.10" +"@asyncapi/openapi-schema-parser@npm:^3.0.15": + version: 3.0.15 + resolution: "@asyncapi/openapi-schema-parser@npm:3.0.15" dependencies: - "@asyncapi/parser": ^3.0.2 + "@asyncapi/parser": ^3.0.7 "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 ajv: ^8.11.0 ajv-errors: ^3.0.0 ajv-formats: ^2.1.1 - checksum: ddab8b38b86a2ca12dc9345e1a911cfd63bd537524bbb3bc804a137947381eb97e287c6383cf3575a46cadb73f60c2a826a589c54b15ef3881e5a2bb499d2f4c + checksum: 43800f303ddf3f0309befed2d085766726e49bc61208d7ce005ccae3235f3ca48c7e39b3133fc72778b4d2057a323d986552b894389d938e5349ad2e22e37626 languageName: node linkType: hard -"@asyncapi/parser@npm:^3.0.2": - version: 3.0.2 - resolution: "@asyncapi/parser@npm:3.0.2" +"@asyncapi/parser@npm:^3.0.7": + version: 3.0.7 + resolution: "@asyncapi/parser@npm:3.0.7" dependencies: - "@asyncapi/specs": ^6.2.0 + "@asyncapi/specs": ^6.5.0 "@openapi-contrib/openapi-schema-to-json-schema": ~3.2.0 "@stoplight/json": ^3.20.2 "@stoplight/json-ref-readers": ^1.2.2 @@ -185,29 +161,29 @@ __metadata: js-yaml: ^4.1.0 jsonpath-plus: ^7.2.0 node-fetch: 2.6.7 - checksum: 07c82c5fddbc97f5f53a7ab29e0e8b538d325bbd2a15c9f130b79d7f0d253af001207ea9121b7de88d672f23514bdf33d327bb322653281f0cd582ea9f15e962 + checksum: 8297f415c43c0e539cdeaaa5ef48c920f24e9af2efae8f7d14c8f1768238bce02075f7f649d29f953eeb9634e8d6692d08e831e3c2fab11bb6c8a98ccbd8f67a languageName: node linkType: hard -"@asyncapi/protobuf-schema-parser@npm:^3.0.6": - version: 3.0.6 - resolution: "@asyncapi/protobuf-schema-parser@npm:3.0.6" +"@asyncapi/protobuf-schema-parser@npm:^3.2.4": + version: 3.2.4 + resolution: "@asyncapi/protobuf-schema-parser@npm:3.2.4" dependencies: - "@asyncapi/parser": ^3.0.2 + "@asyncapi/parser": ^3.0.7 "@types/protocol-buffers-schema": ^3.4.1 - protocol-buffers-schema: ^3.6.0 - checksum: 9e185734971c10bcc5155b734939a74f3b87b4fe6173c8e4d404c723611b0257a67e4728c3999ea5d37d9ae89608026f73a9bdc4fb51bfa958eb5eece418aee3 + protobufjs: ^7.2.6 + checksum: 461caaadc3a74eb7856d2535a7f8f6ad768d9e9343e873f180ed9a8cf30cb80bb3f7d96d2ab87e6e4f408908a969740446fe78d86ad6dc25977b8b81993e0242 languageName: node linkType: hard -"@asyncapi/react-component@npm:1.2.13": - version: 1.2.13 - resolution: "@asyncapi/react-component@npm:1.2.13" +"@asyncapi/react-component@npm:1.3.1": + version: 1.3.1 + resolution: "@asyncapi/react-component@npm:1.3.1" dependencies: - "@asyncapi/avro-schema-parser": ^3.0.9 - "@asyncapi/openapi-schema-parser": ^3.0.10 - "@asyncapi/parser": ^3.0.2 - "@asyncapi/protobuf-schema-parser": ^3.0.6 + "@asyncapi/avro-schema-parser": ^3.0.15 + "@asyncapi/openapi-schema-parser": ^3.0.15 + "@asyncapi/parser": ^3.0.7 + "@asyncapi/protobuf-schema-parser": ^3.2.4 highlight.js: ^10.7.2 isomorphic-dompurify: ^0.13.0 marked: ^4.0.14 @@ -216,7 +192,7 @@ __metadata: peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 1e870caa07a3507685ab52af7e34f31c47b31464159f435f29b0be68adf1c110dc0c9196d8f20ab1d6b998500bbac821181477897636322c0c29fe2708284871 + checksum: d70992809223643e17bab39352d4fc31b188cd83f548e6ec16d9a638d448a96d1f52e4d9900c9e6a3070211ad6b9ddbb5e992e48445385dbf6cb4c5165d95dac languageName: node linkType: hard @@ -229,12 +205,12 @@ __metadata: languageName: node linkType: hard -"@asyncapi/specs@npm:^6.2.0": - version: 6.2.0 - resolution: "@asyncapi/specs@npm:6.2.0" +"@asyncapi/specs@npm:^6.5.0": + version: 6.5.0 + resolution: "@asyncapi/specs@npm:6.5.0" dependencies: "@types/json-schema": ^7.0.11 - checksum: 9fa959350a75d9d9ab886436720d59bbf1c7bff16ed657fa34cce3a006136d2d853264366c8eee5abf4761f611c305acd5d7fb17e6de92fdc573b32e08f94912 + checksum: 85c3719a9de8af1b0c5585e93be9967845a9c02fc3cc62dcce7f9ed5f31eb1bbab0b8488840da3a93da1e8e4dbb9a8e6a525b19fa6954f94c36b22971cab8788 languageName: node linkType: hard @@ -363,569 +339,617 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.515.0" +"@aws-sdk/client-codecommit@npm:^3.350.0": + version: 3.556.0 + resolution: "@aws-sdk/client-codecommit@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.515.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: e254357719b355a7c6cdd718c3896aca9971ea9479887c221841ec2c6e91f15b880f6a5d1ebfc62af223b4d02a0d4a882aa8394b436f9b544658ee87a481e1ac + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 09a7393ba36cf0eaf527041580e468b62346634768ee1ced243e5e894d6a532f96332642ddc1965c9e2078cbe4183c84bc6003a427a05e6ea781ceff5c143e0d + languageName: node + linkType: hard + +"@aws-sdk/client-cognito-identity@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.556.0" + dependencies: + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 964ee562d41df0fc3d71a739ef86846dddbfa8742df74831926dd629de0111ace69faed4869d9b7a50cd5eb8d2c1ac09da2126b7071e9d69f8ba8e8d85d24323 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/client-eks@npm:3.515.0" + version: 3.556.0 + resolution: "@aws-sdk/client-eks@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.515.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - "@smithy/util-waiter": ^2.1.1 - tslib: ^2.5.0 + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + "@smithy/util-waiter": ^2.2.0 + tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 38366b504f5cda083637801b8a89cb03fb05fca56e6266a18d4fa4772a5556a461efcb82c8ed9690d8ba4c49e2ec2bdd71c7d3f987d2e7a85506439de2199ff6 + checksum: c36a0f23d3f01ed9fcbeec286b5e919cacc2ecb0bb3e880844e9b84018d81935c4b8f3dc33a3392c808a6e001659f5ca0c99889d830491c48040b9df3d474cc8 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/client-organizations@npm:3.515.0" + version: 3.556.0 + resolution: "@aws-sdk/client-organizations@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.515.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: 4b947f1fc5ca196b007855cc5d75accb82825adfe4dea370d181b9605bfe827ddc0f6cb073d7ef7f768a523be4e393a2dc1e28a999d118bda050f354997e8f60 + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: e747d1f2f75a9985944765ac920408bffe5fc79dfb700c56b1633fec4e6f480b9568e30f72a6c80f09dcb7998480f158fa5c40646e8af4fed4a68e694d78c4f8 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/client-s3@npm:3.515.0" + version: 3.556.0 + resolution: "@aws-sdk/client-s3@npm:3.556.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.515.0 - "@aws-sdk/middleware-bucket-endpoint": 3.515.0 - "@aws-sdk/middleware-expect-continue": 3.515.0 - "@aws-sdk/middleware-flexible-checksums": 3.515.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-location-constraint": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-sdk-s3": 3.515.0 - "@aws-sdk/middleware-signing": 3.515.0 - "@aws-sdk/middleware-ssec": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/signature-v4-multi-region": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@aws-sdk/xml-builder": 3.496.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/eventstream-serde-browser": ^2.1.1 - "@smithy/eventstream-serde-config-resolver": ^2.1.1 - "@smithy/eventstream-serde-node": ^2.1.1 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-blob-browser": ^2.1.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/hash-stream-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/md5-js": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-stream": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - "@smithy/util-waiter": ^2.1.1 - fast-xml-parser: 4.2.5 - tslib: ^2.5.0 - checksum: f61f91fb45500108520357e61a018975f4e4a49df378fa16ad0fc15b59560bdfcc11c6cb7d95ad1c4b6e0607e99788662e4013d8d529af75a36dffa5c8bfe5ca + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/middleware-bucket-endpoint": 3.535.0 + "@aws-sdk/middleware-expect-continue": 3.535.0 + "@aws-sdk/middleware-flexible-checksums": 3.535.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-location-constraint": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-sdk-s3": 3.556.0 + "@aws-sdk/middleware-signing": 3.556.0 + "@aws-sdk/middleware-ssec": 3.537.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/signature-v4-multi-region": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@aws-sdk/xml-builder": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/eventstream-serde-browser": ^2.2.0 + "@smithy/eventstream-serde-config-resolver": ^2.2.0 + "@smithy/eventstream-serde-node": ^2.2.0 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-blob-browser": ^2.2.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/hash-stream-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/md5-js": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-stream": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + "@smithy/util-waiter": ^2.2.0 + tslib: ^2.6.2 + checksum: e5b04013a9270b438b196ccf60bedba14187ee059fbd3fd42a8bac927c7935226ba031c1a5312befa6e37e4ea8cd075fe28b8b524fe51b5b372bf5543dd46216 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/client-sqs@npm:3.515.0" + version: 3.556.0 + resolution: "@aws-sdk/client-sqs@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/credential-provider-node": 3.515.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-sdk-sqs": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/md5-js": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: e92bbea7c7453cee74898ffde1092437693eb19b3a623243913805229ab6b1ec7905735a2dd58476915d574beeca2675f00eb89b5de8c3f099becc68c9ade901 + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-sdk-sqs": 3.552.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/md5-js": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: fe14caaffe9115b430d7c89895b193b2415532862b6cb70918ea0790f01017ca4bbf998ed221bf7fb4285b7eb6090c156bca4c8ccf49f61f2c34f96fd57e7ed4 languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.515.0" +"@aws-sdk/client-sso-oidc@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 peerDependencies: - "@aws-sdk/credential-provider-node": ^3.515.0 - checksum: f220a9ba8542460b2aa91ad060302fb9e68bdf096ecca2ec1d6e525f4df1036b330cb85d20bac3e8399276c0d8d8d388b3f2191b58804919c68369afac0be37b + "@aws-sdk/credential-provider-node": ^3.556.0 + checksum: d932569016b811e14bd977e2e198556e3e4bf156108b098eb8850f83486cf361e23e17cc2fbae2ae7ebb1c2268f312a64c90dafb9f19e8dd6e9a817397e79552 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/client-sso@npm:3.515.0" +"@aws-sdk/client-sso@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/client-sso@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: 12287dfa469fb2c6b5bedd3cbd37f7416f8234669b5ed0ff38cb1217d746ba6a5e6ff227b091a7751d1c20489a6b8bd93bcbed8f394cb4c51b6bebb9a9f79108 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: bf0f2d449983c650e25befbee80dd48508464c1814e5b412a8f5e725e88e0764ac75a1b959df509c746b638dbbb571f51617be4c02f7b0ef8185c045255f6c52 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.515.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/client-sts@npm:3.515.0" +"@aws-sdk/client-sts@npm:3.556.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.556.0 + resolution: "@aws-sdk/client-sts@npm:3.556.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/core": 3.513.0 - "@aws-sdk/middleware-host-header": 3.515.0 - "@aws-sdk/middleware-logger": 3.515.0 - "@aws-sdk/middleware-recursion-detection": 3.515.0 - "@aws-sdk/middleware-user-agent": 3.515.0 - "@aws-sdk/region-config-resolver": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@aws-sdk/util-user-agent-browser": 3.515.0 - "@aws-sdk/util-user-agent-node": 3.515.0 - "@smithy/config-resolver": ^2.1.1 - "@smithy/core": ^1.3.2 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/hash-node": ^2.1.1 - "@smithy/invalid-dependency": ^2.1.1 - "@smithy/middleware-content-length": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-body-length-browser": ^2.1.1 - "@smithy/util-body-length-node": ^2.2.1 - "@smithy/util-defaults-mode-browser": ^2.1.1 - "@smithy/util-defaults-mode-node": ^2.2.0 - "@smithy/util-endpoints": ^1.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 + "@aws-sdk/core": 3.556.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/credential-provider-node": ^3.556.0 + checksum: 81ce40440de0c3012b6e21d7f9b748bc46982e72ffaccc763efeed34d79eee519ed9a95e2cb37b2e411460cced2897f409d90e42a5b012344358839c717fa435 + languageName: node + linkType: hard + +"@aws-sdk/core@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/core@npm:3.556.0" + dependencies: + "@smithy/core": ^1.4.2 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 fast-xml-parser: 4.2.5 - tslib: ^2.5.0 - peerDependencies: - "@aws-sdk/credential-provider-node": ^3.515.0 - checksum: 9af6a2484909e88a83c411551d55ad149c80a8f449c2e54c499769535243602a6283cd71f6a0cf975b295a321a74e90eb95f6659bba93bae3d12e2186e7545f4 + tslib: ^2.6.2 + checksum: 9b446f0939f8573289b598282194aeff81b3e8c9aa76b29d6e865fe40f38b301f041fab39d565f975ed6e8a3ba4d4b9b43444aaab7dbf2c7ea84e67d370a2695 languageName: node linkType: hard -"@aws-sdk/core@npm:3.513.0": - version: 3.513.0 - resolution: "@aws-sdk/core@npm:3.513.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.556.0" dependencies: - "@smithy/core": ^1.3.2 - "@smithy/protocol-http": ^3.1.1 - "@smithy/signature-v4": ^2.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 94a41263e5d0c754f4d6d603572704822b570d5fc5ed450c8eb461b989198b625d2c115a470b087defe2c6c45b9442527062382c9bb1ca32842332317300b2fe + "@aws-sdk/client-cognito-identity": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 4c66b780f9f8c3e5df9d5e397069e0bbd31596bfb93b5ac76baa39cb0ef7bebc848a879b940dbcdda7c40cb78beeb46e0b10fab94e71ea317e0512e49c9b6f80 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.515.0" +"@aws-sdk/credential-provider-env@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.535.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: cb8cb5fa19b3e10e0a816eddda0a56a412da6bc68eba4807698ed94ef6bf2f3de288d959ced099b399dfc29f08154c84f8c025816e94226e5fb21c605e710542 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: ec7d011051d69643efd26fe7f3767b1301c6e6bdba12640dad542b60efb2b5fe31df01f8137703d814cf857a69485cc928d0de49ab56c5d05f79815dce19bdbf languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.515.0" +"@aws-sdk/credential-provider-http@npm:3.552.0": + version: 3.552.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.552.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 3573bc3f1aa89bc8eedb9eb39c8c1d501a68aec5eb059364a1091c8bf10dfda9cfbd78ee49d3ad25ec1012f765a4464363c4cd70997e94005fd21245871a4229 + "@aws-sdk/types": 3.535.0 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-stream": ^2.2.0 + tslib: ^2.6.2 + checksum: 86be07b2a0c73b5c1140557e00b08c091303da1908ff40a29bcc69b73bf4ad175a5ad945e0d45d5c76b02bee3f15a947abb18838b2771ad71feb795a5309a446 languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.515.0" +"@aws-sdk/credential-provider-ini@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.556.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/property-provider": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/util-stream": ^2.1.1 - tslib: ^2.5.0 - checksum: d13943dc7a83c9c129dd03a8b337b7753c791441d65a894085e00146d807738b420b9127f570a32497665be4f6e1cc8eeefd7cb1b013a04789d874c8b23b829f + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/credential-provider-env": 3.535.0 + "@aws-sdk/credential-provider-process": 3.535.0 + "@aws-sdk/credential-provider-sso": 3.556.0 + "@aws-sdk/credential-provider-web-identity": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 24b7dc1349f80090455bde95856955aef824752bff8b91dbad1dea784dc03b48b9671650aa2002de8427bd1df832c33be52b5bf157ad2759ad65a6d37247e339 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.515.0" +"@aws-sdk/credential-provider-node@npm:3.556.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.556.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.556.0" dependencies: - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/credential-provider-env": 3.515.0 - "@aws-sdk/credential-provider-process": 3.515.0 - "@aws-sdk/credential-provider-sso": 3.515.0 - "@aws-sdk/credential-provider-web-identity": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/credential-provider-imds": ^2.2.1 - "@smithy/property-provider": ^2.1.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: c136d4257460be8331d7645854b7e3c91205a1eb12efd3dcbcd84501c787085292d1ccc4578c4776308d91748bde5af2c6eaa873b56aed83ab472a878a2d8883 + "@aws-sdk/credential-provider-env": 3.535.0 + "@aws-sdk/credential-provider-http": 3.552.0 + "@aws-sdk/credential-provider-ini": 3.556.0 + "@aws-sdk/credential-provider-process": 3.535.0 + "@aws-sdk/credential-provider-sso": 3.556.0 + "@aws-sdk/credential-provider-web-identity": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: c4b83c36426941caff81a25393eec101cf2d21264c29c69e5a7a940ae8af1f4b2a8f0a26f47c2294a32f381d53eed9ba2dc2cbbcd053585aa9016acb79e98ad8 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.515.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.515.0" +"@aws-sdk/credential-provider-process@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.535.0" dependencies: - "@aws-sdk/credential-provider-env": 3.515.0 - "@aws-sdk/credential-provider-http": 3.515.0 - "@aws-sdk/credential-provider-ini": 3.515.0 - "@aws-sdk/credential-provider-process": 3.515.0 - "@aws-sdk/credential-provider-sso": 3.515.0 - "@aws-sdk/credential-provider-web-identity": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/credential-provider-imds": ^2.2.1 - "@smithy/property-provider": ^2.1.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: c51f267c61de0d82afe47d97cdf58971e3b8eec6e7364fe28d3867addd65e156358b96c39a335fad521e9a6925b349a967ae3eed1aa6e9cb4bcc1f0931e3ed50 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: af5fad70513e8d0bc10013f220588e45e83d488e0780873d7e76bf5b7099e70c9b4e49b6409d16add64ae212c53a472b12a2178e8bafd7878fdf121d6e2fd112 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.515.0" +"@aws-sdk/credential-provider-sso@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.556.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 11159b4c9502218ec6cba9a46ddc120e53aec7f04507c14d4e99a186073cfd363af438c623705890a2e8f6cc792475ebd14c82766dad82dabf7f20d9708f7faf + "@aws-sdk/client-sso": 3.556.0 + "@aws-sdk/token-providers": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: ea6c9bd7f183abedf79ff7959fdc31c16cb250afece2304d3005343aae4a203d04f2421ac1dd0a815a6d1823c721b277449d0ab27dc17fe8c75b211e44a31667 languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.515.0" +"@aws-sdk/credential-provider-web-identity@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.556.0" dependencies: - "@aws-sdk/client-sso": 3.515.0 - "@aws-sdk/token-providers": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: fbe1eebc50e9bd3715bca4e6ee1a2922cf1ea383953730a6bd3b88b12f23a95cb3ff0edaf8578c81156ef65648eb0295f5c39ed6ae2c8e16b6ce9d4c46f207e9 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.515.0" - dependencies: - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: f0a7e9855f78849143c3139c613cc1531a88272f3ec039d23ac9366b94495a3e07212ade9541e56c93560ad9f58600376e9de38706a4cd97aaf5f400911361cd + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 79d3277db07130b201b5788a76e8a71c2816be1e190ce7f96d174c2c8153fdcfb6adbf17575d8fd5c928452327a37872f18a48e563805997247bdc3cda2b9cac languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/credential-providers@npm:3.515.0" + version: 3.556.0 + resolution: "@aws-sdk/credential-providers@npm:3.556.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.515.0 - "@aws-sdk/client-sso": 3.515.0 - "@aws-sdk/client-sts": 3.515.0 - "@aws-sdk/credential-provider-cognito-identity": 3.515.0 - "@aws-sdk/credential-provider-env": 3.515.0 - "@aws-sdk/credential-provider-http": 3.515.0 - "@aws-sdk/credential-provider-ini": 3.515.0 - "@aws-sdk/credential-provider-node": 3.515.0 - "@aws-sdk/credential-provider-process": 3.515.0 - "@aws-sdk/credential-provider-sso": 3.515.0 - "@aws-sdk/credential-provider-web-identity": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/credential-provider-imds": ^2.2.1 - "@smithy/property-provider": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 8890e83fc19072c51cee8d50ee7168800b9775aa00bcb7a0feb836e60fbae0fb8ba55133d256719033cd7ccda0f5881350474ba3f4769016f01ce7de4ef7b6e5 + "@aws-sdk/client-cognito-identity": 3.556.0 + "@aws-sdk/client-sso": 3.556.0 + "@aws-sdk/client-sts": 3.556.0 + "@aws-sdk/credential-provider-cognito-identity": 3.556.0 + "@aws-sdk/credential-provider-env": 3.535.0 + "@aws-sdk/credential-provider-http": 3.552.0 + "@aws-sdk/credential-provider-ini": 3.556.0 + "@aws-sdk/credential-provider-node": 3.556.0 + "@aws-sdk/credential-provider-process": 3.535.0 + "@aws-sdk/credential-provider-sso": 3.556.0 + "@aws-sdk/credential-provider-web-identity": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 6d00b6ab7fbd0e0ca83ecd2823b446290be20d68f7c2b26128b8f678ab9d6e0f7fb423adf94bb12903abdeb324b4aa7ce8dd81e0b17f5b3322f6b14e634552e0 languageName: node linkType: hard @@ -951,34 +975,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.515.0 - resolution: "@aws-sdk/lib-storage@npm:3.515.0" + version: 3.556.0 + resolution: "@aws-sdk/lib-storage@npm:3.556.0" dependencies: - "@smithy/abort-controller": ^2.1.1 - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/smithy-client": ^2.3.1 + "@smithy/abort-controller": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/smithy-client": ^2.5.1 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 - tslib: ^2.5.0 + tslib: ^2.6.2 peerDependencies: "@aws-sdk/client-s3": ^3.0.0 - checksum: b4d7b3783508ce3ef93150b2a249490c5af803d02d91ce81aebf0ec055870aae3260d4d66e9bf1d4234fb61d11cfaa54f2916c9c2572cf4cb6ee1b15993c41b5 + checksum: 361e87ce38f566e7ffe0da2bd436bfda5dfce1c9e4f86f4fbab9e157ba24a47e169824dd9723f02eab8cd682b381a765453bd8d4c5fa0ae3c5273ff6d3a166e5 languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.515.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-arn-parser": 3.495.0 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - "@smithy/util-config-provider": ^2.2.1 - tslib: ^2.5.0 - checksum: 8ecec09ac50c33a24178e73be6b4238e5047984eebf54c4786392e82d2b1cdd09807ee97104f603d22890a58657335843f9587c66e544c2ffbb9a25f3e3bf065 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-arn-parser": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + tslib: ^2.6.2 + checksum: d72dfd197dc9aa1ed8ea3de6fb0a18363688fa8e18f6a9d01cb2f425087c5b72aa4bfd0955715c84da86adf9a46029755cff55a02a6ffbf4459009982a5a5415 languageName: node linkType: hard @@ -995,108 +1019,108 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.515.0" +"@aws-sdk/middleware-expect-continue@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: c989e0e55f51c631f914b444a0e3a6a81c79c1ad8046346c16a4ccfbb77aeaf48ba948a6b8185fc36c00abf07951cc374c3673da6d23d7de6cd3ec8d5b4d840e + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: fdac9bc59833ca9688155f115f85c31f690df5ef690e9a8921b94b87c4faac3eb3ff10641699822faaaf9a6cc4ce4c67e693a7b4befe8baf8138a9d276d6714d languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.515.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.535.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 - "@aws-sdk/types": 3.515.0 - "@smithy/is-array-buffer": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: 89f2df7a3dd40c174586aec1349e4e144825cffb252df843b115390702523dc6cfb745756a69a1ab1e77e44340fd55bed04be3856fe96d937af5702bcbcf869b + "@aws-sdk/types": 3.535.0 + "@smithy/is-array-buffer": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 14c04cd932bdb9029466079b248c1fa8222183de4c288bf12ad661cdc7717938485fdb973b7948da729e5be218573cfd2cbe74b51a1bc2bd27131ca7d67909c1 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.515.0" +"@aws-sdk/middleware-host-header@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: ff066cf47b0ba2c64bd70efdec795ac2da8bad7ba8dd44913c98f42b153ca6e753b13b6c1ef7075499590279a5cc49b5a60511dae4512dcdb11a62a0e67fa061 + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 13a22a5b19912a86fe872c9c0f6ba9ab758ba9483ce9a2e73fa68acae498b68404e38e7fc1e3962639a6c3f80ebe19ea5c5340e1024e11ab417998696c8a5dca languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.515.0" +"@aws-sdk/middleware-location-constraint@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: c3e7c7b51c276eba7ceef05c18416d2cca976c83ac9db227877090c33f676b50b0c90ceaf5d924cd9894a4c2f44c0a2d06ec93da753ac646fecb68d5facef570 + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 4e89b6c5d4253568e599f0e8be37e80cf12a755ba89b89d9c9ae2ced75213850c41922fa1871a9c92345057e15d5db956a353841eb63353d8f2bb69a61d4a10d languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-logger@npm:3.515.0" +"@aws-sdk/middleware-logger@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-logger@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 32d251e77f43593ffdd192a4d0628f33773e29c14a3001a4c6519553e94958edbd0fb8e6954a65d1180b0caa16cafe9fc9b362d1ab663db1d1eac84b15667645 + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: e264d05aa88fadd94d17000b1df79bf1931c5fbc2c871616de9b836bab7254d8c21e0fc2ac509a07af578bd823b795efafaf48daca805bc4493986288ed0c4ab languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.515.0" +"@aws-sdk/middleware-recursion-detection@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 23c4a1e4d7de86196acfcfbc84bea84c8c3211c4831fdc7c975a6388022037bd5baa4e5809dca188631f06726b51fcf85af358f9ef526e255dc494b368d0da0c + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: b6b518243a10dcdcea7c1fd4790cf2e1e0e3d4363ebce51ac364c9b15631a6f3d1db44d00e7c75cbdf1d558a0d868583d6e1853e571e15e23d0d2901f168e2e4 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.515.0" +"@aws-sdk/middleware-sdk-s3@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.556.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-arn-parser": 3.495.0 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/signature-v4": ^2.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/util-config-provider": ^2.2.1 - tslib: ^2.5.0 - checksum: cb67334b30eee8fcf52637407cab2787353e463bdf5a99a33966f0e765f6f8fc687c4bba2b63ec7a4374b2ab544be807e1849bd910e6f163ff43d036f026e7e1 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-arn-parser": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + tslib: ^2.6.2 + checksum: a50d96f898a8e6f7cfa0bc61c888240e1fd7aa55cb9fd9376d720f43d30a83d7ad4bd9d828224c125f62b362d77ccfc7fbd64c5c4563f97790f9683ea87abe93 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.515.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.552.0": + version: 3.552.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.552.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/util-hex-encoding": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: 67a7d9ed3e975a3fd83266f18ce2d94e3dc457d7001af7031e732b2d96135678dd3323ecae56ffe214f3dbe23d1df295a0cd0d21df7f6b9c98699e6a9b4704ca + "@aws-sdk/types": 3.535.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: a2dfeab25b89b8c0f3204195df58bf5deefb261883db936c6701e70d5a1f6e2a0e8e3a756fea6a4f0e3a1dc4023d820c6b8b3717f759622ffa7cd8851cd9ed59 languageName: node linkType: hard @@ -1110,42 +1134,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-signing@npm:3.515.0" +"@aws-sdk/middleware-signing@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/middleware-signing@npm:3.556.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/signature-v4": ^2.1.1 - "@smithy/types": ^2.9.1 - "@smithy/util-middleware": ^2.1.1 - tslib: ^2.5.0 - checksum: 7ee85c70a81b85e455c4411caad79c7b41a0a0fd9696feead394a31ca360b096c74f7b2b6b5d449fcfa622659305618e24a49d15c45cab3afa54503459a9b24a + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: b72c0223cc531d9eaac41124c3dcf60d974dbe0a5698fa6cf2ec877d73d83ff02ae310636478054ba5f7d1c3240ff277831c5144955ddb59e513b3de7cb4f272 languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.515.0" +"@aws-sdk/middleware-ssec@npm:3.537.0": + version: 3.537.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.537.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 3a91ebaf128ff63665f9aa69b9b2d475ebb8e519da2e94a142bcea7f9b173be52a0476b814e90e88e0936db3371e3c1c090b4e44018f006e1cfc37d2631a36d8 + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 7a963134cab4c9056d249113f6d5e2847be28847fc8c39b943c487ff5d22b9b1d91092e801694e2da95929a4820c45f6b5afc22c655a6dcfb5eb82e44952de14 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.515.0" +"@aws-sdk/middleware-user-agent@npm:3.540.0": + version: 3.540.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.540.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@aws-sdk/util-endpoints": 3.515.0 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: fd601cb0367d42e38b71494c773d82bde8970f9aafbdbf18d7cadc25732ecc2b787f0cfef2110755d0cef73d6aa3ce2ca77dc5353854bedaf392a69019b39ac2 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 7ee609fb2b669f93657a87c291dff17f8315973ddbbeee36c54a0233b4911091916880f6e27da93fef01e5fd53654b3834a68cf74256b88b1c4dbe5880a4c14f languageName: node linkType: hard @@ -1193,31 +1217,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.515.0" +"@aws-sdk/region-config-resolver@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/types": ^2.9.1 - "@smithy/util-config-provider": ^2.2.1 - "@smithy/util-middleware": ^2.1.1 - tslib: ^2.5.0 - checksum: 0ed7fbd6390baebdf511b30877236fa8be8716e0162e2c9e0138c9b41ebda7d99a6f3d6cf66cb4af24761631c2c29102ecfe7a5f08894e1de3c98ca6a135fa74 + "@aws-sdk/types": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: 7b556e47c721c0829ae635203a1dbcab7040e2885d2bdc37898eb3139dabb5f6da580b860202e3b7737330bfc02de5084a98ff8f8b5c36adcfe8e076b82d3487 languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.515.0" +"@aws-sdk/signature-v4-multi-region@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.556.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/protocol-http": ^3.1.1 - "@smithy/signature-v4": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 1f780409af431b3ac91beee294cf4af74fff9f3dffc21ddd1c8a1782a01916da162ceec27c133a9e86452279bdf0005f9118809820d557a248613cd44f0f7ec3 + "@aws-sdk/middleware-sdk-s3": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 0a23fbb8f99e1b8ab6c7523d5584864749a2ad5b244b78667d88d4a0eb0f74127e22fff4b44a9b694c235e70a66520ee72e0e57b129847d9405c6d907abf5e81 languageName: node linkType: hard @@ -1237,17 +1261,17 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/token-providers@npm:3.515.0" +"@aws-sdk/token-providers@npm:3.556.0": + version: 3.556.0 + resolution: "@aws-sdk/token-providers@npm:3.556.0" dependencies: - "@aws-sdk/client-sso-oidc": 3.515.0 - "@aws-sdk/types": 3.515.0 - "@smithy/property-provider": ^2.1.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: ab51c440da9772d0ee58948241b975705c171395cf1bad81a4ffd8f11f34106af54dcba930e360fb19489beedc1106ac14432bd27abdfe4b7536dc2113841027 + "@aws-sdk/client-sso-oidc": 3.556.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 15726af45c8a52837eb3291391c23e5b66a153218275c4fcc228a80f63169b401270ff736271401b6d4c301944bc20620d63dfb14a87bbe743a50e3157e68c7e languageName: node linkType: hard @@ -1261,13 +1285,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.515.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": - version: 3.515.0 - resolution: "@aws-sdk/types@npm:3.515.0" +"@aws-sdk/types@npm:3.535.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.535.0 + resolution: "@aws-sdk/types@npm:3.535.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 0874f1814b58eae6e7115c3d08c2bc56e558e73d1ff8c5f833a73b4a0f76a42743c83c36a4b2759177e41b1feff065e85450f7bc235a087b94e67db12f87d298 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 3f735c78ea3a6f37d05387286f6d18b0e5deb41442095bd2f7c27b000659962872d1c801fa8484a6ac4b7d2725b2e176dc628c3fa2a903a3141d4be76488d48f languageName: node linkType: hard @@ -1282,12 +1306,12 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.495.0, @aws-sdk/util-arn-parser@npm:^3.310.0": - version: 3.495.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.495.0" +"@aws-sdk/util-arn-parser@npm:3.535.0, @aws-sdk/util-arn-parser@npm:^3.310.0": + version: 3.535.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.535.0" dependencies: - tslib: ^2.5.0 - checksum: 130f1b1c0d2b9917782049693aa4ab6aec98858d6e2b46c14a3a6c4979e65073f731aec96aa0e1c04e927d0b32ad2d4a6a701e2a6d5d416c6ea35e670e4eb987 + tslib: ^2.6.2 + checksum: 0e4c4ea080c7c6da00d359c337a1f9d961eac20c35cebad9cb6bb9b618f981955643990de7bfd6b53c29367a6d33550fe27b2a7539efdff08e01bdd303f0c5c2 languageName: node linkType: hard @@ -1301,15 +1325,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/util-endpoints@npm:3.515.0" +"@aws-sdk/util-endpoints@npm:3.540.0": + version: 3.540.0 + resolution: "@aws-sdk/util-endpoints@npm:3.540.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/types": ^2.9.1 - "@smithy/util-endpoints": ^1.1.1 - tslib: ^2.5.0 - checksum: 1ab8fcd3054dc0366f10813a01130d05f4ba33f1488c1a168f44881cb24f3fbc2393111b7b0fd4dc06c852e4c9a5bbe8a82717b72229b0977cdba8a631ddeee1 + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + "@smithy/util-endpoints": ^1.2.0 + tslib: ^2.6.2 + checksum: 62312773965480f8df5edb62ecf82ab3e54d5aa1b1f7eebdad78a2925eab47218b0268bc25a5d03598ac4d0c08935733031a2e3e1ce72531535ed1ea8a9b56c3 languageName: node linkType: hard @@ -1361,32 +1385,32 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.515.0" +"@aws-sdk/util-user-agent-browser@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/types": ^2.9.1 + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 bowser: ^2.11.0 - tslib: ^2.5.0 - checksum: 40f518006cb7e76d06d83dcf05222b0b0ff47c10b63149cd5db2c0c1db79c8eff34bd582e89c748897bc11697b7b357bdca77d569f57ad0b2081c088752d601f + tslib: ^2.6.2 + checksum: 148b82900e4b9efd24f5fc4152a8d6010c90eb019517fa3c00c3ac42205055f7611ef3834fb63397def40e600ea20f901177a7dd5b6aefa2aef4208e994f7d90 languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.515.0": - version: 3.515.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.515.0" +"@aws-sdk/util-user-agent-node@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.535.0" dependencies: - "@aws-sdk/types": 3.515.0 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 + "@aws-sdk/types": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: 4e91d9cd5bbe4aa8321417ea1bd9caf3229416ee624b7f67b5206b284a539116692412ca41d60dcb5759b841fed7d9fb570915566d1f7e620578657f89548a23 + checksum: f214c406fccde14591d1df25fed662e573510cdf1d5829d22e7a93e517ea4a3905acd123eaaeafdb8b217400e8c8e159231d37be02b67307922023996b398f42 languageName: node linkType: hard @@ -1409,13 +1433,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.496.0": - version: 3.496.0 - resolution: "@aws-sdk/xml-builder@npm:3.496.0" +"@aws-sdk/xml-builder@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/xml-builder@npm:3.535.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 42d9d60c1c7f8a22f6a64ac36ba9d5ccff200ce963beebb142ad4708d2486fe29b61ecb37bbccd6f0019e25107aa2327e6d8550d30214b4895e7219ccb8661c8 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 9320f6600c7852b681ed4171f1521eda166321ef7ffea5a6b99a1d328835bb12f7423431ea23a696c678ec4fc8e6dbb2f979d941289f6e0cb55c3da7d5eee140 languageName: node linkType: hard @@ -1428,34 +1452,7 @@ __metadata: languageName: node linkType: hard -"@azure/arm-appservice@npm:^14.0.0": - version: 14.1.0 - resolution: "@azure/arm-appservice@npm:14.1.0" - dependencies: - "@azure/abort-controller": ^1.0.0 - "@azure/core-auth": ^1.3.0 - "@azure/core-client": ^1.7.0 - "@azure/core-lro": ^2.5.4 - "@azure/core-paging": ^1.2.0 - "@azure/core-rest-pipeline": ^1.12.0 - tslib: ^2.2.0 - checksum: b989bc26d94056e0f02d2ede9981ebbf90ebefdc8b35c8f66531d3220c4ce52484d49c0a15b7056b79898a76533b0de0edf141b7736aadfabf2c33305804b884 - languageName: node - linkType: hard - -"@azure/arm-resourcegraph@npm:^4.2.1": - version: 4.2.1 - resolution: "@azure/arm-resourcegraph@npm:4.2.1" - dependencies: - "@azure/core-auth": ^1.1.4 - "@azure/ms-rest-azure-js": ^2.1.0 - "@azure/ms-rest-js": ^2.2.0 - tslib: ^1.10.0 - checksum: a5afea9faef84ed4576fda430301039524aefe6976a54204fe4453e672aa3d13edc7ef5c996ad6293e9afa3a0833549174aaac18ce236c4ec1242698e2c22bd2 - languageName: node - linkType: hard - -"@azure/core-auth@npm:^1.1.4, @azure/core-auth@npm:^1.3.0, @azure/core-auth@npm:^1.4.0, @azure/core-auth@npm:^1.5.0": +"@azure/core-auth@npm:^1.3.0, @azure/core-auth@npm:^1.4.0, @azure/core-auth@npm:^1.5.0": version: 1.5.0 resolution: "@azure/core-auth@npm:1.5.0" dependencies: @@ -1466,7 +1463,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-client@npm:^1.4.0, @azure/core-client@npm:^1.7.0": +"@azure/core-client@npm:^1.4.0": version: 1.7.3 resolution: "@azure/core-client@npm:1.7.3" dependencies: @@ -1503,7 +1500,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-lro@npm:^2.2.0, @azure/core-lro@npm:^2.5.4": +"@azure/core-lro@npm:^2.2.0": version: 2.5.4 resolution: "@azure/core-lro@npm:2.5.4" dependencies: @@ -1515,7 +1512,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-paging@npm:^1.1.1, @azure/core-paging@npm:^1.2.0": +"@azure/core-paging@npm:^1.1.1": version: 1.3.0 resolution: "@azure/core-paging@npm:1.3.0" dependencies: @@ -1524,7 +1521,7 @@ __metadata: languageName: node linkType: hard -"@azure/core-rest-pipeline@npm:^1.1.0, @azure/core-rest-pipeline@npm:^1.12.0, @azure/core-rest-pipeline@npm:^1.9.1": +"@azure/core-rest-pipeline@npm:^1.1.0, @azure/core-rest-pipeline@npm:^1.9.1": version: 1.12.2 resolution: "@azure/core-rest-pipeline@npm:1.12.2" dependencies: @@ -1571,8 +1568,8 @@ __metadata: linkType: hard "@azure/identity@npm:^4.0.0": - version: 4.0.1 - resolution: "@azure/identity@npm:4.0.1" + version: 4.1.0 + resolution: "@azure/identity@npm:4.1.0" dependencies: "@azure/abort-controller": ^1.0.0 "@azure/core-auth": ^1.5.0 @@ -1581,14 +1578,14 @@ __metadata: "@azure/core-tracing": ^1.0.0 "@azure/core-util": ^1.3.0 "@azure/logger": ^1.0.0 - "@azure/msal-browser": ^3.5.0 - "@azure/msal-node": ^2.5.1 + "@azure/msal-browser": ^3.11.1 + "@azure/msal-node": ^2.6.6 events: ^3.0.0 jws: ^4.0.0 open: ^8.0.0 stoppable: ^1.1.0 tslib: ^2.2.0 - checksum: 2c975ca70b274dc185022c2b19f1774079fd5cfb08c78ec3500e4baf973911b2958031d5fa36369d3c9acdeb25db457cc497991e7393b383103c058e097703e5 + checksum: ff46494c7a7fdc866406f0e7938e7621c9ee0e852af2faad7ecf53d62a45b1528150f9c8b13a0fdd846995943025fbcbc88f2582b107cd5afac1511c28252377 languageName: node linkType: hard @@ -1601,57 +1598,30 @@ __metadata: languageName: node linkType: hard -"@azure/ms-rest-azure-js@npm:^2.1.0": - version: 2.1.0 - resolution: "@azure/ms-rest-azure-js@npm:2.1.0" +"@azure/msal-browser@npm:^3.11.1": + version: 3.11.1 + resolution: "@azure/msal-browser@npm:3.11.1" dependencies: - "@azure/core-auth": ^1.1.4 - "@azure/ms-rest-js": ^2.2.0 - tslib: ^1.10.0 - checksum: 0e6d6700f4ee0ad14383642b02fe86b33f4034aaff38499374ed5be59154e869ee231790d20b7557622ebcdfa9eed45dc2559391a79dee51c849a8ced0c86fed + "@azure/msal-common": 14.8.1 + checksum: edad14a92422de8ee9d4edaa934bb308815361bb90c044a5db2e36efff03c6bae04e487fe9d43f085012745620a6c8789af61b1f1c782f63f1bda0970dd12ebb languageName: node linkType: hard -"@azure/ms-rest-js@npm:^2.2.0": - version: 2.7.0 - resolution: "@azure/ms-rest-js@npm:2.7.0" - dependencies: - "@azure/core-auth": ^1.1.4 - abort-controller: ^3.0.0 - form-data: ^2.5.0 - node-fetch: ^2.6.7 - tslib: ^1.10.0 - tunnel: 0.0.6 - uuid: ^8.3.2 - xml2js: ^0.5.0 - checksum: 38434010f3fc54a625f637a7758358d7ce0ad3e55ce9a6c7490bf05bbec8ea75ae95fe80041d2376beb3ef78ee6e55858bd0541477d7a88703246e368cfd59c1 +"@azure/msal-common@npm:14.8.1": + version: 14.8.1 + resolution: "@azure/msal-common@npm:14.8.1" + checksum: 28f606d429effba475d88d3d0d6934e50c944c6636f7ad07ddb0d31113659cc9d55a1df8242d7daed051e308672618eaac7e0c70a7aeaa64ffd85c1ef23c28b3 languageName: node linkType: hard -"@azure/msal-browser@npm:^3.5.0": - version: 3.5.0 - resolution: "@azure/msal-browser@npm:3.5.0" +"@azure/msal-node@npm:^2.6.6": + version: 2.6.6 + resolution: "@azure/msal-node@npm:2.6.6" dependencies: - "@azure/msal-common": 14.4.0 - checksum: 876e5d5ac4fc638acc18faa2cea269b595963df5806482b858f3ec72b2cff3e2b4cb47fa1e0f7ace04dd66b0544e4471f04de299a551975bdb74f111fc65af34 - languageName: node - linkType: hard - -"@azure/msal-common@npm:14.4.0": - version: 14.4.0 - resolution: "@azure/msal-common@npm:14.4.0" - checksum: 63c63fac0915b4dbd026add260e2527138a02ba6f9ccd8d92d2641fc3e2b5d59c6943415d470e40af2f34c55e77ccfc2d3f90e8a2befc1eeae3a9896ec65ade8 - languageName: node - linkType: hard - -"@azure/msal-node@npm:^2.5.1": - version: 2.5.1 - resolution: "@azure/msal-node@npm:2.5.1" - dependencies: - "@azure/msal-common": 14.4.0 + "@azure/msal-common": 14.8.1 jsonwebtoken: ^9.0.0 uuid: ^8.3.0 - checksum: f2e5cfbfeea010e88885d19d1fca22aa70fbdc488ec58e8c76b8da8a632be002ffacddd54671c7e58162bce3f5f1ddfcb440c330ddd627aa74134b6a81d1753e + checksum: 45a83d774af1bb58df99c67551c68c686385950f701421e0c4c446e4d1b80c316f5e525024189bdbdd520b34e326d0e901a476c2afae07389fb9efd1c616c867 languageName: node linkType: hard @@ -1680,7 +1650,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3": version: 7.23.5 resolution: "@babel/code-frame@npm:7.23.5" dependencies: @@ -3134,22 +3104,22 @@ __metadata: languageName: node linkType: hard -"@babel/runtime-corejs3@npm:^7.20.7, @babel/runtime-corejs3@npm:^7.22.15, @babel/runtime-corejs3@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/runtime-corejs3@npm:7.23.9" +"@babel/runtime-corejs3@npm:^7.20.7, @babel/runtime-corejs3@npm:^7.22.15, @babel/runtime-corejs3@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/runtime-corejs3@npm:7.24.4" dependencies: core-js-pure: ^3.30.2 regenerator-runtime: ^0.14.0 - checksum: 715d916b6cf60013597aa9a5823fd04a9c6cc6ba6221bb8611e76c369cbf1b4baf1d0ad63b6522736593a38e89a6502213a38f57a9c24e5586628e930c4fd52c + checksum: 0c2e7c477de3dbf5cc6f2434cee3d78a34d87e8f1e2ea65840eb948d00f7d6968e0ef055449adf372a39d6214f8b9b2532506149b9d0e7ea3d09b1b84678ae6c languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.23.8 - resolution: "@babel/runtime@npm:7.23.8" +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" dependencies: regenerator-runtime: ^0.14.0 - checksum: 0bd5543c26811153822a9f382fd39886f66825ff2a397a19008011376533747cd05c33a91f6248c0b8b0edf0448d7c167ebfba34786088f1b7eb11c65be7dfc3 + checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 languageName: node linkType: hard @@ -3193,6 +3163,52 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-explore-common@npm:^0.0.3": + version: 0.0.3 + resolution: "@backstage-community/plugin-explore-common@npm:0.0.3" + checksum: 54b81496122c11bd16cbb71c4fcc92e6bf16b5e4f580fc8043dbea35955447d67b463a40065e629ed81ef3aeeb36d1f41d445b7fa4d8ab7e0036a296b361e398 + languageName: node + linkType: hard + +"@backstage-community/plugin-puppetdb@npm:^0.1.18": + version: 0.1.18 + resolution: "@backstage-community/plugin-puppetdb@npm:0.1.18" + dependencies: + "@backstage/catalog-model": ^1.4.5 + "@backstage/core-components": ^0.14.4 + "@backstage/core-plugin-api": ^1.9.2 + "@backstage/errors": ^1.2.4 + "@backstage/plugin-catalog-react": ^1.11.3 + "@material-ui/core": ^4.12.2 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: d0e4fe3f818aa05c527d773d558291b97f3a4fee1b1a765e0e6f5a2f36ca1897e3933e92abdeffeb8b33701c21314eb3565900ff78624fe1d5eff3ee2781cfff + languageName: node + linkType: hard + +"@backstage-community/plugin-stackstorm@npm:^0.1.16": + version: 0.1.16 + resolution: "@backstage-community/plugin-stackstorm@npm:0.1.16" + dependencies: + "@backstage/core-components": ^0.14.4 + "@backstage/core-plugin-api": ^1.9.2 + "@backstage/errors": ^1.2.4 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 2fd7d290cd98ad09b16862a5dee3302796942e85818abf9c4a9102038a4fb83e86ceee39d901e59bb7fb7c60df7797524f8c6a5cfee1a4a0ea59edcbb4de5a0a + languageName: node + linkType: hard + "@backstage/app-defaults@workspace:^, @backstage/app-defaults@workspace:packages/app-defaults": version: 0.0.0-use.local resolution: "@backstage/app-defaults@workspace:packages/app-defaults" @@ -3207,7 +3223,7 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -3244,21 +3260,28 @@ __metadata: "@types/node-forge": ^1.3.0 "@types/stoppable": ^1.1.0 compression: ^1.7.4 + cookie: ^0.6.0 cors: ^2.8.5 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: ^11.2.0 helmet: ^6.0.0 http-errors: ^2.0.0 + jose: ^5.0.0 + knex: ^3.0.0 lodash: ^4.17.21 logform: ^2.3.2 - minimatch: ^5.0.0 + luxon: ^3.0.0 + minimatch: ^9.0.0 minimist: ^1.2.5 morgan: ^1.10.0 + msw: ^1.0.0 node-forge: ^1.3.1 + path-to-regexp: ^6.2.1 selfsigned: ^2.0.0 stoppable: ^1.1.0 supertest: ^6.1.3 + uuid: ^9.0.0 winston: ^3.2.1 winston-transport: ^4.5.0 languageName: unknown @@ -3269,6 +3292,7 @@ __metadata: resolution: "@backstage/backend-common@workspace:packages/backend-common" dependencies: "@aws-sdk/abort-controller": ^3.347.0 + "@aws-sdk/client-codecommit": ^3.350.0 "@aws-sdk/client-s3": ^3.350.0 "@aws-sdk/credential-providers": ^3.350.0 "@aws-sdk/types": ^3.347.0 @@ -3284,6 +3308,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/integration-aws-node": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" "@backstage/types": "workspace:^" "@google-cloud/storage": ^7.0.0 "@keyv/memcache": ^1.3.5 @@ -3307,7 +3332,7 @@ __metadata: "@types/webpack-env": ^1.15.2 "@types/yauzl": ^2.10.0 archiver: ^6.0.0 - aws-sdk-client-mock: ^3.0.0 + aws-sdk-client-mock: ^4.0.0 base64-stream: ^1.0.0 better-sqlite3: ^9.0.0 compression: ^1.7.4 @@ -3321,25 +3346,25 @@ __metadata: helmet: ^6.0.0 http-errors: ^2.0.0 isomorphic-git: ^1.23.0 - jose: ^4.6.0 + jose: ^5.0.0 keyv: ^4.5.2 knex: ^3.0.0 lodash: ^4.17.21 logform: ^2.3.2 luxon: ^3.0.0 - minimatch: ^5.0.0 + minimatch: ^9.0.0 msw: ^1.0.0 - mysql2: ^2.2.5 + mysql2: ^3.0.0 node-fetch: ^2.6.7 p-limit: ^3.1.0 pg: ^8.11.3 raw-body: ^2.4.1 supertest: ^6.1.3 tar: ^6.1.12 - uuid: ^8.3.2 + uuid: ^9.0.0 winston: ^3.2.1 winston-transport: ^4.5.0 - yauzl: ^2.10.0 + yauzl: ^3.0.0 yn: ^4.0.0 peerDependencies: pg-connection-string: ^2.3.0 @@ -3418,7 +3443,7 @@ __metadata: express: ^4.17.1 express-openapi-validator: ^5.0.4 express-promise-router: ^4.1.0 - json-schema-to-ts: ^2.6.2 + json-schema-to-ts: ^3.0.0 lodash: ^4.17.21 openapi-merge: ^1.3.2 openapi3-ts: ^3.1.2 @@ -3447,6 +3472,7 @@ __metadata: resolution: "@backstage/backend-tasks@workspace:packages/backend-tasks" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" @@ -3458,9 +3484,8 @@ __metadata: knex: ^3.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - uuid: ^8.0.0 + uuid: ^9.0.0 wait-for-expect: ^3.0.2 - winston: ^3.2.1 zod: ^3.22.4 languageName: unknown linkType: soft @@ -3479,30 +3504,31 @@ __metadata: "@backstage/types": "workspace:^" "@types/supertest": ^2.0.8 better-sqlite3: ^9.0.0 + cookie: ^0.6.0 express: ^4.17.1 fs-extra: ^11.0.0 knex: ^3.0.0 msw: ^1.0.0 - mysql2: ^2.2.5 + mysql2: ^3.0.0 pg: ^8.11.3 supertest: ^6.1.3 - testcontainers: ^8.1.2 + testcontainers: ^10.0.0 textextensions: ^5.16.0 - uuid: ^8.0.0 + uuid: ^9.0.0 peerDependencies: "@types/jest": "*" languageName: unknown linkType: soft -"@backstage/catalog-client@npm:^1.5.2": - version: 1.5.2 - resolution: "@backstage/catalog-client@npm:1.5.2" +"@backstage/catalog-client@npm:^1.6.4": + version: 1.6.4 + resolution: "@backstage/catalog-client@npm:1.6.4" dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/errors": ^1.2.3 + "@backstage/catalog-model": ^1.4.5 + "@backstage/errors": ^1.2.4 cross-fetch: ^4.0.0 uri-template: ^2.0.0 - checksum: 70fe43269c016830fa1b4c1a58425c38cdaa704e07d4913a39e1e9aaa8680614177f9d1b2f4b0d8c50f356868c745d69d8bb6d03f56e8be97c6a3502a41c9431 + checksum: af3537d04f0abd6e6f3e49c7623994cc83db6efb2776fff5d59faee26c598840486e42a99c2bbb4a1b6ff97ad97ac857e913830cad62cda7cd71eef74cf2e179 languageName: node linkType: hard @@ -3519,15 +3545,15 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@npm:^1.4.3": - version: 1.4.3 - resolution: "@backstage/catalog-model@npm:1.4.3" +"@backstage/catalog-model@npm:^1.4.3, @backstage/catalog-model@npm:^1.4.5": + version: 1.4.5 + resolution: "@backstage/catalog-model@npm:1.4.5" dependencies: - "@backstage/errors": ^1.2.3 + "@backstage/errors": ^1.2.4 "@backstage/types": ^1.1.1 ajv: ^8.10.0 lodash: ^4.17.21 - checksum: 56a844d0c78adf62cefc09cf50f5aa221cdcf085e3558512758df9b1ea4ac088c7dbdf8274467a841170177d6cdd83d299ac412ccce5177c907fd6d6e2b2011c + checksum: 34aaa4b82d29bf3b0a4b52552f8eb8189041df826f87a7bbdef5107a1efb8ce1f7eb1c1a343868718ca2af9be76d9f5184f6a92076d893d3a3951d16881647b7 languageName: node linkType: hard @@ -3605,9 +3631,9 @@ __metadata: "@rollup/plugin-json": ^6.0.0 "@rollup/plugin-node-resolve": ^15.0.0 "@rollup/plugin-yaml": ^4.0.0 - "@spotify/eslint-config-base": ^14.0.0 - "@spotify/eslint-config-react": ^14.0.0 - "@spotify/eslint-config-typescript": ^14.0.0 + "@spotify/eslint-config-base": ^15.0.0 + "@spotify/eslint-config-react": ^15.0.0 + "@spotify/eslint-config-typescript": ^15.0.0 "@sucrase/webpack-loader": ^2.0.0 "@svgr/core": 6.5.x "@svgr/plugin-jsx": 6.5.x @@ -3625,7 +3651,6 @@ __metadata: "@types/http-proxy": ^1.17.4 "@types/inquirer": ^8.1.3 "@types/jest": ^29.5.11 - "@types/minimatch": ^5.0.0 "@types/node": ^18.17.8 "@types/npm-packlist": ^3.0.0 "@types/recursive-readdir": ^2.2.0 @@ -3638,6 +3663,7 @@ __metadata: "@types/yarnpkg__lockfile": ^1.1.4 "@typescript-eslint/eslint-plugin": ^6.12.0 "@typescript-eslint/parser": ^6.7.2 + "@vitejs/plugin-react": ^4.0.4 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": ^3.0.0-rc.4 bfj: ^8.0.0 @@ -3680,23 +3706,25 @@ __metadata: json-schema: ^0.4.0 lodash: ^4.17.21 mini-css-extract-plugin: ^2.4.2 - minimatch: ^5.1.1 + minimatch: ^9.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 node-libs-browser: ^2.2.1 nodemon: ^3.0.1 npm-packlist: ^5.0.0 ora: ^5.3.0 + p-limit: ^3.1.0 p-queue: ^6.6.2 + pirates: ^4.0.6 postcss: ^8.1.0 process: ^0.11.10 react-dev-utils: ^12.0.0-next.60 react-refresh: ^0.14.0 recursive-readdir: ^2.2.2 - replace-in-file: ^6.0.0 - rollup: ^2.60.2 - rollup-plugin-dts: ^4.0.1 - rollup-plugin-esbuild: ^4.7.2 + replace-in-file: ^7.1.0 + rollup: ^4.0.0 + rollup-plugin-dts: ^6.1.0 + rollup-plugin-esbuild: ^6.1.1 rollup-plugin-postcss: ^4.0.0 rollup-pluginutils: ^2.8.2 run-script-webpack-plugin: ^0.2.0 @@ -3706,11 +3734,12 @@ __metadata: swc-loader: ^0.2.3 tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 - ts-node: ^10.0.0 - tsx: ^4.0.0 util: ^0.12.3 + vite: ^4.4.9 + vite-plugin-html: ^3.2.0 + vite-plugin-node-polyfills: ^0.21.0 webpack: ^5.70.0 - webpack-dev-server: ^4.7.3 + webpack-dev-server: ^5.0.0 webpack-node-externals: ^3.0.0 yaml: ^2.0.0 yml-loader: ^2.1.0 @@ -3747,7 +3776,6 @@ __metadata: commander: ^12.0.0 jscodeshift: ^0.15.0 jscodeshift-add-imports: ^1.0.10 - ts-node: ^10.0.0 bin: backstage-codemods: bin/backstage-codemods languageName: unknown @@ -3781,7 +3809,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.1.1, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@^1.1.1, @backstage/config@^1.2.0, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -3789,7 +3817,6 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" - lodash: ^4.17.21 languageName: unknown linkType: soft @@ -3803,9 +3830,9 @@ __metadata: "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@backstage/version-bridge": "workspace:^" - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/react-hooks": ^8.0.0 "@testing-library/user-event": ^14.0.0 "@types/prop-types": ^15.7.3 @@ -3834,6 +3861,8 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/core-compat-api@workspace:packages/core-compat-api" dependencies: + "@backstage-community/plugin-puppetdb": ^0.1.18 + "@backstage-community/plugin-stackstorm": ^0.1.16 "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" "@backstage/core-plugin-api": "workspace:^" @@ -3841,12 +3870,10 @@ __metadata: "@backstage/frontend-plugin-api": "workspace:^" "@backstage/frontend-test-utils": "workspace:^" "@backstage/plugin-catalog": "workspace:^" - "@backstage/plugin-puppetdb": "workspace:^" - "@backstage/plugin-stackstorm": "workspace:^" "@backstage/version-bridge": "workspace:^" "@oriflame/backstage-plugin-score-card": ^0.8.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -3854,7 +3881,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.13.10, @backstage/core-components@npm:^0.13.8": +"@backstage/core-components@npm:^0.13.10": version: 0.13.10 resolution: "@backstage/core-components@npm:0.13.10" dependencies: @@ -3905,6 +3932,57 @@ __metadata: languageName: node linkType: hard +"@backstage/core-components@npm:^0.14.4": + version: 0.14.4 + resolution: "@backstage/core-components@npm:0.14.4" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.2 + "@backstage/errors": ^1.2.4 + "@backstage/theme": ^0.5.3 + "@backstage/version-bridge": ^1.0.8 + "@date-io/core": ^1.3.13 + "@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.61 + "@react-hookz/web": ^24.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + linkify-react: 4.1.3 + linkifyjs: 4.1.3 + lodash: ^4.17.21 + pluralize: ^8.0.0 + qs: ^6.9.4 + rc-progress: 3.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.7.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.11 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ^3.22.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: b96721b267daeec5a73a8b487f96ab5b5b3a85b8b113b2e45c5b733f3201af0d5cda3d7a325f5f68a4057ccbe78beac9f239b51ceb3099d3b0001709ec16928b + languageName: node + linkType: hard + "@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" @@ -3924,9 +4002,9 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/ansi-regex": ^5.0.0 "@types/classnames": ^2.2.9 @@ -3960,7 +4038,7 @@ __metadata: rc-progress: 3.5.1 react-helmet: 6.1.0 react-hook-form: ^7.12.2 - react-idle-timer: 5.6.2 + react-idle-timer: 5.7.2 react-markdown: ^8.0.0 react-sparklines: ^1.7.0 react-syntax-highlighter: ^15.4.5 @@ -3978,24 +4056,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.8.0, @backstage/core-plugin-api@npm:^1.8.2": - version: 1.8.2 - resolution: "@backstage/core-plugin-api@npm:1.8.2" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.7 - "@types/react": ^16.13.1 || ^17.0.0 - history: ^5.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 48aeccba7efa29e6989839216fdd2bc212b96334cc94a9ac8feb713038074bdb10c9caa9a2e696c0c2282faa5473883908655148b59c8f071158b3b59c1a9629 - languageName: node - linkType: hard - -"@backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.2, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4006,9 +4067,9 @@ __metadata: "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@backstage/version-bridge": "workspace:^" - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 history: ^5.0.0 @@ -4041,7 +4102,6 @@ __metadata: nodemon: ^3.0.1 ora: ^5.3.0 recursive-readdir: ^2.2.2 - ts-node: ^10.0.0 bin: backstage-create-app: bin/backstage-create-app languageName: unknown @@ -4063,9 +4123,9 @@ __metadata: "@backstage/theme": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 @@ -4094,7 +4154,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/errors@^1.2.3, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": +"@backstage/errors@^1.2.3, @backstage/errors@^1.2.4, @backstage/errors@workspace:^, @backstage/errors@workspace:packages/errors": version: 0.0.0-use.local resolution: "@backstage/errors@workspace:packages/errors" dependencies: @@ -4110,8 +4170,9 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@manypkg/get-packages": ^1.1.3 + "@types/estree": ^1.0.5 eslint: ^8.33.0 - minimatch: ^5.1.2 + minimatch: ^9.0.0 languageName: unknown linkType: soft @@ -4133,7 +4194,7 @@ __metadata: "@material-ui/core": ^4.12.4 "@material-ui/icons": ^4.11.3 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 lodash: ^4.17.21 peerDependencies: @@ -4142,23 +4203,23 @@ __metadata: languageName: unknown linkType: soft -"@backstage/frontend-plugin-api@npm:^0.5.0": - version: 0.5.0 - resolution: "@backstage/frontend-plugin-api@npm:0.5.0" +"@backstage/frontend-plugin-api@npm:^0.6.4": + version: 0.6.4 + resolution: "@backstage/frontend-plugin-api@npm:0.6.4" dependencies: - "@backstage/core-components": ^0.13.10 - "@backstage/core-plugin-api": ^1.8.2 + "@backstage/core-components": ^0.14.4 + "@backstage/core-plugin-api": ^1.9.2 "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.7 + "@backstage/version-bridge": ^1.0.8 "@material-ui/core": ^4.12.4 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 lodash: ^4.17.21 zod: ^3.22.4 zod-to-json-schema: ^3.21.4 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: e21742463937f2ad14234dc2f75a650df50dcdaae596df38540a5a21bce28c6693f1c3fe43b6aaea9cca9fd4bcd5c0cab5a77880a6e2bf11f14811bcaa9b3c6c + checksum: 2ae2919147dcfd8a5b4379059ecb76461a27f38159c398915384db7a7396bc65451cf696d955e4ba23eb6dfb549395624d09412d0c9c776072d3f003e5f1cba8 languageName: node linkType: hard @@ -4176,7 +4237,7 @@ __metadata: "@backstage/version-bridge": "workspace:^" "@material-ui/core": ^4.12.4 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 history: ^5.3.0 lodash: ^4.17.21 @@ -4200,7 +4261,7 @@ __metadata: "@testing-library/jest-dom": ^6.0.0 "@types/react": "*" peerDependencies: - "@testing-library/react": ^12.1.3 || ^13.0.0 || ^14.0.0 + "@testing-library/react": ^15.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 languageName: unknown @@ -4220,30 +4281,12 @@ __metadata: "@backstage/config-loader": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/test-utils": "workspace:^" - aws-sdk-client-mock: ^3.0.0 - aws-sdk-client-mock-jest: ^3.0.0 + aws-sdk-client-mock: ^4.0.0 + aws-sdk-client-mock-jest: ^4.0.0 languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.21, @backstage/integration-react@npm:^1.1.23": - version: 1.1.23 - resolution: "@backstage/integration-react@npm:1.1.23" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.2 - "@backstage/integration": ^1.8.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 84861ed10d2081d53451862a68c63ad123e2b3bf3bbcb541c2b938669ecf93b2244020edb6a505536f811c37344c2b1c639d1a29978df829d819fc5df43fba63 - languageName: node - linkType: hard - -"@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@^1.1.26, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: @@ -4256,7 +4299,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@types/react": ^16.13.1 || ^17.0.0 msw: ^1.0.0 @@ -4267,22 +4310,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration@npm:^1.8.0": - version: 1.8.0 - resolution: "@backstage/integration@npm:1.8.0" - dependencies: - "@azure/identity": ^4.0.0 - "@backstage/config": ^1.1.1 - "@octokit/auth-app": ^4.0.0 - "@octokit/rest": ^19.0.3 - cross-fetch: ^4.0.0 - git-url-parse: ^13.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - checksum: 2cf2956cf2d37e7e0a1c21e60e5bb2e435c4d1a70f63fe915932ee618f3b673c3907e0dc5832a8221a1592e3c8338f333768a9f9693b7ed3bd8e7af1d7ebb2cb - languageName: node - linkType: hard - "@backstage/integration@workspace:^, @backstage/integration@workspace:packages/integration": version: 0.0.0-use.local resolution: "@backstage/integration@workspace:packages/integration" @@ -4303,240 +4330,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-adr-backend@workspace:^, @backstage/plugin-adr-backend@workspace:plugins/adr-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-adr-backend@workspace:plugins/adr-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-adr-common": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" - "@types/express": ^4.17.6 - "@types/marked": ^5.0.0 - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - luxon: ^3.0.0 - marked: ^4.0.14 - node-fetch: ^2.6.5 - supertest: ^6.1.3 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-adr-common@workspace:^, @backstage/plugin-adr-common@workspace:plugins/adr-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-adr-common@workspace:plugins/adr-common" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" - front-matter: ^4.0.2 - luxon: ^3.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-adr@workspace:^, @backstage/plugin-adr@workspace:plugins/adr": - version: 0.0.0-use.local - resolution: "@backstage/plugin-adr@workspace:plugins/adr" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/integration-react": "workspace:^" - "@backstage/plugin-adr-common": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" - "@backstage/plugin-search-react": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - lodash: ^4.17.21 - react-markdown: ^8.0.0 - react-use: ^17.2.4 - remark-gfm: ^3.0.1 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-airbrake-backend@workspace:plugins/airbrake-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-airbrake-backend@workspace:plugins/airbrake-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@types/express": "*" - "@types/http-proxy-middleware": ^0.19.3 - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - http-proxy-middleware: ^2.0.0 - supertest: ^6.1.6 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-airbrake@workspace:^, @backstage/plugin-airbrake@workspace:plugins/airbrake": - version: 0.0.0-use.local - resolution: "@backstage/plugin-airbrake@workspace:plugins/airbrake" - dependencies: - "@backstage/app-defaults": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-allure@workspace:plugins/allure": - version: 0.0.0-use.local - resolution: "@backstage/plugin-allure@workspace:plugins/allure" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-analytics-module-ga4@workspace:plugins/analytics-module-ga4": - version: 0.0.0-use.local - resolution: "@backstage/plugin-analytics-module-ga4@workspace:plugins/analytics-module-ga4" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/jest": ^29.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - react-ga4: ^2.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-analytics-module-ga@workspace:plugins/analytics-module-ga": - version: 0.0.0-use.local - resolution: "@backstage/plugin-analytics-module-ga@workspace:plugins/analytics-module-ga" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - react-ga: ^3.3.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-newrelic-browser": - version: 0.0.0-use.local - resolution: "@backstage/plugin-analytics-module-newrelic-browser@workspace:plugins/analytics-module-newrelic-browser" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@newrelic/browser-agent": ^1.236.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-apache-airflow@workspace:^, @backstage/plugin-apache-airflow@workspace:plugins/apache-airflow": - version: 0.0.0-use.local - resolution: "@backstage/plugin-apache-airflow@workspace:plugins/apache-airflow" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - cross-fetch: ^4.0.0 - msw: ^1.0.0 - qs: ^6.10.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-api-docs-module-protoc-gen-doc@workspace:plugins/api-docs-module-protoc-gen-doc": version: 0.0.0-use.local resolution: "@backstage/plugin-api-docs-module-protoc-gen-doc@workspace:plugins/api-docs-module-protoc-gen-doc" @@ -4556,7 +4349,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-api-docs@workspace:plugins/api-docs" dependencies: - "@asyncapi/react-component": 1.2.13 + "@asyncapi/react-component": 1.3.1 "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-app-api": "workspace:^" @@ -4574,13 +4367,14 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 + "@types/highlightjs": ^10.1.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 "@types/swagger-ui-react": ^4.18.0 - graphiql: 3.1.0 + graphiql: 3.1.1 graphql: ^16.0.0 graphql-config: ^5.0.2 graphql-ws: ^5.4.1 @@ -4593,28 +4387,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-apollo-explorer@workspace:plugins/apollo-explorer": - version: 0.0.0-use.local - resolution: "@backstage/plugin-apollo-explorer@workspace:plugins/apollo-explorer" - dependencies: - "@apollo/explorer": ^3.0.0 - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - use-deep-compare-effect: ^1.8.1 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-app-backend@workspace:^, @backstage/plugin-app-backend@workspace:plugins/app-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-app-backend@workspace:plugins/app-backend" @@ -4626,7 +4398,9 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/config-loader": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/plugin-app-node": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" "@backstage/types": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -4640,7 +4414,6 @@ __metadata: luxon: ^3.0.0 node-fetch: ^2.6.7 supertest: ^6.1.3 - winston: ^3.2.1 yn: ^4.0.0 languageName: unknown linkType: soft @@ -4706,13 +4479,70 @@ __metadata: "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" express: ^4.18.2 - jose: ^4.6.0 + jose: ^5.0.0 msw: ^2.0.8 node-cache: ^5.1.2 node-fetch: ^2.6.7 languageName: unknown linkType: soft +"@backstage/plugin-auth-backend-module-azure-easyauth-provider@workspace:^, @backstage/plugin-auth-backend-module-azure-easyauth-provider@workspace:plugins/auth-backend-module-azure-easyauth-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-azure-easyauth-provider@workspace:plugins/auth-backend-module-azure-easyauth-provider" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@types/passport": ^1.0.16 + express: ^4.19.2 + jose: ^5.0.0 + passport: ^0.7.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-auth-backend-module-bitbucket-provider@workspace:^, @backstage/plugin-auth-backend-module-bitbucket-provider@workspace:plugins/auth-backend-module-bitbucket-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-bitbucket-provider@workspace:plugins/auth-backend-module-bitbucket-provider" + dependencies: + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + express: ^4.18.2 + passport: ^0.7.0 + passport-bitbucket-oauth2: ^0.1.2 + supertest: ^6.3.3 + languageName: unknown + linkType: soft + +"@backstage/plugin-auth-backend-module-cloudflare-access-provider@workspace:^, @backstage/plugin-auth-backend-module-cloudflare-access-provider@workspace:plugins/auth-backend-module-cloudflare-access-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-cloudflare-access-provider@workspace:plugins/auth-backend-module-cloudflare-access-provider" + dependencies: + "@backstage/backend-defaults": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@backstage/types": "workspace:^" + express: ^4.18.2 + jose: ^5.0.0 + msw: ^2.0.0 + node-fetch: ^2.6.7 + node-mocks-http: ^1.0.0 + uuid: ^9.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-auth-backend-module-gcp-iap-provider@workspace:^, @backstage/plugin-auth-backend-module-gcp-iap-provider@workspace:plugins/auth-backend-module-gcp-iap-provider": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-gcp-iap-provider@workspace:plugins/auth-backend-module-gcp-iap-provider" @@ -4724,7 +4554,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@backstage/types": "workspace:^" express: ^4.18.2 - google-auth-library: ^8.0.0 + google-auth-library: ^9.0.0 languageName: unknown linkType: soft @@ -4770,12 +4600,29 @@ __metadata: "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@types/passport-google-oauth20": ^2.0.3 - google-auth-library: ^8.0.0 + google-auth-library: ^9.0.0 passport-google-oauth20: ^2.0.0 supertest: ^6.1.3 languageName: unknown linkType: soft +"@backstage/plugin-auth-backend-module-guest-provider@workspace:^, @backstage/plugin-auth-backend-module-guest-provider@workspace:plugins/auth-backend-module-guest-provider": + version: 0.0.0-use.local + resolution: "@backstage/plugin-auth-backend-module-guest-provider@workspace:plugins/auth-backend-module-guest-provider" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + express: ^4.18.2 + passport-oauth2: ^1.7.0 + languageName: unknown + linkType: soft + "@backstage/plugin-auth-backend-module-microsoft-provider@workspace:^, @backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider" @@ -4789,7 +4636,7 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@types/passport-microsoft": ^1.0.0 express: ^4.18.2 - jose: ^4.6.0 + jose: ^5.0.0 lodash: ^4.17.21 msw: ^1.0.0 node-fetch: ^2.6.7 @@ -4824,7 +4671,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" - jose: ^4.6.0 + jose: ^5.0.0 languageName: unknown linkType: soft @@ -4844,7 +4691,7 @@ __metadata: express: ^4.18.2 express-promise-router: ^4.1.1 express-session: ^1.17.3 - jose: ^4.14.6 + jose: ^5.0.0 msw: ^1.3.1 openid-client: ^5.5.0 passport: ^0.7.0 @@ -4883,7 +4730,7 @@ __metadata: cookie-parser: ^1.4.6 express: ^4.18.2 express-session: ^1.17.3 - jose: ^4.14.6 + jose: ^5.0.0 luxon: ^3.4.3 msw: ^1.3.0 openid-client: ^5.4.3 @@ -4906,7 +4753,7 @@ __metadata: "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" "@types/passport-oauth2": ^1.4.15 - jose: ^4.6.0 + jose: ^5.0.0 msw: ^2.0.8 passport-oauth2: ^1.6.1 supertest: ^6.3.3 @@ -4928,6 +4775,9 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/plugin-auth-backend-module-atlassian-provider": "workspace:^" "@backstage/plugin-auth-backend-module-aws-alb-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-bitbucket-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "workspace:^" "@backstage/plugin-auth-backend-module-gcp-iap-provider": "workspace:^" "@backstage/plugin-auth-backend-module-github-provider": "workspace:^" "@backstage/plugin-auth-backend-module-gitlab-provider": "workspace:^" @@ -4962,12 +4812,12 @@ __metadata: express-promise-router: ^4.1.0 express-session: ^1.17.1 fs-extra: ^11.2.0 - google-auth-library: ^8.0.0 - jose: ^4.6.0 + google-auth-library: ^9.0.0 + jose: ^5.0.0 knex: ^3.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - minimatch: ^5.0.0 + minimatch: ^9.0.0 morgan: ^1.10.0 msw: ^1.0.0 node-cache: ^5.1.2 @@ -4975,14 +4825,13 @@ __metadata: openid-client: ^5.2.1 passport: ^0.7.0 passport-auth0: ^1.4.3 - passport-bitbucket-oauth2: ^0.1.2 passport-github2: ^0.1.12 passport-google-oauth20: ^2.0.0 passport-microsoft: ^1.0.0 passport-oauth2: ^1.6.1 passport-onelogin-oauth: ^0.0.1 supertest: ^6.1.3 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 yn: ^4.0.0 languageName: unknown @@ -5006,251 +4855,37 @@ __metadata: cookie-parser: ^1.4.6 express: ^4.17.1 express-promise-router: ^4.1.1 - jose: ^4.6.0 + jose: ^5.0.0 lodash: ^4.17.21 msw: ^1.0.0 node-fetch: ^2.6.7 passport: ^0.7.0 supertest: ^6.1.3 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 zod: ^3.22.4 zod-to-json-schema: ^3.21.4 languageName: unknown linkType: soft -"@backstage/plugin-azure-devops-backend@workspace:^, @backstage/plugin-azure-devops-backend@workspace:plugins/azure-devops-backend": +"@backstage/plugin-auth-react@workspace:^, @backstage/plugin-auth-react@workspace:plugins/auth-react": version: 0.0.0-use.local - resolution: "@backstage/plugin-azure-devops-backend@workspace:plugins/azure-devops-backend" + resolution: "@backstage/plugin-auth-react@workspace:plugins/auth-react" dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-azure-devops-common": "workspace:^" - "@backstage/plugin-catalog-common": "workspace:^" - "@backstage/plugin-catalog-node": "workspace:^" - "@types/express": ^4.17.6 - "@types/supertest": ^2.0.8 - azure-devops-node-api: ^12.0.0 - express: ^4.17.1 - express-promise-router: ^4.1.0 - lodash: ^4.17.21 - mime-types: ^2.1.27 - p-limit: ^3.1.0 - supertest: ^6.1.6 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-azure-devops-common@workspace:^, @backstage/plugin-azure-devops-common@workspace:plugins/azure-devops-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-azure-devops-common@workspace:plugins/azure-devops-common" - dependencies: - "@backstage/cli": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-azure-devops@workspace:^, @backstage/plugin-azure-devops@workspace:plugins/azure-devops": - version: 0.0.0-use.local - resolution: "@backstage/plugin-azure-devops@workspace:plugins/azure-devops" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-compat-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/plugin-azure-devops-common": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - humanize-duration: ^3.27.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-azure-sites-backend@workspace:plugins/azure-sites-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-azure-sites-backend@workspace:plugins/azure-sites-backend" - dependencies: - "@azure/arm-appservice": ^14.0.0 - "@azure/arm-resourcegraph": ^4.2.1 - "@azure/identity": ^4.0.0 - "@backstage/backend-common": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-azure-sites-common": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - "@backstage/plugin-permission-node": "workspace:^" - "@types/express": ^4.17.6 - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - node-fetch: ^2.6.7 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-azure-sites-common@workspace:^, @backstage/plugin-azure-sites-common@workspace:plugins/azure-sites-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-azure-sites-common@workspace:plugins/azure-sites-common" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/plugin-catalog-common": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-azure-sites@workspace:^, @backstage/plugin-azure-sites@workspace:plugins/azure-sites": - version: 0.0.0-use.local - resolution: "@backstage/plugin-azure-sites@workspace:plugins/azure-sites" - dependencies: - "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-azure-sites-common": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - "@backstage/plugin-permission-react": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/test-utils": "workspace:^" - "@backstage/theme": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@material-ui/core": ^4.9.13 + "@react-hookz/web": ^24.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 + "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 msw: ^1.0.0 - react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-badges-backend@workspace:^, @backstage/plugin-badges-backend@workspace:plugins/badges-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-badges-backend@workspace:plugins/badges-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@types/express": ^4.17.6 - badge-maker: ^3.3.0 - cors: ^2.8.5 - express: ^4.17.1 - express-promise-router: ^4.1.0 - knex: ^3.0.0 - lodash: ^4.17.21 - supertest: ^6.3.3 - uuid: ^9.0.0 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-badges@workspace:^, @backstage/plugin-badges@workspace:plugins/badges": - version: 0.0.0-use.local - resolution: "@backstage/plugin-badges@workspace:plugins/badges" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-bazaar-backend@workspace:plugins/bazaar-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-bazaar-backend@workspace:plugins/bazaar-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@types/express": ^4.17.6 - express: ^4.17.1 - express-promise-router: ^4.1.0 - knex: ^3.0.0 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-bazaar@workspace:plugins/bazaar": - version: 0.0.0-use.local - resolution: "@backstage/plugin-bazaar@workspace:plugins/bazaar" - dependencies: - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@date-io/luxon": 1.x - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@material-ui/pickers": ^3.3.10 - "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - material-ui-search-bar: ^1.0.0 - react-hook-form: ^7.13.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 languageName: unknown linkType: soft @@ -5267,40 +4902,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-bitrise@workspace:plugins/bitrise": - version: 0.0.0-use.local - resolution: "@backstage/plugin-bitrise@workspace:plugins/bitrise" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/recharts": ^1.8.15 - lodash: ^4.17.21 - luxon: ^3.0.0 - msw: ^1.0.0 - qs: ^6.9.6 - react-use: ^17.2.4 - recharts: ^2.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-catalog-backend-module-aws@workspace:plugins/catalog-backend-module-aws": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-aws@workspace:plugins/catalog-backend-module-aws" @@ -5325,11 +4926,11 @@ __metadata: "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" - aws-sdk-client-mock: ^3.0.0 - aws-sdk-client-mock-jest: ^3.0.0 + aws-sdk-client-mock: ^4.0.0 + aws-sdk-client-mock-jest: ^4.0.0 luxon: ^3.0.0 p-limit: ^3.0.2 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 yaml: ^2.0.0 languageName: unknown @@ -5351,8 +4952,7 @@ __metadata: luxon: ^3.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5360,7 +4960,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-backstage-openapi@workspace:plugins/catalog-backend-module-backstage-openapi" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-openapi-utils": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" @@ -5369,14 +4968,11 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.8 cross-fetch: ^4.0.0 lodash: ^4.17.21 openapi-merge: ^1.3.2 openapi3-ts: ^3.1.2 uuid: ^9.0.0 - yn: ^4.0.0 languageName: unknown linkType: soft @@ -5396,11 +4992,11 @@ __metadata: "@backstage/plugin-bitbucket-cloud-common": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" luxon: ^3.0.0 msw: ^1.0.0 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5422,8 +5018,7 @@ __metadata: luxon: ^3.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5441,7 +5036,6 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-kubernetes-common": "workspace:^" "@google-cloud/container": ^5.0.0 - winston: ^3.2.1 languageName: unknown linkType: soft @@ -5463,8 +5057,7 @@ __metadata: luxon: ^3.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5480,6 +5073,7 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/plugin-catalog-backend-module-github": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" luxon: ^3.0.0 languageName: unknown linkType: soft @@ -5507,15 +5101,31 @@ __metadata: git-url-parse: ^14.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - minimatch: ^5.1.2 + minimatch: ^9.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft -"@backstage/plugin-catalog-backend-module-gitlab@workspace:plugins/catalog-backend-module-gitlab": +"@backstage/plugin-catalog-backend-module-gitlab-org@workspace:plugins/catalog-backend-module-gitlab-org": + version: 0.0.0-use.local + resolution: "@backstage/plugin-catalog-backend-module-gitlab-org@workspace:plugins/catalog-backend-module-gitlab-org" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-tasks": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-catalog-backend-module-gitlab": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + luxon: ^3.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-catalog-backend-module-gitlab@workspace:^, @backstage/plugin-catalog-backend-module-gitlab@workspace:plugins/catalog-backend-module-gitlab": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-gitlab@workspace:plugins/catalog-backend-module-gitlab" dependencies: @@ -5527,15 +5137,18 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/integration": "workspace:^" + "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + "@gitbeaker/rest": ^40.0.3 "@types/lodash": ^4.14.151 - "@types/uuid": ^8.0.0 + "@types/uuid": ^9.0.0 lodash: ^4.17.21 luxon: ^3.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5562,8 +5175,7 @@ __metadata: express-promise-router: ^4.1.0 knex: ^3.0.0 luxon: ^3.0.0 - uuid: ^8.3.2 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5579,11 +5191,11 @@ __metadata: "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/types": "workspace:^" - "@types/ldapjs": ^2.2.0 + "@types/ldapjs": ^2.2.5 "@types/lodash": ^4.14.151 - ldapjs: ^2.2.0 + ldapjs: ^2.3.3 lodash: ^4.17.21 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 languageName: unknown linkType: soft @@ -5611,8 +5223,7 @@ __metadata: node-fetch: ^2.6.7 p-limit: ^3.0.2 qs: ^6.9.4 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5657,8 +5268,7 @@ __metadata: luxon: ^3.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 - uuid: ^8.0.0 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -5680,10 +5290,16 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-unprocessed@workspace:plugins/catalog-backend-module-unprocessed" dependencies: + "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/errors": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-catalog-unprocessed-entities-common": "workspace:^" + "@backstage/plugin-permission-common": "workspace:^" + "@types/express": ^4.17.6 express-promise-router: ^4.1.1 knex: ^3.0.0 languageName: unknown @@ -5704,7 +5320,6 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-events-node": "workspace:^" @@ -5720,7 +5335,7 @@ __metadata: "@types/glob": ^8.0.0 "@types/lodash": ^4.14.151 "@types/supertest": ^2.0.8 - "@types/uuid": ^8.0.0 + "@types/uuid": ^9.0.0 better-sqlite3: ^9.0.0 codeowners-utils: ^1.0.2 core-js: ^3.6.5 @@ -5732,29 +5347,29 @@ __metadata: knex: ^3.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - minimatch: ^5.0.0 + minimatch: ^9.0.0 msw: ^1.0.0 node-fetch: ^2.6.7 p-limit: ^3.0.2 prom-client: ^15.0.0 supertest: ^6.1.3 - uuid: ^8.0.0 + uuid: ^9.0.0 wait-for-expect: ^3.0.2 - winston: ^3.2.1 + winston: ^3.13.0 yaml: ^2.0.0 yn: ^4.0.0 zod: ^3.22.4 languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@npm:^1.0.20": - version: 1.0.20 - resolution: "@backstage/plugin-catalog-common@npm:1.0.20" +"@backstage/plugin-catalog-common@npm:^1.0.20, @backstage/plugin-catalog-common@npm:^1.0.22": + version: 1.0.22 + resolution: "@backstage/plugin-catalog-common@npm:1.0.22" dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/plugin-permission-common": ^0.7.12 - "@backstage/plugin-search-common": ^1.2.10 - checksum: 9691e4e022d39b6e2799fe95cbf6397c2f03ff7f0ce7859bb1d90d5df91215a94ee1eed5c174aceaaf2d51d0500eb87c441ae3786a939aae602402f828349dd4 + "@backstage/catalog-model": ^1.4.5 + "@backstage/plugin-permission-common": ^0.7.13 + "@backstage/plugin-search-common": ^1.2.11 + checksum: f468ade184d5e535cc27cbb27a9dbd6cd21c1601b5a84167d2ea1004f471180ef8bf148df5561b5557c332bdc01480d020e93f62915f029cc728802cebf8e255 languageName: node linkType: hard @@ -5789,9 +5404,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 classnames: ^2.3.1 @@ -5830,9 +5445,9 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@octokit/rest": ^19.0.3 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 git-url-parse: ^14.0.0 @@ -5866,27 +5481,27 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.9.1, @backstage/plugin-catalog-react@npm:^1.9.3": - version: 1.9.3 - resolution: "@backstage/plugin-catalog-react@npm:1.9.3" +"@backstage/plugin-catalog-react@npm:^1.11.3, @backstage/plugin-catalog-react@npm:^1.9.3": + version: 1.11.3 + resolution: "@backstage/plugin-catalog-react@npm:1.11.3" dependencies: - "@backstage/catalog-client": ^1.5.2 - "@backstage/catalog-model": ^1.4.3 - "@backstage/core-components": ^0.13.10 - "@backstage/core-plugin-api": ^1.8.2 - "@backstage/errors": ^1.2.3 - "@backstage/frontend-plugin-api": ^0.5.0 - "@backstage/integration-react": ^1.1.23 - "@backstage/plugin-catalog-common": ^1.0.20 - "@backstage/plugin-permission-common": ^0.7.12 - "@backstage/plugin-permission-react": ^0.4.19 + "@backstage/catalog-client": ^1.6.4 + "@backstage/catalog-model": ^1.4.5 + "@backstage/core-components": ^0.14.4 + "@backstage/core-plugin-api": ^1.9.2 + "@backstage/errors": ^1.2.4 + "@backstage/frontend-plugin-api": ^0.6.4 + "@backstage/integration-react": ^1.1.26 + "@backstage/plugin-catalog-common": ^1.0.22 + "@backstage/plugin-permission-common": ^0.7.13 + "@backstage/plugin-permission-react": ^0.4.22 "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.7 + "@backstage/version-bridge": ^1.0.8 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^23.0.0 - "@types/react": ^16.13.1 || ^17.0.0 + "@react-hookz/web": ^24.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 classnames: ^2.2.6 lodash: ^4.17.21 material-ui-popup-state: ^1.9.3 @@ -5898,7 +5513,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 2c24a269b2718e77a73c782138c8a68fea17353b517e664ac7dc8e079f9eea6415960efc92e99d555ff749c53df2d843566ae7632581f9f5d7e247b316dd54e4 + checksum: d04919bff692094bb145d8479aae47368911f3adc92644b4742e5db1296af9a2673cf4341995b9c65e660cd608d3b59a136b9c164ab2df51bdc3ccbaf5af71fd languageName: node linkType: hard @@ -5926,9 +5541,9 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 "@types/zen-observable": ^0.8.0 @@ -5947,6 +5562,15 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-catalog-unprocessed-entities-common@workspace:^, @backstage/plugin-catalog-unprocessed-entities-common@workspace:plugins/catalog-unprocessed-entities-common": + version: 0.0.0-use.local + resolution: "@backstage/plugin-catalog-unprocessed-entities-common@workspace:plugins/catalog-unprocessed-entities-common" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/plugin-permission-common": "workspace:^" + languageName: unknown + linkType: soft + "@backstage/plugin-catalog-unprocessed-entities@workspace:^, @backstage/plugin-catalog-unprocessed-entities@workspace:plugins/catalog-unprocessed-entities": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-unprocessed-entities@workspace:plugins/catalog-unprocessed-entities" @@ -5961,7 +5585,7 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.60 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 peerDependencies: @@ -5999,10 +5623,11 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@mui/utils": ^5.14.15 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 + "@types/pluralize": ^0.0.33 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 dataloader: ^2.0.0 expiry-map: ^2.0.0 @@ -6018,224 +5643,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-cicd-statistics-module-gitlab@workspace:plugins/cicd-statistics-module-gitlab": - version: 0.0.0-use.local - resolution: "@backstage/plugin-cicd-statistics-module-gitlab@workspace:plugins/cicd-statistics-module-gitlab" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/plugin-cicd-statistics": "workspace:^" - "@gitbeaker/browser": ^35.6.0 - "@gitbeaker/core": ^35.6.0 - "@types/react": ^16.13.1 || ^17.0.0 - luxon: ^3.0.0 - p-limit: ^4.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-cicd-statistics@workspace:^, @backstage/plugin-cicd-statistics@workspace:plugins/cicd-statistics": - version: 0.0.0-use.local - resolution: "@backstage/plugin-cicd-statistics@workspace:plugins/cicd-statistics" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@date-io/luxon": ^1.3.13 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@material-ui/pickers": ^3.3.10 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - already: ^3.2.0 - humanize-duration: ^3.27.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - react-use: ^17.3.1 - recharts: ^2.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-circleci@workspace:plugins/circleci": - version: 0.0.0-use.local - resolution: "@backstage/plugin-circleci@workspace:plugins/circleci" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@types/humanize-duration": ^3.25.1 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - circleci-api: ^4.0.0 - humanize-duration: ^3.27.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-cloudbuild@workspace:^, @backstage/plugin-cloudbuild@workspace:plugins/cloudbuild": - version: 0.0.0-use.local - resolution: "@backstage/plugin-cloudbuild@workspace:plugins/cloudbuild" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - qs: ^6.9.4 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-code-climate@workspace:plugins/code-climate": - version: 0.0.0-use.local - resolution: "@backstage/plugin-code-climate@workspace:plugins/code-climate" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/humanize-duration": ^3.27.1 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - humanize-duration: ^3.27.1 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-code-coverage-backend@workspace:^, @backstage/plugin-code-coverage-backend@workspace:plugins/code-coverage-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-code-coverage-backend@workspace:plugins/code-coverage-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@types/body-parser-xml": ^2.0.2 - "@types/express": ^4.17.6 - "@types/supertest": ^2.0.8 - body-parser: ^1.20.0 - body-parser-xml: ^2.0.5 - express: ^4.17.1 - express-promise-router: ^4.1.0 - knex: ^3.0.0 - supertest: ^6.1.6 - uuid: ^8.3.2 - winston: ^3.2.1 - xml2js: ^0.6.0 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-code-coverage@workspace:^, @backstage/plugin-code-coverage@workspace:plugins/code-coverage": - version: 0.0.0-use.local - resolution: "@backstage/plugin-code-coverage@workspace:plugins/code-coverage" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@material-ui/styles": ^4.11.0 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/highlightjs": ^10.1.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/recharts": ^1.8.15 - highlight.js: ^10.6.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - recharts: ^2.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-codescene@workspace:plugins/codescene": - version: 0.0.0-use.local - resolution: "@backstage/plugin-codescene@workspace:plugins/codescene" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - rc-progress: 3.5.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-config-schema@workspace:plugins/config-schema": version: 0.0.0-use.local resolution: "@backstage/plugin-config-schema@workspace:plugins/config-schema" @@ -6249,9 +5656,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 jsonschema: ^1.2.6 react-use: ^17.2.4 @@ -6263,78 +5670,24 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-cost-insights-common@workspace:^, @backstage/plugin-cost-insights-common@workspace:plugins/cost-insights-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-cost-insights-common@workspace:plugins/cost-insights-common" - dependencies: - "@backstage/cli": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-cost-insights@workspace:^, @backstage/plugin-cost-insights@workspace:plugins/cost-insights": - version: 0.0.0-use.local - resolution: "@backstage/plugin-cost-insights@workspace:plugins/cost-insights" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-cost-insights-common": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@backstage/theme": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@material-ui/styles": ^4.9.6 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/pluralize": ^0.0.33 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/recharts": ^1.8.14 - "@types/regression": ^2.0.0 - "@types/yup": ^0.29.13 - canvas: ^2.10.2 - classnames: ^2.2.6 - history: ^5.0.0 - luxon: ^3.0.0 - pluralize: ^8.0.0 - qs: ^6.9.4 - react-use: ^17.2.4 - recharts: ^2.5.0 - regression: ^2.0.1 - yup: ^0.32.9 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-devtools-backend@workspace:^, @backstage/plugin-devtools-backend@workspace:plugins/devtools-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-devtools-backend@workspace:plugins/devtools-backend" dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@backstage/config": "workspace:^" "@backstage/config-loader": "workspace:^" "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-devtools-common": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 "@types/express": "*" - "@types/minimist": ^1.2.0 "@types/ping": ^0.4.1 "@types/supertest": ^2.0.8 "@types/yarnpkg__lockfile": ^1.1.4 @@ -6348,7 +5701,6 @@ __metadata: ping: ^0.4.1 semver: ^7.5.3 supertest: ^6.2.4 - winston: ^3.2.1 yn: ^4.0.0 languageName: unknown linkType: soft @@ -6380,7 +5732,6 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.57 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 react-json-view: ^1.21.3 react-use: ^17.2.4 peerDependencies: @@ -6391,128 +5742,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-dynatrace@workspace:^, @backstage/plugin-dynatrace@workspace:plugins/dynatrace": - version: 0.0.0-use.local - resolution: "@backstage/plugin-dynatrace@workspace:plugins/dynatrace" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - react-use: ^17.2.4 - peerDependencies: - "@backstage/plugin-catalog-react": "workspace:^" - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-entity-feedback-backend@workspace:^, @backstage/plugin-entity-feedback-backend@workspace:plugins/entity-feedback-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-entity-feedback-backend@workspace:plugins/entity-feedback-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-entity-feedback-common": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.12 - express: ^4.18.1 - express-promise-router: ^4.1.0 - knex: ^3.0.0 - node-fetch: ^2.6.7 - supertest: ^6.2.4 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-entity-feedback-common@workspace:^, @backstage/plugin-entity-feedback-common@workspace:plugins/entity-feedback-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-entity-feedback-common@workspace:plugins/entity-feedback-common" - dependencies: - "@backstage/cli": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-entity-feedback@workspace:^, @backstage/plugin-entity-feedback@workspace:plugins/entity-feedback": - version: 0.0.0-use.local - resolution: "@backstage/plugin-entity-feedback@workspace:plugins/entity-feedback" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-entity-feedback-common": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-entity-validation@workspace:plugins/entity-validation": - version: 0.0.0-use.local - resolution: "@backstage/plugin-entity-validation@workspace:plugins/entity-validation" - dependencies: - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-common": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@codemirror/language": ^6.0.0 - "@codemirror/legacy-modes": ^6.1.0 - "@codemirror/view": ^6.0.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^24.0.0 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@uiw/react-codemirror": ^4.9.3 - lodash: ^4.17.21 - react-use: ^17.2.4 - yaml: ^2.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs": version: 0.0.0-use.local resolution: "@backstage/plugin-events-backend-module-aws-sqs@workspace:plugins/events-backend-module-aws-sqs" @@ -6528,9 +5757,8 @@ __metadata: "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/types": "workspace:^" - aws-sdk-client-mock: ^3.0.0 + aws-sdk-client-mock: ^4.0.0 luxon: ^3.0.0 - winston: ^3.2.1 languageName: unknown linkType: soft @@ -6543,7 +5771,6 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" - winston: ^3.2.1 languageName: unknown linkType: soft @@ -6556,7 +5783,6 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" - winston: ^3.2.1 languageName: unknown linkType: soft @@ -6569,7 +5795,6 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" - winston: ^3.2.1 languageName: unknown linkType: soft @@ -6584,7 +5809,6 @@ __metadata: "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@octokit/webhooks-methods": ^3.0.0 - winston: ^3.2.1 languageName: unknown linkType: soft @@ -6598,7 +5822,6 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/plugin-events-backend-test-utils": "workspace:^" "@backstage/plugin-events-node": "workspace:^" - winston: ^3.2.1 languageName: unknown linkType: soft @@ -6633,489 +5856,13 @@ __metadata: "@backstage/plugin-events-node@workspace:^, @backstage/plugin-events-node@workspace:plugins/events-node": version: 0.0.0-use.local resolution: "@backstage/plugin-events-node@workspace:plugins/events-node" - dependencies: - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-explore-backend@workspace:^, @backstage/plugin-explore-backend@workspace:plugins/explore-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-explore-backend@workspace:plugins/explore-backend" dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/plugin-explore-common": "workspace:^" - "@backstage/plugin-search-backend-module-explore": "workspace:^" - "@backstage/types": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.8 - express: ^4.18.1 - express-promise-router: ^4.1.0 - lodash: ^4.17.21 - node-fetch: ^2.6.7 - supertest: ^6.2.4 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-explore-common@workspace:^, @backstage/plugin-explore-common@workspace:plugins/explore-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-explore-common@workspace:plugins/explore-common" - dependencies: "@backstage/cli": "workspace:^" languageName: unknown linkType: soft -"@backstage/plugin-explore-react@workspace:^, @backstage/plugin-explore-react@workspace:plugins/explore-react": - version: 0.0.0-use.local - resolution: "@backstage/plugin-explore-react@workspace:plugins/explore-react" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/plugin-explore-common": "workspace:^" - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-explore@workspace:^, @backstage/plugin-explore@workspace:plugins/explore": - version: 0.0.0-use.local - resolution: "@backstage/plugin-explore@workspace:plugins/explore" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/plugin-catalog": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-explore-common": "workspace:^" - "@backstage/plugin-explore-react": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" - "@backstage/plugin-search-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - classnames: ^2.2.6 - msw: ^1.0.0 - pluralize: ^8.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-firehydrant@workspace:plugins/firehydrant": - version: 0.0.0-use.local - resolution: "@backstage/plugin-firehydrant@workspace:plugins/firehydrant" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-fossa@workspace:plugins/fossa": - version: 0.0.0-use.local - resolution: "@backstage/plugin-fossa@workspace:plugins/fossa" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - cross-fetch: ^4.0.0 - luxon: ^3.0.0 - msw: ^1.0.0 - p-limit: ^3.0.2 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-gcalendar@workspace:^, @backstage/plugin-gcalendar@workspace:plugins/gcalendar": - version: 0.0.0-use.local - resolution: "@backstage/plugin-gcalendar@workspace:plugins/gcalendar" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@maxim_mazurok/gapi.client.calendar": ^3.0.20220408 - "@tanstack/react-query": ^4.1.3 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/dompurify": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/sanitize-html": ^2.6.2 - classnames: ^2.3.1 - dompurify: ^3.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - material-ui-popup-state: ^1.9.3 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-gcp-projects@workspace:^, @backstage/plugin-gcp-projects@workspace:plugins/gcp-projects": - version: 0.0.0-use.local - resolution: "@backstage/plugin-gcp-projects@workspace:plugins/gcp-projects" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@react-hookz/web": ^24.0.0 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-git-release-manager@workspace:plugins/git-release-manager": - version: 0.0.0-use.local - resolution: "@backstage/plugin-git-release-manager@workspace:plugins/git-release-manager" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/integration": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@octokit/rest": ^19.0.3 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/recharts": ^1.8.15 - luxon: ^3.0.0 - qs: ^6.10.1 - react-use: ^17.2.4 - recharts: ^2.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-github-actions@workspace:^, @backstage/plugin-github-actions@workspace:plugins/github-actions": - version: 0.0.0-use.local - resolution: "@backstage/plugin-github-actions@workspace:plugins/github-actions" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/integration-react": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@octokit/rest": ^19.0.3 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - git-url-parse: ^14.0.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-github-deployments@workspace:plugins/github-deployments": - version: 0.0.0-use.local - resolution: "@backstage/plugin-github-deployments@workspace:plugins/github-deployments" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/integration-react": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@octokit/graphql": ^5.0.0 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-github-issues@workspace:plugins/github-issues": - version: 0.0.0-use.local - resolution: "@backstage/plugin-github-issues@workspace:plugins/github-issues" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.4 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - octokit: ^3.0.0 - react-use: ^17.4.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-github-pull-requests-board@workspace:plugins/github-pull-requests-board": - version: 0.0.0-use.local - resolution: "@backstage/plugin-github-pull-requests-board@workspace:plugins/github-pull-requests-board" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@octokit/rest": ^19.0.3 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - p-limit: ^4.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-gitops-profiles@workspace:plugins/gitops-profiles": - version: 0.0.0-use.local - resolution: "@backstage/plugin-gitops-profiles@workspace:plugins/gitops-profiles" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-gocd@workspace:^, @backstage/plugin-gocd@workspace:plugins/gocd": - version: 0.0.0-use.local - resolution: "@backstage/plugin-gocd@workspace:plugins/gocd" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/lodash": ^4.14.173 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - qs: ^6.10.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-graphiql@workspace:^, @backstage/plugin-graphiql@workspace:plugins/graphiql": - version: 0.0.0-use.local - resolution: "@backstage/plugin-graphiql@workspace:plugins/graphiql" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-compat-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/codemirror": ^5.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - graphiql: ^3.0.6 - graphql: ^16.0.0 - graphql-ws: ^5.4.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-graphql-voyager@workspace:plugins/graphql-voyager": - version: 0.0.0-use.local - resolution: "@backstage/plugin-graphql-voyager@workspace:plugins/graphql-voyager" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - graphql-voyager: ^1.0.0-rc.31 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-home-react@npm:^0.1.5": - version: 0.1.7 - resolution: "@backstage/plugin-home-react@npm:0.1.7" - dependencies: - "@backstage/core-components": ^0.13.10 - "@backstage/core-plugin-api": ^1.8.2 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.15.1 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 9777b3e3d696c93f49a0e20d704826faffb3afb550975e498c034dc9b3bb1202eb1defbe8e2639f979ccba949771ecece26e15dd1aa1f0268f2c20de97b6600c - languageName: node - linkType: hard - "@backstage/plugin-home-react@workspace:^, @backstage/plugin-home-react@workspace:plugins/home-react": version: 0.0.0-use.local resolution: "@backstage/plugin-home-react@workspace:plugins/home-react" @@ -7125,7 +5872,7 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.17.0 + "@rjsf/utils": 5.18.2 "@types/react": ^16.13.1 || ^17.0.0 "@types/react-grid-layout": ^1.3.2 peerDependencies: @@ -7156,13 +5903,13 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core": 5.17.0 - "@rjsf/material-ui": 5.17.0 - "@rjsf/utils": 5.17.0 - "@rjsf/validator-ajv8": 5.17.0 - "@testing-library/dom": ^9.0.0 + "@rjsf/core": 5.18.2 + "@rjsf/material-ui": 5.18.2 + "@rjsf/utils": 5.18.2 + "@rjsf/validator-ajv8": 5.18.2 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 "@types/react-grid-layout": ^1.3.2 @@ -7179,151 +5926,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-ilert@workspace:plugins/ilert": - version: 0.0.0-use.local - resolution: "@backstage/plugin-ilert@workspace:plugins/ilert" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@date-io/luxon": 1.x - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@material-ui/pickers": ^3.3.10 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - humanize-duration: ^3.26.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-jenkins-backend@workspace:^, @backstage/plugin-jenkins-backend@workspace:plugins/jenkins-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-jenkins-backend@workspace:plugins/jenkins-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-catalog-node": "workspace:^" - "@backstage/plugin-jenkins-common": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - "@backstage/plugin-permission-node": "workspace:^" - "@types/express": ^4.17.6 - "@types/jenkins": ^1.0.0 - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - jenkins: ^1.0.0 - node-fetch: ^2.6.7 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-jenkins-common@workspace:^, @backstage/plugin-jenkins-common@workspace:plugins/jenkins-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-jenkins-common@workspace:plugins/jenkins-common" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/plugin-catalog-common": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-jenkins@workspace:^, @backstage/plugin-jenkins@workspace:plugins/jenkins": - version: 0.0.0-use.local - resolution: "@backstage/plugin-jenkins@workspace:plugins/jenkins" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-jenkins-common": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/testing-library__jest-dom": ^5.9.1 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-kafka-backend@workspace:^, @backstage/plugin-kafka-backend@workspace:plugins/kafka-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-kafka-backend@workspace:plugins/kafka-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@types/express": ^4.17.6 - "@types/jest-when": ^3.5.0 - "@types/lodash": ^4.14.151 - express: ^4.17.1 - express-promise-router: ^4.1.0 - jest-when: ^3.1.0 - kafkajs: ^2.0.0 - lodash: ^4.17.21 - supertest: ^6.1.3 - winston: ^3.2.1 - languageName: unknown - linkType: soft - -"@backstage/plugin-kafka@workspace:^, @backstage/plugin-kafka@workspace:plugins/kafka": - version: 0.0.0-use.local - resolution: "@backstage/plugin-kafka@workspace:plugins/kafka" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - jest-when: ^3.1.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-kubernetes-backend@workspace:^, @backstage/plugin-kubernetes-backend@workspace:plugins/kubernetes-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-kubernetes-backend@workspace:plugins/kubernetes-backend" @@ -7356,7 +5958,7 @@ __metadata: "@kubernetes/client-node": 0.20.0 "@types/aws4": ^1.5.1 "@types/express": ^4.17.6 - "@types/http-proxy-middleware": ^0.19.3 + "@types/http-proxy-middleware": ^1.0.0 "@types/luxon": ^3.0.0 compression: ^1.7.4 cors: ^2.8.5 @@ -7394,9 +5996,9 @@ __metadata: "@kubernetes-models/base": ^4.0.1 "@material-ui/core": ^4.12.2 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 cronstrue: ^2.2.0 @@ -7468,7 +6070,7 @@ __metadata: "@material-ui/icons": ^4.11.3 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 cronstrue: ^2.32.0 jest-websocket-mock: ^2.5.0 @@ -7503,9 +6105,9 @@ __metadata: "@kubernetes-models/base": ^4.0.1 "@kubernetes/client-node": 0.20.0 "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 cronstrue: ^2.2.0 js-yaml: ^4.0.0 @@ -7522,264 +6124,12 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-lighthouse-backend@workspace:^, @backstage/plugin-lighthouse-backend@workspace:plugins/lighthouse-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-lighthouse-backend@workspace:plugins/lighthouse-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-tasks": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/plugin-catalog-node": "workspace:^" - "@backstage/plugin-lighthouse-common": "workspace:^" - "@backstage/types": "workspace:^" - winston: ^3.2.1 - languageName: unknown - linkType: soft - -"@backstage/plugin-lighthouse-common@workspace:^, @backstage/plugin-lighthouse-common@workspace:plugins/lighthouse-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-lighthouse-common@workspace:plugins/lighthouse-common" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-lighthouse@workspace:^, @backstage/plugin-lighthouse@workspace:plugins/lighthouse": - version: 0.0.0-use.local - resolution: "@backstage/plugin-lighthouse@workspace:plugins/lighthouse" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-lighthouse-common": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-linguist-backend@workspace:^, @backstage/plugin-linguist-backend@workspace:plugins/linguist-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-linguist-backend@workspace:plugins/linguist-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-tasks": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-catalog-node": "workspace:^" - "@backstage/plugin-linguist-common": "workspace:^" - "@backstage/types": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.8 - express: ^4.18.1 - express-promise-router: ^4.1.0 - fs-extra: ^11.0.0 - js-yaml: ^4.1.0 - knex: ^3.0.0 - linguist-js: ^2.5.3 - luxon: ^2.0.2 - node-fetch: ^2.6.7 - supertest: ^6.2.4 - uuid: ^8.3.2 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-linguist-common@workspace:^, @backstage/plugin-linguist-common@workspace:plugins/linguist-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-linguist-common@workspace:plugins/linguist-common" - dependencies: - "@backstage/cli": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-linguist@workspace:^, @backstage/plugin-linguist@workspace:plugins/linguist": - version: 0.0.0-use.local - resolution: "@backstage/plugin-linguist@workspace:plugins/linguist" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-compat-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-linguist-common": "workspace:^" - "@material-ui/core": ^4.9.13 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^2.0.2 - react-use: ^17.2.4 - slugify: ^1.6.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-microsoft-calendar@workspace:^, @backstage/plugin-microsoft-calendar@workspace:plugins/microsoft-calendar": - version: 0.0.0-use.local - resolution: "@backstage/plugin-microsoft-calendar@workspace:plugins/microsoft-calendar" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@microsoft/microsoft-graph-types": ^2.25.0 - "@tanstack/react-query": ^4.1.3 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - classnames: ^2.3.1 - dompurify: ^3.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - material-ui-popup-state: ^1.9.3 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-newrelic-dashboard@workspace:^, @backstage/plugin-newrelic-dashboard@workspace:plugins/newrelic-dashboard": - version: 0.0.0-use.local - resolution: "@backstage/plugin-newrelic-dashboard@workspace:plugins/newrelic-dashboard" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-newrelic@workspace:^, @backstage/plugin-newrelic@workspace:plugins/newrelic": - version: 0.0.0-use.local - resolution: "@backstage/plugin-newrelic@workspace:plugins/newrelic" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/parse-link-header": ^2.0.1 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.2.3 - parse-link-header: ^2.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-nomad-backend@workspace:^, @backstage/plugin-nomad-backend@workspace:plugins/nomad-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-nomad-backend@workspace:plugins/nomad-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - node-fetch: ^2.6.7 - supertest: ^6.2.4 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-nomad@workspace:^, @backstage/plugin-nomad@workspace:plugins/nomad": - version: 0.0.0-use.local - resolution: "@backstage/plugin-nomad@workspace:plugins/nomad" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.9.1 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - cross-fetch: ^4.0.0 - luxon: ^3.3.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-notifications-backend@workspace:^, @backstage/plugin-notifications-backend@workspace:plugins/notifications-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-notifications-backend@workspace:plugins/notifications-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" @@ -7787,10 +6137,14 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-notifications-common": "workspace:^" "@backstage/plugin-notifications-node": "workspace:^" + "@backstage/plugin-signals-backend": "workspace:^" "@backstage/plugin-signals-node": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -7800,7 +6154,7 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.2.4 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 yn: ^4.0.0 languageName: unknown @@ -7821,6 +6175,7 @@ __metadata: dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -7829,7 +6184,7 @@ __metadata: "@backstage/test-utils": "workspace:^" knex: ^3.0.0 msw: ^1.0.0 - uuid: ^8.0.0 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -7844,6 +6199,7 @@ __metadata: "@backstage/dev-utils": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-notifications-common": "workspace:^" + "@backstage/plugin-signals": "workspace:^" "@backstage/plugin-signals-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" @@ -7852,10 +6208,12 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 + lodash: ^4.17.21 msw: ^1.0.0 + notistack: ^3.0.1 react-relative-time: ^0.0.9 react-use: ^17.2.4 peerDependencies: @@ -7864,54 +6222,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-octopus-deploy@workspace:^, @backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy": - version: 0.0.0-use.local - resolution: "@backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@material-ui/core": ^4.9.13 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-opencost@workspace:plugins/opencost": - version: 0.0.0-use.local - resolution: "@backstage/plugin-opencost@workspace:plugins/opencost" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@date-io/luxon": 1.x - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.9.1 - "@material-ui/pickers": ^3.3.10 - "@material-ui/styles": ^4.11.5 - "@testing-library/jest-dom": ^6.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - axios: ^1.4.0 - date-fns: ^3.0.0 - lodash: ^4.17.21 - recharts: ^2.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: "*" - languageName: unknown - linkType: soft - "@backstage/plugin-org-react@workspace:plugins/org-react": version: 0.0.0-use.local resolution: "@backstage/plugin-org-react@workspace:plugins/org-react" @@ -7927,9 +6237,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 @@ -7963,9 +6273,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 lodash: ^4.17.21 @@ -7980,80 +6290,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-pagerduty@workspace:^, @backstage/plugin-pagerduty@workspace:plugins/pagerduty": - version: 0.0.0-use.local - resolution: "@backstage/plugin-pagerduty@workspace:plugins/pagerduty" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-home-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-periskop-backend@workspace:plugins/periskop-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-periskop-backend@workspace:plugins/periskop-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - node-fetch: ^2.6.7 - supertest: ^6.1.6 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-periskop@workspace:plugins/periskop": - version: 0.0.0-use.local - resolution: "@backstage/plugin-periskop@workspace:plugins/periskop" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-permission-backend-module-allow-all-policy@workspace:^, @backstage/plugin-permission-backend-module-allow-all-policy@workspace:plugins/permission-backend-module-policy-allow-all": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-backend-module-allow-all-policy@workspace:plugins/permission-backend-module-policy-allow-all" @@ -8073,6 +6309,7 @@ __metadata: dependencies: "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" @@ -8089,13 +6326,12 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.1.6 - winston: ^3.2.1 yn: ^4.0.0 zod: ^3.22.4 languageName: unknown linkType: soft -"@backstage/plugin-permission-common@^0.7.12, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@^0.7.13, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -8105,7 +6341,7 @@ __metadata: "@backstage/types": "workspace:^" cross-fetch: ^4.0.0 msw: ^1.0.0 - uuid: ^8.0.0 + uuid: ^9.0.0 zod: ^3.22.4 languageName: unknown linkType: soft @@ -8133,24 +6369,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@npm:^0.4.19": - version: 0.4.19 - resolution: "@backstage/plugin-permission-react@npm:0.4.19" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.2 - "@backstage/plugin-permission-common": ^0.7.12 - "@types/react": ^16.13.1 || ^17.0.0 - swr: ^2.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 256ea54e395faeacb827d3e691dfd584e9f863c4a97af34468b3a49d252506e2d6f5672c011f8d05725374fa11f98ce50ed359c6c078855f13b5cce2e6a52bc7 - languageName: node - linkType: hard - -"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@^0.4.22, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -8160,7 +6379,7 @@ __metadata: "@backstage/plugin-permission-common": "workspace:^" "@backstage/test-utils": "workspace:^" "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 swr: ^2.0.0 peerDependencies: @@ -8170,85 +6389,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-playlist-backend@workspace:^, @backstage/plugin-playlist-backend@workspace:plugins/playlist-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-playlist-backend@workspace:plugins/playlist-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - "@backstage/plugin-permission-node": "workspace:^" - "@backstage/plugin-playlist-common": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - knex: ^3.0.0 - node-fetch: ^2.6.7 - supertest: ^6.1.3 - uuid: ^8.2.0 - winston: ^3.2.1 - yn: ^4.0.0 - zod: ^3.22.4 - languageName: unknown - linkType: soft - -"@backstage/plugin-playlist-common@workspace:^, @backstage/plugin-playlist-common@workspace:plugins/playlist-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-playlist-common@workspace:plugins/playlist-common" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-playlist@workspace:^, @backstage/plugin-playlist@workspace:plugins/playlist": - version: 0.0.0-use.local - resolution: "@backstage/plugin-playlist@workspace:plugins/playlist" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-common": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-permission-common": "workspace:^" - "@backstage/plugin-permission-react": "workspace:^" - "@backstage/plugin-playlist-common": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" - "@backstage/plugin-search-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - lodash: ^4.17.21 - msw: ^1.0.0 - pluralize: ^8.0.0 - qs: ^6.9.4 - react-hook-form: ^7.13.0 - react-use: ^17.2.4 - swr: ^2.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-proxy-backend@workspace:^, @backstage/plugin-proxy-backend@workspace:plugins/proxy-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-proxy-backend@workspace:plugins/proxy-backend" @@ -8260,99 +6400,21 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/config-loader": "workspace:^" "@types/express": ^4.17.6 - "@types/http-proxy-middleware": ^0.19.3 + "@types/http-proxy-middleware": ^1.0.0 "@types/supertest": ^2.0.8 - "@types/uuid": ^8.0.0 - "@types/yup": ^0.29.13 + "@types/uuid": ^9.0.0 + "@types/yup": ^0.32.0 express: ^4.17.1 express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.0 morgan: ^1.10.0 msw: ^1.0.0 supertest: ^6.1.3 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 yaml: ^2.0.0 yn: ^4.0.0 - yup: ^0.32.9 - languageName: unknown - linkType: soft - -"@backstage/plugin-puppetdb@workspace:^, @backstage/plugin-puppetdb@workspace:plugins/puppetdb": - version: 0.0.0-use.local - resolution: "@backstage/plugin-puppetdb@workspace:plugins/puppetdb" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-rollbar-backend@workspace:^, @backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@types/express": ^4.17.6 - "@types/supertest": ^2.0.8 - compression: ^1.7.4 - cors: ^2.8.5 - express: ^4.17.1 - express-promise-router: ^4.1.0 - fs-extra: ^11.2.0 - lodash: ^4.17.21 - morgan: ^1.10.0 - msw: ^1.0.0 - node-fetch: ^2.6.7 - supertest: ^6.1.3 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-rollbar@workspace:^, @backstage/plugin-rollbar@workspace:plugins/rollbar": - version: 0.0.0-use.local - resolution: "@backstage/plugin-rollbar@workspace:plugins/rollbar" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - lodash: ^4.17.21 - react-sparklines: ^1.7.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 + yup: ^1.0.0 languageName: unknown linkType: soft @@ -8360,13 +6422,13 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-azure@workspace:plugins/scaffolder-backend-module-azure" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" azure-devops-node-api: ^12.0.0 yaml: ^2.0.0 languageName: unknown @@ -8376,7 +6438,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@workspace:plugins/scaffolder-backend-module-bitbucket-cloud" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -8384,6 +6445,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 msw: ^1.0.0 node-fetch: ^2.6.7 @@ -8395,7 +6457,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-server@workspace:plugins/scaffolder-backend-module-bitbucket-server" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -8403,6 +6464,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 msw: ^1.0.0 node-fetch: ^2.6.7 @@ -8414,7 +6476,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket@workspace:plugins/scaffolder-backend-module-bitbucket" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -8424,6 +6485,7 @@ __metadata: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "workspace:^" "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 msw: ^1.0.0 node-fetch: ^2.6.7 @@ -8443,6 +6505,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 git-url-parse: ^14.0.0 msw: ^1.0.0 @@ -8464,6 +6527,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" "@types/command-exists": ^1.2.0 "@types/fs-extra": ^11.0.0 @@ -8478,7 +6542,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-gerrit@workspace:plugins/scaffolder-backend-module-gerrit" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -8486,6 +6549,25 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" + msw: ^1.0.0 + node-fetch: ^2.6.7 + yaml: ^2.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-scaffolder-backend-module-gitea@workspace:^, @backstage/plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-gitea@workspace:plugins/scaffolder-backend-module-gitea" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/integration": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" msw: ^1.0.0 node-fetch: ^2.6.7 yaml: ^2.0.0 @@ -8504,15 +6586,14 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@octokit/webhooks": ^10.0.0 "@types/libsodium-wrappers": ^0.7.10 fs-extra: ^11.2.0 - jest-when: ^3.1.0 jsonschema: ^1.2.6 libsodium-wrappers: ^0.7.11 octokit: ^3.0.0 - octokit-plugin-create-pull-request: ^3.10.0 - winston: ^3.2.1 + octokit-plugin-create-pull-request: ^5.0.0 yaml: ^2.0.0 languageName: unknown linkType: soft @@ -8530,10 +6611,10 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@gitbeaker/core": ^35.8.0 "@gitbeaker/node": ^35.8.0 "@gitbeaker/rest": ^39.25.0 - jest-date-mock: ^1.0.8 luxon: ^3.0.0 yaml: ^2.0.0 zod: ^3.22.4 @@ -8552,6 +6633,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" "@types/command-exists": ^1.2.0 "@types/fs-extra": ^11.0.0 @@ -8572,6 +6654,7 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" msw: ^2.0.0 yaml: ^2.3.3 @@ -8586,8 +6669,10 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" winston: ^3.2.1 + yaml: ^2.0.0 yeoman-environment: ^3.9.1 languageName: unknown linkType: soft @@ -8616,10 +6701,12 @@ __metadata: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "workspace:^" "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^" "@backstage/plugin-scaffolder-backend-module-gerrit": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-gitea": "workspace:^" "@backstage/plugin-scaffolder-backend-module-github": "workspace:^" "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^" "@backstage/plugin-scaffolder-common": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" "@backstage/types": "workspace:^" "@types/express": ^4.17.6 "@types/fs-extra": ^11.0.0 @@ -8637,6 +6724,7 @@ __metadata: jsonschema: ^1.2.6 knex: ^3.0.0 lodash: ^4.17.21 + logform: ^2.3.2 luxon: ^3.0.0 nunjucks: ^3.2.3 p-limit: ^3.1.0 @@ -8644,9 +6732,10 @@ __metadata: prom-client: ^15.0.0 strip-ansi: ^7.1.0 supertest: ^6.1.3 - uuid: ^8.2.0 + uuid: ^9.0.0 wait-for-expect: ^3.0.2 winston: ^3.2.1 + winston-transport: ^4.7.0 yaml: ^2.0.0 zen-observable: ^0.10.0 zod: ^3.22.4 @@ -8664,6 +6753,19 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-scaffolder-node-test-utils@workspace:^, @backstage/plugin-scaffolder-node-test-utils@workspace:plugins/scaffolder-node-test-utils": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-node-test-utils@workspace:plugins/scaffolder-node-test-utils" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-scaffolder-node": "workspace:^" + "@backstage/types": "workspace:^" + "@types/react": "*" + languageName: unknown + linkType: soft + "@backstage/plugin-scaffolder-node@workspace:^, @backstage/plugin-scaffolder-node@workspace:plugins/scaffolder-node": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-node@workspace:plugins/scaffolder-node" @@ -8710,24 +6812,23 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.17.0 - "@rjsf/material-ui": 5.17.0 - "@rjsf/utils": 5.17.0 - "@rjsf/validator-ajv8": 5.17.0 - "@testing-library/dom": ^9.0.0 + "@rjsf/core": 5.18.2 + "@rjsf/material-ui": 5.18.2 + "@rjsf/utils": 5.18.2 + "@rjsf/validator-ajv8": 5.18.2 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 "@types/luxon": ^3.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 classnames: ^2.2.6 - flatted: 3.2.9 + flatted: 3.3.1 humanize-duration: ^3.25.1 - immer: ^9.0.1 json-schema: ^0.4.0 - json-schema-library: ^7.3.9 + json-schema-library: ^9.0.0 lodash: ^4.17.21 luxon: ^3.0.0 qs: ^6.9.4 @@ -8774,13 +6875,13 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.17.0 - "@rjsf/material-ui": 5.17.0 - "@rjsf/utils": 5.17.0 - "@rjsf/validator-ajv8": 5.17.0 - "@testing-library/dom": ^9.0.0 + "@rjsf/core": 5.18.2 + "@rjsf/material-ui": 5.18.2 + "@rjsf/utils": 5.18.2 + "@rjsf/validator-ajv8": 5.18.2 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 @@ -8790,9 +6891,8 @@ __metadata: event-source-polyfill: ^1.0.31 git-url-parse: ^14.0.0 humanize-duration: ^3.25.1 - immer: ^9.0.1 json-schema: ^0.4.0 - json-schema-library: ^7.3.9 + json-schema-library: ^9.0.0 jszip: ^3.10.1 lodash: ^4.17.21 luxon: ^3.0.0 @@ -8850,7 +6950,7 @@ __metadata: aws4: ^1.12.0 elastic-builder: ^2.16.0 lodash: ^4.17.21 - uuid: ^8.3.2 + uuid: ^9.0.0 winston: ^3.2.1 languageName: unknown linkType: soft @@ -8859,18 +6959,17 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-explore@workspace:plugins/search-backend-module-explore" dependencies: + "@backstage-community/plugin-explore-common": ^0.0.3 "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" - "@backstage/plugin-explore-common": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" msw: ^1.2.1 node-fetch: ^2.6.7 - winston: ^3.2.1 languageName: unknown linkType: soft @@ -8887,12 +6986,12 @@ __metadata: "@backstage/plugin-search-common": "workspace:^" knex: ^3.0.0 lodash: ^4.17.21 - uuid: ^8.3.2 + uuid: ^9.0.0 winston: ^3.2.1 languageName: unknown linkType: soft -"@backstage/plugin-search-backend-module-stack-overflow-collator@workspace:^, @backstage/plugin-search-backend-module-stack-overflow-collator@workspace:plugins/search-backend-module-stack-overflow-collator": +"@backstage/plugin-search-backend-module-stack-overflow-collator@workspace:plugins/search-backend-module-stack-overflow-collator": version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-stack-overflow-collator@workspace:plugins/search-backend-module-stack-overflow-collator" dependencies: @@ -8907,7 +7006,6 @@ __metadata: msw: ^1.2.1 node-fetch: ^2.6.7 qs: ^6.9.4 - winston: ^3.2.1 languageName: unknown linkType: soft @@ -8933,7 +7031,6 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.6.7 p-limit: ^3.1.0 - winston: ^3.2.1 languageName: unknown linkType: soft @@ -8954,8 +7051,7 @@ __metadata: lodash: ^4.17.21 lunr: ^2.3.9 ndjson: ^2.0.0 - uuid: ^8.3.2 - winston: ^3.2.1 + uuid: ^9.0.0 languageName: unknown linkType: soft @@ -8970,11 +7066,11 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" - "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" + "@backstage/repo-tools": "workspace:^" "@backstage/types": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 @@ -8989,7 +7085,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-common@^1.2.10, @backstage/plugin-search-common@workspace:^, @backstage/plugin-search-common@workspace:plugins/search-common": +"@backstage/plugin-search-common@^1.2.11, @backstage/plugin-search-common@workspace:^, @backstage/plugin-search-common@workspace:plugins/search-common": version: 0.0.0-use.local resolution: "@backstage/plugin-search-common@workspace:plugins/search-common" dependencies: @@ -9018,9 +7114,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 lodash: ^4.17.21 @@ -9053,9 +7149,9 @@ __metadata: "@backstage/version-bridge": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 history: ^5.0.0 @@ -9068,73 +7164,19 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-sentry@workspace:^, @backstage/plugin-sentry@workspace:plugins/sentry": - version: 0.0.0-use.local - resolution: "@backstage/plugin-sentry@workspace:plugins/sentry" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - react-sparklines: ^1.7.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-shortcuts@workspace:^, @backstage/plugin-shortcuts@workspace:plugins/shortcuts": - version: 0.0.0-use.local - resolution: "@backstage/plugin-shortcuts@workspace:plugins/shortcuts" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@backstage/theme": "workspace:^" - "@backstage/types": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/zen-observable": ^0.8.2 - react-hook-form: ^7.12.2 - react-use: ^17.2.4 - uuid: ^8.3.2 - zen-observable: ^0.10.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-signals-backend@workspace:^, @backstage/plugin-signals-backend@workspace:plugins/signals-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-signals-backend@workspace:plugins/signals-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-signals-node": "workspace:^" "@backstage/types": "workspace:^" @@ -9146,7 +7188,7 @@ __metadata: msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.2.4 - uuid: ^8.0.0 + uuid: ^9.0.0 winston: ^3.2.1 ws: ^8.14.2 yn: ^4.0.0 @@ -9166,7 +7208,7 @@ __metadata: "@backstage/types": "workspace:^" "@types/express": ^4.17.21 express: ^4.17.1 - uuid: ^8.0.0 + uuid: ^9.0.0 ws: ^8.14.2 languageName: unknown linkType: soft @@ -9181,7 +7223,7 @@ __metadata: "@backstage/types": "workspace:^" "@material-ui/core": ^4.12.4 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 languageName: unknown @@ -9204,328 +7246,17 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 jest-websocket-mock: ^2.5.0 msw: ^1.0.0 react-use: ^17.2.4 - uuid: ^8.0.0 + uuid: ^9.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 languageName: unknown linkType: soft -"@backstage/plugin-sonarqube-backend@workspace:^, @backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@types/express": "*" - "@types/supertest": ^2.0.12 - express: ^4.18.1 - express-promise-router: ^4.1.0 - msw: ^1.0.0 - node-fetch: ^2.6.7 - supertest: ^6.2.4 - winston: ^3.2.1 - yn: ^5.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-sonarqube-react@workspace:^, @backstage/plugin-sonarqube-react@workspace:plugins/sonarqube-react": - version: 0.0.0-use.local - resolution: "@backstage/plugin-sonarqube-react@workspace:plugins/sonarqube-react" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-sonarqube@workspace:plugins/sonarqube": - version: 0.0.0-use.local - resolution: "@backstage/plugin-sonarqube@workspace:plugins/sonarqube" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-sonarqube-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/styles": ^4.10.0 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - cross-fetch: ^4.0.0 - luxon: ^3.0.0 - msw: ^1.0.0 - rc-progress: 3.5.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-splunk-on-call@workspace:plugins/splunk-on-call": - version: 0.0.0-use.local - resolution: "@backstage/plugin-splunk-on-call@workspace:plugins/splunk-on-call" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-stack-overflow-backend@workspace:plugins/stack-overflow-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-stack-overflow-backend@workspace:plugins/stack-overflow-backend" - dependencies: - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/plugin-search-backend-module-stack-overflow-collator": "workspace:^" - node-fetch: ^2.6.7 - qs: ^6.9.4 - winston: ^3.2.1 - languageName: unknown - linkType: soft - -"@backstage/plugin-stack-overflow@workspace:^, @backstage/plugin-stack-overflow@workspace:plugins/stack-overflow": - version: 0.0.0-use.local - resolution: "@backstage/plugin-stack-overflow@workspace:plugins/stack-overflow" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/plugin-home-react": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" - "@backstage/plugin-search-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - cross-fetch: ^4.0.0 - lodash: ^4.17.21 - msw: ^1.0.0 - qs: ^6.9.4 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-stackstorm@workspace:^, @backstage/plugin-stackstorm@workspace:plugins/stackstorm": - version: 0.0.0-use.local - resolution: "@backstage/plugin-stackstorm@workspace:plugins/stackstorm" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-tech-insights-backend-module-jsonfc@workspace:^, @backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc": - version: 0.0.0-use.local - resolution: "@backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-tech-insights-common": "workspace:^" - "@backstage/plugin-tech-insights-node": "workspace:^" - "@backstage/types": "workspace:^" - ajv: ^8.10.0 - json-rules-engine: ^6.1.2 - lodash: ^4.17.21 - luxon: ^3.0.0 - winston: ^3.2.1 - languageName: unknown - linkType: soft - -"@backstage/plugin-tech-insights-backend@workspace:^, @backstage/plugin-tech-insights-backend@workspace:plugins/tech-insights-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-tech-insights-backend@workspace:plugins/tech-insights-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-tasks": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-tech-insights-common": "workspace:^" - "@backstage/plugin-tech-insights-node": "workspace:^" - "@backstage/types": "workspace:^" - "@types/express": ^4.17.6 - "@types/luxon": ^3.0.0 - "@types/semver": ^7.3.8 - "@types/supertest": ^2.0.8 - express: ^4.17.1 - express-promise-router: ^4.1.0 - knex: ^3.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - semver: ^7.5.3 - supertest: ^6.1.3 - uuid: ^8.3.2 - wait-for-expect: ^3.0.2 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-tech-insights-common@workspace:^, @backstage/plugin-tech-insights-common@workspace:plugins/tech-insights-common": - version: 0.0.0-use.local - resolution: "@backstage/plugin-tech-insights-common@workspace:plugins/tech-insights-common" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/types": "workspace:^" - "@types/luxon": ^3.0.0 - luxon: ^3.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-tech-insights-node@workspace:^, @backstage/plugin-tech-insights-node@workspace:plugins/tech-insights-node": - version: 0.0.0-use.local - resolution: "@backstage/plugin-tech-insights-node@workspace:plugins/tech-insights-node" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/plugin-tech-insights-common": "workspace:^" - "@backstage/types": "workspace:^" - "@types/luxon": ^3.0.0 - luxon: ^3.0.0 - winston: ^3.2.1 - languageName: unknown - linkType: soft - -"@backstage/plugin-tech-insights@workspace:^, @backstage/plugin-tech-insights@workspace:plugins/tech-insights": - version: 0.0.0-use.local - resolution: "@backstage/plugin-tech-insights@workspace:plugins/tech-insights" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/plugin-tech-insights-common": "workspace:^" - "@backstage/types": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - qs: ^6.9.4 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-tech-radar@workspace:^, @backstage/plugin-tech-radar@workspace:plugins/tech-radar": - version: 0.0.0-use.local - resolution: "@backstage/plugin-tech-radar@workspace:plugins/tech-radar" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-compat-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/frontend-plugin-api": "workspace:^" - "@backstage/frontend-test-utils": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/color": ^3.0.1 - "@types/d3-force": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - color: ^4.0.1 - d3-force: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-techdocs-addons-test-utils@workspace:^, @backstage/plugin-techdocs-addons-test-utils@workspace:plugins/techdocs-addons-test-utils": version: 0.0.0-use.local resolution: "@backstage/plugin-techdocs-addons-test-utils@workspace:plugins/techdocs-addons-test-utils" @@ -9540,12 +7271,12 @@ __metadata: "@backstage/plugin-techdocs": "workspace:^" "@backstage/plugin-techdocs-react": "workspace:^" "@backstage/test-utils": "workspace:^" - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 testing-library__dom: ^7.29.4-beta.1 peerDependencies: - "@testing-library/react": ^12.1.3 || ^13.0.0 || ^14.0.0 + "@testing-library/react": ^15.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 @@ -9600,9 +7331,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@react-hookz/web": ^24.0.0 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 git-url-parse: ^14.0.0 photoswipe: ^5.3.7 @@ -9642,7 +7373,7 @@ __metadata: "@types/mime-types": ^2.1.0 "@types/recursive-readdir": ^2.2.0 "@types/supertest": ^2.0.8 - aws-sdk-client-mock: ^3.0.0 + aws-sdk-client-mock: ^4.0.0 express: ^4.17.1 fs-extra: ^11.2.0 git-url-parse: ^14.0.0 @@ -9672,7 +7403,7 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/styles": ^4.11.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 jss: ~10.10.0 lodash: ^4.17.21 @@ -9701,6 +7432,7 @@ __metadata: "@backstage/frontend-plugin-api": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/integration-react": "workspace:^" + "@backstage/plugin-auth-react": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-search-react": "workspace:^" @@ -9712,9 +7444,9 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@material-ui/styles": ^4.10.0 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/dompurify": ^3.0.0 "@types/event-source-polyfill": ^1.0.0 @@ -9734,55 +7466,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-todo-backend@workspace:^, @backstage/plugin-todo-backend@workspace:plugins/todo-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-todo-backend@workspace:plugins/todo-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-openapi-utils": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/catalog-client": "workspace:^" - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/integration": "workspace:^" - "@backstage/plugin-catalog-node": "workspace:^" - "@backstage/repo-tools": "workspace:^" - "@types/express": ^4.17.6 - "@types/supertest": ^2.0.8 - express: ^4.17.1 - leasot: ^12.0.0 - supertest: ^6.1.3 - winston: ^3.2.1 - yn: ^4.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-todo@workspace:^, @backstage/plugin-todo@workspace:plugins/todo": - version: 0.0.0-use.local - resolution: "@backstage/plugin-todo@workspace:plugins/todo" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/plugin-user-settings-backend@workspace:plugins/user-settings-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-user-settings-backend@workspace:plugins/user-settings-backend" @@ -9826,9 +7509,9 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 msw: ^1.0.0 @@ -9841,103 +7524,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-vault-backend@workspace:plugins/vault-backend": - version: 0.0.0-use.local - resolution: "@backstage/plugin-vault-backend@workspace:plugins/vault-backend" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-tasks": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-vault-node": "workspace:^" - "@types/compression": ^1.7.2 - "@types/express": "*" - "@types/supertest": ^2.0.8 - compression: ^1.7.4 - cors: ^2.8.5 - express: ^4.17.1 - express-promise-router: ^4.1.0 - helmet: ^6.0.0 - msw: ^1.0.0 - node-fetch: ^2.6.7 - p-limit: ^3.1.0 - supertest: ^6.1.6 - winston: ^3.2.1 - yn: ^5.0.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-vault-node@workspace:^, @backstage/plugin-vault-node@workspace:plugins/vault-node": - version: 0.0.0-use.local - resolution: "@backstage/plugin-vault-node@workspace:plugins/vault-node" - dependencies: - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/cli": "workspace:^" - languageName: unknown - linkType: soft - -"@backstage/plugin-vault@workspace:plugins/vault": - version: 0.0.0-use.local - resolution: "@backstage/plugin-vault@workspace:plugins/vault" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - msw: ^1.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - -"@backstage/plugin-xcmetrics@workspace:plugins/xcmetrics": - version: 0.0.0-use.local - resolution: "@backstage/plugin-xcmetrics@workspace:plugins/xcmetrics" - dependencies: - "@backstage/cli": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/dev-utils": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/test-utils": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 - "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 - "@testing-library/user-event": ^14.0.0 - "@types/luxon": ^3.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - react-use: ^17.2.4 - recharts: ^2.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - languageName: unknown - linkType: soft - "@backstage/release-manifests@workspace:^, @backstage/release-manifests@workspace:packages/release-manifests": version: 0.0.0-use.local resolution: "@backstage/release-manifests@workspace:packages/release-manifests" @@ -9961,6 +7547,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@backstage/cli-node": "workspace:^" + "@backstage/config-loader": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 @@ -9979,16 +7566,16 @@ __metadata: "@types/prettier": ^2.0.0 chalk: ^4.0.0 codeowners-utils: ^1.0.2 + command-exists: ^1.2.9 commander: ^12.0.0 fs-extra: ^11.2.0 glob: ^8.0.3 is-glob: ^4.0.3 js-yaml: ^4.1.0 lodash: ^4.17.21 - minimatch: ^5.1.1 + minimatch: ^9.0.0 p-limit: ^3.0.2 portfinder: ^1.0.32 - ts-node: ^10.0.0 yaml-diff-patch: ^2.0.0 peerDependencies: "@microsoft/api-extractor-model": "*" @@ -10026,42 +7613,26 @@ __metadata: msw: ^1.0.0 zen-observable: ^0.10.0 peerDependencies: - "@testing-library/react": ^12.1.3 || ^13.0.0 || ^14.0.0 + "@testing-library/react": ^15.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 languageName: unknown linkType: soft -"@backstage/theme@npm:^0.4.4": - version: 0.4.4 - resolution: "@backstage/theme@npm:0.4.4" +"@backstage/theme@npm:^0.5.0, @backstage/theme@npm:^0.5.3": + version: 0.5.3 + resolution: "@backstage/theme@npm:0.5.3" dependencies: "@emotion/react": ^11.10.5 "@emotion/styled": ^11.10.5 "@mui/material": ^5.12.2 peerDependencies: "@material-ui/core": ^4.12.2 - "@types/react": ^16.13.1 || ^17.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 562ce0f0fd07202b44971b55bba9c39cd13c91a65873034d2e68fb5833c0d9882c2fd967d6c779a8563618ce035ec159823c865b0163911b7004f1bfce3ce4a1 - languageName: node - linkType: hard - -"@backstage/theme@npm:^0.5.0": - version: 0.5.0 - resolution: "@backstage/theme@npm:0.5.0" - dependencies: - "@emotion/react": ^11.10.5 - "@emotion/styled": ^11.10.5 - "@mui/material": ^5.12.2 - peerDependencies: - "@material-ui/core": ^4.12.2 - "@types/react": ^16.13.1 || ^17.0.0 - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: b3f7ebb3d37daa72ea41ff2cd2bc01df2fcdacf411576e28c8a8b8c9c656c3c2f7e1ce6e82d00add10aecbcaf58f6024cc87a47986618d61eb8b95ec85464d37 + checksum: ac6c3bbd73294385f73aa91e04f8bf3a1bb78cadc0e43034760ebf19e86814ed2d679f2641bb086aa9e305a24d923d8c3480b2de3bff55189c19bc5dfdce1814 languageName: node linkType: hard @@ -10075,7 +7646,7 @@ __metadata: "@mui/material": ^5.12.2 "@mui/styles": ^5.14.18 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: "@material-ui/core": ^4.12.2 @@ -10096,13 +7667,13 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@^1.0.8, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: "@backstage/cli": "workspace:^" "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -10125,10 +7696,10 @@ __metadata: languageName: node linkType: hard -"@braintree/sanitize-url@npm:=7.0.0": - version: 7.0.0 - resolution: "@braintree/sanitize-url@npm:7.0.0" - checksum: 2ca9c617343d00c668486f5382cd6ef7d0bd54ba6c8d40deb0f3e7843390a056cf0c590f1d06d38a49b7d8b3f63c006f89873944996742835f2b523b707913a0 +"@braintree/sanitize-url@npm:=7.0.1": + version: 7.0.1 + resolution: "@braintree/sanitize-url@npm:7.0.1" + checksum: 793a3b01c5e06152b197c73cccee2db99e921b36d944fc0738e732b5da068709da8844eb8e1489ea360c34b00a100c8b9b3065d5e2030ba5252cdd5d2a6a9a28 languageName: node linkType: hard @@ -10385,32 +7956,6 @@ __metadata: languageName: node linkType: hard -"@circleci/backstage-plugin@npm:^0.1.1": - version: 0.1.1 - resolution: "@circleci/backstage-plugin@npm:0.1.1" - dependencies: - "@backstage/catalog-model": "workspace:^" - "@backstage/core-components": "workspace:^" - "@backstage/core-plugin-api": "workspace:^" - "@backstage/plugin-catalog-react": "workspace:^" - "@backstage/theme": "workspace:^" - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@types/react": ^16.13.1 || ^17.0.0 - circleci-api: ^4.0.0 - humanize-duration: ^3.27.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: ded80e2eef1cec3f83f76e62b1362499c1662ae6307bdc829b78aed02101af6fd85134d94716fbbb60e8a0d5b3d2a4653df81fbdfcab576a47f7b59a332e580f - languageName: node - linkType: hard - "@codemirror/autocomplete@npm:^6.0.0": version: 6.3.0 resolution: "@codemirror/autocomplete@npm:6.3.0" @@ -10455,11 +8000,11 @@ __metadata: linkType: hard "@codemirror/legacy-modes@npm:^6.1.0": - version: 6.3.3 - resolution: "@codemirror/legacy-modes@npm:6.3.3" + version: 6.4.0 + resolution: "@codemirror/legacy-modes@npm:6.4.0" dependencies: "@codemirror/language": ^6.0.0 - checksum: 3cd32b0f011b0a193e0948e5901b625f38aa6d9a8b24344531d6e142eb6fbb3e6cb5969429102044f3d04fbe53c4deaebd9f659c05067a0b18d17766290c9e05 + checksum: d382aa6f640a67418bd209e1e4b395340f96aac1b0cf185927fc2c7f98b62cfd0c59ef0f7048148ce8771622003ca844c78c2d18548235ecc57d0bcbfbbfe091 languageName: node linkType: hard @@ -10505,13 +8050,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.23.0": - version: 6.24.0 - resolution: "@codemirror/view@npm:6.24.0" + version: 6.26.3 + resolution: "@codemirror/view@npm:6.26.3" dependencies: "@codemirror/state": ^6.4.0 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: c594f7628074d6f1a87636bb1281d1a1b579d0d73df4f8e04972eb7aca53de9c98f45e585d059f682920a89fa68dcad85a1418df90c28a746ae52aa06cdd0b8f + checksum: fdee35fb5e0bbba7b6f1a9b43a865880911bbfafd30360da5dda21b35f81ba2d080ff66b6c3d94dbe946b6b7ec98a76208786360b8f030ef10bcb054b816de05 languageName: node linkType: hard @@ -10549,13 +8094,6 @@ __metadata: languageName: node linkType: hard -"@date-io/core@npm:2.10.7": - version: 2.10.7 - resolution: "@date-io/core@npm:2.10.7" - checksum: 0d8b047e600296ffe31f83a6785d8a80ffbc2de1b536ce0349275c383b4cc30f62316e88ee6da21d39b8081a1d8fe2f698e7ec78927458603fdc47ec2fc64e25 - languageName: node - linkType: hard - "@date-io/date-fns@npm:^1.3.13": version: 1.3.13 resolution: "@date-io/date-fns@npm:1.3.13" @@ -10567,17 +8105,6 @@ __metadata: languageName: node linkType: hard -"@date-io/luxon@npm:1.x, @date-io/luxon@npm:^1.3.13": - version: 1.3.13 - resolution: "@date-io/luxon@npm:1.3.13" - dependencies: - "@date-io/core": ^1.3.13 - peerDependencies: - luxon: ^1.21.3 - checksum: 7dd18ef11ea14111595d8836247ffe756889bd31309796fd98f3bf05b5aaf25f63e8574280d35ae1f511ba11ba6903accc4a584b7103b8affd626b79ab69b056 - languageName: node - linkType: hard - "@davidzemon/passport-okta-oauth@npm:^0.0.5": version: 0.0.5 resolution: "@davidzemon/passport-okta-oauth@npm:0.0.5" @@ -10668,12 +8195,12 @@ __metadata: languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.1": - version: 1.2.1 - resolution: "@emotion/is-prop-valid@npm:1.2.1" +"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.2": + version: 1.2.2 + resolution: "@emotion/is-prop-valid@npm:1.2.2" dependencies: "@emotion/memoize": ^0.8.1 - checksum: 8f42dc573a3fad79b021479becb639b8fe3b60bdd1081a775d32388bca418ee53074c7602a4c845c5f75fa6831eb1cbdc4d208cc0299f57014ed3a02abcad16a + checksum: 61f6b128ea62b9f76b47955057d5d86fcbe2a6989d2cd1e583daac592901a950475a37d049b9f7a7c6aa8758a33b408735db759fdedfd1f629df0f85ab60ea25 languageName: node linkType: hard @@ -10692,8 +8219,8 @@ __metadata: linkType: hard "@emotion/react@npm:^11.10.5": - version: 11.11.3 - resolution: "@emotion/react@npm:11.11.3" + version: 11.11.4 + resolution: "@emotion/react@npm:11.11.4" dependencies: "@babel/runtime": ^7.18.3 "@emotion/babel-plugin": ^11.11.0 @@ -10708,20 +8235,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 2e4b223591569f0a41686d5bd72dc8778629b7be33267e4a09582979e6faee4d7218de84e76294ed827058d4384d75557b5d71724756539c1f235e9a69e62b2e + checksum: 6abaa7a05c5e1db31bffca7ac79169f5456990022cbb3794e6903221536609a60420f2b4888dd3f84e9634a304e394130cb88dc32c243a1dedc263e50da329f8 languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3": - version: 1.1.3 - resolution: "@emotion/serialize@npm:1.1.3" +"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": + version: 1.1.4 + resolution: "@emotion/serialize@npm:1.1.4" dependencies: "@emotion/hash": ^0.9.1 "@emotion/memoize": ^0.8.1 "@emotion/unitless": ^0.8.1 "@emotion/utils": ^1.2.1 csstype: ^3.0.2 - checksum: 5a756ce7e2692322683978d8ed2e84eadd60bd6f629618a82c5018c84d98684b117e57fad0174f68ec2ec0ac089bb2e0bcc8ea8c2798eb904b6d3236aa046063 + checksum: 71b99f816a9c1d61a87c62cf4928da3894bb62213f3aff38b1ea9790b3368f084af98a3e5453b5055c2f36a7d70318d2fa9955b7b5676c2065b868062375df39 languageName: node linkType: hard @@ -10733,13 +8260,13 @@ __metadata: linkType: hard "@emotion/styled@npm:^11.10.5": - version: 11.11.0 - resolution: "@emotion/styled@npm:11.11.0" + version: 11.11.5 + resolution: "@emotion/styled@npm:11.11.5" dependencies: "@babel/runtime": ^7.18.3 "@emotion/babel-plugin": ^11.11.0 - "@emotion/is-prop-valid": ^1.2.1 - "@emotion/serialize": ^1.1.2 + "@emotion/is-prop-valid": ^1.2.2 + "@emotion/serialize": ^1.1.4 "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 "@emotion/utils": ^1.2.1 peerDependencies: @@ -10748,7 +8275,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 904f641aad3892c65d7d6c0808b036dae1e6d6dad4861c1c7dc0baa59977047c6cad220691206eba7b4059f1a1c6e6c1ef4ebb8c829089e280fa0f2164a01e6b + checksum: ad5fc42d00e8aa9597f6d9665986036d5ebe0e8f8155af6d95831c5e8fb2319fb837724e6c5cd59e5346f14c3263711b7ce7271d34688e974d1f32ffeecb37ba languageName: node linkType: hard @@ -10823,16 +8350,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/aix-ppc64@npm:0.19.12" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/aix-ppc64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/aix-ppc64@npm:0.20.0" +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -10844,16 +8364,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm64@npm:0.19.12" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/android-arm64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/android-arm64@npm:0.20.0" +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -10865,16 +8378,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-arm@npm:0.19.12" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@esbuild/android-arm@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/android-arm@npm:0.20.0" +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -10886,16 +8392,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/android-x64@npm:0.19.12" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/android-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/android-x64@npm:0.20.0" +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -10907,16 +8406,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-arm64@npm:0.19.12" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/darwin-arm64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/darwin-arm64@npm:0.20.0" +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -10928,16 +8420,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/darwin-x64@npm:0.19.12" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/darwin-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/darwin-x64@npm:0.20.0" +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -10949,16 +8434,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-arm64@npm:0.19.12" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/freebsd-arm64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/freebsd-arm64@npm:0.20.0" +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -10970,16 +8448,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/freebsd-x64@npm:0.19.12" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/freebsd-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/freebsd-x64@npm:0.20.0" +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -10991,16 +8462,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm64@npm:0.19.12" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/linux-arm64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-arm64@npm:0.20.0" +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -11012,16 +8476,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-arm@npm:0.19.12" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@esbuild/linux-arm@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-arm@npm:0.20.0" +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -11033,16 +8490,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ia32@npm:0.19.12" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/linux-ia32@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-ia32@npm:0.20.0" +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -11054,16 +8504,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-loong64@npm:0.19.12" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-loong64@npm:0.20.0" +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -11075,16 +8518,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-mips64el@npm:0.19.12" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-mips64el@npm:0.20.0" +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -11096,16 +8532,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-ppc64@npm:0.19.12" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-ppc64@npm:0.20.0" +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -11117,16 +8546,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-riscv64@npm:0.19.12" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-riscv64@npm:0.20.0" +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -11138,16 +8560,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-s390x@npm:0.19.12" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-s390x@npm:0.20.0" +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -11159,16 +8574,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/linux-x64@npm:0.19.12" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/linux-x64@npm:0.20.0" +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -11180,16 +8588,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/netbsd-x64@npm:0.19.12" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/netbsd-x64@npm:0.20.0" +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -11201,16 +8602,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/openbsd-x64@npm:0.19.12" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/openbsd-x64@npm:0.20.0" +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -11222,16 +8616,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/sunos-x64@npm:0.19.12" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/sunos-x64@npm:0.20.0" +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -11243,16 +8630,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-arm64@npm:0.19.12" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/win32-arm64@npm:0.20.0" +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -11264,16 +8644,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-ia32@npm:0.19.12" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/win32-ia32@npm:0.20.0" +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -11285,16 +8658,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.12": - version: 0.19.12 - resolution: "@esbuild/win32-x64@npm:0.19.12" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.20.0": - version: 0.20.0 - resolution: "@esbuild/win32-x64@npm:0.20.0" +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -11334,60 +8700,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.56.0": - version: 8.56.0 - resolution: "@eslint/js@npm:8.56.0" - checksum: 5804130574ef810207bdf321c265437814e7a26f4e6fac9b496de3206afd52f533e09ec002a3be06cd9adcc9da63e727f1883938e663c4e4751c007d5b58e539 - languageName: node - linkType: hard - -"@f/animate@npm:^1.0.1": - version: 1.0.1 - resolution: "@f/animate@npm:1.0.1" - dependencies: - "@f/elapsed-time": ^1.0.0 - "@f/raf": ^1.0.0 - "@f/tween": ^1.0.0 - checksum: 660b44d297b1a6e5e28c48438633e00ded40f8e51adb4bfb26fc809b60c8c056f567f2e61f4f842c8fd2cf8a85dffaa1c2502bd0963eb926135f2d66d9f997db - languageName: node - linkType: hard - -"@f/elapsed-time@npm:^1.0.0": - version: 1.0.0 - resolution: "@f/elapsed-time@npm:1.0.0" - dependencies: - "@f/timestamp": ^1.0.0 - checksum: 5934d24a667bae4e0089408aa362c0ee1503945adf73ca0ff0d09fed33d62d070f0323eb9a54f42c37bd0545330a0f63da13319f66cc89fef59b8917a3278b5f - languageName: node - linkType: hard - -"@f/map-obj@npm:^1.2.2": - version: 1.2.2 - resolution: "@f/map-obj@npm:1.2.2" - checksum: d67db6074e1daa7a3c0f8c2e54094bff48b54d11817fddc886631dd8a17586d0040e7116282a374cc1d3d643d05862d49a1062ea5b2d03b9069507c09ae888a4 - languageName: node - linkType: hard - -"@f/raf@npm:^1.0.0": - version: 1.0.3 - resolution: "@f/raf@npm:1.0.3" - checksum: 800344caf4c649c0bcdefd4febbf3f0eed96bb9b7e54b5bc6eebd7d781c9e6d98ba22fb39da41474080d97ac21916bd1e82051558b43dabcbbf410d2dd0899c1 - languageName: node - linkType: hard - -"@f/timestamp@npm:^1.0.0": - version: 1.0.0 - resolution: "@f/timestamp@npm:1.0.0" - checksum: 8c37acb40cf67952309a214be2ddfd5c4f6634a414efc47406e8d1c1624e74662f584f6b48f3382c742f256aea1537e730e74c6078e52be3a28d0624cc7306a0 - languageName: node - linkType: hard - -"@f/tween@npm:^1.0.0": - version: 1.0.1 - resolution: "@f/tween@npm:1.0.1" - dependencies: - "@f/map-obj": ^1.2.2 - checksum: e37155c43875becc9eca8425b8dc83e64a78fa327738b33fcb3946418369568aa77007ade39591991379187381da829702e5cb84729dd2a0bc3bb4b7c94e4f2b +"@eslint/js@npm:8.57.0": + version: 8.57.0 + resolution: "@eslint/js@npm:8.57.0" + checksum: 315dc65b0e9893e2bff139bddace7ea601ad77ed47b4550e73da8c9c2d2766c7a575c3cddf17ef85b8fd6a36ff34f91729d0dcca56e73ca887c10df91a41b0bb languageName: node linkType: hard @@ -11398,45 +8714,38 @@ __metadata: languageName: node linkType: hard -"@fastify/busboy@npm:^2.0.0": - version: 2.0.0 - resolution: "@fastify/busboy@npm:2.0.0" - checksum: 41879937ce1dee6421ef9cd4da53239830617e1f0bb7a0e843940772cd72827205d05e518af6adabe6e1ea19301285fff432b9d11bad01a531e698bea95c781b +"@floating-ui/core@npm:^1.0.0": + version: 1.6.0 + resolution: "@floating-ui/core@npm:1.6.0" + dependencies: + "@floating-ui/utils": ^0.2.1 + checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127 languageName: node linkType: hard -"@floating-ui/core@npm:^1.5.3": - version: 1.5.3 - resolution: "@floating-ui/core@npm:1.5.3" +"@floating-ui/dom@npm:^1.6.1": + version: 1.6.3 + resolution: "@floating-ui/dom@npm:1.6.3" dependencies: + "@floating-ui/core": ^1.0.0 "@floating-ui/utils": ^0.2.0 - checksum: 72af8563e1742791acee82e86f82a0fbca7445809988d31eea3fd5771909463aa7655a6cb001cc244f8fe3a9de600420257e4dfb887ca33e2a31ac47b52e39a2 + checksum: 81cbb18ece3afc37992f436e469e7fabab2e433248e46fff4302d12493a175b0c64310f8a971e6e1eda7218df28ace6b70237b0f3c22fe12a21bba05b5579555 languageName: node linkType: hard -"@floating-ui/dom@npm:^1.5.4": - version: 1.5.4 - resolution: "@floating-ui/dom@npm:1.5.4" +"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.8": + version: 2.0.8 + resolution: "@floating-ui/react-dom@npm:2.0.8" dependencies: - "@floating-ui/core": ^1.5.3 - "@floating-ui/utils": ^0.2.0 - checksum: 5e6f05532ff4e6daf9f2d91534184d8f942ddb8fd260c2543a49bdf0c0ff69fd0867937ce1d023126008724ac238f8fc89b5e48f82cdf9f8355a1d04edd085bd - languageName: node - linkType: hard - -"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.5": - version: 2.0.6 - resolution: "@floating-ui/react-dom@npm:2.0.6" - dependencies: - "@floating-ui/dom": ^1.5.4 + "@floating-ui/dom": ^1.6.1 peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 3608537be6cae5f0442d3f826379b8e4a9ce5c4bdecf1d2b34e6709842d80444be1a00eca3641d680e2e6405d833092f58005d1b120a9d39ffd341c60b0c017c + checksum: 5da7f13a69281e38859a3203a608fe9de1d850b332b355c10c0c2427c7b7209a0374c10f6295b6577c1a70237af8b678340bd4cc0a4b1c66436a94755d81e526 languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.0": +"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": version: 0.2.1 resolution: "@floating-ui/utils@npm:0.2.1" checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 @@ -11450,19 +8759,7 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/browser@npm:^35.6.0": - version: 35.8.1 - resolution: "@gitbeaker/browser@npm:35.8.1" - dependencies: - "@gitbeaker/core": ^35.8.1 - "@gitbeaker/requester-utils": ^35.8.1 - delay: ^5.0.0 - ky: 0.28.7 - checksum: 8a76322cfd19da3d691fb08c7ebc79971da02cfb950841578523f20de02cb5e2dcf9741eca048dfa17d6a9620eb4884c9a29d84a230ba9c8d18fc528deb830cd - languageName: node - linkType: hard - -"@gitbeaker/core@npm:^35.6.0, @gitbeaker/core@npm:^35.8.0, @gitbeaker/core@npm:^35.8.1": +"@gitbeaker/core@npm:^35.8.0, @gitbeaker/core@npm:^35.8.1": version: 35.8.1 resolution: "@gitbeaker/core@npm:35.8.1" dependencies: @@ -11476,14 +8773,25 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/core@npm:^39.34.2": - version: 39.34.2 - resolution: "@gitbeaker/core@npm:39.34.2" +"@gitbeaker/core@npm:^39.34.3": + version: 39.34.3 + resolution: "@gitbeaker/core@npm:39.34.3" dependencies: - "@gitbeaker/requester-utils": ^39.34.2 + "@gitbeaker/requester-utils": ^39.34.3 qs: ^6.11.2 xcase: ^2.0.1 - checksum: 3c1db0ed169d83c2f6631d34a3dd5b4dde597480e47b1f212fab00e2eb31ff2759e3f983475a4dc368df8811642c0c2822039d87461dcee7ac4b5bd2fa04adab + checksum: 2b0ccd6137ee717b6f51c51c8f7063b84beeebfdb044574f2257f282864411c4f0932f2619893385f2a86bb4fa342b75be972fd1868640ab4e260f2280cc52b3 + languageName: node + linkType: hard + +"@gitbeaker/core@npm:^40.0.3": + version: 40.0.3 + resolution: "@gitbeaker/core@npm:40.0.3" + dependencies: + "@gitbeaker/requester-utils": ^40.0.3 + qs: ^6.11.2 + xcase: ^2.0.1 + checksum: 999cea3f1523eabfae473e8a21849fdd4f6b4d30f0de681e735b238713b198ff9381c35d2ba5949d27ddc7ed5a953b14fc5a6ed38a5d98b05b6a5670a0c69162 languageName: node linkType: hard @@ -11511,46 +8819,68 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/requester-utils@npm:^39.34.2": - version: 39.34.2 - resolution: "@gitbeaker/requester-utils@npm:39.34.2" +"@gitbeaker/requester-utils@npm:^39.34.3": + version: 39.34.3 + resolution: "@gitbeaker/requester-utils@npm:39.34.3" dependencies: picomatch-browser: ^2.2.6 qs: ^6.11.2 rate-limiter-flexible: ^4.0.0 xcase: ^2.0.1 - checksum: ae70d558ce13af56e2b0b31330b76f2b528a503a27e9f152d4224d1c165f08f20109fff6dabea5ac4679a6c07e49f9025149a3fab4aabe3cd03754d8b138b5f9 + checksum: 55881864f42e243d9cd73840ea44c9eee13be7974fa13fde241f19bc47915712532d5f7339a598cdd258c32193a37375719984d2630620ab8d962d6d7724cbeb + languageName: node + linkType: hard + +"@gitbeaker/requester-utils@npm:^40.0.3": + version: 40.0.3 + resolution: "@gitbeaker/requester-utils@npm:40.0.3" + dependencies: + picomatch-browser: ^2.2.6 + qs: ^6.11.2 + rate-limiter-flexible: ^4.0.0 + xcase: ^2.0.1 + checksum: 1a46dc9c730c29e2229b04ed9bbe6cd87b7e5f16c1d0a5e78106f0287ab3d981ce2b099eb41cdb0f9180bb6b11d25f5f1fa92a91b69682bcd4ac986e58b55d31 languageName: node linkType: hard "@gitbeaker/rest@npm:^39.25.0": - version: 39.34.2 - resolution: "@gitbeaker/rest@npm:39.34.2" + version: 39.34.3 + resolution: "@gitbeaker/rest@npm:39.34.3" dependencies: - "@gitbeaker/core": ^39.34.2 - "@gitbeaker/requester-utils": ^39.34.2 - checksum: e224214b816b9a9e38c77b0eb604aa456793ea7610e7f426899579ab738abe4b8aeafb0f6b9e94ccde9d5fd82cc4d6af0d51cc50174173184df2e7a8be18af5b + "@gitbeaker/core": ^39.34.3 + "@gitbeaker/requester-utils": ^39.34.3 + checksum: e2a484891b12c71d4218168ab3884af14d036fb16a710ea023556a3d57dd220b13feaebd1f4aa3f61d0180c9f17b66f283650cd543416bb402d3bed8b6eaa465 + languageName: node + linkType: hard + +"@gitbeaker/rest@npm:^40.0.3": + version: 40.0.3 + resolution: "@gitbeaker/rest@npm:40.0.3" + dependencies: + "@gitbeaker/core": ^40.0.3 + "@gitbeaker/requester-utils": ^40.0.3 + checksum: 6a6427b82ee3357fbe07e1235de7a3c98d50155898180fbe4dd641c8575faa93853f1a39185e18876f84469e1a385ccd9beb26fd95b61c260b81eb0ed342355b languageName: node linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.7.0 - resolution: "@google-cloud/container@npm:5.7.0" + version: 5.12.0 + resolution: "@google-cloud/container@npm:5.12.0" dependencies: google-gax: ^4.0.3 - checksum: 8d6d1e80b1bd33e24e4d0ed667fc16543b7ad2962c3918b74ff42efc0ed3c915a3682e83d8f53aaa06eb5fbe6fb661e46640f954f59b79f991598b03c68f3e13 + checksum: bf22c6754d67b133f272522b41f9f383e960a3288847d345407a171cce593856527cd3ee3df13bb4b09091bfce03f3404d24559ce2c28733ce71866068fb5277 languageName: node linkType: hard "@google-cloud/firestore@npm:^7.0.0": - version: 7.3.0 - resolution: "@google-cloud/firestore@npm:7.3.0" + version: 7.4.0 + resolution: "@google-cloud/firestore@npm:7.4.0" dependencies: fast-deep-equal: ^3.1.1 functional-red-black-tree: ^1.0.1 google-gax: ^4.0.4 protobufjs: ^7.2.5 - checksum: 6e12f011250ee6e3f8a522ab02d706af7966675b6653e77734929fce1493efc9fed90de398900228da660f4f4738ccafa2bad96f4573e8097267c67f1ab87f90 + checksum: df0094c3be5473a96f925d7bcd4234f376e4928065bdd96bdc2debc73b4c976df160c2553dfc8ed3d73f859778996159e69770983fa0224a53afbe4e77754db3 languageName: node linkType: hard @@ -11579,31 +8909,29 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^7.0.0": - version: 7.7.0 - resolution: "@google-cloud/storage@npm:7.7.0" + version: 7.10.1 + resolution: "@google-cloud/storage@npm:7.10.1" dependencies: "@google-cloud/paginator": ^5.0.0 "@google-cloud/projectify": ^4.0.0 "@google-cloud/promisify": ^4.0.0 abort-controller: ^3.0.0 async-retry: ^1.3.3 - compressible: ^2.0.12 - duplexify: ^4.0.0 + duplexify: ^4.1.3 ent: ^2.2.0 fast-xml-parser: ^4.3.0 gaxios: ^6.0.2 - google-auth-library: ^9.0.0 + google-auth-library: ^9.6.3 mime: ^3.0.0 - mime-types: ^2.0.8 p-limit: ^3.0.1 retry-request: ^7.0.0 teeny-request: ^9.0.0 uuid: ^8.0.0 - checksum: b63069b7e591e55f9132aab9e8f9cd03b72a5b6e531c1f37fc44c4cd34eb02dd50e8007739dad6f0ac2ddb216eb5a80bc3b062d1d8c42aad7351e6cc6008d27f + checksum: 0605f8abf67cde98bc48b05c749b569416af821fcc3eb8ed3fac6dc5ade9c1f2f3210404c85e30525260ea4f34785d7436f7684e6eacd083613237669badff25 languageName: node linkType: hard -"@graphiql/react@npm:^0.20.0, @graphiql/react@npm:^0.20.2, @graphiql/react@npm:^0.20.3": +"@graphiql/react@npm:^0.20.0, @graphiql/react@npm:^0.20.3": version: 0.20.3 resolution: "@graphiql/react@npm:0.20.3" dependencies: @@ -12006,14 +9334,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.13": - version: 0.11.13 - resolution: "@humanwhocodes/config-array@npm:0.11.13" +"@humanwhocodes/config-array@npm:^0.11.14": + version: 0.11.14 + resolution: "@humanwhocodes/config-array@npm:0.11.14" dependencies: - "@humanwhocodes/object-schema": ^2.0.1 - debug: ^4.1.1 + "@humanwhocodes/object-schema": ^2.0.2 + debug: ^4.3.1 minimatch: ^3.0.5 - checksum: f8ea57b0d7ed7f2d64cd3944654976829d9da91c04d9c860e18804729a33f7681f78166ef4c761850b8c324d362f7d53f14c5c44907a6b38b32c703ff85e4805 + checksum: 861ccce9eaea5de19546653bccf75bf09fe878bc39c3aab00aeee2d2a0e654516adad38dd1098aab5e3af0145bbcbf3f309bdf4d964f8dab9dcd5834ae4c02f2 languageName: node linkType: hard @@ -12024,10 +9352,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.1": - version: 2.0.1 - resolution: "@humanwhocodes/object-schema@npm:2.0.1" - checksum: 24929487b1ed48795d2f08346a0116cc5ee4634848bce64161fb947109352c562310fd159fc64dda0e8b853307f5794605191a9547f7341158559ca3c8262a45 +"@humanwhocodes/object-schema@npm:^2.0.2": + version: 2.0.2 + resolution: "@humanwhocodes/object-schema@npm:2.0.2" + checksum: 2fc11503361b5fb4f14714c700c02a3f4c7c93e9acd6b87a29f62c522d90470f364d6161b03d1cc618b979f2ae02aed1106fd29d302695d8927e2fc8165ba8ee languageName: node linkType: hard @@ -12103,12 +9431,11 @@ __metadata: "@backstage/plugin-auth-node": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 - "@types/uuid": ^8.0.0 + "@types/uuid": ^9.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 supertest: ^6.1.6 - uuid: ^8.3.2 - winston: ^3.2.1 + uuid: ^9.0.0 yn: ^4.0.0 languageName: unknown linkType: soft @@ -12131,9 +9458,9 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/lab": 4.0.0-alpha.61 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 react-use: ^17.2.4 peerDependencies: @@ -12275,15 +9602,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/expect-utils@npm:28.1.3" - dependencies: - jest-get-type: ^28.0.2 - checksum: 808ea3a68292a7e0b95490fdd55605c430b4cf209ea76b5b61bfb2a1badcb41bc046810fe4e364bd5fe04663978aa2bd73d8f8465a761dd7c655aeb44cf22987 - languageName: node - linkType: hard - "@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" @@ -12366,15 +9684,6 @@ __metadata: languageName: node linkType: hard -"@jest/schemas@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/schemas@npm:28.1.3" - dependencies: - "@sinclair/typebox": ^0.24.1 - checksum: 3cf1d4b66c9c4ffda58b246de1ddcba8e6ad085af63dccdf07922511f13b68c0cc480a7bc620cb4f3099a6f134801c747e1df7bfc7a4ef4dceefbdea3e31e1de - languageName: node - linkType: hard - "@jest/schemas@npm:^29.6.3": version: 29.6.3 resolution: "@jest/schemas@npm:29.6.3" @@ -12442,20 +9751,6 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/types@npm:28.1.3" - dependencies: - "@jest/schemas": ^28.1.3 - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^17.0.8 - chalk: ^4.0.0 - checksum: 1e258d9c063fcf59ebc91e46d5ea5984674ac7ae6cae3e50aa780d22b4405bf2c925f40350bf30013839eb5d4b5e521d956ddf8f3b7c78debef0e75a07f57350 - languageName: node - linkType: hard - "@jest/types@npm:^29.6.3": version: 29.6.3 resolution: "@jest/types@npm:29.6.3" @@ -12728,8 +10023,8 @@ __metadata: linkType: hard "@material-table/core@npm:^3.1.0": - version: 3.1.0 - resolution: "@material-table/core@npm:3.1.0" + version: 3.2.5 + resolution: "@material-table/core@npm:3.2.5" dependencies: "@babel/runtime": ^7.12.5 "@date-io/date-fns": ^1.3.13 @@ -12742,54 +10037,17 @@ __metadata: prop-types: ^15.7.2 react-beautiful-dnd: ^13.0.0 react-double-scrollbar: 0.0.15 + uuid: ^3.4.0 peerDependencies: "@date-io/core": ^1.3.13 "@material-ui/core": ^4.11.2 react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: c54114733c061d99424859465c25fdd0c51314f533d37269ee41062195bb34b5bd7eabae8e7b14532b90baee9363d00333b00d1619c01b821a7ee974053c4947 + checksum: 707e85cfcb8c1cfc8eb78ea6991509879f774081d7a54ad428f702fe00478b6d3707d0fd85f4ad443ebcfac0c0cab79c046c4d5083adcbc767615445667b50cf languageName: node linkType: hard -"@material-ui/core@npm:^3.9.3": - version: 3.9.4 - resolution: "@material-ui/core@npm:3.9.4" - dependencies: - "@babel/runtime": ^7.2.0 - "@material-ui/system": ^3.0.0-alpha.0 - "@material-ui/utils": ^3.0.0-alpha.2 - "@types/jss": ^9.5.6 - "@types/react-transition-group": ^2.0.8 - brcast: ^3.0.1 - classnames: ^2.2.5 - csstype: ^2.5.2 - debounce: ^1.1.0 - deepmerge: ^3.0.0 - dom-helpers: ^3.2.1 - hoist-non-react-statics: ^3.2.1 - is-plain-object: ^2.0.4 - jss: ^9.8.7 - jss-camel-case: ^6.0.0 - jss-default-unit: ^8.0.2 - jss-global: ^3.0.0 - jss-nested: ^6.0.1 - jss-props-sort: ^6.0.0 - jss-vendor-prefixer: ^7.0.0 - normalize-scroll-left: ^0.1.2 - popper.js: ^1.14.1 - prop-types: ^15.6.0 - react-event-listener: ^0.6.2 - react-transition-group: ^2.2.1 - recompose: 0.28.0 - 0.30.0 - warning: ^4.0.1 - peerDependencies: - react: ^16.3.0 - react-dom: ^16.3.0 - checksum: c3923bfba4ef4449fbdcd37712ec0d11393ffa396c575a05b5f9530ca1e714028882d39402eb6918dad49f2eb1c53b261cfd0f2dfed494c2dfd96ee335336b44 - languageName: node - linkType: hard - -"@material-ui/core@npm:^4.11.0, @material-ui/core@npm:^4.11.3, @material-ui/core@npm:^4.12.1, @material-ui/core@npm:^4.12.2, @material-ui/core@npm:^4.12.4, @material-ui/core@npm:^4.9.13": +"@material-ui/core@npm:^4.12.2, @material-ui/core@npm:^4.12.4, @material-ui/core@npm:^4.9.13": version: 4.12.4 resolution: "@material-ui/core@npm:4.12.4" dependencies: @@ -12833,48 +10091,6 @@ __metadata: languageName: node linkType: hard -"@material-ui/lab@npm:4.0.0-alpha.45": - version: 4.0.0-alpha.45 - resolution: "@material-ui/lab@npm:4.0.0-alpha.45" - dependencies: - "@babel/runtime": ^7.4.4 - "@material-ui/utils": ^4.7.1 - clsx: ^1.0.4 - prop-types: ^15.7.2 - react-is: ^16.8.0 - peerDependencies: - "@material-ui/core": ^4.9.0 - "@types/react": ^16.8.6 - react: ^16.8.0 - react-dom: ^16.8.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: fa9edb1c6351df6b5d69faa32f94a98fe4ab1b54da02c2287f8448041f9bbb7df940deb1c9dce169c00c0e46d3553175b16a56129a549320ece39094c8836eba - languageName: node - linkType: hard - -"@material-ui/lab@npm:4.0.0-alpha.57": - version: 4.0.0-alpha.57 - resolution: "@material-ui/lab@npm:4.0.0-alpha.57" - dependencies: - "@babel/runtime": ^7.4.4 - "@material-ui/utils": ^4.11.2 - clsx: ^1.0.4 - prop-types: ^15.7.2 - react-is: ^16.8.0 || ^17.0.0 - peerDependencies: - "@material-ui/core": ^4.9.10 - "@types/react": ^16.8.6 || ^17.0.0 - react: ^16.8.0 || ^17.0.0 - react-dom: ^16.8.0 || ^17.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 0bc8b35e4a96ea04fa3fd43a64ff9685bdea2ad6ed8baf4c8f5cbe1524101a87f33229f6d23638074a3626fc3c55ba15a38d2ab984777dda896e117d0cea5c0e - languageName: node - linkType: hard - "@material-ui/lab@npm:4.0.0-alpha.61, @material-ui/lab@npm:^4.0.0-alpha.57, @material-ui/lab@npm:^4.0.0-alpha.60, @material-ui/lab@npm:^4.0.0-alpha.61": version: 4.0.0-alpha.61 resolution: "@material-ui/lab@npm:4.0.0-alpha.61" @@ -12918,7 +10134,7 @@ __metadata: "@material-ui/pickers@patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch::locator=root%40workspace%3A.": version: 3.3.11 - resolution: "@material-ui/pickers@patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch::version=3.3.11&hash=c18f79&locator=root%40workspace%3A." + resolution: "@material-ui/pickers@patch:@material-ui/pickers@npm%3A3.3.11#./.yarn/patches/@material-ui-pickers-npm-3.3.11-1c8f68ea20.patch::version=3.3.11&hash=5d572b&locator=root%40workspace%3A." dependencies: "@babel/runtime": ^7.6.0 "@date-io/core": 1.x @@ -12936,7 +10152,7 @@ __metadata: languageName: node linkType: hard -"@material-ui/styles@npm:^4.10.0, @material-ui/styles@npm:^4.11.0, @material-ui/styles@npm:^4.11.4, @material-ui/styles@npm:^4.11.5, @material-ui/styles@npm:^4.9.6": +"@material-ui/styles@npm:^4.10.0, @material-ui/styles@npm:^4.11.0, @material-ui/styles@npm:^4.11.4, @material-ui/styles@npm:^4.11.5": version: 4.11.5 resolution: "@material-ui/styles@npm:4.11.5" dependencies: @@ -12967,21 +10183,6 @@ __metadata: languageName: node linkType: hard -"@material-ui/system@npm:^3.0.0-alpha.0": - version: 3.0.0-alpha.2 - resolution: "@material-ui/system@npm:3.0.0-alpha.2" - dependencies: - "@babel/runtime": ^7.2.0 - deepmerge: ^3.0.0 - prop-types: ^15.6.0 - warning: ^4.0.1 - peerDependencies: - react: ^16.3.0 - react-dom: ^16.3.0 - checksum: 3aacb8b4afe2a820844b90905cfcd86ab934108cd719f11713ee46f8a4da30cb8c50e86219e1440b3c6dd333a09d4123cd1990d9c51862c1d56ec2b36e4d7ded - languageName: node - linkType: hard - "@material-ui/system@npm:^4.12.2": version: 4.12.2 resolution: "@material-ui/system@npm:4.12.2" @@ -13025,21 +10226,7 @@ __metadata: languageName: node linkType: hard -"@material-ui/utils@npm:^3.0.0-alpha.2": - version: 3.0.0-alpha.3 - resolution: "@material-ui/utils@npm:3.0.0-alpha.3" - dependencies: - "@babel/runtime": ^7.2.0 - prop-types: ^15.6.0 - react-is: ^16.6.3 - peerDependencies: - react: ^16.3.0 - react-dom: ^16.3.0 - checksum: 589a16245338c374b604a793d9f7a05bd932c9710f78261e46176b74a61d5d308b3e36dab688988ee5177d689c53d9e9da4649eca009ea11d8aac948db27af50 - languageName: node - linkType: hard - -"@material-ui/utils@npm:^4.11.2, @material-ui/utils@npm:^4.11.3, @material-ui/utils@npm:^4.7.1": +"@material-ui/utils@npm:^4.11.3": version: 4.11.3 resolution: "@material-ui/utils@npm:4.11.3" dependencies: @@ -13053,15 +10240,6 @@ __metadata: languageName: node linkType: hard -"@maxim_mazurok/gapi.client.calendar@npm:^3.0.20220408": - version: 3.0.20220805 - resolution: "@maxim_mazurok/gapi.client.calendar@npm:3.0.20220805" - dependencies: - "@types/gapi.client": "*" - checksum: 981560f83b310a9a8ab1641befac02b732ce92e803b20dabd2cb6fc701d4df97aa265820762455385ce9691850ce31f4323778c60de11f144060800cf10c6ef5 - languageName: node - linkType: hard - "@microsoft/api-documenter@npm:^7.22.33": version: 7.22.33 resolution: "@microsoft/api-documenter@npm:7.22.33" @@ -13112,7 +10290,7 @@ __metadata: languageName: node linkType: hard -"@microsoft/microsoft-graph-types@npm:^2.25.0, @microsoft/microsoft-graph-types@npm:^2.6.0": +"@microsoft/microsoft-graph-types@npm:^2.6.0": version: 2.40.0 resolution: "@microsoft/microsoft-graph-types@npm:2.40.0" checksum: 3892e910baf4fcf2d1bcee4c71683e3707818be6ff1b4b9dbc29b9e2eab942ea0b171b3023d4620213f10d93d03611e6615706a3d1af4ca44028491a0544ccaf @@ -13236,9 +10414,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.25.16": - version: 0.25.16 - resolution: "@mswjs/interceptors@npm:0.25.16" +"@mswjs/interceptors@npm:^0.26.14": + version: 0.26.15 + resolution: "@mswjs/interceptors@npm:0.26.15" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 @@ -13246,18 +10424,18 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.2.1 strict-event-emitter: ^0.5.1 - checksum: 862eb02be5f7606c643793b66b50b75e6a00784c4c6fcca3db7a52391f01a557f404d178493e716b9190412317a5fa7177abb33bfa4be576a08be4ba4e765575 + checksum: 6087ba7049c73af8d0d60344976950ec65c733b73dddcd1ed18b5bd91d013f5f364a09583bb70f8a82558391c125b2e1ff38eb4076f2bdc21d7833134bd4f7dd languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.32": - version: 5.0.0-beta.32 - resolution: "@mui/base@npm:5.0.0-beta.32" +"@mui/base@npm:5.0.0-beta.40": + version: 5.0.0-beta.40 + resolution: "@mui/base@npm:5.0.0-beta.40" dependencies: - "@babel/runtime": ^7.23.8 - "@floating-ui/react-dom": ^2.0.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@floating-ui/react-dom": ^2.0.8 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 "@popperjs/core": ^2.11.8 clsx: ^2.1.0 prop-types: ^15.8.1 @@ -13268,30 +10446,30 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 5f27be8914c072ffcbe6720de9aa6129180e68927657e8bcbc03a6f322d1ee6c6740a199d72ed0b490a7b29b79cc0c59d1e05a427089b17f4cbc9cc756e67506 + checksum: 9c084ee67de372411a71af5eca9a5367db9f5bce57bb43973629c522760fe64fa2a43d2934dccd24d6dcbcd0ed399c5fc5c461226c86104f5767de1c9b8deba2 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/core-downloads-tracker@npm:5.15.5" - checksum: 4c9b1281ebe8d17d402e22f7f50c347c0b3918b1ed17af721f4de5ce282d90bc6d90fe9730595998b2bbb2f7ebe57fc55d4c858f31754fccdb606af472a59dc8 +"@mui/core-downloads-tracker@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/core-downloads-tracker@npm:5.15.15" + checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.15.5 - resolution: "@mui/material@npm:5.15.5" + version: 5.15.15 + resolution: "@mui/material@npm:5.15.15" dependencies: - "@babel/runtime": ^7.23.8 - "@mui/base": 5.0.0-beta.32 - "@mui/core-downloads-tracker": ^5.15.5 - "@mui/system": ^5.15.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@mui/base": 5.0.0-beta.40 + "@mui/core-downloads-tracker": ^5.15.15 + "@mui/system": ^5.15.15 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 "@types/react-transition-group": ^4.4.10 clsx: ^2.1.0 - csstype: ^3.1.2 + csstype: ^3.1.3 prop-types: ^15.8.1 react-is: ^18.2.0 react-transition-group: ^4.4.5 @@ -13308,16 +10486,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: dbfcb31810c674d9ab3b9145752433de3917d9c0d1b491bdff84c44b8f1124e8fe8ab04fa09b974b497983b7bd3011b86fb441ad365f979f971d3ddb46712060 + checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/private-theming@npm:5.15.5" +"@mui/private-theming@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/private-theming@npm:5.15.14" dependencies: - "@babel/runtime": ^7.23.8 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@mui/utils": ^5.15.14 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -13325,17 +10503,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 3a5f7f190aa69a0ad69a34f77e54ee2fdcb088d21a61d4720b76d098d178e1c3f6a470fc5e7a30d351db10efbc062cb11af75b8789e2f38eaa2ca612bcb0f851 + checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/styled-engine@npm:5.15.5" +"@mui/styled-engine@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/styled-engine@npm:5.15.14" dependencies: - "@babel/runtime": ^7.23.8 + "@babel/runtime": ^7.23.9 "@emotion/cache": ^11.11.0 - csstype: ^3.1.2 + csstype: ^3.1.3 prop-types: ^15.8.1 peerDependencies: "@emotion/react": ^11.4.1 @@ -13346,21 +10524,21 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 42bb7f50ed33ec88f799bd90a00337689837ee0b2d603681fe69c9a14850e5ae1d037505365ce78cd564307cc2c0654c46cece8d9250adb21c77b1de316e3c45 + checksum: 23b45c859a4f0d2b10933d06a6082c0ff093f7b6d8d32a2bfe3a6e515fe46d7a38ca9e7150d45c025a2e98d963bae9a5991d131cf4748b62670075ef0fa321ed languageName: node linkType: hard "@mui/styles@npm:^5.14.18": - version: 5.15.5 - resolution: "@mui/styles@npm:5.15.5" + version: 5.15.15 + resolution: "@mui/styles@npm:5.15.15" dependencies: - "@babel/runtime": ^7.23.8 + "@babel/runtime": ^7.23.9 "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.15.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@mui/private-theming": ^5.15.14 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 clsx: ^2.1.0 - csstype: ^3.1.2 + csstype: ^3.1.3 hoist-non-react-statics: ^3.3.2 jss: ^10.10.0 jss-plugin-camel-case: ^10.10.0 @@ -13377,21 +10555,21 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: dc131c0e7763f7ac4fd96a1db3dd85abf59de5429a73f7cf9ed15d423fb9bb5883835c1951d36e8804da9ab2ed13d603ed349f12e7cd15885f8279d90d13511b + checksum: 5e436a8a22ae9a2e6fcb63ead3a6eff2092cc9731fce0b22d04ab9c67639a173a0e27fb617628e7720592862118a32248be458bedfabaf1de5448543a97b0307 languageName: node linkType: hard -"@mui/system@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/system@npm:5.15.5" +"@mui/system@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/system@npm:5.15.15" dependencies: - "@babel/runtime": ^7.23.8 - "@mui/private-theming": ^5.15.5 - "@mui/styled-engine": ^5.15.5 - "@mui/types": ^7.2.13 - "@mui/utils": ^5.15.5 + "@babel/runtime": ^7.23.9 + "@mui/private-theming": ^5.15.14 + "@mui/styled-engine": ^5.15.14 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 clsx: ^2.1.0 - csstype: ^3.1.2 + csstype: ^3.1.3 prop-types: ^15.8.1 peerDependencies: "@emotion/react": ^11.5.0 @@ -13405,27 +10583,27 @@ __metadata: optional: true "@types/react": optional: true - checksum: 3f736f120d65fa14588cd7554a9ef63c9d4480716807d7ee5543b9f25d936b5ac0396a51a565c53b2905114fed5f94880c896f091e8d269260bfc53e8a8e2fb5 + checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f languageName: node linkType: hard -"@mui/types@npm:^7.2.13": - version: 7.2.13 - resolution: "@mui/types@npm:7.2.13" +"@mui/types@npm:^7.2.14": + version: 7.2.14 + resolution: "@mui/types@npm:7.2.14" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 58dfc96f9654288519ff01d6b54e6a242f05cadad51210deb85710a81be4fa1501a116c8968e2614b16c748fc1f407dc23beeeeae70fa37fceb6c6de876ff70d + checksum: 615c9f9110933157f5d3c4fee69d6e70b98fc0d9ebc3b63079b6a1e23e6b389748687a25ab4ac15b56166fc228885da87c3929503b41fa322cfdee0f6d411206 languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.5": - version: 5.15.5 - resolution: "@mui/utils@npm:5.15.5" +"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/utils@npm:5.15.14" dependencies: - "@babel/runtime": ^7.23.8 + "@babel/runtime": ^7.23.9 "@types/prop-types": ^15.7.11 prop-types: ^15.8.1 react-is: ^18.2.0 @@ -13435,7 +10613,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: fe71ce69e23cb4c00886138da1422e4baa66959cd10f97b2aa00f7324a038b13084ea4a0da123774c0018f48ddb6ce4f3cb20a915ec3c5c1ff5495bf337f665f + checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893 languageName: node linkType: hard @@ -13507,18 +10685,6 @@ __metadata: languageName: node linkType: hard -"@newrelic/browser-agent@npm:^1.236.0": - version: 1.252.0 - resolution: "@newrelic/browser-agent@npm:1.252.0" - dependencies: - core-js: ^3.26.0 - fflate: ^0.7.4 - rrweb: 2.0.0-alpha.11 - web-vitals: ^3.1.0 - checksum: 575bbce72bee84b63bdd7e7e9409982e0b2656fef7c48f2f034868c7017a1bce7b8037b5b0c3690b204bbd5f60d0782e0314a643777916b9bb3149a0d5d6fc75 - languageName: node - linkType: hard - "@node-saml/node-saml@npm:^4.0.4": version: 4.0.5 resolution: "@node-saml/node-saml@npm:4.0.5" @@ -13734,18 +10900,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/map-workspaces@npm:3.0.4": - version: 3.0.4 - resolution: "@npmcli/map-workspaces@npm:3.0.4" - dependencies: - "@npmcli/name-from-folder": ^2.0.0 - glob: ^10.2.2 - minimatch: ^9.0.0 - read-package-json-fast: ^3.0.0 - checksum: 99607dbc502b16d0ce7a47a81ccc496b3f5ed10df4e61e61a505929de12c356092996044174ae0cfd6d8cc177ef3b597eef4987b674fc0c5a306d3a8cc1fe91a - languageName: node - linkType: hard - "@npmcli/map-workspaces@npm:^2.0.0": version: 2.0.0 resolution: "@npmcli/map-workspaces@npm:2.0.0" @@ -13758,6 +10912,18 @@ __metadata: languageName: node linkType: hard +"@npmcli/map-workspaces@npm:^3.0.4": + version: 3.0.6 + resolution: "@npmcli/map-workspaces@npm:3.0.6" + dependencies: + "@npmcli/name-from-folder": ^2.0.0 + glob: ^10.2.2 + minimatch: ^9.0.0 + read-package-json-fast: ^3.0.0 + checksum: bdb09ee1d044bb9b2857d9e2d7ca82f40783a8549b5a7e150e25f874ee354cdbc8109ad7c3df42ec412f7057d95baa05920c4d361c868a93a42146b8e4390d3d + languageName: node + linkType: hard + "@npmcli/metavuln-calculator@npm:^2.0.0": version: 2.0.0 resolution: "@npmcli/metavuln-calculator@npm:2.0.0" @@ -13811,9 +10977,18 @@ __metadata: languageName: node linkType: hard -"@npmcli/package-json@npm:5.0.0": - version: 5.0.0 - resolution: "@npmcli/package-json@npm:5.0.0" +"@npmcli/package-json@npm:^1.0.1": + version: 1.0.1 + resolution: "@npmcli/package-json@npm:1.0.1" + dependencies: + json-parse-even-better-errors: ^2.3.1 + checksum: 08b66c8ddb1d6b678975a83006d2fe5070b3013bcb68ea9d54c0142538a614596ddfd1143183fbb8f82c5cecf477d98f3c4e473ef34df3bbf3814e97e37e18d3 + languageName: node + linkType: hard + +"@npmcli/package-json@npm:^5.0.0": + version: 5.0.2 + resolution: "@npmcli/package-json@npm:5.0.2" dependencies: "@npmcli/git": ^5.0.0 glob: ^10.2.2 @@ -13822,16 +10997,7 @@ __metadata: normalize-package-data: ^6.0.0 proc-log: ^3.0.0 semver: ^7.5.3 - checksum: 0d128e84e05e8a1771c8cc1f4232053fecf32e28f44e123ad16366ca3a7fd06f272f25f0b7d058f2763cab26bc479c8fc3c570af5de6324b05cb39868dcc6264 - languageName: node - linkType: hard - -"@npmcli/package-json@npm:^1.0.1": - version: 1.0.1 - resolution: "@npmcli/package-json@npm:1.0.1" - dependencies: - json-parse-even-better-errors: ^2.3.1 - checksum: 08b66c8ddb1d6b678975a83006d2fe5070b3013bcb68ea9d54c0142538a614596ddfd1143183fbb8f82c5cecf477d98f3c4e473ef34df3bbf3814e97e37e18d3 + checksum: f0e69d093a5733c7d31ce45098e2ce059f01d09b79329a7f3e975baf91d87f4bf3171fadc27442f4f540dc546954259f178be40ca632b87cfe16bcfe04f00dd3 languageName: node linkType: hard @@ -14258,6 +11424,13 @@ __metadata: languageName: node linkType: hard +"@octokit/openapi-types@npm:^14.0.0": + version: 14.0.0 + resolution: "@octokit/openapi-types@npm:14.0.0" + checksum: 0a1f8f3be998cd82c5a640e9166d43fd183b33d5d36f5e1a9b81608e94d0da87c01ec46c9988f69cd26585d4e2ffc4d3ec99ee4f75e5fe997fc86dad0aa8293c + languageName: node + linkType: hard + "@octokit/openapi-types@npm:^17.2.0": version: 17.2.0 resolution: "@octokit/openapi-types@npm:17.2.0" @@ -14462,7 +11635,7 @@ __metadata: languageName: node linkType: hard -"@octokit/types@npm:^6.0.3, @octokit/types@npm:^6.10.0, @octokit/types@npm:^6.12.2, @octokit/types@npm:^6.16.1, @octokit/types@npm:^6.8.2": +"@octokit/types@npm:^6.0.3, @octokit/types@npm:^6.10.0, @octokit/types@npm:^6.12.2, @octokit/types@npm:^6.16.1": version: 6.41.0 resolution: "@octokit/types@npm:6.41.0" dependencies: @@ -14480,6 +11653,15 @@ __metadata: languageName: node linkType: hard +"@octokit/types@npm:^8.0.0": + version: 8.2.1 + resolution: "@octokit/types@npm:8.2.1" + dependencies: + "@octokit/openapi-types": ^14.0.0 + checksum: 92f2fe5ea8c4c6ddbb2363c74cd865c64e5753eaa4895bc925b5064390890b1441c5406015d8a92285f386cc7e6fe714c47fe4beda370fcda9177153299c9e37 + languageName: node + linkType: hard + "@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.2.3": version: 9.2.3 resolution: "@octokit/types@npm:9.2.3" @@ -14582,8 +11764,8 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.9.0 - resolution: "@openapitools/openapi-generator-cli@npm:2.9.0" + version: 2.13.2 + resolution: "@openapitools/openapi-generator-cli@npm:2.13.2" dependencies: "@nestjs/axios": 3.0.1 "@nestjs/common": 10.3.0 @@ -14597,6 +11779,7 @@ __metadata: console.table: 0.10.0 fs-extra: 10.1.0 glob: 7.2.3 + https-proxy-agent: 7.0.4 inquirer: 8.2.6 lodash: 4.17.21 reflect-metadata: 0.1.13 @@ -14604,83 +11787,83 @@ __metadata: tslib: 2.6.2 bin: openapi-generator-cli: main.js - checksum: 102040381b42edbab4fa34aa49c3cf8188fdb892c3e251bcb5bdf7c599597f3572d52d44fed7bead5fcaec24d624491c20dc96d2f164fa44e7fc232c7d787f69 + checksum: 553458ffface4090f117ec488352f664bb4656b645ef51faf5be35f27e739ac5c8931adf401309dfa0aad7ceefa39fb267d452b72d7a22f0fdb26d988d73b642 languageName: node linkType: hard "@opensearch-project/opensearch@npm:^2.2.1": - version: 2.5.0 - resolution: "@opensearch-project/opensearch@npm:2.5.0" + version: 2.7.0 + resolution: "@opensearch-project/opensearch@npm:2.7.0" dependencies: aws4: ^1.11.0 debug: ^4.3.1 hpagent: ^1.2.0 ms: ^2.1.3 secure-json-parse: ^2.4.0 - checksum: f9a4afa06c2917ffb76baac1ee1df9b8cf4594af6aded451b7c4838a4a0320101a432c0cbd3586d3533a4eb662fc414d4f1b315b73fac5b7a0c1d5f0ff0ac6ed + checksum: 6905373048d3896e158de8a229b1110828cf0cbffee3180fcd98b114a025f11e8938124863106544df09d7aa587b41843e2818fe03f34e33a27abcd1601740fe languageName: node linkType: hard "@opentelemetry/api@npm:^1.0.1, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0, @opentelemetry/api@npm:^1.4.1": - version: 1.7.0 - resolution: "@opentelemetry/api@npm:1.7.0" - checksum: 2398cbe65f199c3a7050125b3ad9c835f789bb0a616665e9c7f4475a29ac8334b6a3c15f38db48d345b522180c41c00b04cc174cd0eeffba98eb4874a565fa7e + version: 1.8.0 + resolution: "@opentelemetry/api@npm:1.8.0" + checksum: 0e32079975f05bee6de2ad8ade097f0afdc63f462c76550150fce2444c73ab92aaf851ac85e638b6e3b269da6640ac7e63f33913a0fd7df9f9beec2e100759df languageName: node linkType: hard -"@opentelemetry/core@npm:1.21.0": - version: 1.21.0 - resolution: "@opentelemetry/core@npm:1.21.0" +"@opentelemetry/core@npm:1.23.0": + version: 1.23.0 + resolution: "@opentelemetry/core@npm:1.23.0" dependencies: - "@opentelemetry/semantic-conventions": 1.21.0 + "@opentelemetry/semantic-conventions": 1.23.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.8.0" - checksum: 857eb667732edd1ad20107446935f1860b67602ab78493c2d0fc1711fdff0d8d1b63afcf1ea28468d62605e1237a38feb641ed9a154c3af87adb21b54101ba65 + "@opentelemetry/api": ">=1.0.0 <1.9.0" + checksum: 88aa733364c42f90a61a6efc8b5138dcfed4763f3a0692d957d506a6fe49db943169a0631ad762ac7569723faf5eaca092d6590eca1ad8ff77583fb10512a06b languageName: node linkType: hard -"@opentelemetry/exporter-prometheus@npm:^0.48.0": - version: 0.48.0 - resolution: "@opentelemetry/exporter-prometheus@npm:0.48.0" +"@opentelemetry/exporter-prometheus@npm:^0.50.0": + version: 0.50.0 + resolution: "@opentelemetry/exporter-prometheus@npm:0.50.0" dependencies: - "@opentelemetry/core": 1.21.0 - "@opentelemetry/resources": 1.21.0 - "@opentelemetry/sdk-metrics": 1.21.0 + "@opentelemetry/core": 1.23.0 + "@opentelemetry/resources": 1.23.0 + "@opentelemetry/sdk-metrics": 1.23.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: e003fb18f2a0e2010901b4f2ebd72f8a3b79c6961426e122e428babede7f6926fbba10f7483c524411bb024e809623782812e2a07d937b04c6425d5bf4559671 + checksum: 0bb3e6c36f2a6ef4822d31eb23254e6f6380b3bf50b29767349881ce606bd685bb4e728adb93187c9df190291e3d64f7f98593f96ec7bb5eff76be9e338f1d05 languageName: node linkType: hard -"@opentelemetry/resources@npm:1.21.0": - version: 1.21.0 - resolution: "@opentelemetry/resources@npm:1.21.0" +"@opentelemetry/resources@npm:1.23.0": + version: 1.23.0 + resolution: "@opentelemetry/resources@npm:1.23.0" dependencies: - "@opentelemetry/core": 1.21.0 - "@opentelemetry/semantic-conventions": 1.21.0 + "@opentelemetry/core": 1.23.0 + "@opentelemetry/semantic-conventions": 1.23.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.8.0" - checksum: 79866dd673aa0b3cc4c2bbe614af48b7fa15e09661875c160eb00667832a83f531ea7c4bea8f1d3d97ee01ab5107152125ddc85837bf984c441471707417cacb + "@opentelemetry/api": ">=1.0.0 <1.9.0" + checksum: e780d34f8107cdd2853aab3c0c680a817da54d9c6020bba9b8a6b8e7b637487592d87440e5c4f09a10dfad7aededde34532e0e337a5c2d441bf26dd921836cfc languageName: node linkType: hard -"@opentelemetry/sdk-metrics@npm:1.21.0, @opentelemetry/sdk-metrics@npm:^1.13.0": - version: 1.21.0 - resolution: "@opentelemetry/sdk-metrics@npm:1.21.0" +"@opentelemetry/sdk-metrics@npm:1.23.0, @opentelemetry/sdk-metrics@npm:^1.13.0": + version: 1.23.0 + resolution: "@opentelemetry/sdk-metrics@npm:1.23.0" dependencies: - "@opentelemetry/core": 1.21.0 - "@opentelemetry/resources": 1.21.0 + "@opentelemetry/core": 1.23.0 + "@opentelemetry/resources": 1.23.0 lodash.merge: ^4.6.2 peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.8.0" - checksum: 393d01c15ab000bb2b05c95233e58d9e8341b0e1e2e437b7257291bf6e1edfec2971aaf76f5bc974a2291c4678dfcaed699676223e18a5f33018d3e4825b479b + "@opentelemetry/api": ">=1.3.0 <1.9.0" + checksum: ca24338ceb537fa9c4d9a87b4e81164db1275d96ecf97347a2e48f07cfaab0fb25013091898fb435751eb488efcd6d01232150cce3c034263fe293ce6bd83abd languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:1.21.0": - version: 1.21.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.21.0" - checksum: 8bd477ddabecf87499985de773265b35a09142071b14e1e427237181e90c4e0f5b1959d009acfb81b80319debbcb453f137e6686c63b60af9656aa611f607b77 +"@opentelemetry/semantic-conventions@npm:1.23.0": + version: 1.23.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.23.0" + checksum: a4bd6e67e0fe5821be7dc14baff77574e9881d208a63740a3ab416b367c132bc77cf3c0b398daea1344c9af2f32383cf6c7da3141ba6d1e87e30756e4f2234b8 languageName: node linkType: hard @@ -14718,13 +11901,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.41.2 - resolution: "@playwright/test@npm:1.41.2" + version: 1.43.1 + resolution: "@playwright/test@npm:1.43.1" dependencies: - playwright: 1.41.2 + playwright: 1.43.1 bin: playwright: cli.js - checksum: 87d9e725106111b2af1b2dec32454cd2a2d9665ff735669dc751caa30240e6db595ecfb9422719fa65dcff6ca19dea93ac2ae70d587efddde31def0754549d4c + checksum: f9db387b488a03125e5dc22dd7ffed9c661d1f2428188912a35a2235b3bd9d826b390e7600d04998639994f5a96695b9dc9034ca9cb59e261d2fdee93a60df3f languageName: node linkType: hard @@ -14890,7 +12073,7 @@ __metadata: languageName: node linkType: hard -"@pnpm/workspace.pkgs-graph@npm:^2.0.14": +"@pnpm/workspace.pkgs-graph@npm:2.0.14": version: 2.0.14 resolution: "@pnpm/workspace.pkgs-graph@npm:2.0.14" dependencies: @@ -14982,6 +12165,24 @@ __metadata: languageName: node linkType: hard +"@puppeteer/browsers@npm:2.2.1": + version: 2.2.1 + resolution: "@puppeteer/browsers@npm:2.2.1" + dependencies: + debug: 4.3.4 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.4.0 + semver: 7.6.0 + tar-fs: 3.0.5 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + bin: + browsers: lib/cjs/main-cli.js + checksum: c2ec8bac9978ae6279d67442a3a81c517db1e172bd4603d1983eb48de12b088d8b565b1817abe21ba6df76be9a68e3fc543d4c7111c964a93f3ac9b14f7c76e5 + languageName: node + linkType: hard + "@radix-ui/primitive@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/primitive@npm:1.0.1" @@ -15579,10 +12780,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.15.0": - version: 1.15.0 - resolution: "@remix-run/router@npm:1.15.0" - checksum: 0b5ea6b2e7bb7f3266005e033337a6fed29c458aa5ddc9a97a90ff19813ae6dfb4392871722d66d7e8db93a29760a8257830a9af58824b3a3363ed58e1e471d8 +"@remix-run/router@npm:1.15.3": + version: 1.15.3 + resolution: "@remix-run/router@npm:1.15.3" + checksum: 9e70bd334d99fdf9285f0885c10353d7e25f66369080f551d997e3ce204e1af3a12d6f12b091f94a2dc9a54c80598bbe3c5194b57cbae17b7b40ab815dcd49a0 languageName: node linkType: hard @@ -15600,9 +12801,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core@npm:5.17.0": - version: 5.17.0 - resolution: "@rjsf/core@npm:5.17.0" +"@rjsf/core@npm:5.18.2": + version: 5.18.2 + resolution: "@rjsf/core@npm:5.18.2" dependencies: lodash: ^4.17.21 lodash-es: ^4.17.21 @@ -15610,28 +12811,28 @@ __metadata: nanoid: ^3.3.7 prop-types: ^15.8.1 peerDependencies: - "@rjsf/utils": ^5.16.x + "@rjsf/utils": ^5.18.x react: ^16.14.0 || >=17 - checksum: adfcbd1d44cef5f9e5de2873096085abd03b146dcef2c9c226060341ce2c935b5399e4ad5f00ad5091394224f5859bd6ac9bac533537dc5c8e2edb16b52b67cf + checksum: b8b20bd75090b15b19e176aa766c037f3a7f1a27dbbde07ab095376a85e0027fd441b6e37355c8d3b389393db1f1b27699769034146040864c63a8f110d5e2d7 languageName: node linkType: hard -"@rjsf/material-ui@npm:5.17.0": - version: 5.17.0 - resolution: "@rjsf/material-ui@npm:5.17.0" +"@rjsf/material-ui@npm:5.18.2": + version: 5.18.2 + resolution: "@rjsf/material-ui@npm:5.18.2" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 - "@rjsf/core": ^5.16.x - "@rjsf/utils": ^5.16.x + "@rjsf/core": ^5.18.x + "@rjsf/utils": ^5.18.x react: ^16.14.0 || >=17 - checksum: c56fb145042cd1af7c6f0e149f4c7e61a9c4b9cf9e6dce40cd4f691da569e7d14ca1b922a0f54aafd6ae6900772cdccbdf3719ea83a0be2d0cc3a5f0486939f3 + checksum: fc898efa7834e32c59e9f607c8650e39689252c6bc7e84f081ab131c90b92c28787288c647b81841b2cfab40231660324b8cc35bf7d05649f31bf70e207d4a7e languageName: node linkType: hard -"@rjsf/utils@npm:5.15.1": - version: 5.15.1 - resolution: "@rjsf/utils@npm:5.15.1" +"@rjsf/utils@npm:5.18.2": + version: 5.18.2 + resolution: "@rjsf/utils@npm:5.18.2" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -15640,143 +12841,21 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: ec0d56bf2627d55759a59090db0d59402244a6fae64528f66dde1f5de2eaaf2a6841dea7bbb185eb36fd344b3abd4825b2b422f3b1b0bb05365847073aa1e790 + checksum: 19342ce160f5f2ff1b1448bc61b0767c9b19a3c365fe3dca221c9178dff6b54123bdfe9dd4b0314aa7965011edb0e76029f7e76226936066bfacbaaa619546b4 languageName: node linkType: hard -"@rjsf/utils@npm:5.17.0": - version: 5.17.0 - resolution: "@rjsf/utils@npm:5.17.0" - dependencies: - json-schema-merge-allof: ^0.8.1 - jsonpointer: ^5.0.1 - lodash: ^4.17.21 - lodash-es: ^4.17.21 - react-is: ^18.2.0 - peerDependencies: - react: ^16.14.0 || >=17 - checksum: 01d0001f83083764a8552e009aa7df084621df9d1fc6ccdfad9d534513084421b1ad7494cab77b9b8205d680fd915f612d87800e20ab242e7066f33184c73d4f - languageName: node - linkType: hard - -"@rjsf/validator-ajv8@npm:5.17.0": - version: 5.17.0 - resolution: "@rjsf/validator-ajv8@npm:5.17.0" +"@rjsf/validator-ajv8@npm:5.18.2": + version: 5.18.2 + resolution: "@rjsf/validator-ajv8@npm:5.18.2" dependencies: ajv: ^8.12.0 ajv-formats: ^2.1.1 lodash: ^4.17.21 lodash-es: ^4.17.21 peerDependencies: - "@rjsf/utils": ^5.16.x - checksum: c6e20e04b33e5b37e55a3d378add22c36970c9c92b6d692003acc5cfaff10282ead6ff775b1fa152ead66e451bc3f0cc518730c6f0ed68a7ecfbcd4098d59f32 - languageName: node - linkType: hard - -"@roadiehq/backstage-plugin-buildkite@npm:^2.0.8": - version: 2.1.17 - resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.17" - dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/core-components": ^0.13.8 - "@backstage/core-plugin-api": ^1.8.0 - "@backstage/plugin-catalog-react": ^1.9.1 - "@backstage/theme": ^0.4.4 - "@material-ui/core": ^4.12.1 - "@material-ui/icons": ^4.11.2 - "@material-ui/lab": 4.0.0-alpha.57 - history: ^5.0.0 - moment: ^2.29.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router: 6.0.0-beta.0 || ^6.3.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 218a614d81ee89b2a1613979258788d612c675da2af7ffdcecaa6e47206d6aa4f463defc376f5c4a53ba2136038d0e0659ba80182bd8001c144323e40f3ff5ab - languageName: node - linkType: hard - -"@roadiehq/backstage-plugin-github-insights@npm:^2.0.5": - version: 2.3.23 - resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.23" - dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/core-components": ^0.13.8 - "@backstage/core-plugin-api": ^1.8.0 - "@backstage/integration-react": ^1.1.21 - "@backstage/plugin-catalog-react": ^1.9.1 - "@backstage/theme": ^0.4.4 - "@date-io/core": 2.10.7 - "@material-ui/core": ^4.11.0 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.45 - "@octokit/rest": ^19.0.3 - "@octokit/types": ^9.0.0 - history: ^5.0.0 - immer: 9.0.7 - react-use: ^17.2.4 - zustand: 3.6.9 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 07dd3df1d8f99ea6f2910d343c361bd27b249fbd1e982fc42630ddc8e530901ef42e9a3cf5a944c80abd0c5be25cca716c12a838057ec1e83ad538a9462033e4 - languageName: node - linkType: hard - -"@roadiehq/backstage-plugin-github-pull-requests@npm:^2.2.7": - version: 2.5.20 - resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.5.20" - dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/core-components": ^0.13.8 - "@backstage/core-plugin-api": ^1.8.0 - "@backstage/plugin-catalog-react": ^1.9.1 - "@backstage/plugin-home-react": ^0.1.5 - "@material-ui/core": ^4.11.0 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": ^4.0.0-alpha.60 - "@octokit/rest": ^19.0.3 - "@octokit/types": ^9.0.0 - "@types/node-fetch": ^2.5.7 - history: ^5.0.0 - lodash: ^4.17.21 - luxon: ^3.3.0 - msw: ^1.0.1 - node-fetch: ^2.6.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: f9ac5bbff5173eff98002f3f8bd7b7fe349723039481651b1e81b7aa5bbaaa799f4cd51d5425a5d74cebf3d0f5bb7340a0c4091b858addc45791881c3802f7a7 - languageName: node - linkType: hard - -"@roadiehq/backstage-plugin-travis-ci@npm:^2.0.5": - version: 2.1.17 - resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.17" - dependencies: - "@backstage/catalog-model": ^1.4.3 - "@backstage/core-components": ^0.13.8 - "@backstage/core-plugin-api": ^1.8.0 - "@backstage/plugin-catalog-react": ^1.9.1 - "@backstage/theme": ^0.4.4 - "@material-ui/core": ^4.11.3 - "@material-ui/icons": ^4.11.2 - "@material-ui/lab": 4.0.0-alpha.57 - cross-fetch: ^3.1.3 - date-fns: ^2.18.0 - history: ^5.0.0 - moment: ^2.29.1 - react-use: ^17.2.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 - react-dom: ^16.13.1 || ^17.0.0 - react-router: 6.0.0-beta.0 || ^6.3.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: fcf0b788a2f004a6eff181ff9f9babd07aceb630333b1a3e8ce7fb37b6e9a303444ecc9521a920f6aced2c9a081fa3024ee9079d1bb9f453e2d322af04f57113 + "@rjsf/utils": ^5.18.x + checksum: 0ed953615b0619a376edfa95ccb891f1aa701e1915a09de562fb1c13a69a4902887359dcf68597f78ffc0a9be9c402c1488ef8ae552be8c8f48aeb7d59d3eae3 languageName: node linkType: hard @@ -15864,7 +12943,7 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^4.1.1, @rollup/pluginutils@npm:^4.2.0, @rollup/pluginutils@npm:^4.2.1": +"@rollup/pluginutils@npm:^4.2.0, @rollup/pluginutils@npm:^4.2.1": version: 4.2.1 resolution: "@rollup/pluginutils@npm:4.2.1" dependencies: @@ -15874,7 +12953,7 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.1.0": +"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.0.5, @rollup/pluginutils@npm:^5.1.0": version: 5.1.0 resolution: "@rollup/pluginutils@npm:5.1.0" dependencies: @@ -15890,12 +12969,115 @@ __metadata: languageName: node linkType: hard -"@rrweb/types@npm:^2.0.0-alpha.11": - version: 2.0.0-alpha.11 - resolution: "@rrweb/types@npm:2.0.0-alpha.11" - dependencies: - rrweb-snapshot: ^2.0.0-alpha.11 - checksum: 63c815597daacb7f6978c973c53e6e8f10301c0224ce675792c2c8a2cdf059845aefef92b2ee259837813081796398e3432195fdd8cb72c437ab77a20c50b2c7 +"@rollup/rollup-android-arm-eabi@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.16.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-android-arm64@npm:4.16.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.16.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.16.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.16.2" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.16.2" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.16.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.16.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.16.2" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.16.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.16.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.16.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.16.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.16.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.16.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.16.2": + version: 4.16.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.16.2" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -15941,20 +13123,20 @@ __metadata: languageName: node linkType: hard -"@sagold/json-pointer@npm:^5.1.1": - version: 5.1.1 - resolution: "@sagold/json-pointer@npm:5.1.1" - checksum: d0aa16330997d479b8035f22cab3e2f63f3ae8d9e5ab1137746056581606baba47a7b15116a751c9ea430e1aba9ee7a5459a3ee352509a4afca109cce1dcd9e1 +"@sagold/json-pointer@npm:^5.1.2": + version: 5.1.2 + resolution: "@sagold/json-pointer@npm:5.1.2" + checksum: e29afd3f7e21196e369b332e99504472742ac5a0c141438071e822d3bd9fa55164a14dd25cc0396f2d50b0f9d9b76161e81c83c2035e16e72731b98130968cda languageName: node linkType: hard -"@sagold/json-query@npm:^6.1.0": - version: 6.1.1 - resolution: "@sagold/json-query@npm:6.1.1" +"@sagold/json-query@npm:^6.1.3": + version: 6.2.0 + resolution: "@sagold/json-query@npm:6.2.0" dependencies: - "@sagold/json-pointer": ^5.1.1 + "@sagold/json-pointer": ^5.1.2 ebnf: ^1.9.1 - checksum: bc9697ae45efce92600185491679379e44d494ed13fdb927984aaade40939e6ab2e6f982cf8b1b8b29ec80df560bab0052a86b349cc0071e0e5feb40c465ba54 + checksum: 1c29a1bb81fa14573d37f485170083b0f43ecee66d08422f8ff6d3083ab65954cff9178502132d87175f34cf1e432e1ee7985d60417e350a730de907c63ef633 languageName: node linkType: hard @@ -16035,13 +13217,6 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.42 - resolution: "@sinclair/typebox@npm:0.24.42" - checksum: 83a3083b71063ad270669308634f7c5b473272da71cbc405343b2ff774d641ec2be0993e0a61386f8ef3f8b786c173dc01921a5bc6627d95657eb98f19f1a4c4 - languageName: node - linkType: hard - "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -16115,385 +13290,384 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/abort-controller@npm:2.1.1" +"@smithy/abort-controller@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/abort-controller@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 4bfad0d6b3a75bd1e6f997aa41cc9d8ba8bfdf548cfe703553ad7b42f0bf3e06b595d584be7b9ab90d2e3b22aacad94c02c32e21bea96e46933443f09c59523a + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: d0d7fcaa7b67b04c9ad825017110cc294ff06af07f8054ac3b75d8de88ff5fbef1d08f5c1ae672db1839d14ce25f277c459d2b7b7263cbe9e6c3d4518a19230e languageName: node linkType: hard -"@smithy/chunked-blob-reader-native@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/chunked-blob-reader-native@npm:2.1.1" +"@smithy/chunked-blob-reader-native@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/chunked-blob-reader-native@npm:2.2.0" dependencies: - "@smithy/util-base64": ^2.1.1 - tslib: ^2.5.0 - checksum: 82f475b9090e12306292d46b27cca841691a251db5c9b5520830f7e5c947bbe69b497619773b25754dcdd8580620fd3677f478e1325501549f6182d78e95c583 + "@smithy/util-base64": ^2.3.0 + tslib: ^2.6.2 + checksum: ac619f18844e8a8288672c40b8967a82b78f5398119638b3e4fcadf451a3356139307c2d9f24c8c041530238f1ce6e0f90ce82adfcb050d08afefa2f0541c2d0 languageName: node linkType: hard -"@smithy/chunked-blob-reader@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/chunked-blob-reader@npm:2.1.1" +"@smithy/chunked-blob-reader@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/chunked-blob-reader@npm:2.2.0" dependencies: - tslib: ^2.5.0 - checksum: e9d7f6f80fffccb5b615aa4eecf0e48849e625a70a79acc371b74b3d5e6dffed3b0d21d8beafe2e1cc1ebc235b8c24ed7d7e31e8c3565d97efe1238dda82c813 + tslib: ^2.6.2 + checksum: f5acb1e812f97d7c233ccf955557ac10c7e94c8c9610d2fad715d1010fe30ee686a93a5d6e589ce8ae4eb7cf201d5eab61cee5e8646bbebdfa8a5f23693d7a5a languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/config-resolver@npm:2.1.1" +"@smithy/config-resolver@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/config-resolver@npm:2.2.0" dependencies: - "@smithy/node-config-provider": ^2.2.1 - "@smithy/types": ^2.9.1 - "@smithy/util-config-provider": ^2.2.1 - "@smithy/util-middleware": ^2.1.1 - tslib: ^2.5.0 - checksum: 18c8af60cbc528887a82dc0eabaf0b398d868511dc6b10fa01f41c77ea9c2679ab2137feaee51aa9060dbc5c46fc33325a659f4bd54549c203f64e15dbacbc0a + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: dcb15d40faf46c370cd83dfbf1e632fae29c64c500b33b53850a520cfb02c9fa6f7e239c07824793b47645462567d51cb1554c02f9ec4531bd51bc759aede2ed languageName: node linkType: hard -"@smithy/core@npm:^1.3.2": - version: 1.3.2 - resolution: "@smithy/core@npm:1.3.2" +"@smithy/core@npm:^1.4.2": + version: 1.4.2 + resolution: "@smithy/core@npm:1.4.2" dependencies: - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-retry": ^2.1.1 - "@smithy/middleware-serde": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/util-middleware": ^2.1.1 - tslib: ^2.5.0 - checksum: 5c716b170aa8fb6485b7c98d2d59c44a7333566345727472fb9fabbe86473b33f090fa7a3e08de6ca10829a048c5f20bd238da7da471214789171c7e0a4460a9 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: 414ec1c392ab5346f2b833f310078d7e850df8b9e5db6fedbce65116146c2fda116d56db841401ba05b5e7399a5f5c426870d324bf6fd060143ce66e2f3eafbb languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.2.1": - version: 2.2.1 - resolution: "@smithy/credential-provider-imds@npm:2.2.1" +"@smithy/credential-provider-imds@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/credential-provider-imds@npm:2.3.0" dependencies: - "@smithy/node-config-provider": ^2.2.1 - "@smithy/property-provider": ^2.1.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - tslib: ^2.5.0 - checksum: a4e693719384440718728772ea2126be133bbc83fa7bfcefd236942ccb28d1390f1b32fe3262bf330ba4c8e600d01ac73a57110eb42462ec1eb6bbd51e2676a6 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + tslib: ^2.6.2 + checksum: dd57e09e60bd51ed103f7a5363a43e1373470ea3cee04ace66f5bbaafab005355ffbfa3e137e2ecac34aa28911fb5b6ecac60845846c6a4a5432f3e57a74b837 languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/eventstream-codec@npm:2.1.1" +"@smithy/eventstream-codec@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-codec@npm:2.2.0" dependencies: "@aws-crypto/crc32": 3.0.0 - "@smithy/types": ^2.9.1 - "@smithy/util-hex-encoding": ^2.1.1 - tslib: ^2.5.0 - checksum: 7e59028a69e669d1ca1a0fef788f9892a427fad32f33ded731cbfa3bde0163acbc1e7d207e0ce3eae2d3b53f48dce7a99ded092122cdf78e4f392cffd762bfe3 + "@smithy/types": ^2.12.0 + "@smithy/util-hex-encoding": ^2.2.0 + tslib: ^2.6.2 + checksum: ae59067964e19c6728b1be74a6e19793e4d3decdcbcea546bd40f77c3cc1eacc48c30272ef68927ba477c2b6450d023474f2dec516dfd93e204150ba18cab697 languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/eventstream-serde-browser@npm:2.1.1" +"@smithy/eventstream-serde-browser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-browser@npm:2.2.0" dependencies: - "@smithy/eventstream-serde-universal": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: c909b620de25e9779653742012c665df8c76bf5193bb79054ef302bc3c08b0fa5620884a5965a3a6ebbb4f059da1b05221662a7a652aa979f4830f26c534be60 + "@smithy/eventstream-serde-universal": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: c00bd592365f42ddafcad83f06d3c85ce8ee21bd806de903043ef132de9acca8bf1592ed811b11daba1742332928fc73a66c9032b06df2f6526da0339918f8d5 languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/eventstream-serde-config-resolver@npm:2.1.1" +"@smithy/eventstream-serde-config-resolver@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-config-resolver@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 14d4d1c638be460290eb05dec3a700d742f8ce77814c1c235fbd7cf248941a387595f1cd684b9acfc3e081a8d9e6dc2810f10c894b3e08f16f0c3adb130cb736 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: a35dbcbc14ad1825ce22a9e7daac93067d8ade6173a3ce33b819eed61390f8d93ea63b70945f6d1bced175fad58def3d09a14ee3043c63a798ecef407b2d1701 languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/eventstream-serde-node@npm:2.1.1" +"@smithy/eventstream-serde-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-node@npm:2.2.0" dependencies: - "@smithy/eventstream-serde-universal": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 4be3dd11854d66310273bae07faafd4ca872158be8d3ef7bdc1dec55a175e983975750ebdaf762e74daf80495e379bd2791971a50899076865759a75b2634d73 + "@smithy/eventstream-serde-universal": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1d4971b99654c4672716608a63e668ccefd78cc1806c0ea4df5c3cc0ca0208b7647f7914d2c77a37d0a29b31b66cff660ce2ab2f46f56d997c9a58ea6b6241b2 languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/eventstream-serde-universal@npm:2.1.1" +"@smithy/eventstream-serde-universal@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-universal@npm:2.2.0" dependencies: - "@smithy/eventstream-codec": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 99c7cf5b869f8e6323e976335a3238b77d3b1c32005fc78093d448981883294e4d59bcbd419e88d6a53c76aab01c27bc9af63a5dfed9451d2302eaf6ccddbd64 + "@smithy/eventstream-codec": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: c28038c2f57deed7b5e0e5f8ab8150d4a7947f2971241da96ef1d53b45d83dfa661717065f059099c420ee66ae2455818ae124bb8601b609558040d4a7509227 languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.4.1": - version: 2.4.1 - resolution: "@smithy/fetch-http-handler@npm:2.4.1" +"@smithy/fetch-http-handler@npm:^2.5.0": + version: 2.5.0 + resolution: "@smithy/fetch-http-handler@npm:2.5.0" dependencies: - "@smithy/protocol-http": ^3.1.1 - "@smithy/querystring-builder": ^2.1.1 - "@smithy/types": ^2.9.1 - "@smithy/util-base64": ^2.1.1 - tslib: ^2.5.0 - checksum: c23701d45bca6842b5206939ccd587e3482ace9f656ae3dca92ff0bad3fefb846cc33683dff41a19186f2a5662ca6cd66c8aefda4664b7dfd95f9a616055a1c1 + "@smithy/protocol-http": ^3.3.0 + "@smithy/querystring-builder": ^2.2.0 + "@smithy/types": ^2.12.0 + "@smithy/util-base64": ^2.3.0 + tslib: ^2.6.2 + checksum: 91a58ac32c6b4afc6d7fb2b9ac3e3b817171f76e09b013a6506308b044455054444a92e1acbd8f98bdd159b15fdd44b1e3fb52c21cbb2e69be8e3698d2206021 languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/hash-blob-browser@npm:2.1.1" +"@smithy/hash-blob-browser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/hash-blob-browser@npm:2.2.0" dependencies: - "@smithy/chunked-blob-reader": ^2.1.1 - "@smithy/chunked-blob-reader-native": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: f4dc57c11ef32ddea0e7094d2c230aa274f1e410d84c789d8f5e2ed8a090da8675ca76da9605d297285324107ea8106af1c2aab2859bd62d6e9a8db415eb8e55 + "@smithy/chunked-blob-reader": ^2.2.0 + "@smithy/chunked-blob-reader-native": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1b748b4449ccee723c8b47a412491283fa7b5a2a6c27b0b73e03d905c2af70b56b74d63a658d8ef0bd330cc4617bc11431c86e24a4932b4722aad08e1b25e576 languageName: node linkType: hard -"@smithy/hash-node@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/hash-node@npm:2.1.1" +"@smithy/hash-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/hash-node@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - "@smithy/util-buffer-from": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: 5d5aae69b94dcb8abaf9f6a5b53ee320c9e126445c4540fcf2169e8ea7ebd953acff7fd77ba514614f6ebbb0baf412e878eebcc3427a5b9b6f8ee39abbc59230 + "@smithy/types": ^2.12.0 + "@smithy/util-buffer-from": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 3305b5778fa99558375b16629ad98fd00a1fb33ea905037977b0a7c93d92c8de1481756ef7dbc004e45210b23f983dec04bcd13d43c98f36a5f47291cbed9d89 languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/hash-stream-node@npm:2.1.1" +"@smithy/hash-stream-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/hash-stream-node@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: da3c4ba14c648ee0d2fe7d3298d601150ee0ce5ac0c7d9f54a88148b5f67b03513b41560f76f5f109f11196547b4dc4f26e314774794596d7e3ee1103a9906a8 + "@smithy/types": ^2.12.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 191d76fd1df705c32d24463794f8b8b391061c7ca7265591cd4f070259fa80395c2f115fd3d37f6bb3a4a2303b3811a31509ea767d0c3d0a9644789ae8283118 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/invalid-dependency@npm:2.1.1" +"@smithy/invalid-dependency@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/invalid-dependency@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: f95ecd9acd337a408b6608a3f451b24a61e26149878f61fc7855c724888f0d28abf0b798d16990dadb7eafc8027098f934c0cd44e75d01d31617bd1fbfd93935 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: ed17980ccdf4c564cfcb517f3959dfeb7c7dbddd76eaf2c9e10031ebd19e78e56609df3377626215e51a6c4b98db03cfa88ad46f15ba26bb55c34351f3182a98 languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/is-array-buffer@npm:2.1.1" +"@smithy/is-array-buffer@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/is-array-buffer@npm:2.2.0" dependencies: - tslib: ^2.5.0 - checksum: 5dbf9ed59715c871321d0624e3842340c1d662d2e8b78313d1658d39eb793b3ac5c379d573eba0a2ca3add9b313848d4d93fd04bb8565c75fbab749928b239a6 + tslib: ^2.6.2 + checksum: cd12c2e27884fec89ca8966d33c9dc34d3234efe89b33a9b309c61ebcde463e6f15f6a02d31d4fddbfd6e5904743524ca5b95021b517b98fe10957c2da0cd5fc languageName: node linkType: hard -"@smithy/md5-js@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/md5-js@npm:2.1.1" +"@smithy/md5-js@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/md5-js@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: d15bc426a46d80d450b555a5ccd3d5a6bf37190f4b9ccb705852cd53ce61e4fe6fb08a569b87303ee787da57023f2b75f0e7893644af16c89e9aaf513f8afff3 + "@smithy/types": ^2.12.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: ae343c198a8d8c6689bcb1d7f766e29578d370e8d79180db9b6183b5c74ac091829e8abe3053df0589f53324c01a79c7f9e889e5cd92094e3b5c4be96fb7b970 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/middleware-content-length@npm:2.1.1" +"@smithy/middleware-content-length@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/middleware-content-length@npm:2.2.0" dependencies: - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: cb0ea801f72a1a01f5956b3526df930fc19762b07d43a3871ff29815f621603410753d37710d72675d9761b93da32a38cfd5195582de8b6a47e299b1f073be25 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1eae8d2b6f432ce9a849e741d4f2426baee8a51f22a5262c11802e125078ee33d9d8f4183fb142043ba9d1371adad9c835c784333a394d865fb248339f7482e6 languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.4.1": - version: 2.4.1 - resolution: "@smithy/middleware-endpoint@npm:2.4.1" +"@smithy/middleware-endpoint@npm:^2.5.1": + version: 2.5.1 + resolution: "@smithy/middleware-endpoint@npm:2.5.1" dependencies: - "@smithy/middleware-serde": ^2.1.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/url-parser": ^2.1.1 - "@smithy/util-middleware": ^2.1.1 - tslib: ^2.5.0 - checksum: 685f74c76cba205bdb20ad7bda449b73e498ae2e9074a026d48b38c7b4456d8a0cfb4fdb48625b65f93f3a75e92eaf7951db28f8e9f44e50ce18fd59a7b325af + "@smithy/middleware-serde": ^2.3.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: 7ac2a35a6f52c33d868fc4b73330ae34fecfc43c59b8d501ee9fb81924c6747494700b55b3025b83fe7bea3d4e323c8853ec5b117c17cccf06cc27bbc4f492b2 languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/middleware-retry@npm:2.1.1" - dependencies: - "@smithy/node-config-provider": ^2.2.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/service-error-classification": ^2.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-retry": ^2.1.1 - tslib: ^2.5.0 - uuid: ^8.3.2 - checksum: a4bc59d2ff8f65367aeb93391a2aafc7caf8031d8b2dfb32ee35748cdc46e06d5182c37bee90d7a107e890959bd40e6a7f4041bc1b0b36a99d14919b1cc78812 - languageName: node - linkType: hard - -"@smithy/middleware-serde@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/middleware-serde@npm:2.1.1" - dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: ed77b80ac6b68640ee4bf8310bc4d9f5aa13de2741333f6f03a4983e897fa66e0de057d178e78d9ba095d5686d3e4531437c9dd2583366efe948bd75b2aa8581 - languageName: node - linkType: hard - -"@smithy/middleware-stack@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/middleware-stack@npm:2.1.1" - dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 0d7c1051c96fcf19f7d5e96bc59484ce13df4e570c1da3eda74d23a7911b41eb61d6c378aad0aa21f7e9c72934148bdf39f9767c57abd4845aa4417a84e3f6e4 - languageName: node - linkType: hard - -"@smithy/node-config-provider@npm:^2.2.1": - version: 2.2.1 - resolution: "@smithy/node-config-provider@npm:2.2.1" - dependencies: - "@smithy/property-provider": ^2.1.1 - "@smithy/shared-ini-file-loader": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 62ed3124d888a10cac633a250fbe12d6c5b8aa75ea691889abebce227cbaf155f3db00fa6beb453fbd6147e667e70819d043da1750980669451281a28eafd285 - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.3.1": +"@smithy/middleware-retry@npm:^2.3.1": version: 2.3.1 - resolution: "@smithy/node-http-handler@npm:2.3.1" + resolution: "@smithy/middleware-retry@npm:2.3.1" dependencies: - "@smithy/abort-controller": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/querystring-builder": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: e6a514098f44cfc962318b15df79bb5e9de7fffe883fe073965879b2cf2436726709b5be14262871794104272e8506f793f8e77b8bf5b36398714a3a51512516 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/service-error-classification": ^2.1.5 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 5eebf9d26fccc6c8c517924463e93d244edebe52d120b28d5d705904f83773da1734296b8d57b4f30a15cbf36690e508f5946dfd56749cbcda501d08cb778933 languageName: node linkType: hard -"@smithy/property-provider@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/property-provider@npm:2.1.1" +"@smithy/middleware-serde@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/middleware-serde@npm:2.3.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: e87d70c4efe07e830cfb2094b046af89175b87b13259fba37641aa7bfc2ab0c7bf2397797ac48b92e1feb11bf6129b82b350519172093efd7ac4d3a4a98bbe2f + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 5393370c0f8a820d8ca36eccecff5b6434c4f81fbaad8800088fb4c8dad5312bf3eb47f67533784de959807bbb3379c23d81a1bcbaf8824254034dd2b83fd76b languageName: node linkType: hard -"@smithy/protocol-http@npm:^3.1.1": - version: 3.1.1 - resolution: "@smithy/protocol-http@npm:3.1.1" +"@smithy/middleware-stack@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/middleware-stack@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: a5be1c5b5bff18c5a35c23870e1ffa38da33e56f93bdd8f26c615f4c0d2d3e1effffe441e756c0b0ba3aad2dd0845332f634702bf8455ed865a04eebfef1329b + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 293d76764e327a5ada4ea7de268f451e62a6a56983ba7dcdbc63fdbb0427c01071a9a81d7807b16586977df829ce5d9587facbd9367b089841bbc9fc329ce6af languageName: node linkType: hard -"@smithy/querystring-builder@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/querystring-builder@npm:2.1.1" +"@smithy/node-config-provider@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/node-config-provider@npm:2.3.0" dependencies: - "@smithy/types": ^2.9.1 - "@smithy/util-uri-escape": ^2.1.1 - tslib: ^2.5.0 - checksum: b8623c7ef6d19fb21c41bfda29cce9c673ac501914085b39642ff5a72cf5742b19cd9de1a1851d13f2e1bbfc2e9522070b5ca32ed906aacf93f732a56e76098a + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 9c1dc6d97e0379d947498e7d64e593ea183d5f2c89dace4561c1c613850bf264581b597105c15d64ceabdea954e57ad8e6bf9e42642ddc3f737464f350ffbb5b languageName: node linkType: hard -"@smithy/querystring-parser@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/querystring-parser@npm:2.1.1" +"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.5.0": + version: 2.5.0 + resolution: "@smithy/node-http-handler@npm:2.5.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: bfac40793b0e42f4e25137db4e7d866debfa32557359cc41e02a23174a6fd8e0132f098cef5669a3ddf5211e477c9c97d4aa9039b35c7b4a29f2207236da236e + "@smithy/abort-controller": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/querystring-builder": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 2e63fafdac5bef62181994af2ec065b0f7f04eaed88fb2990a21a9925226fead5013cf4f232b527f3f4d9ffb68ccbe8cd263ad22a7351d36b0dc23e975929a0c languageName: node linkType: hard -"@smithy/service-error-classification@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/service-error-classification@npm:2.1.1" +"@smithy/property-provider@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/property-provider@npm:2.2.0" dependencies: - "@smithy/types": ^2.9.1 - checksum: 59a5e3cb0fb42d70fc2d85814124abbff60e28cc9aa45d87fde3370e25943abaf4b6baf62cc40e496c3687e9fa9161156a055ad29a4f7ce8dd7d937bbf49f9a7 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 8d257cbc5222baf6706e288c3b51196588f135878141f8af76fcb3f0abafc027ed46cf4bb938266d1906111175082ee85f73806d5a2b1c929aee16ec8b5283e6 languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/shared-ini-file-loader@npm:2.3.1" +"@smithy/protocol-http@npm:^3.3.0": + version: 3.3.0 + resolution: "@smithy/protocol-http@npm:3.3.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 89b0dfb65faab917fcb4a6a8f34a85d668a759ccbfd6c4dc3d6311e59a8f1b78baab1d97402c333d2207da810cb00de9d5b4379f114bde82135f9aa0d0069cab + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 6c1aaaee9f6ecfb841766938312268f30cbda253f172de7467463aae7d7bfea19a801ab570f3737334e992d2d0ee7446e6af6a6fd82b08533790c489289dff76 languageName: node linkType: hard -"@smithy/signature-v4@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/signature-v4@npm:2.1.1" +"@smithy/querystring-builder@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/querystring-builder@npm:2.2.0" dependencies: - "@smithy/eventstream-codec": ^2.1.1 - "@smithy/is-array-buffer": ^2.1.1 - "@smithy/types": ^2.9.1 - "@smithy/util-hex-encoding": ^2.1.1 - "@smithy/util-middleware": ^2.1.1 - "@smithy/util-uri-escape": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: fa3d4728b0bcf98e606a6e13a47f91efc6eb9edb6925ba48c3b9cecdf8170adf27e28a0684dabe385e8a7379d0743f52b19cd9a1a01884cd0f75c048c4324fd2 + "@smithy/types": ^2.12.0 + "@smithy/util-uri-escape": ^2.2.0 + tslib: ^2.6.2 + checksum: db492903302a694a0e982c37b9a74314160c5ee485742f24f8b6d0da66f121e7ff8588742a3a1964f6b983c15cacd52b883c5efa714882a754f575da7a7e014d languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/smithy-client@npm:2.3.1" +"@smithy/querystring-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/querystring-parser@npm:2.2.0" dependencies: - "@smithy/middleware-endpoint": ^2.4.1 - "@smithy/middleware-stack": ^2.1.1 - "@smithy/protocol-http": ^3.1.1 - "@smithy/types": ^2.9.1 - "@smithy/util-stream": ^2.1.1 - tslib: ^2.5.0 - checksum: 9b13c361528b3120b1a1db17cd60521d04c72f664c2709be20934cea12756117441d2a33d0464ff3099be11ccb12946c62ece1126b9532eb8f6243a35d6fd171 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 9b27751c329fecc84bdfe7f128ab766c7e5f1d4bdda6184699a0df8999e95aef21fafc6179d6c693e519c78874e738fd9afb5ac4679901cb68d092a86a612419 + languageName: node + linkType: hard + +"@smithy/service-error-classification@npm:^2.1.5": + version: 2.1.5 + resolution: "@smithy/service-error-classification@npm:2.1.5" + dependencies: + "@smithy/types": ^2.12.0 + checksum: 00ac54110a258c7a47c62d4f655d4998bd40e5adb47e10281b28df7a585f2f1e960dc35325eac006636280e7fb2b81dbeb32b89e08bac87acc136c4d29a4dc53 + languageName: node + linkType: hard + +"@smithy/shared-ini-file-loader@npm:^2.4.0": + version: 2.4.0 + resolution: "@smithy/shared-ini-file-loader@npm:2.4.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: b0c9e045bfe2150e07f4b31ae7d69d3646679337df9fec1e1201b845cc64ea2250c37db8e8d0e7573fc3c11188164adba43bbaf32275fa8a9f70e8bbc77146bf + languageName: node + linkType: hard + +"@smithy/signature-v4@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/signature-v4@npm:2.3.0" + dependencies: + "@smithy/is-array-buffer": ^2.2.0 + "@smithy/types": ^2.12.0 + "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-uri-escape": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 96050956b86876d0137af9b003d0a30005766bffc730495d7c106bd2eb05c8ada2da23ceac51d56e04f98b304e0ea55d698e1a10c99cda3ade44b3ac30166a00 + languageName: node + linkType: hard + +"@smithy/smithy-client@npm:^2.5.1": + version: 2.5.1 + resolution: "@smithy/smithy-client@npm:2.5.1" + dependencies: + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-stream": ^2.2.0 + tslib: ^2.6.2 + checksum: 10d51793aab8f6e0ba0890a2a101216ffc3a1c43664f8ed9688dcbc174ca0f83f2d1c8d7af484c84491174067af3d6b235b765a58b12f2308a6bfe42b1d74f59 languageName: node linkType: hard @@ -16506,185 +13680,186 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.9.1": - version: 2.9.1 - resolution: "@smithy/types@npm:2.9.1" +"@smithy/types@npm:^2.12.0": + version: 2.12.0 + resolution: "@smithy/types@npm:2.12.0" dependencies: - tslib: ^2.5.0 - checksum: 8570affb4abb5d0ead57293977fc915d44be481120defcabb87a3fb1c7b5d2501b117835eca357b5d54ea4bbee08032f9dc3d909ecbf0abb0cec2ca9678ae7bd + tslib: ^2.6.2 + checksum: 2dd93746624d87afbf51c22116fc69f82e95004b78cf681c4a283d908155c22a2b7a3afbd64a3aff7deefb6619276f186e212422ad200df3b42c32ef5330374e languageName: node linkType: hard -"@smithy/url-parser@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/url-parser@npm:2.1.1" - dependencies: - "@smithy/querystring-parser": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 5c939f3ff9c53a0b7a0c5a1ac7641f229598d2bf9499e1abf4d33c1c1cd13bd5f7fcfffd00c366ca9f8092d28979a4a958b80f9bbc91e817e4d1940451e93489 - languageName: node - linkType: hard - -"@smithy/util-base64@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-base64@npm:2.1.1" - dependencies: - "@smithy/util-buffer-from": ^2.1.1 - tslib: ^2.5.0 - checksum: 6dbb93b8745798d56476d37c99dc9f53fe5fc29329b8161fc9e5c55c5a3062916b3e5e4dd596541b248979eefa550d8da7fbb6ab254bf069cb4c920aea6c3590 - languageName: node - linkType: hard - -"@smithy/util-body-length-browser@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-body-length-browser@npm:2.1.1" - dependencies: - tslib: ^2.5.0 - checksum: 6f7808a41b57a5ab1334f0d036ecec6809a959bcfe6a200f985f35e0c96e72f34fdcb6154873f795835d1d927098055e2dec31ebfb5e5382d1c4c612c80a37c0 - languageName: node - linkType: hard - -"@smithy/util-body-length-node@npm:^2.2.1": - version: 2.2.1 - resolution: "@smithy/util-body-length-node@npm:2.2.1" - dependencies: - tslib: ^2.5.0 - checksum: 6bddc6fac7c9875ae7baaf6088d91192fbe4405bc5c1b69100d52aa1bfebabcc194f5f1b159d8f6f3ade3b54e416f185781970c30a97d4b0a7cec6d02fc490c4 - languageName: node - linkType: hard - -"@smithy/util-buffer-from@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-buffer-from@npm:2.1.1" - dependencies: - "@smithy/is-array-buffer": ^2.1.1 - tslib: ^2.5.0 - checksum: 8dc7f9afaa356696f14a80cd983a750cbad8eba7c46498ed74fb8ec0cb307f14df64fb10ceb30b2d4792395bb8b216c89155a93dee0f2b3e5cab94fef459a195 - languageName: node - linkType: hard - -"@smithy/util-config-provider@npm:^2.2.1": - version: 2.2.1 - resolution: "@smithy/util-config-provider@npm:2.2.1" - dependencies: - tslib: ^2.5.0 - checksum: f5b34bcf6ef944779f20d7639070e87a521e1a5620e5a91f2d2dbd764824985930a68b71b0b2bde12e1eaac947155789b73a8c09c1aa7ab923f08e42a4173ef4 - languageName: node - linkType: hard - -"@smithy/util-defaults-mode-browser@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-defaults-mode-browser@npm:2.1.1" - dependencies: - "@smithy/property-provider": ^2.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - bowser: ^2.11.0 - tslib: ^2.5.0 - checksum: 5d3b11be1768410e24ad9829dc70bed9b50419f85a8ca934c6296e21e278d87f665cfdb603241ef749f80d154a2c4be26cd29338daecc625d31b30af8bd9c139 - languageName: node - linkType: hard - -"@smithy/util-defaults-mode-node@npm:^2.2.0": +"@smithy/url-parser@npm:^2.2.0": version: 2.2.0 - resolution: "@smithy/util-defaults-mode-node@npm:2.2.0" + resolution: "@smithy/url-parser@npm:2.2.0" dependencies: - "@smithy/config-resolver": ^2.1.1 - "@smithy/credential-provider-imds": ^2.2.1 - "@smithy/node-config-provider": ^2.2.1 - "@smithy/property-provider": ^2.1.1 - "@smithy/smithy-client": ^2.3.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: c4a69b73bc46c3bb5ff4149b80bdfa79f4c25b82253d9c7168c9920066e12830e1bea324dce09414b09791fd0379bdc05c39117155d5b37a229d226962a95d5f + "@smithy/querystring-parser": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: f21f1e44bc2a4634220465990651f5ee0708cb6759b3685b8a8c00cc2cd64bbbc7807f66cd79ec6e654f7245867d4fb4ced406ad5c14612ebc47eae3f34e63c5 languageName: node linkType: hard -"@smithy/util-endpoints@npm:^1.1.1": - version: 1.1.1 - resolution: "@smithy/util-endpoints@npm:1.1.1" +"@smithy/util-base64@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-base64@npm:2.3.0" dependencies: - "@smithy/node-config-provider": ^2.2.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 40619bf739c1fc959486946cb49319f34c9c4c5c19f46cdefc7ff8e7331b84f6ad7a4aeb8a0268f6d77d266ff5ec9df8d2244094dd79ae469983e9c07e43766a + "@smithy/util-buffer-from": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 2ce995c5d12037e9518bb2732f24090bc493d48118dfd6519faa41e19cd91863895bc0b5958b790d2cdeb919a8c410790dcffa3a452d560f0eeab73dc0c92cbd languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-hex-encoding@npm:2.1.1" +"@smithy/util-body-length-browser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-body-length-browser@npm:2.2.0" dependencies: - tslib: ^2.5.0 - checksum: eae5c94fd4d57dccbae5ad4d7684787b1e9b1df944cf9fcb497cbefaed6aec49c0a777cc1ea4d10fa7002b82f0b73b8830ae2efe98ed35a62dcf3c4f7d08a4cd + tslib: ^2.6.2 + checksum: e9c1d16b3b95d529011476e6154eaf282d3a983204b29dcf1e7ef04a9f5c2deae30167e06190f315771c813c768f19f486d3139fe9fcaf34d12c2333350f3412 languageName: node linkType: hard -"@smithy/util-middleware@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-middleware@npm:2.1.1" +"@smithy/util-body-length-node@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-body-length-node@npm:2.3.0" dependencies: - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 404bb944202df70ba0ff8bb6ea105ead0a6b365d5ef7bfafbfc919df228823563818f0ee36f0f1e20462200da2fb8c8961e20b237e4e1bd9f77c38dd701f39ab + tslib: ^2.6.2 + checksum: 5d5c31b071e0b3222dcfe863ea2d179253f0dfaa30d03f40ebfa352ed292e00a451053cc523e27527e61094d5ed475069d2287ef19a857c6da0364ca71cfdf3c languageName: node linkType: hard -"@smithy/util-retry@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-retry@npm:2.1.1" +"@smithy/util-buffer-from@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-buffer-from@npm:2.2.0" dependencies: - "@smithy/service-error-classification": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 1747c75f55a208f16104483cd76ec45200dedaa924868e84d4882b88f8b4a8d3a4422834359fd9bfba242e0e96a474349ac0a6f5d804fb15b15e8b639b6d2ad0 + "@smithy/is-array-buffer": ^2.2.0 + tslib: ^2.6.2 + checksum: 424c5b7368ae5880a8f2732e298d17879a19ca925f24ca45e1c6c005f717bb15b76eb28174d308d81631ad457ea0088aab0fd3255dd42f45a535c81944ad64d3 languageName: node linkType: hard -"@smithy/util-stream@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-stream@npm:2.1.1" +"@smithy/util-config-provider@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-config-provider@npm:2.3.0" dependencies: - "@smithy/fetch-http-handler": ^2.4.1 - "@smithy/node-http-handler": ^2.3.1 - "@smithy/types": ^2.9.1 - "@smithy/util-base64": ^2.1.1 - "@smithy/util-buffer-from": ^2.1.1 - "@smithy/util-hex-encoding": ^2.1.1 - "@smithy/util-utf8": ^2.1.1 - tslib: ^2.5.0 - checksum: 3a060226b8a506e722d0d8c1c4b7a2989241f7946c8acc892a8a70d92d9952cc8619b14bf686c9c822115d99159c6c16534bad2d72ecc2809a56f865224e82a6 + tslib: ^2.6.2 + checksum: 0f3f113c2658bd5a79f98dc28d53ca9c0adf8ec3c8c86c7dd91d2cd37149b4cf83d85cc89d5fe67ffe5cd319ec85f139ef229844eb039017193b307a4c315399 languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-uri-escape@npm:2.1.1" +"@smithy/util-defaults-mode-browser@npm:^2.2.1": + version: 2.2.1 + resolution: "@smithy/util-defaults-mode-browser@npm:2.2.1" dependencies: - tslib: ^2.5.0 - checksum: 822ed7390e28d5c7b8dab5e5c5a8de998e0778220137962a71b47b2d8900289d48a3a2c9945e68e1cac921d43f61660045e7fdffe8df9e63004575fcf2aa99b2 + "@smithy/property-provider": ^2.2.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 286337d9165181e1df3d28d348210e88f20662ec63a9d6c1bcfce3342003de130a218dab42ce64aa4399ef345e2528414f73f399f8f4c8e9a6fcbc8e48250f98 languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-utf8@npm:2.1.1" +"@smithy/util-defaults-mode-node@npm:^2.3.1": + version: 2.3.1 + resolution: "@smithy/util-defaults-mode-node@npm:2.3.1" dependencies: - "@smithy/util-buffer-from": ^2.1.1 - tslib: ^2.5.0 - checksum: 286ce5cba3f45a8abd3d6c28e40b3204dd64300340818d77e42c1cbb0c2f6ad0c42f0e47ffaf38d74d0895b0dfd1750c5b55222ab4d205a3b39da4325971d303 + "@smithy/config-resolver": ^2.2.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 7fb9d0ac8b5919955399284c1801f49a1f5275f6cf240894ba0a91a8825248bb167938647a983d89905d6bfa7b226789781e85d2ff7f27c58cdd32c2e68600ae languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.1.1": - version: 2.1.1 - resolution: "@smithy/util-waiter@npm:2.1.1" +"@smithy/util-endpoints@npm:^1.2.0": + version: 1.2.0 + resolution: "@smithy/util-endpoints@npm:1.2.0" dependencies: - "@smithy/abort-controller": ^2.1.1 - "@smithy/types": ^2.9.1 - tslib: ^2.5.0 - checksum: 52d9c82bb9684b6b11eeb2814fa1454514cb90aeeb87bfdf7c458613c13d18189712585486859c975824d08f2d1e3c817dd7e51c400531aaa479af8a06ea0bff + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 19a59b1c9b214457371d4d7109b190c237de5ebd06f5b4f3665dddc5fe0879dbb19bcdc5dec23d1825cd04388b7f9bf7fddf354e1a23e84d9c690ad21e71cb86 + languageName: node + linkType: hard + +"@smithy/util-hex-encoding@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-hex-encoding@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: 7d14589bc4a44eebf878595290c53ee4d90cc6b5445b5fe130608d6dea477c292730b85e4e08190a1555ef7664214f0f00dc478ba725516787a49fff658e725e + languageName: node + linkType: hard + +"@smithy/util-middleware@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-middleware@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 312dc86e5415a12e2580a02311750b350aec8fb9da5a60c3010c10694990ded869b7ca5b87aa20e5facbacdd233e928e418b7765d7797019cd48177052aedd03 + languageName: node + linkType: hard + +"@smithy/util-retry@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-retry@npm:2.2.0" + dependencies: + "@smithy/service-error-classification": ^2.1.5 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1a8071c8ac5a2646b3d3894e3bd9c36a9db045f52eadb194f32b02d2fdedd69fb267a2b02bcef9f91d0f8f3fe061754ac075d07ac166d90894acb27d68c62a41 + languageName: node + linkType: hard + +"@smithy/util-stream@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-stream@npm:2.2.0" + dependencies: + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/types": ^2.12.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-buffer-from": ^2.2.0 + "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: f0febd1a7558201d9178c0018478f89729800e9b8962dc735ec99f41ce01d1128373e3bd6008f0b4ff79b25ee4476db4fd5fa18d6feeb8b5b715d416da7027c3 + languageName: node + linkType: hard + +"@smithy/util-uri-escape@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-uri-escape@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: bade35312d75d1c84226f2a81b70dfef91766c02ecb6c6854b6f920cddb423e01963f7d0c183d523b5991f8e7ca93bcf73f8b3c6923979152b8350c9f3c24fd6 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-utf8@npm:2.3.0" + dependencies: + "@smithy/util-buffer-from": ^2.2.0 + tslib: ^2.6.2 + checksum: 00e55d4b4e37d48be0eef3599082402b933c52a1407fed7e8e8ad76d94d81a0b30b8bfaf2047c59d9c3af31e5f20e7a8c959cb7ae270f894255e05a2229964f0 + languageName: node + linkType: hard + +"@smithy/util-waiter@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-waiter@npm:2.2.0" + dependencies: + "@smithy/abort-controller": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 303f56beb9ba4afada862eff4950a17d904a4fdfc01bd8acb932b0457e457730981162777004414252e700014c554d894a1ce9d32e0bad75e1a4a2ca6492429e languageName: node linkType: hard @@ -16701,54 +13876,54 @@ __metadata: languageName: node linkType: hard -"@spotify/eslint-config-base@npm:^14.0.0": - version: 14.0.1 - resolution: "@spotify/eslint-config-base@npm:14.0.1" +"@spotify/eslint-config-base@npm:^15.0.0": + version: 15.0.0 + resolution: "@spotify/eslint-config-base@npm:15.0.0" peerDependencies: eslint: ">=7.x" - checksum: 8893e7c903c07ede7f3a03b5b6af03b65d2f334615d30fecb527ce4d888970168b73dbaef43275f9ece9e7b0193e13e6807e506507b32bdde9b64000cc52c8b1 + checksum: 265a4d807b5236030466a3a8373f41e51a9b4939b450d47ed2cb4704485004a5d64b2f9e024e865b4f5eea61ab6bbe439442e4ca2ac06e52a3b5c7e94c2d6b27 languageName: node linkType: hard -"@spotify/eslint-config-react@npm:^14.0.0": - version: 14.0.1 - resolution: "@spotify/eslint-config-react@npm:14.0.1" +"@spotify/eslint-config-react@npm:^15.0.0": + version: 15.0.0 + resolution: "@spotify/eslint-config-react@npm:15.0.0" peerDependencies: eslint: ">=8.x" eslint-plugin-jsx-a11y: 6.x eslint-plugin-react: ">=7.7.0 <8" eslint-plugin-react-hooks: ^4.0.0 - checksum: d8545c3c3967bb8b923bd55dad2c50b5e2eb6d716cd9dcbbfa32417c3a6e786537ee3263ebedae99bd45abe3378acb0879c9644a729820ea61dd5d9e45e55465 + checksum: 42e16f63d51b2230d2e4eba6524d2d9278d480827c5d2ab32f96253bafd4d8ceb87c37d8429601e36642ff30c86b92011ad4efd26c83db4037478ad118497cce languageName: node linkType: hard -"@spotify/eslint-config-typescript@npm:^14.0.0": - version: 14.0.1 - resolution: "@spotify/eslint-config-typescript@npm:14.0.1" +"@spotify/eslint-config-typescript@npm:^15.0.0": + version: 15.0.0 + resolution: "@spotify/eslint-config-typescript@npm:15.0.0" peerDependencies: "@typescript-eslint/eslint-plugin": ">=5" "@typescript-eslint/parser": ">=5" eslint: ">=8.x" - checksum: faf3ab89880e626d388e9ae212dd3486d6f91ca4d079020066c22d44c3df215dc61439c4e65ef3fc4eb5c3ea9893d5b504a2d251694d7a333d8803991349535b + checksum: d30d07e1e2e0e18cc583a72ca74b5fdb80ee26e6529de26e1e85d1416ca5396c942efaccc2613287365c7ac3659378b0ba0cdda3df25c7e5cdbd7317f1cbe885 languageName: node linkType: hard -"@spotify/eslint-plugin@npm:^14.1.3": - version: 14.1.3 - resolution: "@spotify/eslint-plugin@npm:14.1.3" +"@spotify/eslint-plugin@npm:^15.0.0": + version: 15.0.0 + resolution: "@spotify/eslint-plugin@npm:15.0.0" peerDependencies: "@typescript-eslint/parser": ^5.13.0 - eslint: ^8.10.0 - checksum: 788f5d9aab6f7b6c0ad7e414ebd5f4504f058f26a769dc4bcd0088dd8e6d9e5334965c8f6fffcf5b7ed52dbe25de0dc7bba403bcffa79b6d94c7ba3094757b5f + eslint: ">=8.x" + checksum: 899166abb108f1f53867729a35fb711d89dc70d5fc0a725a80386adb85805149008f7226262619044680264c64c0a8a0e9703059f64d0b390650bcae86727ed6 languageName: node linkType: hard -"@spotify/prettier-config@npm:^14.0.0": - version: 14.0.1 - resolution: "@spotify/prettier-config@npm:14.0.1" +"@spotify/prettier-config@npm:^15.0.0": + version: 15.0.0 + resolution: "@spotify/prettier-config@npm:15.0.0" peerDependencies: prettier: 2.x - checksum: 07fb33ff3bb4678ab3bfe2f6f5da2cfb366de427c544e94178f5f8c75b3708282f7ea1a4344404e4ad1bbc5b38fccfde10795528cdfe7f61a8afed62076f8fe9 + checksum: aa5ec5739427f9acdb9d62ae6c04f04a344898567239f7ee45c75c6205ebdffbc61747ea8de6e83baf0bc3785359967de4b7097a8723c4b4063ff57dc5cb6c44 languageName: node linkType: hard @@ -16806,10 +13981,10 @@ __metadata: languageName: node linkType: hard -"@stoplight/ordered-object-literal@npm:^1.0.1, @stoplight/ordered-object-literal@npm:^1.0.3": - version: 1.0.4 - resolution: "@stoplight/ordered-object-literal@npm:1.0.4" - checksum: 81afa24943880b0a213af3728a9fe0a28bd01d4840b9583d448f7823ced5b6e673628698b59d201cef50afebcbd89256e133714a174968d11b624d943e0c2c2f +"@stoplight/ordered-object-literal@npm:^1.0.3, @stoplight/ordered-object-literal@npm:^1.0.5": + version: 1.0.5 + resolution: "@stoplight/ordered-object-literal@npm:1.0.5" + checksum: 84fe385ed742c5298fd5bee3f95366bfe17a2b99ed52f9b323180756d3495078dfb3bf7e5f49f3c8dee7b79f2e8358b38fe4977b7b6475f0094765160d716bb5 languageName: node linkType: hard @@ -16900,14 +14075,14 @@ __metadata: linkType: hard "@stoplight/spectral-parsers@npm:^1.0.0, @stoplight/spectral-parsers@npm:^1.0.2": - version: 1.0.3 - resolution: "@stoplight/spectral-parsers@npm:1.0.3" + version: 1.0.4 + resolution: "@stoplight/spectral-parsers@npm:1.0.4" dependencies: "@stoplight/json": ~3.21.0 - "@stoplight/types": ^13.6.0 - "@stoplight/yaml": ~4.2.3 + "@stoplight/types": ^14.1.1 + "@stoplight/yaml": ~4.3.0 tslib: ^2.3.1 - checksum: e1120e9ffc3db7f50573db08768c1206f5adc5fc503e77d3696e86e0765ce247c3c513ed12e53318b6aef0de33fc730aa78ccd542142d17d6bae01e23cba5879 + checksum: ca88183661651d99b40da254316fec062c219253ea3054151b9379e7c492121cdeef49a2d1ac08cd89b2f89f7d16dbc4ecf9da6d7a7539979ac6418991fe804a languageName: node linkType: hard @@ -16971,7 +14146,7 @@ __metadata: languageName: node linkType: hard -"@stoplight/types@npm:^12.3.0 || ^13.0.0, @stoplight/types@npm:^13.0.0, @stoplight/types@npm:^13.12.0, @stoplight/types@npm:^13.15.0, @stoplight/types@npm:^13.6.0": +"@stoplight/types@npm:^12.3.0 || ^13.0.0, @stoplight/types@npm:^13.12.0, @stoplight/types@npm:^13.15.0, @stoplight/types@npm:^13.6.0": version: 13.20.0 resolution: "@stoplight/types@npm:13.20.0" dependencies: @@ -16981,7 +14156,7 @@ __metadata: languageName: node linkType: hard -"@stoplight/types@npm:^14.0.0": +"@stoplight/types@npm:^14.0.0, @stoplight/types@npm:^14.1.1": version: 14.1.1 resolution: "@stoplight/types@npm:14.1.1" dependencies: @@ -17001,22 +14176,22 @@ __metadata: languageName: node linkType: hard -"@stoplight/yaml-ast-parser@npm:0.0.48": - version: 0.0.48 - resolution: "@stoplight/yaml-ast-parser@npm:0.0.48" - checksum: 4e252a874636d4015ff78a638075c438ccf7b8b4b38e3df12f7b8381da2da0411dfff7a6de38354b8093a36a8911a9dd656264fb0d34453cb7bcf78a3627dfa0 +"@stoplight/yaml-ast-parser@npm:0.0.50": + version: 0.0.50 + resolution: "@stoplight/yaml-ast-parser@npm:0.0.50" + checksum: dd46f2e39cef4e3a56276202872282bc435c5f92ea7cf344abd6722fbdab62547ec7d2b84983c6c05aaa2776ac29efd53affe6d9753cce10ef37b4e15ce6ccdc languageName: node linkType: hard -"@stoplight/yaml@npm:~4.2.3": - version: 4.2.3 - resolution: "@stoplight/yaml@npm:4.2.3" +"@stoplight/yaml@npm:~4.3.0": + version: 4.3.0 + resolution: "@stoplight/yaml@npm:4.3.0" dependencies: - "@stoplight/ordered-object-literal": ^1.0.1 - "@stoplight/types": ^13.0.0 - "@stoplight/yaml-ast-parser": 0.0.48 + "@stoplight/ordered-object-literal": ^1.0.5 + "@stoplight/types": ^14.1.1 + "@stoplight/yaml-ast-parser": 0.0.50 tslib: ^2.2.0 - checksum: 8e61c4499c0849dafecf487e51e10d4d3e99192834dd87eba4b27c20c42d3fe1b5b022f9c3eb63b96249b46d7277ffb4ce37447d84d01d4768b88d142e3d0e15 + checksum: f113f600a62b75c76c96c27ce3713ba2c48be205fca73097699b66b6f861411c6917dcc5afa4dd08c17fe63f5181b49fa2be9c6500140ea5d05a107ffcb48a4f languageName: node linkType: hard @@ -17204,409 +14379,408 @@ __metadata: languageName: node linkType: hard -"@swagger-api/apidom-ast@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ast@npm:0.92.0" +"@swagger-api/apidom-ast@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ast@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-error": ^0.99.0 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 unraw: ^3.0.0 - checksum: 11770246944b3bb5964a88e71a7e32e37691b7a3b6ec9ae6acf58cd580571ca75c079d749bb952cd08c86be2155cbef3ed418ad6194681e1e2fea643a2128af2 + checksum: 48288eb46edb03040e9afec47762d826d8c343ee6a3216d54d65f21ad3e62daade6c8edf228d1ab9bff8f23163841f9ce8170951cf211bf1a2c08e52137293b0 languageName: node linkType: hard -"@swagger-api/apidom-core@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-core@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-core@npm:0.92.0" +"@swagger-api/apidom-core@npm:>=0.99.1 <1.0.0, @swagger-api/apidom-core@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-core@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ast": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 "@types/ramda": ~0.29.6 minim: ~0.23.8 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 short-unique-id: ^5.0.2 stampit: ^4.3.2 - checksum: e02f1a838ab1d811960a48f98922c66bb306f1a5a1a154b8fe4c6445fb0a20c671409fee14a2e49051387bc7b5c28e218161bcc1519c6ad9cbc767bf432ee05d + checksum: f4313d6971e65feeaa6581a82dc3e720af87358e470c6dde0d11d8ae5b7d251cc430a2f70a88eebd251dd6c454a5708b61b9daf9f5d00fcbb1ce9d280874d5cc languageName: node linkType: hard -"@swagger-api/apidom-error@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-error@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-error@npm:0.92.0" +"@swagger-api/apidom-error@npm:>=0.99.0 <1.0.0, @swagger-api/apidom-error@npm:^0.99.0": + version: 0.99.0 + resolution: "@swagger-api/apidom-error@npm:0.99.0" dependencies: "@babel/runtime-corejs3": ^7.20.7 - checksum: bdd3051a47f4300344c0f1f2a55c4bb3dbe147ba8ebd27c94a77db2c90e8cc371bca63b72dfb49d0034794b82929edbf70d20ab33f59ba9f8c2d2fc8dc0430db + checksum: 06d3da38ff9501376d2de3240d1a5023110482e053766c389f734a587dfd4c10b6ba695268edc58ce649284fd8e04a1f57484ae49dba210dcc5764df33fd52a0 languageName: node linkType: hard -"@swagger-api/apidom-json-pointer@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-json-pointer@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-json-pointer@npm:0.92.0" +"@swagger-api/apidom-json-pointer@npm:>=0.99.1 <1.0.0, @swagger-api/apidom-json-pointer@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-json-pointer@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 89d748fd1f52fce381d4e07710244d94c4d9f8a20411ca8bcfb33e7ec515432c7766660b296a9c603fa6b861b39eca4917151f98f3688f1bdcf10f25f9d90134 + checksum: d566f7410d3600766f7130a23da811b4c7a3a1542ab173f2b0b6578b01dcb531c61d1d43da5e944ef1d4059c47b6f472ee3ad55da625e672c1c1dd7315941689 languageName: node linkType: hard -"@swagger-api/apidom-ns-api-design-systems@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-api-design-systems@npm:0.92.0" +"@swagger-api/apidom-ns-api-design-systems@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-api-design-systems@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 + "@swagger-api/apidom-ns-openapi-3-1": ^0.99.1 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 + ramda-adjunct: ^4.1.1 + ts-mixer: ^6.0.3 + checksum: 22ce1af89437b104005158ded9b8237511f1d6dae9f564fb1c336e6f842898fde9dca8549aa94dc0724c03df51b4a33b7e081f79b5c44e68ab625d76a4589d47 + languageName: node + linkType: hard + +"@swagger-api/apidom-ns-asyncapi-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-asyncapi-2@npm:0.99.1" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-json-schema-draft-7": ^0.99.1 + "@types/ramda": ~0.29.6 + ramda: ~0.29.1 + ramda-adjunct: ^4.1.1 + ts-mixer: ^6.0.3 + checksum: d1759ca24f238ae833a34128e8672f972f8cca61ddbd9660e277bc8ad3d78b835e1b7406a97e8eed4946e526ce7ec8ed1debd79edaaf504fae86c92534cb0875 + languageName: node + linkType: hard + +"@swagger-api/apidom-ns-json-schema-draft-4@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-json-schema-draft-4@npm:0.99.1" + dependencies: + "@babel/runtime-corejs3": ^7.20.7 + "@swagger-api/apidom-ast": ^0.99.1 + "@swagger-api/apidom-core": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 8e993f6b8cd37cb9857a34437e2b16e087ccce524373726a167bf98ab622c44a03c47c81e218ff4b00aa7bd973a25bd696e2437c5fd018ace09ba2ad0fcda9de + checksum: 1b6c034e94287de0bea11a5f1c62de7b833436918cf961f38a12d877cf6de3caf3080fd38f0244905ea3b2fe8bb178a26c29ec631b4638ac46b597b992c7640a languageName: node linkType: hard -"@swagger-api/apidom-ns-asyncapi-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-asyncapi-2@npm:0.92.0" +"@swagger-api/apidom-ns-json-schema-draft-6@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-json-schema-draft-6@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-json-schema-draft-7": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: bef3de2c2a854590c8bb1cd892a5b170b65e14119a97528652457bf1e3e19f4a05d7da41ddb697f64de9972c8fad8afc7e6ccfa97ce8809fc9eba8c1305d509c + checksum: e521ac3aec57f4239cce89641c7dc3555b2986ef23c6e9a15462d0b3015e54d89b0802546c313f5a91a2e5f94c8c570c417fe22034da57049bf49c61fc4e3592 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-4@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-4@npm:0.92.0" +"@swagger-api/apidom-ns-json-schema-draft-7@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-json-schema-draft-7@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.92.0 - "@swagger-api/apidom-core": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 + "@swagger-api/apidom-ns-json-schema-draft-6": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 stampit: ^4.3.2 - checksum: 6b0d57acf1c34df314c401ab25d0feb3ad5638fc8c848f6b84c76691fef177a39a9e8ebfa16309d22c764d9bfb292ed5ad39943b2cece67dde746a6e9d5fdc12 + checksum: 791df6981518d239fdee2ae76bd9abf2542322e36785d2153fe2d4dcc1e6b2fdbb430ac9becb55734fc7968f77570895d5c9113f5aa59f0cc3c59ed3ed604b41 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-6@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-6@npm:0.92.0" +"@swagger-api/apidom-ns-openapi-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-openapi-2@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 - checksum: 5660459753ff1359527e61820db59a6465ecc8b51cc5a6c14e155b2144b67570c6fc2c7c41d97617470d1478b85e26879fadc3f1ff4460c6309411c13db209e6 + ts-mixer: ^6.0.3 + checksum: 8222aaffa9d1472ca2f876a361bbb888bc39b888d4600d9bd06ada7d9b516104391fbba9f51305ea0f522d0ae44370134631fc9492461483fad3cf757fa70b75 languageName: node linkType: hard -"@swagger-api/apidom-ns-json-schema-draft-7@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-json-schema-draft-7@npm:0.92.0" +"@swagger-api/apidom-ns-openapi-3-0@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-openapi-3-0@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 - "@swagger-api/apidom-ns-json-schema-draft-6": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 + "@swagger-api/apidom-ns-json-schema-draft-4": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 - checksum: 838d2b9917b4086880156e895d67adfd6400236e97b2a75814356dc55b0d45afd3e458bfe97b52af39aeea4c3483fc40f7a1551af14285977009513a168fb87c + ts-mixer: ^6.0.3 + checksum: 8b5150e317e79795bc73a4a0c53860de4ab50e9e8fd9895d21d4a204e6ecee626477107e06df51aaef0e3651fdb2e48f197b5c8a0c33464b38d74abdffda0b60 languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-openapi-2@npm:0.92.0" +"@swagger-api/apidom-ns-openapi-3-1@npm:>=0.99.1 <1.0.0, @swagger-api/apidom-ns-openapi-3-1@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-openapi-3-1@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 + "@swagger-api/apidom-ast": ^0.99.1 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-0": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 - checksum: 154de0b299a3ff0fcac40cf995dafb8c173cb4e294c75f952a9fa9cd5452eaab7783a9e5abb425fbc6e7135466155645e9b96fa9495f3effa7aec18f3152e6c3 + ts-mixer: ^6.0.3 + checksum: 64d97f6569c68982af5e2933e52060a5b404a270ad45689209f57e049776a4d3e2062f89474eb26a2689bc08014a6d69d45c6d48c496e67b2664e7bf80356232 languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-3-0@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-openapi-3-0@npm:0.92.0" +"@swagger-api/apidom-ns-workflows-1@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-ns-workflows-1@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 - "@swagger-api/apidom-ns-json-schema-draft-4": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-1": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 - checksum: 9ae883feea63c06f2514ba834b637bd00d6a56c35fe9b875507698d991199202d307a90bd06ebeaeb5642e3e42fe54238249858568c8a61a1797792fa5fff259 + ts-mixer: ^6.0.3 + checksum: 53ab8bd15d382648c701bb1e374d0ccc8e9d90a1aeb0106631d77846b765e3dd282e7b3d7f2b748f2eaccaf0d16ec02a49e3319078e298b1c228d22625934e1b languageName: node linkType: hard -"@swagger-api/apidom-ns-openapi-3-1@npm:>=0.90.0 <1.0.0, @swagger-api/apidom-ns-openapi-3-1@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-openapi-3-1@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.92.0 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 - "@types/ramda": ~0.29.6 - ramda: ~0.29.1 - ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 - checksum: 316861ccd563d28c46039fa4202337f2266e0b99bf803bc71f64d307d824a74dcf7e4cdf7fc4ac25d6cf3521aebc74938c2001eb74ef0c364bc02470a1ffc723 - languageName: node - linkType: hard - -"@swagger-api/apidom-ns-workflows-1@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-ns-workflows-1@npm:0.92.0" - dependencies: - "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 - "@types/ramda": ~0.29.6 - ramda: ~0.29.1 - ramda-adjunct: ^4.1.1 - stampit: ^4.3.2 - checksum: 684804790b58b52a28ae10ffc7fc2fa5bf6b99d8cb3e5d9409e28325c4d4b9ce5b5cc10e0cc401fb21788753ea65287e33db79337388afccd54f6902f60d9159 - languageName: node - linkType: hard - -"@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-json@npm:0.92.0" - dependencies: - "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-api-design-systems": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-api-design-systems": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: d9c361b8bb7b8a056acc2c52ef70a2d7304c511efc836cfebc315558ced7e93fe4e958dd554030a3315702d49ace30082ff7f2f91e9a76aaa2fff944a19fe39e + checksum: 406e4168c09e8907ac8983aecdc18429cded4db2b9793d2eb56a8e8494cae96d4309787c6316e3b584ad9c71434c0b31a933ee91d5b610b6fac72880692cfa3a languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-api-design-systems-yaml@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-api-design-systems": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-api-design-systems": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 248e61ed6e202eeab048c7c5e3eff0e0f2b6bfea958a02cbc6d8b831693a015d063db118af25c2e7380a4828ab84bf991764d200409a8eb99ffadb0dc6db65c0 + checksum: 899d2181efd0afdfda5eb9d678b7ae4e1f4710b2d56a05272751aec86510c0e48d681d8cb16388b8e88f225fbb63c9a0b49aa79b94589a82c1bdb41d66d77012 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-asyncapi-json-2@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-asyncapi-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 0fc981bc839758af1b3a8dfa0695376919a515a11ae71e6f9f1e0c91dd1530aa659fa7405cb73109db28fd95f594f09b5ee941611cc4ce4f3d1817335b12ec4b + checksum: e2b2d38769a11ad5c578a501acb8a015c8c359f7623ad37226d14845c96efd8d50d8d0bda417789402e74d52cbaf75c5e659936380b444f26dcfa5bb8c5df2df languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-asyncapi-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: a1554f73cc20b75df71296322f6bdf5b5a0f1d775bd9bff89d7798843606e1a383c48960ddc2b1f879c962d2d56962e6096c3000ec2ad6091d49627aa2992b2e + checksum: 27f8e1486f41074b679dd0016fd8b764ba2ec11fd589438e10f6c712f9d816b9b45edb3de02315fe43dcbbafdd68f392e217855109919b9b75d5065885691e7e languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-json@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-json@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-json@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-json@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.92.0 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ast": ^0.99.1 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 "@types/ramda": ~0.29.6 node-gyp: latest ramda: ~0.29.1 ramda-adjunct: ^4.1.1 tree-sitter: =0.20.4 - tree-sitter-json: =0.20.1 + tree-sitter-json: =0.20.2 web-tree-sitter: =0.20.3 - checksum: ca66dd9fffaa84249398420b9cf2301721d2b173340e0f07097348b73654f54698a370a94d814d7f51b7e662f968054b7fc745607074dbd71892c53714a18b62 + checksum: eb8383965c866a60b06ea3da8f7a25a18fde35ae0455df8ce2a5a537b95424fba01cb3dd4f403869a3ba14d685388dc6f0b1362e5cf95ad6cdd1c65bd31dfa49 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-2@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-openapi-json-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-2@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 383827eec8fbc2bb36c095c8db4f8dce5264e5ffdfa7aca9a938d603294d99f0a552d57947222c160fbbbc1b79be7d08a7091348f3b373bbe25bd52a34bee529 + checksum: 4711cc0c42c7e31c82a45e15c118ddec5a8c0da628e1bc43c8096b849f2f56ff45e96d9ae32efb3f6d586b094cba1e068a5c42ff4bb99ffeba99389d4d865458 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-0@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-0": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 592c1149d901a3c21594aca5c96a997382648ff559fb67cd6b75630440248a52f26df91ad96fa762e585e297725e20eb6f5623f91a6b6a5e2c950f57df4de760 + checksum: 0e5146fcd49c5aae257b148420358bd136863df7261cfb5a338bb12bd86503c71bcb12cb510e5bff9a3dd84783ce8ed6776ac9300bc0c4e795c1ecb45fac91d0 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-openapi-json-3-1@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: feaa0b825921ea9defde642b65a07049a8539905142baa113b3b5e90c76630a58ef2557a6f770740e32e5cfa46486fc9f7d3c468b8ec29aaa53cb507c4ad3469 + checksum: e36e808ce1d79279cc495327e0223922071be3856603a485980f9a237af37dc3488c96e20b0b0d4f364b8a0247574185d61be1b6d536f06e49a8e91a3b262a1e languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-2@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: efd8dbd705592accadce53b25fc293ee48d1d11ec191f618df4243e6fdfea1add502ef3a5d433051883092dd29bf0a9f2026f2314a0cced1b8f04af59e63e995 + checksum: ec0156285810a76148f16bcb525ac8267ea99bc7c7a3ded7bb5dfdef987ab11c5d9fe20f5e1d43e35e0de777b68a0fd38633247bbe2ee66d05d76753f25f61e9 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-0": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 47a034efae971b56d13e96bc64d0973a2015ca303bf63334117ebbcfb2b2676d50a0b68aa24ea5a3b669786a524035762d52ae1cc795f3c3dc65249297a23068 + checksum: 397cf17638246ce6b4b4a7ddb315d78dfa50c565b399ff73f929ed64c6d8d991f3a4e38aa2b0ae70af6e5fa6fef06bae9205e9547649a957f3b5e4696ff0a050 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: c565913065e401109e7e4494f1024d24958959c742e5f842247a56eca6b75dcc9c3495a4c550912a62d62db896b2803bd317642336b4b18c851adc141fa38b61 + checksum: 186f37d84758adcd02ba2d7734b5c99cc97f57dd102d1f2c82991bb7b68380a1a9d632656389262dfd20b53234a55ca8fa17e800c0401544abb90ace174bf1cf languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-workflows-json-1@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-workflows-json-1@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-workflows-json-1@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-workflows-json-1@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-workflows-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-workflows-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 570f8323aaa5c67da3b5421d6ca6a9f0c3bf486a602584fa5969476e6a4943abe9a7f8f2bd7dfc1a7019286746e65cc76b050cadfabab276e0d452fbad4db59f + checksum: 3a2e928be611461a9533eb69eebabd8bf59381e82507725c938e36dd77fead3c260d27cd287d92f884323928683e518c47361889c52720a58294c0b3eb2a7b55 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-workflows-yaml-1@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-ns-workflows-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-ns-workflows-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 ramda: ~0.29.1 ramda-adjunct: ^4.0.0 - checksum: 020ecd34fb45ba57977377f71dc0b28ebba95b950bb873e1f6222eb6b544f91243dfb6b1f7555fe5f279d7bee044089337216a3f4b8e58612fb7066530938f32 + checksum: 7869ba27343a8936ff2def5570b41b9abb2618afa8ee0fbecbb0a0213031dbbc28bb5692e486350748099fadd22578928f8d5a420f11769247044a026c8138e5 languageName: node linkType: hard -"@swagger-api/apidom-parser-adapter-yaml-1-2@npm:^0.92.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-parser-adapter-yaml-1-2@npm:0.92.0" +"@swagger-api/apidom-parser-adapter-yaml-1-2@npm:^0.99.1": + version: 0.99.1 + resolution: "@swagger-api/apidom-parser-adapter-yaml-1-2@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-ast": ^0.92.0 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 + "@swagger-api/apidom-ast": ^0.99.1 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 "@types/ramda": ~0.29.6 node-gyp: latest ramda: ~0.29.1 @@ -17614,37 +14788,37 @@ __metadata: tree-sitter: =0.20.4 tree-sitter-yaml: =0.5.0 web-tree-sitter: =0.20.3 - checksum: 1ee0bf2c2f7fed54ff194917034f31080ad4ad36e14dc2018c80d8bda38f8b6574ace974eca1a65aa336a86df375dabd0661215909551031e796dcee9d0d1a14 + checksum: c10237864c4a99a319f5b19bb6c4234e32b422c03fc358350e9c9106a8612839abcc68e3e06e58ee2f9b450e1d7ab0288f8b89ee8b5338735170af1b48b2112a languageName: node linkType: hard -"@swagger-api/apidom-reference@npm:>=0.90.0 <1.0.0": - version: 0.92.0 - resolution: "@swagger-api/apidom-reference@npm:0.92.0" +"@swagger-api/apidom-reference@npm:>=0.99.1 <1.0.0": + version: 0.99.1 + resolution: "@swagger-api/apidom-reference@npm:0.99.1" dependencies: "@babel/runtime-corejs3": ^7.20.7 - "@swagger-api/apidom-core": ^0.92.0 - "@swagger-api/apidom-error": ^0.92.0 - "@swagger-api/apidom-json-pointer": ^0.92.0 - "@swagger-api/apidom-ns-asyncapi-2": ^0.92.0 - "@swagger-api/apidom-ns-openapi-2": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-0": ^0.92.0 - "@swagger-api/apidom-ns-openapi-3-1": ^0.92.0 - "@swagger-api/apidom-ns-workflows-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-api-design-systems-json": ^0.92.0 - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": ^0.92.0 - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-json": ^0.92.0 - "@swagger-api/apidom-parser-adapter-openapi-json-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": ^0.92.0 - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-2": ^0.92.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": ^0.92.0 - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-workflows-json-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-workflows-yaml-1": ^0.92.0 - "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.92.0 + "@swagger-api/apidom-core": ^0.99.1 + "@swagger-api/apidom-error": ^0.99.0 + "@swagger-api/apidom-json-pointer": ^0.99.1 + "@swagger-api/apidom-ns-asyncapi-2": ^0.99.1 + "@swagger-api/apidom-ns-openapi-2": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-0": ^0.99.1 + "@swagger-api/apidom-ns-openapi-3-1": ^0.99.1 + "@swagger-api/apidom-ns-workflows-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-api-design-systems-json": ^0.99.1 + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": ^0.99.1 + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-json": ^0.99.1 + "@swagger-api/apidom-parser-adapter-openapi-json-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": ^0.99.1 + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-openapi-yaml-2": ^0.99.1 + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": ^0.99.1 + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-workflows-json-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": ^0.99.1 + "@swagger-api/apidom-parser-adapter-yaml-1-2": ^0.99.1 "@types/ramda": ~0.29.6 axios: ^1.4.0 minimatch: ^7.4.3 @@ -17695,94 +14869,94 @@ __metadata: optional: true "@swagger-api/apidom-parser-adapter-yaml-1-2": optional: true - checksum: 05b2c97233f2f60879d2dc62a811a4b31520acb7b3c730d47e60e5927f861c1bf1376e790648b773b242ccb1e24596c567014c570d123655dc59fc2c590668c7 + checksum: 2131dc3df89c1670d8f5fde91f524a240afc253cf4fa8cf3c4b0ed2a35671b20b44fe944c7f3149fecd17e0cce3502f9d333df982d01ca999149a05bd9d9fc12 languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-darwin-arm64@npm:1.4.1" +"@swc/core-darwin-arm64@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-darwin-arm64@npm:1.5.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-darwin-x64@npm:1.4.1" +"@swc/core-darwin-x64@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-darwin-x64@npm:1.5.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.4.1" +"@swc/core-linux-arm-gnueabihf@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm64-gnu@npm:1.4.1" +"@swc/core-linux-arm64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm64-gnu@npm:1.5.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-arm64-musl@npm:1.4.1" +"@swc/core-linux-arm64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-arm64-musl@npm:1.5.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-x64-gnu@npm:1.4.1" +"@swc/core-linux-x64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-x64-gnu@npm:1.5.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-linux-x64-musl@npm:1.4.1" +"@swc/core-linux-x64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-linux-x64-musl@npm:1.5.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-arm64-msvc@npm:1.4.1" +"@swc/core-win32-arm64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-arm64-msvc@npm:1.5.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-ia32-msvc@npm:1.4.1" +"@swc/core-win32-ia32-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-ia32-msvc@npm:1.5.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.4.1": - version: 1.4.1 - resolution: "@swc/core-win32-x64-msvc@npm:1.4.1" +"@swc/core-win32-x64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@swc/core-win32-x64-msvc@npm:1.5.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.4.1 - resolution: "@swc/core@npm:1.4.1" + version: 1.5.0 + resolution: "@swc/core@npm:1.5.0" dependencies: - "@swc/core-darwin-arm64": 1.4.1 - "@swc/core-darwin-x64": 1.4.1 - "@swc/core-linux-arm-gnueabihf": 1.4.1 - "@swc/core-linux-arm64-gnu": 1.4.1 - "@swc/core-linux-arm64-musl": 1.4.1 - "@swc/core-linux-x64-gnu": 1.4.1 - "@swc/core-linux-x64-musl": 1.4.1 - "@swc/core-win32-arm64-msvc": 1.4.1 - "@swc/core-win32-ia32-msvc": 1.4.1 - "@swc/core-win32-x64-msvc": 1.4.1 + "@swc/core-darwin-arm64": 1.5.0 + "@swc/core-darwin-x64": 1.5.0 + "@swc/core-linux-arm-gnueabihf": 1.5.0 + "@swc/core-linux-arm64-gnu": 1.5.0 + "@swc/core-linux-arm64-musl": 1.5.0 + "@swc/core-linux-x64-gnu": 1.5.0 + "@swc/core-linux-x64-musl": 1.5.0 + "@swc/core-win32-arm64-msvc": 1.5.0 + "@swc/core-win32-ia32-msvc": 1.5.0 + "@swc/core-win32-x64-msvc": 1.5.0 "@swc/counter": ^0.1.2 "@swc/types": ^0.1.5 peerDependencies: @@ -17811,7 +14985,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 3549b4a0ba8201be2dd39954ef8375df5d028da5688a68211dc5cbf69ff7a43533e9ffd36f629095f51555552f4df52116384ef779d5ec45c2b9de938e651d57 + checksum: 1abab0b57755020b60ebf2557629c23c65c3546e4cd80f9d02fbdf208d4169c9300a0229c088081b43a01e630c9d86d02f8c240c9fc2842eaed2a517770fcd1d languageName: node linkType: hard @@ -17823,11 +14997,11 @@ __metadata: linkType: hard "@swc/helpers@npm:^0.5.0": - version: 0.5.6 - resolution: "@swc/helpers@npm:0.5.6" + version: 0.5.10 + resolution: "@swc/helpers@npm:0.5.10" dependencies: tslib: ^2.4.0 - checksum: 45de57097e1f6f356f571c7a4f55c692a46b0404c8601e5d9552e152000dfe541ff529d3d01c8a4abf60799d6e7d0078936e40be0a203ca356299d5d6adea765 + checksum: 7a202710e494ff8e6f74b92cc12f2ce226c4d75c0f82c7c4fb911173d27744def1b3a8274fb3820f4161403182acb06ee553eb6e8e5b77b0d0ed7132a9e85bc2 languageName: node linkType: hard @@ -17869,32 +15043,6 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:4.36.1": - version: 4.36.1 - resolution: "@tanstack/query-core@npm:4.36.1" - checksum: 47672094da20d89402d9fe03bb7b0462be73a76ff9ca715169738bc600a719d064d106d083a8eedae22a2c22de22f87d5eb5d31ef447aba771d9190f2117ed10 - languageName: node - linkType: hard - -"@tanstack/react-query@npm:^4.1.3": - version: 4.36.1 - resolution: "@tanstack/react-query@npm:4.36.1" - dependencies: - "@tanstack/query-core": 4.36.1 - use-sync-external-store: ^1.2.0 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-native: "*" - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - checksum: 1aff0a476859386f8d32253fa0d0bde7b81769a6d4d4d9cbd78778f0f955459a3bdb7ee27a0d2ee7373090f12998b45df80db0b5b313bd0a7a39d36c6e8e51c5 - languageName: node - linkType: hard - "@techdocs/cli@workspace:*, @techdocs/cli@workspace:packages/techdocs-cli": version: 0.0.0-use.local resolution: "@techdocs/cli@workspace:packages/techdocs-cli" @@ -17922,26 +15070,25 @@ __metadata: react-dev-utils: ^12.0.0-next.60 serve-handler: ^6.1.3 techdocs-cli-embedded-app: "link:../techdocs-cli-embedded-app" - ts-node: ^10.0.0 winston: ^3.2.1 bin: techdocs-cli: bin/techdocs-cli languageName: unknown linkType: soft -"@testing-library/dom@npm:^9.0.0": - version: 9.3.4 - resolution: "@testing-library/dom@npm:9.3.4" +"@testing-library/dom@npm:^10.0.0": + version: 10.0.0 + resolution: "@testing-library/dom@npm:10.0.0" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 "@types/aria-query": ^5.0.1 - aria-query: 5.1.3 + aria-query: 5.3.0 chalk: ^4.1.0 dom-accessibility-api: ^0.5.9 lz-string: ^1.5.0 pretty-format: ^27.0.2 - checksum: dfd6fb0d6c7b4dd716ba3c47309bc9541b4a55772cb61758b4f396b3785efe2dbc75dc63423545c039078c7ffcc5e4b8c67c2db1b6af4799580466036f70026f + checksum: 682cc22cb3414ffbcf5d9bac777907167c5523f2dcbe5d96cd2e99386009acd879640c7fe5b1c66b199c2d2679f97057410557b3848b871f59c547b1dc8fc28a languageName: node linkType: hard @@ -18000,17 +15147,17 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:^14.0.0": - version: 14.2.1 - resolution: "@testing-library/react@npm:14.2.1" +"@testing-library/react@npm:^15.0.0": + version: 15.0.2 + resolution: "@testing-library/react@npm:15.0.2" dependencies: "@babel/runtime": ^7.12.5 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@types/react-dom": ^18.0.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 7054ae69a0e06c0777da8105fa08fac7e8dac570476a065285d7b993947acda5c948598764a203ebaac759c161c562d6712f19f5bd08be3f09a07e23baee5426 + checksum: 32be030a5540164403f3cd8d6f46ad907119b2bc0a0df43ce6b925cdd520d5003298d06af1ee94d7bd764f294d74e802b6509caf2cf10afc77e67407baa9c1fb languageName: node linkType: hard @@ -18119,15 +15266,6 @@ __metadata: languageName: node linkType: hard -"@types/archiver@npm:^5.3.1": - version: 5.3.4 - resolution: "@types/archiver@npm:5.3.4" - dependencies: - "@types/readdir-glob": "*" - checksum: 4ef27b99091ada9b8f13017d5b9e6d42a439e35a7858b30e040c408e081d98d8db6307b0762500288b5da38cab9823c4756b6abae1fdd2658d42bfb09eb7c5fb - languageName: node - linkType: hard - "@types/archiver@npm:^6.0.0": version: 6.0.2 resolution: "@types/archiver@npm:6.0.2" @@ -18217,19 +15355,6 @@ __metadata: languageName: node linkType: hard -"@types/body-parser-xml@npm:^2.0.2": - version: 2.0.5 - resolution: "@types/body-parser-xml@npm:2.0.5" - dependencies: - "@types/body-parser": "*" - "@types/connect": "*" - "@types/express-serve-static-core": "*" - "@types/node": "*" - "@types/xml2js": "*" - checksum: 97def7a9c60fe72d78a29b14c05bee5cd3f9afb365db919d139d72691ec0435d9df0b2c2f208edcc375c8a78e5dce75bd142c8f2fd5377c101f1c80405df6506 - languageName: node - linkType: hard - "@types/body-parser@npm:*, @types/body-parser@npm:^1.19.0": version: 1.19.5 resolution: "@types/body-parser@npm:1.19.5" @@ -18240,12 +15365,12 @@ __metadata: languageName: node linkType: hard -"@types/bonjour@npm:^3.5.9": - version: 3.5.10 - resolution: "@types/bonjour@npm:3.5.10" +"@types/bonjour@npm:^3.5.13": + version: 3.5.13 + resolution: "@types/bonjour@npm:3.5.13" dependencies: "@types/node": "*" - checksum: bfcadb042a41b124c4e3de4925e3be6d35b78f93f27c4535d5ff86980dc0f8bc407ed99b9b54528952dc62834d5a779392f7a12c2947dd19330eb05a6bcae15a + checksum: e827570e097bd7d625a673c9c208af2d1a22fa3885c0a1646533cf24394c839c3e5f60ac1bc60c0ddcc69c0615078c9fb2c01b42596c7c582d895d974f2409ee languageName: node linkType: hard @@ -18293,7 +15418,7 @@ __metadata: languageName: node linkType: hard -"@types/codemirror@npm:^5.0.0, @types/codemirror@npm:^5.60.8": +"@types/codemirror@npm:^5.60.8": version: 5.60.15 resolution: "@types/codemirror@npm:5.60.15" dependencies: @@ -18302,31 +15427,6 @@ __metadata: languageName: node linkType: hard -"@types/color-convert@npm:*": - version: 2.0.0 - resolution: "@types/color-convert@npm:2.0.0" - dependencies: - "@types/color-name": "*" - checksum: 027b68665dc2278cc2d83e796ada0a05a08aa5a11297e227c48c7f9f6eac518dec98578ab0072bd211963d3e4b431da70b20ea28d6c3136d0badfd3f9913baee - languageName: node - linkType: hard - -"@types/color-name@npm:*": - version: 1.1.1 - resolution: "@types/color-name@npm:1.1.1" - checksum: b71fcad728cc68abcba1d405742134410c8f8eb3c2ef18113b047afca158ad23a4f2c229bcf71a38f4a818dead375c45b20db121d0e69259c2d81e97a740daa6 - languageName: node - linkType: hard - -"@types/color@npm:^3.0.1": - version: 3.0.6 - resolution: "@types/color@npm:3.0.6" - dependencies: - "@types/color-convert": "*" - checksum: 0f16dcf4e202896d5425019c44a1f99713fca998052ab2fd836cdd38048398a0caf5b79a2efe560e41fca4b9401e8d8f6f02ed541cfea30cca3a8cb1b50b80f7 - languageName: node - linkType: hard - "@types/command-exists@npm:^1.2.0": version: 1.2.3 resolution: "@types/command-exists@npm:1.2.3" @@ -18343,7 +15443,7 @@ __metadata: languageName: node linkType: hard -"@types/compression@npm:^1.7.0, @types/compression@npm:^1.7.2": +"@types/compression@npm:^1.7.0": version: 1.7.5 resolution: "@types/compression@npm:1.7.5" dependencies: @@ -18361,13 +15461,13 @@ __metadata: languageName: node linkType: hard -"@types/connect-history-api-fallback@npm:^1.3.5": - version: 1.3.5 - resolution: "@types/connect-history-api-fallback@npm:1.3.5" +"@types/connect-history-api-fallback@npm:^1.5.4": + version: 1.5.4 + resolution: "@types/connect-history-api-fallback@npm:1.5.4" dependencies: "@types/express-serve-static-core": "*" "@types/node": "*" - checksum: 464d06e5ab00f113fa89978633d5eb00d225aeb4ebbadc07f6f3bc337aa7cbfcd74957b2a539d6d47f2e128e956a17819973ec7ae62ade2e16e367a6c38b8d3a + checksum: e1dee43b8570ffac02d2d47a2b4ba80d3ca0dd1840632dafb221da199e59dbe3778d3d7303c9e23c6b401f37c076935a5bc2aeae1c4e5feaefe1c371fe2073fd languageName: node linkType: hard @@ -18381,11 +15481,11 @@ __metadata: linkType: hard "@types/cookie-parser@npm:^1.4.2": - version: 1.4.6 - resolution: "@types/cookie-parser@npm:1.4.6" + version: 1.4.7 + resolution: "@types/cookie-parser@npm:1.4.7" dependencies: "@types/express": "*" - checksum: b1bbb17bc4189c0e953d4996b3b58bfa20161c27db21f98353e237032e7559aec733735d8902c283300e0a4cded20e62b1a5086af608608ef30a45387e080360 + checksum: 7b87c59420598e686a57e240be6e0db53967c3c8814be9326bf86609ee2fc39c4b3b9f2263e1deba43526090121d1df88684b64c19f7b494a80a4437caf3d40b languageName: node linkType: hard @@ -18435,20 +15535,6 @@ __metadata: languageName: node linkType: hard -"@types/css-font-loading-module@npm:0.0.7": - version: 0.0.7 - resolution: "@types/css-font-loading-module@npm:0.0.7" - checksum: a074d3b824b2232160f2353daf1cc62937e4a24154d13607f14f93feaaac6abcf069c8ae02c1396840950fa02c1b3f19ce0f119321f9735905bfb3cd4b9b2021 - languageName: node - linkType: hard - -"@types/d3-array@npm:^3.0.3": - version: 3.0.4 - resolution: "@types/d3-array@npm:3.0.4" - checksum: b0e398365fc1f638d48442e865e036d671c731b2b18f7a92e5172db1f60f5a38d4cd992693a29ad64b38e7ba981eb8c63a2aef95fbdcfbc4bf8926a9cb9ca978 - languageName: node - linkType: hard - "@types/d3-color@npm:*": version: 3.0.2 resolution: "@types/d3-color@npm:3.0.2" @@ -18456,21 +15542,7 @@ __metadata: languageName: node linkType: hard -"@types/d3-ease@npm:^3.0.0": - version: 3.0.0 - resolution: "@types/d3-ease@npm:3.0.0" - checksum: 1be7c993643b5a08332e0ee146375a3845545d8deb423db5d152e0b061524385d2345ceccf968f75f605247b940dd3f9a144335fee2e7d935cddaf187afb7095 - languageName: node - linkType: hard - -"@types/d3-force@npm:^3.0.0": - version: 3.0.9 - resolution: "@types/d3-force@npm:3.0.9" - checksum: 6ec16109b5048cda0877931b5e60565436fee697ccbc223eae1562c4a8401dddacb25b0137da2babca2a810ad0471114444e08c8e395ce90758d768a05a23b4f - languageName: node - linkType: hard - -"@types/d3-interpolate@npm:*, @types/d3-interpolate@npm:^3.0.1": +"@types/d3-interpolate@npm:*": version: 3.0.1 resolution: "@types/d3-interpolate@npm:3.0.1" dependencies: @@ -18486,22 +15558,6 @@ __metadata: languageName: node linkType: hard -"@types/d3-path@npm:^1": - version: 1.0.9 - resolution: "@types/d3-path@npm:1.0.9" - checksum: acbf7376fd7bef61701bce915bf5a9cb5eaa9741b7919d3e644f841a65faf1aea3cf63ba949c21ddda8c9849221394856a2054805aa698d3bb5ac3fe7d029817 - languageName: node - linkType: hard - -"@types/d3-scale@npm:^4.0.2": - version: 4.0.3 - resolution: "@types/d3-scale@npm:4.0.3" - dependencies: - "@types/d3-time": "*" - checksum: 76684da8519ab5f2210e647f74f96ece9c6816dea4ad5d76131121703a5268cc65687a8bc9ebbf4a44039482247336d98811ecc3fbfeb7f0122fdce4bb295547 - languageName: node - linkType: hard - "@types/d3-selection@npm:*, @types/d3-selection@npm:^3.0.1": version: 3.0.10 resolution: "@types/d3-selection@npm:3.0.10" @@ -18509,16 +15565,7 @@ __metadata: languageName: node linkType: hard -"@types/d3-shape@npm:^1": - version: 1.3.12 - resolution: "@types/d3-shape@npm:1.3.12" - dependencies: - "@types/d3-path": ^1 - checksum: 3a62a0a20ef3f767ecd396b2331b836aeaba43a87926a33bb257e3bbe9c70013a2be60718dd94539e287d628da2c5b6f80675c12c0c3a086a3f4129b04ac2285 - languageName: node - linkType: hard - -"@types/d3-shape@npm:^3.0.1, @types/d3-shape@npm:^3.1.0": +"@types/d3-shape@npm:^3.0.1": version: 3.1.6 resolution: "@types/d3-shape@npm:3.1.6" dependencies: @@ -18527,20 +15574,6 @@ __metadata: languageName: node linkType: hard -"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0": - version: 3.0.0 - resolution: "@types/d3-time@npm:3.0.0" - checksum: e76adb056daccf80107f4db190ac6deb77e8774f00362bb6c76f178e67f2f217422fe502b654edbc9ac6451f6619045b9f6f5fe0db1ec5520e2ada377af7c72e - languageName: node - linkType: hard - -"@types/d3-timer@npm:^3.0.0": - version: 3.0.0 - resolution: "@types/d3-timer@npm:3.0.0" - checksum: 1ec86b3808de6ecfa93cfdf34254761069658af0cc1d9540e8353dbcba161cdf1296a0724187bd17433b2ff16563115fd20b85fc89d5e809ff28f9b1ab134b42 - languageName: node - linkType: hard - "@types/d3-zoom@npm:^3.0.1": version: 3.0.8 resolution: "@types/d3-zoom@npm:3.0.8" @@ -18568,9 +15601,9 @@ __metadata: linkType: hard "@types/diff@npm:^5.0.0": - version: 5.0.9 - resolution: "@types/diff@npm:5.0.9" - checksum: fb5cb6d6407e3ebcd8883bdc9f9124b57ebc04720cfb605afc5f839f9a71878ccf895da66b09d5d8df25e684cfe57a6f6f4bf65f87ccc0ce0b58a18b1f3ce5b0 + version: 5.2.0 + resolution: "@types/diff@npm:5.2.0" + checksum: 07e20ba25d15b997758cc248628bb1e6459e7b396c868f176dee1e6a5d1dfcdf1e186fb5bf5e67128d7f55a11e989cff2ec656de089e15ed4a44e654c5c1fda3 languageName: node linkType: hard @@ -18584,13 +15617,14 @@ __metadata: languageName: node linkType: hard -"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.8": - version: 3.3.23 - resolution: "@types/dockerode@npm:3.3.23" +"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.24": + version: 3.3.28 + resolution: "@types/dockerode@npm:3.3.28" dependencies: "@types/docker-modem": "*" "@types/node": "*" - checksum: 065e9ae43f13641e0df149335914d10af95e559002efe5a5de8e56df9a21b4309b18dbc04fd4c59a4e893c4fedc7df892db28e9d25457bce0c4fd33d21a67834 + "@types/ssh2": "*" + checksum: d354d790a970b20f7e6b65554eaf851a931adb6fdce831408797b660ff58bf46e87c625ae56c8f7eb902437515cc2286a7cb171ca4e54fbc1262f2d08ab93b78 languageName: node linkType: hard @@ -18638,17 +15672,17 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:*, @types/eslint@npm:^8.37.0": - version: 8.56.2 - resolution: "@types/eslint@npm:8.56.2" +"@types/eslint@npm:*, @types/eslint@npm:^8.56.5": + version: 8.56.5 + resolution: "@types/eslint@npm:8.56.5" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 38e054971596f5c0413f66a62dc26b10e0a21ac46ceacb06fbf8cfb838d20820787209b17218b3916e4c23d990ff77cfdb482d655cac0e0d2b837d430fcc5db8 + checksum: 95a7a23ca38c78e5c27a2ed36ef60f094d5e6589e3473c320b6ff69eb3ca6333d5b7f0d5053416369f5ab2fb86874df19562d4d67a98237c17def6e30abff540 languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5": +"@types/estree@npm:*, @types/estree@npm:1.0.5, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a @@ -18677,27 +15711,27 @@ __metadata: linkType: hard "@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": - version: 4.17.43 - resolution: "@types/express-serve-static-core@npm:4.17.43" + version: 4.19.0 + resolution: "@types/express-serve-static-core@npm:4.19.0" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 08e940cae52eb1388a7b5f61d65f028e783add77d1854243ae920a6a2dfb5febb6acaafbcf38be9d678b0411253b9bc325893c463a93302405f24135664ab1e4 + checksum: 39c09fcb3f61de96ed56d97273874cafe50e6675ac254af4d77014e569e4fdc29d1d0d1dd12e11f008cb9a52785b07c2801c6ba91397965392b20c75ee01fb4e languageName: node linkType: hard "@types/express-session@npm:^1.17.2": - version: 1.17.10 - resolution: "@types/express-session@npm:1.17.10" + version: 1.18.0 + resolution: "@types/express-session@npm:1.18.0" dependencies: "@types/express": "*" - checksum: 2fb63b53e164f615a538d4be292695789a7f3105ce3246b8d3816e78eca05c8cce43d703af55c4f675c99cfb6fa512ae70a787e536e2b064f001fda897e0d5ab + checksum: f624bc956d223eda618dc3ee5908cfc91d5cf67252aa83e667c1260b96c2d2ac302407d57d2a57b29728a21bf521f09c6409da5e727509c01a2b50d7a012f0a1 languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.14, @types/express@npm:^4.17.17, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": +"@types/express@npm:*, @types/express@npm:^4.17.14, @types/express@npm:^4.17.17, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: @@ -18719,13 +15753,6 @@ __metadata: languageName: node linkType: hard -"@types/gapi.client@npm:*": - version: 1.0.5 - resolution: "@types/gapi.client@npm:1.0.5" - checksum: 2e85b381b45e290de13052e108e4281c0966065db085c3b4294cd801c9425f8ad37b38f76f6a1f404a963fa326564bed953db3352c933c4f417fa209ff4d3c0c - languageName: node - linkType: hard - "@types/git-url-parse@npm:^9.0.0": version: 9.0.3 resolution: "@types/git-url-parse@npm:9.0.3" @@ -18801,25 +15828,23 @@ __metadata: languageName: node linkType: hard -"@types/http-errors@npm:^2.0.0": +"@types/http-errors@npm:*, @types/http-errors@npm:^2.0.0": version: 2.0.4 resolution: "@types/http-errors@npm:2.0.4" checksum: 1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3 languageName: node linkType: hard -"@types/http-proxy-middleware@npm:^0.19.3": - version: 0.19.3 - resolution: "@types/http-proxy-middleware@npm:0.19.3" +"@types/http-proxy-middleware@npm:^1.0.0": + version: 1.0.0 + resolution: "@types/http-proxy-middleware@npm:1.0.0" dependencies: - "@types/connect": "*" - "@types/http-proxy": "*" - "@types/node": "*" - checksum: 51000558db0aad31947fd60b6ba6cbd05782e09c17ded63bf9de2574200695885b362d23cf16cb796797d5779c1e3b32792bbef69386dd2a9ce688f7856cd8ec + http-proxy-middleware: "*" + checksum: 643ce3ec3b9f302328eadd8d6487c01dd8702dd17beaa1bcf35c3cdb4c9eaf512ffd3c8aa8c66790900ec60315ecdbbc8895244203c5296fdd24843d451496ae languageName: node linkType: hard -"@types/http-proxy@npm:*, @types/http-proxy@npm:^1.17.4, @types/http-proxy@npm:^1.17.8": +"@types/http-proxy@npm:^1.17.10, @types/http-proxy@npm:^1.17.4, @types/http-proxy@npm:^1.17.8": version: 1.17.14 resolution: "@types/http-proxy@npm:1.17.14" dependencies: @@ -18828,7 +15853,7 @@ __metadata: languageName: node linkType: hard -"@types/humanize-duration@npm:^3.18.1, @types/humanize-duration@npm:^3.25.1, @types/humanize-duration@npm:^3.27.1": +"@types/humanize-duration@npm:^3.18.1": version: 3.27.4 resolution: "@types/humanize-duration@npm:3.27.4" checksum: aa7fa41af839021c846a1728d2f097b7885f80acbc5050623a9804d23fd8fee19d2654eaae331f000a4e551b88d99cd0b5f6cc97aa99f869b9205f6248066827 @@ -18877,26 +15902,7 @@ __metadata: languageName: node linkType: hard -"@types/jenkins@npm:^1.0.0": - version: 1.0.2 - resolution: "@types/jenkins@npm:1.0.2" - dependencies: - "@types/node": "*" - form-data: ^4.0.0 - checksum: c02895642c81a74cb40740117b5fce0af768ac7985028b6fd0c68d88b350261473db8c05681fc1de0c612579f905f283f0de33efe683ea9a716ae5264287bfba - languageName: node - linkType: hard - -"@types/jest-when@npm:^3.5.0": - version: 3.5.5 - resolution: "@types/jest-when@npm:3.5.5" - dependencies: - "@types/jest": "*" - checksum: 816c1ed5554182c43261d23c2902506c316bc0368f2ea1e632a0a93d05d8f6f2918afa6a406c2f5fdd4d277e042b8d2ba797993dc3c2fd2d5f53cda946696772 - languageName: node - linkType: hard - -"@types/jest@npm:*, @types/jest@npm:^29.0.0, @types/jest@npm:^29.5.11": +"@types/jest@npm:^29.5.11": version: 29.5.12 resolution: "@types/jest@npm:29.5.12" dependencies: @@ -18906,16 +15912,6 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:^28.1.3": - version: 28.1.8 - resolution: "@types/jest@npm:28.1.8" - dependencies: - expect: ^28.0.0 - pretty-format: ^28.0.0 - checksum: d4cd36158a3ae1d4b42cc48a77c95de74bc56b84cf81e09af3ee0399c34f4a7da8ab9e787570f10004bd642f9e781b0033c37327fbbf4a8e4b6e37e8ee3693a7 - languageName: node - linkType: hard - "@types/jquery@npm:^3.3.34": version: 3.5.29 resolution: "@types/jquery@npm:3.5.29" @@ -19008,16 +16004,6 @@ __metadata: languageName: node linkType: hard -"@types/jss@npm:^9.5.6": - version: 9.5.8 - resolution: "@types/jss@npm:9.5.8" - dependencies: - csstype: ^2.0.0 - indefinite-observable: ^1.0.1 - checksum: 6e51707529a15f2f5ff94555ecb555d29427fd10c4f3d2d29474934292e365c2dfaa4ad30b2ab46946201cbca7f6e8df56513a22fc6ceca10a979db8338935c5 - languageName: node - linkType: hard - "@types/keyv@npm:*, @types/keyv@npm:^3.1.1": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" @@ -19027,7 +16013,7 @@ __metadata: languageName: node linkType: hard -"@types/ldapjs@npm:^2.2.0": +"@types/ldapjs@npm:^2.2.5": version: 2.2.5 resolution: "@types/ldapjs@npm:2.2.5" dependencies: @@ -19037,16 +16023,16 @@ __metadata: linkType: hard "@types/libsodium-wrappers@npm:^0.7.10": - version: 0.7.13 - resolution: "@types/libsodium-wrappers@npm:0.7.13" - checksum: 94d608bed8ccd364754c3a7bf5d4c770b229efa33f0c475061b1b82bb8d5da8d57a72df0b8876b887077edbb6ff9594b7a1183029de4d1ad679821d1013f3db9 + version: 0.7.14 + resolution: "@types/libsodium-wrappers@npm:0.7.14" + checksum: 565d178cd12aa5f7abc03149e50a962450d797e995935368ca1abe1cb5a5b96d81f3115a91f6b6f7dcff210d25f104003708b4bfc5a34751f23460efeb169fa4 languageName: node linkType: hard -"@types/lodash@npm:^4.14.151, @types/lodash@npm:^4.14.173, @types/lodash@npm:^4.14.175": - version: 4.14.202 - resolution: "@types/lodash@npm:4.14.202" - checksum: a91acf3564a568c6f199912f3eb2c76c99c5a0d7e219394294213b3f2d54f672619f0fde4da22b29dc5d4c31457cd799acc2e5cb6bd90f9af04a1578483b6ff7 +"@types/lodash@npm:^4.14.151": + version: 4.17.0 + resolution: "@types/lodash@npm:4.17.0" + checksum: 3f98c0b67a93994cbc3403d4fa9dbaf52b0b6bb7f07a764d73875c2dcd5ef91222621bd5bcf8eee7b417a74d175c2f7191b9f595f8603956fd06f0674c0cba93 languageName: node linkType: hard @@ -19064,17 +16050,10 @@ __metadata: languageName: node linkType: hard -"@types/luxon@npm:^3.0.0, @types/luxon@npm:~3.3.0": - version: 3.3.8 - resolution: "@types/luxon@npm:3.3.8" - checksum: 026711b4aefc01c6e233e359c693b6d4c0873acc3f52a08661ea3751b2cf3e34d1ce1d5b0b99b0e40a059a2a3755acc20498d37db5f9a5a4f0f330cdf72db3db - languageName: node - linkType: hard - -"@types/marked@npm:^5.0.0": - version: 5.0.2 - resolution: "@types/marked@npm:5.0.2" - checksum: 2875618970bd5aaba472e313c799bbe241fe9e31d1e79782841a0cc04e08ab2a98653166f1fb99bf8bcf140d3878c3ab960a12aa8f0fb949d8277e8a01d3411b +"@types/luxon@npm:^3.0.0, @types/luxon@npm:~3.4.0": + version: 3.4.2 + resolution: "@types/luxon@npm:3.4.2" + checksum: 6f92d5bd02e89f310395753506bcd9cef3a56f5940f7a50db2a2b9822bce753553ac767d143cb5b4f9ed5ddd4a84e64f89ff538082ceb4d18739af7781b56925 languageName: node linkType: hard @@ -19101,6 +16080,13 @@ __metadata: languageName: node linkType: hard +"@types/mime@npm:*": + version: 3.0.4 + resolution: "@types/mime@npm:3.0.4" + checksum: a6139c8e1f705ef2b064d072f6edc01f3c099023ad7c4fce2afc6c2bf0231888202adadbdb48643e8e20da0ce409481a49922e737eca52871b3dc08017455843 + languageName: node + linkType: hard + "@types/mime@npm:^1": version: 1.3.2 resolution: "@types/mime@npm:1.3.2" @@ -19115,7 +16101,7 @@ __metadata: languageName: node linkType: hard -"@types/minimatch@npm:^5.0.0, @types/minimatch@npm:^5.1.2": +"@types/minimatch@npm:^5.1.2": version: 5.1.2 resolution: "@types/minimatch@npm:5.1.2" checksum: 0391a282860c7cb6fe262c12b99564732401bdaa5e395bee9ca323c312c1a0f45efbf34dce974682036e857db59a5c9b1da522f3d6055aeead7097264c8705a8 @@ -19173,7 +16159,7 @@ __metadata: languageName: node linkType: hard -"@types/node-fetch@npm:^2.5.0, @types/node-fetch@npm:^2.5.12, @types/node-fetch@npm:^2.5.7": +"@types/node-fetch@npm:^2.5.0, @types/node-fetch@npm:^2.5.12": version: 2.6.11 resolution: "@types/node-fetch@npm:2.6.11" dependencies: @@ -19192,12 +16178,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1, @types/node@npm:^20.11.16": - version: 20.11.17 - resolution: "@types/node@npm:20.11.17" +"@types/node@npm:*, @types/node@npm:>=12.12.47, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1, @types/node@npm:^20.10.6, @types/node@npm:^20.11.16": + version: 20.12.7 + resolution: "@types/node@npm:20.12.7" dependencies: undici-types: ~5.26.4 - checksum: 59c0dde187120adc97da30063c86511664b24b50fe777abfe1f557c217d0a0b84a68aaab5ef8ac44f5c2986b3f9cd605a15fa6e4f31195e594da96bbe9617c20 + checksum: 7cc979f7e2ca9a339ec71318c3901b9978555257929ef3666987f3e447123bc6dc92afcc89f6347e09e07d602fde7d51bcddea626c23aa2bb74aeaacfd1e1686 languageName: node linkType: hard @@ -19275,13 +16261,6 @@ __metadata: languageName: node linkType: hard -"@types/parse-link-header@npm:^2.0.1": - version: 2.0.3 - resolution: "@types/parse-link-header@npm:2.0.3" - checksum: 600093cd66fcc3841e799837581ba9d33ae49c299c00ad3d55791a90f5baa876511cf39aecbf06bc07c60eb7ccd6766ecc8feff52ecae241621f7b1e6c6cdcbc - languageName: node - linkType: hard - "@types/passport-auth0@npm:^1.0.5": version: 1.0.9 resolution: "@types/passport-auth0@npm:1.0.9" @@ -19354,7 +16333,7 @@ __metadata: languageName: node linkType: hard -"@types/passport@npm:*, @types/passport@npm:^1.0.11, @types/passport@npm:^1.0.3": +"@types/passport@npm:*, @types/passport@npm:^1.0.11, @types/passport@npm:^1.0.16, @types/passport@npm:^1.0.3": version: 1.0.16 resolution: "@types/passport@npm:1.0.16" dependencies: @@ -19364,13 +16343,13 @@ __metadata: linkType: hard "@types/pg@npm:^8.6.6": - version: 8.11.0 - resolution: "@types/pg@npm:8.11.0" + version: 8.11.5 + resolution: "@types/pg@npm:8.11.5" dependencies: "@types/node": "*" pg-protocol: "*" pg-types: ^4.0.1 - checksum: 8ae18abce86a012afdd68b2fb85a9fd0e9529f2dae8ca64311a4804fc8423441d605df51f547170efa4584c6ee9f919b4f5f731d5a6221386c5d04560de4334c + checksum: 7346d3df959a8d279cba581c8ee93ed7e331e516c5d8c6866029b9f70eadecb8400818bdc9994d69dd75ccab5bdb7e5a1fc16897efd2e3033fa1ccecd2d2d31a languageName: node linkType: hard @@ -19418,12 +16397,12 @@ __metadata: languageName: node linkType: hard -"@types/puppeteer@npm:^5.4.4": - version: 5.4.7 - resolution: "@types/puppeteer@npm:5.4.7" +"@types/puppeteer@npm:^7.0.0": + version: 7.0.4 + resolution: "@types/puppeteer@npm:7.0.4" dependencies: - "@types/node": "*" - checksum: 491c0ca2d879b72e869f5152a9ea7de1356a66f44ef6210fdd5c5036d893b4ee2956212e2f3353c7045b9e56d1a4cea408f41a26d7cf3708774c4d6c19a7c654 + puppeteer: "*" + checksum: c84a44b054454c13935a9cf0f8983166e238532397af4f321c918d89b43a91f854460e3d0dda122f72c258b444dbcdc04ada950e35adc1938ff3b7831c6fd7a4 languageName: node linkType: hard @@ -19516,15 +16495,6 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^2.0.8": - version: 2.9.2 - resolution: "@types/react-transition-group@npm:2.9.2" - dependencies: - "@types/react": "*" - checksum: 6f30fffc221339de90bd3e999f32328618cfaedfcaa501603f5ddc5bed1c2dbaa0d51347c3a25e5f8fd3041c671aabd2b7bfbcad611a7636adcd9da4e0666fa5 - languageName: node - linkType: hard - "@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.10": version: 4.4.10 resolution: "@types/react-transition-group@npm:4.4.10" @@ -19553,13 +16523,13 @@ __metadata: linkType: hard "@types/react@npm:^18": - version: 18.2.55 - resolution: "@types/react@npm:18.2.55" + version: 18.2.58 + resolution: "@types/react@npm:18.2.58" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: a8eb4fa77f73831b9112d4f11a7006217dc0740361649b9b0da3fd441d151a9cd415d5d68b91c0af4e430e063424d301c77489e5edaddc9f711c4e46cf9818a5 + checksum: 42551e30c8a54161a11b2ecd11406782ddba4472a4471d45034c551295263d56f06234f283526d0c0420352ce9ce9675b2a6c65db7a287d9613643d3ceaaf1f0 languageName: node linkType: hard @@ -19572,16 +16542,6 @@ __metadata: languageName: node linkType: hard -"@types/recharts@npm:^1.8.14, @types/recharts@npm:^1.8.15": - version: 1.8.29 - resolution: "@types/recharts@npm:1.8.29" - dependencies: - "@types/d3-shape": ^1 - "@types/react": "*" - checksum: 091d018298d9c5e22b1a937e1229e721e2f6ac030fb73024717f6d20f3ff18575557560afd2247987f102f5981402b1fa1bf13362147aa0e89656ecc51ac3e2b - languageName: node - linkType: hard - "@types/recursive-readdir@npm:^2.2.0": version: 2.2.4 resolution: "@types/recursive-readdir@npm:2.2.4" @@ -19591,13 +16551,6 @@ __metadata: languageName: node linkType: hard -"@types/regression@npm:^2.0.0": - version: 2.0.6 - resolution: "@types/regression@npm:2.0.6" - checksum: c412ddd924efd53395f0011b38a6b1dbc94fc71adfa80efcb6657f0f1b6123fb27c101798dda8d0aa638c925900b4b4a9c5c03504a0d1255edd160e3090a5ce9 - languageName: node - linkType: hard - "@types/request@npm:^2.47.1, @types/request@npm:^2.48.8": version: 2.48.12 resolution: "@types/request@npm:2.48.12" @@ -19626,20 +16579,19 @@ __metadata: languageName: node linkType: hard -"@types/retry@npm:^0.12.0": - version: 0.12.0 - resolution: "@types/retry@npm:0.12.0" - checksum: 61a072c7639f6e8126588bf1eb1ce8835f2cb9c2aba795c4491cf6310e013267b0c8488039857c261c387e9728c1b43205099223f160bb6a76b4374f741b5603 +"@types/retry@npm:0.12.2": + version: 0.12.2 + resolution: "@types/retry@npm:0.12.2" + checksum: e5675035717b39ce4f42f339657cae9637cf0c0051cf54314a6a2c44d38d91f6544be9ddc0280587789b6afd056be5d99dbe3e9f4df68c286c36321579b1bf4a languageName: node linkType: hard "@types/rollup-plugin-peer-deps-external@npm:^2.2.0": - version: 2.2.4 - resolution: "@types/rollup-plugin-peer-deps-external@npm:2.2.4" + version: 2.2.5 + resolution: "@types/rollup-plugin-peer-deps-external@npm:2.2.5" dependencies: - "@types/node": "*" rollup: ^0.63.4 - checksum: 215849a0ae0f5bd4aec0ae2c1f05defaca1a88013b1c89ebfd207a4732799b970b0aaf7d3fe1797548f08c972e1bd028352d3193d00cb570d58cd86fd4da9447 + checksum: 3f0d130fc15c80eac737391e180e77597da1200ff1f6d28a44f785a0de7f29144df805ab5b020ba38b243af6959e9da0757efa4141c4e737cd04eebe50f59c07 languageName: node linkType: hard @@ -19652,15 +16604,6 @@ __metadata: languageName: node linkType: hard -"@types/sanitize-html@npm:^2.6.2": - version: 2.11.0 - resolution: "@types/sanitize-html@npm:2.11.0" - dependencies: - htmlparser2: ^8.0.0 - checksum: a901d55d31cd946a7fce0130cc7cf6bcf56602af9c87291be77d8149c60e7afc47c83ca74c67c2d84e6ba029fe9bbd6f14f89a8cb30fbd185766eebc5722c251 - languageName: node - linkType: hard - "@types/sarif@npm:^2.1.4": version: 2.1.5 resolution: "@types/sarif@npm:2.1.5" @@ -19675,10 +16618,10 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.8, @types/semver@npm:^7.5.0": - version: 7.5.7 - resolution: "@types/semver@npm:7.5.7" - checksum: 5af9b13e3d74d86d4b618f6506ccbded801fb35dbc28608cd5a7bfb8bcac0021dd35ef305a72a0c2a8def0cff60acd706bfee16a9ed1c39a893d2a175e778ea7 +"@types/semver@npm:^7.3.12, @types/semver@npm:^7.5.0": + version: 7.5.8 + resolution: "@types/semver@npm:7.5.8" + checksum: ea6f5276f5b84c55921785a3a27a3cd37afee0111dfe2bcb3e03c31819c197c782598f17f0b150a69d453c9584cd14c4c4d7b9a55d2c5e6cacd4d66fdb3b3663 languageName: node linkType: hard @@ -19701,22 +16644,23 @@ __metadata: languageName: node linkType: hard -"@types/serve-index@npm:^1.9.1": - version: 1.9.1 - resolution: "@types/serve-index@npm:1.9.1" +"@types/serve-index@npm:^1.9.4": + version: 1.9.4 + resolution: "@types/serve-index@npm:1.9.4" dependencies: "@types/express": "*" - checksum: 026f3995fb500f6df7c3fe5009e53bad6d739e20b84089f58ebfafb2f404bbbb6162bbe33f72d2f2af32d5b8d3799c8e179793f90d9ed5871fb8591190bb6056 + checksum: 72727c88d54da5b13275ebfb75dcdc4aa12417bbe9da1939e017c4c5f0c906fae843aa4e0fbfe360e7ee9df2f3d388c21abfc488f77ce58693fb57809f8ded92 languageName: node linkType: hard -"@types/serve-static@npm:*, @types/serve-static@npm:^1.13.10": - version: 1.13.10 - resolution: "@types/serve-static@npm:1.13.10" +"@types/serve-static@npm:*, @types/serve-static@npm:^1.15.5": + version: 1.15.5 + resolution: "@types/serve-static@npm:1.15.5" dependencies: - "@types/mime": ^1 + "@types/http-errors": "*" + "@types/mime": "*" "@types/node": "*" - checksum: eaca858739483e3ded254cad7d7a679dc2c8b3f52c8bb0cd845b3b7eb1984bde0371fdcb0a5c83aa12e6daf61b6beb762545021f520f08a1fe882a3fa4ea5554 + checksum: 0ff4b3703cf20ba89c9f9e345bc38417860a88e85863c8d6fe274a543220ab7f5f647d307c60a71bb57dc9559f0890a661e8dc771a6ec5ef195d91c8afc4a893 languageName: node linkType: hard @@ -19752,12 +16696,12 @@ __metadata: languageName: node linkType: hard -"@types/sockjs@npm:^0.3.33": - version: 0.3.33 - resolution: "@types/sockjs@npm:0.3.33" +"@types/sockjs@npm:^0.3.36": + version: 0.3.36 + resolution: "@types/sockjs@npm:0.3.36" dependencies: "@types/node": "*" - checksum: b9bbb2b5c5ead2fb884bb019f61a014e37410bddd295de28184e1b2e71ee6b04120c5ba7b9954617f0bdf962c13d06249ce65004490889c747c80d3f628ea842 + checksum: b4b5381122465d80ea8b158537c00bc82317222d3fb31fd7229ff25b31fa89134abfbab969118da55622236bf3d8fee75759f3959908b5688991f492008f29bc languageName: node linkType: hard @@ -19822,7 +16766,7 @@ __metadata: languageName: node linkType: hard -"@types/supertest@npm:^2.0.12, @types/supertest@npm:^2.0.8": +"@types/supertest@npm:^2.0.8": version: 2.0.16 resolution: "@types/supertest@npm:2.0.16" dependencies: @@ -19850,12 +16794,12 @@ __metadata: linkType: hard "@types/tar@npm:^6.1.1": - version: 6.1.11 - resolution: "@types/tar@npm:6.1.11" + version: 6.1.12 + resolution: "@types/tar@npm:6.1.12" dependencies: "@types/node": "*" minipass: ^4.0.0 - checksum: 9b79f61f9179db65ecd3f5e9c0d2152839ad13381d39c38c3a9408aa1f3a2b061ba195e7d758be1863294a0ce69df6659f0e3e09f440c9f5309bded58bc87c89 + checksum: b1cbae1894cc943e3a86f88613853986f97f552c6bec34ee990a47fe5905871d1552397ff440108233d75d05653be2fbc356e62beb0b93a45b927fb88060b438 languageName: node linkType: hard @@ -19877,15 +16821,6 @@ __metadata: languageName: node linkType: hard -"@types/testing-library__jest-dom@npm:^5.9.1": - version: 5.14.9 - resolution: "@types/testing-library__jest-dom@npm:5.14.9" - dependencies: - "@types/jest": "*" - checksum: d364494fc2545316292e88861146146af1e3818792ca63b62a63758b2f737669b687f4aaddfcfbcb7d0e1ed7890a9bd05de23ff97f277d5e68de574497a9ee72 - languageName: node - linkType: hard - "@types/through@npm:*": version: 0.0.30 resolution: "@types/through@npm:0.0.30" @@ -19946,10 +16881,10 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^8.0.0": - version: 8.3.4 - resolution: "@types/uuid@npm:8.3.4" - checksum: 6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f +"@types/uuid@npm:^9.0.0": + version: 9.0.8 + resolution: "@types/uuid@npm:9.0.8" + checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 languageName: node linkType: hard @@ -19981,13 +16916,6 @@ __metadata: languageName: node linkType: hard -"@types/whatwg-mimetype@npm:^3.0.0": - version: 3.0.0 - resolution: "@types/whatwg-mimetype@npm:3.0.0" - checksum: 98254edcddb5b9580aa41c19e6c96d2bfb178285d5c2560e3a1f321f14da70192adc82950baecd2cad5876098b0677fbe813db1edf9ab9ba0a9996f0bf2bb703 - languageName: node - linkType: hard - "@types/wrap-ansi@npm:^3.0.0": version: 3.0.0 resolution: "@types/wrap-ansi@npm:3.0.0" @@ -19995,12 +16923,12 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:*, @types/ws@npm:^8.0.0, @types/ws@npm:^8.5.3, @types/ws@npm:^8.5.5": - version: 8.5.9 - resolution: "@types/ws@npm:8.5.9" +"@types/ws@npm:*, @types/ws@npm:^8.0.0, @types/ws@npm:^8.5.10, @types/ws@npm:^8.5.3": + version: 8.5.10 + resolution: "@types/ws@npm:8.5.10" dependencies: "@types/node": "*" - checksum: 83f436b731d2cdc49a45ced31a0a65cdd2e39c24d7b882776c26efa190dad6553e266d624c7a7089f36ad3ed471e02e729f3219282c80689b435f665df4a2b0b + checksum: 3ec416ea2be24042ebd677932a462cf16d2080393d8d7d0b1b3f5d6eaa4a7387aaf0eefb99193c0bfd29444857cf2e0c3ac89899e130550dc6c14ada8a46d25e languageName: node linkType: hard @@ -20023,7 +16951,7 @@ __metadata: languageName: node linkType: hard -"@types/xml2js@npm:*, @types/xml2js@npm:^0.4.11, @types/xml2js@npm:^0.4.7": +"@types/xml2js@npm:^0.4.11, @types/xml2js@npm:^0.4.7": version: 0.4.14 resolution: "@types/xml2js@npm:0.4.14" dependencies: @@ -20055,7 +16983,7 @@ __metadata: languageName: node linkType: hard -"@types/yauzl@npm:^2.10.0": +"@types/yauzl@npm:^2.10.0, @types/yauzl@npm:^2.9.1": version: 2.10.3 resolution: "@types/yauzl@npm:2.10.3" dependencies: @@ -20064,14 +16992,16 @@ __metadata: languageName: node linkType: hard -"@types/yup@npm:^0.29.13": - version: 0.29.14 - resolution: "@types/yup@npm:0.29.14" - checksum: 291b6c2f06761bfb2be4c551e2c675a0b48512192850ca547837389de8422707b2a2cf50f50e64ea3caf5ddf41cfa36f0ce4bdb820f86ba1f074eabd0e272c2b +"@types/yup@npm:^0.32.0": + version: 0.32.0 + resolution: "@types/yup@npm:0.32.0" + dependencies: + yup: "*" + checksum: 5b30f1118bca288d949bcd4c7e17d1425ffa320eddd751a78c895b158fae0b6cbf242ced45ad47e9e70643c9475da09a7ad004192fb6f2111791d37e6a627e73 languageName: node linkType: hard -"@types/zen-observable@npm:^0.8.0, @types/zen-observable@npm:^0.8.2": +"@types/zen-observable@npm:^0.8.0": version: 0.8.7 resolution: "@types/zen-observable@npm:0.8.7" checksum: 6d4cdccded97f8e21b18224a70524e559abe2568863ed21ea000580aa3446c6d583253e83e8ecc0c93b4060ef3fb7f9d14739a57ee18925cc30e0e7d79713a15 @@ -20264,9 +17194,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.21.21": - version: 4.21.21 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.21" +"@uiw/codemirror-extensions-basic-setup@npm:4.21.25": + version: 4.21.25 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.25" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -20283,19 +17213,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 5d96ec930be286b5e324ee8dd57128171c72a8e333b4b991a5c4f33a05420a638def3776bd1a77c5b88184f7d3cbc6828b5c9a42b3b490f51908bedf69eaa0f0 + checksum: 1714fcb9ff1a80c14cef5b6b78f41d18f3991877fc088e5c5edf4ce4ee203f468a6401aab7d042ceae527f6475e2e11d4f30dbab6e127bd157c6aaf4c68049d2 languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.21.21 - resolution: "@uiw/react-codemirror@npm:4.21.21" + version: 4.21.25 + resolution: "@uiw/react-codemirror@npm:4.21.25" dependencies: "@babel/runtime": ^7.18.6 "@codemirror/commands": ^6.1.0 "@codemirror/state": ^6.1.1 "@codemirror/theme-one-dark": ^6.0.0 - "@uiw/codemirror-extensions-basic-setup": 4.21.21 + "@uiw/codemirror-extensions-basic-setup": 4.21.25 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -20305,7 +17235,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 6a8500290bf0a739fd345221465b10112e0f758914bc8aa28ce0b9904b76489ae018d390f6a2d7dd7752b21f0ed87ba3fedb45b4185d04e4985abf0eb22e6d75 + checksum: 63d7578dab73f66d0357bdd566d24c3c43431627c77b5756f0a982ac5ebff35322e3292ce33a16cb19d5e8fb750a64f59d17c35a3d84c66b38c8454d06613dff languageName: node linkType: hard @@ -20502,13 +17432,13 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/ast@npm:1.11.6" +"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/ast@npm:1.12.1" dependencies: "@webassemblyjs/helper-numbers": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - checksum: 38ef1b526ca47c210f30975b06df2faf1a8170b1636ce239fc5738fc231ce28389dd61ecedd1bacfc03cbe95b16d1af848c805652080cb60982836eb4ed2c6cf + checksum: 31bcc64147236bd7b1b6d29d1f419c1f5845c785e1e42dc9e3f8ca2e05a029e9393a271b84f3a5bff2a32d35f51ff59e2181a6e5f953fe88576acd6750506202 languageName: node linkType: hard @@ -20526,10 +17456,10 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-buffer@npm:1.11.6" - checksum: b14d0573bf680d22b2522e8a341ec451fddd645d1f9c6bd9012ccb7e587a2973b86ab7b89fe91e1c79939ba96095f503af04369a3b356c8023c13a5893221644 +"@webassemblyjs/helper-buffer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.12.1" + checksum: c3ffb723024130308db608e86e2bdccd4868bbb62dffb0a9a1530606496f79c87f8565bd8e02805ce64912b71f1a70ee5fb00307258b0c082c3abf961d097eca languageName: node linkType: hard @@ -20551,15 +17481,15 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.11.6" +"@webassemblyjs/helper-wasm-section@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - checksum: b2cf751bf4552b5b9999d27bbb7692d0aca75260140195cb58ea6374d7b9c2dc69b61e10b211a0e773f66209c3ddd612137ed66097e3684d7816f854997682e9 + "@webassemblyjs/wasm-gen": 1.12.1 + checksum: c19810cdd2c90ff574139b6d8c0dda254d42d168a9e5b3d353d1bc085f1d7164ccd1b3c05592a45a939c47f7e403dc8d03572bb686642f06a3d02932f6f0bc8f languageName: node linkType: hard @@ -20588,68 +17518,68 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-edit@npm:1.11.6" +"@webassemblyjs/wasm-edit@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 - "@webassemblyjs/helper-wasm-section": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-opt": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - "@webassemblyjs/wast-printer": 1.11.6 - checksum: 29ce75870496d6fad864d815ebb072395a8a3a04dc9c3f4e1ffdc63fc5fa58b1f34304a1117296d8240054cfdbc38aca88e71fb51483cf29ffab0a61ef27b481 + "@webassemblyjs/helper-wasm-section": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-opt": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + "@webassemblyjs/wast-printer": 1.12.1 + checksum: ae23642303f030af888d30c4ef37b08dfec7eab6851a9575a616e65d1219f880d9223913a39056dd654e49049d76e97555b285d1f7e56935047abf578cce0692 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-gen@npm:1.11.6" +"@webassemblyjs/wasm-gen@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: a645a2eecbea24833c3260a249704a7f554ef4a94c6000984728e94bb2bc9140a68dfd6fd21d5e0bbb09f6dfc98e083a45760a83ae0417b41a0196ff6d45a23a + checksum: 5787626bb7f0b033044471ddd00ce0c9fe1ee4584e8b73e232051e3a4c99ba1a102700d75337151c8b6055bae77eefa4548960c610a5e4a504e356bd872138ff languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-opt@npm:1.11.6" +"@webassemblyjs/wasm-opt@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 - "@webassemblyjs/helper-buffer": 1.11.6 - "@webassemblyjs/wasm-gen": 1.11.6 - "@webassemblyjs/wasm-parser": 1.11.6 - checksum: b4557f195487f8e97336ddf79f7bef40d788239169aac707f6eaa2fa5fe243557c2d74e550a8e57f2788e70c7ae4e7d32f7be16101afe183d597b747a3bdd528 + "@webassemblyjs/ast": 1.12.1 + "@webassemblyjs/helper-buffer": 1.12.1 + "@webassemblyjs/wasm-gen": 1.12.1 + "@webassemblyjs/wasm-parser": 1.12.1 + checksum: 0e8fa8a0645304a1e18ff40d3db5a2e9233ebaa169b19fcc651d6fc9fe2cac0ce092ddee927318015ae735d9cd9c5d97c0cafb6a51dcd2932ac73587b62df991 languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.11.6, @webassemblyjs/wasm-parser@npm:^1.11.5": - version: 1.11.6 - resolution: "@webassemblyjs/wasm-parser@npm:1.11.6" +"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@webassemblyjs/helper-api-error": 1.11.6 "@webassemblyjs/helper-wasm-bytecode": 1.11.6 "@webassemblyjs/ieee754": 1.11.6 "@webassemblyjs/leb128": 1.11.6 "@webassemblyjs/utf8": 1.11.6 - checksum: 8200a8d77c15621724a23fdabe58d5571415cda98a7058f542e670ea965dd75499f5e34a48675184947c66f3df23adf55df060312e6d72d57908e3f049620d8a + checksum: 176015de3551ac068cd4505d837414f258d9ade7442bd71efb1232fa26c9f6d7d4e11a5c816caeed389943f409af7ebff6899289a992d7a70343cb47009d21a8 languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.11.6": - version: 1.11.6 - resolution: "@webassemblyjs/wast-printer@npm:1.11.6" +"@webassemblyjs/wast-printer@npm:1.12.1": + version: 1.12.1 + resolution: "@webassemblyjs/wast-printer@npm:1.12.1" dependencies: - "@webassemblyjs/ast": 1.11.6 + "@webassemblyjs/ast": 1.12.1 "@xtuc/long": 4.2.2 - checksum: d2fa6a4c427325ec81463e9c809aa6572af6d47f619f3091bf4c4a6fc34f1da3df7caddaac50b8e7a457f8784c62cd58c6311b6cb69b0162ccd8d4c072f79cf8 + checksum: 2974b5dda8d769145ba0efd886ea94a601e61fb37114c14f9a9a7606afc23456799af652ac3052f284909bd42edc3665a76bc9b50f95f0794c053a8a1757b713 languageName: node linkType: hard @@ -20697,13 +17627,6 @@ __metadata: languageName: node linkType: hard -"@xstate/fsm@npm:^1.4.0": - version: 1.6.5 - resolution: "@xstate/fsm@npm:1.6.5" - checksum: da24fa4f40479223da34714640cea64ec894bbfeb2281a0a870af68882ae1d6fb6d724d6e5c0d4e6929728c699b92858f7389ef7d6a5d00ac66ba8cde3934eed - languageName: node - linkType: hard - "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -20802,7 +17725,7 @@ __metadata: languageName: node linkType: hard -"accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": +"accepts@npm:^1.3.7, accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -20986,7 +17909,7 @@ __metadata: languageName: node linkType: hard -"ajv-keywords@npm:^5.0.0": +"ajv-keywords@npm:^5.1.0": version: 5.1.0 resolution: "ajv-keywords@npm:5.1.0" dependencies: @@ -21009,7 +17932,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.11.2, ajv@npm:^8.12.0, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.8.0, ajv@npm:^8.8.2": +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.11.2, ajv@npm:^8.12.0, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.8.2, ajv@npm:^8.9.0": version: 8.12.0 resolution: "ajv@npm:8.12.0" dependencies: @@ -21028,22 +17951,6 @@ __metadata: languageName: node linkType: hard -"already@npm:^3.2.0": - version: 3.4.1 - resolution: "already@npm:3.4.1" - checksum: 4bc145ca4d3c0b92d8cdbd9c47590f5b1e52f7cb112d16961aeab35496cf4639b6f49c5c7bb9056cfdcf47f2c26ac9c9c09a86d11a5108d605e79628d9f64d93 - languageName: node - linkType: hard - -"anafanafo@npm:2.0.0": - version: 2.0.0 - resolution: "anafanafo@npm:2.0.0" - dependencies: - char-width-table-consumer: ^1.0.0 - checksum: c166fc5920ca83c321ecfecdaf7b8b6e09553ad8c6214da39cd82e77decb4b06da440bdcb978ba567c4ed34746e048d61901ff9ddedf52555aeba82642115ac8 - languageName: node - linkType: hard - "analytics-node@npm:^6.2.0": version: 6.2.0 resolution: "analytics-node@npm:6.2.0" @@ -21173,7 +18080,7 @@ __metadata: languageName: node linkType: hard -"app-next-example-plugin@workspace:^, app-next-example-plugin@workspace:packages/app-next-example-plugin": +"app-next-example-plugin@workspace:packages/app-next-example-plugin": version: 0.0.0-use.local resolution: "app-next-example-plugin@workspace:packages/app-next-example-plugin" dependencies: @@ -21236,7 +18143,7 @@ __metadata: languageName: node linkType: hard -"archiver@npm:^5.3.1": +"archiver@npm:^5.3.2": version: 5.3.2 resolution: "archiver@npm:5.3.2" dependencies: @@ -21252,8 +18159,8 @@ __metadata: linkType: hard "archiver@npm:^6.0.0": - version: 6.0.1 - resolution: "archiver@npm:6.0.1" + version: 6.0.2 + resolution: "archiver@npm:6.0.2" dependencies: archiver-utils: ^4.0.1 async: ^3.2.4 @@ -21262,7 +18169,7 @@ __metadata: readdir-glob: ^1.1.2 tar-stream: ^3.0.0 zip-stream: ^5.0.1 - checksum: 20549eef7366173440a86873387412226568744a410626f826998b0dda85fe84e739c542d9db9aca3923b772436eb795eafdff29c2983e683355fdd9faaa0fdb + checksum: 17a20a1291d9bf41e25c96f029373bec5306d6e381063b3ab06ea805d234afaf55a7829c3577dd003558c188c6631769a80c51f245175fdb8310631df36ceb4b languageName: node linkType: hard @@ -21330,16 +18237,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.1.3": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" - dependencies: - deep-equal: ^2.0.5 - checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b - languageName: node - linkType: hard - -"aria-query@npm:^5.0.0, aria-query@npm:^5.3.0": +"aria-query@npm:5.3.0, aria-query@npm:^5.0.0, aria-query@npm:^5.3.0": version: 5.3.0 resolution: "aria-query@npm:5.3.0" dependencies: @@ -21355,13 +18253,13 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.0": - version: 1.0.0 - resolution: "array-buffer-byte-length@npm:1.0.0" +"array-buffer-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "array-buffer-byte-length@npm:1.0.1" dependencies: - call-bind: ^1.0.2 - is-array-buffer: ^3.0.1 - checksum: 044e101ce150f4804ad19c51d6c4d4cfa505c5b2577bd179256e4aa3f3f6a0a5e9874c78cd428ee566ac574c8a04d7ce21af9fe52e844abfdccb82b33035a7c3 + call-bind: ^1.0.5 + is-array-buffer: ^3.0.4 + checksum: 53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e languageName: node linkType: hard @@ -21379,13 +18277,6 @@ __metadata: languageName: node linkType: hard -"array-flatten@npm:^2.1.2": - version: 2.1.2 - resolution: "array-flatten@npm:2.1.2" - checksum: e8988aac1fbfcdaae343d08c9a06a6fddd2c6141721eeeea45c3cf523bf4431d29a46602929455ed548c7a3e0769928cdc630405427297e7081bd118fdec9262 - languageName: node - linkType: hard - "array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": version: 3.1.7 resolution: "array-includes@npm:3.1.7" @@ -21408,6 +18299,13 @@ __metadata: languageName: node linkType: hard +"array-to-table@npm:^1.0.1": + version: 1.0.1 + resolution: "array-to-table@npm:1.0.1" + checksum: 3ca021c642b8698dc2ab3ca48c969af8d3f3d2f0444c5306b456cb716daf6ecdfb442be4bec54b9331de895b384de4e7e77e6f8b453e265e8328519bedd8f9a7 + languageName: node + linkType: hard + "array-union@npm:^2.1.0": version: 2.1.0 resolution: "array-union@npm:2.1.0" @@ -21415,6 +18313,19 @@ __metadata: languageName: node linkType: hard +"array.prototype.findlast@npm:^1.2.4": + version: 1.2.4 + resolution: "array.prototype.findlast@npm:1.2.4" + dependencies: + call-bind: ^1.0.5 + define-properties: ^1.2.1 + es-abstract: ^1.22.3 + es-errors: ^1.3.0 + es-shim-unscopables: ^1.0.2 + checksum: b4c76571adf6c3cffbbbb8acd7ac39d94af6b120dd388dcf44637c22d77ba3ae13dd43d1be25d90956848fae5a01191fbdebe48ce4c0aa0989d7ee269a94a5a4 + languageName: node + linkType: hard + "array.prototype.findlastindex@npm:^1.2.3": version: 1.2.3 resolution: "array.prototype.findlastindex@npm:1.2.3" @@ -21440,7 +18351,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.1, array.prototype.flatmap@npm:^1.3.2": +"array.prototype.flatmap@npm:^1.3.2": version: 1.3.2 resolution: "array.prototype.flatmap@npm:1.3.2" dependencies: @@ -21452,31 +18363,44 @@ __metadata: languageName: node linkType: hard -"array.prototype.tosorted@npm:^1.1.1": - version: 1.1.1 - resolution: "array.prototype.tosorted@npm:1.1.1" +"array.prototype.toreversed@npm:^1.1.2": + version: 1.1.2 + resolution: "array.prototype.toreversed@npm:1.1.2" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - es-shim-unscopables: ^1.0.0 - get-intrinsic: ^1.1.3 - checksum: 7923324a67e70a2fc0a6e40237405d92395e45ebd76f5cb89c2a5cf1e66b47aca6baacd0cd628ffd88830b90d47fff268071493d09c9ae123645613dac2c2ca3 - languageName: node - linkType: hard - -"arraybuffer.prototype.slice@npm:^1.0.2": - version: 1.0.2 - resolution: "arraybuffer.prototype.slice@npm:1.0.2" - dependencies: - array-buffer-byte-length: ^1.0.0 call-bind: ^1.0.2 define-properties: ^1.2.0 es-abstract: ^1.22.1 - get-intrinsic: ^1.2.1 - is-array-buffer: ^3.0.2 + es-shim-unscopables: ^1.0.0 + checksum: 58598193426282155297bedf950dc8d464624a0d81659822fb73124286688644cb7e0e4927a07f3ab2daaeb6617b647736cc3a5e6ca7ade5bb8e573b284e6240 + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.3": + version: 1.1.3 + resolution: "array.prototype.tosorted@npm:1.1.3" + dependencies: + call-bind: ^1.0.5 + define-properties: ^1.2.1 + es-abstract: ^1.22.3 + es-errors: ^1.1.0 + es-shim-unscopables: ^1.0.2 + checksum: 555e8808086bbde9e634c5dc5a8c0a2f1773075447b43b2fa76ab4f94f4e90f416d2a4f881024e1ce1a2931614caf76cd6b408af901c9d7cd13061d0d268f5af + languageName: node + linkType: hard + +"arraybuffer.prototype.slice@npm:^1.0.3": + version: 1.0.3 + resolution: "arraybuffer.prototype.slice@npm:1.0.3" + dependencies: + array-buffer-byte-length: ^1.0.1 + call-bind: ^1.0.5 + define-properties: ^1.2.1 + es-abstract: ^1.22.3 + es-errors: ^1.2.1 + get-intrinsic: ^1.2.3 + is-array-buffer: ^3.0.4 is-shared-array-buffer: ^1.0.2 - checksum: c200faf437786f5b2c80d4564ff5481c886a16dee642ef02abdc7306c7edd523d1f01d1dd12b769c7eb42ac9bc53874510db19a92a2c035c0f6696172aafa5d3 + checksum: 352259cba534dcdd969c92ab002efd2ba5025b2e3b9bead3973150edbdf0696c629d7f4b3f061c5931511e8207bdc2306da614703c820b45dabce39e3daf7e3e languageName: node linkType: hard @@ -21608,10 +18532,10 @@ __metadata: languageName: node linkType: hard -"async-lock@npm:^1.1.0": - version: 1.2.4 - resolution: "async-lock@npm:1.2.4" - checksum: 9b8cf65bb9ac7b58ff95539a03b73d51f64d0aea95cde1ebf787859670a8998f0a5258f118db6b54305bf6ed20cf3a2f923f4dd69a58d472fa78cca436c42342 +"async-lock@npm:^1.1.0, async-lock@npm:^1.4.1": + version: 1.4.1 + resolution: "async-lock@npm:1.4.1" + checksum: 29e70cd892932b7c202437786cedc39ff62123cb6941014739bd3cabd6106326416e9e7c21285a5d1dc042cad239a0f7ec9c44658491ee4a615fd36a21c1d10a languageName: node linkType: hard @@ -21633,22 +18557,13 @@ __metadata: languageName: node linkType: hard -"async@npm:^3.2.0, async@npm:^3.2.3, async@npm:^3.2.4": +"async@npm:^3.2.3, async@npm:^3.2.4": version: 3.2.4 resolution: "async@npm:3.2.4" checksum: 43d07459a4e1d09b84a20772414aa684ff4de085cbcaec6eea3c7a8f8150e8c62aa6cd4e699fe8ee93c3a5b324e777d34642531875a0817a35697522c1b02e89 languageName: node linkType: hard -"asynciterator.prototype@npm:^1.0.0": - version: 1.0.0 - resolution: "asynciterator.prototype@npm:1.0.0" - dependencies: - has-symbols: ^1.0.3 - checksum: e8ebfd9493ac651cf9b4165e9d64030b3da1d17181bb1963627b59e240cdaf021d9b59d44b827dc1dde4e22387ec04c2d0f8720cf58a1c282e34e40cc12721b3 - languageName: node - linkType: hard - "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -21696,10 +18611,12 @@ __metadata: languageName: node linkType: hard -"available-typed-arrays@npm:^1.0.5": - version: 1.0.5 - resolution: "available-typed-arrays@npm:1.0.5" - checksum: 20eb47b3cefd7db027b9bbb993c658abd36d4edd3fe1060e83699a03ee275b0c9b216cc076ff3f2db29073225fb70e7613987af14269ac1fe2a19803ccc97f1a +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: ^1.0.0 + checksum: 1aa3ffbfe6578276996de660848b6e95669d9a95ad149e3dd0c0cda77db6ee1dbd9d1dd723b65b6d277b882dd0c4b91a654ae9d3cf9e1254b7e93e4908d78fd3 languageName: node linkType: hard @@ -21710,26 +18627,26 @@ __metadata: languageName: node linkType: hard -"aws-sdk-client-mock-jest@npm:^3.0.0": - version: 3.0.1 - resolution: "aws-sdk-client-mock-jest@npm:3.0.1" +"aws-sdk-client-mock-jest@npm:^4.0.0": + version: 4.0.0 + resolution: "aws-sdk-client-mock-jest@npm:4.0.0" dependencies: - "@types/jest": ^28.1.3 + expect: ">28.1.3" tslib: ^2.1.0 peerDependencies: - aws-sdk-client-mock: 3.0.1 - checksum: c5c72ae63c9d3862636b833c66ebc708a1c170ba1159508f9a1e56c8e71ba82f7f85a00e68148b72cc699ab3e7ce6945d29bfd23151ae62c3f78133d56585ddd + aws-sdk-client-mock: 4.0.0 + checksum: 177d3317d337e501590ce62769b63407ac9fbfacdea0834b47d46f360c51959e32b598a3c341dcaaf66c4c6e369a72beecff9142e7110149b5bc69891ece2b78 languageName: node linkType: hard -"aws-sdk-client-mock@npm:^3.0.0": - version: 3.0.1 - resolution: "aws-sdk-client-mock@npm:3.0.1" +"aws-sdk-client-mock@npm:^4.0.0": + version: 4.0.0 + resolution: "aws-sdk-client-mock@npm:4.0.0" dependencies: "@types/sinon": ^10.0.10 sinon: ^16.1.3 tslib: ^2.1.0 - checksum: e875af24a765d7883059c101a629a58bbb2ec3a055443562f9410ebd96823691dfae25d69b962dc3c22ad5867971c37b378d05f3c8344bbb992b1a624a0fb836 + checksum: c5a2768390758093201df91a8b4610287b167ed87522b8b57514c89fd5ccc78cab60b92a2965bac944ed848da0d8a0dd2b660bd4e99b80a5a7116e39ad1745e9 languageName: node linkType: hard @@ -21795,15 +18712,6 @@ __metadata: languageName: node linkType: hard -"axios@npm:^0.21.1": - version: 0.21.4 - resolution: "axios@npm:0.21.4" - dependencies: - follow-redirects: ^1.14.0 - checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c - languageName: node - linkType: hard - "axios@npm:^0.27.2": version: 0.27.2 resolution: "axios@npm:0.27.2" @@ -21815,13 +18723,13 @@ __metadata: linkType: hard "axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0": - version: 1.6.7 - resolution: "axios@npm:1.6.7" + version: 1.6.8 + resolution: "axios@npm:1.6.8" dependencies: - follow-redirects: ^1.15.4 + follow-redirects: ^1.15.6 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: 87d4d429927d09942771f3b3a6c13580c183e31d7be0ee12f09be6d5655304996bb033d85e54be81606f4e89684df43be7bf52d14becb73a12727bf33298a082 + checksum: bf007fa4b207d102459300698620b3b0873503c6d47bf5a8f6e43c0c64c90035a4f698b55027ca1958f61ab43723df2781c38a99711848d232cad7accbcdfcdd languageName: node linkType: hard @@ -21835,12 +18743,12 @@ __metadata: linkType: hard "azure-devops-node-api@npm:^12.0.0": - version: 12.4.0 - resolution: "azure-devops-node-api@npm:12.4.0" + version: 12.5.0 + resolution: "azure-devops-node-api@npm:12.5.0" dependencies: tunnel: 0.0.6 typed-rest-client: ^1.8.4 - checksum: d7207c2bb0e021a25e11d1f6e4b4ac02efdbe4467b0c28bfb19260b2a1a799393978e6ff0b916cf81e309ba8b9a80015d8638751bed253695ef779a3a904efd2 + checksum: 7c2c3ae21eaf1bc3627ba4ea87bdac1085a3594eacf40eb6d7b11292f057988db38f718f4597733c6861d854c28bfe146bcf3964a13adddebe1085270bb63097 languageName: node linkType: hard @@ -22051,18 +18959,6 @@ __metadata: languageName: node linkType: hard -"badge-maker@npm:^3.3.0": - version: 3.3.1 - resolution: "badge-maker@npm:3.3.1" - dependencies: - anafanafo: 2.0.0 - css-color-converter: ^2.0.0 - bin: - badge: lib/badge-cli.js - checksum: 17ddd409da395a5a58a4b984aa3224a26fec80a580f7b2f011cbfcf3d1ecc4b8daae879d0ff21b7bb78081eb03c703fd161bebc846018456edfa7e3544932e10 - languageName: node - linkType: hard - "bail@npm:^2.0.0": version: 2.0.1 resolution: "bail@npm:2.0.1" @@ -22077,6 +18973,41 @@ __metadata: languageName: node linkType: hard +"bare-events@npm:^2.0.0, bare-events@npm:^2.2.0": + version: 2.2.0 + resolution: "bare-events@npm:2.2.0" + checksum: b3001d61cbb7e6c91c7e47ed1d5701512f94c68955a88c1fe368ff313ba68f372fd701f422d1604fd6ac6e2237024d99373aa14e43a92696755a1f7ae46a8626 + languageName: node + linkType: hard + +"bare-fs@npm:^2.1.1": + version: 2.2.0 + resolution: "bare-fs@npm:2.2.0" + dependencies: + bare-events: ^2.0.0 + bare-os: ^2.0.0 + bare-path: ^2.0.0 + streamx: ^2.13.0 + checksum: 8832abc6c222bdfc8dcf37253493eefdd153048dd2fd482fe7722d6fea083f9e44574197a47e2b0046057f9fb271078ed799d03663e387ad06d2ab116a64cce4 + languageName: node + linkType: hard + +"bare-os@npm:^2.0.0, bare-os@npm:^2.1.0": + version: 2.2.0 + resolution: "bare-os@npm:2.2.0" + checksum: ed78e2f3ea498e35c7565532ae3aa3b85a7e5e223ab6353de64864823cadff02a2a8b7722e9a6c1a0ff56cb9f21f23ada8e88a085cc0a5d38a7c1bcf65e8f7fd + languageName: node + linkType: hard + +"bare-path@npm:^2.0.0, bare-path@npm:^2.1.0": + version: 2.1.0 + resolution: "bare-path@npm:2.1.0" + dependencies: + bare-os: ^2.1.0 + checksum: 03f260e72bd0ae0df4cd712322a2d3c8c16701ffaa55cf2d517ae62b7f78c64b7ec5bba81ec579367f966472481f5160db282e6663bd0fc8cfb09ebe272d8bba + languageName: node + linkType: hard + "base16@npm:^1.0.0": version: 1.0.0 resolution: "base16@npm:1.0.0" @@ -22091,13 +19022,6 @@ __metadata: languageName: node linkType: hard -"base64-arraybuffer@npm:^1.0.1": - version: 1.0.2 - resolution: "base64-arraybuffer@npm:1.0.2" - checksum: 15e6400d2d028bf18be4ed97702b11418f8f8779fb8c743251c863b726638d52f69571d4cc1843224da7838abef0949c670bde46936663c45ad078e89fee5c62 - languageName: node - linkType: hard - "base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -22168,13 +19092,13 @@ __metadata: linkType: hard "better-sqlite3@npm:^9.0.0": - version: 9.4.1 - resolution: "better-sqlite3@npm:9.4.1" + version: 9.5.0 + resolution: "better-sqlite3@npm:9.5.0" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: 4d14a95c9ec62eb76321aaf085fd08e9dae10527149f5b54e9f9868feb50ae6fbf6f7eed52f52e6126472938aa789f7e82f5ad9357c88b4efeaf8f7d958c5c11 + checksum: cfa56519755d6dd29ef8361c872c6f29392fcfcc44a435099eb61729aae23c4f18057972592a0b9ff0fcedc98e43db4ee7a1a2de21ab2868f8dcec4f8272ad9d languageName: node linkType: hard @@ -22226,20 +19150,13 @@ __metadata: languageName: node linkType: hard -"binary-extensions@npm:^2.0.0, binary-extensions@npm:^2.2.0": +"binary-extensions@npm:^2.0.0": version: 2.2.0 resolution: "binary-extensions@npm:2.2.0" checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8 languageName: node linkType: hard -"binary-search@npm:^1.3.5": - version: 1.3.6 - resolution: "binary-search@npm:1.3.6" - checksum: 2e6b3459a9c1ba1bd674a6a855a5ef7505f70707422244430e3510e989c0df6074a49fe60784a98b93b51545c9bcace1db1defee06ff861b124c036a2f2836bf - languageName: node - linkType: hard - "binaryextensions@npm:^4.15.0, binaryextensions@npm:^4.16.0": version: 4.18.0 resolution: "binaryextensions@npm:4.18.0" @@ -22295,36 +19212,7 @@ __metadata: languageName: node linkType: hard -"body-parser-xml@npm:^2.0.5": - version: 2.0.5 - resolution: "body-parser-xml@npm:2.0.5" - dependencies: - xml2js: ^0.5.0 - checksum: 57133dbe6439f74f2ffb814b54ab806596a31c51e0d93e045b3068402ae184d4fcb799b2966414d1f393f8dcc8342529d4d3ce4cdeaa219c3af140d961c56dfd - languageName: node - linkType: hard - -"body-parser@npm:1.20.1": - version: 1.20.1 - resolution: "body-parser@npm:1.20.1" - dependencies: - bytes: 3.1.2 - content-type: ~1.0.4 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: ~1.6.18 - unpipe: 1.0.0 - checksum: f1050dbac3bede6a78f0b87947a8d548ce43f91ccc718a50dd774f3c81f2d8b04693e52acf62659fad23101827dd318da1fb1363444ff9a8482b886a3e4a5266 - languageName: node - linkType: hard - -"body-parser@npm:^1.15.2, body-parser@npm:^1.20.0": +"body-parser@npm:1.20.2, body-parser@npm:^1.15.2": version: 1.20.2 resolution: "body-parser@npm:1.20.2" dependencies: @@ -22354,15 +19242,13 @@ __metadata: languageName: node linkType: hard -"bonjour-service@npm:^1.0.11": - version: 1.0.11 - resolution: "bonjour-service@npm:1.0.11" +"bonjour-service@npm:^1.2.1": + version: 1.2.1 + resolution: "bonjour-service@npm:1.2.1" dependencies: - array-flatten: ^2.1.2 - dns-equal: ^1.0.0 fast-deep-equal: ^3.1.3 - multicast-dns: ^7.2.4 - checksum: b6093a856de9bc303551f1639945318e93782d3c40f03e38def3e2f079f478afd5385cf46538ade86f07205ac4b5f059105832b01eb9ce142fc69d27c006982f + multicast-dns: ^7.2.5 + checksum: b65b3e6e3a07e97f2da5806afb76f3946d5a6426b72e849a0236dc3c9d3612fb8c5359ebade4be7eb63f74a37670c53a53be2ff17f4f709811fda77f600eb25b languageName: node linkType: hard @@ -22438,13 +19324,6 @@ __metadata: languageName: node linkType: hard -"brcast@npm:^3.0.1": - version: 3.0.2 - resolution: "brcast@npm:3.0.2" - checksum: 7abae42088c6ffad9ff9e0fc756607a1764e299d737b3007fa49a73a38b3fda1e51362713f645db7991878ca388de94942011188450324c3debd08509315fa94 - languageName: node - linkType: hard - "breakword@npm:^1.0.5": version: 1.0.5 resolution: "breakword@npm:1.0.5" @@ -22615,13 +19494,6 @@ __metadata: languageName: node linkType: hard -"buffer-writer@npm:2.0.0": - version: 2.0.0 - resolution: "buffer-writer@npm:2.0.0" - checksum: 11736b48bb75106c52ca8ec9f025e7c1b3b25ce31875f469d7210eabd5c576c329e34f6b805d4a8d605ff3f0db1e16342328802c4c963e9c826b0e43a4e631c2 - languageName: node - linkType: hard - "buffer-xor@npm:^1.0.3": version: 1.0.3 resolution: "buffer-xor@npm:1.0.3" @@ -22650,7 +19522,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.5.0, buffer@npm:^5.7.1": +"buffer@npm:^5.2.1, buffer@npm:^5.5.0, buffer@npm:^5.7.1": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -22707,6 +19579,15 @@ __metadata: languageName: node linkType: hard +"bundle-name@npm:^4.1.0": + version: 4.1.0 + resolution: "bundle-name@npm:4.1.0" + dependencies: + run-applescript: ^7.0.0 + checksum: 1d966c8d2dbf4d9d394e53b724ac756c2414c45c01340b37743621f59cc565a435024b394ddcb62b9b335d1c9a31f4640eb648c3fec7f97ee74dc0694c9beb6c + languageName: node + linkType: hard + "busboy@npm:^1.0.0, busboy@npm:^1.6.0": version: 1.6.0 resolution: "busboy@npm:1.6.0" @@ -22853,14 +19734,16 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": - version: 1.0.5 - resolution: "call-bind@npm:1.0.5" +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 function-bind: ^1.1.2 - get-intrinsic: ^1.2.1 - set-function-length: ^1.1.1 - checksum: 449e83ecbd4ba48e7eaac5af26fea3b50f8f6072202c2dd7c5a6e7a6308f2421abe5e13a3bbd55221087f76320c5e09f25a8fdad1bab2b77c68ae74d92234ea5 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 languageName: node linkType: hard @@ -23010,13 +19893,6 @@ __metadata: languageName: node linkType: hard -"change-emitter@npm:^0.1.2": - version: 0.1.6 - resolution: "change-emitter@npm:0.1.6" - checksum: 0ed494ba9901ca56ea6f942668fd294465c334a9a0981dca96da5aea5e387c0023a630d7c658c1b532d203db54c928ddca2564e434b4a8b7f6d39155d09db255 - languageName: node - linkType: hard - "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -23024,15 +19900,6 @@ __metadata: languageName: node linkType: hard -"char-width-table-consumer@npm:^1.0.0": - version: 1.0.0 - resolution: "char-width-table-consumer@npm:1.0.0" - dependencies: - binary-search: ^1.3.5 - checksum: daffca7cf4201f55acb75c6f98967be6d8a7cbb5783f3e58d90930d83cadc367e63e62fcfa893ea3985c05d8c32557a1bfa2ea7e2f39b845cb2dea966cfbeccd - languageName: node - linkType: hard - "character-entities-legacy@npm:^1.0.0": version: 1.1.4 resolution: "character-entities-legacy@npm:1.1.4" @@ -23103,7 +19970,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.3.1, chokidar@npm:^3.4.2, chokidar@npm:^3.5.2, chokidar@npm:^3.5.3": +"chokidar@npm:^3.3.1, chokidar@npm:^3.4.2, chokidar@npm:^3.5.2, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -23145,6 +20012,19 @@ __metadata: languageName: node linkType: hard +"chromium-bidi@npm:0.5.17": + version: 0.5.17 + resolution: "chromium-bidi@npm:0.5.17" + dependencies: + mitt: 3.0.1 + urlpattern-polyfill: 10.0.0 + zod: 3.22.4 + peerDependencies: + devtools-protocol: "*" + checksum: 522da996ed5abfb47707583cc24785f9aa05d87bd968dbd520f245cf8972fa3ec102f8d1d72fa07558daa70495d8c6f2bf364d8599eb60b77504e528601d8a30 + languageName: node + linkType: hard + "ci-info@npm:^2.0.0": version: 2.0.0 resolution: "ci-info@npm:2.0.0" @@ -23169,15 +20049,6 @@ __metadata: languageName: node linkType: hard -"circleci-api@npm:^4.0.0": - version: 4.1.4 - resolution: "circleci-api@npm:4.1.4" - dependencies: - axios: ^0.21.1 - checksum: b01df7a3361df93f447957abcefbf9d99041076de7c8a27da8c9ae27514ae3a9527c4d3677a6a13131cecb882efe18077e0665b6b34619a3c0678664ed94b4ed - languageName: node - linkType: hard - "cjs-module-lexer@npm:^1.0.0": version: 1.2.2 resolution: "cjs-module-lexer@npm:1.2.2" @@ -23185,7 +20056,7 @@ __metadata: languageName: node linkType: hard -"classnames@npm:*, classnames@npm:^2.2.5, classnames@npm:^2.2.6, classnames@npm:^2.3.1, classnames@npm:^2.5.1": +"classnames@npm:*, classnames@npm:^2.2.6, classnames@npm:^2.3.1, classnames@npm:^2.5.1": version: 2.5.1 resolution: "classnames@npm:2.5.1" checksum: da424a8a6f3a96a2e87d01a432ba19315503294ac7e025f9fece656db6b6a0f7b5003bb1fbb51cbb0d9624d964f1b9bb35a51c73af9b2434c7b292c42231c1e5 @@ -23321,17 +20192,6 @@ __metadata: languageName: node linkType: hard -"clipboard@npm:^2.0.4": - version: 2.0.11 - resolution: "clipboard@npm:2.0.11" - dependencies: - good-listener: ^1.2.2 - select: ^1.1.2 - tiny-emitter: ^2.0.0 - checksum: 413055a6038e43898e0e895216b58ed54fbf386f091cb00188875ef35b186cefbd258acdf4cb4b0ac87cbc00de936f41b45dde9fe1fd1a57f7babb28363b8748 - languageName: node - linkType: hard - "cliui@npm:7.0.4, cliui@npm:^7.0.2": version: 7.0.4 resolution: "cliui@npm:7.0.4" @@ -23399,7 +20259,7 @@ __metadata: languageName: node linkType: hard -"clone@npm:2.x, clone@npm:^2.1.1, clone@npm:^2.1.2": +"clone@npm:2.x, clone@npm:^2.1.1": version: 2.1.2 resolution: "clone@npm:2.1.2" checksum: aaf106e9bc025b21333e2f4c12da539b568db4925c0501a1bf4070836c9e848c892fa22c35548ce0d1132b08bbbfa17a00144fe58fccdab6fa900fec4250f67d @@ -23424,14 +20284,14 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.0.2, clsx@npm:^1.0.4, clsx@npm:^1.1.1, clsx@npm:^1.2.1": +"clsx@npm:^1.0.2, clsx@npm:^1.0.4, clsx@npm:^1.1.0, clsx@npm:^1.1.1, clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12 languageName: node linkType: hard -"clsx@npm:^2.0.0, clsx@npm:^2.1.0": +"clsx@npm:^2.1.0": version: 2.1.0 resolution: "clsx@npm:2.1.0" checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d @@ -23469,8 +20329,8 @@ __metadata: linkType: hard "codemirror-graphql@npm:^2.0.10": - version: 2.0.10 - resolution: "codemirror-graphql@npm:2.0.10" + version: 2.0.11 + resolution: "codemirror-graphql@npm:2.0.11" dependencies: "@types/codemirror": ^0.0.90 graphql-language-service: 5.2.0 @@ -23478,7 +20338,7 @@ __metadata: "@codemirror/language": 6.0.0 codemirror: ^5.65.3 graphql: ^15.5.0 || ^16.0.0 - checksum: d14e680168f407fd3d6ab09d88ea33640dd39f84d9ceb1ce605d9687d459fd08787109800a9847bbce72122e3318e975b255f65ddb19725d7a12781f4bf26506 + checksum: cdbeb713af63a069c5526f864edf4f71dd811437e44dba7967164ea2d380c52dfe51d3ea3fde06c94ffeb596b93af737767923d6fc434c628fa4241621684950 languageName: node linkType: hard @@ -23523,13 +20383,6 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^0.5.2": - version: 0.5.3 - resolution: "color-convert@npm:0.5.3" - checksum: 1074989a2c216d0171a397b870a0d698ef802ab3f9ece72b35bd92c4d20aeab31f222ea525dd5d3fad175a3f256a750eadd14ab882caed0089efc1cb7ba74086 - languageName: node - linkType: hard - "color-convert@npm:^1.9.0, color-convert@npm:^1.9.1": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -23555,14 +20408,14 @@ __metadata: languageName: node linkType: hard -"color-name@npm:^1.0.0, color-name@npm:^1.1.4, color-name@npm:~1.1.4": +"color-name@npm:^1.0.0, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 languageName: node linkType: hard -"color-string@npm:^1.5.2, color-string@npm:^1.9.0": +"color-string@npm:^1.5.2": version: 1.9.0 resolution: "color-string@npm:1.9.0" dependencies: @@ -23591,16 +20444,6 @@ __metadata: languageName: node linkType: hard -"color@npm:^4.0.1": - version: 4.2.3 - resolution: "color@npm:4.2.3" - dependencies: - color-convert: ^2.0.1 - color-string: ^1.9.0 - checksum: 0579629c02c631b426780038da929cca8e8d80a40158b09811a0112a107c62e10e4aad719843b791b1e658ab4e800558f2e87ca4522c8b32349d497ecb6adeb4 - languageName: node - linkType: hard - "colord@npm:^2.9.1": version: 2.9.1 resolution: "colord@npm:2.9.1" @@ -23739,13 +20582,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^9.5.0 <10": - version: 9.5.0 - resolution: "commander@npm:9.5.0" - checksum: c7a3e27aa59e913b54a1bafd366b88650bc41d6651f0cbe258d4ff09d43d6a7394232a4dadd0bf518b3e696fdf595db1028a0d82c785b88bd61f8a440cecfade - languageName: node - linkType: hard - "common-ancestor-path@npm:^1.0.1": version: 1.0.1 resolution: "common-ancestor-path@npm:1.0.1" @@ -23774,20 +20610,6 @@ __metadata: languageName: node linkType: hard -"commonmark@npm:^0.29.0": - version: 0.29.3 - resolution: "commonmark@npm:0.29.3" - dependencies: - entities: ~2.0 - mdurl: ~1.0.1 - minimist: ">=1.2.2" - string.prototype.repeat: ^0.2.0 - bin: - commonmark: bin/commonmark - checksum: 892b603aeffea6a04770ce24979fc4024d2d92ca6d5146353398faab15be980af6802f3d7b35357400b870e752a9f80b766fed5c09ca063a2951c8c26013876c - languageName: node - linkType: hard - "compare-versions@npm:4.1.4": version: 4.1.4 resolution: "compare-versions@npm:4.1.4" @@ -23842,7 +20664,7 @@ __metadata: languageName: node linkType: hard -"compressible@npm:^2.0.12, compressible@npm:~2.0.16": +"compressible@npm:~2.0.16": version: 2.0.18 resolution: "compressible@npm:2.0.18" dependencies: @@ -23947,26 +20769,6 @@ __metadata: languageName: node linkType: hard -"concurrently@npm:^8.0.0": - version: 8.2.2 - resolution: "concurrently@npm:8.2.2" - dependencies: - chalk: ^4.1.2 - date-fns: ^2.30.0 - lodash: ^4.17.21 - rxjs: ^7.8.1 - shell-quote: ^1.8.1 - spawn-command: 0.0.2 - supports-color: ^8.1.1 - tree-kill: ^1.2.2 - yargs: ^17.7.2 - bin: - conc: dist/bin/concurrently.js - concurrently: dist/bin/concurrently.js - checksum: 8ac774df06869773438f1bf91025180c52d5b53139bc86cf47659136c0d97461d0579c515d848d1e945d4e3e0cafe646b2ea18af8d74259b46abddcfe39b2c6c - languageName: node - linkType: hard - "conf@npm:^10.2.0": version: 10.2.0 resolution: "conf@npm:10.2.0" @@ -24079,7 +20881,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4": +"content-disposition@npm:0.5.4, content-disposition@npm:^0.5.3": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -24140,14 +20942,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.5.0, cookie@npm:^0.5.0": - version: 0.5.0 - resolution: "cookie@npm:0.5.0" - checksum: 1f4bd2ca5765f8c9689a7e8954183f5332139eb72b6ff783d8947032ec1fdf43109852c178e21a953a30c0dd42257828185be01b49d1eb1a67fd054ca588a180 - languageName: node - linkType: hard - -"cookie@npm:0.6.0, cookie@npm:~0.6.0": +"cookie@npm:0.6.0, cookie@npm:^0.6.0, cookie@npm:~0.6.0": version: 0.6.0 resolution: "cookie@npm:0.6.0" checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 @@ -24161,6 +20956,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:^0.5.0": + version: 0.5.0 + resolution: "cookie@npm:0.5.0" + checksum: 1f4bd2ca5765f8c9689a7e8954183f5332139eb72b6ff783d8947032ec1fdf43109852c178e21a953a30c0dd42257828185be01b49d1eb1a67fd054ca588a180 + languageName: node + linkType: hard + "cookiejar@npm:^2.1.4": version: 2.1.4 resolution: "cookiejar@npm:2.1.4" @@ -24193,13 +20995,6 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^1.0.0": - version: 1.2.7 - resolution: "core-js@npm:1.2.7" - checksum: 0b76371bfa98708351cde580f9287e2360d2209920e738ae950ae74ad08639a2e063541020bf666c28778956fc356ed9fe56d962129c88a87a6a4a0612526c75 - languageName: node - linkType: hard - "core-js@npm:^2.4.0, core-js@npm:^2.5.0": version: 2.6.12 resolution: "core-js@npm:2.6.12" @@ -24207,10 +21002,10 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^3.26.0, core-js@npm:^3.6.5": - version: 3.36.0 - resolution: "core-js@npm:3.36.0" - checksum: 48c807d5055ad0424f52d13583e96ddca2efcdc4e3cd9c479d60f269c8fe225191cd4e26a4593f43f7ef6dba08d161091147ecf8ae0300c15bc648a4f555217b +"core-js@npm:^3.6.5": + version: 3.37.0 + resolution: "core-js@npm:3.37.0" + checksum: 212c3e9b3fc277dbb63739ef58a61c5709ccd0b36f09c3ce6946aa91fa180c60f57f976d4a5fdb9cda0c6cb55417379ba5a008fc3a1384ec94ec8ec61826469d languageName: node linkType: hard @@ -24238,6 +21033,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:9.0.0": + version: 9.0.0 + resolution: "cosmiconfig@npm:9.0.0" + dependencies: + env-paths: ^2.2.1 + import-fresh: ^3.3.0 + js-yaml: ^4.1.0 + parse-json: ^5.2.0 + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: a30c424b53d442ea0bdd24cb1b3d0d8687c8dda4a17ab6afcdc439f8964438801619cdb66e8e79f63b9caa3e6586b60d8bab9ce203e72df6c5e80179b971fe8f + languageName: node + linkType: hard + "cosmiconfig@npm:^6.0.0": version: 6.0.0 resolution: "cosmiconfig@npm:6.0.0" @@ -24393,21 +21205,21 @@ __metadata: linkType: hard "cron@npm:^3.0.0": - version: 3.1.6 - resolution: "cron@npm:3.1.6" + version: 3.1.7 + resolution: "cron@npm:3.1.7" dependencies: - "@types/luxon": ~3.3.0 + "@types/luxon": ~3.4.0 luxon: ~3.4.0 - checksum: e97bb6f85acf3195577c609f28bbac2e22812d8632802752a13591882deceeeeefd2c91c1293fb5102ef442f96ae17ca687854fd0b005149aae9a25834363e1d + checksum: d98ee5297543c138221d96dd49270bf6576db80134e6041f4ce4a3c0cb6060863d76910209b34fee66fbf134461449ec3bd283d6a76d1c50da220cde7fc10c65 languageName: node linkType: hard "cronstrue@npm:^2.2.0, cronstrue@npm:^2.32.0": - version: 2.48.0 - resolution: "cronstrue@npm:2.48.0" + version: 2.49.0 + resolution: "cronstrue@npm:2.49.0" bin: cronstrue: bin/cli.js - checksum: d767d0f2cc1e286256bf6a92f555aacd1da103e97efd3dfc057a6f836f449b34302ace9fc00fdd28732fa5f8be1a1e940cef1a222b23dff90a419f33b3ff45aa + checksum: 8f45275b95d7f03c0762efe7318c373ceef1d45a34ac73ab1523bfc32359f383380268ab35e4592224284d3844df4002ffcb289d42057e91dfd8567284c73995 languageName: node linkType: hard @@ -24423,7 +21235,7 @@ __metadata: languageName: node linkType: hard -"cross-fetch@npm:^3.1.3, cross-fetch@npm:^3.1.5, cross-fetch@npm:^3.1.8 <4": +"cross-fetch@npm:^3.1.5": version: 3.1.8 resolution: "cross-fetch@npm:3.1.8" dependencies: @@ -24536,17 +21348,6 @@ __metadata: languageName: node linkType: hard -"css-color-converter@npm:^2.0.0": - version: 2.0.0 - resolution: "css-color-converter@npm:2.0.0" - dependencies: - color-convert: ^0.5.2 - color-name: ^1.1.4 - css-unit-converter: ^1.1.2 - checksum: 87819fb3648bb433de49e534c5597d8021642f3199f8985f27b41dc5170c522f775db804fc4533ea78723f8cc70747c545c8f010f4a3ca0ba7bc4dd8f3eea532 - languageName: node - linkType: hard - "css-color-keywords@npm:^1.0.0": version: 1.0.0 resolution: "css-color-keywords@npm:1.0.0" @@ -24575,14 +21376,14 @@ __metadata: linkType: hard "css-loader@npm:^6.5.1": - version: 6.10.0 - resolution: "css-loader@npm:6.10.0" + version: 6.11.0 + resolution: "css-loader@npm:6.11.0" dependencies: icss-utils: ^5.1.0 postcss: ^8.4.33 - postcss-modules-extract-imports: ^3.0.0 - postcss-modules-local-by-default: ^4.0.4 - postcss-modules-scope: ^3.1.1 + postcss-modules-extract-imports: ^3.1.0 + postcss-modules-local-by-default: ^4.0.5 + postcss-modules-scope: ^3.2.0 postcss-modules-values: ^4.0.0 postcss-value-parser: ^4.2.0 semver: ^7.5.4 @@ -24594,7 +21395,7 @@ __metadata: optional: true webpack: optional: true - checksum: ee3d62b5f7e4eb24281a22506431e920d07a45bd6ea627731ce583f3c6a846ab8b8b703bace599b9b35256b9e762f9f326d969abb72b69c7e6055eacf39074fd + checksum: 5c8d35975a7121334905394e88e28f05df72f037dbed2fb8fec4be5f0b313ae73a13894ba791867d4a4190c35896da84a7fd0c54fb426db55d85ba5e714edbe3 languageName: node linkType: hard @@ -24645,22 +21446,6 @@ __metadata: languageName: node linkType: hard -"css-unit-converter@npm:^1.1.2": - version: 1.1.2 - resolution: "css-unit-converter@npm:1.1.2" - checksum: 07888033346a5128f34dbe2f72884c966d24e9f29db24416dcde92860242490617ef9a178ac193a92f730834bbeea026cdc7027701d92ba9bbbe59db7a37eb2a - languageName: node - linkType: hard - -"css-vendor@npm:^0.3.8": - version: 0.3.8 - resolution: "css-vendor@npm:0.3.8" - dependencies: - is-in-browser: ^1.0.2 - checksum: 0a2e0cd0d4adbfdb6236950e7f9697b8a9b294eb2ae7c95996a95d273d2a63316ce793cb4654ae048aa3c129327124d2a29aada9935a0c284f9cc341c2768c8a - languageName: node - linkType: hard - "css-vendor@npm:^2.0.8": version: 2.0.8 resolution: "css-vendor@npm:2.0.8" @@ -24795,14 +21580,14 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^2.0.0, csstype@npm:^2.5.2, csstype@npm:^2.6.7": +"csstype@npm:^2.5.2, csstype@npm:^2.6.7": version: 2.6.21 resolution: "csstype@npm:2.6.21" checksum: 2ce8bc832375146eccdf6115a1f8565a27015b74cce197c35103b4494955e9516b246140425ad24103864076aa3e1257ac9bab25a06c8d931dd87a6428c9dccf languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.2": +"csstype@npm:^3.0.2, csstype@npm:^3.1.2, csstype@npm:^3.1.3": version: 3.0.9 resolution: "csstype@npm:3.0.9" checksum: 199f9af7e673f9f188525c3102a329d637ff46c52f6385a4427ff5cb17adcb736189150170a7af7c5701d18d7704bdad130273f4aa7e44c6c4f9967e6115dc93 @@ -24849,15 +21634,6 @@ __metadata: languageName: node linkType: hard -"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6": - version: 3.2.3 - resolution: "d3-array@npm:3.2.3" - dependencies: - internmap: 1 - 2 - checksum: 41d6a4989b73e0d2649a880b2f29a7e7cc059db0eba36cd29a79e0118ebdf6b78922a84cde0733cd54cb4072f3442ec44f3563902e00ea42892442d60e99f961 - languageName: node - linkType: hard - "d3-color@npm:1 - 3": version: 3.1.0 resolution: "d3-color@npm:3.1.0" @@ -24882,32 +21658,14 @@ __metadata: languageName: node linkType: hard -"d3-ease@npm:1 - 3, d3-ease@npm:^3.0.1": +"d3-ease@npm:1 - 3": version: 3.0.1 resolution: "d3-ease@npm:3.0.1" checksum: 06e2ee5326d1e3545eab4e2c0f84046a123dcd3b612e68858219aa034da1160333d9ce3da20a1d3486d98cb5c2a06f7d233eee1bc19ce42d1533458bd85dedcd languageName: node linkType: hard -"d3-force@npm:^3.0.0": - version: 3.0.0 - resolution: "d3-force@npm:3.0.0" - dependencies: - d3-dispatch: 1 - 3 - d3-quadtree: 1 - 3 - d3-timer: 1 - 3 - checksum: 6c7e96438cab62fa32aeadb0ade3297b62b51f81b1b38b0a60a5ec9fd627d74090c1189654d92df2250775f31b06812342f089f1d5947de9960a635ee3581def - languageName: node - linkType: hard - -"d3-format@npm:1 - 3": - version: 3.1.0 - resolution: "d3-format@npm:3.1.0" - checksum: f345ec3b8ad3cab19bff5dead395bd9f5590628eb97a389b1dd89f0b204c7c4fc1d9520f13231c2c7cf14b7c9a8cf10f8ef15bde2befbab41454a569bd706ca2 - languageName: node - linkType: hard - -"d3-interpolate@npm:1 - 3, d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1": +"d3-interpolate@npm:1 - 3": version: 3.0.1 resolution: "d3-interpolate@npm:3.0.1" dependencies: @@ -24923,26 +21681,6 @@ __metadata: languageName: node linkType: hard -"d3-quadtree@npm:1 - 3": - version: 3.0.1 - resolution: "d3-quadtree@npm:3.0.1" - checksum: 5469d462763811475f34a7294d984f3eb100515b0585ca5b249656f6b1a6e99b20056a2d2e463cc9944b888896d2b1d07859c50f9c0cf23438df9cd2e3146066 - languageName: node - linkType: hard - -"d3-scale@npm:^4.0.2": - version: 4.0.2 - resolution: "d3-scale@npm:4.0.2" - dependencies: - d3-array: 2.10.0 - 3 - d3-format: 1 - 3 - d3-interpolate: 1.2.0 - 3 - d3-time: 2.1.1 - 3 - d3-time-format: 2 - 4 - checksum: a9c770d283162c3bd11477c3d9d485d07f8db2071665f1a4ad23eec3e515e2cefbd369059ec677c9ac849877d1a765494e90e92051d4f21111aa56791c98729e - languageName: node - linkType: hard - "d3-selection@npm:2 - 3, d3-selection@npm:3, d3-selection@npm:^3.0.0": version: 3.0.0 resolution: "d3-selection@npm:3.0.0" @@ -24950,7 +21688,7 @@ __metadata: languageName: node linkType: hard -"d3-shape@npm:^3.0.0, d3-shape@npm:^3.1.0": +"d3-shape@npm:^3.0.0": version: 3.2.0 resolution: "d3-shape@npm:3.2.0" dependencies: @@ -24959,25 +21697,7 @@ __metadata: languageName: node linkType: hard -"d3-time-format@npm:2 - 4": - version: 4.1.0 - resolution: "d3-time-format@npm:4.1.0" - dependencies: - d3-time: 1 - 3 - checksum: 7342bce28355378152bbd4db4e275405439cabba082d9cd01946d40581140481c8328456d91740b0fe513c51ec4a467f4471ffa390c7e0e30ea30e9ec98fcdf4 - languageName: node - linkType: hard - -"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0": - version: 3.1.0 - resolution: "d3-time@npm:3.1.0" - dependencies: - d3-array: 2 - 3 - checksum: 613b435352a78d9f31b7f68540788186d8c331b63feca60ad21c88e9db1989fe888f97f242322ebd6365e45ec3fb206a4324cd4ca0dfffa1d9b5feb856ba00a7 - languageName: node - linkType: hard - -"d3-timer@npm:1 - 3, d3-timer@npm:^3.0.1": +"d3-timer@npm:1 - 3": version: 3.0.1 resolution: "d3-timer@npm:3.0.1" checksum: 1cfddf86d7bca22f73f2c427f52dfa35c49f50d64e187eb788dcad6e927625c636aa18ae4edd44d084eb9d1f81d8ca4ec305dae7f733c15846a824575b789d73 @@ -25084,6 +21804,39 @@ __metadata: languageName: node linkType: hard +"data-view-buffer@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-buffer@npm:1.0.1" + dependencies: + call-bind: ^1.0.6 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: ce24348f3c6231223b216da92e7e6a57a12b4af81a23f27eff8feabdf06acfb16c00639c8b705ca4d167f761cfc756e27e5f065d0a1f840c10b907fdaf8b988c + languageName: node + linkType: hard + +"data-view-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-length@npm:1.0.1" + dependencies: + call-bind: ^1.0.7 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: dbb3200edcb7c1ef0d68979834f81d64fd8cab2f7691b3a4c6b97e67f22182f3ec2c8602efd7b76997b55af6ff8bce485829c1feda4fa2165a6b71fb7baa4269 + languageName: node + linkType: hard + +"data-view-byte-offset@npm:^1.0.0": + version: 1.0.0 + resolution: "data-view-byte-offset@npm:1.0.0" + dependencies: + call-bind: ^1.0.6 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: 7f0bf8720b7414ca719eedf1846aeec392f2054d7af707c5dc9a753cc77eb8625f067fa901e0b5127e831f9da9056138d894b9c2be79c27a21f6db5824f009c2 + languageName: node + linkType: hard + "dataloader@npm:^2.0.0, dataloader@npm:^2.2.2": version: 2.2.2 resolution: "dataloader@npm:2.2.2" @@ -25091,7 +21844,7 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:^2.16.1, date-fns@npm:^2.18.0, date-fns@npm:^2.30.0": +"date-fns@npm:^2.16.1": version: 2.30.0 resolution: "date-fns@npm:2.30.0" dependencies: @@ -25100,13 +21853,6 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:^3.0.0": - version: 3.3.1 - resolution: "date-fns@npm:3.3.1" - checksum: 6245e93a47de28ac96dffd4d62877f86e6b64854860ae1e00a4f83174d80bc8e59bd1259cf265223fb2ddce5c8e586dc9cc210f0d052faba2f7660e265877283 - languageName: node - linkType: hard - "dateformat@npm:^3.0.3": version: 3.0.3 resolution: "dateformat@npm:3.0.3" @@ -25130,7 +21876,7 @@ __metadata: languageName: node linkType: hard -"debounce@npm:^1.1.0, debounce@npm:^1.2.0": +"debounce@npm:^1.2.0": version: 1.2.1 resolution: "debounce@npm:1.2.1" checksum: 682a89506d9e54fb109526f4da255c5546102fbb8e3ae75eef3b04effaf5d4853756aee97475cd4650641869794e44f410eeb20ace2b18ea592287ab2038519e @@ -25191,13 +21937,6 @@ __metadata: languageName: node linkType: hard -"decimal.js-light@npm:^2.4.1": - version: 2.5.0 - resolution: "decimal.js-light@npm:2.5.0" - checksum: 89d4d301f72728b10ac5def610b9ccb072cd5fa1bf80c607236bbdd28a9ec9f806faad3159c5a0a82a80a81d84e39ae470f90b6bacecae2617525c8e58f7e201 - languageName: node - linkType: hard - "decimal.js@npm:^10.2.1, decimal.js@npm:^10.3.1": version: 10.4.1 resolution: "decimal.js@npm:10.4.1" @@ -25260,31 +21999,6 @@ __metadata: languageName: node linkType: hard -"deep-equal@npm:^2.0.5": - version: 2.2.0 - resolution: "deep-equal@npm:2.2.0" - dependencies: - call-bind: ^1.0.2 - es-get-iterator: ^1.1.2 - get-intrinsic: ^1.1.3 - is-arguments: ^1.1.1 - is-array-buffer: ^3.0.1 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - isarray: ^2.0.5 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.4.3 - side-channel: ^1.0.4 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.9 - checksum: 46a34509d2766d6c6dc5aec4756089cf0cc137e46787e91f08f1ee0bb570d874f19f0493146907df0cf18aed4a7b4b50f6f62c899240a76c323f057528b122e3 - languageName: node - linkType: hard - "deep-extend@npm:0.6.0, deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -25306,20 +22020,30 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^3.0.0": - version: 3.3.0 - resolution: "deepmerge@npm:3.3.0" - checksum: 4322195389e0170a0443c07b36add19b90249802c4b47b96265fdc5f5d8beddf491d5e50cbc5bfd65f85ccf76598173083863c202f5463b3b667aca8be75d5ac - languageName: node - linkType: hard - -"deepmerge@npm:^4.2.2, deepmerge@npm:~4.3.0": +"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.1, deepmerge@npm:~4.3.0": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 languageName: node linkType: hard +"default-browser-id@npm:^5.0.0": + version: 5.0.0 + resolution: "default-browser-id@npm:5.0.0" + checksum: 185bfaecec2c75fa423544af722a3469b20704c8d1942794a86e4364fe7d9e8e9f63241a5b769d61c8151993bc65833a5b959026fa1ccea343b3db0a33aa6deb + languageName: node + linkType: hard + +"default-browser@npm:^5.2.1": + version: 5.2.1 + resolution: "default-browser@npm:5.2.1" + dependencies: + bundle-name: ^4.1.0 + default-browser-id: ^5.0.0 + checksum: afab7eff7b7f5f7a94d9114d1ec67273d3fbc539edf8c0f80019879d53aa71e867303c6f6d7cffeb10a6f3cfb59d4f963dba3f9c96830b4540cc7339a1bf9840 + languageName: node + linkType: hard + "default-gateway@npm:^6.0.3": version: 6.0.3 resolution: "default-gateway@npm:6.0.3" @@ -25352,14 +22076,14 @@ __metadata: languageName: node linkType: hard -"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1": - version: 1.1.1 - resolution: "define-data-property@npm:1.1.1" +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" dependencies: - get-intrinsic: ^1.2.1 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 gopd: ^1.0.1 - has-property-descriptors: ^1.0.0 - checksum: a29855ad3f0630ea82e3c5012c812efa6ca3078d5c2aa8df06b5f597c1cde6f7254692df41945851d903e05a1668607b6d34e778f402b9ff9ffb38111f1a3f0d + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b languageName: node linkType: hard @@ -25370,6 +22094,13 @@ __metadata: languageName: node linkType: hard +"define-lazy-prop@npm:^3.0.0": + version: 3.0.0 + resolution: "define-lazy-prop@npm:3.0.0" + checksum: 54884f94caac0791bf6395a3ec530ce901cf71c47b0196b8754f3fd17edb6c0e80149c1214429d851873bb0d689dbe08dcedbb2306dc45c8534a5934723851b6 + languageName: node + linkType: hard + "define-properties@npm:^1.1.3, define-properties@npm:^1.1.4, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" @@ -25422,13 +22153,6 @@ __metadata: languageName: node linkType: hard -"delegate@npm:^3.1.2": - version: 3.2.0 - resolution: "delegate@npm:3.2.0" - checksum: d943058fe05897228b158cbd1bab05164df28c8f54127873231d6b03b0a5acc1b3ee1f98ac70ccc9b79cd84aa47118a7de111fee2923753491583905069da27d - languageName: node - linkType: hard - "delegates@npm:^1.0.0": version: 1.0.0 resolution: "delegates@npm:1.0.0" @@ -25436,7 +22160,7 @@ __metadata: languageName: node linkType: hard -"denque@npm:^2.0.1, denque@npm:^2.1.0": +"denque@npm:^2.1.0": version: 2.1.0 resolution: "denque@npm:2.1.0" checksum: 1d4ae1d05e59ac3a3481e7b478293f4b4c813819342273f3d5b826c7ffa9753c520919ba264f377e09108d24ec6cf0ec0ac729a5686cbb8f32d797126c5dae74 @@ -25450,7 +22174,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:^1.1.2, depd@npm:~1.1.2": +"depd@npm:^1.1.0, depd@npm:^1.1.2, depd@npm:~1.1.2": version: 1.1.2 resolution: "depd@npm:1.1.2" checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 @@ -25471,7 +22195,7 @@ __metadata: languageName: node linkType: hard -"dequal@npm:^2.0.0, dequal@npm:^2.0.2, dequal@npm:^2.0.3": +"dequal@npm:^2.0.0, dequal@npm:^2.0.3": version: 2.0.3 resolution: "dequal@npm:2.0.3" checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 @@ -25511,6 +22235,13 @@ __metadata: languageName: node linkType: hard +"detect-indent@npm:^7.0.1": + version: 7.0.1 + resolution: "detect-indent@npm:7.0.1" + checksum: cbf3f0b1c3c881934ca94428e1179b26ab2a587e0d719031d37a67fb506d49d067de54ff057cb1e772e75975fed5155c01cd4518306fee60988b1486e3fc7768 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.0": version: 2.0.1 resolution: "detect-libc@npm:2.0.1" @@ -25525,6 +22256,13 @@ __metadata: languageName: node linkType: hard +"detect-newline@npm:^4.0.0": + version: 4.0.1 + resolution: "detect-newline@npm:4.0.1" + checksum: 0409ecdfb93419591ccff24fccfe2ddddad29b66637d1ed898872125b25af05014fdeedc9306339577060f69f59fe6e9830cdd80948597f136dfbffefa60599c + languageName: node + linkType: hard + "detect-node-es@npm:^1.1.0": version: 1.1.0 resolution: "detect-node-es@npm:1.1.0" @@ -25552,6 +22290,13 @@ __metadata: languageName: node linkType: hard +"devtools-protocol@npm:0.0.1262051": + version: 0.0.1262051 + resolution: "devtools-protocol@npm:0.0.1262051" + checksum: beaad00059964a661ab056d5e993492742c612c0370c6f08acd91490181c4d4ecf57d316eedb5a37fb6bb59321901d09ce50762f79ea09a50751d86f601b8f8e + languageName: node + linkType: hard + "dezalgo@npm:^1.0.0, dezalgo@npm:^1.0.4": version: 1.0.4 resolution: "dezalgo@npm:1.0.4" @@ -25562,13 +22307,6 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^28.1.1": - version: 28.1.1 - resolution: "diff-sequences@npm:28.1.1" - checksum: e2529036505567c7ca5a2dea86b6bcd1ca0e3ae63bf8ebf529b8a99cfa915bbf194b7021dc1c57361a4017a6d95578d4ceb29fabc3232a4f4cb866a2726c7690 - languageName: node - linkType: hard - "diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -25624,13 +22362,6 @@ __metadata: languageName: node linkType: hard -"dns-equal@npm:^1.0.0": - version: 1.0.0 - resolution: "dns-equal@npm:1.0.0" - checksum: a8471ac849c7c13824f053babea1bc26e2f359394dd5a460f8340d8abd13434be01e3327a5c59d212f8c8997817450efd3f3ac77bec709b21979cf0235644524 - languageName: node - linkType: hard - "dns-packet@npm:^5.2.2": version: 5.4.0 resolution: "dns-packet@npm:5.4.0" @@ -25640,12 +22371,12 @@ __metadata: languageName: node linkType: hard -"docker-compose@npm:^0.23.17": - version: 0.23.17 - resolution: "docker-compose@npm:0.23.17" +"docker-compose@npm:^0.24.6": + version: 0.24.7 + resolution: "docker-compose@npm:0.24.7" dependencies: - yaml: ^1.10.2 - checksum: c308bf067cabe178d245b3e499119937b1d2a5effdc9fac6227e04be4308a0250ca7bb1471789b3d0492ea2ce83f74e40b7517a9a5cb540a21355a64e4ad5d3c + yaml: ^2.2.2 + checksum: 54daa1985fd7a57a1881dfdb7d294a189b9ba4e097de81127bfb4ff2f7727d249cc1514ee6a5a06c0085f9f6b5bcafe55b3e463f30b87c4d682bd8b0dac0450e languageName: node linkType: hard @@ -25673,7 +22404,7 @@ __metadata: languageName: node linkType: hard -"dockerode@npm:^3.3.1": +"dockerode@npm:^3.3.5": version: 3.3.5 resolution: "dockerode@npm:3.3.5" dependencies: @@ -25736,15 +22467,6 @@ __metadata: languageName: node linkType: hard -"dom-helpers@npm:^3.2.1, dom-helpers@npm:^3.4.0": - version: 3.4.0 - resolution: "dom-helpers@npm:3.4.0" - dependencies: - "@babel/runtime": ^7.1.2 - checksum: 58d9f1c4a96daf77eddc63ae1236b826e1cddd6db66bbf39b18d7e21896d99365b376593352d52a60969d67fa4a8dbef26adc1439fa2c1b355efa37cacbaf637 - languageName: node - linkType: hard - "dom-helpers@npm:^5.0.1": version: 5.1.4 resolution: "dom-helpers@npm:5.1.4" @@ -25834,17 +22556,17 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:=3.0.8, dompurify@npm:^3.0.0": - version: 3.0.8 - resolution: "dompurify@npm:3.0.8" - checksum: cac660ccae15a9603f06a85344da868a4c3732d8b57f7998de0f421eb4b9e67d916be52e9bb2a57b2f95b49e994cc50bcd06bb87f2cb2849cf058bdf15266237 +"dompurify@npm:=3.1.0, dompurify@npm:^3.0.0": + version: 3.1.0 + resolution: "dompurify@npm:3.1.0" + checksum: 06fc76607cd076e394b2ea5479ab6f0407b8fedb6877ae95e94207b878365e5e1cd914055dacce152a5f419818afb8d4cd284b780246cf35363f0747c179a0ba languageName: node linkType: hard "dompurify@npm:^2.2.7": - version: 2.4.7 - resolution: "dompurify@npm:2.4.7" - checksum: 13c047e772a1998348191554dda403950d45ef2ec75fa0b9915cc179ccea0a39ef780d283109bd72cf83a2a085af6c77664281d4d0106a737bc5f39906364efe + version: 2.5.0 + resolution: "dompurify@npm:2.5.0" + checksum: 9eab7be868ddb5a43fa634898605681e7b6b18dc5b89f5d143afc9ec63bb4d2c113a15900d5ee363859aa8722e8534da346486997eafbb29e3178cbb89077e15 languageName: node linkType: hard @@ -25952,15 +22674,15 @@ __metadata: languageName: node linkType: hard -"duplexify@npm:^4.0.0": - version: 4.1.1 - resolution: "duplexify@npm:4.1.1" +"duplexify@npm:^4.0.0, duplexify@npm:^4.1.3": + version: 4.1.3 + resolution: "duplexify@npm:4.1.3" dependencies: end-of-stream: ^1.4.1 inherits: ^2.0.3 readable-stream: ^3.1.1 - stream-shift: ^1.0.0 - checksum: 1cf800f1dc1647d6e0272b811421d4ce78b7d9b12dd85c7ecd78b9e4bfba374d309ac9e3440c66461fc62adb69db49aebf49da15962c98a84d8fd33c7e9c5c5a + stream-shift: ^1.0.2 + checksum: 9636a027345de3dd3c801594d01a7c73d9ce260019538beb1ee650bba7544e72f40a4d4902b52e1ab283dc32a06f210d42748773af02ff15e3064a9659deab7f languageName: node linkType: hard @@ -25984,17 +22706,16 @@ __metadata: "@backstage/errors": "workspace:^" "@types/fs-extra": ^11.0.0 "@types/node": ^18.17.8 - "@types/puppeteer": ^5.4.4 + "@types/puppeteer": ^7.0.0 chalk: ^4.0.0 commander: ^12.0.0 cross-fetch: ^4.0.0 fs-extra: ^11.2.0 handlebars: ^4.7.3 - mysql2: ^2.2.5 + mysql2: ^3.0.0 nodemon: ^3.0.1 pgtools: ^1.0.0 tree-kill: ^1.2.2 - ts-node: ^10.0.0 bin: e2e-test: bin/e2e-test languageName: unknown @@ -26079,8 +22800,8 @@ __metadata: linkType: hard "elastic-builder@npm:^2.16.0": - version: 2.24.0 - resolution: "elastic-builder@npm:2.24.0" + version: 2.28.1 + resolution: "elastic-builder@npm:2.28.1" dependencies: lodash.has: ^4.5.2 lodash.hasin: ^4.5.2 @@ -26090,7 +22811,7 @@ __metadata: lodash.isobject: ^3.0.2 lodash.isstring: ^4.0.1 lodash.omit: ^4.5.0 - checksum: 4bbfa66a179b78dbd90a0a3ee19cf7fc2105deca195c65d3047cf2ef2e6fa4925049038ed1f28d46a3ce96daa47f2cf8d924ea2e2fc0c585569a5a7acd09f2ed + checksum: 5a3fb79441942825005e2bfa798c113809c3198b3cc711d3500894677eb212bb2bf100c5110bedafe354e154e035de1bbeebb7c593fb1aaacc58f98f0d8cd2bc languageName: node linkType: hard @@ -26174,7 +22895,7 @@ __metadata: languageName: node linkType: hard -"encoding@npm:^0.1.11, encoding@npm:^0.1.12, encoding@npm:^0.1.13": +"encoding@npm:^0.1.12, encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" dependencies: @@ -26192,13 +22913,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": - version: 5.15.0 - resolution: "enhanced-resolve@npm:5.15.0" +"enhanced-resolve@npm:^5.16.0": + version: 5.16.0 + resolution: "enhanced-resolve@npm:5.16.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 + checksum: ccfd01850ecf2aa51e8554d539973319ff7d8a539ef1e0ba3460a0ccad6223c4ef6e19165ee64161b459cd8a48df10f52af4434c60023c65fde6afa32d475f7e languageName: node linkType: hard @@ -26225,20 +22946,13 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.2.0, entities@npm:^4.3.0, entities@npm:^4.4.0": +"entities@npm:^4.2.0, entities@npm:^4.4.0": version: 4.4.0 resolution: "entities@npm:4.4.0" checksum: 84d250329f4b56b40fa93ed067b194db21e8815e4eb9b59f43a086f0ecd342814f6bc483de8a77da5d64e0f626033192b1b4f1792232a7ea6b970ebe0f3187c2 languageName: node linkType: hard -"entities@npm:~2.0": - version: 2.0.3 - resolution: "entities@npm:2.0.3" - checksum: 5a7899fcc622e0d76afdeafe4c58a6b40ae3a8ee4772e5825a648c11a2ca324a9a02515386f512e466baac4aeb551f3d3b79eaece5cd98369b9f8601be336b1a - languageName: node - linkType: hard - "entities@npm:~2.1.0": version: 2.1.0 resolution: "entities@npm:2.1.0" @@ -26253,13 +22967,6 @@ __metadata: languageName: node linkType: hard -"eol@npm:^0.9.1": - version: 0.9.1 - resolution: "eol@npm:0.9.1" - checksum: ba9fa998bc8148b935dcf85585eacf049eeaf18d2ab6196710d4d1f59e7dfd0e87b18508dc67144ff8ba12f835a4a4989aeea64c98b13cca77b74b9d4b33bce5 - languageName: node - linkType: hard - "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" @@ -26292,50 +22999,57 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.20.4, es-abstract@npm:^1.22.1": - version: 1.22.3 - resolution: "es-abstract@npm:1.22.3" +"es-abstract@npm:^1.20.4, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0": + version: 1.23.1 + resolution: "es-abstract@npm:1.23.1" dependencies: - array-buffer-byte-length: ^1.0.0 - arraybuffer.prototype.slice: ^1.0.2 - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.5 - es-set-tostringtag: ^2.0.1 + array-buffer-byte-length: ^1.0.1 + arraybuffer.prototype.slice: ^1.0.3 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 + data-view-buffer: ^1.0.1 + data-view-byte-length: ^1.0.1 + data-view-byte-offset: ^1.0.0 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-set-tostringtag: ^2.0.3 es-to-primitive: ^1.2.1 function.prototype.name: ^1.1.6 - get-intrinsic: ^1.2.2 - get-symbol-description: ^1.0.0 + get-intrinsic: ^1.2.4 + get-symbol-description: ^1.0.2 globalthis: ^1.0.3 gopd: ^1.0.1 - has-property-descriptors: ^1.0.0 - has-proto: ^1.0.1 + has-property-descriptors: ^1.0.2 + has-proto: ^1.0.3 has-symbols: ^1.0.3 - hasown: ^2.0.0 - internal-slot: ^1.0.5 - is-array-buffer: ^3.0.2 + hasown: ^2.0.2 + internal-slot: ^1.0.7 + is-array-buffer: ^3.0.4 is-callable: ^1.2.7 - is-negative-zero: ^2.0.2 + is-data-view: ^1.0.1 + is-negative-zero: ^2.0.3 is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 + is-shared-array-buffer: ^1.0.3 is-string: ^1.0.7 - is-typed-array: ^1.1.12 + is-typed-array: ^1.1.13 is-weakref: ^1.0.2 object-inspect: ^1.13.1 object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.1 - safe-array-concat: ^1.0.1 - safe-regex-test: ^1.0.0 + object.assign: ^4.1.5 + regexp.prototype.flags: ^1.5.2 + safe-array-concat: ^1.1.2 + safe-regex-test: ^1.0.3 string.prototype.trim: ^1.2.8 string.prototype.trimend: ^1.0.7 string.prototype.trimstart: ^1.0.7 - typed-array-buffer: ^1.0.0 - typed-array-byte-length: ^1.0.0 - typed-array-byte-offset: ^1.0.0 - typed-array-length: ^1.0.4 + typed-array-buffer: ^1.0.2 + typed-array-byte-length: ^1.0.1 + typed-array-byte-offset: ^1.0.2 + typed-array-length: ^1.0.5 unbox-primitive: ^1.0.2 - which-typed-array: ^1.1.13 - checksum: b1bdc962856836f6e72be10b58dc128282bdf33771c7a38ae90419d920fc3b36cc5d2b70a222ad8016e3fc322c367bf4e9e89fc2bc79b7e933c05b218e83d79a + which-typed-array: ^1.1.15 + checksum: a55b01af616898bfb1167fc567f3a6e22bb2800811a7f41f1c037f10bdc653894fc4c7000cce3a01e852628fd85044dff51d6d41f65f356a2ea847de3178b6ec languageName: node linkType: hard @@ -26354,75 +23068,77 @@ __metadata: languageName: node linkType: hard -"es-get-iterator@npm:^1.1.2": - version: 1.1.2 - resolution: "es-get-iterator@npm:1.1.2" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.0 - has-symbols: ^1.0.1 - is-arguments: ^1.1.0 - is-map: ^2.0.2 - is-set: ^2.0.2 - is-string: ^1.0.5 - isarray: ^2.0.5 - checksum: f75e66acb6a45686fa08b3ade9c9421a70d36a0c43ed4363e67f4d7aab2226cb73dd977cb48abbaf75721b946d3cd810682fcf310c7ad0867802fbf929b17dcf - languageName: node - linkType: hard - -"es-iterator-helpers@npm:^1.0.12, es-iterator-helpers@npm:^1.0.15": - version: 1.0.15 - resolution: "es-iterator-helpers@npm:1.0.15" - dependencies: - asynciterator.prototype: ^1.0.0 - call-bind: ^1.0.2 - define-properties: ^1.2.1 - es-abstract: ^1.22.1 - es-set-tostringtag: ^2.0.1 - function-bind: ^1.1.1 - get-intrinsic: ^1.2.1 - globalthis: ^1.0.3 - has-property-descriptors: ^1.0.0 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - internal-slot: ^1.0.5 - iterator.prototype: ^1.1.2 - safe-array-concat: ^1.0.1 - checksum: 50081ae5c549efe62e5c1d244df0194b40b075f7897fc2116b7e1aa437eb3c41f946d2afda18c33f9b31266ec544765932542765af839f76fa6d7b7855d1e0e1 - languageName: node - linkType: hard - -"es-module-lexer@npm:^0.9.3": - version: 0.9.3 - resolution: "es-module-lexer@npm:0.9.3" - checksum: 84bbab23c396281db2c906c766af58b1ae2a1a2599844a504df10b9e8dc77ec800b3211fdaa133ff700f5703d791198807bba25d9667392d27a5e9feda344da8 - languageName: node - linkType: hard - -"es-module-lexer@npm:^1.2.1": - version: 1.2.1 - resolution: "es-module-lexer@npm:1.2.1" - checksum: c4145b853e1491eaa5d591e4580926d242978c38071ad3d09165c3b6d50314cc0ae3bf6e1dec81a9e53768b9299df2063d2e4a67d7742a5029ddeae6c4fc26f0 - languageName: node - linkType: hard - -"es-set-tostringtag@npm:^2.0.1": - version: 2.0.1 - resolution: "es-set-tostringtag@npm:2.0.1" - dependencies: - get-intrinsic: ^1.1.3 - has: ^1.0.3 - has-tostringtag: ^1.0.0 - checksum: ec416a12948cefb4b2a5932e62093a7cf36ddc3efd58d6c58ca7ae7064475ace556434b869b0bbeb0c365f1032a8ccd577211101234b69837ad83ad204fff884 - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.0.0": +"es-define-property@npm:^1.0.0": version: 1.0.0 - resolution: "es-shim-unscopables@npm:1.0.0" + resolution: "es-define-property@npm:1.0.0" dependencies: - has: ^1.0.3 - checksum: 83e95cadbb6ee44d3644dfad60dcad7929edbc42c85e66c3e99aefd68a3a5c5665f2686885cddb47dfeabfd77bd5ea5a7060f2092a955a729bbd8834f0d86fa1 + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": + version: 1.0.18 + resolution: "es-iterator-helpers@npm:1.0.18" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.0 + es-errors: ^1.3.0 + es-set-tostringtag: ^2.0.3 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + globalthis: ^1.0.3 + has-property-descriptors: ^1.0.2 + has-proto: ^1.0.3 + has-symbols: ^1.0.3 + internal-slot: ^1.0.7 + iterator.prototype: ^1.1.2 + safe-array-concat: ^1.1.2 + checksum: 1594324ff3ca8890fe30c98b2419d3007d2b14b35f9773f188114408ff973e13c526f6045d88209e932f58dc0c55fc9a4ae1554636f8938ed7d926ffc27d3e1a + languageName: node + linkType: hard + +"es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.3.1": + version: 1.4.1 + resolution: "es-module-lexer@npm:1.4.1" + checksum: a11b5a256d4e8e9c7d94c2fd87415ccd1591617b6edd847e064503f8eaece2d25e2e9078a02c5ce3ed5e83bb748f5b4820efbe78072c8beb07ac619c2edec35d + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + checksum: 26f0ff78ab93b63394e8403c353842b2272836968de4eafe97656adfb8a7c84b9099bf0fe96ed58f4a4cddc860f6e34c77f91649a58a5daa4a9c40b902744e3c + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.3": + version: 2.0.3 + resolution: "es-set-tostringtag@npm:2.0.3" + dependencies: + get-intrinsic: ^1.2.4 + has-tostringtag: ^1.0.2 + hasown: ^2.0.1 + checksum: 7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": + version: 1.0.2 + resolution: "es-shim-unscopables@npm:1.0.2" + dependencies: + hasown: ^2.0.0 + checksum: 432bd527c62065da09ed1d37a3f8e623c423683285e6188108286f4a1e8e164a5bcbfbc0051557c7d14633cd2a41ce24c7048e6bbb66a985413fd32f1be72626 languageName: node linkType: hard @@ -26437,14 +23153,15 @@ __metadata: languageName: node linkType: hard -"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.46, es5-ext@npm:^0.10.50, es5-ext@npm:^0.10.53, es5-ext@npm:^0.10.61, es5-ext@npm:~0.10.14, es5-ext@npm:~0.10.2, es5-ext@npm:~0.10.46": - version: 0.10.62 - resolution: "es5-ext@npm:0.10.62" +"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.46, es5-ext@npm:^0.10.50, es5-ext@npm:^0.10.53, es5-ext@npm:^0.10.61, es5-ext@npm:^0.10.62, es5-ext@npm:~0.10.14, es5-ext@npm:~0.10.2, es5-ext@npm:~0.10.46": + version: 0.10.63 + resolution: "es5-ext@npm:0.10.63" dependencies: es6-iterator: ^2.0.3 es6-symbol: ^3.1.3 + esniff: ^2.0.1 next-tick: ^1.1.0 - checksum: 25f42f6068cfc6e393cf670bc5bba249132c5f5ec2dd0ed6e200e6274aca2fed8e9aec8a31c76031744c78ca283c57f0b41c7e737804c6328c7b8d3fbcba7983 + checksum: 3bf04d9bac12a14e716a0a00b1706f538a3211da82703babd3e907deaeadaa30eab71202785027058d44d2a7c0e92e34631fb03fa63ef1097191e88de5223fda languageName: node linkType: hard @@ -26496,16 +23213,16 @@ __metadata: linkType: hard "esbuild-loader@npm:^4.0.0": - version: 4.0.3 - resolution: "esbuild-loader@npm:4.0.3" + version: 4.1.0 + resolution: "esbuild-loader@npm:4.1.0" dependencies: - esbuild: ^0.19.0 + esbuild: ^0.20.0 get-tsconfig: ^4.7.0 loader-utils: ^2.0.4 webpack-sources: ^1.4.3 peerDependencies: webpack: ^4.40.0 || ^5.0.0 - checksum: 8303a106ec9e74fb4ad2c10f5e23fb082d742cfa7bc42b1476886a9f49ef1bff99cb39c1a569827195865d2d179a09a54bedfd34fae82841ce1f02beebfd9127 + checksum: 51e76c36dd1fb70545889b07e3c4b4a437aaf1a2acc836e83141f06bcb8fbf96af778cf21b37355ea724c30504ad288ba76b0554ff94af260bb12ece647de861 languageName: node linkType: hard @@ -26586,113 +23303,33 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.19.0, esbuild@npm:~0.19.10": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" - dependencies: - "@esbuild/aix-ppc64": 0.19.12 - "@esbuild/android-arm": 0.19.12 - "@esbuild/android-arm64": 0.19.12 - "@esbuild/android-x64": 0.19.12 - "@esbuild/darwin-arm64": 0.19.12 - "@esbuild/darwin-x64": 0.19.12 - "@esbuild/freebsd-arm64": 0.19.12 - "@esbuild/freebsd-x64": 0.19.12 - "@esbuild/linux-arm": 0.19.12 - "@esbuild/linux-arm64": 0.19.12 - "@esbuild/linux-ia32": 0.19.12 - "@esbuild/linux-loong64": 0.19.12 - "@esbuild/linux-mips64el": 0.19.12 - "@esbuild/linux-ppc64": 0.19.12 - "@esbuild/linux-riscv64": 0.19.12 - "@esbuild/linux-s390x": 0.19.12 - "@esbuild/linux-x64": 0.19.12 - "@esbuild/netbsd-x64": 0.19.12 - "@esbuild/openbsd-x64": 0.19.12 - "@esbuild/sunos-x64": 0.19.12 - "@esbuild/win32-arm64": 0.19.12 - "@esbuild/win32-ia32": 0.19.12 - "@esbuild/win32-x64": 0.19.12 - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 2936e29107b43e65a775b78b7bc66ddd7d76febd73840ac7e825fb22b65029422ff51038a08d19b05154f543584bd3afe7d1ef1c63900429475b17fbe61cb61f - languageName: node - linkType: hard - "esbuild@npm:^0.20.0": - version: 0.20.0 - resolution: "esbuild@npm:0.20.0" + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" dependencies: - "@esbuild/aix-ppc64": 0.20.0 - "@esbuild/android-arm": 0.20.0 - "@esbuild/android-arm64": 0.20.0 - "@esbuild/android-x64": 0.20.0 - "@esbuild/darwin-arm64": 0.20.0 - "@esbuild/darwin-x64": 0.20.0 - "@esbuild/freebsd-arm64": 0.20.0 - "@esbuild/freebsd-x64": 0.20.0 - "@esbuild/linux-arm": 0.20.0 - "@esbuild/linux-arm64": 0.20.0 - "@esbuild/linux-ia32": 0.20.0 - "@esbuild/linux-loong64": 0.20.0 - "@esbuild/linux-mips64el": 0.20.0 - "@esbuild/linux-ppc64": 0.20.0 - "@esbuild/linux-riscv64": 0.20.0 - "@esbuild/linux-s390x": 0.20.0 - "@esbuild/linux-x64": 0.20.0 - "@esbuild/netbsd-x64": 0.20.0 - "@esbuild/openbsd-x64": 0.20.0 - "@esbuild/sunos-x64": 0.20.0 - "@esbuild/win32-arm64": 0.20.0 - "@esbuild/win32-ia32": 0.20.0 - "@esbuild/win32-x64": 0.20.0 + "@esbuild/aix-ppc64": 0.20.2 + "@esbuild/android-arm": 0.20.2 + "@esbuild/android-arm64": 0.20.2 + "@esbuild/android-x64": 0.20.2 + "@esbuild/darwin-arm64": 0.20.2 + "@esbuild/darwin-x64": 0.20.2 + "@esbuild/freebsd-arm64": 0.20.2 + "@esbuild/freebsd-x64": 0.20.2 + "@esbuild/linux-arm": 0.20.2 + "@esbuild/linux-arm64": 0.20.2 + "@esbuild/linux-ia32": 0.20.2 + "@esbuild/linux-loong64": 0.20.2 + "@esbuild/linux-mips64el": 0.20.2 + "@esbuild/linux-ppc64": 0.20.2 + "@esbuild/linux-riscv64": 0.20.2 + "@esbuild/linux-s390x": 0.20.2 + "@esbuild/linux-x64": 0.20.2 + "@esbuild/netbsd-x64": 0.20.2 + "@esbuild/openbsd-x64": 0.20.2 + "@esbuild/sunos-x64": 0.20.2 + "@esbuild/win32-arm64": 0.20.2 + "@esbuild/win32-ia32": 0.20.2 + "@esbuild/win32-x64": 0.20.2 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -26742,7 +23379,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 501b0f540ab68b3843cb9b1be7efa2d90353c8743e99e84931baa1ef5fe1b87934e29becb23cc635a8af45fab223875efa62200589e18d796f0881a655cb9c07 + checksum: bc88050fc1ca5c1bd03648f9979e514bdefb956a63aa3974373bb7b9cbac0b3aac9b9da1b5bdca0b3490e39d6b451c72815dbd6b7d7f978c91fbe9c9e9aa4e4c languageName: node linkType: hard @@ -26921,8 +23558,8 @@ __metadata: linkType: hard "eslint-plugin-jest@npm:^27.0.0": - version: 27.8.0 - resolution: "eslint-plugin-jest@npm:27.8.0" + version: 27.9.0 + resolution: "eslint-plugin-jest@npm:27.9.0" dependencies: "@typescript-eslint/utils": ^5.10.0 peerDependencies: @@ -26934,7 +23571,7 @@ __metadata: optional: true jest: optional: true - checksum: 1fcdcf332b6d95c2433dcdf908b46e494a671bb101c675f99525c7a664853e60c247d63f302946d5a4f74f497a73c41673bc365a841f81bb4651b527379487e2 + checksum: e2a4b415105408de28ad146818fcc6f4e122f6a39c6b2216ec5c24a80393f1390298b20231b0467bc5fd730f6e24b05b89e1a6a3ce651fc159aa4174ecc233d0 languageName: node linkType: hard @@ -26987,39 +23624,41 @@ __metadata: linkType: hard "eslint-plugin-react@npm:^7.28.0": - version: 7.33.2 - resolution: "eslint-plugin-react@npm:7.33.2" + version: 7.34.1 + resolution: "eslint-plugin-react@npm:7.34.1" dependencies: - array-includes: ^3.1.6 - array.prototype.flatmap: ^1.3.1 - array.prototype.tosorted: ^1.1.1 + array-includes: ^3.1.7 + array.prototype.findlast: ^1.2.4 + array.prototype.flatmap: ^1.3.2 + array.prototype.toreversed: ^1.1.2 + array.prototype.tosorted: ^1.1.3 doctrine: ^2.1.0 - es-iterator-helpers: ^1.0.12 + es-iterator-helpers: ^1.0.17 estraverse: ^5.3.0 jsx-ast-utils: ^2.4.1 || ^3.0.0 minimatch: ^3.1.2 - object.entries: ^1.1.6 - object.fromentries: ^2.0.6 - object.hasown: ^1.1.2 - object.values: ^1.1.6 + object.entries: ^1.1.7 + object.fromentries: ^2.0.7 + object.hasown: ^1.1.3 + object.values: ^1.1.7 prop-types: ^15.8.1 - resolve: ^2.0.0-next.4 + resolve: ^2.0.0-next.5 semver: ^6.3.1 - string.prototype.matchall: ^4.0.8 + string.prototype.matchall: ^4.0.10 peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: b4c3d76390b0ae6b6f9fed78170604cc2c04b48e6778a637db339e8e3911ec9ef22510b0ae77c429698151d0f1b245f282177f384105b6830e7b29b9c9b26610 + checksum: 82f391c5a093235c3bc2f664c54e009c49460778ee7d1b86c1536df9ac4d2a80d1dedc9241ac797df4a9dced936e955d9c89042fb3ac8d017b5359d1320d3c0f languageName: node linkType: hard "eslint-plugin-testing-library@npm:^6.0.0": - version: 6.2.0 - resolution: "eslint-plugin-testing-library@npm:6.2.0" + version: 6.2.2 + resolution: "eslint-plugin-testing-library@npm:6.2.2" dependencies: "@typescript-eslint/utils": ^5.58.0 peerDependencies: eslint: ^7.5.0 || ^8.0.0 - checksum: 7af7e0a1eee44c6ba65ce2ae99f8e46ce709a319f4cce778bb0af2dda5828d78f3a81e8989c7b691a8b9b9fef102b56136209aac700038b9e64794600b0d12db + checksum: df55ca98415bad3e7d6b21adcd0f817d7c6df59cb32099528e45b39e8d7edf95e040334106fc7574fd402ed624ca65215ccf37745e1da1a9c90cfe00b99c5be4 languageName: node linkType: hard @@ -27073,30 +23712,30 @@ __metadata: linkType: hard "eslint-webpack-plugin@npm:^4.0.0": - version: 4.0.1 - resolution: "eslint-webpack-plugin@npm:4.0.1" + version: 4.1.0 + resolution: "eslint-webpack-plugin@npm:4.1.0" dependencies: - "@types/eslint": ^8.37.0 - jest-worker: ^29.5.0 + "@types/eslint": ^8.56.5 + jest-worker: ^29.7.0 micromatch: ^4.0.5 normalize-path: ^3.0.0 - schema-utils: ^4.0.0 + schema-utils: ^4.2.0 peerDependencies: eslint: ^8.0.0 webpack: ^5.0.0 - checksum: 94fe0817fc580729dc6edc4a31c9f7dbeb97ad134c6c4192feab66aae711ed5afe35c5bc8d5e99b39626b469300196df72e631f5e53c55723adbf850765924e5 + checksum: 1676ff08b0424e4656aa638a0c2a7b2f3f6a504651689a2d86b237c9a52ad65e17aeb5abbe13663e25353d8a706dcf45f49dbe4795dad27b6b0650db8aa21b16 languageName: node linkType: hard "eslint@npm:^8.33.0, eslint@npm:^8.6.0": - version: 8.56.0 - resolution: "eslint@npm:8.56.0" + version: 8.57.0 + resolution: "eslint@npm:8.57.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.56.0 - "@humanwhocodes/config-array": ^0.11.13 + "@eslint/js": 8.57.0 + "@humanwhocodes/config-array": ^0.11.14 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 "@ungap/structured-clone": ^1.2.0 @@ -27132,7 +23771,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 883436d1e809b4a25d9eb03d42f584b84c408dbac28b0019f6ea07b5177940bf3cca86208f749a6a1e0039b63e085ee47aca1236c30721e91f0deef5cc5a5136 + checksum: 3a48d7ff85ab420a8447e9810d8087aea5b1df9ef68c9151732b478de698389ee656fd895635b5f2871c89ee5a2652b3f343d11e9db6f8486880374ebc74a2d9 languageName: node linkType: hard @@ -27143,6 +23782,18 @@ __metadata: languageName: node linkType: hard +"esniff@npm:^2.0.1": + version: 2.0.1 + resolution: "esniff@npm:2.0.1" + dependencies: + d: ^1.0.1 + es5-ext: ^0.10.62 + event-emitter: ^0.3.5 + type: ^2.7.2 + checksum: d814c0e5c39bce9925b2e65b6d8767af72c9b54f35a65f9f3d6e8c606dce9aebe35a9599d30f15b0807743f88689f445163cfb577a425de4fb8c3c5bc16710cc + languageName: node + linkType: hard + "espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" @@ -27265,13 +23916,6 @@ __metadata: languageName: node linkType: hard -"eventemitter2@npm:^6.4.4": - version: 6.4.7 - resolution: "eventemitter2@npm:6.4.7" - checksum: 1b36a77e139d6965ebf3a36c01fa00c089ae6b80faa1911e52888f40b3a7057b36a2cc45dcd1ad87cda3798fe7b97a0aabcbb8175a8b96092a23bb7d0f039e66 - languageName: node - linkType: hard - "eventemitter3@npm:^3.1.0": version: 3.1.2 resolution: "eventemitter3@npm:3.1.2" @@ -27279,7 +23923,7 @@ __metadata: languageName: node linkType: hard -"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.1, eventemitter3@npm:^4.0.4": +"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.4": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 @@ -27318,6 +23962,7 @@ __metadata: "@backstage/app-defaults": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" "@backstage/core-app-api": "workspace:^" "@backstage/core-compat-api": "workspace:^" "@backstage/core-components": "workspace:^" @@ -27325,93 +23970,56 @@ __metadata: "@backstage/frontend-app-api": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/integration-react": "workspace:^" - "@backstage/plugin-adr": "workspace:^" - "@backstage/plugin-airbrake": "workspace:^" - "@backstage/plugin-apache-airflow": "workspace:^" "@backstage/plugin-api-docs": "workspace:^" "@backstage/plugin-app-visualizer": "workspace:^" - "@backstage/plugin-azure-devops": "workspace:^" - "@backstage/plugin-azure-sites": "workspace:^" - "@backstage/plugin-badges": "workspace:^" + "@backstage/plugin-auth-react": "workspace:^" "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-graph": "workspace:^" "@backstage/plugin-catalog-import": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-catalog-unprocessed-entities": "workspace:^" - "@backstage/plugin-cloudbuild": "workspace:^" - "@backstage/plugin-code-coverage": "workspace:^" - "@backstage/plugin-cost-insights": "workspace:^" - "@backstage/plugin-devtools": "workspace:^" - "@backstage/plugin-dynatrace": "workspace:^" - "@backstage/plugin-entity-feedback": "workspace:^" - "@backstage/plugin-explore": "workspace:^" - "@backstage/plugin-gcalendar": "workspace:^" - "@backstage/plugin-gcp-projects": "workspace:^" - "@backstage/plugin-github-actions": "workspace:^" - "@backstage/plugin-gocd": "workspace:^" - "@backstage/plugin-graphiql": "workspace:^" "@backstage/plugin-home": "workspace:^" - "@backstage/plugin-jenkins": "workspace:^" - "@backstage/plugin-kafka": "workspace:^" "@backstage/plugin-kubernetes": "workspace:^" - "@backstage/plugin-lighthouse": "workspace:^" - "@backstage/plugin-linguist": "workspace:^" - "@backstage/plugin-linguist-common": "workspace:^" - "@backstage/plugin-microsoft-calendar": "workspace:^" - "@backstage/plugin-newrelic": "workspace:^" - "@backstage/plugin-newrelic-dashboard": "workspace:^" - "@backstage/plugin-octopus-deploy": "workspace:^" + "@backstage/plugin-kubernetes-cluster": "workspace:^" + "@backstage/plugin-notifications": "workspace:^" "@backstage/plugin-org": "workspace:^" - "@backstage/plugin-pagerduty": "workspace:^" "@backstage/plugin-permission-react": "workspace:^" - "@backstage/plugin-playlist": "workspace:^" - "@backstage/plugin-puppetdb": "workspace:^" - "@backstage/plugin-rollbar": "workspace:^" "@backstage/plugin-scaffolder": "workspace:^" "@backstage/plugin-scaffolder-react": "workspace:^" "@backstage/plugin-search": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-search-react": "workspace:^" - "@backstage/plugin-sentry": "workspace:^" - "@backstage/plugin-shortcuts": "workspace:^" - "@backstage/plugin-stackstorm": "workspace:^" - "@backstage/plugin-tech-insights": "workspace:^" - "@backstage/plugin-tech-radar": "workspace:^" + "@backstage/plugin-signals": "workspace:^" "@backstage/plugin-techdocs": "workspace:^" "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^" "@backstage/plugin-techdocs-react": "workspace:^" - "@backstage/plugin-todo": "workspace:^" "@backstage/plugin-user-settings": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" - "@circleci/backstage-plugin": ^0.1.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@octokit/rest": ^19.0.3 - "@oriflame/backstage-plugin-score-card": ^0.8.0 - "@roadiehq/backstage-plugin-buildkite": ^2.0.8 - "@roadiehq/backstage-plugin-github-insights": ^2.0.5 - "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 - "@roadiehq/backstage-plugin-travis-ci": ^2.0.5 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 - app-next-example-plugin: "workspace:^" + "@vitejs/plugin-react": ^4.0.4 cross-env: ^7.0.0 history: ^5.0.0 - lodash: ^4.17.21 react: ^18.0.2 react-dom: ^18.0.2 react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 + vite: ^4.4.9 + vite-plugin-html: ^3.2.0 + vite-plugin-node-polyfills: ^0.21.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -27435,84 +24043,41 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@backstage/frontend-app-api": "workspace:^" "@backstage/integration-react": "workspace:^" - "@backstage/plugin-adr": "workspace:^" - "@backstage/plugin-airbrake": "workspace:^" - "@backstage/plugin-apache-airflow": "workspace:^" "@backstage/plugin-api-docs": "workspace:^" - "@backstage/plugin-azure-devops": "workspace:^" - "@backstage/plugin-azure-sites": "workspace:^" - "@backstage/plugin-badges": "workspace:^" + "@backstage/plugin-auth-react": "workspace:^" "@backstage/plugin-catalog": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-graph": "workspace:^" "@backstage/plugin-catalog-import": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" "@backstage/plugin-catalog-unprocessed-entities": "workspace:^" - "@backstage/plugin-cloudbuild": "workspace:^" - "@backstage/plugin-code-coverage": "workspace:^" - "@backstage/plugin-cost-insights": "workspace:^" "@backstage/plugin-devtools": "workspace:^" - "@backstage/plugin-dynatrace": "workspace:^" - "@backstage/plugin-entity-feedback": "workspace:^" - "@backstage/plugin-explore": "workspace:^" - "@backstage/plugin-gcalendar": "workspace:^" - "@backstage/plugin-gcp-projects": "workspace:^" - "@backstage/plugin-github-actions": "workspace:^" - "@backstage/plugin-gocd": "workspace:^" - "@backstage/plugin-graphiql": "workspace:^" "@backstage/plugin-home": "workspace:^" - "@backstage/plugin-jenkins": "workspace:^" - "@backstage/plugin-kafka": "workspace:^" "@backstage/plugin-kubernetes": "workspace:^" "@backstage/plugin-kubernetes-cluster": "workspace:^" - "@backstage/plugin-lighthouse": "workspace:^" - "@backstage/plugin-linguist": "workspace:^" - "@backstage/plugin-linguist-common": "workspace:^" - "@backstage/plugin-microsoft-calendar": "workspace:^" - "@backstage/plugin-newrelic": "workspace:^" - "@backstage/plugin-newrelic-dashboard": "workspace:^" - "@backstage/plugin-nomad": "workspace:^" "@backstage/plugin-notifications": "workspace:^" - "@backstage/plugin-octopus-deploy": "workspace:^" "@backstage/plugin-org": "workspace:^" - "@backstage/plugin-pagerduty": "workspace:^" "@backstage/plugin-permission-react": "workspace:^" - "@backstage/plugin-playlist": "workspace:^" - "@backstage/plugin-puppetdb": "workspace:^" - "@backstage/plugin-rollbar": "workspace:^" "@backstage/plugin-scaffolder": "workspace:^" "@backstage/plugin-scaffolder-react": "workspace:^" "@backstage/plugin-search": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-search-react": "workspace:^" - "@backstage/plugin-sentry": "workspace:^" - "@backstage/plugin-shortcuts": "workspace:^" "@backstage/plugin-signals": "workspace:^" - "@backstage/plugin-stack-overflow": "workspace:^" - "@backstage/plugin-stackstorm": "workspace:^" - "@backstage/plugin-tech-insights": "workspace:^" - "@backstage/plugin-tech-radar": "workspace:^" "@backstage/plugin-techdocs": "workspace:^" "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^" "@backstage/plugin-techdocs-react": "workspace:^" - "@backstage/plugin-todo": "workspace:^" "@backstage/plugin-user-settings": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" - "@circleci/backstage-plugin": ^0.1.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@octokit/rest": ^19.0.3 - "@oriflame/backstage-plugin-score-card": ^0.8.0 "@playwright/test": ^1.32.3 - "@roadiehq/backstage-plugin-buildkite": ^2.0.8 - "@roadiehq/backstage-plugin-github-insights": ^2.0.5 - "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 - "@roadiehq/backstage-plugin-travis-ci": ^2.0.5 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/jquery": ^3.3.34 "@types/react": "*" @@ -27540,41 +24105,35 @@ __metadata: "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" + "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" - "@backstage/plugin-adr-backend": "workspace:^" "@backstage/plugin-app-backend": "workspace:^" + "@backstage/plugin-auth-backend": "workspace:^" + "@backstage/plugin-auth-backend-module-github-provider": "workspace:^" + "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-azure-devops-backend": "workspace:^" - "@backstage/plugin-badges-backend": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-catalog-backend-module-backstage-openapi": "workspace:^" "@backstage/plugin-catalog-backend-module-openapi": "workspace:^" "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^" "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^" "@backstage/plugin-devtools-backend": "workspace:^" - "@backstage/plugin-entity-feedback-backend": "workspace:^" - "@backstage/plugin-jenkins-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" - "@backstage/plugin-lighthouse-backend": "workspace:^" - "@backstage/plugin-linguist-backend": "workspace:^" - "@backstage/plugin-nomad-backend": "workspace:^" "@backstage/plugin-notifications-backend": "workspace:^" "@backstage/plugin-permission-backend": "workspace:^" "@backstage/plugin-permission-backend-module-allow-all-policy": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" - "@backstage/plugin-playlist-backend": "workspace:^" "@backstage/plugin-proxy-backend": "workspace:^" "@backstage/plugin-scaffolder-backend": "workspace:^" + "@backstage/plugin-scaffolder-backend-module-github": "workspace:^" "@backstage/plugin-search-backend": "workspace:^" "@backstage/plugin-search-backend-module-catalog": "workspace:^" "@backstage/plugin-search-backend-module-explore": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-signals-backend": "workspace:^" - "@backstage/plugin-sonarqube-backend": "workspace:^" "@backstage/plugin-techdocs-backend": "workspace:^" - "@backstage/plugin-todo-backend": "workspace:^" languageName: unknown linkType: soft @@ -27589,35 +24148,21 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/integration": "workspace:^" - "@backstage/plugin-adr-backend": "workspace:^" "@backstage/plugin-app-backend": "workspace:^" "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" - "@backstage/plugin-azure-devops-backend": "workspace:^" - "@backstage/plugin-azure-sites-common": "workspace:^" - "@backstage/plugin-badges-backend": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^" "@backstage/plugin-catalog-backend-module-unprocessed": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" - "@backstage/plugin-code-coverage-backend": "workspace:^" "@backstage/plugin-devtools-backend": "workspace:^" - "@backstage/plugin-entity-feedback-backend": "workspace:^" "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" - "@backstage/plugin-explore-backend": "workspace:^" - "@backstage/plugin-jenkins-backend": "workspace:^" - "@backstage/plugin-kafka-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" - "@backstage/plugin-lighthouse-backend": "workspace:^" - "@backstage/plugin-linguist-backend": "workspace:^" - "@backstage/plugin-nomad-backend": "workspace:^" "@backstage/plugin-permission-backend": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" - "@backstage/plugin-playlist-backend": "workspace:^" "@backstage/plugin-proxy-backend": "workspace:^" - "@backstage/plugin-rollbar-backend": "workspace:^" "@backstage/plugin-scaffolder-backend": "workspace:^" "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "workspace:^" "@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^" @@ -27629,18 +24174,13 @@ __metadata: "@backstage/plugin-search-backend-module-pg": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-signals-backend": "workspace:^" "@backstage/plugin-signals-node": "workspace:^" - "@backstage/plugin-tech-insights-backend": "workspace:^" - "@backstage/plugin-tech-insights-backend-module-jsonfc": "workspace:^" - "@backstage/plugin-tech-insights-node": "workspace:^" "@backstage/plugin-techdocs-backend": "workspace:^" - "@backstage/plugin-todo-backend": "workspace:^" "@gitbeaker/node": ^35.1.0 "@octokit/rest": ^19.0.3 "@opentelemetry/api": ^1.4.1 - "@opentelemetry/exporter-prometheus": ^0.48.0 + "@opentelemetry/exporter-prometheus": ^0.50.0 "@opentelemetry/sdk-metrics": ^1.13.0 "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 @@ -27654,7 +24194,7 @@ __metadata: express-prom-bundle: ^7.0.0 express-promise-router: ^4.1.0 luxon: ^3.0.0 - mysql2: ^2.2.5 + mysql2: ^3.0.0 pg: ^8.11.3 pg-connection-string: ^2.3.0 prom-client: ^15.0.0 @@ -27739,20 +24279,7 @@ __metadata: languageName: node linkType: hard -"expect@npm:^28.0.0": - version: 28.1.3 - resolution: "expect@npm:28.1.3" - dependencies: - "@jest/expect-utils": ^28.1.3 - jest-get-type: ^28.0.2 - jest-matcher-utils: ^28.1.3 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 - checksum: 101e0090de300bcafedb7dbfd19223368a2251ce5fe0105bbb6de5720100b89fb6b64290ebfb42febc048324c76d6a4979cdc4b61eb77747857daf7a5de9b03d - languageName: node - linkType: hard - -"expect@npm:^29.0.0, expect@npm:^29.7.0": +"expect@npm:>28.1.3, expect@npm:^29.0.0, expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" dependencies: @@ -27849,16 +24376,16 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2": - version: 4.18.2 - resolution: "express@npm:4.18.2" +"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.19.2": + version: 4.19.2 + resolution: "express@npm:4.19.2" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.1 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: ~1.0.4 - cookie: 0.5.0 + cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 @@ -27884,7 +24411,7 @@ __metadata: type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 3c4b9b076879442f6b968fe53d85d9f1eeacbb4f4c41e5f16cc36d77ce39a2b0d81b3f250514982110d815b2f7173f5561367f9110fcc541f9371948e8c8b037 + checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 languageName: node linkType: hard @@ -27929,6 +24456,23 @@ __metadata: languageName: node linkType: hard +"extract-zip@npm:2.0.1": + version: 2.0.1 + resolution: "extract-zip@npm:2.0.1" + dependencies: + "@types/yauzl": ^2.9.1 + debug: ^4.1.1 + get-stream: ^5.1.0 + yauzl: ^2.10.0 + dependenciesMeta: + "@types/yauzl": + optional: true + bin: + extract-zip: cli.js + checksum: 8cbda9debdd6d6980819cc69734d874ddd71051c9fe5bde1ef307ebcedfe949ba57b004894b585f758b7c9eeeea0e3d87f2dda89b7d25320459c2c9643ebb635 + languageName: node + linkType: hard + "extsprintf@npm:1.3.0": version: 1.3.0 resolution: "extsprintf@npm:1.3.0" @@ -27943,6 +24487,13 @@ __metadata: languageName: node linkType: hard +"fast-copy@npm:^3.0.2": + version: 3.0.2 + resolution: "fast-copy@npm:3.0.2" + checksum: 47f584bcede08ab3198559d3e0e093a547d567715b86be2198da6e3366c3c73eed550d97b86f9fb90dae179982b89c15d68187def960f522cdce14bacdfc6184 + languageName: node + linkType: hard + "fast-decode-uri-component@npm:^1.0.1": version: 1.0.1 resolution: "fast-decode-uri-component@npm:1.0.1" @@ -27957,13 +24508,6 @@ __metadata: languageName: node linkType: hard -"fast-equals@npm:^5.0.1": - version: 5.0.1 - resolution: "fast-equals@npm:5.0.1" - checksum: fbb3b6a74f3a0fa930afac151ff7d01639159b4fddd2678b5d50708e0ba38e9ec14602222d10dadb8398187342692c04fbef5a62b1cfcc7942fe03e754e064bc - languageName: node - linkType: hard - "fast-fifo@npm:^1.1.0, fast-fifo@npm:^1.2.0": version: 1.3.2 resolution: "fast-fifo@npm:1.3.2" @@ -28056,13 +24600,6 @@ __metadata: languageName: node linkType: hard -"fast-text-encoding@npm:^1.0.0": - version: 1.0.3 - resolution: "fast-text-encoding@npm:1.0.3" - checksum: 3e51365896f06d0dcab128092d095a0037d274deec419fecbd2388bc236d7b387610e0c72f920c6126e00c885ab096fbfaa3645712f5b98f721bef6b064916a8 - languageName: node - linkType: hard - "fast-url-parser@npm:1.1.3, fast-url-parser@npm:^1.1.3": version: 1.1.3 resolution: "fast-url-parser@npm:1.1.3" @@ -28153,21 +24690,6 @@ __metadata: languageName: node linkType: hard -"fbjs@npm:^0.8.1": - version: 0.8.18 - resolution: "fbjs@npm:0.8.18" - dependencies: - core-js: ^1.0.0 - isomorphic-fetch: ^2.1.1 - loose-envify: ^1.0.0 - object-assign: ^4.1.0 - promise: ^7.1.1 - setimmediate: ^1.0.5 - ua-parser-js: ^0.7.30 - checksum: 668731b946a765908c9cbe51d5160f973abb78004b3d122587c3e930e3e1ddcc0ce2b17f2a8637dc9d733e149aa580f8d3035a35cc2d3bc78b78f1b19aab90e2 - languageName: node - linkType: hard - "fbjs@npm:^3.0.0, fbjs@npm:^3.0.1": version: 3.0.4 resolution: "fbjs@npm:3.0.4" @@ -28209,20 +24731,6 @@ __metadata: languageName: node linkType: hard -"fflate@npm:^0.4.4": - version: 0.4.8 - resolution: "fflate@npm:0.4.8" - checksum: 29d8cbe44d5e7f53e7f5a160ac7f9cc025480c7b3bfd85c5f898cbe20dfa2dad4732daa534982664bf30b35896a90af44ea33ede5d94c5ffd1b8b0c0a0a56ca2 - languageName: node - linkType: hard - -"fflate@npm:^0.7.4": - version: 0.7.4 - resolution: "fflate@npm:0.7.4" - checksum: b812ab26047432db70ff4c73eb45ad53bd0774575b4818b9c61c2921e89ec65d1259f06ec1618f2ac55e6a2f2e29b6dc09173d213b46580bc69efae5344bf8f1 - languageName: node - linkType: hard - "figures@npm:^3.0.0, figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -28452,10 +24960,10 @@ __metadata: languageName: node linkType: hard -"flatted@npm:3.2.9, flatted@npm:^3.1.0": - version: 3.2.9 - resolution: "flatted@npm:3.2.9" - checksum: f14167fbe26a9d20f6fca8d998e8f1f41df72c8e81f9f2c9d61ed2bea058248f5e1cbd05e7f88c0e5087a6a0b822a1e5e2b446e879f3cfbe0b07ba2d7f80b026 +"flatted@npm:3.3.1, flatted@npm:^3.1.0": + version: 3.3.1 + resolution: "flatted@npm:3.3.1" + checksum: 85ae7181650bb728c221e7644cbc9f4bf28bc556f2fc89bb21266962bdf0ce1029cc7acc44bb646cd469d9baac7c317f64e841c4c4c00516afa97320cdac7f94 languageName: node linkType: hard @@ -28485,13 +24993,13 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.4": - version: 1.15.4 - resolution: "follow-redirects@npm:1.15.4" +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.4, follow-redirects@npm:^1.15.6": + version: 1.15.6 + resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: debug: optional: true - checksum: e178d1deff8b23d5d24ec3f7a94cde6e47d74d0dc649c35fc9857041267c12ec5d44650a0c5597ef83056ada9ea6ca0c30e7c4f97dbf07d035086be9e6a5b7b6 + checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5 languageName: node linkType: hard @@ -28682,7 +25190,7 @@ __metadata: languageName: node linkType: hard -"fresh@npm:0.5.2": +"fresh@npm:0.5.2, fresh@npm:^0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" checksum: 13ea8b08f91e669a64e3ba3a20eb79d7ca5379a81f1ff7f4310d54e2320645503cc0c78daedc93dfb6191287295f6479544a649c64d8e41a1c0fb0c221552346 @@ -28706,15 +25214,6 @@ __metadata: languageName: node linkType: hard -"front-matter@npm:^4.0.2": - version: 4.0.2 - resolution: "front-matter@npm:4.0.2" - dependencies: - js-yaml: ^3.13.1 - checksum: a5b4c36d75a820301ebf31db0f677332d189c4561903ab6853eaa0504b43634f98557dbf87752e09043dbd2c9dcc14b4bcf9151cb319c8ad7e26edb203c0cd23 - languageName: node - linkType: hard - "fs-constants@npm:^1.0.0": version: 1.0.0 resolution: "fs-constants@npm:1.0.0" @@ -28796,10 +25295,10 @@ __metadata: languageName: node linkType: hard -"fs-monkey@npm:1.0.3": - version: 1.0.3 - resolution: "fs-monkey@npm:1.0.3" - checksum: cf50804833f9b88a476911ae911fe50f61a98d986df52f890bd97e7262796d023698cb2309fa9b74fdd8974f04315b648748a0a8ee059e7d5257b293bfc409c0 +"fs-monkey@npm:^1.0.4": + version: 1.0.5 + resolution: "fs-monkey@npm:1.0.5" + checksum: 424b67f65b37fe66117ae2bb061f790fe6d4b609e1d160487c74b3d69fbf42f262c665ccfba32e8b5f113f96f92e9a58fcdebe42d5f6649bdfc72918093a3119 languageName: node linkType: hard @@ -28820,7 +25319,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": +"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -28832,16 +25331,16 @@ __metadata: "fsevents@patch:fsevents@2.3.2#~builtin": version: 2.3.2 - resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" dependencies: node-gyp: latest conditions: os=darwin languageName: node linkType: hard -"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": +"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.3 - resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=18f3a7" + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" dependencies: node-gyp: latest conditions: os=darwin @@ -28915,41 +25414,19 @@ __metadata: languageName: node linkType: hard -"gaxios@npm:^5.0.0, gaxios@npm:^5.0.1": - version: 5.0.1 - resolution: "gaxios@npm:5.0.1" - dependencies: - extend: ^3.0.2 - https-proxy-agent: ^5.0.0 - is-stream: ^2.0.0 - node-fetch: ^2.6.7 - checksum: 65464122a5be72084d07947536d18a0dcebd115b28cbcd19da8a98763a67c8c8fde995bf2f358251397c939df9d2ff84f54628a94f634a98a16c7b7553cdb4a5 - languageName: node - linkType: hard - -"gaxios@npm:^6.0.0, gaxios@npm:^6.0.2": - version: 6.1.1 - resolution: "gaxios@npm:6.1.1" +"gaxios@npm:^6.0.0, gaxios@npm:^6.0.2, gaxios@npm:^6.1.1": + version: 6.3.0 + resolution: "gaxios@npm:6.3.0" dependencies: extend: ^3.0.2 https-proxy-agent: ^7.0.1 is-stream: ^2.0.0 node-fetch: ^2.6.9 - checksum: bb4a4e6c81847b690ee29e01294d2093eb9bb4f9e60bbf81fcc6cd3b274f3c551c50a9bc134e7e7019a9b116eac9d9df6af9f2519c695da7ddd785f36564da72 + checksum: 4d4a8db32d833f8012435e2016cb0c919cac288e821bf81f877504e4284ef12b444cd903448e738c4031cd5219adf1e8d68e7df2b3dba774db9fde27f71109d4 languageName: node linkType: hard -"gcp-metadata@npm:^5.3.0": - version: 5.3.0 - resolution: "gcp-metadata@npm:5.3.0" - dependencies: - gaxios: ^5.0.0 - json-bigint: ^1.0.0 - checksum: 891ea0b902a17f33d7bae753830d23962b63af94ed071092c30496e7d26f8128ba9af43c3d38474bea29cb32a884b4bcb5720ce8b9de4a7e1108475d3d7ae219 - languageName: node - linkType: hard - -"gcp-metadata@npm:^6.0.0": +"gcp-metadata@npm:^6.1.0": version: 6.1.0 resolution: "gcp-metadata@npm:6.1.0" dependencies: @@ -29008,15 +25485,16 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": - version: 1.2.2 - resolution: "get-intrinsic@npm:1.2.2" +"get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" dependencies: + es-errors: ^1.3.0 function-bind: ^1.1.2 has-proto: ^1.0.1 has-symbols: ^1.0.3 hasown: ^2.0.0 - checksum: 447ff0724df26829908dc033b62732359596fcf66027bc131ab37984afb33842d9cd458fd6cecadfe7eac22fd8a54b349799ed334cf2726025c921c7250e7417 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 languageName: node linkType: hard @@ -29041,10 +25519,10 @@ __metadata: languageName: node linkType: hard -"get-stdin@npm:^8.0.0": - version: 8.0.0 - resolution: "get-stdin@npm:8.0.0" - checksum: 40128b6cd25781ddbd233344f1a1e4006d4284906191ed0a7d55ec2c1a3e44d650f280b2c9eeab79c03ac3037da80257476c0e4e5af38ddfb902d6ff06282d77 +"get-stdin@npm:^9.0.0": + version: 9.0.0 + resolution: "get-stdin@npm:9.0.0" + checksum: 5972bc34d05932b45512c8e2d67b040f1c1ca8afb95c56cbc480985f2d761b7e37fe90dc8abd22527f062cc5639a6930ff346e9952ae4c11a2d4275869459594 languageName: node linkType: hard @@ -29080,22 +25558,23 @@ __metadata: languageName: node linkType: hard -"get-symbol-description@npm:^1.0.0": - version: 1.0.0 - resolution: "get-symbol-description@npm:1.0.0" +"get-symbol-description@npm:^1.0.2": + version: 1.0.2 + resolution: "get-symbol-description@npm:1.0.2" dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.1 - checksum: 9ceff8fe968f9270a37a1f73bf3f1f7bda69ca80f4f80850670e0e7b9444ff99323f7ac52f96567f8b5f5fbe7ac717a0d81d3407c7313e82810c6199446a5247 + call-bind: ^1.0.5 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + checksum: e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 languageName: node linkType: hard "get-tsconfig@npm:^4.7.0, get-tsconfig@npm:^4.7.2": - version: 4.7.2 - resolution: "get-tsconfig@npm:4.7.2" + version: 4.7.3 + resolution: "get-tsconfig@npm:4.7.3" dependencies: resolve-pkg-maps: ^1.0.0 - checksum: 172358903250eff0103943f816e8a4e51d29b8e5449058bdf7266714a908a48239f6884308bd3a6ff28b09f692b9533dbebfd183ab63e4e14f073cda91f1bca9 + checksum: d124e6900f8beb3b71f215941096075223158d0abb09fb5daa8d83299f6c17d5e95a97d12847b387e9e716bb9bd256a473f918fb8020f3b1acc0b1e5c2830bbf languageName: node linkType: hard @@ -29127,6 +25606,13 @@ __metadata: languageName: node linkType: hard +"git-hooks-list@npm:^3.0.0": + version: 3.1.0 + resolution: "git-hooks-list@npm:3.1.0" + checksum: 05cbdb29e1e14f3b6fde78c876a34383e4476b1be32e8486ad03293f01add884c1a8df8c2dce2ca5d99119c94951b2ff9fa9cbd51d834ae6477b6813cefb998f + languageName: node + linkType: hard + "git-up@npm:^7.0.0": version: 7.0.0 resolution: "git-up@npm:7.0.0" @@ -29137,7 +25623,7 @@ __metadata: languageName: node linkType: hard -"git-url-parse@npm:^13.0.0, git-url-parse@npm:^13.1.0": +"git-url-parse@npm:^13.1.0": version: 13.1.1 resolution: "git-url-parse@npm:13.1.1" dependencies: @@ -29187,7 +25673,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7, glob@npm:^7.2.0": +"glob@npm:7.2.3, glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -29201,7 +25687,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10": +"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": version: 10.3.10 resolution: "glob@npm:10.3.10" dependencies: @@ -29216,7 +25702,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3": +"glob@npm:^8.0.0, glob@npm:^8.0.1, glob@npm:^8.0.3, glob@npm:^8.1.0": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -29324,43 +25810,26 @@ __metadata: languageName: node linkType: hard -"good-listener@npm:^1.2.2": - version: 1.2.2 - resolution: "good-listener@npm:1.2.2" - dependencies: - delegate: ^3.1.2 - checksum: f39fb82c4e41524f56104cfd2d7aef1a88e72f3f75139115fbdf98cc7d844e0c1b39218b2e83438c6188727bf904ed78c7f0f2feff67b32833bc3af7f0202b33 +"goober@npm:^2.0.33": + version: 2.1.14 + resolution: "goober@npm:2.1.14" + peerDependencies: + csstype: ^3.0.10 + checksum: 78978b7192d6a1af5cfbf1fd64b661b5f53ee6c733554b1f1b2ad3e1e2c979847fc080434390647640bb8358c0b193895d0007432c0886d12001f02f8f56b5e6 languageName: node linkType: hard -"google-auth-library@npm:^8.0.0": - version: 8.9.0 - resolution: "google-auth-library@npm:8.9.0" - dependencies: - arrify: ^2.0.0 - base64-js: ^1.3.0 - ecdsa-sig-formatter: ^1.0.11 - fast-text-encoding: ^1.0.0 - gaxios: ^5.0.0 - gcp-metadata: ^5.3.0 - gtoken: ^6.1.0 - jws: ^4.0.0 - lru-cache: ^6.0.0 - checksum: 8e0bc5f1e91804523786413bf4358e4c5ad94b1e873c725ddd03d0f1c242e2b38e26352c0f375334fbc1d94110f761b304aa0429de49b4a27ebc3875a5b56644 - languageName: node - linkType: hard - -"google-auth-library@npm:^9.0.0": - version: 9.2.0 - resolution: "google-auth-library@npm:9.2.0" +"google-auth-library@npm:^9.0.0, google-auth-library@npm:^9.6.3": + version: 9.8.0 + resolution: "google-auth-library@npm:9.8.0" dependencies: base64-js: ^1.3.0 ecdsa-sig-formatter: ^1.0.11 - gaxios: ^6.0.0 - gcp-metadata: ^6.0.0 + gaxios: ^6.1.1 + gcp-metadata: ^6.1.0 gtoken: ^7.0.0 jws: ^4.0.0 - checksum: 0da686964a769c79b5a1f7e518cb885f7c433edd50c8adf5cc310bfce607235184ebe6f9bc5290618d760c25e4ce1e273d444c9914c815353faa9d9dea37d1b3 + checksum: dd67972861e16d47de494ac333bd76c57a5132e300793ae2dc8866fb76b3e57099846ce84b036ab2564bc4e85e0dc4d4cf245f4ca95aedebf53a9a2c03f35b38 languageName: node linkType: hard @@ -29383,17 +25852,6 @@ __metadata: languageName: node linkType: hard -"google-p12-pem@npm:^4.0.0": - version: 4.0.0 - resolution: "google-p12-pem@npm:4.0.0" - dependencies: - node-forge: ^1.3.1 - bin: - gp12-pem: build/src/bin/gp12-pem.js - checksum: f41a88d339e9fe633dc915bc0f3335c0196fa318f994dcd5dfaa0f3f7aa2d99f6122e2c80bd0f4bb22f2b61ff645b7cc782a74e12ceaf6c9ad9e08cdeb4d615e - languageName: node - linkType: hard - "google-protobuf@npm:^3.15.8, google-protobuf@npm:^3.19.1": version: 3.20.1 resolution: "google-protobuf@npm:3.20.1" @@ -29469,23 +25927,7 @@ __metadata: languageName: node linkType: hard -"graphiql@npm:3.1.0": - version: 3.1.0 - resolution: "graphiql@npm:3.1.0" - dependencies: - "@graphiql/react": ^0.20.2 - "@graphiql/toolkit": ^0.9.1 - graphql-language-service: ^5.2.0 - markdown-it: ^12.2.0 - peerDependencies: - graphql: ^15.5.0 || ^16.0.0 - react: ^16.8.0 || ^17 || ^18 - react-dom: ^16.8.0 || ^17 || ^18 - checksum: a8969ea299561fe627ba566fb72dd90eda31b195e9983af87c4079bf807f5b356d116ece133e46d5098d6809a88b8f3b64b04a9e95dfe34cd84eb8fd109e2b8a - languageName: node - linkType: hard - -"graphiql@npm:^3.0.6": +"graphiql@npm:3.1.1": version: 3.1.1 resolution: "graphiql@npm:3.1.1" dependencies: @@ -29580,33 +26022,12 @@ __metadata: languageName: node linkType: hard -"graphql-voyager@npm:^1.0.0-rc.31": - version: 1.0.0-rc.31 - resolution: "graphql-voyager@npm:1.0.0-rc.31" - dependencies: - "@f/animate": ^1.0.1 - "@material-ui/core": ^3.9.3 - classnames: ^2.2.6 - clipboard: ^2.0.4 - commonmark: ^0.29.0 - lodash: ^4.17.10 - prop-types: ^15.7.2 - svg-pan-zoom: ^3.6.0 - viz.js: 2.1.2 - peerDependencies: - graphql: ">=14.0.0" - react: ">=15.4.2" - react-dom: ">=15.4.2" - checksum: 80e826eeb42d286540447723ea35a463a3a155287914a45e24b69f31617d8ca74c0c43bdaa64123bf4ed046e68f7e31feca7661c06288551040f3e5b96c48fed - languageName: node - linkType: hard - -"graphql-ws@npm:^5.14.0, graphql-ws@npm:^5.4.1, graphql-ws@npm:^5.9.0": - version: 5.15.0 - resolution: "graphql-ws@npm:5.15.0" +"graphql-ws@npm:^5.14.0, graphql-ws@npm:^5.4.1": + version: 5.16.0 + resolution: "graphql-ws@npm:5.16.0" peerDependencies: graphql: ">=0.11 <=16" - checksum: 699b3a74af772f974948947b2124917610dfcc89cbde1e3ed36080d17455712c9e24f6d8a3f102baaa662fc7a0777880492a507294dbaa3f6f669afae27510c3 + checksum: e3e077ec187a92be3fd5dfae49e23af11a82711d3537064384f6861c2b5ceb339f60dc1871d0026b47ff05e4ed3c941404812a8086347e454688e0e6ef0e69f3 languageName: node linkType: hard @@ -29655,17 +26076,6 @@ __metadata: languageName: node linkType: hard -"gtoken@npm:^6.1.0": - version: 6.1.1 - resolution: "gtoken@npm:6.1.1" - dependencies: - gaxios: ^5.0.1 - google-p12-pem: ^4.0.0 - jws: ^4.0.0 - checksum: f063ed3f418f5a9c33fbe599b09f56a55b18f6c8d2913f11cc2fc5025d53b96fd6ab1b4deb2c7631167d6b89d0939e4ea77f94767fcf338862ffda8911250980 - languageName: node - linkType: hard - "gtoken@npm:^7.0.0": version: 7.0.1 resolution: "gtoken@npm:7.0.1" @@ -29769,35 +26179,35 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.0": - version: 1.0.0 - resolution: "has-property-descriptors@npm:1.0.0" +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" dependencies: - get-intrinsic: ^1.1.1 - checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 languageName: node linkType: hard -"has-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "has-proto@npm:1.0.1" - checksum: febc5b5b531de8022806ad7407935e2135f1cc9e64636c3916c6842bd7995994ca3b29871ecd7954bd35f9e2986c17b3b227880484d22259e2f8e6ce63fd383e +"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: fe7c3d50b33f50f3933a04413ed1f69441d21d2d2944f81036276d30635cad9279f6b43bc8f32036c31ebdfcf6e731150f46c1907ad90c669ffe9b066c3ba5c4 languageName: node linkType: hard -"has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": +"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": version: 1.0.3 resolution: "has-symbols@npm:1.0.3" checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 languageName: node linkType: hard -"has-tostringtag@npm:^1.0.0": - version: 1.0.0 - resolution: "has-tostringtag@npm:1.0.0" +"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" dependencies: - has-symbols: ^1.0.2 - checksum: cc12eb28cb6ae22369ebaad3a8ab0799ed61270991be88f208d508076a1e99abe4198c965935ce85ea90b60c94ddda73693b0920b58e7ead048b4a391b502c1c + has-symbols: ^1.0.3 + checksum: 999d60bb753ad714356b2c6c87b7fb74f32463b8426e159397da4bde5bca7e598ab1073f4d8d4deafac297f2eb311484cd177af242776bf05f0d11565680468d languageName: node linkType: hard @@ -29815,15 +26225,6 @@ __metadata: languageName: node linkType: hard -"has@npm:^1.0.3": - version: 1.0.3 - resolution: "has@npm:1.0.3" - dependencies: - function-bind: ^1.1.1 - checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 - languageName: node - linkType: hard - "hash-base@npm:^3.0.0": version: 3.0.4 resolution: "hash-base@npm:3.0.4" @@ -29834,13 +26235,6 @@ __metadata: languageName: node linkType: hard -"hash-it@npm:^6.0.0": - version: 6.0.0 - resolution: "hash-it@npm:6.0.0" - checksum: 10ca948ff7902a752344c3975c1a5c76ba9e4aa0363032f347a7235cce98473dce60fe4399b05979596aedf649adaf5b3f792a55b9b64ad59ae686e43300c2d1 - languageName: node - linkType: hard - "hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": version: 1.1.7 resolution: "hash.js@npm:1.1.7" @@ -29851,12 +26245,12 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0": - version: 2.0.0 - resolution: "hasown@npm:2.0.0" +"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" dependencies: function-bind: ^1.1.2 - checksum: 6151c75ca12554565098641c98a40f4cc86b85b0fd5b6fe92360967e4605a4f9610f7757260b4e8098dd1c2ce7f4b095f2006fe72a570e3b6d2d28de0298c176 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db languageName: node linkType: hard @@ -29931,7 +26325,7 @@ __metadata: languageName: node linkType: hard -"highlight.js@npm:^10.1.0, highlight.js@npm:^10.4.1, highlight.js@npm:^10.6.0, highlight.js@npm:^10.7.2, highlight.js@npm:~10.7.0": +"highlight.js@npm:^10.1.0, highlight.js@npm:^10.4.1, highlight.js@npm:^10.7.2, highlight.js@npm:~10.7.0": version: 10.7.3 resolution: "highlight.js@npm:10.7.3" checksum: defeafcd546b535d710d8efb8e650af9e3b369ef53e28c3dc7893eacfe263200bba4c5fcf43524ae66d5c0c296b1af0870523ceae3e3104d24b7abf6374a4fea @@ -29958,14 +26352,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^2.3.1": - version: 2.5.5 - resolution: "hoist-non-react-statics@npm:2.5.5" - checksum: ee2d05e5c7e1398ad84a15b0327f66bd78f38a8e0015e852f954b36434e32eb7e942d5357505020a3a1147f247b165bf1e69d72393e3accab67cafdafeb86230 - languageName: node - linkType: hard - -"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.2.1, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -30050,10 +26437,10 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^2.1.0, html-entities@npm:^2.3.2": - version: 2.3.2 - resolution: "html-entities@npm:2.3.2" - checksum: 522d8d202df301ff51b517a379e642023ed5c81ea9fb5674ffad88cff386165733d00b6089d5c2fcc644e44777d6072017b6216d8fa40f271d3610420d00a886 +"html-entities@npm:^2.1.0, html-entities@npm:^2.4.0": + version: 2.4.0 + resolution: "html-entities@npm:2.4.0" + checksum: 25bea32642ce9ebd0eedc4d24381883ecb0335ccb8ac26379a0958b9b16652fdbaa725d70207ce54a51db24103436a698a8e454397d3ba8ad81460224751f1dc languageName: node linkType: hard @@ -30114,18 +26501,6 @@ __metadata: languageName: node linkType: hard -"htmlparser2@npm:^8.0.0": - version: 8.0.1 - resolution: "htmlparser2@npm:8.0.1" - dependencies: - domelementtype: ^2.3.0 - domhandler: ^5.0.2 - domutils: ^3.0.1 - entities: ^4.3.0 - checksum: 06d5c71e8313597722bc429ae2a7a8333d77bd3ab07ccb916628384b37332027b047f8619448d8f4a3312b6609c6ea3302a4e77435d859e9e686999e6699ca39 - languageName: node - linkType: hard - "http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0, http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -30205,13 +26580,27 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.0": - version: 7.0.0 - resolution: "http-proxy-agent@npm:7.0.0" +"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" dependencies: agent-base: ^7.1.0 debug: ^4.3.4 - checksum: 48d4fac997917e15f45094852b63b62a46d0c8a4f0b9c6c23ca26d27b8df8d178bed88389e604745e748bd9a01f5023e25093722777f0593c3f052009ff438b6 + checksum: 670858c8f8f3146db5889e1fa117630910101db601fff7d5a8aa637da0abedf68c899f03d3451cac2f83bcc4c3d2dabf339b3aa00ff8080571cceb02c3ce02f3 + languageName: node + linkType: hard + +"http-proxy-middleware@npm:*": + version: 3.0.0 + resolution: "http-proxy-middleware@npm:3.0.0" + dependencies: + "@types/http-proxy": ^1.17.10 + debug: ^4.3.4 + http-proxy: ^1.18.1 + is-glob: ^4.0.1 + is-plain-obj: ^3.0.0 + micromatch: ^4.0.5 + checksum: 2c286f0604f7a08af707a8df8e6f043fca022e55df6f7f843ea48081c9288277fc7fd7196446a7c8e8568dd1db8bf89f1555b2bc8a11bda87123f9f28aebd3a5 languageName: node linkType: hard @@ -30289,6 +26678,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:7.0.4, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2, https-proxy-agent@npm:^7.0.3": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: ^7.0.2 + debug: 4 + checksum: daaab857a967a2519ddc724f91edbbd388d766ff141b9025b629f92b9408fc83cee8a27e11a907aede392938e9c398e240d643e178408a59e4073539cde8cfe9 + languageName: node + linkType: hard + "https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" @@ -30299,16 +26698,6 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": - version: 7.0.2 - resolution: "https-proxy-agent@npm:7.0.2" - dependencies: - agent-base: ^7.0.2 - debug: 4 - checksum: 088969a0dd476ea7a0ed0a2cf1283013682b08f874c3bc6696c83fa061d2c157d29ef0ad3eb70a2046010bb7665573b2388d10fdcb3e410a66995e5248444292 - languageName: node - linkType: hard - "human-id@npm:^1.0.2": version: 1.0.2 resolution: "human-id@npm:1.0.2" @@ -30330,10 +26719,10 @@ __metadata: languageName: node linkType: hard -"humanize-duration@npm:^3.25.1, humanize-duration@npm:^3.26.0, humanize-duration@npm:^3.27.0, humanize-duration@npm:^3.27.1": - version: 3.31.0 - resolution: "humanize-duration@npm:3.31.0" - checksum: a21b1c80d43580c28fef07213846f74703c467270d41b774faeb4df6041b1da65effc554346fe6f0a70c4096b011d75f2ba6c2fd254b5a3c93231d85910533fe +"humanize-duration@npm:^3.25.1": + version: 3.32.0 + resolution: "humanize-duration@npm:3.32.0" + checksum: fd12af03045278c24542d2222d46831f74d21a2132bba053d4847ff8c8f6799840db6ff8a14ce24cc920f69633970fbde4f83d7cbcfed26806ed21804e72a03a languageName: node linkType: hard @@ -30355,7 +26744,7 @@ __metadata: languageName: node linkType: hard -"hyphenate-style-name@npm:^1.0.2, hyphenate-style-name@npm:^1.0.3": +"hyphenate-style-name@npm:^1.0.3": version: 1.0.3 resolution: "hyphenate-style-name@npm:1.0.3" checksum: e333f610e7cb32210861ff8c55f99582cdc39e4737903936a7eb61702c98f8db45f33d54f9d230221fabc4d321b2ab8382b8af50d24a1eba21916f2edddd7b85 @@ -30467,14 +26856,7 @@ __metadata: languageName: node linkType: hard -"immer@npm:9.0.7": - version: 9.0.7 - resolution: "immer@npm:9.0.7" - checksum: 3655ad64bf5ab5adf2854f7d2a9ad543f2cd995fcd169b6f10294f41fdb2cbcbd44d8beaa3e01b3c0b6149001190e57f6ab2cd735e6a929780b7462f2e973c9b - languageName: node - linkType: hard - -"immer@npm:^9.0.1, immer@npm:^9.0.6, immer@npm:^9.0.7": +"immer@npm:^9.0.6, immer@npm:^9.0.7": version: 9.0.21 resolution: "immer@npm:9.0.21" checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432 @@ -30549,15 +26931,6 @@ __metadata: languageName: node linkType: hard -"indefinite-observable@npm:^1.0.1": - version: 1.0.2 - resolution: "indefinite-observable@npm:1.0.2" - dependencies: - symbol-observable: 1.2.0 - checksum: 69a337967f48fca18989f9d68ad98c7220ed9b499bf00330ff72669a9583cb7f8e82f801da10720f720edf1313f427c77ce793350bdc413c952cec8ce112fc12 - languageName: node - linkType: hard - "indent-string@npm:^4.0.0": version: 4.0.0 resolution: "indent-string@npm:4.0.0" @@ -30671,21 +27044,14 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.5": - version: 1.0.5 - resolution: "internal-slot@npm:1.0.5" +"internal-slot@npm:^1.0.5, internal-slot@npm:^1.0.7": + version: 1.0.7 + resolution: "internal-slot@npm:1.0.7" dependencies: - get-intrinsic: ^1.2.0 - has: ^1.0.3 + es-errors: ^1.3.0 + hasown: ^2.0.0 side-channel: ^1.0.4 - checksum: 97e84046bf9e7574d0956bd98d7162313ce7057883b6db6c5c7b5e5f05688864b0978ba07610c726d15d66544ffe4b1050107d93f8a39ebc59b15d8b429b497a - languageName: node - linkType: hard - -"internmap@npm:1 - 2": - version: 2.0.3 - resolution: "internmap@npm:2.0.3" - checksum: 7ca41ec6aba8f0072fc32fa8a023450a9f44503e2d8e403583c55714b25efd6390c38a87161ec456bf42d7bc83aab62eb28f5aef34876b1ac4e60693d5e1d241 + checksum: cadc5eea5d7d9bc2342e93aae9f31f04c196afebb11bde97448327049f492cd7081e18623ae71388aac9cd237b692ca3a105be9c68ac39c1dec679d7409e33eb languageName: node linkType: hard @@ -30740,9 +27106,9 @@ __metadata: linkType: hard "ip@npm:^1.1.8": - version: 1.1.8 - resolution: "ip@npm:1.1.8" - checksum: a2ade53eb339fb0cbe9e69a44caab10d6e3784662285eb5d2677117ee4facc33a64679051c35e0dfdb1a3983a51ce2f5d2cb36446d52e10d01881789b76e28fb + version: 1.1.9 + resolution: "ip@npm:1.1.9" + checksum: b6d91fd45a856e3bd6d4f601ea0619d90f3517638f6918ebd079f959a8a6308568d8db5ef4fdf037e0d9cfdcf264f46833dfeea81ca31309cf0a7eb4b1307b84 languageName: node linkType: hard @@ -30760,10 +27126,10 @@ __metadata: languageName: node linkType: hard -"ipaddr.js@npm:^2.0.1": - version: 2.0.1 - resolution: "ipaddr.js@npm:2.0.1" - checksum: dd194a394a843d470f88d17191b0948f383ed1c8e320813f850c336a0fcb5e9215d97ec26ca35ab4fbbd31392c8b3467f3e8344628029ed3710b2ff6b5d1034e +"ipaddr.js@npm:^2.1.0": + version: 2.1.0 + resolution: "ipaddr.js@npm:2.1.0" + checksum: 807a054f2bd720c4d97ee479d6c9e865c233bea21f139fb8dabd5a35c4226d2621c42e07b4ad94ff3f82add926a607d8d9d37c625ad0319f0e08f9f2bd1968e2 languageName: node linkType: hard @@ -30817,7 +27183,7 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.0, is-arguments@npm:^1.1.1": +"is-arguments@npm:^1.0.4": version: 1.1.1 resolution: "is-arguments@npm:1.1.1" dependencies: @@ -30827,14 +27193,13 @@ __metadata: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.1, is-array-buffer@npm:^3.0.2": - version: 3.0.2 - resolution: "is-array-buffer@npm:3.0.2" +"is-array-buffer@npm:^3.0.4": + version: 3.0.4 + resolution: "is-array-buffer@npm:3.0.4" dependencies: call-bind: ^1.0.2 - get-intrinsic: ^1.2.0 - is-typed-array: ^1.1.10 - checksum: dcac9dda66ff17df9cabdc58214172bf41082f956eab30bb0d86bc0fab1e44b690fc8e1f855cf2481245caf4e8a5a006a982a71ddccec84032ed41f9d8da8c14 + get-intrinsic: ^1.2.1 + checksum: e4e3e6ef0ff2239e75371d221f74bc3c26a03564a22efb39f6bb02609b598917ddeecef4e8c877df2a25888f247a98198959842a5e73236bc7f22cabdf6351a7 languageName: node linkType: hard @@ -30930,7 +27295,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.1.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": +"is-core-module@npm:^2.1.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1, is-core-module@npm:^2.8.1": version: 2.13.1 resolution: "is-core-module@npm:2.13.1" dependencies: @@ -30939,6 +27304,15 @@ __metadata: languageName: node linkType: hard +"is-data-view@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-view@npm:1.0.1" + dependencies: + is-typed-array: ^1.1.13 + checksum: 4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 + languageName: node + linkType: hard + "is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" @@ -30971,6 +27345,15 @@ __metadata: languageName: node linkType: hard +"is-docker@npm:^3.0.0": + version: 3.0.0 + resolution: "is-docker@npm:3.0.0" + bin: + is-docker: cli.js + checksum: b698118f04feb7eaf3338922bd79cba064ea54a1c3db6ec8c0c8d8ee7613e7e5854d802d3ef646812a8a3ace81182a085dfa0a71cc68b06f3fa794b9783b3c90 + languageName: node + linkType: hard + "is-elevated@npm:^3.0.0": version: 3.0.0 resolution: "is-elevated@npm:3.0.0" @@ -31066,6 +27449,17 @@ __metadata: languageName: node linkType: hard +"is-inside-container@npm:^1.0.0": + version: 1.0.0 + resolution: "is-inside-container@npm:1.0.0" + dependencies: + is-docker: ^3.0.0 + bin: + is-inside-container: cli.js + checksum: c50b75a2ab66ab3e8b92b3bc534e1ea72ca25766832c0623ac22d134116a98bcf012197d1caabe1d1c4bd5f84363d4aa5c36bb4b585fbcaf57be172cd10a1a03 + languageName: node + linkType: hard + "is-installed-globally@npm:^0.4.0": version: 0.4.0 resolution: "is-installed-globally@npm:0.4.0" @@ -31097,7 +27491,7 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.1, is-map@npm:^2.0.2": +"is-map@npm:^2.0.1": version: 2.0.2 resolution: "is-map@npm:2.0.2" checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 @@ -31121,10 +27515,17 @@ __metadata: languageName: node linkType: hard -"is-negative-zero@npm:^2.0.2": - version: 2.0.2 - resolution: "is-negative-zero@npm:2.0.2" - checksum: f3232194c47a549da60c3d509c9a09be442507616b69454716692e37ae9f37c4dea264fb208ad0c9f3efd15a796a46b79df07c7e53c6227c32170608b809149a +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: c1e6b23d2070c0539d7b36022d5a94407132411d01aba39ec549af824231f3804b1aea90b5e4e58e807a65d23ceb538ed6e355ce76b267bdd86edb757ffcbdcd + languageName: node + linkType: hard + +"is-network-error@npm:^1.0.0": + version: 1.0.1 + resolution: "is-network-error@npm:1.0.1" + checksum: 165d61500c4186c62db5a3a693d6bfa14ca40fe9b471ef4cd4f27b20ef6760880faf5386dc01ca9867531631782941fedaa94521d09959edf71f046e393c7b91 languageName: node linkType: hard @@ -31207,10 +27608,10 @@ __metadata: languageName: node linkType: hard -"is-plain-obj@npm:^4.0.0": - version: 4.0.0 - resolution: "is-plain-obj@npm:4.0.0" - checksum: a6bb55a90636345a64c6153b74d85a9b6440f9975f4dcc57eed596c280b7ba228c71c406355a3147ed0488330d2743d5756e052c9492b1aa4f7dcd281f08c4b6 +"is-plain-obj@npm:^4.0.0, is-plain-obj@npm:^4.1.0": + version: 4.1.0 + resolution: "is-plain-obj@npm:4.1.0" + checksum: 6dc45da70d04a81f35c9310971e78a6a3c7a63547ef782e3a07ee3674695081b6ca4e977fbb8efc48dae3375e0b34558d2bcd722aec9bddfa2d7db5b041be8ce languageName: node linkType: hard @@ -31314,19 +27715,19 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.1, is-set@npm:^2.0.2": +"is-set@npm:^2.0.1": version: 2.0.2 resolution: "is-set@npm:2.0.2" checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 languageName: node linkType: hard -"is-shared-array-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "is-shared-array-buffer@npm:1.0.2" +"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "is-shared-array-buffer@npm:1.0.3" dependencies: - call-bind: ^1.0.2 - checksum: 9508929cf14fdc1afc9d61d723c6e8d34f5e117f0bffda4d97e7a5d88c3a8681f633a74f8e3ad1fe92d5113f9b921dc5ca44356492079612f9a247efbce7032a + call-bind: ^1.0.7 + checksum: a4fff602c309e64ccaa83b859255a43bb011145a42d3f56f67d9268b55bc7e6d98a5981a1d834186ad3105d6739d21547083fe7259c76c0468483fc538e716d8 languageName: node linkType: hard @@ -31339,7 +27740,7 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^1.0.1, is-stream@npm:^1.1.0": +"is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" checksum: 063c6bec9d5647aa6d42108d4c59723d2bd4ae42135a2d4db6eadbd49b7ea05b750fd69d279e5c7c45cf9da753ad2c00d8978be354d65aa9f6bb434969c6a2ae @@ -31387,12 +27788,12 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.12, is-typed-array@npm:^1.1.3, is-typed-array@npm:^1.1.9": - version: 1.1.12 - resolution: "is-typed-array@npm:1.1.12" +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.3": + version: 1.1.13 + resolution: "is-typed-array@npm:1.1.13" dependencies: - which-typed-array: ^1.1.11 - checksum: 4c89c4a3be07186caddadf92197b17fda663a9d259ea0d44a85f171558270d36059d1c386d34a12cba22dfade5aba497ce22778e866adc9406098c8fc4771796 + which-typed-array: ^1.1.14 + checksum: 150f9ada183a61554c91e1c4290086d2c100b0dff45f60b028519be72a8db964da403c48760723bf5253979b8dffe7b544246e0e5351dcd05c5fdb1dcc1dc0f0 languageName: node linkType: hard @@ -31466,6 +27867,15 @@ __metadata: languageName: node linkType: hard +"is-wsl@npm:^3.1.0": + version: 3.1.0 + resolution: "is-wsl@npm:3.1.0" + dependencies: + is-inside-container: ^1.0.0 + checksum: f9734c81f2f9cf9877c5db8356bfe1ff61680f1f4c1011e91278a9c0564b395ae796addb4bf33956871041476ec82c3e5260ed57b22ac91794d4ae70a1d2f0a9 + languageName: node + linkType: hard + "is-yarn-global@npm:^0.3.0": version: 0.3.0 resolution: "is-yarn-global@npm:0.3.0" @@ -31494,7 +27904,7 @@ __metadata: languageName: node linkType: hard -"isbinaryfile@npm:^4.0.10, isbinaryfile@npm:^4.0.10 <5, isbinaryfile@npm:^4.0.8": +"isbinaryfile@npm:^4.0.10, isbinaryfile@npm:^4.0.8": version: 4.0.10 resolution: "isbinaryfile@npm:4.0.10" checksum: a6b28db7e23ac7a77d3707567cac81356ea18bd602a4f21f424f862a31d0e7ab4f250759c98a559ece35ffe4d99f0d339f1ab884ffa9795172f632ab8f88e686 @@ -31550,16 +27960,6 @@ __metadata: languageName: node linkType: hard -"isomorphic-fetch@npm:^2.1.1": - version: 2.2.1 - resolution: "isomorphic-fetch@npm:2.2.1" - dependencies: - node-fetch: ^1.0.1 - whatwg-fetch: ">=0.10.0" - checksum: bb5daa7c3785d6742f4379a81e55b549a469503f7c9bf9411b48592e86632cf5e8fe8ea878dba185c0f33eb7c510c23abdeb55aebfdf5d3c70f031ced68c5424 - languageName: node - linkType: hard - "isomorphic-form-data@npm:^2.0.0": version: 2.0.0 resolution: "isomorphic-form-data@npm:2.0.0" @@ -31570,8 +27970,8 @@ __metadata: linkType: hard "isomorphic-git@npm:^1.23.0": - version: 1.25.4 - resolution: "isomorphic-git@npm:1.25.4" + version: 1.25.7 + resolution: "isomorphic-git@npm:1.25.7" dependencies: async-lock: ^1.1.0 clean-git-ref: ^2.0.1 @@ -31586,7 +27986,7 @@ __metadata: simple-get: ^4.0.1 bin: isogit: cli.cjs - checksum: 86ed42b7d15db04af5a1918b7cf50153e688a2aabd5d77a6a5f2a1798bb476aef265edd3bb3d80058929d70cd0c23247074760a48720bbba9e76b044881e6d6c + checksum: 6655c70c8c9974c907f6ca864ca16b0aed113ca8b6f50de4858a624b2ed66633a83ce64ca8935f370e328a29bc37811447eb7494be379388123feb811e867459 languageName: node linkType: hard @@ -31748,15 +28148,6 @@ __metadata: languageName: node linkType: hard -"jenkins@npm:^1.0.0": - version: 1.1.0 - resolution: "jenkins@npm:1.1.0" - dependencies: - papi: ^1.1.0 - checksum: 3aada79e2e081926f2d335320e3993a39605124a22c0429c2acd6d4dd3bd5ccded9c6e03fb84f120ebb0755f9e70d931a7ffb36aaa18bc73d7ca3b7f2a5391e6 - languageName: node - linkType: hard - "jest-changed-files@npm:^29.7.0": version: 29.7.0 resolution: "jest-changed-files@npm:29.7.0" @@ -31869,25 +28260,6 @@ __metadata: languageName: node linkType: hard -"jest-date-mock@npm:^1.0.8": - version: 1.0.8 - resolution: "jest-date-mock@npm:1.0.8" - checksum: 7b012870440b0df742d0b651435b91625dbbf02d916633a0c70c7deb5d5087f9aadc59847602312368826325909e70e95cd412896a0c9ee1d5ac382000bf5ef9 - languageName: node - linkType: hard - -"jest-diff@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-diff@npm:28.1.3" - dependencies: - chalk: ^4.0.0 - diff-sequences: ^28.1.1 - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: fa8583e0ccbe775714ce850b009be1b0f6b17a4b6759f33ff47adef27942ebc610dbbcc8a5f7cfb7f12b3b3b05afc9fb41d5f766674616025032ff1e4f9866e0 - languageName: node - linkType: hard - "jest-diff@npm:^29.2.0, jest-diff@npm:^29.7.0": version: 29.7.0 resolution: "jest-diff@npm:29.7.0" @@ -31957,13 +28329,6 @@ __metadata: languageName: node linkType: hard -"jest-get-type@npm:^28.0.2": - version: 28.0.2 - resolution: "jest-get-type@npm:28.0.2" - checksum: 5281d7c89bc8156605f6d15784f45074f4548501195c26e9b188742768f72d40948252d13230ea905b5349038865a1a8eeff0e614cc530ff289dfc41fe843abd - languageName: node - linkType: hard - "jest-get-type@npm:^29.6.3": version: 29.6.3 resolution: "jest-get-type@npm:29.6.3" @@ -31996,7 +28361,7 @@ __metadata: "jest-haste-map@patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch::locator=root%40workspace%3A.": version: 29.7.0 - resolution: "jest-haste-map@patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch::version=29.7.0&hash=c4774f&locator=root%40workspace%3A." + resolution: "jest-haste-map@patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch::version=29.7.0&hash=feed88&locator=root%40workspace%3A." dependencies: "@jest/types": ^29.6.3 "@types/graceful-fs": ^4.1.3 @@ -32027,18 +28392,6 @@ __metadata: languageName: node linkType: hard -"jest-matcher-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-matcher-utils@npm:28.1.3" - dependencies: - chalk: ^4.0.0 - jest-diff: ^28.1.3 - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: 6b34f0cf66f6781e92e3bec97bf27796bd2ba31121e5c5997218d9adba6deea38a30df5203937d6785b68023ed95cbad73663cc9aad6fb0cb59aeb5813a58daf - languageName: node - linkType: hard - "jest-matcher-utils@npm:^29.7.0": version: 29.7.0 resolution: "jest-matcher-utils@npm:29.7.0" @@ -32051,23 +28404,6 @@ __metadata: languageName: node linkType: hard -"jest-message-util@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-message-util@npm:28.1.3" - dependencies: - "@babel/code-frame": ^7.12.13 - "@jest/types": ^28.1.3 - "@types/stack-utils": ^2.0.0 - chalk: ^4.0.0 - graceful-fs: ^4.2.9 - micromatch: ^4.0.4 - pretty-format: ^28.1.3 - slash: ^3.0.0 - stack-utils: ^2.0.3 - checksum: 1f266854166dcc6900d75a88b54a25225a2f3710d463063ff1c99021569045c35c7d58557b25447a17eb3a65ce763b2f9b25550248b468a9d4657db365f39e96 - languageName: node - linkType: hard - "jest-message-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-message-util@npm:29.7.0" @@ -32229,20 +28565,6 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-util@npm:28.1.3" - dependencies: - "@jest/types": ^28.1.3 - "@types/node": "*" - chalk: ^4.0.0 - ci-info: ^3.2.0 - graceful-fs: ^4.2.9 - picomatch: ^2.2.3 - checksum: fd6459742c941f070223f25e38a2ac0719aad92561591e9fb2a50d602a5d19d754750b79b4074327a42b00055662b95da3b006542ceb8b54309da44d4a62e721 - languageName: node - linkType: hard - "jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" @@ -32317,7 +28639,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.5.0, jest-worker@npm:^29.7.0": +"jest-worker@npm:^29.7.0": version: 29.7.0 resolution: "jest-worker@npm:29.7.0" dependencies: @@ -32378,24 +28700,24 @@ __metadata: languageName: node linkType: hard -"jose@npm:^4.14.6, jose@npm:^4.15.4, jose@npm:^4.6.0": - version: 4.15.4 - resolution: "jose@npm:4.15.4" - checksum: dccad91cb3357f36423774a0b89ad830dd84b31090de65cd139b85488439f16a00f8c59c0773825e8a1adb0dd9d13ad725ad66e6ea33880ecb3959bb99e1ea5b +"jose@npm:^4.15.5": + version: 4.15.5 + resolution: "jose@npm:4.15.5" + checksum: 7dde76447c7707bd4b448f914b216f3858e701aa83f00447434252461af5b9e159dcbffb88badea3f9616739526763581267c9560622f0a058df8d68c86d7f79 languageName: node linkType: hard -"joycon@npm:^3.0.1": - version: 3.1.0 - resolution: "joycon@npm:3.1.0" - checksum: f21f17b46142f14c92cc99f5a157ebf224717a284c45e870452be5c5ebc3bb7e07e66692fc9da3a40f6b08106ac986dc9eae2f77977db62416fe47a99b0de0ac +"jose@npm:^5.0.0": + version: 5.2.4 + resolution: "jose@npm:5.2.4" + checksum: 81e1f4494f406debd14392975327f0daa8b88ff09c83f2fe94754dcd7cfdefdb1adf785b2ec7481751927e609d342581cd41cb444628ef62fca423facebcd280 languageName: node linkType: hard "js-base64@npm:^3.6.0": - version: 3.7.6 - resolution: "js-base64@npm:3.7.6" - checksum: 4e1e82443c22f3f8f24902b071ea824069a28a16a86c3d8706e8c0741cace92cfb4affd093f52d13981369e10df840e54df8d0a59ede6dd2204a1f0aa4b64deb + version: 3.7.7 + resolution: "js-base64@npm:3.7.7" + checksum: d1b02971db9dc0fd35baecfaf6ba499731fb44fe3373e7e1d6681fbd3ba665f29e8d9d17910254ef8104e2cb8b44117fe4202d3dc54c7cafe9ba300fe5433358 languageName: node linkType: hard @@ -32491,8 +28813,8 @@ __metadata: linkType: hard "jscodeshift@npm:^0.15.0": - version: 0.15.1 - resolution: "jscodeshift@npm:0.15.1" + version: 0.15.2 + resolution: "jscodeshift@npm:0.15.2" dependencies: "@babel/core": ^7.23.0 "@babel/parser": ^7.23.0 @@ -32521,7 +28843,7 @@ __metadata: optional: true bin: jscodeshift: bin/jscodeshift.js - checksum: d760dee2b634fa8a4610bdbdf787ce117a9a6bcc73e9ae55a38be77e380698d928d34a375a93ed4685e8bbdecfbd3cdbb87eb4b7e22fc58381db3d59fb554687 + checksum: e3fa018bfd0ee5b65da1b98797a2536ae8ff0185f0c0d11f9be11e27e1f25ab33a4e17cecc8b73ef520e5d9d8dade98abc49bc0835c024a0f1ff14b48288528b languageName: node linkType: hard @@ -32676,19 +28998,6 @@ __metadata: languageName: node linkType: hard -"json-rules-engine@npm:^6.1.2": - version: 6.5.0 - resolution: "json-rules-engine@npm:6.5.0" - dependencies: - clone: ^2.1.2 - eventemitter2: ^6.4.4 - hash-it: ^6.0.0 - jsonpath-plus: ^7.2.0 - lodash.isobjectlike: ^4.0.0 - checksum: c1a6fa2bb65743397c838c4e4a9157f184e0c24423031fa4bab6b83b5edbb64341f9197ccad9fdd44fcd6c58ac329c0c77882a64acf0d90ee1d856768a4154e3 - languageName: node - linkType: hard - "json-schema-compare@npm:^0.2.2": version: 0.2.2 resolution: "json-schema-compare@npm:0.2.2" @@ -32698,16 +29007,18 @@ __metadata: languageName: node linkType: hard -"json-schema-library@npm:^7.3.9": - version: 7.4.9 - resolution: "json-schema-library@npm:7.4.9" +"json-schema-library@npm:^9.0.0": + version: 9.3.4 + resolution: "json-schema-library@npm:9.3.4" dependencies: - "@sagold/json-pointer": ^5.1.1 - "@sagold/json-query": ^6.1.0 - deepmerge: ^4.2.2 + "@sagold/json-pointer": ^5.1.2 + "@sagold/json-query": ^6.1.3 + deepmerge: ^4.3.1 + fast-copy: ^3.0.2 fast-deep-equal: ^3.1.3 + smtp-address-parser: 1.0.10 valid-url: ^1.0.9 - checksum: 178a388bb7baf917a71ad369cfffa2952472e2bbffcdbc4711ed8b53b5d2b07aa882317c1479abc33c950667791047312fa1baa213502f128c38287cd726ff79 + checksum: 6e3accc45bdf0fe4831c8b2a560d8feaa9402bd6c5833a0c7e11ee78c316b17a389a3368a7ee2c989d4aac36018742d7dcc83c66b11170c54800b0e56418638f languageName: node linkType: hard @@ -32722,14 +29033,13 @@ __metadata: languageName: node linkType: hard -"json-schema-to-ts@npm:^2.6.2": - version: 2.12.0 - resolution: "json-schema-to-ts@npm:2.12.0" +"json-schema-to-ts@npm:^3.0.0": + version: 3.0.1 + resolution: "json-schema-to-ts@npm:3.0.1" dependencies: "@babel/runtime": ^7.18.3 - "@types/json-schema": ^7.0.9 ts-algebra: ^1.2.2 - checksum: 6dc4bc836591d888beb20e8bf45dfa3b75df4a331f18675bd2e39a2262e105e0dc86012031fff0be408499a07ae8bc30f5a879c24696189b2c30a34edd5fa72f + checksum: 32013ac5cc28b55d056d3241e50360f69fe86d7a6efeeed097e3b6c30c17d30e655b2565ff27d2e7cc232dcbcf9180f77556c154482b30a8d32bc428a0692c62 languageName: node linkType: hard @@ -32791,13 +29101,6 @@ __metadata: languageName: node linkType: hard -"json2xml@npm:^0.1.3": - version: 0.1.3 - resolution: "json2xml@npm:0.1.3" - checksum: 88954de67d88c5c1ea7ea99267da712aa5b78886df6db98ebbb63e3caa8310eb7c1c94fe72ba3a575f06813fd344725ddcb9cf1547e1223d1c141d3e24ad3cf9 - languageName: node - linkType: hard - "json5@npm:^1.0.1, json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" @@ -32818,7 +29121,7 @@ __metadata: languageName: node linkType: hard -"jsonc-parser@npm:^3.0.0, jsonc-parser@npm:^3.2.0": +"jsonc-parser@npm:^3.2.0": version: 3.2.0 resolution: "jsonc-parser@npm:3.2.0" checksum: 946dd9a5f326b745aa326d48a7257e3f4a4b62c5e98ec8e49fa2bdd8d96cef7e6febf1399f5c7016114fd1f68a1c62c6138826d5d90bc650448e3cf0951c53c7 @@ -32941,46 +29244,6 @@ __metadata: languageName: node linkType: hard -"jss-camel-case@npm:^6.0.0": - version: 6.1.0 - resolution: "jss-camel-case@npm:6.1.0" - dependencies: - hyphenate-style-name: ^1.0.2 - peerDependencies: - jss: ^9.7.0 - checksum: f20ad892cddc30241b5127d648233b513ce57b2a6ed2f710cd995510f8d06e1418cd8f6e8e50dc6bd60b2e8a35159bfdeb40143938e0f2cdc19fd39279953789 - languageName: node - linkType: hard - -"jss-default-unit@npm:^8.0.2": - version: 8.0.2 - resolution: "jss-default-unit@npm:8.0.2" - peerDependencies: - jss: ^9.4.0 - checksum: 5277c5ccc3d56f5c137d6d65f0fc36d15eb22ef08b5949e887ee75e9f4f25197e25f2a99706b70a2828cee010fd8ed7484fb1bb2086fe327f2b24b1bdcc22abb - languageName: node - linkType: hard - -"jss-global@npm:^3.0.0": - version: 3.0.0 - resolution: "jss-global@npm:3.0.0" - peerDependencies: - jss: ^9.0.0 - checksum: e3fa80d8251ba5f183d9b0b4416d64e8f5d285cfdb595cc600daf1a1366b67bca573939bb71d98b6596bf4d6f2c95711cf53a358af3d63cd7945dbb434c6547b - languageName: node - linkType: hard - -"jss-nested@npm:^6.0.1": - version: 6.0.1 - resolution: "jss-nested@npm:6.0.1" - dependencies: - warning: ^3.0.0 - peerDependencies: - jss: ^9.0.0 - checksum: 437bdacc559be0b4b5bc1faa2bc77b5c6cf14733fefbf73a34bb7335786b9f08e4e79b3d73cf83b386959adcd8fa9d725877912e96d9a0921ed38baa1a69b8d9 - languageName: node - linkType: hard - "jss-plugin-camel-case@npm:^10.10.0, jss-plugin-camel-case@npm:^10.5.1": version: 10.10.0 resolution: "jss-plugin-camel-case@npm:10.10.0" @@ -33055,26 +29318,6 @@ __metadata: languageName: node linkType: hard -"jss-props-sort@npm:^6.0.0": - version: 6.0.0 - resolution: "jss-props-sort@npm:6.0.0" - peerDependencies: - jss: ^9.0.0 - checksum: 82a04f625a2f2b3a71b2fcb00b1ed0478137c83dc47c323d24c7ea88d08c9ea295b061f99cf264db133fef3435366d6da594724f7713e0415dc50b4eff2aeb53 - languageName: node - linkType: hard - -"jss-vendor-prefixer@npm:^7.0.0": - version: 7.0.0 - resolution: "jss-vendor-prefixer@npm:7.0.0" - dependencies: - css-vendor: ^0.3.8 - peerDependencies: - jss: ^9.0.0 - checksum: 8ec3608711833e79da7ccfffd8177e752f16093589fa28d3a24ec19e6588fbc6a07cc5cacf59ef4c111ab1d0fb72e07b88cb3444eb8c0c6ed4cc8107da984633 - languageName: node - linkType: hard - "jss@npm:10.10.0, jss@npm:^10.10.0, jss@npm:^10.5.1, jss@npm:~10.10.0": version: 10.10.0 resolution: "jss@npm:10.10.0" @@ -33087,17 +29330,6 @@ __metadata: languageName: node linkType: hard -"jss@npm:^9.8.7": - version: 9.8.7 - resolution: "jss@npm:9.8.7" - dependencies: - is-in-browser: ^1.1.3 - symbol-observable: ^1.1.0 - warning: ^3.0.0 - checksum: ebb264cc893fb8c17a0277875947f8f72e01f5be991bf7f61a39abb861e1276e75ee402fdd2be9ce827af839a1a08bd81ad86a4e108d57fd7d7ebb2361837a53 - languageName: node - linkType: hard - "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -33185,13 +29417,6 @@ __metadata: languageName: node linkType: hard -"kafkajs@npm:^2.0.0": - version: 2.2.4 - resolution: "kafkajs@npm:2.2.4" - checksum: 83e9e8bc50a09b142f4ff79f6a2bd88ecc21b83bcefe6621ab1716118d624886befb7371731274f67812ce35dd50b53140ff3b49a06e5d9169fe6b164d72fea5 - languageName: node - linkType: hard - "keyv@npm:^3.0.0": version: 3.1.0 resolution: "keyv@npm:3.1.0" @@ -33280,15 +29505,15 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.0.1 - resolution: "knip@npm:5.0.1" + version: 5.9.4 + resolution: "knip@npm:5.9.4" dependencies: "@ericcornelissen/bash-parser": 0.5.2 "@nodelib/fs.walk": 2.0.0 - "@npmcli/map-workspaces": 3.0.4 - "@npmcli/package-json": 5.0.0 + "@npmcli/map-workspaces": ^3.0.4 + "@npmcli/package-json": ^5.0.0 "@pnpm/logger": 5.0.0 - "@pnpm/workspace.pkgs-graph": ^2.0.14 + "@pnpm/workspace.pkgs-graph": 2.0.14 "@snyk/github-codeowners": 1.1.0 "@types/picomatch": 2.3.3 easy-table: 1.2.0 @@ -33298,20 +29523,20 @@ __metadata: micromatch: 4.0.5 minimist: 1.2.8 picocolors: 1.0.0 - picomatch: 4.0.1 + picomatch: ^4.0.1 pretty-ms: 9.0.0 - semver: 7.6.0 + resolve: 1.22.8 smol-toml: 1.1.4 strip-json-comments: 5.0.1 summary: 2.1.0 - zod: 3.22.4 - zod-validation-error: 3.0.0 + zod: ^3.22.4 + zod-validation-error: ^3.0.3 peerDependencies: "@types/node": ">=18" typescript: ">=5.0.4" bin: knip: bin/knip.js - checksum: d4d97e44c45d0c7b2b0c86495e6337d89cd94e005a4d29190498f29dc61945d51be2e6d2373b53104a98949c6b1eb9ca71f24f58526459d6118ea72713536ad4 + checksum: 112f93982090c8947bd28904ad835b4b2793f9ee23fcb895ba0815e759d6b644e9d6ff6d6661af56ecbebb2f6bff21e4e3afcccce93df778aadf9c6d52ca9541 languageName: node linkType: hard @@ -33334,13 +29559,6 @@ __metadata: languageName: node linkType: hard -"ky@npm:0.28.7": - version: 0.28.7 - resolution: "ky@npm:0.28.7" - checksum: ff38c9c5a5b9c0354b9db167662cdb1fc48c91803a580807a1d18a1fccc024953cba3708e7bcbd9c7a27670c68631d4806e2c5a169ebc586e573a7c5802a6086 - languageName: node - linkType: hard - "language-subtag-registry@npm:^0.3.20": version: 0.3.22 resolution: "language-subtag-registry@npm:0.3.22" @@ -33366,13 +29584,13 @@ __metadata: languageName: node linkType: hard -"launch-editor@npm:^2.6.0": - version: 2.6.0 - resolution: "launch-editor@npm:2.6.0" +"launch-editor@npm:^2.6.1": + version: 2.6.1 + resolution: "launch-editor@npm:2.6.1" dependencies: picocolors: ^1.0.0 - shell-quote: ^1.7.3 - checksum: 48e4230643e8fdb5c14c11314706d58d9f3fbafe2606be3d6e37da1918ad8bfe39dd87875c726a1b59b9f4da99d87ec3e36d4c528464f0b820f9e91e5cb1c02d + shell-quote: ^1.8.1 + checksum: e06d193075ac09f7f8109f10cabe464a211bf7ed4cbe75f83348d6f67bf4d9f162f06e7a1ab3e1cd7fc250b5342c3b57080618aff2e646dc34248fe499227601 languageName: node linkType: hard @@ -33394,7 +29612,7 @@ __metadata: languageName: node linkType: hard -"ldapjs@npm:^2.2.0": +"ldapjs@npm:^2.3.3": version: 2.3.3 resolution: "ldapjs@npm:2.3.3" dependencies: @@ -33410,28 +29628,6 @@ __metadata: languageName: node linkType: hard -"leasot@npm:^12.0.0": - version: 12.5.0 - resolution: "leasot@npm:12.5.0" - dependencies: - async: ^3.2.0 - chalk: ^4.1.0 - commander: ^7.2.0 - eol: ^0.9.1 - get-stdin: ^8.0.0 - globby: ^11.0.3 - json2xml: ^0.1.3 - lodash: ^4.17.21 - log-symbols: ^4.1.0 - strip-ansi: ^6.0.0 - text-table: ^0.2.0 - bin: - leasot: bin/leasot - leasot-reporter: bin/leasot-reporter - checksum: 1f27381bafc226f4242ec4bd907229d68a45be79463f26a8b7b41179212841668f49b1ee8b675b48f9452f6222c91fafe6e4eccb01b5004ec1a806d75d372b7c - languageName: node - linkType: hard - "leven@npm:2.1.0": version: 2.1.0 resolution: "leven@npm:2.1.0" @@ -33519,25 +29715,6 @@ __metadata: languageName: node linkType: hard -"linguist-js@npm:^2.5.3": - version: 2.6.1 - resolution: "linguist-js@npm:2.6.1" - dependencies: - binary-extensions: ^2.2.0 - commander: ^9.5.0 <10 - common-path-prefix: ^3.0.0 - cross-fetch: ^3.1.8 <4 - ignore: ^5.2.4 - isbinaryfile: ^4.0.10 <5 - js-yaml: ^4.1.0 - node-cache: ^5.1.2 - bin: - linguist: bin/index.js - linguist-js: bin/index.js - checksum: 5eea5a0562e4a8958703833eef0377235fd34da1f12b7b8b8208934b877c9f36b7c140b25c66ab563ff229203cd8c224e84d840edbc4ee285ad051b8b8fdb5ae - languageName: node - linkType: hard - "linkify-it@npm:^3.0.1": version: 3.0.2 resolution: "linkify-it@npm:3.0.2" @@ -33840,13 +30017,6 @@ __metadata: languageName: node linkType: hard -"lodash.isobjectlike@npm:^4.0.0": - version: 4.0.0 - resolution: "lodash.isobjectlike@npm:4.0.0" - checksum: eabcd968b1bd11208a90b27f9b167bd5ce30165a5b20d7886b94df95acfbc929dbe00cf16f2ce7a7779bdaf3f0ef4ee705e671782599ab73097307d2b8b488c5 - languageName: node - linkType: hard - "lodash.isplainobject@npm:^4.0.6": version: 4.0.6 resolution: "lodash.isplainobject@npm:4.0.6" @@ -33924,7 +30094,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.16.4, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0, lodash@npm:~4.17.15, lodash@npm:~4.17.21": +"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.16.4, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0, lodash@npm:~4.17.15, lodash@npm:~4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -34008,17 +30178,10 @@ __metadata: languageName: node linkType: hard -"long@npm:^4.0.0": - version: 4.0.0 - resolution: "long@npm:4.0.0" - checksum: 16afbe8f749c7c849db1f4de4e2e6a31ac6e617cead3bdc4f9605cb703cd20e1e9fc1a7baba674ffcca57d660a6e5b53a9e236d7b25a295d3855cca79cc06744 - languageName: node - linkType: hard - -"long@npm:^5.0.0": - version: 5.2.0 - resolution: "long@npm:5.2.0" - checksum: 37aa4e67b9c3eebc6d9d675adcc9d06f06059ca268922a71273de389746bf07f0ff282f9e604d17fdf84c4149099b44e936ea2b621a6c4759a216621afa97efd +"long@npm:^5.0.0, long@npm:^5.2.1": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 languageName: node linkType: hard @@ -34080,7 +30243,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^4.0.1, lru-cache@npm:^4.1.3": +"lru-cache@npm:^4.0.1": version: 4.1.5 resolution: "lru-cache@npm:4.1.5" dependencies: @@ -34108,13 +30271,20 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^7.14.0, lru-cache@npm:^7.7.1": +"lru-cache@npm:^7.14.0, lru-cache@npm:^7.14.1, lru-cache@npm:^7.7.1": version: 7.18.3 resolution: "lru-cache@npm:7.18.3" checksum: e550d772384709deea3f141af34b6d4fa392e2e418c1498c078de0ee63670f1f46f5eee746e8ef7e69e1c895af0d4224e62ee33e66a543a14763b0f2e74c1356 languageName: node linkType: hard +"lru-cache@npm:^8.0.0": + version: 8.0.5 + resolution: "lru-cache@npm:8.0.5" + checksum: 87d72196d8f46e8299c4ab576ed2ec8a07e3cbef517dc9874399c0b2470bd9bf62aacec3b67f84ed6d74aaa1ef31636d048edf996f76248fd17db72bfb631609 + languageName: node + linkType: hard + "lru-cache@npm:^9.0.0": version: 9.1.2 resolution: "lru-cache@npm:9.1.2" @@ -34145,14 +30315,7 @@ __metadata: languageName: node linkType: hard -"luxon@npm:^2.0.2": - version: 2.5.2 - resolution: "luxon@npm:2.5.2" - checksum: d8b671ffd2ff0b438af862ac11082a81b3aedd9f8b6a4ca636f944224f8dd381125cd4d274ca0a8aedcaf2cfca0fc2ca96fe4cc1b16a28b7af701afb95c0bff8 - languageName: node - linkType: hard - -"luxon@npm:^3.0.0, luxon@npm:^3.3.0, luxon@npm:^3.4.3, luxon@npm:~3.4.0": +"luxon@npm:^3.0.0, luxon@npm:^3.4.3, luxon@npm:~3.4.0": version: 3.4.4 resolution: "luxon@npm:3.4.4" checksum: 36c1f99c4796ee4bfddf7dc94fa87815add43ebc44c8934c924946260a58512f0fd2743a629302885df7f35ccbd2d13f178c15df046d0e3b6eb71db178f1c60c @@ -34186,21 +30349,12 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.26.6": - version: 0.26.7 - resolution: "magic-string@npm:0.26.7" - dependencies: - sourcemap-codec: ^1.4.8 - checksum: 89b0d60cbb32bbf3d1e23c46ea93db082d18a8230b972027aecb10a40bba51be519ecce0674f995571e3affe917b76b09f59d8dbc9a1b2c9c4102a2b6e8a2b01 - languageName: node - linkType: hard - -"magic-string@npm:^0.30.3": - version: 0.30.5 - resolution: "magic-string@npm:0.30.5" +"magic-string@npm:^0.30.3, magic-string@npm:^0.30.4": + version: 0.30.8 + resolution: "magic-string@npm:0.30.8" dependencies: "@jridgewell/sourcemap-codec": ^1.4.15 - checksum: da10fecff0c0a7d3faf756913ce62bd6d5e7b0402be48c3b27bfd651b90e29677e279069a63b764bcdc1b8ecdcdb898f29a5c5ec510f2323e8d62ee057a6eb18 + checksum: 79922f4500d3932bb587a04440d98d040170decf432edc0f91c0bf8d41db16d364189bf800e334170ac740918feda62cd39dcc170c337dc18050cfcf00a5f232 languageName: node linkType: hard @@ -34409,20 +30563,6 @@ __metadata: languageName: node linkType: hard -"material-ui-search-bar@npm:^1.0.0": - version: 1.0.1 - resolution: "material-ui-search-bar@npm:1.0.1" - dependencies: - classnames: ^2.2.5 - prop-types: ^15.5.8 - peerDependencies: - "@material-ui/core": ^4.0.0 - "@material-ui/icons": ^4.0.0 - react: ">=16.8.0" - checksum: f2bbc90471bdf3734d704b164857eb2b5c7f30dbe5ee362b448d8362fbfe152f1d1d5280fe4bf44624dc6135782ef58f63cf488ecb82f3392e0090757a767175 - languageName: node - linkType: hard - "md5.js@npm:^1.3.4": version: 1.3.5 resolution: "md5.js@npm:1.3.5" @@ -34600,7 +30740,7 @@ __metadata: languageName: node linkType: hard -"mdurl@npm:^1.0.0, mdurl@npm:^1.0.1, mdurl@npm:~1.0.1": +"mdurl@npm:^1.0.0, mdurl@npm:^1.0.1": version: 1.0.1 resolution: "mdurl@npm:1.0.1" checksum: 71731ecba943926bfbf9f9b51e28b5945f9411c4eda80894221b47cc105afa43ba2da820732b436f0798fd3edbbffcd1fc1415843c41a87fea08a41cc1e3d02b @@ -34677,11 +30817,20 @@ __metadata: linkType: hard "memfs@npm:^3.1.2, memfs@npm:^3.4.1": - version: 3.4.1 - resolution: "memfs@npm:3.4.1" + version: 3.5.3 + resolution: "memfs@npm:3.5.3" dependencies: - fs-monkey: 1.0.3 - checksum: 6d2f49d447d1be24ff9c747618933784eeb059189bc6a0d77b7a51c7daf06e2d3a74674a2e2ff1520e2c312bf91e719ed37144cf05087379b3ba0aef0b6aa062 + fs-monkey: ^1.0.4 + checksum: 18dfdeacad7c8047b976a6ccd58bc98ba76e122ad3ca0e50a21837fe2075fc0d9aafc58ab9cf2576c2b6889da1dd2503083f2364191b695273f40969db2ecc44 + languageName: node + linkType: hard + +"memfs@npm:^4.6.0": + version: 4.7.7 + resolution: "memfs@npm:4.7.7" + dependencies: + tslib: ^2.0.0 + checksum: 060d54fba6103ad19cda65a5e416527fdf3ca1d756e9bb250f176a2628fbfa96da647c8d1567c575f241ab1a6362caac1a318091159657432094089cf6dac16f languageName: node linkType: hard @@ -34741,6 +30890,13 @@ __metadata: languageName: node linkType: hard +"merge-descriptors@npm:^1.0.1": + version: 1.0.3 + resolution: "merge-descriptors@npm:1.0.3" + checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -35156,7 +31312,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:2.1.35, mime-types@npm:^2.0.8, mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -35165,7 +31321,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:1.6.0": +"mime@npm:1.6.0, mime@npm:^1.3.4": version: 1.6.0 resolution: "mime@npm:1.6.0" bin: @@ -35242,14 +31398,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.4.2": - version: 2.8.0 - resolution: "mini-css-extract-plugin@npm:2.8.0" + version: 2.9.0 + resolution: "mini-css-extract-plugin@npm:2.9.0" dependencies: schema-utils: ^4.0.0 tapable: ^2.2.1 peerDependencies: webpack: ^5.0.0 - checksum: c1edc3ee0e1b3514c3323fa72ad38e993f357964e76737f1d7bb6cf50a0af1ac071080ec16b4e1a94688d23f78533944badad50cd0f00d2ae176f9c58c1f2029 + checksum: ae192c67ba85ac8bffeab66774635bf90181f00d5dd6cf95412426192599ddf5506fb4b1550acbd7a5476476e39db53c770dd40f8378f7baf5de96e3fec4e6e9 languageName: node linkType: hard @@ -35285,7 +31441,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:9.0.3, minimatch@npm:^9.0.0, minimatch@npm:^9.0.1, minimatch@npm:^9.0.3": +"minimatch@npm:9.0.3": version: 9.0.3 resolution: "minimatch@npm:9.0.3" dependencies: @@ -35303,7 +31459,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.0, minimatch@npm:^5.0.1, minimatch@npm:^5.1.0, minimatch@npm:^5.1.1, minimatch@npm:^5.1.2": +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": version: 5.1.6 resolution: "minimatch@npm:5.1.6" dependencies: @@ -35321,6 +31477,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.1, minimatch@npm:^9.0.3": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" + dependencies: + brace-expansion: ^2.0.1 + checksum: cf717f597ec3eed7dabc33153482a2e8d49f4fd3c26e58fd9c71a94c5029a0838728841b93f46bf1263b65a8010e2ee800d0dc9b004ab8ba8b6d1ec07cc115b5 + languageName: node + linkType: hard + "minimist-options@npm:^4.0.2": version: 4.1.0 resolution: "minimist-options@npm:4.1.0" @@ -35332,7 +31497,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:1.2.8, minimist@npm:>=1.2.2, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6": +"minimist@npm:1.2.8, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -35481,10 +31646,10 @@ __metadata: languageName: node linkType: hard -"mitt@npm:^3.0.0": - version: 3.0.0 - resolution: "mitt@npm:3.0.0" - checksum: f7be5049d27d18b1dbe9408452d66376fa60ae4a79fe9319869d1b90ae8cbaedadc7e9dab30b32d781411256d468be5538996bb7368941c09009ef6bbfa6bfc7 +"mitt@npm:3.0.1": + version: 3.0.1 + resolution: "mitt@npm:3.0.1" + checksum: b55a489ac9c2949ab166b7f060601d3b6d893a852515ae9eca4e11df01c013876df777ea109317622b5c1c60e8aae252558e33c8c94e14124db38f64a39614b1 languageName: node linkType: hard @@ -35598,13 +31763,6 @@ __metadata: languageName: node linkType: hard -"moment@npm:^2.29.1": - version: 2.29.4 - resolution: "moment@npm:2.29.4" - checksum: 0ec3f9c2bcba38dc2451b1daed5daded747f17610b92427bebe1d08d48d8b7bdd8d9197500b072d14e326dd0ccf3e326b9e3d07c5895d3d49e39b6803b76e80e - languageName: node - linkType: hard - "moo@npm:^0.5.0": version: 0.5.2 resolution: "moo@npm:0.5.2" @@ -35660,9 +31818,9 @@ __metadata: languageName: node linkType: hard -"msw@npm:^1.0.0, msw@npm:^1.0.1, msw@npm:^1.2.1, msw@npm:^1.2.3, msw@npm:^1.3.0, msw@npm:^1.3.1": - version: 1.3.2 - resolution: "msw@npm:1.3.2" +"msw@npm:^1.0.0, msw@npm:^1.2.1, msw@npm:^1.3.0, msw@npm:^1.3.1": + version: 1.3.3 + resolution: "msw@npm:1.3.3" dependencies: "@mswjs/cookies": ^0.2.2 "@mswjs/interceptors": ^0.17.10 @@ -35684,25 +31842,25 @@ __metadata: type-fest: ^2.19.0 yargs: ^17.3.1 peerDependencies: - typescript: ">= 4.4.x <= 5.2.x" + typescript: ">= 4.4.x" peerDependenciesMeta: typescript: optional: true bin: msw: cli/index.js - checksum: c2d4f7747f5806f0fd8d8cc3ca250ee1c2a7a6cd608de43f95bd072ba1fb13cdce0b52932ce9bf8f4a21b194d2815db535501e224ec8f7052593447fe1c0cb70 + checksum: cb3fda1519485f219d36c4e5ac1e1190ffe77dab66121c88cb9db0bace1ecb5a45c83db49e68e7c688b330ce43eed17d00939e09812dc710c0d4b3e59925730c languageName: node linkType: hard "msw@npm:^2.0.0, msw@npm:^2.0.8": - version: 2.2.0 - resolution: "msw@npm:2.2.0" + version: 2.2.14 + resolution: "msw@npm:2.2.14" dependencies: "@bundled-es-modules/cookie": ^2.0.0 "@bundled-es-modules/statuses": ^1.0.1 "@inquirer/confirm": ^3.0.0 "@mswjs/cookies": ^1.1.0 - "@mswjs/interceptors": ^0.25.16 + "@mswjs/interceptors": ^0.26.14 "@open-draft/until": ^2.1.0 "@types/cookie": ^0.6.0 "@types/statuses": ^2.0.4 @@ -35716,13 +31874,13 @@ __metadata: type-fest: ^4.9.0 yargs: ^17.7.2 peerDependencies: - typescript: ">= 4.7.x <= 5.3.x" + typescript: ">= 4.7.x" peerDependenciesMeta: typescript: optional: true bin: msw: cli/index.js - checksum: 085ac2996fd1f65d697d3c3d2971e4fdf7b721e9a77a8b1bcd92afb2cc4b11cbb3adaa5adf31421a7824115ed2a0665ecf98d3e6826e4dd211012dca050c8ea4 + checksum: a958b38314f42b733f67ac176e753680f28da862212ab671aa40607b017a577797dcc323e997a3d6c0b2d3f13cc2a3458d4941574e08c916a6b8beeb91d8501a languageName: node linkType: hard @@ -35741,15 +31899,15 @@ __metadata: languageName: node linkType: hard -"multicast-dns@npm:^7.2.4": - version: 7.2.4 - resolution: "multicast-dns@npm:7.2.4" +"multicast-dns@npm:^7.2.5": + version: 7.2.5 + resolution: "multicast-dns@npm:7.2.5" dependencies: dns-packet: ^5.2.2 thunky: ^1.0.2 bin: multicast-dns: cli.js - checksum: 45a78628a8f26479c4018122d689a8b22aff034699a1913dac0b9891e4111162b3222c85bba642d624270a90e51129607f1e41aa701e0108cc974246bc9fe828 + checksum: 00b8a57df152d4cd0297946320a94b7c3cdf75a46a2247f32f958a8927dea42958177f9b7fdae69fab2e4e033fb3416881af1f5e9055a3e1542888767139e2fb languageName: node linkType: hard @@ -35780,19 +31938,19 @@ __metadata: languageName: node linkType: hard -"mysql2@npm:^2.2.5": - version: 2.3.3 - resolution: "mysql2@npm:2.3.3" +"mysql2@npm:^3.0.0": + version: 3.9.7 + resolution: "mysql2@npm:3.9.7" dependencies: - denque: ^2.0.1 + denque: ^2.1.0 generate-function: ^2.3.1 iconv-lite: ^0.6.3 - long: ^4.0.0 - lru-cache: ^6.0.0 - named-placeholders: ^1.1.2 + long: ^5.2.1 + lru-cache: ^8.0.0 + named-placeholders: ^1.1.3 seq-queue: ^0.0.5 sqlstring: ^2.3.2 - checksum: 45e479d0cbdb24ceb9d1846a1708ae2c33aa64f603f7899279b33560b1eec441f1b7a596075896f1305f701cfbc083bceb88bc72ba5d2f3656a3d6102611286a + checksum: 535261d076f840f0966788b3f33a5ff7872e5da321240c2359be5c9e7ec19197ed5f6e01f0bc7beae06dd291d03eb2bde00f474461a578debcb85fcd98e347d3 languageName: node linkType: hard @@ -35807,12 +31965,12 @@ __metadata: languageName: node linkType: hard -"named-placeholders@npm:^1.1.2": - version: 1.1.2 - resolution: "named-placeholders@npm:1.1.2" +"named-placeholders@npm:^1.1.3": + version: 1.1.3 + resolution: "named-placeholders@npm:1.1.3" dependencies: - lru-cache: ^4.1.3 - checksum: c9317d1b479d6733b3baedfde209c6c866cf387c2d625837f93355fdb6a9055b1e8180b883fe00bcb20edb3ba4dd21128ec2f1ed8cb884385cef7698cbcadcc4 + lru-cache: ^7.14.1 + checksum: 7834adc91e92ae1b9c4413384e3ccd297de5168bb44017ff0536705ddc4db421723bd964607849265feb3f6ded390f84cf138e5925f22f7c13324f87a803dc73 languageName: node linkType: hard @@ -35844,13 +32002,6 @@ __metadata: languageName: node linkType: hard -"nanoclone@npm:^0.2.1": - version: 0.2.1 - resolution: "nanoclone@npm:0.2.1" - checksum: 96b2954e22f70561f41e20d69856266c65583c2a441dae108f1dc71b716785d2c8038dac5f1d5e92b117aed3825f526b53139e2e5d6e6db8a77cfa35b3b8bf40 - languageName: node - linkType: hard - "nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" @@ -36031,7 +32182,7 @@ __metadata: languageName: node linkType: hard -"node-fetch-commonjs@npm:^3.3.1": +"node-fetch-commonjs@npm:^3.3.2": version: 3.3.2 resolution: "node-fetch-commonjs@npm:3.3.2" dependencies: @@ -36065,17 +32216,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^1.0.1": - version: 1.7.3 - resolution: "node-fetch@npm:1.7.3" - dependencies: - encoding: ^0.1.11 - is-stream: ^1.0.1 - checksum: 3bb0528c05d541316ebe52770d71ee25a6dce334df4231fd55df41a644143e07f068637488c18a5b0c43f05041dbd3346752f9e19b50df50569a802484544d5b - languageName: node - linkType: hard - -"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.5, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9": +"node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -36097,8 +32238,8 @@ __metadata: linkType: hard "node-gyp@npm:^10.0.0, node-gyp@npm:latest": - version: 10.0.1 - resolution: "node-gyp@npm:10.0.1" + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" dependencies: env-paths: ^2.2.0 exponential-backoff: ^3.1.1 @@ -36112,7 +32253,7 @@ __metadata: which: ^4.0.0 bin: node-gyp: bin/node-gyp.js - checksum: 60a74e66d364903ce02049966303a57f898521d139860ac82744a5fdd9f7b7b3b61f75f284f3bfe6e6add3b8f1871ce305a1d41f775c7482de837b50c792223f + checksum: 72e2ab4b23fc32007a763da94018f58069fc0694bf36115d49a2b195c8831e12cf5dd1e7a3718fa85c06969aedf8fc126722d3b672ec1cb27e06ed33caee3c60 languageName: node linkType: hard @@ -36210,6 +32351,26 @@ __metadata: languageName: node linkType: hard +"node-mocks-http@npm:^1.0.0": + version: 1.14.1 + resolution: "node-mocks-http@npm:1.14.1" + dependencies: + "@types/express": ^4.17.21 + "@types/node": ^20.10.6 + accepts: ^1.3.7 + content-disposition: ^0.5.3 + depd: ^1.1.0 + fresh: ^0.5.2 + merge-descriptors: ^1.0.1 + methods: ^1.1.2 + mime: ^1.3.4 + parseurl: ^1.3.3 + range-parser: ^1.2.0 + type-is: ^1.6.18 + checksum: cc37618fb5f44a6049f8fcfc73373c4b42943e35e4b0f7463939d3f219663fe647e00e6eb9c3b8aedd48e88e10e1542993ac1a7ff8442ee2c3f6b97f23ced0e0 + languageName: node + linkType: hard + "node-releases@npm:^2.0.13": version: 2.0.13 resolution: "node-releases@npm:2.0.13" @@ -36263,8 +32424,8 @@ __metadata: linkType: hard "nodemon@npm:^3.0.1": - version: 3.0.3 - resolution: "nodemon@npm:3.0.3" + version: 3.1.0 + resolution: "nodemon@npm:3.1.0" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -36278,7 +32439,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: 121ebb6349167d87cefd5767ec453ceb49ec5a8d50146134a54b0e25502c29ad01caaa41460e303b35728439012564782d278b3fef3c615f3c278979c2b7d586 + checksum: 0b721f66ee60d9bf092f6101965bc65769698fa2921d0283d90bbf3f0906aa4f3ac77316682375bd7f09c91679fddb131aa39f9fc839fea57061bbc8e81b60e3 languageName: node linkType: hard @@ -36355,13 +32516,6 @@ __metadata: languageName: node linkType: hard -"normalize-scroll-left@npm:^0.1.2": - version: 0.1.2 - resolution: "normalize-scroll-left@npm:0.1.2" - checksum: 817d5a659ba6f14f458cd03a5a0f98ec2a9d7e6c63c160f2db164827b87bb77c0237752890a18d11054fe628907493c5f4d8914907585ec9fbba3de26d2a6815 - languageName: node - linkType: hard - "normalize-url@npm:^4.1.0": version: 4.5.1 resolution: "normalize-url@npm:4.5.1" @@ -36376,6 +32530,19 @@ __metadata: languageName: node linkType: hard +"notistack@npm:^3.0.1": + version: 3.0.1 + resolution: "notistack@npm:3.0.1" + dependencies: + clsx: ^1.1.0 + goober: ^2.0.33 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 421c970308690b8c8cb2e275e7f66020db7c1955e104f638e7fa562396a6b9322ff95f0e62492b07f3d36b0ef72adb4de2c2ce9803089c1c8f028d1a3b088e01 + languageName: node + linkType: hard + "npm-bundled@npm:^1.1.1": version: 1.1.2 resolution: "npm-bundled@npm:1.1.2" @@ -36656,14 +32823,14 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.1, object-inspect@npm:^1.9.0": +"object-inspect@npm:^1.13.1": version: 1.13.1 resolution: "object-inspect@npm:1.13.1" checksum: 7d9fa9221de3311dcb5c7c307ee5dc011cdd31dc43624b7c184b3840514e118e05ef0002be5388304c416c0eb592feb46e983db12577fc47e47d5752fbbfb61f languageName: node linkType: hard -"object-is@npm:^1.0.1, object-is@npm:^1.1.5": +"object-is@npm:^1.0.1": version: 1.1.5 resolution: "object-is@npm:1.1.5" dependencies: @@ -36694,19 +32861,19 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.4": - version: 4.1.4 - resolution: "object.assign@npm:4.1.4" +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": + version: 4.1.5 + resolution: "object.assign@npm:4.1.5" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.4 + call-bind: ^1.0.5 + define-properties: ^1.2.1 has-symbols: ^1.0.3 object-keys: ^1.1.1 - checksum: 76cab513a5999acbfe0ff355f15a6a125e71805fcf53de4e9d4e082e1989bdb81d1e329291e1e4e0ae7719f0e4ef80e88fb2d367ae60500d79d25a6224ac8864 + checksum: f9aeac0541661370a1fc86e6a8065eb1668d3e771f7dbb33ee54578201336c057b21ee61207a186dd42db0c62201d91aac703d20d12a79fc79c353eed44d4e25 languageName: node linkType: hard -"object.entries@npm:^1.1.6, object.entries@npm:^1.1.7": +"object.entries@npm:^1.1.7": version: 1.1.7 resolution: "object.entries@npm:1.1.7" dependencies: @@ -36717,7 +32884,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.6, object.fromentries@npm:^2.0.7": +"object.fromentries@npm:^2.0.7": version: 2.0.7 resolution: "object.fromentries@npm:2.0.7" dependencies: @@ -36740,13 +32907,13 @@ __metadata: languageName: node linkType: hard -"object.hasown@npm:^1.1.2": - version: 1.1.2 - resolution: "object.hasown@npm:1.1.2" +"object.hasown@npm:^1.1.3": + version: 1.1.3 + resolution: "object.hasown@npm:1.1.3" dependencies: - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: b936572536db0cdf38eb30afd2f1026a8b6f2cc5d2c4497c9d9bbb01eaf3e980dead4fd07580cfdd098e6383e5a9db8212d3ea0c6bdd2b5e68c60aa7e3b45566 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + checksum: 76bc17356f6124542fb47e5d0e78d531eafa4bba3fc2d6fc4b1a8ce8b6878912366c0d99f37ce5c84ada8fd79df7aa6ea1214fddf721f43e093ad2df51f27da1 languageName: node linkType: hard @@ -36768,18 +32935,18 @@ __metadata: languageName: node linkType: hard -"octokit-plugin-create-pull-request@npm:^3.10.0": - version: 3.13.1 - resolution: "octokit-plugin-create-pull-request@npm:3.13.1" +"octokit-plugin-create-pull-request@npm:^5.0.0": + version: 5.1.1 + resolution: "octokit-plugin-create-pull-request@npm:5.1.1" dependencies: - "@octokit/types": ^6.8.2 - checksum: 169e393046cecc51b9c9be23321086fc60681bfdfe2bcec5477d0916e5b8e3b64b54588f631f61d98677a0561f5d44fa85589abd75ff851122c798795921292b + "@octokit/types": ^8.0.0 + checksum: bed96700c795868d1fc6a95d41c87b98c370d84421125b561c6b8632bb85bbb399a9fa6d35abb2c3d342e42f8b10032afb195470cac9b640161064b68d276d9e languageName: node linkType: hard "octokit@npm:^3.0.0": - version: 3.1.2 - resolution: "octokit@npm:3.1.2" + version: 3.2.0 + resolution: "octokit@npm:3.2.0" dependencies: "@octokit/app": ^14.0.2 "@octokit/core": ^5.0.0 @@ -36791,7 +32958,7 @@ __metadata: "@octokit/plugin-throttling": ^8.0.0 "@octokit/request-error": ^5.0.0 "@octokit/types": ^12.0.0 - checksum: 8ef0d57a0e0129da5a3fddf2b2150c3214fd19b5cbefdd2fe7fa4604f45aae90587080ce1498fadef6714d385835ee00b7c86c526f31d67c93fcd545e041568c + checksum: 3ec8efe02144aa6210a5c846947245cbe58d31144fa8e6a1726782001d77fcd044b7e1498a56c5e47aba44c1f5726a37c261f474cb46b816579549f7a09db1f6 languageName: node linkType: hard @@ -36802,7 +32969,7 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:2.4.1, on-finished@npm:^2.3.0": +"on-finished@npm:2.4.1, on-finished@npm:^2.3.0, on-finished@npm:^2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -36872,6 +33039,18 @@ __metadata: languageName: node linkType: hard +"open@npm:^10.0.3": + version: 10.0.3 + resolution: "open@npm:10.0.3" + dependencies: + default-browser: ^5.2.1 + define-lazy-prop: ^3.0.0 + is-inside-container: ^1.0.0 + is-wsl: ^3.1.0 + checksum: 3c4b4eb3c08210f7b7b3f3311d36440f4b83f0641ac70e5e56d637f48d4a7736e0fd49a604eebe0a55c51223d77f9ced11912223cab12d5e9fdc866727c6cb1d + languageName: node + linkType: hard + "open@npm:^7.4.2": version: 7.4.2 resolution: "open@npm:7.4.2" @@ -36882,7 +33061,7 @@ __metadata: languageName: node linkType: hard -"open@npm:^8.0.0, open@npm:^8.0.9, open@npm:^8.4.0": +"open@npm:^8.0.0, open@npm:^8.4.0": version: 8.4.0 resolution: "open@npm:8.4.0" dependencies: @@ -36931,14 +33110,14 @@ __metadata: linkType: hard "openid-client@npm:^5.2.1, openid-client@npm:^5.3.0, openid-client@npm:^5.4.3, openid-client@npm:^5.5.0": - version: 5.6.4 - resolution: "openid-client@npm:5.6.4" + version: 5.6.5 + resolution: "openid-client@npm:5.6.5" dependencies: - jose: ^4.15.4 + jose: ^4.15.5 lru-cache: ^6.0.0 object-hash: ^2.2.0 oidc-token-hash: ^5.0.3 - checksum: 69843f078dacbbc6bad6d65ca6689414ac73f095dfe2f8e606822e6cfc9d9cd7d0dfaf2649352eda604653806f0ea65326ad2d6266da897e4740ec93d26d21f6 + checksum: 2240079f761173b10635ce5fefbac04b6820f54e00d588ab2afdddb6c0f0ab6568e663cf1ab6a4a2297fbdbb73e42d78b8190f91dba7e1b80d287b2127fcbc7c languageName: node linkType: hard @@ -37086,15 +33265,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: ^1.0.0 - checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b - languageName: node - linkType: hard - "p-locate@npm:^3.0.0": version: 3.0.0 resolution: "p-locate@npm:3.0.0" @@ -37167,13 +33337,14 @@ __metadata: languageName: node linkType: hard -"p-retry@npm:^4.5.0": - version: 4.5.0 - resolution: "p-retry@npm:4.5.0" +"p-retry@npm:^6.2.0": + version: 6.2.0 + resolution: "p-retry@npm:6.2.0" dependencies: - "@types/retry": ^0.12.0 - retry: ^0.12.0 - checksum: 129cbf070401b4b5fea7c959a85a62d26ac29593bcb59e34ce1544a0cace3674cd1f66c370ba8ec95184cf5745546ea2d5e31b75395cf40a4e34358684867b67 + "@types/retry": 0.12.2 + is-network-error: ^1.0.0 + retry: ^0.13.1 + checksum: 6003573c559ee812329c9c3ede7ba12a783fdc8dd70602116646e850c920b4597dc502fe001c3f9526fca4e93275045db7a27341c458e51db179c1374a01ac44 languageName: node linkType: hard @@ -37203,7 +33374,7 @@ __metadata: languageName: node linkType: hard -"pac-proxy-agent@npm:^7.0.0": +"pac-proxy-agent@npm:^7.0.0, pac-proxy-agent@npm:^7.0.1": version: 7.0.1 resolution: "pac-proxy-agent@npm:7.0.1" dependencies: @@ -37242,13 +33413,6 @@ __metadata: languageName: node linkType: hard -"packet-reader@npm:1.0.0": - version: 1.0.0 - resolution: "packet-reader@npm:1.0.0" - checksum: 0b7516f0cbf3e322aad591bed29ba544220088c53943145c0d9121a6f59182ad811f7fd6785a8979a34356aca69d97653689029964c5998dc02645633d88ffd7 - languageName: node - linkType: hard - "pacote@npm:^12.0.0, pacote@npm:^12.0.2": version: 12.0.3 resolution: "pacote@npm:12.0.3" @@ -37285,13 +33449,6 @@ __metadata: languageName: node linkType: hard -"papi@npm:^1.1.0": - version: 1.1.0 - resolution: "papi@npm:1.1.0" - checksum: f7c566fa10c27ff1820e76bf83035dab7db4f62a84e4ed1bdd1117bd6a1d796a2b4340fa8df34d19997e33be9306de0147065eeaafc1622964aa94b3073d50c4 - languageName: node - linkType: hard - "param-case@npm:^3.0.4": version: 3.0.4 resolution: "param-case@npm:3.0.4" @@ -37375,15 +33532,6 @@ __metadata: languageName: node linkType: hard -"parse-link-header@npm:^2.0.0": - version: 2.0.0 - resolution: "parse-link-header@npm:2.0.0" - dependencies: - xtend: ~4.0.1 - checksum: 0e96c6af9910e8f92084b49b8dc6a10dd58db470847d1499f562576180c1ac5e49d18007697f0d538e5f3efdc8ce1d8777641f3ae225302b74af0dd0578b628e - languageName: node - linkType: hard - "parse-ms@npm:^4.0.0": version: 4.0.0 resolution: "parse-ms@npm:4.0.0" @@ -37441,7 +33589,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -37516,12 +33664,11 @@ __metadata: linkType: hard "passport-microsoft@npm:^1.0.0": - version: 1.0.0 - resolution: "passport-microsoft@npm:1.0.0" + version: 1.1.0 + resolution: "passport-microsoft@npm:1.1.0" dependencies: - passport-oauth2: 1.6.1 - pkginfo: 0.4.x - checksum: 9f66b857364a1653a2becc255be098f895bdfd53425ad3ba95eb0a99820c5f38a0f03935d70122fad2608a6506d9de49fc9696e60df3d60fa7619585ab5dbd5d + passport-oauth2: 1.8.0 + checksum: 97cb68f3adba8914a9375ebf1b0a05f33d8ca53ddad50948a254219e01672e726fc8eb7152d4e31de86041ab603dea950cec4f3dee5c6ade3bcc3de23aa44408 languageName: node linkType: hard @@ -37536,20 +33683,7 @@ __metadata: languageName: node linkType: hard -"passport-oauth2@npm:1.6.1": - version: 1.6.1 - resolution: "passport-oauth2@npm:1.6.1" - dependencies: - base64url: 3.x.x - oauth: 0.9.x - passport-strategy: 1.x.x - uid2: 0.0.x - utils-merge: 1.x.x - checksum: 2a5b01a884ebade01770543d3b84fbdbc45c75ca13b320b88ae59e33388bb485a27c323c2d3904058dca57065bf0e2a78c645cbb62600ced2dcdd43094259f0e - languageName: node - linkType: hard - -"passport-oauth2@npm:1.x.x, passport-oauth2@npm:^1.1.2, passport-oauth2@npm:^1.4.0, passport-oauth2@npm:^1.6.0, passport-oauth2@npm:^1.6.1": +"passport-oauth2@npm:1.8.0, passport-oauth2@npm:1.x.x, passport-oauth2@npm:^1.1.2, passport-oauth2@npm:^1.4.0, passport-oauth2@npm:^1.6.0, passport-oauth2@npm:^1.6.1, passport-oauth2@npm:^1.7.0": version: 1.8.0 resolution: "passport-oauth2@npm:1.8.0" dependencies: @@ -37763,10 +33897,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^6.2.0": - version: 6.2.0 - resolution: "path-to-regexp@npm:6.2.0" - checksum: a6aca74d2d6e2e7594d812f653cf85e9cb5054d3a8d80f099722a44ef6ad22639b02078e5ea83d11db16321c3e4359e3f1ab0274fa78dad0754a6e53f630b0fc +"path-to-regexp@npm:^6.2.0, path-to-regexp@npm:^6.2.1": + version: 6.2.2 + resolution: "path-to-regexp@npm:6.2.2" + checksum: b7b0005c36f5099f9ed1fb20a820d2e4ed1297ffe683ea1d678f5e976eb9544f01debb281369dabdc26da82e6453901bf71acf2c7ed14b9243536c2a45286c33 languageName: node linkType: hard @@ -37839,13 +33973,20 @@ __metadata: languageName: node linkType: hard -"pg-connection-string@npm:2.6.2, pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.2": +"pg-connection-string@npm:2.6.2": version: 2.6.2 resolution: "pg-connection-string@npm:2.6.2" checksum: 22265882c3b6f2320785378d0760b051294a684989163d5a1cde4009e64e84448d7bf67d9a7b9e7f69440c3ee9e2212f9aa10dd17ad6773f6143c6020cebbcb5 languageName: node linkType: hard +"pg-connection-string@npm:^2.3.0, pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.4": + version: 2.6.4 + resolution: "pg-connection-string@npm:2.6.4" + checksum: 2c1d2ac1add1f93076f1594d217a0980f79add05dc48de6363e1c550827c78a6ee3e3b5420da9c54858f6b678cdb348aed49732ee68158b6cdb70f1d1c748cf9 + languageName: node + linkType: hard + "pg-int8@npm:1.0.1": version: 1.0.1 resolution: "pg-int8@npm:1.0.1" @@ -37860,19 +34001,19 @@ __metadata: languageName: node linkType: hard -"pg-pool@npm:^3.6.1": - version: 3.6.1 - resolution: "pg-pool@npm:3.6.1" +"pg-pool@npm:^3.6.2": + version: 3.6.2 + resolution: "pg-pool@npm:3.6.2" peerDependencies: pg: ">=8.0" - checksum: 8a6513e6f74a794708c9dd16d2ccda0debadc56435ec2582de2b2e35b01315550c5dab8a0a9a2a16f4adce45523228f5739940fb7687ec7e9c300f284eb08fd1 + checksum: 5ceee4320a35fce08777d085d50a30a1253574257e1e7c5c56c915056d387d340f797115580c8d90a46691f83c39a9b4da1fd810d9ad168cc455c79c289116f4 languageName: node linkType: hard -"pg-protocol@npm:*, pg-protocol@npm:^1.6.0": - version: 1.6.0 - resolution: "pg-protocol@npm:1.6.0" - checksum: e12662d2de2011e0c3a03f6a09f435beb1025acdc860f181f18a600a5495dc38a69d753bbde1ace279c8c442536af9c1a7c11e1d0fe3fad3aa1348b28d9d2683 +"pg-protocol@npm:*, pg-protocol@npm:^1.6.1": + version: 1.6.1 + resolution: "pg-protocol@npm:1.6.1" + checksum: cce3f72cc4bdc04db9ce3fa38b2c45b745f0a95a925847b349087f52c02c4d51b7c74d8867e40639699d0c7609accfaffb6b1d221b3268d2bdc4bb8d6a2995a3 languageName: node linkType: hard @@ -37905,15 +34046,13 @@ __metadata: linkType: hard "pg@npm:^8.11.3, pg@npm:^8.9.0": - version: 8.11.3 - resolution: "pg@npm:8.11.3" + version: 8.11.5 + resolution: "pg@npm:8.11.5" dependencies: - buffer-writer: 2.0.0 - packet-reader: 1.0.0 pg-cloudflare: ^1.1.1 - pg-connection-string: ^2.6.2 - pg-pool: ^3.6.1 - pg-protocol: ^1.6.0 + pg-connection-string: ^2.6.4 + pg-pool: ^3.6.2 + pg-protocol: ^1.6.1 pg-types: ^2.1.0 pgpass: 1.x peerDependencies: @@ -37924,7 +34063,7 @@ __metadata: peerDependenciesMeta: pg-native: optional: true - checksum: 8af9468b8969fa0d73a6b349216c8cbc953d938fcae5594f2d24043060e9226a072c8085fc4230172b5576fcab4c39c8563c655f271dc2a9209b6ad5370cafe5 + checksum: 2317bcc7080f116ced761620b8cbc98175080cacf1e8a894e14f468bcd9c996a7bd5ef36c9db91d380a772667508eb72c42b10206a90cd82b0b4a7669a19f9e4 languageName: node linkType: hard @@ -37972,13 +34111,6 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:4.0.1": - version: 4.0.1 - resolution: "picomatch@npm:4.0.1" - checksum: f135d38bb7d190186907714cf2f3abe043de9c66b1c5e5687ae7ae63fd9693a51634aa3662ac1dcd79e1209e02edcaa0740c4f3edda2ffed03f1a0bee38d8f67 - languageName: node - linkType: hard - "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.0, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -37986,6 +34118,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.1": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: a7a5188c954f82c6585720e9143297ccd0e35ad8072231608086ca950bee672d51b0ef676254af0788205e59bd4e4deb4e7708769226bed725bf13370a7d1464 + languageName: node + linkType: hard + "pidtree@npm:0.6.0": version: 0.6.0 resolution: "pidtree@npm:0.6.0" @@ -38065,7 +34204,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.5": +"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.5, pirates@npm:^4.0.6": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 @@ -38115,34 +34254,34 @@ __metadata: languageName: node linkType: hard -"pkginfo@npm:0.4.x, pkginfo@npm:^0.4.1": +"pkginfo@npm:^0.4.1": version: 0.4.1 resolution: "pkginfo@npm:0.4.1" checksum: 0f13694f3682345647b7cb887fb6fe258df51b635f252324cd75eeb8181b4381cb8b9d91dc2d869849e857192b403bea65038d2f7c05b524eeae69ece5048209 languageName: node linkType: hard -"playwright-core@npm:1.41.2": - version: 1.41.2 - resolution: "playwright-core@npm:1.41.2" +"playwright-core@npm:1.43.1": + version: 1.43.1 + resolution: "playwright-core@npm:1.43.1" bin: playwright-core: cli.js - checksum: b41ede0db3fd3e3f7e0b0efbdfb2dbc4db345e113cf9c4451af21d1d5b5d9ab5e969f5662852925e37b2198ae5daab92aa48108fe3d4eb81c849ba8752aaf8cc + checksum: 7c96b3a4a4bce2ee22c3cd680c9b0bb9e4bf07ee4b51d1e9a7f47a6489c7b0b960d4b550e530b8f41d1ffeadd26c7c6bb626ae8689dfd90dce1cb8e35ae78ff7 languageName: node linkType: hard -"playwright@npm:1.41.2": - version: 1.41.2 - resolution: "playwright@npm:1.41.2" +"playwright@npm:1.43.1": + version: 1.43.1 + resolution: "playwright@npm:1.43.1" dependencies: fsevents: 2.3.2 - playwright-core: 1.41.2 + playwright-core: 1.43.1 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: acf166003ec42cd795f5fca096c5135880d78e84ec2d0a1911b2cab984cf75dc06e50d3aa24b56cbcbc5369ca8c61831e76c5f8674531a272fbd0f6e624fa387 + checksum: de9db021f93018a18275bbb5af09ebf1804aa0534f47578b35b440064abc774509740205802824afc94a99fc84dd55ffe9e215718ad3ecc691b251ab3882b096 languageName: node linkType: hard @@ -38179,13 +34318,6 @@ __metadata: languageName: node linkType: hard -"popper.js@npm:^1.14.1": - version: 1.16.1 - resolution: "popper.js@npm:1.16.1" - checksum: c56ae5001ec50a77ee297a8061a0221d99d25c7348d2e6bcd3e45a0d0f32a1fd81bca29d46cb0d4bdf13efb77685bd6a0ce93f9eb3c608311a461f945fffedbe - languageName: node - linkType: hard - "portfinder@npm:1.0.28": version: 1.0.28 resolution: "portfinder@npm:1.0.28" @@ -38208,6 +34340,13 @@ __metadata: languageName: node linkType: hard +"possible-typed-array-names@npm:^1.0.0": + version: 1.0.0 + resolution: "possible-typed-array-names@npm:1.0.0" + checksum: b32d403ece71e042385cc7856385cecf1cd8e144fa74d2f1de40d1e16035dba097bc189715925e79b67bdd1472796ff168d3a90d296356c9c94d272d5b95f3ae + languageName: node + linkType: hard + "postcss-calc@npm:^8.0.0": version: 8.0.0 resolution: "postcss-calc@npm:8.0.0" @@ -38367,36 +34506,36 @@ __metadata: languageName: node linkType: hard -"postcss-modules-extract-imports@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-modules-extract-imports@npm:3.0.0" +"postcss-modules-extract-imports@npm:^3.0.0, postcss-modules-extract-imports@npm:^3.1.0": + version: 3.1.0 + resolution: "postcss-modules-extract-imports@npm:3.1.0" peerDependencies: postcss: ^8.1.0 - checksum: 4b65f2f1382d89c4bc3c0a1bdc5942f52f3cb19c110c57bd591ffab3a5fee03fcf831604168205b0c1b631a3dce2255c70b61aaae3ef39d69cd7eb450c2552d2 + checksum: b9192e0f4fb3d19431558be6f8af7ca45fc92baaad9b2778d1732a5880cd25c3df2074ce5484ae491e224f0d21345ffc2d419bd51c25b019af76d7a7af88c17f languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^4.0.0, postcss-modules-local-by-default@npm:^4.0.4": - version: 4.0.4 - resolution: "postcss-modules-local-by-default@npm:4.0.4" +"postcss-modules-local-by-default@npm:^4.0.0, postcss-modules-local-by-default@npm:^4.0.5": + version: 4.0.5 + resolution: "postcss-modules-local-by-default@npm:4.0.5" dependencies: icss-utils: ^5.0.0 postcss-selector-parser: ^6.0.2 postcss-value-parser: ^4.1.0 peerDependencies: postcss: ^8.1.0 - checksum: 578b955b0773147890caa88c30b10dfc849c5b1412a47ad51751890dba16fca9528c3ab00a19b186a8c2c150c2d08e2ce64d3d907800afee1f37c6d38252e365 + checksum: ca9b01f4a0a3dfb33e016299e2dfb7e85c3123292f7aec2efc0c6771b9955648598bfb4c1561f7ee9732fb27fb073681233661b32eef98baab43743f96735452 languageName: node linkType: hard -"postcss-modules-scope@npm:^3.0.0, postcss-modules-scope@npm:^3.1.1": - version: 3.1.1 - resolution: "postcss-modules-scope@npm:3.1.1" +"postcss-modules-scope@npm:^3.0.0, postcss-modules-scope@npm:^3.2.0": + version: 3.2.0 + resolution: "postcss-modules-scope@npm:3.2.0" dependencies: postcss-selector-parser: ^6.0.4 peerDependencies: postcss: ^8.1.0 - checksum: 9e9d23abb0babc7fa243be65704d72a5a9ceb2bded4dbaef96a88210d468b03c8c3158c197f4e22300c851f08c6fdddd6ebe65f44e4c34448b45b8a2e063a16d + checksum: 2ffe7e98c1fa993192a39c8dd8ade93fc4f59fbd1336ce34fcedaee0ee3bafb29e2e23fb49189256895b30e4f21af661c6a6a16ef7b17ae2c859301e4a4459ae languageName: node linkType: hard @@ -38610,13 +34749,13 @@ __metadata: linkType: hard "postcss@npm:^8.1.0, postcss@npm:^8.4.27, postcss@npm:^8.4.33": - version: 8.4.35 - resolution: "postcss@npm:8.4.35" + version: 8.4.38 + resolution: "postcss@npm:8.4.38" dependencies: nanoid: ^3.3.7 picocolors: ^1.0.0 - source-map-js: ^1.0.2 - checksum: cf3c3124d3912a507603f6d9a49b3783f741075e9aa73eb592a6dd9194f9edab9d20a8875d16d137d4f779fe7b6fbd1f5727e39bfd1c3003724980ee4995e1da + source-map-js: ^1.2.0 + checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451 languageName: node linkType: hard @@ -38814,18 +34953,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^28.0.0, pretty-format@npm:^28.1.3": - version: 28.1.3 - resolution: "pretty-format@npm:28.1.3" - dependencies: - "@jest/schemas": ^28.1.3 - ansi-regex: ^5.0.1 - ansi-styles: ^5.0.0 - react-is: ^18.0.0 - checksum: e69f857358a3e03d271252d7524bec758c35e44680287f36c1cb905187fbc82da9981a6eb07edfd8a03bc3cbeebfa6f5234c13a3d5b59f2bbdf9b4c4053e0a7f - languageName: node - linkType: hard - "pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" @@ -38890,13 +35017,20 @@ __metadata: languageName: node linkType: hard +"progress@npm:2.0.3": + version: 2.0.3 + resolution: "progress@npm:2.0.3" + checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7 + languageName: node + linkType: hard + "prom-client@npm:^15.0.0": - version: 15.1.0 - resolution: "prom-client@npm:15.1.0" + version: 15.1.2 + resolution: "prom-client@npm:15.1.2" dependencies: "@opentelemetry/api": ^1.4.0 tdigest: ^0.1.1 - checksum: 85bb134dfd0aab4606a27bce2d478d82650053da4340390210ed8280c14af24fc703a28fbc401b5edb4b756686a3df229f243ce5c7166c53925236fb763e4a51 + checksum: b9b2f439588a462c0aec840e8aa857bb0a77284174d6587ca042eb13ea6ac36ba13277f45ae6ed3696b3007a1020c5ee2c5ee46b23be033a7bb45207a5365c21 languageName: node linkType: hard @@ -38957,7 +35091,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:15.x, prop-types@npm:^15.0.0, prop-types@npm:^15.5.10, prop-types@npm:^15.5.7, prop-types@npm:^15.5.8, prop-types@npm:^15.6.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:15.x, prop-types@npm:^15.0.0, prop-types@npm:^15.5.10, prop-types@npm:^15.5.7, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -38968,19 +35102,30 @@ __metadata: languageName: node linkType: hard -"properties-reader@npm:^2.2.0": - version: 2.2.0 - resolution: "properties-reader@npm:2.2.0" +"proper-lockfile@npm:^4.1.2": + version: 4.1.2 + resolution: "proper-lockfile@npm:4.1.2" dependencies: - mkdirp: ^1.0.4 - checksum: a5c5684b1e16633cb695f4fef5476a63f43298619381e8f7f609448f3bda32b26d7c9042b57a427a6dedd1c7fdca1a01ccbe8771b4311ed534079b676c64eec7 + graceful-fs: ^4.2.4 + retry: ^0.12.0 + signal-exit: ^3.0.2 + checksum: 00078ee6a61c216a56a6140c7d2a98c6c733b3678503002dc073ab8beca5d50ca271de4c85fca13b9b8ee2ff546c36674d1850509b84a04a5d0363bcb8638939 languageName: node linkType: hard -"property-expr@npm:^2.0.4": - version: 2.0.4 - resolution: "property-expr@npm:2.0.4" - checksum: 7ac142e189f0feef685f327f582efe13bfbc24a0b6e2328afdb38520bc140caa5f91dfa9529f2539b4468d85dc83a593e1ef0e0f7401b525368bb634b323bf54 +"properties-reader@npm:^2.3.0": + version: 2.3.0 + resolution: "properties-reader@npm:2.3.0" + dependencies: + mkdirp: ^1.0.4 + checksum: cbf59e862dc507f8ce1f8d7641ed9737119f16a1d4dad8e79f17b303aaca1c6af7d36ddfef0f649cab4d200ba4334ac159af0b238f6978a085f5b1b5126b6cc3 + languageName: node + linkType: hard + +"property-expr@npm:^2.0.5": + version: 2.0.6 + resolution: "property-expr@npm:2.0.6" + checksum: 89977f4bb230736c1876f460dd7ca9328034502fd92e738deb40516d16564b850c0bbc4e052c3df88b5b8cd58e51c93b46a94bea049a3f23f4a022c038864cab languageName: node linkType: hard @@ -39009,7 +35154,7 @@ __metadata: languageName: node linkType: hard -"protobufjs@npm:7.2.5, protobufjs@npm:^7.0.0, protobufjs@npm:^7.2.4, protobufjs@npm:^7.2.5": +"protobufjs@npm:7.2.5": version: 7.2.5 resolution: "protobufjs@npm:7.2.5" dependencies: @@ -39029,10 +35174,23 @@ __metadata: languageName: node linkType: hard -"protocol-buffers-schema@npm:^3.6.0": - version: 3.6.0 - resolution: "protocol-buffers-schema@npm:3.6.0" - checksum: 8713b5770f6745ddbcdf3bbd03ee020624d506233bb567927a6615a6f69a5bd620a5f49597f34f4115792b853a4c9cb9e2d5d6b930a1c04bf198023e45c1c349 +"protobufjs@npm:^7.0.0, protobufjs@npm:^7.2.4, protobufjs@npm:^7.2.5, protobufjs@npm:^7.2.6": + version: 7.2.6 + resolution: "protobufjs@npm:7.2.6" + 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/node": ">=13.7.0" + long: ^5.0.0 + checksum: 3c62e48f7d50017ac3b0dcd2a58e617cf858f9fba56a488bd48b9aa3482893a75540052dbcb3c12dfbaab42b1d04964611175faf06bdadcd33a4ebac982a511e languageName: node linkType: hard @@ -39053,6 +35211,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:6.4.0": + version: 6.4.0 + resolution: "proxy-agent@npm:6.4.0" + dependencies: + agent-base: ^7.0.2 + debug: ^4.3.4 + http-proxy-agent: ^7.0.1 + https-proxy-agent: ^7.0.3 + lru-cache: ^7.14.1 + pac-proxy-agent: ^7.0.1 + proxy-from-env: ^1.1.0 + socks-proxy-agent: ^8.0.2 + checksum: 4d3794ad5e07486298902f0a7f250d0f869fa0e92d790767ca3f793a81374ce0ab6c605f8ab8e791c4d754da96656b48d1c24cb7094bfd310a15867e4a0841d7 + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -39135,6 +35309,33 @@ __metadata: languageName: node linkType: hard +"puppeteer-core@npm:22.6.4": + version: 22.6.4 + resolution: "puppeteer-core@npm:22.6.4" + dependencies: + "@puppeteer/browsers": 2.2.1 + chromium-bidi: 0.5.17 + debug: 4.3.4 + devtools-protocol: 0.0.1262051 + ws: 8.16.0 + checksum: 76d4328e7d2a788a7a2dc3a8b19571f8eda842ff990da2fe773c3e5c01236a03856b67d9a2a6ae976f8fa74ab38813e2c7e7c4b15b9715965b2156e9ca1f9a78 + languageName: node + linkType: hard + +"puppeteer@npm:*": + version: 22.6.4 + resolution: "puppeteer@npm:22.6.4" + dependencies: + "@puppeteer/browsers": 2.2.1 + cosmiconfig: 9.0.0 + devtools-protocol: 0.0.1262051 + puppeteer-core: 22.6.4 + bin: + puppeteer: lib/esm/puppeteer/node/cli.js + checksum: 7dcbda7fc3b999f3ee7808d1c67da41be0aeabd66b0831711a46a897a2681d117f044263e57aeb7d0a096c420bb9f5871c5c2b21c38e40d323fa675e1de322c9 + languageName: node + linkType: hard + "pure-color@npm:^1.2.0": version: 1.3.0 resolution: "pure-color@npm:1.3.0" @@ -39158,12 +35359,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.9.1, qs@npm:^6.9.4, qs@npm:^6.9.6": - version: 6.11.2 - resolution: "qs@npm:6.11.2" +"qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.9.1, qs@npm:^6.9.4": + version: 6.12.1 + resolution: "qs@npm:6.12.1" dependencies: - side-channel: ^1.0.4 - checksum: e812f3c590b2262548647d62f1637b6989cc56656dc960b893fe2098d96e1bd633f36576f4cd7564dfbff9db42e17775884db96d846bebe4f37420d073ecdc0b + side-channel: ^1.0.6 + checksum: aa761d99e65b6936ba2dd2187f2d9976afbcda38deb3ff1b3fe331d09b0c578ed79ca2abdde1271164b5be619c521ec7db9b34c23f49a074e5921372d16242d5 languageName: node linkType: hard @@ -39332,7 +35533,7 @@ __metadata: languageName: node linkType: hard -"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": +"range-parser@npm:^1.2.0, range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" checksum: 0a268d4fea508661cf5743dfe3d5f47ce214fd6b7dec1de0da4d669dd4ef3d2144468ebe4179049eff253d9d27e719c88dae55be64f954e80135a0cada804ec9 @@ -39346,18 +35547,6 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.1": - version: 2.5.1 - resolution: "raw-body@npm:2.5.1" - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - checksum: 5362adff1575d691bb3f75998803a0ffed8c64eabeaa06e54b4ada25a0cd1b2ae7f4f5ec46565d1bec337e08b5ac90c76eaa0758de6f72a633f025d754dec29e - languageName: node - linkType: hard - "raw-body@npm:2.5.2, raw-body@npm:^2.4.1": version: 2.5.2 resolution: "raw-body@npm:2.5.2" @@ -39564,19 +35753,6 @@ __metadata: languageName: node linkType: hard -"react-event-listener@npm:^0.6.2": - version: 0.6.6 - resolution: "react-event-listener@npm:0.6.6" - dependencies: - "@babel/runtime": ^7.2.0 - prop-types: ^15.6.0 - warning: ^4.0.1 - peerDependencies: - react: ^16.3.0 - checksum: 0287e0ae8cbf0a4c03889ffc2b745f5494b3edea0f4667357d709f5646dd78c7289ce305b6f473ec6ac5789f8a937c86b7e543d0249f0bf787bccdb1eab7ecd0 - languageName: node - linkType: hard - "react-fast-compare@npm:^3.1.1": version: 3.2.0 resolution: "react-fast-compare@npm:3.2.0" @@ -39584,23 +35760,6 @@ __metadata: languageName: node linkType: hard -"react-ga4@npm:^2.0.0": - version: 2.1.0 - resolution: "react-ga4@npm:2.1.0" - checksum: f7fb41141418d4ad14756f1126a1e9958db37d4d84ae6cd798043dc03a390b6dba74d69311af0349f0b9580a43bda8930138194ccc29c4100efe446e2d6eb057 - languageName: node - linkType: hard - -"react-ga@npm:^3.3.0": - version: 3.3.1 - resolution: "react-ga@npm:3.3.1" - peerDependencies: - prop-types: ^15.6.0 - react: ^15.6.2 || ^16.0 || ^17 || ^18 - checksum: 3026976d0249fbf80e7b5dad7707964198064d7ac460f3397de40524e76dd6c29dead0900f850e2bd3135a86a9b083af8cda9cfa087f195852bf8d2b17c1fcfb - languageName: node - linkType: hard - "react-grid-layout@npm:1.3.4": version: 1.3.4 resolution: "react-grid-layout@npm:1.3.4" @@ -39631,12 +35790,12 @@ __metadata: languageName: node linkType: hard -"react-hook-form@npm:^7.12.2, react-hook-form@npm:^7.13.0": - version: 7.50.1 - resolution: "react-hook-form@npm:7.50.1" +"react-hook-form@npm:^7.12.2": + version: 7.51.3 + resolution: "react-hook-form@npm:7.51.3" peerDependencies: react: ^16.8.0 || ^17 || ^18 - checksum: 40dcb64d2ff631f6da76db2c5788957da3429f07649a6f3aed76545c616fae8eee557a6b06d0d0842be1f80ac8244f44d87f4d8d83fddabec76d7ab9921f8781 + checksum: 4ac71033b66ae0b7b9d75a1bc2053a6747fb37f68c6895ee85a72cabb890168d82990c8ca7bddd271e80fdbf58f471d14d6a0e0714400d017590d4f56b3d241f languageName: node linkType: hard @@ -39650,6 +35809,16 @@ __metadata: languageName: node linkType: hard +"react-idle-timer@npm:5.7.2": + version: 5.7.2 + resolution: "react-idle-timer@npm:5.7.2" + peerDependencies: + react: ">=16" + react-dom: ">=16" + checksum: 6faf3cfa87c9d65ae7a87078a2d82db5b821936a45565a98d69e7341e4b4acd5610b1f26cf1a6809b5551e4c30357f2ab5ce729c4c33751f66cb9ce6072dfb02 + languageName: node + linkType: hard + "react-immutable-proptypes@npm:2.2.0": version: 2.2.0 resolution: "react-immutable-proptypes@npm:2.2.0" @@ -39681,7 +35850,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.10.2, react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.6.3, react-is@npm:^16.7.0, react-is@npm:^16.8.0, react-is@npm:^16.8.6": +"react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.7.0, react-is@npm:^16.8.0, react-is@npm:^16.8.6": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f @@ -39717,7 +35886,7 @@ __metadata: languageName: node linkType: hard -"react-lifecycles-compat@npm:^3.0.2, react-lifecycles-compat@npm:^3.0.4": +"react-lifecycles-compat@npm:^3.0.4": version: 3.0.4 resolution: "react-lifecycles-compat@npm:3.0.4" checksum: a904b0fc0a8eeb15a148c9feb7bc17cec7ef96e71188280061fc340043fd6d8ee3ff233381f0e8f95c1cf926210b2c4a31f38182c8f35ac55057e453d6df204f @@ -39771,9 +35940,9 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^9.1.0": - version: 9.1.0 - resolution: "react-redux@npm:9.1.0" +"react-redux@npm:^9.1.1": + version: 9.1.1 + resolution: "react-redux@npm:9.1.1" dependencies: "@types/use-sync-external-store": ^0.0.3 use-sync-external-store: ^1.0.0 @@ -39789,7 +35958,7 @@ __metadata: optional: true redux: optional: true - checksum: 1b07714379ff0087b4fb43ffd138cc84efb7608c874d632a4e2162e1874f3e0f6b69a0a9b0f24f93cbf122c694ac9cfd315770676d4cabb167d159f1ef419560 + checksum: 51a61215d7195f381c045dc263b6f5e4e297ec9219c3d34132cae594f4070ac5db9b3762f3b8a73bb8d10bbf251310c364ec61b36829103b1cc7ef9244ee7c8a languageName: node linkType: hard @@ -39896,15 +36065,15 @@ __metadata: linkType: hard "react-router-dom@npm:^6.3.0": - version: 6.22.0 - resolution: "react-router-dom@npm:6.22.0" + version: 6.22.3 + resolution: "react-router-dom@npm:6.22.3" dependencies: - "@remix-run/router": 1.15.0 - react-router: 6.22.0 + "@remix-run/router": 1.15.3 + react-router: 6.22.3 peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 21cbdda0070dffb50845a97e2688648a9925c7ebabd1f9335523a1f8ae66048c1d9d06442f1b0ec35a266d1c63ed3b56b437db70807f73440a185f3e2d3c632f + checksum: 5ae3759a70e4123cd4b8efbb82199a69f5d8c4a7a434d186d2ec7b532b6ef3302df2a98e5c27db977d3f0d725c7a279010a16ae77a3bf6257f1fee96123d8b77 languageName: node linkType: hard @@ -39919,14 +36088,14 @@ __metadata: languageName: node linkType: hard -"react-router@npm:6.22.0, react-router@npm:^6.3.0": - version: 6.22.0 - resolution: "react-router@npm:6.22.0" +"react-router@npm:6.22.3, react-router@npm:^6.3.0": + version: 6.22.3 + resolution: "react-router@npm:6.22.3" dependencies: - "@remix-run/router": 1.15.0 + "@remix-run/router": 1.15.3 peerDependencies: react: ">=16.8" - checksum: 94f382f3fa6fcb8525c143d83d4c3a3b010979f417cac0bbe7a63f906b3809e2bb56e8c329b9b3fd3212a498670ab278aea72893e921b827dcf00024c3d115dd + checksum: 1f7d9a5a849761ff69ef8f3d3131b4c1c25d18b76317ba5ad6f0d9421192c0b8b71ab0cc818c57aad7b81ada725559e513307d0ab43296a460262f0358602672 languageName: node linkType: hard @@ -39939,20 +36108,6 @@ __metadata: languageName: node linkType: hard -"react-smooth@npm:^4.0.0": - version: 4.0.0 - resolution: "react-smooth@npm:4.0.0" - dependencies: - fast-equals: ^5.0.1 - prop-types: ^15.8.1 - react-transition-group: ^4.4.5 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 0b4859593d4e24c500aab3a6660b23ca458a3cb7f3e74a00864fbdceafbdef93c8962d606bd97fff13f6075f4f5429b3826276b261e54577f7326511e3cb812b - languageName: node - linkType: hard - "react-sparklines@npm:^1.7.0": version: 1.7.0 resolution: "react-sparklines@npm:1.7.0" @@ -40036,21 +36191,6 @@ __metadata: languageName: node linkType: hard -"react-transition-group@npm:^2.2.1": - version: 2.9.0 - resolution: "react-transition-group@npm:2.9.0" - dependencies: - dom-helpers: ^3.4.0 - loose-envify: ^1.4.0 - prop-types: ^15.6.2 - react-lifecycles-compat: ^3.0.4 - peerDependencies: - react: ">=15.0.0" - react-dom: ">=15.0.0" - checksum: d8c9e50aabdc2cfc324e5cdb0ad1c6eecb02e1c0cd007b26d5b30ccf49015e900683dd489348c71fba4055858308d9ba7019e0d37d0e8d37bd46ed098788f670 - languageName: node - linkType: hard - "react-transition-group@npm:^4.0.0, react-transition-group@npm:^4.4.0, react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -40076,7 +36216,7 @@ __metadata: languageName: node linkType: hard -"react-use@npm:^17.2.4, react-use@npm:^17.3.1, react-use@npm:^17.3.2, react-use@npm:^17.4.0": +"react-use@npm:^17.2.4, react-use@npm:^17.3.2, react-use@npm:^17.4.0": version: 17.5.0 resolution: "react-use@npm:17.5.0" dependencies: @@ -40102,12 +36242,12 @@ __metadata: linkType: hard "react-virtualized-auto-sizer@npm:^1.0.11": - version: 1.0.22 - resolution: "react-virtualized-auto-sizer@npm:1.0.22" + version: 1.0.24 + resolution: "react-virtualized-auto-sizer@npm:1.0.24" peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 - checksum: dc3fc29437b7179de71f77e5be3514e8789944132d7eb03f7157f783ec167ad9bebf1d371c135cf74fc5787dfac313a2914a5d23b45e978ae77be36c673342e5 + checksum: e7d98563735dabbd1c58727c9d3e9f08f6a60a9964d25507cf4ef08f8964b6e421491c892ee0a99e47630118fdca42f1c60cef15ebda3659face58025dba3e98 languageName: node linkType: hard @@ -40307,34 +36447,6 @@ __metadata: languageName: node linkType: hard -"recharts-scale@npm:^0.4.4": - version: 0.4.5 - resolution: "recharts-scale@npm:0.4.5" - dependencies: - decimal.js-light: ^2.4.1 - checksum: e970377190a610e684a32c7461c7684ac3603c2e0ac0020bbba1eea9d099b38138143a8e80bf769bb49c0b7cecf22a2f5c6854885efed2d56f4540d4aa7052bd - languageName: node - linkType: hard - -"recharts@npm:^2.5.0": - version: 2.12.0 - resolution: "recharts@npm:2.12.0" - dependencies: - clsx: ^2.0.0 - eventemitter3: ^4.0.1 - lodash: ^4.17.19 - react-is: ^16.10.2 - react-smooth: ^4.0.0 - recharts-scale: ^0.4.4 - tiny-invariant: ^1.3.1 - victory-vendor: ^36.6.8 - peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 - checksum: 13fc3f8405a16dc8555b5aba9928e7339549b1db2da4821e659df8ac59cbdccec044b985be21093a546c2b2c231113103064c6ea4799322ca360805aede0358b - languageName: node - linkType: hard - "rechoir@npm:^0.6.2": version: 0.6.2 resolution: "rechoir@npm:0.6.2" @@ -40353,22 +36465,6 @@ __metadata: languageName: node linkType: hard -"recompose@npm:0.28.0 - 0.30.0": - version: 0.30.0 - resolution: "recompose@npm:0.30.0" - dependencies: - "@babel/runtime": ^7.0.0 - change-emitter: ^0.1.2 - fbjs: ^0.8.1 - hoist-non-react-statics: ^2.3.1 - react-lifecycles-compat: ^3.0.2 - symbol-observable: ^1.0.4 - peerDependencies: - react: ^0.14.0 || ^15.0.0 || ^16.0.0 - checksum: 18e58252336d0628b22db1e38407d32e836648e6d5c9453ba37c9f8030138b3429ee3952b053a13b60311f8b60893b207a761466bb293083542db0cf317b7a41 - languageName: node - linkType: hard - "recursive-readdir@npm:^2.2.2": version: 2.2.3 resolution: "recursive-readdir@npm:2.2.3" @@ -40507,14 +36603,15 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.4.3, regexp.prototype.flags@npm:^1.5.1": - version: 1.5.1 - resolution: "regexp.prototype.flags@npm:1.5.1" +"regexp.prototype.flags@npm:^1.5.0, regexp.prototype.flags@npm:^1.5.2": + version: 1.5.2 + resolution: "regexp.prototype.flags@npm:1.5.2" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - set-function-name: ^2.0.0 - checksum: 869edff00288442f8d7fa4c9327f91d85f3b3acf8cbbef9ea7a220345cf23e9241b6def9263d2c1ebcf3a316b0aa52ad26a43a84aa02baca3381717b3e307f47 + call-bind: ^1.0.6 + define-properties: ^1.2.1 + es-errors: ^1.3.0 + set-function-name: ^2.0.1 + checksum: d7f333667d5c564e2d7a97c56c3075d64c722c9bb51b2b4df6822b2e8096d623a5e63088fb4c83df919b6951ef8113841de8b47de7224872fa6838bc5d8a7d64 languageName: node linkType: hard @@ -40561,13 +36658,6 @@ __metadata: languageName: node linkType: hard -"regression@npm:^2.0.1": - version: 2.0.1 - resolution: "regression@npm:2.0.1" - checksum: 2afb76ed65c87f22ef25dffb19fa95d70cded586ee9fcd5239f61d40993f5904bab0aae8fece73a8dddd35e19956a027004e727385ee4b4e7f800229a50edfb5 - languageName: node - linkType: hard - "relateurl@npm:^0.2.7": version: 0.2.7 resolution: "relateurl@npm:0.2.7" @@ -40673,16 +36763,16 @@ __metadata: languageName: node linkType: hard -"replace-in-file@npm:^6.0.0": - version: 6.3.5 - resolution: "replace-in-file@npm:6.3.5" +"replace-in-file@npm:^7.1.0": + version: 7.1.0 + resolution: "replace-in-file@npm:7.1.0" dependencies: chalk: ^4.1.2 - glob: ^7.2.0 - yargs: ^17.2.1 + glob: ^8.1.0 + yargs: ^17.7.2 bin: replace-in-file: bin/cli.js - checksum: e5ac3bfee531dcb70cfbb327e6d4ec86bcf4c8045f292e46fb0e4c8743bd70a274c2402918d2609a25fde829862b6e1fe5f09f6c171aabbdde142a9f33008cf1 + checksum: 2ed61bd0cf0752b18775b52342ad36f4ee6c806f7eca0b0d085c23bafe0cb4828e4ec8f59058bde6b67d2ed5ac51e1681284f586089b58b966e2489712830db0 languageName: node linkType: hard @@ -40800,7 +36890,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:~1.22.1": +"resolve@npm:1.22.8, resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:~1.22.1": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -40813,16 +36903,16 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^2.0.0-next.4": - version: 2.0.0-next.4 - resolution: "resolve@npm:2.0.0-next.4" +"resolve@npm:^2.0.0-next.5": + version: 2.0.0-next.5 + resolution: "resolve@npm:2.0.0-next.5" dependencies: - is-core-module: ^2.9.0 + is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: c438ac9a650f2030fd074219d7f12ceb983b475da2d89ad3d6dd05fbf6b7a0a8cd37d4d10b43cb1f632bc19f22246ab7f36ebda54d84a29bfb2910a0680906d3 + checksum: a73ac69a1c4bd34c56b213d91f5b17ce390688fdb4a1a96ed3025cc7e08e7bfb90b3a06fcce461780cb0b589c958afcb0080ab802c71c01a7ecc8c64feafc89f languageName: node linkType: hard @@ -40836,9 +36926,9 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@~1.22.1#~builtin": +"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@~1.22.1#~builtin": version: 1.22.8 - resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=07638b" + resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: is-core-module: ^2.13.0 path-parse: ^1.0.7 @@ -40849,22 +36939,22 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^2.0.0-next.4#~builtin": - version: 2.0.0-next.4 - resolution: "resolve@patch:resolve@npm%3A2.0.0-next.4#~builtin::version=2.0.0-next.4&hash=07638b" +"resolve@patch:resolve@^2.0.0-next.5#~builtin": + version: 2.0.0-next.5 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#~builtin::version=2.0.0-next.5&hash=c3c19d" dependencies: - is-core-module: ^2.9.0 + is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 4bf9f4f8a458607af90518ff73c67a4bc1a38b5a23fef2bb0ccbd45e8be89820a1639b637b0ba377eb2be9eedfb1739a84cde24fe4cd670c8207d8fea922b011 + checksum: 064d09c1808d0c51b3d90b5d27e198e6d0c5dad0eb57065fd40803d6a20553e5398b07f76739d69cbabc12547058bec6b32106ea66622375fb0d7e8fca6a846c languageName: node linkType: hard "resolve@patch:resolve@~1.19.0#~builtin": version: 1.19.0 - resolution: "resolve@patch:resolve@npm%3A1.19.0#~builtin::version=1.19.0&hash=07638b" + resolution: "resolve@patch:resolve@npm%3A1.19.0#~builtin::version=1.19.0&hash=c3c19d" dependencies: is-core-module: ^2.1.0 path-parse: ^1.0.6 @@ -40936,7 +37026,7 @@ __metadata: languageName: node linkType: hard -"retry@npm:0.13.1": +"retry@npm:0.13.1, retry@npm:^0.13.1": version: 0.13.1 resolution: "retry@npm:0.13.1" checksum: 47c4d5be674f7c13eee4cfe927345023972197dbbdfba5d3af7e461d13b44de1bfd663bfc80d2f601f8ef3fc8164c16dd99655a221921954a65d044a2fc1233b @@ -41011,6 +37101,17 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^5.0.5": + version: 5.0.5 + resolution: "rimraf@npm:5.0.5" + dependencies: + glob: ^10.3.7 + bin: + rimraf: dist/esm/bin.mjs + checksum: d66eef829b2e23b16445f34e73d75c7b7cf4cbc8834b04720def1c8f298eb0753c3d76df77325fad79d0a2c60470525d95f89c2475283ad985fd7441c32732d1 + languageName: node + linkType: hard + "rimraf@npm:~2.6.2": version: 2.6.3 resolution: "rimraf@npm:2.6.3" @@ -41046,35 +37147,34 @@ __metadata: languageName: node linkType: hard -"rollup-plugin-dts@npm:^4.0.1": - version: 4.2.3 - resolution: "rollup-plugin-dts@npm:4.2.3" +"rollup-plugin-dts@npm:^6.1.0": + version: 6.1.0 + resolution: "rollup-plugin-dts@npm:6.1.0" dependencies: - "@babel/code-frame": ^7.18.6 - magic-string: ^0.26.6 + "@babel/code-frame": ^7.22.13 + magic-string: ^0.30.4 peerDependencies: - rollup: ^2.55 - typescript: ^4.1 + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 dependenciesMeta: "@babel/code-frame": optional: true - checksum: b1de94202d0574e7c12105bf0d013e7142c1b9b74d6b83d194d870dcdc281e90cff45ed47a0ab1c62280cc25e75f522e1278ec0ba89c8f75b8bcb56dc98c2c63 + checksum: a90f8e975e4515734c84fa17e0feaf8fdd9ed9368722c3908687875903a393cba4d07d9934bae9b91a0c1b6c63ac1ef0ccd7363d3e6e4dc10eabca3540be9f11 languageName: node linkType: hard -"rollup-plugin-esbuild@npm:^4.7.2": - version: 4.10.3 - resolution: "rollup-plugin-esbuild@npm:4.10.3" +"rollup-plugin-esbuild@npm:^6.1.1": + version: 6.1.1 + resolution: "rollup-plugin-esbuild@npm:6.1.1" dependencies: - "@rollup/pluginutils": ^4.1.1 - debug: ^4.3.3 - es-module-lexer: ^0.9.3 - joycon: ^3.0.1 - jsonc-parser: ^3.0.0 + "@rollup/pluginutils": ^5.0.5 + debug: ^4.3.4 + es-module-lexer: ^1.3.1 + get-tsconfig: ^4.7.2 peerDependencies: - esbuild: ">=0.10.1" - rollup: ^1.20.0 || ^2.0.0 - checksum: 490a6a77573672cfda64a0222bb0dc2c202060bf4e9162571e24f2c26689e0e9faffced9c409eac80b35943dab06d1f0bd8bb3e2d3c6957b6bac1c0d6e5155cc + esbuild: ">=0.18.0" + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 + checksum: b027ddfbc9519f6f6aa41537b102ea23a38df588686b86d62ebd40441dd7cc8ca8e227dcaea92fc7ae8a42dc57a9975a3b184771e0eeb4c1fbe6296f10ef9da5 languageName: node linkType: hard @@ -41149,20 +37249,6 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^2.60.2": - version: 2.79.1 - resolution: "rollup@npm:2.79.1" - dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 6a2bf167b3587d4df709b37d149ad0300692cc5deb510f89ac7bdc77c8738c9546ae3de9322b0968e1ed2b0e984571f5f55aae28fa7de4cfcb1bc5402a4e2be6 - languageName: node - linkType: hard - "rollup@npm:^3.27.1": version: 3.29.4 resolution: "rollup@npm:3.29.4" @@ -41177,6 +37263,69 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.0.0": + version: 4.16.2 + resolution: "rollup@npm:4.16.2" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.16.2 + "@rollup/rollup-android-arm64": 4.16.2 + "@rollup/rollup-darwin-arm64": 4.16.2 + "@rollup/rollup-darwin-x64": 4.16.2 + "@rollup/rollup-linux-arm-gnueabihf": 4.16.2 + "@rollup/rollup-linux-arm-musleabihf": 4.16.2 + "@rollup/rollup-linux-arm64-gnu": 4.16.2 + "@rollup/rollup-linux-arm64-musl": 4.16.2 + "@rollup/rollup-linux-powerpc64le-gnu": 4.16.2 + "@rollup/rollup-linux-riscv64-gnu": 4.16.2 + "@rollup/rollup-linux-s390x-gnu": 4.16.2 + "@rollup/rollup-linux-x64-gnu": 4.16.2 + "@rollup/rollup-linux-x64-musl": 4.16.2 + "@rollup/rollup-win32-arm64-msvc": 4.16.2 + "@rollup/rollup-win32-ia32-msvc": 4.16.2 + "@rollup/rollup-win32-x64-msvc": 4.16.2 + "@types/estree": 1.0.5 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: ae20184e8c53cb2167873f6423524143c012b8df36f7b7c2fe40a440206453b8043fec48d8eb9ed184710b94e92a7195b2d4074854906763602267cba5bb72f9 + languageName: node + linkType: hard + "root@workspace:.": version: 0.0.0-use.local resolution: "root@workspace:." @@ -41191,14 +37340,14 @@ __metadata: "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 "@playwright/test": ^1.32.3 - "@spotify/eslint-plugin": ^14.1.3 - "@spotify/prettier-config": ^14.0.0 + "@spotify/eslint-plugin": ^15.0.0 + "@spotify/prettier-config": ^15.0.0 "@techdocs/cli": "workspace:*" "@types/node": ^18.17.8 "@types/webpack": ^5.28.0 "@useoptic/optic": ^0.50.10 + array-to-table: ^1.0.1 command-exists: ^1.2.9 - concurrently: ^8.0.0 cross-env: ^7.0.0 e2e-test: "workspace:*" eslint: ^8.6.0 @@ -41215,43 +37364,11 @@ __metadata: semver: ^7.5.3 shx: ^0.3.2 sloc: ^0.3.1 - ts-node: ^10.4.0 + sort-package-json: ^2.8.0 typescript: ~5.1.0 languageName: unknown linkType: soft -"rrdom@npm:^2.0.0-alpha.11": - version: 2.0.0-alpha.11 - resolution: "rrdom@npm:2.0.0-alpha.11" - dependencies: - rrweb-snapshot: ^2.0.0-alpha.11 - checksum: cfc8f18698902224bd4b666586497b2682d3d11e30946c2b9fe374b8209d977c0d6c4157231a2a4bfed12761a79db1cbc9a139741a9b3d7c943536cd9eb3bb50 - languageName: node - linkType: hard - -"rrweb-snapshot@npm:^2.0.0-alpha.11": - version: 2.0.0-alpha.11 - resolution: "rrweb-snapshot@npm:2.0.0-alpha.11" - checksum: 8b5e40ebe17d61546f9c93b4cc266156be0fc28b7452e4fea6ea4c24a35a857c021e15503d218f10d3fc8c478c793450f1f2ebf9c751c1d7a24e25322b9d1677 - languageName: node - linkType: hard - -"rrweb@npm:2.0.0-alpha.11": - version: 2.0.0-alpha.11 - resolution: "rrweb@npm:2.0.0-alpha.11" - dependencies: - "@rrweb/types": ^2.0.0-alpha.11 - "@types/css-font-loading-module": 0.0.7 - "@xstate/fsm": ^1.4.0 - base64-arraybuffer: ^1.0.1 - fflate: ^0.4.4 - mitt: ^3.0.0 - rrdom: ^2.0.0-alpha.11 - rrweb-snapshot: ^2.0.0-alpha.11 - checksum: f601d1b96f3a3622551b5f12f08d53cee272ebc23a61ed722a8687b2b8cb89ff6f7813a44eaa905afcaadd3e37e6055201474de0bd010720f45ecaaf2a0b4d01 - languageName: node - linkType: hard - "rtl-css-js@npm:^1.16.1": version: 1.16.1 resolution: "rtl-css-js@npm:1.16.1" @@ -41261,6 +37378,13 @@ __metadata: languageName: node linkType: hard +"run-applescript@npm:^7.0.0": + version: 7.0.0 + resolution: "run-applescript@npm:7.0.0" + checksum: b02462454d8b182ad4117e5d4626e9e6782eb2072925c9fac582170b0627ae3c1ea92ee9b2df7daf84b5e9ffe14eb1cf5fb70bc44b15c8a0bfcdb47987e2410c + languageName: node + linkType: hard + "run-async@npm:^2.4.0": version: 2.4.0 resolution: "run-async@npm:2.4.0" @@ -41293,7 +37417,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.1, rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.8.1": +"rxjs@npm:7.8.1, rxjs@npm:^7.2.0, rxjs@npm:^7.5.5": version: 7.8.1 resolution: "rxjs@npm:7.8.1" dependencies: @@ -41320,15 +37444,15 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.0.1": - version: 1.0.1 - resolution: "safe-array-concat@npm:1.0.1" +"safe-array-concat@npm:^1.1.2": + version: 1.1.2 + resolution: "safe-array-concat@npm:1.1.2" dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.2.1 + call-bind: ^1.0.7 + get-intrinsic: ^1.2.4 has-symbols: ^1.0.3 isarray: ^2.0.5 - checksum: 001ecf1d8af398251cbfabaf30ed66e3855127fbceee178179524b24160b49d15442f94ed6c0db0b2e796da76bb05b73bf3cc241490ec9c2b741b41d33058581 + checksum: a3b259694754ddfb73ae0663829e396977b99ff21cbe8607f35a469655656da8e271753497e59da8a7575baa94d2e684bea3e10ddd74ba046c0c9b4418ffa0c4 languageName: node linkType: hard @@ -41353,14 +37477,14 @@ __metadata: languageName: node linkType: hard -"safe-regex-test@npm:^1.0.0": - version: 1.0.0 - resolution: "safe-regex-test@npm:1.0.0" +"safe-regex-test@npm:^1.0.3": + version: 1.0.3 + resolution: "safe-regex-test@npm:1.0.3" dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.3 + call-bind: ^1.0.6 + es-errors: ^1.3.0 is-regex: ^1.1.4 - checksum: bc566d8beb8b43c01b94e67de3f070fd2781685e835959bbbaaec91cc53381145ca91f69bd837ce6ec244817afa0a5e974fc4e40a2957f0aca68ac3add1ddd34 + checksum: 6c7d392ff1ae7a3ae85273450ed02d1d131f1d2c76e177d6b03eb88e6df8fa062639070e7d311802c1615f351f18dc58f9454501c58e28d5ffd9b8f502ba6489 languageName: node linkType: hard @@ -41460,15 +37584,15 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0": - version: 4.0.0 - resolution: "schema-utils@npm:4.0.0" +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0": + version: 4.2.0 + resolution: "schema-utils@npm:4.2.0" dependencies: "@types/json-schema": ^7.0.9 - ajv: ^8.8.0 + ajv: ^8.9.0 ajv-formats: ^2.1.1 - ajv-keywords: ^5.0.0 - checksum: c843e92fdd1a5c145dbb6ffdae33e501867f9703afac67bdf35a685e49f85b1dcc10ea250033175a64bd9d31f0555bc6785b8359da0c90bcea30cf6dfbb55a8f + ajv-keywords: ^5.1.0 + checksum: 26a0463d47683258106e6652e9aeb0823bf0b85843039e068b57da1892f7ae6b6b1094d48e9ed5ba5cbe9f7166469d880858b9d91abe8bd249421eb813850cde languageName: node linkType: hard @@ -41509,14 +37633,7 @@ __metadata: languageName: node linkType: hard -"select@npm:^1.1.2": - version: 1.1.2 - resolution: "select@npm:1.1.2" - checksum: 4346151e94f226ea6131e44e68e6d837f3fdee64831b756dd657cc0b02f4cb5107f867cb34a1d1216ab7737d0bf0645d44546afb030bbd8d64e891f5e4c4814e - languageName: node - linkType: hard - -"selfsigned@npm:^2.0.0, selfsigned@npm:^2.1.1": +"selfsigned@npm:^2.0.0, selfsigned@npm:^2.4.1": version: 2.4.1 resolution: "selfsigned@npm:2.4.1" dependencies: @@ -41569,7 +37686,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.0, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.4.0, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:7.6.0, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.4.0, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": version: 7.6.0 resolution: "semver@npm:7.6.0" dependencies: @@ -41701,15 +37818,17 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.1.1": - version: 1.1.1 - resolution: "set-function-length@npm:1.1.1" +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" dependencies: - define-data-property: ^1.1.1 - get-intrinsic: ^1.2.1 + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 gopd: ^1.0.1 - has-property-descriptors: ^1.0.0 - checksum: c131d7569cd7e110cafdfbfbb0557249b538477624dfac4fc18c376d879672fa52563b74029ca01f8f4583a8acb35bb1e873d573a24edb80d978a7ee607c6e06 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 languageName: node linkType: hard @@ -41871,14 +37990,15 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: - call-bind: ^1.0.0 - get-intrinsic: ^1.0.2 - object-inspect: ^1.9.0 - checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 + call-bind: ^1.0.7 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 languageName: node linkType: hard @@ -42039,13 +38159,6 @@ __metadata: languageName: node linkType: hard -"slugify@npm:^1.6.4": - version: 1.6.6 - resolution: "slugify@npm:1.6.6" - checksum: 04773c2d3b7aea8d2a61fa47cc7e5d29ce04e1a96cbaec409da57139df906acb3a449fac30b167d203212c806e73690abd4ff94fbad0a9a7b7ea109a2a638ae9 - languageName: node - linkType: hard - "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -42076,7 +38189,7 @@ __metadata: languageName: node linkType: hard -"smtp-address-parser@npm:^1.0.3": +"smtp-address-parser@npm:1.0.10, smtp-address-parser@npm:^1.0.3": version: 1.0.10 resolution: "smtp-address-parser@npm:1.0.10" dependencies: @@ -42149,6 +38262,31 @@ __metadata: languageName: node linkType: hard +"sort-object-keys@npm:^1.1.3": + version: 1.1.3 + resolution: "sort-object-keys@npm:1.1.3" + checksum: abea944d6722a1710a1aa6e4f9509da085d93d5fc0db23947cb411eedc7731f80022ce8fa68ed83a53dd2ac7441fcf72a3f38c09b3d9bbc4ff80546aa2e151ad + languageName: node + linkType: hard + +"sort-package-json@npm:^2.8.0": + version: 2.10.0 + resolution: "sort-package-json@npm:2.10.0" + dependencies: + detect-indent: ^7.0.1 + detect-newline: ^4.0.0 + get-stdin: ^9.0.0 + git-hooks-list: ^3.0.0 + globby: ^13.1.2 + is-plain-obj: ^4.1.0 + semver: ^7.6.0 + sort-object-keys: ^1.1.3 + bin: + sort-package-json: cli.js + checksum: 095e5c5075c9799d3d6174f82e963fa3be0a1d193af0be656b651d2e5b563dfc794f46c7aa74e3fc761de3fba76951ad2d3de716cf50b3aca4e938f63edbfcae + languageName: node + linkType: hard + "source-list-map@npm:^2.0.0": version: 2.0.1 resolution: "source-list-map@npm:2.0.1" @@ -42156,10 +38294,10 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.2": - version: 1.0.2 - resolution: "source-map-js@npm:1.0.2" - checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c +"source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97 languageName: node linkType: hard @@ -42211,7 +38349,7 @@ __metadata: languageName: node linkType: hard -"sourcemap-codec@npm:^1.4.4, sourcemap-codec@npm:^1.4.8": +"sourcemap-codec@npm:^1.4.4": version: 1.4.8 resolution: "sourcemap-codec@npm:1.4.8" checksum: b57981c05611afef31605732b598ccf65124a9fcb03b833532659ac4d29ac0f7bfacbc0d6c5a28a03e84c7510e7e556d758d0bb57786e214660016fb94279316 @@ -42232,7 +38370,7 @@ __metadata: languageName: node linkType: hard -"spawn-command@npm:0.0.2, spawn-command@npm:^0.0.2-1": +"spawn-command@npm:^0.0.2-1": version: 0.0.2 resolution: "spawn-command@npm:0.0.2" checksum: e35c5d28177b4d461d33c88cc11f6f3a5079e2b132c11e1746453bbb7a0c0b8a634f07541a2a234fa4758239d88203b758def509161b651e81958894c0b4b64b @@ -42628,10 +38766,10 @@ __metadata: languageName: node linkType: hard -"stream-shift@npm:^1.0.0": - version: 1.0.1 - resolution: "stream-shift@npm:1.0.1" - checksum: 59b82b44b29ec3699b5519a49b3cedcc6db58c72fb40c04e005525dfdcab1c75c4e0c180b923c380f204bed78211b9bad8faecc7b93dece4d004c3f6ec75737b +"stream-shift@npm:^1.0.0, stream-shift@npm:^1.0.2": + version: 1.0.3 + resolution: "stream-shift@npm:1.0.3" + checksum: a24c0a3f66a8f9024bd1d579a533a53be283b4475d4e6b4b3211b964031447bdf6532dd1f3c2b0ad66752554391b7c62bd7ca4559193381f766534e723d50242 languageName: node linkType: hard @@ -42651,13 +38789,17 @@ __metadata: languageName: node linkType: hard -"streamx@npm:^2.15.0": - version: 2.15.5 - resolution: "streamx@npm:2.15.5" +"streamx@npm:^2.13.0, streamx@npm:^2.15.0": + version: 2.16.1 + resolution: "streamx@npm:2.16.1" dependencies: + bare-events: ^2.2.0 fast-fifo: ^1.1.0 queue-tick: ^1.0.1 - checksum: 52e0ec94026d67c9e2e2e1090f05e5b138c2f2822462d9a8ef4a4805625a31d103e55ea5267fcd9bfe041374926424e42aec2dda28a85cb9de42c2a16d416d94 + dependenciesMeta: + bare-events: + optional: true + checksum: 6bbb4c38c0ab6ddbe0857d55e72f71288f308f2a9f4413b7b07391cdf9f94232ffc2bbe40a1212d2e09634ecdbd5052b444c73cc8d67ae1c97e2b7e553dad559 languageName: node linkType: hard @@ -42762,26 +38904,20 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.8": - version: 4.0.8 - resolution: "string.prototype.matchall@npm:4.0.8" +"string.prototype.matchall@npm:^4.0.10": + version: 4.0.10 + resolution: "string.prototype.matchall@npm:4.0.10" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - get-intrinsic: ^1.1.3 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + get-intrinsic: ^1.2.1 has-symbols: ^1.0.3 - internal-slot: ^1.0.3 - regexp.prototype.flags: ^1.4.3 + internal-slot: ^1.0.5 + regexp.prototype.flags: ^1.5.0 + set-function-name: ^2.0.0 side-channel: ^1.0.4 - checksum: 952da3a818de42ad1c10b576140a5e05b4de7b34b8d9dbf00c3ac8c1293e9c0f533613a39c5cda53e0a8221f2e710bc2150e730b1c2278d60004a8a35726efb6 - languageName: node - linkType: hard - -"string.prototype.repeat@npm:^0.2.0": - version: 0.2.0 - resolution: "string.prototype.repeat@npm:0.2.0" - checksum: 5127ce1b5bce45258905877048ac28bae71be18f1c3421011bd3979cfbcacf9c16f6b7f42daa3b999c9d90f5da39bd7136982c8e64439f02666dd6c0778ed262 + checksum: 3c78bdeff39360c8e435d7c4c6ea19f454aa7a63eda95fa6fadc3a5b984446a2f9f2c02d5c94171ce22268a573524263fbd0c8edbe3ce2e9890d7cc036cdc3ed languageName: node linkType: hard @@ -43070,21 +39206,6 @@ __metadata: languageName: node linkType: hard -"subscriptions-transport-ws@npm:^0.11.0": - version: 0.11.0 - resolution: "subscriptions-transport-ws@npm:0.11.0" - 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 - peerDependencies: - graphql: ^15.7.2 || ^16.0.0 - checksum: cc2e98d5c9d89c44d2e15eca188781c6ebae13d1661c42a99cee9d2897aebe2a22bc118eefff83244a79c88ee4ea24d46973ebf26ae7cb47ac1857fb8ee2c947 - languageName: node - linkType: hard - "sucrase@npm:^3.20.2": version: 3.35.0 resolution: "sucrase@npm:3.35.0" @@ -43181,13 +39302,6 @@ __metadata: languageName: node linkType: hard -"svg-pan-zoom@npm:^3.6.0": - version: 3.6.1 - resolution: "svg-pan-zoom@npm:3.6.1" - checksum: 500b99378d321315e1668067ef6a73af3f61f9adfab75a575b21d2d216cb446def61d60ad12265203463cca9bef56b090f00e48118fa9b7f0ffa1c691e4c1621 - languageName: node - linkType: hard - "svg-parser@npm:^2.0.4": version: 2.0.4 resolution: "svg-parser@npm:2.0.4" @@ -43212,41 +39326,40 @@ __metadata: languageName: node linkType: hard -"swagger-client@npm:^3.25.0": - version: 3.25.0 - resolution: "swagger-client@npm:3.25.0" +"swagger-client@npm:^3.27.0": + version: 3.27.0 + resolution: "swagger-client@npm:3.27.0" dependencies: "@babel/runtime-corejs3": ^7.22.15 - "@swagger-api/apidom-core": ">=0.90.0 <1.0.0" - "@swagger-api/apidom-error": ">=0.90.0 <1.0.0" - "@swagger-api/apidom-json-pointer": ">=0.90.0 <1.0.0" - "@swagger-api/apidom-ns-openapi-3-1": ">=0.90.0 <1.0.0" - "@swagger-api/apidom-reference": ">=0.90.0 <1.0.0" + "@swagger-api/apidom-core": ">=0.99.1 <1.0.0" + "@swagger-api/apidom-error": ">=0.99.0 <1.0.0" + "@swagger-api/apidom-json-pointer": ">=0.99.1 <1.0.0" + "@swagger-api/apidom-ns-openapi-3-1": ">=0.99.1 <1.0.0" + "@swagger-api/apidom-reference": ">=0.99.1 <1.0.0" cookie: ~0.6.0 deepmerge: ~4.3.0 fast-json-patch: ^3.0.0-1 is-plain-object: ^5.0.0 js-yaml: ^4.1.0 node-abort-controller: ^3.1.1 - node-fetch-commonjs: ^3.3.1 + node-fetch-commonjs: ^3.3.2 qs: ^6.10.2 traverse: ~0.6.6 - undici: ^5.24.0 - checksum: 2e989059b4edeab26b148993cea8a68c4ad34927d4058479f2722c01d8bd0f67bfb1f69dc93ce24a5adb5a8e0f45e4438ad38f8bfb70f8d0b1a8d66650abe060 + checksum: 7279ea2cb96dee71c428f758a7d983ee0a143cbcb1c11432d02327f1e4c65d39ca78f1c39dab7771cda54a4e04c57b33936287f23e663181c5058cbd2aea7477 languageName: node linkType: hard "swagger-ui-react@npm:^5.0.0": - version: 5.11.7 - resolution: "swagger-ui-react@npm:5.11.7" + version: 5.17.0 + resolution: "swagger-ui-react@npm:5.17.0" dependencies: - "@babel/runtime-corejs3": ^7.23.9 - "@braintree/sanitize-url": =7.0.0 + "@babel/runtime-corejs3": ^7.24.4 + "@braintree/sanitize-url": =7.0.1 base64-js: ^1.5.1 classnames: ^2.5.1 css.escape: 1.5.1 deep-extend: 0.6.0 - dompurify: =3.0.8 + dompurify: =3.1.0 ieee754: ^1.2.1 immutable: ^3.x.x js-file-download: ^0.4.12 @@ -43261,7 +39374,7 @@ __metadata: react-immutable-proptypes: 2.2.0 react-immutable-pure-component: ^2.2.0 react-inspector: ^6.0.1 - react-redux: ^9.1.0 + react-redux: ^9.1.1 react-syntax-highlighter: ^15.5.0 redux: ^5.0.1 redux-immutable: ^4.0.0 @@ -43269,7 +39382,7 @@ __metadata: reselect: ^5.1.0 serialize-error: ^8.1.0 sha.js: ^2.4.11 - swagger-client: ^3.25.0 + swagger-client: ^3.27.0 url-parse: ^1.5.10 xml: =1.0.1 xml-but-prettier: ^1.0.1 @@ -43277,7 +39390,7 @@ __metadata: peerDependencies: react: ">=16.8.0 <19" react-dom: ">=16.8.0 <19" - checksum: b4589abe7d4cdc97fd05f8f8f8b40daee33bb4604faa1f9c513b3ef4765fc407fef37c704dbc56c5493fa5430472e8cb30921a4d4ba544372266d06ef4d1b1e6 + checksum: f7c0820b9bd5fe5e1ed2ab6118a56aab31176ce3e6693f489d6915d33c70bfd6b9aa3122cbd371d722a917c1395b863b2f0483515f62e7f5e180fa310eefdca0 languageName: node linkType: hard @@ -43305,7 +39418,7 @@ __metadata: languageName: node linkType: hard -"symbol-observable@npm:1.2.0, symbol-observable@npm:^1.0.4, symbol-observable@npm:^1.1.0": +"symbol-observable@npm:^1.0.4": version: 1.2.0 resolution: "symbol-observable@npm:1.2.0" checksum: 48ffbc22e3d75f9853b3ff2ae94a44d84f386415110aea5effc24d84c502e03a4a6b7a8f75ebaf7b585780bda34eb5d6da3121f826a6f93398429d30032971b6 @@ -43333,7 +39446,24 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^2.0.0, tar-fs@npm:^2.1.1": +"tar-fs@npm:3.0.5, tar-fs@npm:^3.0.5": + version: 3.0.5 + resolution: "tar-fs@npm:3.0.5" + dependencies: + bare-fs: ^2.1.1 + bare-path: ^2.1.0 + pump: ^3.0.0 + tar-stream: ^3.1.5 + dependenciesMeta: + bare-fs: + optional: true + bare-path: + optional: true + checksum: e31c7e3e525fec0afecdec1cac58071809e396187725f2eba442f08a4c5649c8cd6b7ce25982f9a91bb0f055628df47c08177dd2ea4f5dafd3c22f42f8da8f00 + languageName: node + linkType: hard + +"tar-fs@npm:^2.0.0": version: 2.1.1 resolution: "tar-fs@npm:2.1.1" dependencies: @@ -43370,20 +39500,20 @@ __metadata: languageName: node linkType: hard -"tar-stream@npm:^3.0.0": - version: 3.1.6 - resolution: "tar-stream@npm:3.1.6" +"tar-stream@npm:^3.0.0, tar-stream@npm:^3.1.5": + version: 3.1.7 + resolution: "tar-stream@npm:3.1.7" dependencies: b4a: ^1.6.4 fast-fifo: ^1.2.0 streamx: ^2.15.0 - checksum: f3627f918581976e954ff03cb8d370551053796b82564f8c7ca8fac84c48e4d042026d0854fc222171a34ff9c682b72fae91be9c9b0a112d4c54f9e4f443e9c5 + checksum: 6393a6c19082b17b8dcc8e7fd349352bb29b4b8bfe1075912b91b01743ba6bb4298f5ff0b499a3bbaf82121830e96a1a59d4f21a43c0df339e54b01789cb8cc6 languageName: node linkType: hard "tar@npm:^6.0.2, tar@npm:^6.1.0, tar@npm:^6.1.11, tar@npm:^6.1.12, tar@npm:^6.1.2": - version: 6.2.0 - resolution: "tar@npm:6.2.0" + version: 6.2.1 + resolution: "tar@npm:6.2.1" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 @@ -43391,7 +39521,7 @@ __metadata: minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: db4d9fe74a2082c3a5016630092c54c8375ff3b280186938cfd104f2e089c4fd9bad58688ef6be9cf186a889671bf355c7cda38f09bbf60604b281715ca57f5c + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c languageName: node linkType: hard @@ -43436,9 +39566,9 @@ __metadata: "@backstage/theme": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@testing-library/dom": ^9.0.0 + "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 - "@testing-library/react": ^14.0.0 + "@testing-library/react": ^15.0.0 "@testing-library/user-event": ^14.0.0 "@types/react": "*" "@types/react-dom": "*" @@ -43527,23 +39657,26 @@ __metadata: languageName: node linkType: hard -"testcontainers@npm:^8.1.2": - version: 8.16.0 - resolution: "testcontainers@npm:8.16.0" +"testcontainers@npm:^10.0.0": + version: 10.8.2 + resolution: "testcontainers@npm:10.8.2" dependencies: "@balena/dockerignore": ^1.0.2 - "@types/archiver": ^5.3.1 - "@types/dockerode": ^3.3.8 - archiver: ^5.3.1 + "@types/dockerode": ^3.3.24 + archiver: ^5.3.2 + async-lock: ^1.4.1 byline: ^5.0.0 debug: ^4.3.4 - docker-compose: ^0.23.17 - dockerode: ^3.3.1 + docker-compose: ^0.24.6 + dockerode: ^3.3.5 get-port: ^5.1.1 - properties-reader: ^2.2.0 + node-fetch: ^2.7.0 + proper-lockfile: ^4.1.2 + properties-reader: ^2.3.0 ssh-remote-port-forward: ^1.0.4 - tar-fs: ^2.1.1 - checksum: 2fb8250591691a4bd86640b53e13236ad507ba9e03ac3043683de5e9dd632bc29d52827c22ccfe2b0d28dec6896cbaa56dcb153ce65f7f74212ddefc204e8d6a + tar-fs: ^3.0.5 + tmp: ^0.2.1 + checksum: 3a97ad705c98abc5066577699be5e791090ef2a5c45fee3a203196fa09d0cb66c7709f6ae8168c025ed97a07f1f5f0676a34e748680514e732e90671720d34c6 languageName: node linkType: hard @@ -43609,7 +39742,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:^2.3.6": +"through@npm:2, through@npm:^2.3.6, through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -43656,14 +39789,14 @@ __metadata: languageName: node linkType: hard -"tiny-emitter@npm:^2.0.0": - version: 2.1.0 - resolution: "tiny-emitter@npm:2.1.0" - checksum: fbcfb5145751a0e3b109507a828eb6d6d4501352ab7bb33eccef46e22e9d9ad3953158870a6966a59e57ab7c3f9cfac7cab8521db4de6a5e757012f4677df2dd +"tiny-case@npm:^1.0.3": + version: 1.0.3 + resolution: "tiny-case@npm:1.0.3" + checksum: 3f7a30c39d5b0e1bc097b0b271bec14eb5b836093db034f35a0de26c14422380b50dc12bfd37498cf35b192f5df06f28a710712c87ead68872a9e37ad6f6049d languageName: node linkType: hard -"tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1": +"tiny-invariant@npm:^1.0.6": version: 1.3.1 resolution: "tiny-invariant@npm:1.3.1" checksum: 872dbd1ff20a21303a2fd20ce3a15602cfa7fcf9b228bd694a52e2938224313b5385a1078cb667ed7375d1612194feaca81c4ecbe93121ca1baebe344de4f84c @@ -43686,6 +39819,15 @@ __metadata: languageName: node linkType: hard +"tmp@npm:^0.2.1": + version: 0.2.1 + resolution: "tmp@npm:0.2.1" + dependencies: + rimraf: ^3.0.0 + checksum: 8b1214654182575124498c87ca986ac53dc76ff36e8f0e0b67139a8d221eaecfdec108c0e6ec54d76f49f1f72ab9325500b246f562b926f85bcdfca8bf35df9e + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -43860,13 +40002,13 @@ __metadata: languageName: node linkType: hard -"tree-sitter-json@npm:=0.20.1": - version: 0.20.1 - resolution: "tree-sitter-json@npm:0.20.1" +"tree-sitter-json@npm:=0.20.2": + version: 0.20.2 + resolution: "tree-sitter-json@npm:0.20.2" dependencies: nan: ^2.18.0 node-gyp: latest - checksum: fb77f3e3f148a4ce48a58ac478c5ab12fb5ea29b426fbf4978f07c659de982bfa62268c556e262ecc3ef192d50f7e6f6fe650abd566e6be87debb31332c81a26 + checksum: 4f5eba7fc86855d15510647e3e5803ea05a8cd5ab2a2a25c8d173a103ca02a6cc25b4cc925b3d234e31e6180f7eed4a50351d39e2c5254b06d6dd0fabeb6c3d8 languageName: node linkType: hard @@ -43972,6 +40114,13 @@ __metadata: languageName: node linkType: hard +"ts-mixer@npm:^6.0.3": + version: 6.0.4 + resolution: "ts-mixer@npm:6.0.4" + checksum: 36b1af526befd74345e736e9aa16f5c28876ebcea07784da14d929149fd7e6028cfd2fe9304c8efe8cb91b588443a9cc9e991df58e4c6e602326edbaae2af3ab + languageName: node + linkType: hard + "ts-morph@npm:^21.0.0": version: 21.0.1 resolution: "ts-morph@npm:21.0.1" @@ -43982,7 +40131,7 @@ __metadata: languageName: node linkType: hard -"ts-node@npm:^10.0.0, ts-node@npm:^10.4.0, ts-node@npm:^10.9.1": +"ts-node@npm:^10.9.1": version: 10.9.2 resolution: "ts-node@npm:10.9.2" dependencies: @@ -44053,7 +40202,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.10.0, tslib@npm:^1.11.1, tslib@npm:^1.14.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": +"tslib@npm:^1.11.1, tslib@npm:^1.14.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd @@ -44071,22 +40220,6 @@ __metadata: languageName: node linkType: hard -"tsx@npm:^4.0.0": - version: 4.7.1 - resolution: "tsx@npm:4.7.1" - dependencies: - esbuild: ~0.19.10 - fsevents: ~2.3.3 - get-tsconfig: ^4.7.2 - dependenciesMeta: - fsevents: - optional: true - bin: - tsx: dist/cli.mjs - checksum: 7f77294c0eee9a9b203f89eb299ee80b393d6b4bf79ec01b650502213a23ea08d0dfc52e938b302ef27c97b70557f7f5a590c3174a7e3c8f1140c668eea4a3a2 - languageName: node - linkType: hard - "tty-browserify@npm:0.0.0": version: 0.0.0 resolution: "tty-browserify@npm:0.0.0" @@ -44222,7 +40355,7 @@ __metadata: languageName: node linkType: hard -"type-is@npm:^1.6.4, type-is@npm:~1.6.18": +"type-is@npm:^1.6.18, type-is@npm:^1.6.4, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" dependencies: @@ -44246,50 +40379,55 @@ __metadata: languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.0": - version: 1.0.0 - resolution: "typed-array-buffer@npm:1.0.0" +"typed-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-buffer@npm:1.0.2" dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.2.1 - is-typed-array: ^1.1.10 - checksum: 3e0281c79b2a40cd97fe715db803884301993f4e8c18e8d79d75fd18f796e8cd203310fec8c7fdb5e6c09bedf0af4f6ab8b75eb3d3a85da69328f28a80456bd3 + call-bind: ^1.0.7 + es-errors: ^1.3.0 + is-typed-array: ^1.1.13 + checksum: 02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b languageName: node linkType: hard -"typed-array-byte-length@npm:^1.0.0": - version: 1.0.0 - resolution: "typed-array-byte-length@npm:1.0.0" +"typed-array-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "typed-array-byte-length@npm:1.0.1" dependencies: - call-bind: ^1.0.2 + call-bind: ^1.0.7 for-each: ^0.3.3 - has-proto: ^1.0.1 - is-typed-array: ^1.1.10 - checksum: b03db16458322b263d87a702ff25388293f1356326c8a678d7515767ef563ef80e1e67ce648b821ec13178dd628eb2afdc19f97001ceae7a31acf674c849af94 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + checksum: f65e5ecd1cf76b1a2d0d6f631f3ea3cdb5e08da106c6703ffe687d583e49954d570cc80434816d3746e18be889ffe53c58bf3e538081ea4077c26a41055b216d languageName: node linkType: hard -"typed-array-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "typed-array-byte-offset@npm:1.0.0" +"typed-array-byte-offset@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-byte-offset@npm:1.0.2" dependencies: - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.2 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 for-each: ^0.3.3 - has-proto: ^1.0.1 - is-typed-array: ^1.1.10 - checksum: 04f6f02d0e9a948a95fbfe0d5a70b002191fae0b8fe0fe3130a9b2336f043daf7a3dda56a31333c35a067a97e13f539949ab261ca0f3692c41603a46a94e960b + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + checksum: c8645c8794a621a0adcc142e0e2c57b1823bbfa4d590ad2c76b266aa3823895cf7afb9a893bf6685e18454ab1b0241e1a8d885a2d1340948efa4b56add4b5f67 languageName: node linkType: hard -"typed-array-length@npm:^1.0.4": - version: 1.0.4 - resolution: "typed-array-length@npm:1.0.4" +"typed-array-length@npm:^1.0.5": + version: 1.0.5 + resolution: "typed-array-length@npm:1.0.5" dependencies: - call-bind: ^1.0.2 + call-bind: ^1.0.7 for-each: ^0.3.3 - is-typed-array: ^1.1.9 - checksum: 2228febc93c7feff142b8c96a58d4a0d7623ecde6c7a24b2b98eb3170e99f7c7eff8c114f9b283085cd59dcd2bd43aadf20e25bba4b034a53c5bb292f71f8956 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + possible-typed-array-names: ^1.0.0 + checksum: 82f5b666155cff1b345a1f3ab018d3f7667990f525435e4c8448cc094ab0f8ea283bb7cbde4d7bc82ea0b9b1072523bf31e86620d72615951d7fa9ccb4f42dfa languageName: node linkType: hard @@ -44376,21 +40514,21 @@ __metadata: "typescript@patch:typescript@~5.0.4#~builtin": version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=a1c5e5" + resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=b5f058" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 6a1fe9a77bb9c5176ead919cc4a1499ee63e46b4e05bf667079f11bf3a8f7887f135aa72460a4c3b016e6e6bb65a822cb8689a6d86cbfe92d22cc9f501f09213 + checksum: d26b6ba97b6d163c55dbdffd9bbb4c211667ebebc743accfeb2c8c0154aace7afd097b51165a72a5bad2cf65a4612259344ff60f8e642362aa1695c760d303ac languageName: node linkType: hard "typescript@patch:typescript@~5.1.0#~builtin": version: 5.1.6 - resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=a1c5e5" + resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin::version=5.1.6&hash=5da071" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 21e88b0a0c0226f9cb9fd25b9626fb05b4c0f3fddac521844a13e1f30beb8f14e90bd409a9ac43c812c5946d714d6e0dee12d5d02dfc1c562c5aacfa1f49b606 + checksum: f53bfe97f7c8b2b6d23cf572750d4e7d1e0c5fff1c36d859d0ec84556a827b8785077bc27676bf7e71fae538e517c3ecc0f37e7f593be913d884805d931bc8be languageName: node linkType: hard @@ -44461,6 +40599,16 @@ __metadata: languageName: node linkType: hard +"unbzip2-stream@npm:1.4.3": + version: 1.4.3 + resolution: "unbzip2-stream@npm:1.4.3" + dependencies: + buffer: ^5.2.1 + through: ^2.3.8 + checksum: 0e67c4a91f4fa0fc7b4045f8b914d3498c2fc2e8c39c359977708ec85ac6d6029840e97f508675fdbdf21fcb8d276ca502043406f3682b70f075e69aae626d1d + languageName: node + linkType: hard + "undefsafe@npm:^2.0.5": version: 2.0.5 resolution: "undefsafe@npm:2.0.5" @@ -44489,15 +40637,6 @@ __metadata: languageName: node linkType: hard -"undici@npm:^5.24.0": - version: 5.26.3 - resolution: "undici@npm:5.26.3" - dependencies: - "@fastify/busboy": ^2.0.0 - checksum: aaa9aadb712cf80e1a9cea2377e4842670105e00abbc184a21770ea5a8b77e4e2eadc200eac62442e74a1cd3b16a840c6f73b112b9e886bd3c1a125eb22e4f21 - languageName: node - linkType: hard - "unescape-js@npm:^1.0.5": version: 1.1.4 resolution: "unescape-js@npm:1.1.4" @@ -44867,6 +41006,13 @@ __metadata: languageName: node linkType: hard +"urlpattern-polyfill@npm:10.0.0": + version: 10.0.0 + resolution: "urlpattern-polyfill@npm:10.0.0" + checksum: 61d890f151ea4ecf34a3dcab32c65ad1f3cda857c9d154af198260c6e5b2ad96d024593409baaa6d4428dd1ab206c14799bf37fe011117ac93a6a44913ac5aa4 + languageName: node + linkType: hard + "urlpattern-polyfill@npm:^9.0.0": version: 9.0.0 resolution: "urlpattern-polyfill@npm:9.0.0" @@ -44898,18 +41044,6 @@ __metadata: languageName: node linkType: hard -"use-deep-compare-effect@npm:^1.8.1": - version: 1.8.1 - resolution: "use-deep-compare-effect@npm:1.8.1" - dependencies: - "@babel/runtime": ^7.12.5 - dequal: ^2.0.2 - peerDependencies: - react: ">=16.13" - checksum: 2b9b6291df3f772f44d259b352e5d998963ccee0db2efeb76bb05525d928064aeeb69bb0dee5a5e428fea7cf3db67c097a770ebd30caa080662b565f6ef02b2e - languageName: node - linkType: hard - "use-immer@npm:^0.9.0": version: 0.9.0 resolution: "use-immer@npm:0.9.0" @@ -45051,7 +41185,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:8.3.2, uuid@npm:^8.0.0, uuid@npm:^8.2.0, uuid@npm:^8.3.0, uuid@npm:^8.3.2": +"uuid@npm:8.3.2, uuid@npm:^8.0.0, uuid@npm:^8.3.0, uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" bin: @@ -45060,7 +41194,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^3.3.2": +"uuid@npm:^3.3.2, uuid@npm:^3.4.0": version: 3.4.0 resolution: "uuid@npm:3.4.0" bin: @@ -45273,28 +41407,6 @@ __metadata: languageName: node linkType: hard -"victory-vendor@npm:^36.6.8": - version: 36.6.8 - resolution: "victory-vendor@npm:36.6.8" - dependencies: - "@types/d3-array": ^3.0.3 - "@types/d3-ease": ^3.0.0 - "@types/d3-interpolate": ^3.0.1 - "@types/d3-scale": ^4.0.2 - "@types/d3-shape": ^3.1.0 - "@types/d3-time": ^3.0.0 - "@types/d3-timer": ^3.0.0 - d3-array: ^3.1.6 - d3-ease: ^3.0.1 - d3-interpolate: ^3.0.1 - d3-scale: ^4.0.2 - d3-shape: ^3.1.0 - d3-time: ^3.0.0 - d3-timer: ^3.0.1 - checksum: 6411f7c19a776cef3919946d429293cfe33c93a6e4dcfdfa2ba1edecad3a28ed2cd6b0d117169b8917ab6a7679e2bade5e7bfc1fed3fc8b464b842f21dac5f49 - languageName: node - linkType: hard - "vinyl-file@npm:^3.0.0": version: 3.0.0 resolution: "vinyl-file@npm:3.0.0" @@ -45357,8 +41469,8 @@ __metadata: linkType: hard "vite@npm:^4.4.9": - version: 4.5.2 - resolution: "vite@npm:4.5.2" + version: 4.5.3 + resolution: "vite@npm:4.5.3" dependencies: esbuild: ^0.18.10 fsevents: ~2.3.2 @@ -45392,14 +41504,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 9d1f84f703c2660aced34deee7f309278ed368880f66e9570ac115c793d91f7fffb80ab19c602b3c8bc1341fe23437d86a3fcca2a9ef82f7ef0cdac5a40d0c86 - languageName: node - linkType: hard - -"viz.js@npm:2.1.2": - version: 2.1.2 - resolution: "viz.js@npm:2.1.2" - checksum: 299e5a8519a472e0e98197c5f39c0ca6f3f6c4642b6ae007ed888fea998d82455c7ae0118d09cb888bfd2c46ebe3b03d7ce321a4eef1c822a5f5719d3a6ef3bb + checksum: fd3f512ce48ca2a1fe60ad0376283b832de9272725fdbc65064ae9248f792de87b0f27a89573115e23e26784800daca329f8a9234d298ba6f60e808a9c63883c languageName: node linkType: hard @@ -45481,31 +41586,13 @@ __metadata: languageName: node linkType: hard -"warning@npm:^3.0.0": - version: 3.0.0 - resolution: "warning@npm:3.0.0" - dependencies: - loose-envify: ^1.0.0 - checksum: c9f99a12803aab81b29858e7dc3415bf98b41baee3a4c3acdeb680d98c47b6e17490f1087dccc54432deed5711a5ce0ebcda2b27e9b5eb054c32ae50acb4419c - languageName: node - linkType: hard - -"warning@npm:^4.0.1": - version: 4.0.3 - resolution: "warning@npm:4.0.3" - dependencies: - loose-envify: ^1.0.0 - checksum: 4f2cb6a9575e4faf71ddad9ad1ae7a00d0a75d24521c193fa464f30e6b04027bd97aa5d9546b0e13d3a150ab402eda216d59c1d0f2d6ca60124d96cd40dfa35c - languageName: node - linkType: hard - -"watchpack@npm:^2.4.0": - version: 2.4.0 - resolution: "watchpack@npm:2.4.0" +"watchpack@npm:^2.4.1": + version: 2.4.1 + resolution: "watchpack@npm:2.4.1" dependencies: glob-to-regexp: ^0.4.1 graceful-fs: ^4.1.2 - checksum: 23d4bc58634dbe13b86093e01c6a68d8096028b664ab7139d58f0c37d962d549a940e98f2f201cecdabd6f9c340338dc73ef8bf094a2249ef582f35183d1a131 + checksum: 5b0179348655dcdf19cac7cb4ff923fdc024d630650c0bf6bec8899cf47c60e19d4f810a88dba692ed0e7f684cf0fcffea86efdbf6c35d81f031e328043b7fab languageName: node linkType: hard @@ -45554,13 +41641,6 @@ __metadata: languageName: node linkType: hard -"web-vitals@npm:^3.1.0": - version: 3.3.2 - resolution: "web-vitals@npm:3.3.2" - checksum: 76e832341d213d5de6f6767fef7f8c02163ab94326912a6355bbf6e194d930196ca5094b0d0d493b4c194acaaabcc96f0adc87870b913a7b9a51b225807abccf - languageName: node - linkType: hard - "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" @@ -45589,57 +41669,61 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^5.3.1": - version: 5.3.1 - resolution: "webpack-dev-middleware@npm:5.3.1" +"webpack-dev-middleware@npm:^7.1.0": + version: 7.2.1 + resolution: "webpack-dev-middleware@npm:7.2.1" dependencies: colorette: ^2.0.10 - memfs: ^3.4.1 + memfs: ^4.6.0 mime-types: ^2.1.31 + on-finished: ^2.4.1 range-parser: ^1.2.1 schema-utils: ^4.0.0 peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 32e36b5893dde4107e5bb758afdc7fc61fd238a62635cb2964ed6b61e363793275a40870479daeae3fa3b87678c1311f44ba7492f6ebf30fe9360f2aab30bae1 + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + checksum: bb8c75f7ceabc13ee2c3bc9648190e05a0a8c6d40b940ef72b09ea858a63d16bcb434b49995f1025125a1c3a1c8d40274beb5d26ef2fb1458b19e7f6fe3a91fe languageName: node linkType: hard -"webpack-dev-server@npm:^4.7.3": - version: 4.15.1 - resolution: "webpack-dev-server@npm:4.15.1" +"webpack-dev-server@npm:^5.0.0": + version: 5.0.4 + resolution: "webpack-dev-server@npm:5.0.4" dependencies: - "@types/bonjour": ^3.5.9 - "@types/connect-history-api-fallback": ^1.3.5 - "@types/express": ^4.17.13 - "@types/serve-index": ^1.9.1 - "@types/serve-static": ^1.13.10 - "@types/sockjs": ^0.3.33 - "@types/ws": ^8.5.5 + "@types/bonjour": ^3.5.13 + "@types/connect-history-api-fallback": ^1.5.4 + "@types/express": ^4.17.21 + "@types/serve-index": ^1.9.4 + "@types/serve-static": ^1.15.5 + "@types/sockjs": ^0.3.36 + "@types/ws": ^8.5.10 ansi-html-community: ^0.0.8 - bonjour-service: ^1.0.11 - chokidar: ^3.5.3 + bonjour-service: ^1.2.1 + chokidar: ^3.6.0 colorette: ^2.0.10 compression: ^1.7.4 connect-history-api-fallback: ^2.0.0 default-gateway: ^6.0.3 express: ^4.17.3 graceful-fs: ^4.2.6 - html-entities: ^2.3.2 + html-entities: ^2.4.0 http-proxy-middleware: ^2.0.3 - ipaddr.js: ^2.0.1 - launch-editor: ^2.6.0 - open: ^8.0.9 - p-retry: ^4.5.0 - rimraf: ^3.0.2 - schema-utils: ^4.0.0 - selfsigned: ^2.1.1 + ipaddr.js: ^2.1.0 + launch-editor: ^2.6.1 + open: ^10.0.3 + p-retry: ^6.2.0 + rimraf: ^5.0.5 + schema-utils: ^4.2.0 + selfsigned: ^2.4.1 serve-index: ^1.9.1 sockjs: ^0.3.24 spdy: ^4.0.2 - webpack-dev-middleware: ^5.3.1 - ws: ^8.13.0 + webpack-dev-middleware: ^7.1.0 + ws: ^8.16.0 peerDependencies: - webpack: ^4.37.0 || ^5.0.0 + webpack: ^5.0.0 peerDependenciesMeta: webpack: optional: true @@ -45647,7 +41731,7 @@ __metadata: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: cd0063b068d2b938fd76c412d555374186ac2fa84bbae098265212ed50a5c15d6f03aa12a5a310c544a242943eb58c0bfde4c296d5c36765c182f53799e1bc71 + checksum: b3535d01e8d895f4ce6d74b5f76e29398b712476216cd6d459365e5cc2f2fb1e49240aef6c23b2b943b04dbf768d7d18301af3eb064038bde4e11d03c241202d languageName: node linkType: hard @@ -45676,24 +41760,24 @@ __metadata: linkType: hard "webpack@npm:^5, webpack@npm:^5.70.0": - version: 5.90.2 - resolution: "webpack@npm:5.90.2" + version: 5.91.0 + resolution: "webpack@npm:5.91.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 - "@webassemblyjs/ast": ^1.11.5 - "@webassemblyjs/wasm-edit": ^1.11.5 - "@webassemblyjs/wasm-parser": ^1.11.5 + "@webassemblyjs/ast": ^1.12.1 + "@webassemblyjs/wasm-edit": ^1.12.1 + "@webassemblyjs/wasm-parser": ^1.12.1 acorn: ^8.7.1 acorn-import-assertions: ^1.9.0 browserslist: ^4.21.10 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.15.0 + enhanced-resolve: ^5.16.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 glob-to-regexp: ^0.4.1 - graceful-fs: ^4.2.9 + graceful-fs: ^4.2.11 json-parse-even-better-errors: ^2.3.1 loader-runner: ^4.2.0 mime-types: ^2.1.27 @@ -45701,14 +41785,14 @@ __metadata: schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.10 - watchpack: ^2.4.0 + watchpack: ^2.4.1 webpack-sources: ^3.2.3 peerDependenciesMeta: webpack-cli: optional: true bin: webpack: bin/webpack.js - checksum: 4af55f314c3610e0b17afd01960c4cf9d8d90c87a58ef7d7dc7a0a019f48e2bba4eff63b02d9da56fc61df5b04af0d66b3fa4ec82937a780d37a64db84c643fe + checksum: f1073715dbb1ed5c070affef293d800a867708bcbc5aba4d8baee87660e0cf53c55966a6f36fab078d1d6c9567cdcd0a9086bdfb607cab87ea68c6449791b9a3 languageName: node linkType: hard @@ -45748,13 +41832,6 @@ __metadata: languageName: node linkType: hard -"whatwg-fetch@npm:>=0.10.0": - version: 3.6.19 - resolution: "whatwg-fetch@npm:3.6.19" - checksum: 2896bc9ca867ea514392c73e2a272f65d5c4916248fe0837a9df5b1b92f247047bc76cf7c29c28a01ac6c5fb4314021d2718958c8a08292a96d56f72b2f56806 - languageName: node - linkType: hard - "whatwg-mimetype@npm:^2.3.0": version: 2.3.0 resolution: "whatwg-mimetype@npm:2.3.0" @@ -45862,16 +41939,16 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.11, which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": - version: 1.1.13 - resolution: "which-typed-array@npm:1.1.13" +"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": + version: 1.1.15 + resolution: "which-typed-array@npm:1.1.15" dependencies: - available-typed-arrays: ^1.0.5 - call-bind: ^1.0.4 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 for-each: ^0.3.3 gopd: ^1.0.1 - has-tostringtag: ^1.0.0 - checksum: 3828a0d5d72c800e369d447e54c7620742a4cc0c9baf1b5e8c17e9b6ff90d8d861a3a6dd4800f1953dbf80e5e5cec954a289e5b4a223e3bee4aeb1f8c5f33309 + has-tostringtag: ^1.0.2 + checksum: 65227dcbfadf5677aacc43ec84356d17b5500cb8b8753059bb4397de5cd0c2de681d24e1a7bd575633f976a95f88233abfd6549c2105ef4ebd58af8aa1807c75 languageName: node linkType: hard @@ -45926,7 +42003,7 @@ __metadata: languageName: node linkType: hard -"winston-transport@npm:^4.5.0": +"winston-transport@npm:^4.5.0, winston-transport@npm:^4.7.0": version: 4.7.0 resolution: "winston-transport@npm:4.7.0" dependencies: @@ -45937,9 +42014,9 @@ __metadata: languageName: node linkType: hard -"winston@npm:^3.2.1": - version: 3.11.0 - resolution: "winston@npm:3.11.0" +"winston@npm:^3.13.0, winston@npm:^3.2.1": + version: 3.13.0 + resolution: "winston@npm:3.13.0" dependencies: "@colors/colors": ^1.6.0 "@dabh/diagnostics": ^2.0.2 @@ -45951,8 +42028,8 @@ __metadata: safe-stable-stringify: ^2.3.1 stack-trace: 0.0.x triple-beam: ^1.3.0 - winston-transport: ^4.5.0 - checksum: ca4454070f7a71b19f53c8c1765c59a013dab220edb49161b2e81917751d3e9edc3382430e4fb050feda04fb8463290ecab7cbc9240ec8d3d3b32a121849bbb0 + winston-transport: ^4.7.0 + checksum: 66f9fbbadb58e1632701e9c89391f217310c9455462148e163e060dcd25aed21351b0413bdbbf90e5c5fe9bc945fc5de6f53875ac7c7ef3061133a354fc678c0 languageName: node linkType: hard @@ -46054,7 +42131,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:*, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.8.0": +"ws@npm:*, ws@npm:8.16.0, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.16.0, ws@npm:^8.8.0": version: 8.16.0 resolution: "ws@npm:8.16.0" peerDependencies: @@ -46084,7 +42161,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^5.2.0 || ^6.0.0 || ^7.0.0, ws@npm:^7.4.6": +"ws@npm:^7.4.6": version: 7.5.9 resolution: "ws@npm:7.5.9" peerDependencies: @@ -46167,16 +42244,6 @@ __metadata: languageName: node linkType: hard -"xml2js@npm:^0.6.0": - version: 0.6.2 - resolution: "xml2js@npm:0.6.2" - dependencies: - sax: ">=0.6.0" - xmlbuilder: ~11.0.0 - checksum: 458a83806193008edff44562c0bdb982801d61ee7867ae58fd35fab781e69e17f40dfeb8fc05391a4648c9c54012066d3955fe5d993ffbe4dc63399023f32ac2 - languageName: node - linkType: hard - "xml@npm:=1.0.1": version: 1.0.1 resolution: "xml@npm:1.0.1" @@ -46219,7 +42286,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0, xtend@npm:^4.0.2, xtend@npm:~4.0.1": +"xtend@npm:^4.0.0, xtend@npm:^4.0.2": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a @@ -46308,7 +42375,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:2.3.4, yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.1.1, yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.3.2, yaml@npm:^2.3.3": +"yaml@npm:2.3.4": version: 2.3.4 resolution: "yaml@npm:2.3.4" checksum: e6d1dae1c6383bcc8ba11796eef3b8c02d5082911c6723efeeb5ba50fc8e881df18d645e64de68e421b577296000bea9c75d6d9097c2f6699da3ae0406c030d8 @@ -46322,6 +42389,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.1.1, yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.3.2, yaml@npm:^2.3.3": + version: 2.4.1 + resolution: "yaml@npm:2.4.1" + bin: + yaml: bin.mjs + checksum: 4c391d07a5d5e935e058babb71026c9cdc9a6fd889e35dd91b53cfb0a12691b67c6c5c740858e71345fef18cd9c13c554a6dda9196f59820d769d94041badb0b + languageName: node + linkType: hard + "yargs-parser@npm:^18.1.2, yargs-parser@npm:^18.1.3": version: 18.1.3 resolution: "yargs-parser@npm:18.1.3" @@ -46346,6 +42422,21 @@ __metadata: languageName: node linkType: hard +"yargs@npm:17.7.2, yargs@npm:^17.1.1, yargs@npm:^17.3.1, yargs@npm:^17.7.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: ^8.0.1 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.3 + y18n: ^5.0.5 + yargs-parser: ^21.1.1 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + "yargs@npm:^15.1.0": version: 15.4.1 resolution: "yargs@npm:15.4.1" @@ -46380,21 +42471,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.1.1, yargs@npm:^17.2.1, yargs@npm:^17.3.1, yargs@npm:^17.7.1, yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" - dependencies: - cliui: ^8.0.1 - escalade: ^3.1.1 - get-caller-file: ^2.0.5 - require-directory: ^2.1.1 - string-width: ^4.2.3 - y18n: ^5.0.5 - yargs-parser: ^21.1.1 - checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a - languageName: node - linkType: hard - "yauzl@npm:^2.10.0": version: 2.10.0 resolution: "yauzl@npm:2.10.0" @@ -46405,6 +42481,16 @@ __metadata: languageName: node linkType: hard +"yauzl@npm:^3.0.0": + version: 3.1.3 + resolution: "yauzl@npm:3.1.3" + dependencies: + buffer-crc32: ~0.2.3 + pend: ~1.2.0 + checksum: 5b782f6e99361a9c715e7a82e7aae3d983b6ddff6ebe3a66d2dd3f4ee601ec41c55fa88587bf6de0acbc013aac0b2cac84f9f0cd48372fd5329ee5e273f46f2c + languageName: node + linkType: hard + "yeoman-environment@npm:^3.9.1": version: 3.19.3 resolution: "yeoman-environment@npm:3.19.3" @@ -46476,13 +42562,6 @@ __metadata: languageName: node linkType: hard -"yn@npm:^5.0.0": - version: 5.0.0 - resolution: "yn@npm:5.0.0" - checksum: f0ec7710d3d697e88a67a46e8072542448f04677a7e6580c56b1b78da202fa5cd73fabba94957d58ee306e4ce6366c5c38c1a9fb7fd76d07ad77a4d1908b66b0 - languageName: node - linkType: hard - "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" @@ -46490,25 +42569,15 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.0.0 - resolution: "yocto-queue@npm:1.0.0" - checksum: 2cac84540f65c64ccc1683c267edce396b26b1e931aa429660aefac8fbe0188167b7aee815a3c22fa59a28a58d898d1a2b1825048f834d8d629f4c2a5d443801 - languageName: node - linkType: hard - -"yup@npm:^0.32.9": - version: 0.32.11 - resolution: "yup@npm:0.32.11" +"yup@npm:*, yup@npm:^1.0.0": + version: 1.4.0 + resolution: "yup@npm:1.4.0" dependencies: - "@babel/runtime": ^7.15.4 - "@types/lodash": ^4.14.175 - lodash: ^4.17.21 - lodash-es: ^4.17.21 - nanoclone: ^0.2.1 - property-expr: ^2.0.4 + property-expr: ^2.0.5 + tiny-case: ^1.0.3 toposort: ^2.0.2 - checksum: 43a16786b47cc910fed4891cebdd89df6d6e31702e9462e8f969c73eac88551ce750732608012201ea6b93802c8847cb0aa27b5d57370640f4ecf30f9f97d4b0 + type-fest: ^2.19.0 + checksum: 20a2ee0c1e891979ca16b34805b3a3be9ab4bea6ea3d2f9005b998b4dc992d0e4d7b53e5f4d8d9423420046630fb44fdf0ecf7e83bc34dd83392bca046c5229d languageName: node linkType: hard @@ -46529,22 +42598,6 @@ __metadata: languageName: node linkType: hard -"zen-observable-ts@npm:^1.1.0": - version: 1.2.5 - resolution: "zen-observable-ts@npm:1.2.5" - dependencies: - zen-observable: 0.8.15 - checksum: 3b707b7a0239a9bc40f73ba71b27733a689a957c1f364fabb9fa9cbd7d04b7c2faf0d517bf17004e3ed3f4330ac613e84c0d32313e450ddaa046f3350af44541 - languageName: node - linkType: hard - -"zen-observable@npm:0.8.15": - version: 0.8.15 - resolution: "zen-observable@npm:0.8.15" - checksum: b7289084bc1fc74a559b7259faa23d3214b14b538a8843d2b001a35e27147833f4107590b1b44bf5bc7f6dfe6f488660d3a3725f268e09b3925b3476153b7821 - languageName: node - linkType: hard - "zen-observable@npm:^0.10.0": version: 0.10.0 resolution: "zen-observable@npm:0.10.0" @@ -46582,20 +42635,20 @@ __metadata: linkType: hard "zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.21.4": - version: 3.22.4 - resolution: "zod-to-json-schema@npm:3.22.4" + version: 3.22.5 + resolution: "zod-to-json-schema@npm:3.22.5" peerDependencies: zod: ^3.22.4 - checksum: 22f89d505cc3d93020de38e4471362fbecd73a8df58017553ad57fb14e69b6f2f88bcdfe9f84b291442ed0654f97344d517af291d23848e43e6e208ee23dac2b + checksum: 3c4f87c7cf0f8027ff5e40f30d7b6c823a7a5a521b1238c0dd82b2dfcf259d8c8ea01e030639b0ffa2ab50fd69632999fd40b54b4af49f75b3192c1416c4f8d0 languageName: node linkType: hard -"zod-validation-error@npm:3.0.0": - version: 3.0.0 - resolution: "zod-validation-error@npm:3.0.0" +"zod-validation-error@npm:^3.0.3": + version: 3.1.0 + resolution: "zod-validation-error@npm:3.1.0" peerDependencies: zod: ^3.18.0 - checksum: a1492268847aa69a160a50ad04dcce3d65454520c56a63680c1e6382f07a66a98463f5fbc0d58ee536651ec189fd0464d6ce657dddbdc37700cc8f7fc6e9c292 + checksum: 84df01c91d594701eaf7f5f007be881e47f7adef2e3f3765f7be031cb78033f9be0924273106cb81b586d8020da9885dbb81b3da363f00a51df00f26274f2b23 languageName: node linkType: hard @@ -46613,18 +42666,6 @@ __metadata: languageName: node linkType: hard -"zustand@npm:3.6.9": - version: 3.6.9 - resolution: "zustand@npm:3.6.9" - peerDependencies: - react: ">=16.8" - peerDependenciesMeta: - react: - optional: true - checksum: a553cca3d96450fbc3433df8c562d737d00e7183516c1b7538bfd575055b3b9cfb141041505f211d1ee5975d60789bdfd45cdc7d6efe6dfde1fa718279cf5568 - languageName: node - linkType: hard - "zwitch@npm:^2.0.0": version: 2.0.2 resolution: "zwitch@npm:2.0.2"